ocf-20100325.patch 2.9 MB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048350493505035051350523505335054350553505635057350583505935060350613506235063350643506535066350673506835069350703507135072350733507435075350763507735078350793508035081350823508335084350853508635087350883508935090350913509235093350943509535096350973509835099351003510135102351033510435105351063510735108351093511035111351123511335114351153511635117351183511935120351213512235123351243512535126351273512835129351303513135132351333513435135351363513735138351393514035141351423514335144351453514635147351483514935150351513515235153351543515535156351573515835159351603516135162351633516435165351663516735168351693517035171351723517335174351753517635177351783517935180351813518235183351843518535186351873518835189351903519135192351933519435195351963519735198351993520035201352023520335204352053520635207352083520935210352113521235213352143521535216352173521835219352203522135222352233522435225352263522735228352293523035231352323523335234352353523635237352383523935240352413524235243352443524535246352473524835249352503525135252352533525435255352563525735258352593526035261352623526335264352653526635267352683526935270352713527235273352743527535276352773527835279352803528135282352833528435285352863528735288352893529035291352923529335294352953529635297352983529935300353013530235303353043530535306353073530835309353103531135312353133531435315353163531735318353193532035321353223532335324353253532635327353283532935330353313533235333353343533535336353373533835339353403534135342353433534435345353463534735348353493535035351353523535335354353553535635357353583535935360353613536235363353643536535366353673536835369353703537135372353733537435375353763537735378353793538035381353823538335384353853538635387353883538935390353913539235393353943539535396353973539835399354003540135402354033540435405354063540735408354093541035411354123541335414354153541635417354183541935420354213542235423354243542535426354273542835429354303543135432354333543435435354363543735438354393544035441354423544335444354453544635447354483544935450354513545235453354543545535456354573545835459354603546135462354633546435465354663546735468354693547035471354723547335474354753547635477354783547935480354813548235483354843548535486354873548835489354903549135492354933549435495354963549735498354993550035501355023550335504355053550635507355083550935510355113551235513355143551535516355173551835519355203552135522355233552435525355263552735528355293553035531355323553335534355353553635537355383553935540355413554235543355443554535546355473554835549355503555135552355533555435555355563555735558355593556035561355623556335564355653556635567355683556935570355713557235573355743557535576355773557835579355803558135582355833558435585355863558735588355893559035591355923559335594355953559635597355983559935600356013560235603356043560535606356073560835609356103561135612356133561435615356163561735618356193562035621356223562335624356253562635627356283562935630356313563235633356343563535636356373563835639356403564135642356433564435645356463564735648356493565035651356523565335654356553565635657356583565935660356613566235663356643566535666356673566835669356703567135672356733567435675356763567735678356793568035681356823568335684356853568635687356883568935690356913569235693356943569535696356973569835699357003570135702357033570435705357063570735708357093571035711357123571335714357153571635717357183571935720357213572235723357243572535726357273572835729357303573135732357333573435735357363573735738357393574035741357423574335744357453574635747357483574935750357513575235753357543575535756357573575835759357603576135762357633576435765357663576735768357693577035771357723577335774357753577635777357783577935780357813578235783357843578535786357873578835789357903579135792357933579435795357963579735798357993580035801358023580335804358053580635807358083580935810358113581235813358143581535816358173581835819358203582135822358233582435825358263582735828358293583035831358323583335834358353583635837358383583935840358413584235843358443584535846358473584835849358503585135852358533585435855358563585735858358593586035861358623586335864358653586635867358683586935870358713587235873358743587535876358773587835879358803588135882358833588435885358863588735888358893589035891358923589335894358953589635897358983589935900359013590235903359043590535906359073590835909359103591135912359133591435915359163591735918359193592035921359223592335924359253592635927359283592935930359313593235933359343593535936359373593835939359403594135942359433594435945359463594735948359493595035951359523595335954359553595635957359583595935960359613596235963359643596535966359673596835969359703597135972359733597435975359763597735978359793598035981359823598335984359853598635987359883598935990359913599235993359943599535996359973599835999360003600136002360033600436005360063600736008360093601036011360123601336014360153601636017360183601936020360213602236023360243602536026360273602836029360303603136032360333603436035360363603736038360393604036041360423604336044360453604636047360483604936050360513605236053360543605536056360573605836059360603606136062360633606436065360663606736068360693607036071360723607336074360753607636077360783607936080360813608236083360843608536086360873608836089360903609136092360933609436095360963609736098360993610036101361023610336104361053610636107361083610936110361113611236113361143611536116361173611836119361203612136122361233612436125361263612736128361293613036131361323613336134361353613636137361383613936140361413614236143361443614536146361473614836149361503615136152361533615436155361563615736158361593616036161361623616336164361653616636167361683616936170361713617236173361743617536176361773617836179361803618136182361833618436185361863618736188361893619036191361923619336194361953619636197361983619936200362013620236203362043620536206362073620836209362103621136212362133621436215362163621736218362193622036221362223622336224362253622636227362283622936230362313623236233362343623536236362373623836239362403624136242362433624436245362463624736248362493625036251362523625336254362553625636257362583625936260362613626236263362643626536266362673626836269362703627136272362733627436275362763627736278362793628036281362823628336284362853628636287362883628936290362913629236293362943629536296362973629836299363003630136302363033630436305363063630736308363093631036311363123631336314363153631636317363183631936320363213632236323363243632536326363273632836329363303633136332363333633436335363363633736338363393634036341363423634336344363453634636347363483634936350363513635236353363543635536356363573635836359363603636136362363633636436365363663636736368363693637036371363723637336374363753637636377363783637936380363813638236383363843638536386363873638836389363903639136392363933639436395363963639736398363993640036401364023640336404364053640636407364083640936410364113641236413364143641536416364173641836419364203642136422364233642436425364263642736428364293643036431364323643336434364353643636437364383643936440364413644236443364443644536446364473644836449364503645136452364533645436455364563645736458364593646036461364623646336464364653646636467364683646936470364713647236473364743647536476364773647836479364803648136482364833648436485364863648736488364893649036491364923649336494364953649636497364983649936500365013650236503365043650536506365073650836509365103651136512365133651436515365163651736518365193652036521365223652336524365253652636527365283652936530365313653236533365343653536536365373653836539365403654136542365433654436545365463654736548365493655036551365523655336554365553655636557365583655936560365613656236563365643656536566365673656836569365703657136572365733657436575365763657736578365793658036581365823658336584365853658636587365883658936590365913659236593365943659536596365973659836599366003660136602366033660436605366063660736608366093661036611366123661336614366153661636617366183661936620366213662236623366243662536626366273662836629366303663136632366333663436635366363663736638366393664036641366423664336644366453664636647366483664936650366513665236653366543665536656366573665836659366603666136662366633666436665366663666736668366693667036671366723667336674366753667636677366783667936680366813668236683366843668536686366873668836689366903669136692366933669436695366963669736698366993670036701367023670336704367053670636707367083670936710367113671236713367143671536716367173671836719367203672136722367233672436725367263672736728367293673036731367323673336734367353673636737367383673936740367413674236743367443674536746367473674836749367503675136752367533675436755367563675736758367593676036761367623676336764367653676636767367683676936770367713677236773367743677536776367773677836779367803678136782367833678436785367863678736788367893679036791367923679336794367953679636797367983679936800368013680236803368043680536806368073680836809368103681136812368133681436815368163681736818368193682036821368223682336824368253682636827368283682936830368313683236833368343683536836368373683836839368403684136842368433684436845368463684736848368493685036851368523685336854368553685636857368583685936860368613686236863368643686536866368673686836869368703687136872368733687436875368763687736878368793688036881368823688336884368853688636887368883688936890368913689236893368943689536896368973689836899369003690136902369033690436905369063690736908369093691036911369123691336914369153691636917369183691936920369213692236923369243692536926369273692836929369303693136932369333693436935369363693736938369393694036941369423694336944369453694636947369483694936950369513695236953369543695536956369573695836959369603696136962369633696436965369663696736968369693697036971369723697336974369753697636977369783697936980369813698236983369843698536986369873698836989369903699136992369933699436995369963699736998369993700037001370023700337004370053700637007370083700937010370113701237013370143701537016370173701837019370203702137022370233702437025370263702737028370293703037031370323703337034370353703637037370383703937040370413704237043370443704537046370473704837049370503705137052370533705437055370563705737058370593706037061370623706337064370653706637067370683706937070370713707237073370743707537076370773707837079370803708137082370833708437085370863708737088370893709037091370923709337094370953709637097370983709937100371013710237103371043710537106371073710837109371103711137112371133711437115371163711737118371193712037121371223712337124371253712637127371283712937130371313713237133371343713537136371373713837139371403714137142371433714437145371463714737148371493715037151371523715337154371553715637157371583715937160371613716237163371643716537166371673716837169371703717137172371733717437175371763717737178371793718037181371823718337184371853718637187371883718937190371913719237193371943719537196371973719837199372003720137202372033720437205372063720737208372093721037211372123721337214372153721637217372183721937220372213722237223372243722537226372273722837229372303723137232372333723437235372363723737238372393724037241372423724337244372453724637247372483724937250372513725237253372543725537256372573725837259372603726137262372633726437265372663726737268372693727037271372723727337274372753727637277372783727937280372813728237283372843728537286372873728837289372903729137292372933729437295372963729737298372993730037301373023730337304373053730637307373083730937310373113731237313373143731537316373173731837319373203732137322373233732437325373263732737328373293733037331373323733337334373353733637337373383733937340373413734237343373443734537346373473734837349373503735137352373533735437355373563735737358373593736037361373623736337364373653736637367373683736937370373713737237373373743737537376373773737837379373803738137382373833738437385373863738737388373893739037391373923739337394373953739637397373983739937400374013740237403374043740537406374073740837409374103741137412374133741437415374163741737418374193742037421374223742337424374253742637427374283742937430374313743237433374343743537436374373743837439374403744137442374433744437445374463744737448374493745037451374523745337454374553745637457374583745937460374613746237463374643746537466374673746837469374703747137472374733747437475374763747737478374793748037481374823748337484374853748637487374883748937490374913749237493374943749537496374973749837499375003750137502375033750437505375063750737508375093751037511375123751337514375153751637517375183751937520375213752237523375243752537526375273752837529375303753137532375333753437535375363753737538375393754037541375423754337544375453754637547375483754937550375513755237553375543755537556375573755837559375603756137562375633756437565375663756737568375693757037571375723757337574375753757637577375783757937580375813758237583375843758537586375873758837589375903759137592375933759437595375963759737598375993760037601376023760337604376053760637607376083760937610376113761237613376143761537616376173761837619376203762137622376233762437625376263762737628376293763037631376323763337634376353763637637376383763937640376413764237643376443764537646376473764837649376503765137652376533765437655376563765737658376593766037661376623766337664376653766637667376683766937670376713767237673376743767537676376773767837679376803768137682376833768437685376863768737688376893769037691376923769337694376953769637697376983769937700377013770237703377043770537706377073770837709377103771137712377133771437715377163771737718377193772037721377223772337724377253772637727377283772937730377313773237733377343773537736377373773837739377403774137742377433774437745377463774737748377493775037751377523775337754377553775637757377583775937760377613776237763377643776537766377673776837769377703777137772377733777437775377763777737778377793778037781377823778337784377853778637787377883778937790377913779237793377943779537796377973779837799378003780137802378033780437805378063780737808378093781037811378123781337814378153781637817378183781937820378213782237823378243782537826378273782837829378303783137832378333783437835378363783737838378393784037841378423784337844378453784637847378483784937850378513785237853378543785537856378573785837859378603786137862378633786437865378663786737868378693787037871378723787337874378753787637877378783787937880378813788237883378843788537886378873788837889378903789137892378933789437895378963789737898378993790037901379023790337904379053790637907379083790937910379113791237913379143791537916379173791837919379203792137922379233792437925379263792737928379293793037931379323793337934379353793637937379383793937940379413794237943379443794537946379473794837949379503795137952379533795437955379563795737958379593796037961379623796337964379653796637967379683796937970379713797237973379743797537976379773797837979379803798137982379833798437985379863798737988379893799037991379923799337994379953799637997379983799938000380013800238003380043800538006380073800838009380103801138012380133801438015380163801738018380193802038021380223802338024380253802638027380283802938030380313803238033380343803538036380373803838039380403804138042380433804438045380463804738048380493805038051380523805338054380553805638057380583805938060380613806238063380643806538066380673806838069380703807138072380733807438075380763807738078380793808038081380823808338084380853808638087380883808938090380913809238093380943809538096380973809838099381003810138102381033810438105381063810738108381093811038111381123811338114381153811638117381183811938120381213812238123381243812538126381273812838129381303813138132381333813438135381363813738138381393814038141381423814338144381453814638147381483814938150381513815238153381543815538156381573815838159381603816138162381633816438165381663816738168381693817038171381723817338174381753817638177381783817938180381813818238183381843818538186381873818838189381903819138192381933819438195381963819738198381993820038201382023820338204382053820638207382083820938210382113821238213382143821538216382173821838219382203822138222382233822438225382263822738228382293823038231382323823338234382353823638237382383823938240382413824238243382443824538246382473824838249382503825138252382533825438255382563825738258382593826038261382623826338264382653826638267382683826938270382713827238273382743827538276382773827838279382803828138282382833828438285382863828738288382893829038291382923829338294382953829638297382983829938300383013830238303383043830538306383073830838309383103831138312383133831438315383163831738318383193832038321383223832338324383253832638327383283832938330383313833238333383343833538336383373833838339383403834138342383433834438345383463834738348383493835038351383523835338354383553835638357383583835938360383613836238363383643836538366383673836838369383703837138372383733837438375383763837738378383793838038381383823838338384383853838638387383883838938390383913839238393383943839538396383973839838399384003840138402384033840438405384063840738408384093841038411384123841338414384153841638417384183841938420384213842238423384243842538426384273842838429384303843138432384333843438435384363843738438384393844038441384423844338444384453844638447384483844938450384513845238453384543845538456384573845838459384603846138462384633846438465384663846738468384693847038471384723847338474384753847638477384783847938480384813848238483384843848538486384873848838489384903849138492384933849438495384963849738498384993850038501385023850338504385053850638507385083850938510385113851238513385143851538516385173851838519385203852138522385233852438525385263852738528385293853038531385323853338534385353853638537385383853938540385413854238543385443854538546385473854838549385503855138552385533855438555385563855738558385593856038561385623856338564385653856638567385683856938570385713857238573385743857538576385773857838579385803858138582385833858438585385863858738588385893859038591385923859338594385953859638597385983859938600386013860238603386043860538606386073860838609386103861138612386133861438615386163861738618386193862038621386223862338624386253862638627386283862938630386313863238633386343863538636386373863838639386403864138642386433864438645386463864738648386493865038651386523865338654386553865638657386583865938660386613866238663386643866538666386673866838669386703867138672386733867438675386763867738678386793868038681386823868338684386853868638687386883868938690386913869238693386943869538696386973869838699387003870138702387033870438705387063870738708387093871038711387123871338714387153871638717387183871938720387213872238723387243872538726387273872838729387303873138732387333873438735387363873738738387393874038741387423874338744387453874638747387483874938750387513875238753387543875538756387573875838759387603876138762387633876438765387663876738768387693877038771387723877338774387753877638777387783877938780387813878238783387843878538786387873878838789387903879138792387933879438795387963879738798387993880038801388023880338804388053880638807388083880938810388113881238813388143881538816388173881838819388203882138822388233882438825388263882738828388293883038831388323883338834388353883638837388383883938840388413884238843388443884538846388473884838849388503885138852388533885438855388563885738858388593886038861388623886338864388653886638867388683886938870388713887238873388743887538876388773887838879388803888138882388833888438885388863888738888388893889038891388923889338894388953889638897388983889938900389013890238903389043890538906389073890838909389103891138912389133891438915389163891738918389193892038921389223892338924389253892638927389283892938930389313893238933389343893538936389373893838939389403894138942389433894438945389463894738948389493895038951389523895338954389553895638957389583895938960389613896238963389643896538966389673896838969389703897138972389733897438975389763897738978389793898038981389823898338984389853898638987389883898938990389913899238993389943899538996389973899838999390003900139002390033900439005390063900739008390093901039011390123901339014390153901639017390183901939020390213902239023390243902539026390273902839029390303903139032390333903439035390363903739038390393904039041390423904339044390453904639047390483904939050390513905239053390543905539056390573905839059390603906139062390633906439065390663906739068390693907039071390723907339074390753907639077390783907939080390813908239083390843908539086390873908839089390903909139092390933909439095390963909739098390993910039101391023910339104391053910639107391083910939110391113911239113391143911539116391173911839119391203912139122391233912439125391263912739128391293913039131391323913339134391353913639137391383913939140391413914239143391443914539146391473914839149391503915139152391533915439155391563915739158391593916039161391623916339164391653916639167391683916939170391713917239173391743917539176391773917839179391803918139182391833918439185391863918739188391893919039191391923919339194391953919639197391983919939200392013920239203392043920539206392073920839209392103921139212392133921439215392163921739218392193922039221392223922339224392253922639227392283922939230392313923239233392343923539236392373923839239392403924139242392433924439245392463924739248392493925039251392523925339254392553925639257392583925939260392613926239263392643926539266392673926839269392703927139272392733927439275392763927739278392793928039281392823928339284392853928639287392883928939290392913929239293392943929539296392973929839299393003930139302393033930439305393063930739308393093931039311393123931339314393153931639317393183931939320393213932239323393243932539326393273932839329393303933139332393333933439335393363933739338393393934039341393423934339344393453934639347393483934939350393513935239353393543935539356393573935839359393603936139362393633936439365393663936739368393693937039371393723937339374393753937639377393783937939380393813938239383393843938539386393873938839389393903939139392393933939439395393963939739398393993940039401394023940339404394053940639407394083940939410394113941239413394143941539416394173941839419394203942139422394233942439425394263942739428394293943039431394323943339434394353943639437394383943939440394413944239443394443944539446394473944839449394503945139452394533945439455394563945739458394593946039461394623946339464394653946639467394683946939470394713947239473394743947539476394773947839479394803948139482394833948439485394863948739488394893949039491394923949339494394953949639497394983949939500395013950239503395043950539506395073950839509395103951139512395133951439515395163951739518395193952039521395223952339524395253952639527395283952939530395313953239533395343953539536395373953839539395403954139542395433954439545395463954739548395493955039551395523955339554395553955639557395583955939560395613956239563395643956539566395673956839569395703957139572395733957439575395763957739578395793958039581395823958339584395853958639587395883958939590395913959239593395943959539596395973959839599396003960139602396033960439605396063960739608396093961039611396123961339614396153961639617396183961939620396213962239623396243962539626396273962839629396303963139632396333963439635396363963739638396393964039641396423964339644396453964639647396483964939650396513965239653396543965539656396573965839659396603966139662396633966439665396663966739668396693967039671396723967339674396753967639677396783967939680396813968239683396843968539686396873968839689396903969139692396933969439695396963969739698396993970039701397023970339704397053970639707397083970939710397113971239713397143971539716397173971839719397203972139722397233972439725397263972739728397293973039731397323973339734397353973639737397383973939740397413974239743397443974539746397473974839749397503975139752397533975439755397563975739758397593976039761397623976339764397653976639767397683976939770397713977239773397743977539776397773977839779397803978139782397833978439785397863978739788397893979039791397923979339794397953979639797397983979939800398013980239803398043980539806398073980839809398103981139812398133981439815398163981739818398193982039821398223982339824398253982639827398283982939830398313983239833398343983539836398373983839839398403984139842398433984439845398463984739848398493985039851398523985339854398553985639857398583985939860398613986239863398643986539866398673986839869398703987139872398733987439875398763987739878398793988039881398823988339884398853988639887398883988939890398913989239893398943989539896398973989839899399003990139902399033990439905399063990739908399093991039911399123991339914399153991639917399183991939920399213992239923399243992539926399273992839929399303993139932399333993439935399363993739938399393994039941399423994339944399453994639947399483994939950399513995239953399543995539956399573995839959399603996139962399633996439965399663996739968399693997039971399723997339974399753997639977399783997939980399813998239983399843998539986399873998839989399903999139992399933999439995399963999739998399994000040001400024000340004400054000640007400084000940010400114001240013400144001540016400174001840019400204002140022400234002440025400264002740028400294003040031400324003340034400354003640037400384003940040400414004240043400444004540046400474004840049400504005140052400534005440055400564005740058400594006040061400624006340064400654006640067400684006940070400714007240073400744007540076400774007840079400804008140082400834008440085400864008740088400894009040091400924009340094400954009640097400984009940100401014010240103401044010540106401074010840109401104011140112401134011440115401164011740118401194012040121401224012340124401254012640127401284012940130401314013240133401344013540136401374013840139401404014140142401434014440145401464014740148401494015040151401524015340154401554015640157401584015940160401614016240163401644016540166401674016840169401704017140172401734017440175401764017740178401794018040181401824018340184401854018640187401884018940190401914019240193401944019540196401974019840199402004020140202402034020440205402064020740208402094021040211402124021340214402154021640217402184021940220402214022240223402244022540226402274022840229402304023140232402334023440235402364023740238402394024040241402424024340244402454024640247402484024940250402514025240253402544025540256402574025840259402604026140262402634026440265402664026740268402694027040271402724027340274402754027640277402784027940280402814028240283402844028540286402874028840289402904029140292402934029440295402964029740298402994030040301403024030340304403054030640307403084030940310403114031240313403144031540316403174031840319403204032140322403234032440325403264032740328403294033040331403324033340334403354033640337403384033940340403414034240343403444034540346403474034840349403504035140352403534035440355403564035740358403594036040361403624036340364403654036640367403684036940370403714037240373403744037540376403774037840379403804038140382403834038440385403864038740388403894039040391403924039340394403954039640397403984039940400404014040240403404044040540406404074040840409404104041140412404134041440415404164041740418404194042040421404224042340424404254042640427404284042940430404314043240433404344043540436404374043840439404404044140442404434044440445404464044740448404494045040451404524045340454404554045640457404584045940460404614046240463404644046540466404674046840469404704047140472404734047440475404764047740478404794048040481404824048340484404854048640487404884048940490404914049240493404944049540496404974049840499405004050140502405034050440505405064050740508405094051040511405124051340514405154051640517405184051940520405214052240523405244052540526405274052840529405304053140532405334053440535405364053740538405394054040541405424054340544405454054640547405484054940550405514055240553405544055540556405574055840559405604056140562405634056440565405664056740568405694057040571405724057340574405754057640577405784057940580405814058240583405844058540586405874058840589405904059140592405934059440595405964059740598405994060040601406024060340604406054060640607406084060940610406114061240613406144061540616406174061840619406204062140622406234062440625406264062740628406294063040631406324063340634406354063640637406384063940640406414064240643406444064540646406474064840649406504065140652406534065440655406564065740658406594066040661406624066340664406654066640667406684066940670406714067240673406744067540676406774067840679406804068140682406834068440685406864068740688406894069040691406924069340694406954069640697406984069940700407014070240703407044070540706407074070840709407104071140712407134071440715407164071740718407194072040721407224072340724407254072640727407284072940730407314073240733407344073540736407374073840739407404074140742407434074440745407464074740748407494075040751407524075340754407554075640757407584075940760407614076240763407644076540766407674076840769407704077140772407734077440775407764077740778407794078040781407824078340784407854078640787407884078940790407914079240793407944079540796407974079840799408004080140802408034080440805408064080740808408094081040811408124081340814408154081640817408184081940820408214082240823408244082540826408274082840829408304083140832408334083440835408364083740838408394084040841408424084340844408454084640847408484084940850408514085240853408544085540856408574085840859408604086140862408634086440865408664086740868408694087040871408724087340874408754087640877408784087940880408814088240883408844088540886408874088840889408904089140892408934089440895408964089740898408994090040901409024090340904409054090640907409084090940910409114091240913409144091540916409174091840919409204092140922409234092440925409264092740928409294093040931409324093340934409354093640937409384093940940409414094240943409444094540946409474094840949409504095140952409534095440955409564095740958409594096040961409624096340964409654096640967409684096940970409714097240973409744097540976409774097840979409804098140982409834098440985409864098740988409894099040991409924099340994409954099640997409984099941000410014100241003410044100541006410074100841009410104101141012410134101441015410164101741018410194102041021410224102341024410254102641027410284102941030410314103241033410344103541036410374103841039410404104141042410434104441045410464104741048410494105041051410524105341054410554105641057410584105941060410614106241063410644106541066410674106841069410704107141072410734107441075410764107741078410794108041081410824108341084410854108641087410884108941090410914109241093410944109541096410974109841099411004110141102411034110441105411064110741108411094111041111411124111341114411154111641117411184111941120411214112241123411244112541126411274112841129411304113141132411334113441135411364113741138411394114041141411424114341144411454114641147411484114941150411514115241153411544115541156411574115841159411604116141162411634116441165411664116741168411694117041171411724117341174411754117641177411784117941180411814118241183411844118541186411874118841189411904119141192411934119441195411964119741198411994120041201412024120341204412054120641207412084120941210412114121241213412144121541216412174121841219412204122141222412234122441225412264122741228412294123041231412324123341234412354123641237412384123941240412414124241243412444124541246412474124841249412504125141252412534125441255412564125741258412594126041261412624126341264412654126641267412684126941270412714127241273412744127541276412774127841279412804128141282412834128441285412864128741288412894129041291412924129341294412954129641297412984129941300413014130241303413044130541306413074130841309413104131141312413134131441315413164131741318413194132041321413224132341324413254132641327413284132941330413314133241333413344133541336413374133841339413404134141342413434134441345413464134741348413494135041351413524135341354413554135641357413584135941360413614136241363413644136541366413674136841369413704137141372413734137441375413764137741378413794138041381413824138341384413854138641387413884138941390413914139241393413944139541396413974139841399414004140141402414034140441405414064140741408414094141041411414124141341414414154141641417414184141941420414214142241423414244142541426414274142841429414304143141432414334143441435414364143741438414394144041441414424144341444414454144641447414484144941450414514145241453414544145541456414574145841459414604146141462414634146441465414664146741468414694147041471414724147341474414754147641477414784147941480414814148241483414844148541486414874148841489414904149141492414934149441495414964149741498414994150041501415024150341504415054150641507415084150941510415114151241513415144151541516415174151841519415204152141522415234152441525415264152741528415294153041531415324153341534415354153641537415384153941540415414154241543415444154541546415474154841549415504155141552415534155441555415564155741558415594156041561415624156341564415654156641567415684156941570415714157241573415744157541576415774157841579415804158141582415834158441585415864158741588415894159041591415924159341594415954159641597415984159941600416014160241603416044160541606416074160841609416104161141612416134161441615416164161741618416194162041621416224162341624416254162641627416284162941630416314163241633416344163541636416374163841639416404164141642416434164441645416464164741648416494165041651416524165341654416554165641657416584165941660416614166241663416644166541666416674166841669416704167141672416734167441675416764167741678416794168041681416824168341684416854168641687416884168941690416914169241693416944169541696416974169841699417004170141702417034170441705417064170741708417094171041711417124171341714417154171641717417184171941720417214172241723417244172541726417274172841729417304173141732417334173441735417364173741738417394174041741417424174341744417454174641747417484174941750417514175241753417544175541756417574175841759417604176141762417634176441765417664176741768417694177041771417724177341774417754177641777417784177941780417814178241783417844178541786417874178841789417904179141792417934179441795417964179741798417994180041801418024180341804418054180641807418084180941810418114181241813418144181541816418174181841819418204182141822418234182441825418264182741828418294183041831418324183341834418354183641837418384183941840418414184241843418444184541846418474184841849418504185141852418534185441855418564185741858418594186041861418624186341864418654186641867418684186941870418714187241873418744187541876418774187841879418804188141882418834188441885418864188741888418894189041891418924189341894418954189641897418984189941900419014190241903419044190541906419074190841909419104191141912419134191441915419164191741918419194192041921419224192341924419254192641927419284192941930419314193241933419344193541936419374193841939419404194141942419434194441945419464194741948419494195041951419524195341954419554195641957419584195941960419614196241963419644196541966419674196841969419704197141972419734197441975419764197741978419794198041981419824198341984419854198641987419884198941990419914199241993419944199541996419974199841999420004200142002420034200442005420064200742008420094201042011420124201342014420154201642017420184201942020420214202242023420244202542026420274202842029420304203142032420334203442035420364203742038420394204042041420424204342044420454204642047420484204942050420514205242053420544205542056420574205842059420604206142062420634206442065420664206742068420694207042071420724207342074420754207642077420784207942080420814208242083420844208542086420874208842089420904209142092420934209442095420964209742098420994210042101421024210342104421054210642107421084210942110421114211242113421144211542116421174211842119421204212142122421234212442125421264212742128421294213042131421324213342134421354213642137421384213942140421414214242143421444214542146421474214842149421504215142152421534215442155421564215742158421594216042161421624216342164421654216642167421684216942170421714217242173421744217542176421774217842179421804218142182421834218442185421864218742188421894219042191421924219342194421954219642197421984219942200422014220242203422044220542206422074220842209422104221142212422134221442215422164221742218422194222042221422224222342224422254222642227422284222942230422314223242233422344223542236422374223842239422404224142242422434224442245422464224742248422494225042251422524225342254422554225642257422584225942260422614226242263422644226542266422674226842269422704227142272422734227442275422764227742278422794228042281422824228342284422854228642287422884228942290422914229242293422944229542296422974229842299423004230142302423034230442305423064230742308423094231042311423124231342314423154231642317423184231942320423214232242323423244232542326423274232842329423304233142332423334233442335423364233742338423394234042341423424234342344423454234642347423484234942350423514235242353423544235542356423574235842359423604236142362423634236442365423664236742368423694237042371423724237342374423754237642377423784237942380423814238242383423844238542386423874238842389423904239142392423934239442395423964239742398423994240042401424024240342404424054240642407424084240942410424114241242413424144241542416424174241842419424204242142422424234242442425424264242742428424294243042431424324243342434424354243642437424384243942440424414244242443424444244542446424474244842449424504245142452424534245442455424564245742458424594246042461424624246342464424654246642467424684246942470424714247242473424744247542476424774247842479424804248142482424834248442485424864248742488424894249042491424924249342494424954249642497424984249942500425014250242503425044250542506425074250842509425104251142512425134251442515425164251742518425194252042521425224252342524425254252642527425284252942530425314253242533425344253542536425374253842539425404254142542425434254442545425464254742548425494255042551425524255342554425554255642557425584255942560425614256242563425644256542566425674256842569425704257142572425734257442575425764257742578425794258042581425824258342584425854258642587425884258942590425914259242593425944259542596425974259842599426004260142602426034260442605426064260742608426094261042611426124261342614426154261642617426184261942620426214262242623426244262542626426274262842629426304263142632426334263442635426364263742638426394264042641426424264342644426454264642647426484264942650426514265242653426544265542656426574265842659426604266142662426634266442665426664266742668426694267042671426724267342674426754267642677426784267942680426814268242683426844268542686426874268842689426904269142692426934269442695426964269742698426994270042701427024270342704427054270642707427084270942710427114271242713427144271542716427174271842719427204272142722427234272442725427264272742728427294273042731427324273342734427354273642737427384273942740427414274242743427444274542746427474274842749427504275142752427534275442755427564275742758427594276042761427624276342764427654276642767427684276942770427714277242773427744277542776427774277842779427804278142782427834278442785427864278742788427894279042791427924279342794427954279642797427984279942800428014280242803428044280542806428074280842809428104281142812428134281442815428164281742818428194282042821428224282342824428254282642827428284282942830428314283242833428344283542836428374283842839428404284142842428434284442845428464284742848428494285042851428524285342854428554285642857428584285942860428614286242863428644286542866428674286842869428704287142872428734287442875428764287742878428794288042881428824288342884428854288642887428884288942890428914289242893428944289542896428974289842899429004290142902429034290442905429064290742908429094291042911429124291342914429154291642917429184291942920429214292242923429244292542926429274292842929429304293142932429334293442935429364293742938429394294042941429424294342944429454294642947429484294942950429514295242953429544295542956429574295842959429604296142962429634296442965429664296742968429694297042971429724297342974429754297642977429784297942980429814298242983429844298542986429874298842989429904299142992429934299442995429964299742998429994300043001430024300343004430054300643007430084300943010430114301243013430144301543016430174301843019430204302143022430234302443025430264302743028430294303043031430324303343034430354303643037430384303943040430414304243043430444304543046430474304843049430504305143052430534305443055430564305743058430594306043061430624306343064430654306643067430684306943070430714307243073430744307543076430774307843079430804308143082430834308443085430864308743088430894309043091430924309343094430954309643097430984309943100431014310243103431044310543106431074310843109431104311143112431134311443115431164311743118431194312043121431224312343124431254312643127431284312943130431314313243133431344313543136431374313843139431404314143142431434314443145431464314743148431494315043151431524315343154431554315643157431584315943160431614316243163431644316543166431674316843169431704317143172431734317443175431764317743178431794318043181431824318343184431854318643187431884318943190431914319243193431944319543196431974319843199432004320143202432034320443205432064320743208432094321043211432124321343214432154321643217432184321943220432214322243223432244322543226432274322843229432304323143232432334323443235432364323743238432394324043241432424324343244432454324643247432484324943250432514325243253432544325543256432574325843259432604326143262432634326443265432664326743268432694327043271432724327343274432754327643277432784327943280432814328243283432844328543286432874328843289432904329143292432934329443295432964329743298432994330043301433024330343304433054330643307433084330943310433114331243313433144331543316433174331843319433204332143322433234332443325433264332743328433294333043331433324333343334433354333643337433384333943340433414334243343433444334543346433474334843349433504335143352433534335443355433564335743358433594336043361433624336343364433654336643367433684336943370433714337243373433744337543376433774337843379433804338143382433834338443385433864338743388433894339043391433924339343394433954339643397433984339943400434014340243403434044340543406434074340843409434104341143412434134341443415434164341743418434194342043421434224342343424434254342643427434284342943430434314343243433434344343543436434374343843439434404344143442434434344443445434464344743448434494345043451434524345343454434554345643457434584345943460434614346243463434644346543466434674346843469434704347143472434734347443475434764347743478434794348043481434824348343484434854348643487434884348943490434914349243493434944349543496434974349843499435004350143502435034350443505435064350743508435094351043511435124351343514435154351643517435184351943520435214352243523435244352543526435274352843529435304353143532435334353443535435364353743538435394354043541435424354343544435454354643547435484354943550435514355243553435544355543556435574355843559435604356143562435634356443565435664356743568435694357043571435724357343574435754357643577435784357943580435814358243583435844358543586435874358843589435904359143592435934359443595435964359743598435994360043601436024360343604436054360643607436084360943610436114361243613436144361543616436174361843619436204362143622436234362443625436264362743628436294363043631436324363343634436354363643637436384363943640436414364243643436444364543646436474364843649436504365143652436534365443655436564365743658436594366043661436624366343664436654366643667436684366943670436714367243673436744367543676436774367843679436804368143682436834368443685436864368743688436894369043691436924369343694436954369643697436984369943700437014370243703437044370543706437074370843709437104371143712437134371443715437164371743718437194372043721437224372343724437254372643727437284372943730437314373243733437344373543736437374373843739437404374143742437434374443745437464374743748437494375043751437524375343754437554375643757437584375943760437614376243763437644376543766437674376843769437704377143772437734377443775437764377743778437794378043781437824378343784437854378643787437884378943790437914379243793437944379543796437974379843799438004380143802438034380443805438064380743808438094381043811438124381343814438154381643817438184381943820438214382243823438244382543826438274382843829438304383143832438334383443835438364383743838438394384043841438424384343844438454384643847438484384943850438514385243853438544385543856438574385843859438604386143862438634386443865438664386743868438694387043871438724387343874438754387643877438784387943880438814388243883438844388543886438874388843889438904389143892438934389443895438964389743898438994390043901439024390343904439054390643907439084390943910439114391243913439144391543916439174391843919439204392143922439234392443925439264392743928439294393043931439324393343934439354393643937439384393943940439414394243943439444394543946439474394843949439504395143952439534395443955439564395743958439594396043961439624396343964439654396643967439684396943970439714397243973439744397543976439774397843979439804398143982439834398443985439864398743988439894399043991439924399343994439954399643997439984399944000440014400244003440044400544006440074400844009440104401144012440134401444015440164401744018440194402044021440224402344024440254402644027440284402944030440314403244033440344403544036440374403844039440404404144042440434404444045440464404744048440494405044051440524405344054440554405644057440584405944060440614406244063440644406544066440674406844069440704407144072440734407444075440764407744078440794408044081440824408344084440854408644087440884408944090440914409244093440944409544096440974409844099441004410144102441034410444105441064410744108441094411044111441124411344114441154411644117441184411944120441214412244123441244412544126441274412844129441304413144132441334413444135441364413744138441394414044141441424414344144441454414644147441484414944150441514415244153441544415544156441574415844159441604416144162441634416444165441664416744168441694417044171441724417344174441754417644177441784417944180441814418244183441844418544186441874418844189441904419144192441934419444195441964419744198441994420044201442024420344204442054420644207442084420944210442114421244213442144421544216442174421844219442204422144222442234422444225442264422744228442294423044231442324423344234442354423644237442384423944240442414424244243442444424544246442474424844249442504425144252442534425444255442564425744258442594426044261442624426344264442654426644267442684426944270442714427244273442744427544276442774427844279442804428144282442834428444285442864428744288442894429044291442924429344294442954429644297442984429944300443014430244303443044430544306443074430844309443104431144312443134431444315443164431744318443194432044321443224432344324443254432644327443284432944330443314433244333443344433544336443374433844339443404434144342443434434444345443464434744348443494435044351443524435344354443554435644357443584435944360443614436244363443644436544366443674436844369443704437144372443734437444375443764437744378443794438044381443824438344384443854438644387443884438944390443914439244393443944439544396443974439844399444004440144402444034440444405444064440744408444094441044411444124441344414444154441644417444184441944420444214442244423444244442544426444274442844429444304443144432444334443444435444364443744438444394444044441444424444344444444454444644447444484444944450444514445244453444544445544456444574445844459444604446144462444634446444465444664446744468444694447044471444724447344474444754447644477444784447944480444814448244483444844448544486444874448844489444904449144492444934449444495444964449744498444994450044501445024450344504445054450644507445084450944510445114451244513445144451544516445174451844519445204452144522445234452444525445264452744528445294453044531445324453344534445354453644537445384453944540445414454244543445444454544546445474454844549445504455144552445534455444555445564455744558445594456044561445624456344564445654456644567445684456944570445714457244573445744457544576445774457844579445804458144582445834458444585445864458744588445894459044591445924459344594445954459644597445984459944600446014460244603446044460544606446074460844609446104461144612446134461444615446164461744618446194462044621446224462344624446254462644627446284462944630446314463244633446344463544636446374463844639446404464144642446434464444645446464464744648446494465044651446524465344654446554465644657446584465944660446614466244663446644466544666446674466844669446704467144672446734467444675446764467744678446794468044681446824468344684446854468644687446884468944690446914469244693446944469544696446974469844699447004470144702447034470444705447064470744708447094471044711447124471344714447154471644717447184471944720447214472244723447244472544726447274472844729447304473144732447334473444735447364473744738447394474044741447424474344744447454474644747447484474944750447514475244753447544475544756447574475844759447604476144762447634476444765447664476744768447694477044771447724477344774447754477644777447784477944780447814478244783447844478544786447874478844789447904479144792447934479444795447964479744798447994480044801448024480344804448054480644807448084480944810448114481244813448144481544816448174481844819448204482144822448234482444825448264482744828448294483044831448324483344834448354483644837448384483944840448414484244843448444484544846448474484844849448504485144852448534485444855448564485744858448594486044861448624486344864448654486644867448684486944870448714487244873448744487544876448774487844879448804488144882448834488444885448864488744888448894489044891448924489344894448954489644897448984489944900449014490244903449044490544906449074490844909449104491144912449134491444915449164491744918449194492044921449224492344924449254492644927449284492944930449314493244933449344493544936449374493844939449404494144942449434494444945449464494744948449494495044951449524495344954449554495644957449584495944960449614496244963449644496544966449674496844969449704497144972449734497444975449764497744978449794498044981449824498344984449854498644987449884498944990449914499244993449944499544996449974499844999450004500145002450034500445005450064500745008450094501045011450124501345014450154501645017450184501945020450214502245023450244502545026450274502845029450304503145032450334503445035450364503745038450394504045041450424504345044450454504645047450484504945050450514505245053450544505545056450574505845059450604506145062450634506445065450664506745068450694507045071450724507345074450754507645077450784507945080450814508245083450844508545086450874508845089450904509145092450934509445095450964509745098450994510045101451024510345104451054510645107451084510945110451114511245113451144511545116451174511845119451204512145122451234512445125451264512745128451294513045131451324513345134451354513645137451384513945140451414514245143451444514545146451474514845149451504515145152451534515445155451564515745158451594516045161451624516345164451654516645167451684516945170451714517245173451744517545176451774517845179451804518145182451834518445185451864518745188451894519045191451924519345194451954519645197451984519945200452014520245203452044520545206452074520845209452104521145212452134521445215452164521745218452194522045221452224522345224452254522645227452284522945230452314523245233452344523545236452374523845239452404524145242452434524445245452464524745248452494525045251452524525345254452554525645257452584525945260452614526245263452644526545266452674526845269452704527145272452734527445275452764527745278452794528045281452824528345284452854528645287452884528945290452914529245293452944529545296452974529845299453004530145302453034530445305453064530745308453094531045311453124531345314453154531645317453184531945320453214532245323453244532545326453274532845329453304533145332453334533445335453364533745338453394534045341453424534345344453454534645347453484534945350453514535245353453544535545356453574535845359453604536145362453634536445365453664536745368453694537045371453724537345374453754537645377453784537945380453814538245383453844538545386453874538845389453904539145392453934539445395453964539745398453994540045401454024540345404454054540645407454084540945410454114541245413454144541545416454174541845419454204542145422454234542445425454264542745428454294543045431454324543345434454354543645437454384543945440454414544245443454444544545446454474544845449454504545145452454534545445455454564545745458454594546045461454624546345464454654546645467454684546945470454714547245473454744547545476454774547845479454804548145482454834548445485454864548745488454894549045491454924549345494454954549645497454984549945500455014550245503455044550545506455074550845509455104551145512455134551445515455164551745518455194552045521455224552345524455254552645527455284552945530455314553245533455344553545536455374553845539455404554145542455434554445545455464554745548455494555045551455524555345554455554555645557455584555945560455614556245563455644556545566455674556845569455704557145572455734557445575455764557745578455794558045581455824558345584455854558645587455884558945590455914559245593455944559545596455974559845599456004560145602456034560445605456064560745608456094561045611456124561345614456154561645617456184561945620456214562245623456244562545626456274562845629456304563145632456334563445635456364563745638456394564045641456424564345644456454564645647456484564945650456514565245653456544565545656456574565845659456604566145662456634566445665456664566745668456694567045671456724567345674456754567645677456784567945680456814568245683456844568545686456874568845689456904569145692456934569445695456964569745698456994570045701457024570345704457054570645707457084570945710457114571245713457144571545716457174571845719457204572145722457234572445725457264572745728457294573045731457324573345734457354573645737457384573945740457414574245743457444574545746457474574845749457504575145752457534575445755457564575745758457594576045761457624576345764457654576645767457684576945770457714577245773457744577545776457774577845779457804578145782457834578445785457864578745788457894579045791457924579345794457954579645797457984579945800458014580245803458044580545806458074580845809458104581145812458134581445815458164581745818458194582045821458224582345824458254582645827458284582945830458314583245833458344583545836458374583845839458404584145842458434584445845458464584745848458494585045851458524585345854458554585645857458584585945860458614586245863458644586545866458674586845869458704587145872458734587445875458764587745878458794588045881458824588345884458854588645887458884588945890458914589245893458944589545896458974589845899459004590145902459034590445905459064590745908459094591045911459124591345914459154591645917459184591945920459214592245923459244592545926459274592845929459304593145932459334593445935459364593745938459394594045941459424594345944459454594645947459484594945950459514595245953459544595545956459574595845959459604596145962459634596445965459664596745968459694597045971459724597345974459754597645977459784597945980459814598245983459844598545986459874598845989459904599145992459934599445995459964599745998459994600046001460024600346004460054600646007460084600946010460114601246013460144601546016460174601846019460204602146022460234602446025460264602746028460294603046031460324603346034460354603646037460384603946040460414604246043460444604546046460474604846049460504605146052460534605446055460564605746058460594606046061460624606346064460654606646067460684606946070460714607246073460744607546076460774607846079460804608146082460834608446085460864608746088460894609046091460924609346094460954609646097460984609946100461014610246103461044610546106461074610846109461104611146112461134611446115461164611746118461194612046121461224612346124461254612646127461284612946130461314613246133461344613546136461374613846139461404614146142461434614446145461464614746148461494615046151461524615346154461554615646157461584615946160461614616246163461644616546166461674616846169461704617146172461734617446175461764617746178461794618046181461824618346184461854618646187461884618946190461914619246193461944619546196461974619846199462004620146202462034620446205462064620746208462094621046211462124621346214462154621646217462184621946220462214622246223462244622546226462274622846229462304623146232462334623446235462364623746238462394624046241462424624346244462454624646247462484624946250462514625246253462544625546256462574625846259462604626146262462634626446265462664626746268462694627046271462724627346274462754627646277462784627946280462814628246283462844628546286462874628846289462904629146292462934629446295462964629746298462994630046301463024630346304463054630646307463084630946310463114631246313463144631546316463174631846319463204632146322463234632446325463264632746328463294633046331463324633346334463354633646337463384633946340463414634246343463444634546346463474634846349463504635146352463534635446355463564635746358463594636046361463624636346364463654636646367463684636946370463714637246373463744637546376463774637846379463804638146382463834638446385463864638746388463894639046391463924639346394463954639646397463984639946400464014640246403464044640546406464074640846409464104641146412464134641446415464164641746418464194642046421464224642346424464254642646427464284642946430464314643246433464344643546436464374643846439464404644146442464434644446445464464644746448464494645046451464524645346454464554645646457464584645946460464614646246463464644646546466464674646846469464704647146472464734647446475464764647746478464794648046481464824648346484464854648646487464884648946490464914649246493464944649546496464974649846499465004650146502465034650446505465064650746508465094651046511465124651346514465154651646517465184651946520465214652246523465244652546526465274652846529465304653146532465334653446535465364653746538465394654046541465424654346544465454654646547465484654946550465514655246553465544655546556465574655846559465604656146562465634656446565465664656746568465694657046571465724657346574465754657646577465784657946580465814658246583465844658546586465874658846589465904659146592465934659446595465964659746598465994660046601466024660346604466054660646607466084660946610466114661246613466144661546616466174661846619466204662146622466234662446625466264662746628466294663046631466324663346634466354663646637466384663946640466414664246643466444664546646466474664846649466504665146652466534665446655466564665746658466594666046661466624666346664466654666646667466684666946670466714667246673466744667546676466774667846679466804668146682466834668446685466864668746688466894669046691466924669346694466954669646697466984669946700467014670246703467044670546706467074670846709467104671146712467134671446715467164671746718467194672046721467224672346724467254672646727467284672946730467314673246733467344673546736467374673846739467404674146742467434674446745467464674746748467494675046751467524675346754467554675646757467584675946760467614676246763467644676546766467674676846769467704677146772467734677446775467764677746778467794678046781467824678346784467854678646787467884678946790467914679246793467944679546796467974679846799468004680146802468034680446805468064680746808468094681046811468124681346814468154681646817468184681946820468214682246823468244682546826468274682846829468304683146832468334683446835468364683746838468394684046841468424684346844468454684646847468484684946850468514685246853468544685546856468574685846859468604686146862468634686446865468664686746868468694687046871468724687346874468754687646877468784687946880468814688246883468844688546886468874688846889468904689146892468934689446895468964689746898468994690046901469024690346904469054690646907469084690946910469114691246913469144691546916469174691846919469204692146922469234692446925469264692746928469294693046931469324693346934469354693646937469384693946940469414694246943469444694546946469474694846949469504695146952469534695446955469564695746958469594696046961469624696346964469654696646967469684696946970469714697246973469744697546976469774697846979469804698146982469834698446985469864698746988469894699046991469924699346994469954699646997469984699947000470014700247003470044700547006470074700847009470104701147012470134701447015470164701747018470194702047021470224702347024470254702647027470284702947030470314703247033470344703547036470374703847039470404704147042470434704447045470464704747048470494705047051470524705347054470554705647057470584705947060470614706247063470644706547066470674706847069470704707147072470734707447075470764707747078470794708047081470824708347084470854708647087470884708947090470914709247093470944709547096470974709847099471004710147102471034710447105471064710747108471094711047111471124711347114471154711647117471184711947120471214712247123471244712547126471274712847129471304713147132471334713447135471364713747138471394714047141471424714347144471454714647147471484714947150471514715247153471544715547156471574715847159471604716147162471634716447165471664716747168471694717047171471724717347174471754717647177471784717947180471814718247183471844718547186471874718847189471904719147192471934719447195471964719747198471994720047201472024720347204472054720647207472084720947210472114721247213472144721547216472174721847219472204722147222472234722447225472264722747228472294723047231472324723347234472354723647237472384723947240472414724247243472444724547246472474724847249472504725147252472534725447255472564725747258472594726047261472624726347264472654726647267472684726947270472714727247273472744727547276472774727847279472804728147282472834728447285472864728747288472894729047291472924729347294472954729647297472984729947300473014730247303473044730547306473074730847309473104731147312473134731447315473164731747318473194732047321473224732347324473254732647327473284732947330473314733247333473344733547336473374733847339473404734147342473434734447345473464734747348473494735047351473524735347354473554735647357473584735947360473614736247363473644736547366473674736847369473704737147372473734737447375473764737747378473794738047381473824738347384473854738647387473884738947390473914739247393473944739547396473974739847399474004740147402474034740447405474064740747408474094741047411474124741347414474154741647417474184741947420474214742247423474244742547426474274742847429474304743147432474334743447435474364743747438474394744047441474424744347444474454744647447474484744947450474514745247453474544745547456474574745847459474604746147462474634746447465474664746747468474694747047471474724747347474474754747647477474784747947480474814748247483474844748547486474874748847489474904749147492474934749447495474964749747498474994750047501475024750347504475054750647507475084750947510475114751247513475144751547516475174751847519475204752147522475234752447525475264752747528475294753047531475324753347534475354753647537475384753947540475414754247543475444754547546475474754847549475504755147552475534755447555475564755747558475594756047561475624756347564475654756647567475684756947570475714757247573475744757547576475774757847579475804758147582475834758447585475864758747588475894759047591475924759347594475954759647597475984759947600476014760247603476044760547606476074760847609476104761147612476134761447615476164761747618476194762047621476224762347624476254762647627476284762947630476314763247633476344763547636476374763847639476404764147642476434764447645476464764747648476494765047651476524765347654476554765647657476584765947660476614766247663476644766547666476674766847669476704767147672476734767447675476764767747678476794768047681476824768347684476854768647687476884768947690476914769247693476944769547696476974769847699477004770147702477034770447705477064770747708477094771047711477124771347714477154771647717477184771947720477214772247723477244772547726477274772847729477304773147732477334773447735477364773747738477394774047741477424774347744477454774647747477484774947750477514775247753477544775547756477574775847759477604776147762477634776447765477664776747768477694777047771477724777347774477754777647777477784777947780477814778247783477844778547786477874778847789477904779147792477934779447795477964779747798477994780047801478024780347804478054780647807478084780947810478114781247813478144781547816478174781847819478204782147822478234782447825478264782747828478294783047831478324783347834478354783647837478384783947840478414784247843478444784547846478474784847849478504785147852478534785447855478564785747858478594786047861478624786347864478654786647867478684786947870478714787247873478744787547876478774787847879478804788147882478834788447885478864788747888478894789047891478924789347894478954789647897478984789947900479014790247903479044790547906479074790847909479104791147912479134791447915479164791747918479194792047921479224792347924479254792647927479284792947930479314793247933479344793547936479374793847939479404794147942479434794447945479464794747948479494795047951479524795347954479554795647957479584795947960479614796247963479644796547966479674796847969479704797147972479734797447975479764797747978479794798047981479824798347984479854798647987479884798947990479914799247993479944799547996479974799847999480004800148002480034800448005480064800748008480094801048011480124801348014480154801648017480184801948020480214802248023480244802548026480274802848029480304803148032480334803448035480364803748038480394804048041480424804348044480454804648047480484804948050480514805248053480544805548056480574805848059480604806148062480634806448065480664806748068480694807048071480724807348074480754807648077480784807948080480814808248083480844808548086480874808848089480904809148092480934809448095480964809748098480994810048101481024810348104481054810648107481084810948110481114811248113481144811548116481174811848119481204812148122481234812448125481264812748128481294813048131481324813348134481354813648137481384813948140481414814248143481444814548146481474814848149481504815148152481534815448155481564815748158481594816048161481624816348164481654816648167481684816948170481714817248173481744817548176481774817848179481804818148182481834818448185481864818748188481894819048191481924819348194481954819648197481984819948200482014820248203482044820548206482074820848209482104821148212482134821448215482164821748218482194822048221482224822348224482254822648227482284822948230482314823248233482344823548236482374823848239482404824148242482434824448245482464824748248482494825048251482524825348254482554825648257482584825948260482614826248263482644826548266482674826848269482704827148272482734827448275482764827748278482794828048281482824828348284482854828648287482884828948290482914829248293482944829548296482974829848299483004830148302483034830448305483064830748308483094831048311483124831348314483154831648317483184831948320483214832248323483244832548326483274832848329483304833148332483334833448335483364833748338483394834048341483424834348344483454834648347483484834948350483514835248353483544835548356483574835848359483604836148362483634836448365483664836748368483694837048371483724837348374483754837648377483784837948380483814838248383483844838548386483874838848389483904839148392483934839448395483964839748398483994840048401484024840348404484054840648407484084840948410484114841248413484144841548416484174841848419484204842148422484234842448425484264842748428484294843048431484324843348434484354843648437484384843948440484414844248443484444844548446484474844848449484504845148452484534845448455484564845748458484594846048461484624846348464484654846648467484684846948470484714847248473484744847548476484774847848479484804848148482484834848448485484864848748488484894849048491484924849348494484954849648497484984849948500485014850248503485044850548506485074850848509485104851148512485134851448515485164851748518485194852048521485224852348524485254852648527485284852948530485314853248533485344853548536485374853848539485404854148542485434854448545485464854748548485494855048551485524855348554485554855648557485584855948560485614856248563485644856548566485674856848569485704857148572485734857448575485764857748578485794858048581485824858348584485854858648587485884858948590485914859248593485944859548596485974859848599486004860148602486034860448605486064860748608486094861048611486124861348614486154861648617486184861948620486214862248623486244862548626486274862848629486304863148632486334863448635486364863748638486394864048641486424864348644486454864648647486484864948650486514865248653486544865548656486574865848659486604866148662486634866448665486664866748668486694867048671486724867348674486754867648677486784867948680486814868248683486844868548686486874868848689486904869148692486934869448695486964869748698486994870048701487024870348704487054870648707487084870948710487114871248713487144871548716487174871848719487204872148722487234872448725487264872748728487294873048731487324873348734487354873648737487384873948740487414874248743487444874548746487474874848749487504875148752487534875448755487564875748758487594876048761487624876348764487654876648767487684876948770487714877248773487744877548776487774877848779487804878148782487834878448785487864878748788487894879048791487924879348794487954879648797487984879948800488014880248803488044880548806488074880848809488104881148812488134881448815488164881748818488194882048821488224882348824488254882648827488284882948830488314883248833488344883548836488374883848839488404884148842488434884448845488464884748848488494885048851488524885348854488554885648857488584885948860488614886248863488644886548866488674886848869488704887148872488734887448875488764887748878488794888048881488824888348884488854888648887488884888948890488914889248893488944889548896488974889848899489004890148902489034890448905489064890748908489094891048911489124891348914489154891648917489184891948920489214892248923489244892548926489274892848929489304893148932489334893448935489364893748938489394894048941489424894348944489454894648947489484894948950489514895248953489544895548956489574895848959489604896148962489634896448965489664896748968489694897048971489724897348974489754897648977489784897948980489814898248983489844898548986489874898848989489904899148992489934899448995489964899748998489994900049001490024900349004490054900649007490084900949010490114901249013490144901549016490174901849019490204902149022490234902449025490264902749028490294903049031490324903349034490354903649037490384903949040490414904249043490444904549046490474904849049490504905149052490534905449055490564905749058490594906049061490624906349064490654906649067490684906949070490714907249073490744907549076490774907849079490804908149082490834908449085490864908749088490894909049091490924909349094490954909649097490984909949100491014910249103491044910549106491074910849109491104911149112491134911449115491164911749118491194912049121491224912349124491254912649127491284912949130491314913249133491344913549136491374913849139491404914149142491434914449145491464914749148491494915049151491524915349154491554915649157491584915949160491614916249163491644916549166491674916849169491704917149172491734917449175491764917749178491794918049181491824918349184491854918649187491884918949190491914919249193491944919549196491974919849199492004920149202492034920449205492064920749208492094921049211492124921349214492154921649217492184921949220492214922249223492244922549226492274922849229492304923149232492334923449235492364923749238492394924049241492424924349244492454924649247492484924949250492514925249253492544925549256492574925849259492604926149262492634926449265492664926749268492694927049271492724927349274492754927649277492784927949280492814928249283492844928549286492874928849289492904929149292492934929449295492964929749298492994930049301493024930349304493054930649307493084930949310493114931249313493144931549316493174931849319493204932149322493234932449325493264932749328493294933049331493324933349334493354933649337493384933949340493414934249343493444934549346493474934849349493504935149352493534935449355493564935749358493594936049361493624936349364493654936649367493684936949370493714937249373493744937549376493774937849379493804938149382493834938449385493864938749388493894939049391493924939349394493954939649397493984939949400494014940249403494044940549406494074940849409494104941149412494134941449415494164941749418494194942049421494224942349424494254942649427494284942949430494314943249433494344943549436494374943849439494404944149442494434944449445494464944749448494494945049451494524945349454494554945649457494584945949460494614946249463494644946549466494674946849469494704947149472494734947449475494764947749478494794948049481494824948349484494854948649487494884948949490494914949249493494944949549496494974949849499495004950149502495034950449505495064950749508495094951049511495124951349514495154951649517495184951949520495214952249523495244952549526495274952849529495304953149532495334953449535495364953749538495394954049541495424954349544495454954649547495484954949550495514955249553495544955549556495574955849559495604956149562495634956449565495664956749568495694957049571495724957349574495754957649577495784957949580495814958249583495844958549586495874958849589495904959149592495934959449595495964959749598495994960049601496024960349604496054960649607496084960949610496114961249613496144961549616496174961849619496204962149622496234962449625496264962749628496294963049631496324963349634496354963649637496384963949640496414964249643496444964549646496474964849649496504965149652496534965449655496564965749658496594966049661496624966349664496654966649667496684966949670496714967249673496744967549676496774967849679496804968149682496834968449685496864968749688496894969049691496924969349694496954969649697496984969949700497014970249703497044970549706497074970849709497104971149712497134971449715497164971749718497194972049721497224972349724497254972649727497284972949730497314973249733497344973549736497374973849739497404974149742497434974449745497464974749748497494975049751497524975349754497554975649757497584975949760497614976249763497644976549766497674976849769497704977149772497734977449775497764977749778497794978049781497824978349784497854978649787497884978949790497914979249793497944979549796497974979849799498004980149802498034980449805498064980749808498094981049811498124981349814498154981649817498184981949820498214982249823498244982549826498274982849829498304983149832498334983449835498364983749838498394984049841498424984349844498454984649847498484984949850498514985249853498544985549856498574985849859498604986149862498634986449865498664986749868498694987049871498724987349874498754987649877498784987949880498814988249883498844988549886498874988849889498904989149892498934989449895498964989749898498994990049901499024990349904499054990649907499084990949910499114991249913499144991549916499174991849919499204992149922499234992449925499264992749928499294993049931499324993349934499354993649937499384993949940499414994249943499444994549946499474994849949499504995149952499534995449955499564995749958499594996049961499624996349964499654996649967499684996949970499714997249973499744997549976499774997849979499804998149982499834998449985499864998749988499894999049991499924999349994499954999649997499984999950000500015000250003500045000550006500075000850009500105001150012500135001450015500165001750018500195002050021500225002350024500255002650027500285002950030500315003250033500345003550036500375003850039500405004150042500435004450045500465004750048500495005050051500525005350054500555005650057500585005950060500615006250063500645006550066500675006850069500705007150072500735007450075500765007750078500795008050081500825008350084500855008650087500885008950090500915009250093500945009550096500975009850099501005010150102501035010450105501065010750108501095011050111501125011350114501155011650117501185011950120501215012250123501245012550126501275012850129501305013150132501335013450135501365013750138501395014050141501425014350144501455014650147501485014950150501515015250153501545015550156501575015850159501605016150162501635016450165501665016750168501695017050171501725017350174501755017650177501785017950180501815018250183501845018550186501875018850189501905019150192501935019450195501965019750198501995020050201502025020350204502055020650207502085020950210502115021250213502145021550216502175021850219502205022150222502235022450225502265022750228502295023050231502325023350234502355023650237502385023950240502415024250243502445024550246502475024850249502505025150252502535025450255502565025750258502595026050261502625026350264502655026650267502685026950270502715027250273502745027550276502775027850279502805028150282502835028450285502865028750288502895029050291502925029350294502955029650297502985029950300503015030250303503045030550306503075030850309503105031150312503135031450315503165031750318503195032050321503225032350324503255032650327503285032950330503315033250333503345033550336503375033850339503405034150342503435034450345503465034750348503495035050351503525035350354503555035650357503585035950360503615036250363503645036550366503675036850369503705037150372503735037450375503765037750378503795038050381503825038350384503855038650387503885038950390503915039250393503945039550396503975039850399504005040150402504035040450405504065040750408504095041050411504125041350414504155041650417504185041950420504215042250423504245042550426504275042850429504305043150432504335043450435504365043750438504395044050441504425044350444504455044650447504485044950450504515045250453504545045550456504575045850459504605046150462504635046450465504665046750468504695047050471504725047350474504755047650477504785047950480504815048250483504845048550486504875048850489504905049150492504935049450495504965049750498504995050050501505025050350504505055050650507505085050950510505115051250513505145051550516505175051850519505205052150522505235052450525505265052750528505295053050531505325053350534505355053650537505385053950540505415054250543505445054550546505475054850549505505055150552505535055450555505565055750558505595056050561505625056350564505655056650567505685056950570505715057250573505745057550576505775057850579505805058150582505835058450585505865058750588505895059050591505925059350594505955059650597505985059950600506015060250603506045060550606506075060850609506105061150612506135061450615506165061750618506195062050621506225062350624506255062650627506285062950630506315063250633506345063550636506375063850639506405064150642506435064450645506465064750648506495065050651506525065350654506555065650657506585065950660506615066250663506645066550666506675066850669506705067150672506735067450675506765067750678506795068050681506825068350684506855068650687506885068950690506915069250693506945069550696506975069850699507005070150702507035070450705507065070750708507095071050711507125071350714507155071650717507185071950720507215072250723507245072550726507275072850729507305073150732507335073450735507365073750738507395074050741507425074350744507455074650747507485074950750507515075250753507545075550756507575075850759507605076150762507635076450765507665076750768507695077050771507725077350774507755077650777507785077950780507815078250783507845078550786507875078850789507905079150792507935079450795507965079750798507995080050801508025080350804508055080650807508085080950810508115081250813508145081550816508175081850819508205082150822508235082450825508265082750828508295083050831508325083350834508355083650837508385083950840508415084250843508445084550846508475084850849508505085150852508535085450855508565085750858508595086050861508625086350864508655086650867508685086950870508715087250873508745087550876508775087850879508805088150882508835088450885508865088750888508895089050891508925089350894508955089650897508985089950900509015090250903509045090550906509075090850909509105091150912509135091450915509165091750918509195092050921509225092350924509255092650927509285092950930509315093250933509345093550936509375093850939509405094150942509435094450945509465094750948509495095050951509525095350954509555095650957509585095950960509615096250963509645096550966509675096850969509705097150972509735097450975509765097750978509795098050981509825098350984509855098650987509885098950990509915099250993509945099550996509975099850999510005100151002510035100451005510065100751008510095101051011510125101351014510155101651017510185101951020510215102251023510245102551026510275102851029510305103151032510335103451035510365103751038510395104051041510425104351044510455104651047510485104951050510515105251053510545105551056510575105851059510605106151062510635106451065510665106751068510695107051071510725107351074510755107651077510785107951080510815108251083510845108551086510875108851089510905109151092510935109451095510965109751098510995110051101511025110351104511055110651107511085110951110511115111251113511145111551116511175111851119511205112151122511235112451125511265112751128511295113051131511325113351134511355113651137511385113951140511415114251143511445114551146511475114851149511505115151152511535115451155511565115751158511595116051161511625116351164511655116651167511685116951170511715117251173511745117551176511775117851179511805118151182511835118451185511865118751188511895119051191511925119351194511955119651197511985119951200512015120251203512045120551206512075120851209512105121151212512135121451215512165121751218512195122051221512225122351224512255122651227512285122951230512315123251233512345123551236512375123851239512405124151242512435124451245512465124751248512495125051251512525125351254512555125651257512585125951260512615126251263512645126551266512675126851269512705127151272512735127451275512765127751278512795128051281512825128351284512855128651287512885128951290512915129251293512945129551296512975129851299513005130151302513035130451305513065130751308513095131051311513125131351314513155131651317513185131951320513215132251323513245132551326513275132851329513305133151332513335133451335513365133751338513395134051341513425134351344513455134651347513485134951350513515135251353513545135551356513575135851359513605136151362513635136451365513665136751368513695137051371513725137351374513755137651377513785137951380513815138251383513845138551386513875138851389513905139151392513935139451395513965139751398513995140051401514025140351404514055140651407514085140951410514115141251413514145141551416514175141851419514205142151422514235142451425514265142751428514295143051431514325143351434514355143651437514385143951440514415144251443514445144551446514475144851449514505145151452514535145451455514565145751458514595146051461514625146351464514655146651467514685146951470514715147251473514745147551476514775147851479514805148151482514835148451485514865148751488514895149051491514925149351494514955149651497514985149951500515015150251503515045150551506515075150851509515105151151512515135151451515515165151751518515195152051521515225152351524515255152651527515285152951530515315153251533515345153551536515375153851539515405154151542515435154451545515465154751548515495155051551515525155351554515555155651557515585155951560515615156251563515645156551566515675156851569515705157151572515735157451575515765157751578515795158051581515825158351584515855158651587515885158951590515915159251593515945159551596515975159851599516005160151602516035160451605516065160751608516095161051611516125161351614516155161651617516185161951620516215162251623516245162551626516275162851629516305163151632516335163451635516365163751638516395164051641516425164351644516455164651647516485164951650516515165251653516545165551656516575165851659516605166151662516635166451665516665166751668516695167051671516725167351674516755167651677516785167951680516815168251683516845168551686516875168851689516905169151692516935169451695516965169751698516995170051701517025170351704517055170651707517085170951710517115171251713517145171551716517175171851719517205172151722517235172451725517265172751728517295173051731517325173351734517355173651737517385173951740517415174251743517445174551746517475174851749517505175151752517535175451755517565175751758517595176051761517625176351764517655176651767517685176951770517715177251773517745177551776517775177851779517805178151782517835178451785517865178751788517895179051791517925179351794517955179651797517985179951800518015180251803518045180551806518075180851809518105181151812518135181451815518165181751818518195182051821518225182351824518255182651827518285182951830518315183251833518345183551836518375183851839518405184151842518435184451845518465184751848518495185051851518525185351854518555185651857518585185951860518615186251863518645186551866518675186851869518705187151872518735187451875518765187751878518795188051881518825188351884518855188651887518885188951890518915189251893518945189551896518975189851899519005190151902519035190451905519065190751908519095191051911519125191351914519155191651917519185191951920519215192251923519245192551926519275192851929519305193151932519335193451935519365193751938519395194051941519425194351944519455194651947519485194951950519515195251953519545195551956519575195851959519605196151962519635196451965519665196751968519695197051971519725197351974519755197651977519785197951980519815198251983519845198551986519875198851989519905199151992519935199451995519965199751998519995200052001520025200352004520055200652007520085200952010520115201252013520145201552016520175201852019520205202152022520235202452025520265202752028520295203052031520325203352034520355203652037520385203952040520415204252043520445204552046520475204852049520505205152052520535205452055520565205752058520595206052061520625206352064520655206652067520685206952070520715207252073520745207552076520775207852079520805208152082520835208452085520865208752088520895209052091520925209352094520955209652097520985209952100521015210252103521045210552106521075210852109521105211152112521135211452115521165211752118521195212052121521225212352124521255212652127521285212952130521315213252133521345213552136521375213852139521405214152142521435214452145521465214752148521495215052151521525215352154521555215652157521585215952160521615216252163521645216552166521675216852169521705217152172521735217452175521765217752178521795218052181521825218352184521855218652187521885218952190521915219252193521945219552196521975219852199522005220152202522035220452205522065220752208522095221052211522125221352214522155221652217522185221952220522215222252223522245222552226522275222852229522305223152232522335223452235522365223752238522395224052241522425224352244522455224652247522485224952250522515225252253522545225552256522575225852259522605226152262522635226452265522665226752268522695227052271522725227352274522755227652277522785227952280522815228252283522845228552286522875228852289522905229152292522935229452295522965229752298522995230052301523025230352304523055230652307523085230952310523115231252313523145231552316523175231852319523205232152322523235232452325523265232752328523295233052331523325233352334523355233652337523385233952340523415234252343523445234552346523475234852349523505235152352523535235452355523565235752358523595236052361523625236352364523655236652367523685236952370523715237252373523745237552376523775237852379523805238152382523835238452385523865238752388523895239052391523925239352394523955239652397523985239952400524015240252403524045240552406524075240852409524105241152412524135241452415524165241752418524195242052421524225242352424524255242652427524285242952430524315243252433524345243552436524375243852439524405244152442524435244452445524465244752448524495245052451524525245352454524555245652457524585245952460524615246252463524645246552466524675246852469524705247152472524735247452475524765247752478524795248052481524825248352484524855248652487524885248952490524915249252493524945249552496524975249852499525005250152502525035250452505525065250752508525095251052511525125251352514525155251652517525185251952520525215252252523525245252552526525275252852529525305253152532525335253452535525365253752538525395254052541525425254352544525455254652547525485254952550525515255252553525545255552556525575255852559525605256152562525635256452565525665256752568525695257052571525725257352574525755257652577525785257952580525815258252583525845258552586525875258852589525905259152592525935259452595525965259752598525995260052601526025260352604526055260652607526085260952610526115261252613526145261552616526175261852619526205262152622526235262452625526265262752628526295263052631526325263352634526355263652637526385263952640526415264252643526445264552646526475264852649526505265152652526535265452655526565265752658526595266052661526625266352664526655266652667526685266952670526715267252673526745267552676526775267852679526805268152682526835268452685526865268752688526895269052691526925269352694526955269652697526985269952700527015270252703527045270552706527075270852709527105271152712527135271452715527165271752718527195272052721527225272352724527255272652727527285272952730527315273252733527345273552736527375273852739527405274152742527435274452745527465274752748527495275052751527525275352754527555275652757527585275952760527615276252763527645276552766527675276852769527705277152772527735277452775527765277752778527795278052781527825278352784527855278652787527885278952790527915279252793527945279552796527975279852799528005280152802528035280452805528065280752808528095281052811528125281352814528155281652817528185281952820528215282252823528245282552826528275282852829528305283152832528335283452835528365283752838528395284052841528425284352844528455284652847528485284952850528515285252853528545285552856528575285852859528605286152862528635286452865528665286752868528695287052871528725287352874528755287652877528785287952880528815288252883528845288552886528875288852889528905289152892528935289452895528965289752898528995290052901529025290352904529055290652907529085290952910529115291252913529145291552916529175291852919529205292152922529235292452925529265292752928529295293052931529325293352934529355293652937529385293952940529415294252943529445294552946529475294852949529505295152952529535295452955529565295752958529595296052961529625296352964529655296652967529685296952970529715297252973529745297552976529775297852979529805298152982529835298452985529865298752988529895299052991529925299352994529955299652997529985299953000530015300253003530045300553006530075300853009530105301153012530135301453015530165301753018530195302053021530225302353024530255302653027530285302953030530315303253033530345303553036530375303853039530405304153042530435304453045530465304753048530495305053051530525305353054530555305653057530585305953060530615306253063530645306553066530675306853069530705307153072530735307453075530765307753078530795308053081530825308353084530855308653087530885308953090530915309253093530945309553096530975309853099531005310153102531035310453105531065310753108531095311053111531125311353114531155311653117531185311953120531215312253123531245312553126531275312853129531305313153132531335313453135531365313753138531395314053141531425314353144531455314653147531485314953150531515315253153531545315553156531575315853159531605316153162531635316453165531665316753168531695317053171531725317353174531755317653177531785317953180531815318253183531845318553186531875318853189531905319153192531935319453195531965319753198531995320053201532025320353204532055320653207532085320953210532115321253213532145321553216532175321853219532205322153222532235322453225532265322753228532295323053231532325323353234532355323653237532385323953240532415324253243532445324553246532475324853249532505325153252532535325453255532565325753258532595326053261532625326353264532655326653267532685326953270532715327253273532745327553276532775327853279532805328153282532835328453285532865328753288532895329053291532925329353294532955329653297532985329953300533015330253303533045330553306533075330853309533105331153312533135331453315533165331753318533195332053321533225332353324533255332653327533285332953330533315333253333533345333553336533375333853339533405334153342533435334453345533465334753348533495335053351533525335353354533555335653357533585335953360533615336253363533645336553366533675336853369533705337153372533735337453375533765337753378533795338053381533825338353384533855338653387533885338953390533915339253393533945339553396533975339853399534005340153402534035340453405534065340753408534095341053411534125341353414534155341653417534185341953420534215342253423534245342553426534275342853429534305343153432534335343453435534365343753438534395344053441534425344353444534455344653447534485344953450534515345253453534545345553456534575345853459534605346153462534635346453465534665346753468534695347053471534725347353474534755347653477534785347953480534815348253483534845348553486534875348853489534905349153492534935349453495534965349753498534995350053501535025350353504535055350653507535085350953510535115351253513535145351553516535175351853519535205352153522535235352453525535265352753528535295353053531535325353353534535355353653537535385353953540535415354253543535445354553546535475354853549535505355153552535535355453555535565355753558535595356053561535625356353564535655356653567535685356953570535715357253573535745357553576535775357853579535805358153582535835358453585535865358753588535895359053591535925359353594535955359653597535985359953600536015360253603536045360553606536075360853609536105361153612536135361453615536165361753618536195362053621536225362353624536255362653627536285362953630536315363253633536345363553636536375363853639536405364153642536435364453645536465364753648536495365053651536525365353654536555365653657536585365953660536615366253663536645366553666536675366853669536705367153672536735367453675536765367753678536795368053681536825368353684536855368653687536885368953690536915369253693536945369553696536975369853699537005370153702537035370453705537065370753708537095371053711537125371353714537155371653717537185371953720537215372253723537245372553726537275372853729537305373153732537335373453735537365373753738537395374053741537425374353744537455374653747537485374953750537515375253753537545375553756537575375853759537605376153762537635376453765537665376753768537695377053771537725377353774537755377653777537785377953780537815378253783537845378553786537875378853789537905379153792537935379453795537965379753798537995380053801538025380353804538055380653807538085380953810538115381253813538145381553816538175381853819538205382153822538235382453825538265382753828538295383053831538325383353834538355383653837538385383953840538415384253843538445384553846538475384853849538505385153852538535385453855538565385753858538595386053861538625386353864538655386653867538685386953870538715387253873538745387553876538775387853879538805388153882538835388453885538865388753888538895389053891538925389353894538955389653897538985389953900539015390253903539045390553906539075390853909539105391153912539135391453915539165391753918539195392053921539225392353924539255392653927539285392953930539315393253933539345393553936539375393853939539405394153942539435394453945539465394753948539495395053951539525395353954539555395653957539585395953960539615396253963539645396553966539675396853969539705397153972539735397453975539765397753978539795398053981539825398353984539855398653987539885398953990539915399253993539945399553996539975399853999540005400154002540035400454005540065400754008540095401054011540125401354014540155401654017540185401954020540215402254023540245402554026540275402854029540305403154032540335403454035540365403754038540395404054041540425404354044540455404654047540485404954050540515405254053540545405554056540575405854059540605406154062540635406454065540665406754068540695407054071540725407354074540755407654077540785407954080540815408254083540845408554086540875408854089540905409154092540935409454095540965409754098540995410054101541025410354104541055410654107541085410954110541115411254113541145411554116541175411854119541205412154122541235412454125541265412754128541295413054131541325413354134541355413654137541385413954140541415414254143541445414554146541475414854149541505415154152541535415454155541565415754158541595416054161541625416354164541655416654167541685416954170541715417254173541745417554176541775417854179541805418154182541835418454185541865418754188541895419054191541925419354194541955419654197541985419954200542015420254203542045420554206542075420854209542105421154212542135421454215542165421754218542195422054221542225422354224542255422654227542285422954230542315423254233542345423554236542375423854239542405424154242542435424454245542465424754248542495425054251542525425354254542555425654257542585425954260542615426254263542645426554266542675426854269542705427154272542735427454275542765427754278542795428054281542825428354284542855428654287542885428954290542915429254293542945429554296542975429854299543005430154302543035430454305543065430754308543095431054311543125431354314543155431654317543185431954320543215432254323543245432554326543275432854329543305433154332543335433454335543365433754338543395434054341543425434354344543455434654347543485434954350543515435254353543545435554356543575435854359543605436154362543635436454365543665436754368543695437054371543725437354374543755437654377543785437954380543815438254383543845438554386543875438854389543905439154392543935439454395543965439754398543995440054401544025440354404544055440654407544085440954410544115441254413544145441554416544175441854419544205442154422544235442454425544265442754428544295443054431544325443354434544355443654437544385443954440544415444254443544445444554446544475444854449544505445154452544535445454455544565445754458544595446054461544625446354464544655446654467544685446954470544715447254473544745447554476544775447854479544805448154482544835448454485544865448754488544895449054491544925449354494544955449654497544985449954500545015450254503545045450554506545075450854509545105451154512545135451454515545165451754518545195452054521545225452354524545255452654527545285452954530545315453254533545345453554536545375453854539545405454154542545435454454545545465454754548545495455054551545525455354554545555455654557545585455954560545615456254563545645456554566545675456854569545705457154572545735457454575545765457754578545795458054581545825458354584545855458654587545885458954590545915459254593545945459554596545975459854599546005460154602546035460454605546065460754608546095461054611546125461354614546155461654617546185461954620546215462254623546245462554626546275462854629546305463154632546335463454635546365463754638546395464054641546425464354644546455464654647546485464954650546515465254653546545465554656546575465854659546605466154662546635466454665546665466754668546695467054671546725467354674546755467654677546785467954680546815468254683546845468554686546875468854689546905469154692546935469454695546965469754698546995470054701547025470354704547055470654707547085470954710547115471254713547145471554716547175471854719547205472154722547235472454725547265472754728547295473054731547325473354734547355473654737547385473954740547415474254743547445474554746547475474854749547505475154752547535475454755547565475754758547595476054761547625476354764547655476654767547685476954770547715477254773547745477554776547775477854779547805478154782547835478454785547865478754788547895479054791547925479354794547955479654797547985479954800548015480254803548045480554806548075480854809548105481154812548135481454815548165481754818548195482054821548225482354824548255482654827548285482954830548315483254833548345483554836548375483854839548405484154842548435484454845548465484754848548495485054851548525485354854548555485654857548585485954860548615486254863548645486554866548675486854869548705487154872548735487454875548765487754878548795488054881548825488354884548855488654887548885488954890548915489254893548945489554896548975489854899549005490154902549035490454905549065490754908549095491054911549125491354914549155491654917549185491954920549215492254923549245492554926549275492854929549305493154932549335493454935549365493754938549395494054941549425494354944549455494654947549485494954950549515495254953549545495554956549575495854959549605496154962549635496454965549665496754968549695497054971549725497354974549755497654977549785497954980549815498254983549845498554986549875498854989549905499154992549935499454995549965499754998549995500055001550025500355004550055500655007550085500955010550115501255013550145501555016550175501855019550205502155022550235502455025550265502755028550295503055031550325503355034550355503655037550385503955040550415504255043550445504555046550475504855049550505505155052550535505455055550565505755058550595506055061550625506355064550655506655067550685506955070550715507255073550745507555076550775507855079550805508155082550835508455085550865508755088550895509055091550925509355094550955509655097550985509955100551015510255103551045510555106551075510855109551105511155112551135511455115551165511755118551195512055121551225512355124551255512655127551285512955130551315513255133551345513555136551375513855139551405514155142551435514455145551465514755148551495515055151551525515355154551555515655157551585515955160551615516255163551645516555166551675516855169551705517155172551735517455175551765517755178551795518055181551825518355184551855518655187551885518955190551915519255193551945519555196551975519855199552005520155202552035520455205552065520755208552095521055211552125521355214552155521655217552185521955220552215522255223552245522555226552275522855229552305523155232552335523455235552365523755238552395524055241552425524355244552455524655247552485524955250552515525255253552545525555256552575525855259552605526155262552635526455265552665526755268552695527055271552725527355274552755527655277552785527955280552815528255283552845528555286552875528855289552905529155292552935529455295552965529755298552995530055301553025530355304553055530655307553085530955310553115531255313553145531555316553175531855319553205532155322553235532455325553265532755328553295533055331553325533355334553355533655337553385533955340553415534255343553445534555346553475534855349553505535155352553535535455355553565535755358553595536055361553625536355364553655536655367553685536955370553715537255373553745537555376553775537855379553805538155382553835538455385553865538755388553895539055391553925539355394553955539655397553985539955400554015540255403554045540555406554075540855409554105541155412554135541455415554165541755418554195542055421554225542355424554255542655427554285542955430554315543255433554345543555436554375543855439554405544155442554435544455445554465544755448554495545055451554525545355454554555545655457554585545955460554615546255463554645546555466554675546855469554705547155472554735547455475554765547755478554795548055481554825548355484554855548655487554885548955490554915549255493554945549555496554975549855499555005550155502555035550455505555065550755508555095551055511555125551355514555155551655517555185551955520555215552255523555245552555526555275552855529555305553155532555335553455535555365553755538555395554055541555425554355544555455554655547555485554955550555515555255553555545555555556555575555855559555605556155562555635556455565555665556755568555695557055571555725557355574555755557655577555785557955580555815558255583555845558555586555875558855589555905559155592555935559455595555965559755598555995560055601556025560355604556055560655607556085560955610556115561255613556145561555616556175561855619556205562155622556235562455625556265562755628556295563055631556325563355634556355563655637556385563955640556415564255643556445564555646556475564855649556505565155652556535565455655556565565755658556595566055661556625566355664556655566655667556685566955670556715567255673556745567555676556775567855679556805568155682556835568455685556865568755688556895569055691556925569355694556955569655697556985569955700557015570255703557045570555706557075570855709557105571155712557135571455715557165571755718557195572055721557225572355724557255572655727557285572955730557315573255733557345573555736557375573855739557405574155742557435574455745557465574755748557495575055751557525575355754557555575655757557585575955760557615576255763557645576555766557675576855769557705577155772557735577455775557765577755778557795578055781557825578355784557855578655787557885578955790557915579255793557945579555796557975579855799558005580155802558035580455805558065580755808558095581055811558125581355814558155581655817558185581955820558215582255823558245582555826558275582855829558305583155832558335583455835558365583755838558395584055841558425584355844558455584655847558485584955850558515585255853558545585555856558575585855859558605586155862558635586455865558665586755868558695587055871558725587355874558755587655877558785587955880558815588255883558845588555886558875588855889558905589155892558935589455895558965589755898558995590055901559025590355904559055590655907559085590955910559115591255913559145591555916559175591855919559205592155922559235592455925559265592755928559295593055931559325593355934559355593655937559385593955940559415594255943559445594555946559475594855949559505595155952559535595455955559565595755958559595596055961559625596355964559655596655967559685596955970559715597255973559745597555976559775597855979559805598155982559835598455985559865598755988559895599055991559925599355994559955599655997559985599956000560015600256003560045600556006560075600856009560105601156012560135601456015560165601756018560195602056021560225602356024560255602656027560285602956030560315603256033560345603556036560375603856039560405604156042560435604456045560465604756048560495605056051560525605356054560555605656057560585605956060560615606256063560645606556066560675606856069560705607156072560735607456075560765607756078560795608056081560825608356084560855608656087560885608956090560915609256093560945609556096560975609856099561005610156102561035610456105561065610756108561095611056111561125611356114561155611656117561185611956120561215612256123561245612556126561275612856129561305613156132561335613456135561365613756138561395614056141561425614356144561455614656147561485614956150561515615256153561545615556156561575615856159561605616156162561635616456165561665616756168561695617056171561725617356174561755617656177561785617956180561815618256183561845618556186561875618856189561905619156192561935619456195561965619756198561995620056201562025620356204562055620656207562085620956210562115621256213562145621556216562175621856219562205622156222562235622456225562265622756228562295623056231562325623356234562355623656237562385623956240562415624256243562445624556246562475624856249562505625156252562535625456255562565625756258562595626056261562625626356264562655626656267562685626956270562715627256273562745627556276562775627856279562805628156282562835628456285562865628756288562895629056291562925629356294562955629656297562985629956300563015630256303563045630556306563075630856309563105631156312563135631456315563165631756318563195632056321563225632356324563255632656327563285632956330563315633256333563345633556336563375633856339563405634156342563435634456345563465634756348563495635056351563525635356354563555635656357563585635956360563615636256363563645636556366563675636856369563705637156372563735637456375563765637756378563795638056381563825638356384563855638656387563885638956390563915639256393563945639556396563975639856399564005640156402564035640456405564065640756408564095641056411564125641356414564155641656417564185641956420564215642256423564245642556426564275642856429564305643156432564335643456435564365643756438564395644056441564425644356444564455644656447564485644956450564515645256453564545645556456564575645856459564605646156462564635646456465564665646756468564695647056471564725647356474564755647656477564785647956480564815648256483564845648556486564875648856489564905649156492564935649456495564965649756498564995650056501565025650356504565055650656507565085650956510565115651256513565145651556516565175651856519565205652156522565235652456525565265652756528565295653056531565325653356534565355653656537565385653956540565415654256543565445654556546565475654856549565505655156552565535655456555565565655756558565595656056561565625656356564565655656656567565685656956570565715657256573565745657556576565775657856579565805658156582565835658456585565865658756588565895659056591565925659356594565955659656597565985659956600566015660256603566045660556606566075660856609566105661156612566135661456615566165661756618566195662056621566225662356624566255662656627566285662956630566315663256633566345663556636566375663856639566405664156642566435664456645566465664756648566495665056651566525665356654566555665656657566585665956660566615666256663566645666556666566675666856669566705667156672566735667456675566765667756678566795668056681566825668356684566855668656687566885668956690566915669256693566945669556696566975669856699567005670156702567035670456705567065670756708567095671056711567125671356714567155671656717567185671956720567215672256723567245672556726567275672856729567305673156732567335673456735567365673756738567395674056741567425674356744567455674656747567485674956750567515675256753567545675556756567575675856759567605676156762567635676456765567665676756768567695677056771567725677356774567755677656777567785677956780567815678256783567845678556786567875678856789567905679156792567935679456795567965679756798567995680056801568025680356804568055680656807568085680956810568115681256813568145681556816568175681856819568205682156822568235682456825568265682756828568295683056831568325683356834568355683656837568385683956840568415684256843568445684556846568475684856849568505685156852568535685456855568565685756858568595686056861568625686356864568655686656867568685686956870568715687256873568745687556876568775687856879568805688156882568835688456885568865688756888568895689056891568925689356894568955689656897568985689956900569015690256903569045690556906569075690856909569105691156912569135691456915569165691756918569195692056921569225692356924569255692656927569285692956930569315693256933569345693556936569375693856939569405694156942569435694456945569465694756948569495695056951569525695356954569555695656957569585695956960569615696256963569645696556966569675696856969569705697156972569735697456975569765697756978569795698056981569825698356984569855698656987569885698956990569915699256993569945699556996569975699856999570005700157002570035700457005570065700757008570095701057011570125701357014570155701657017570185701957020570215702257023570245702557026570275702857029570305703157032570335703457035570365703757038570395704057041570425704357044570455704657047570485704957050570515705257053570545705557056570575705857059570605706157062570635706457065570665706757068570695707057071570725707357074570755707657077570785707957080570815708257083570845708557086570875708857089570905709157092570935709457095570965709757098570995710057101571025710357104571055710657107571085710957110571115711257113571145711557116571175711857119571205712157122571235712457125571265712757128571295713057131571325713357134571355713657137571385713957140571415714257143571445714557146571475714857149571505715157152571535715457155571565715757158571595716057161571625716357164571655716657167571685716957170571715717257173571745717557176571775717857179571805718157182571835718457185571865718757188571895719057191571925719357194571955719657197571985719957200572015720257203572045720557206572075720857209572105721157212572135721457215572165721757218572195722057221572225722357224572255722657227572285722957230572315723257233572345723557236572375723857239572405724157242572435724457245572465724757248572495725057251572525725357254572555725657257572585725957260572615726257263572645726557266572675726857269572705727157272572735727457275572765727757278572795728057281572825728357284572855728657287572885728957290572915729257293572945729557296572975729857299573005730157302573035730457305573065730757308573095731057311573125731357314573155731657317573185731957320573215732257323573245732557326573275732857329573305733157332573335733457335573365733757338573395734057341573425734357344573455734657347573485734957350573515735257353573545735557356573575735857359573605736157362573635736457365573665736757368573695737057371573725737357374573755737657377573785737957380573815738257383573845738557386573875738857389573905739157392573935739457395573965739757398573995740057401574025740357404574055740657407574085740957410574115741257413574145741557416574175741857419574205742157422574235742457425574265742757428574295743057431574325743357434574355743657437574385743957440574415744257443574445744557446574475744857449574505745157452574535745457455574565745757458574595746057461574625746357464574655746657467574685746957470574715747257473574745747557476574775747857479574805748157482574835748457485574865748757488574895749057491574925749357494574955749657497574985749957500575015750257503575045750557506575075750857509575105751157512575135751457515575165751757518575195752057521575225752357524575255752657527575285752957530575315753257533575345753557536575375753857539575405754157542575435754457545575465754757548575495755057551575525755357554575555755657557575585755957560575615756257563575645756557566575675756857569575705757157572575735757457575575765757757578575795758057581575825758357584575855758657587575885758957590575915759257593575945759557596575975759857599576005760157602576035760457605576065760757608576095761057611576125761357614576155761657617576185761957620576215762257623576245762557626576275762857629576305763157632576335763457635576365763757638576395764057641576425764357644576455764657647576485764957650576515765257653576545765557656576575765857659576605766157662576635766457665576665766757668576695767057671576725767357674576755767657677576785767957680576815768257683576845768557686576875768857689576905769157692576935769457695576965769757698576995770057701577025770357704577055770657707577085770957710577115771257713577145771557716577175771857719577205772157722577235772457725577265772757728577295773057731577325773357734577355773657737577385773957740577415774257743577445774557746577475774857749577505775157752577535775457755577565775757758577595776057761577625776357764577655776657767577685776957770577715777257773577745777557776577775777857779577805778157782577835778457785577865778757788577895779057791577925779357794577955779657797577985779957800578015780257803578045780557806578075780857809578105781157812578135781457815578165781757818578195782057821578225782357824578255782657827578285782957830578315783257833578345783557836578375783857839578405784157842578435784457845578465784757848578495785057851578525785357854578555785657857578585785957860578615786257863578645786557866578675786857869578705787157872578735787457875578765787757878578795788057881578825788357884578855788657887578885788957890578915789257893578945789557896578975789857899579005790157902579035790457905579065790757908579095791057911579125791357914579155791657917579185791957920579215792257923579245792557926579275792857929579305793157932579335793457935579365793757938579395794057941579425794357944579455794657947579485794957950579515795257953579545795557956579575795857959579605796157962579635796457965579665796757968579695797057971579725797357974579755797657977579785797957980579815798257983579845798557986579875798857989579905799157992579935799457995579965799757998579995800058001580025800358004580055800658007580085800958010580115801258013580145801558016580175801858019580205802158022580235802458025580265802758028580295803058031580325803358034580355803658037580385803958040580415804258043580445804558046580475804858049580505805158052580535805458055580565805758058580595806058061580625806358064580655806658067580685806958070580715807258073580745807558076580775807858079580805808158082580835808458085580865808758088580895809058091580925809358094580955809658097580985809958100581015810258103581045810558106581075810858109581105811158112581135811458115581165811758118581195812058121581225812358124581255812658127581285812958130581315813258133581345813558136581375813858139581405814158142581435814458145581465814758148581495815058151581525815358154581555815658157581585815958160581615816258163581645816558166581675816858169581705817158172581735817458175581765817758178581795818058181581825818358184581855818658187581885818958190581915819258193581945819558196581975819858199582005820158202582035820458205582065820758208582095821058211582125821358214582155821658217582185821958220582215822258223582245822558226582275822858229582305823158232582335823458235582365823758238582395824058241582425824358244582455824658247582485824958250582515825258253582545825558256582575825858259582605826158262582635826458265582665826758268582695827058271582725827358274582755827658277582785827958280582815828258283582845828558286582875828858289582905829158292582935829458295582965829758298582995830058301583025830358304583055830658307583085830958310583115831258313583145831558316583175831858319583205832158322583235832458325583265832758328583295833058331583325833358334583355833658337583385833958340583415834258343583445834558346583475834858349583505835158352583535835458355583565835758358583595836058361583625836358364583655836658367583685836958370583715837258373583745837558376583775837858379583805838158382583835838458385583865838758388583895839058391583925839358394583955839658397583985839958400584015840258403584045840558406584075840858409584105841158412584135841458415584165841758418584195842058421584225842358424584255842658427584285842958430584315843258433584345843558436584375843858439584405844158442584435844458445584465844758448584495845058451584525845358454584555845658457584585845958460584615846258463584645846558466584675846858469584705847158472584735847458475584765847758478584795848058481584825848358484584855848658487584885848958490584915849258493584945849558496584975849858499585005850158502585035850458505585065850758508585095851058511585125851358514585155851658517585185851958520585215852258523585245852558526585275852858529585305853158532585335853458535585365853758538585395854058541585425854358544585455854658547585485854958550585515855258553585545855558556585575855858559585605856158562585635856458565585665856758568585695857058571585725857358574585755857658577585785857958580585815858258583585845858558586585875858858589585905859158592585935859458595585965859758598585995860058601586025860358604586055860658607586085860958610586115861258613586145861558616586175861858619586205862158622586235862458625586265862758628586295863058631586325863358634586355863658637586385863958640586415864258643586445864558646586475864858649586505865158652586535865458655586565865758658586595866058661586625866358664586655866658667586685866958670586715867258673586745867558676586775867858679586805868158682586835868458685586865868758688586895869058691586925869358694586955869658697586985869958700587015870258703587045870558706587075870858709587105871158712587135871458715587165871758718587195872058721587225872358724587255872658727587285872958730587315873258733587345873558736587375873858739587405874158742587435874458745587465874758748587495875058751587525875358754587555875658757587585875958760587615876258763587645876558766587675876858769587705877158772587735877458775587765877758778587795878058781587825878358784587855878658787587885878958790587915879258793587945879558796587975879858799588005880158802588035880458805588065880758808588095881058811588125881358814588155881658817588185881958820588215882258823588245882558826588275882858829588305883158832588335883458835588365883758838588395884058841588425884358844588455884658847588485884958850588515885258853588545885558856588575885858859588605886158862588635886458865588665886758868588695887058871588725887358874588755887658877588785887958880588815888258883588845888558886588875888858889588905889158892588935889458895588965889758898588995890058901589025890358904589055890658907589085890958910589115891258913589145891558916589175891858919589205892158922589235892458925589265892758928589295893058931589325893358934589355893658937589385893958940589415894258943589445894558946589475894858949589505895158952589535895458955589565895758958589595896058961589625896358964589655896658967589685896958970589715897258973589745897558976589775897858979589805898158982589835898458985589865898758988589895899058991589925899358994589955899658997589985899959000590015900259003590045900559006590075900859009590105901159012590135901459015590165901759018590195902059021590225902359024590255902659027590285902959030590315903259033590345903559036590375903859039590405904159042590435904459045590465904759048590495905059051590525905359054590555905659057590585905959060590615906259063590645906559066590675906859069590705907159072590735907459075590765907759078590795908059081590825908359084590855908659087590885908959090590915909259093590945909559096590975909859099591005910159102591035910459105591065910759108591095911059111591125911359114591155911659117591185911959120591215912259123591245912559126591275912859129591305913159132591335913459135591365913759138591395914059141591425914359144591455914659147591485914959150591515915259153591545915559156591575915859159591605916159162591635916459165591665916759168591695917059171591725917359174591755917659177591785917959180591815918259183591845918559186591875918859189591905919159192591935919459195591965919759198591995920059201592025920359204592055920659207592085920959210592115921259213592145921559216592175921859219592205922159222592235922459225592265922759228592295923059231592325923359234592355923659237592385923959240592415924259243592445924559246592475924859249592505925159252592535925459255592565925759258592595926059261592625926359264592655926659267592685926959270592715927259273592745927559276592775927859279592805928159282592835928459285592865928759288592895929059291592925929359294592955929659297592985929959300593015930259303593045930559306593075930859309593105931159312593135931459315593165931759318593195932059321593225932359324593255932659327593285932959330593315933259333593345933559336593375933859339593405934159342593435934459345593465934759348593495935059351593525935359354593555935659357593585935959360593615936259363593645936559366593675936859369593705937159372593735937459375593765937759378593795938059381593825938359384593855938659387593885938959390593915939259393593945939559396593975939859399594005940159402594035940459405594065940759408594095941059411594125941359414594155941659417594185941959420594215942259423594245942559426594275942859429594305943159432594335943459435594365943759438594395944059441594425944359444594455944659447594485944959450594515945259453594545945559456594575945859459594605946159462594635946459465594665946759468594695947059471594725947359474594755947659477594785947959480594815948259483594845948559486594875948859489594905949159492594935949459495594965949759498594995950059501595025950359504595055950659507595085950959510595115951259513595145951559516595175951859519595205952159522595235952459525595265952759528595295953059531595325953359534595355953659537595385953959540595415954259543595445954559546595475954859549595505955159552595535955459555595565955759558595595956059561595625956359564595655956659567595685956959570595715957259573595745957559576595775957859579595805958159582595835958459585595865958759588595895959059591595925959359594595955959659597595985959959600596015960259603596045960559606596075960859609596105961159612596135961459615596165961759618596195962059621596225962359624596255962659627596285962959630596315963259633596345963559636596375963859639596405964159642596435964459645596465964759648596495965059651596525965359654596555965659657596585965959660596615966259663596645966559666596675966859669596705967159672596735967459675596765967759678596795968059681596825968359684596855968659687596885968959690596915969259693596945969559696596975969859699597005970159702597035970459705597065970759708597095971059711597125971359714597155971659717597185971959720597215972259723597245972559726597275972859729597305973159732597335973459735597365973759738597395974059741597425974359744597455974659747597485974959750597515975259753597545975559756597575975859759597605976159762597635976459765597665976759768597695977059771597725977359774597755977659777597785977959780597815978259783597845978559786597875978859789597905979159792597935979459795597965979759798597995980059801598025980359804598055980659807598085980959810598115981259813598145981559816598175981859819598205982159822598235982459825598265982759828598295983059831598325983359834598355983659837598385983959840598415984259843598445984559846598475984859849598505985159852598535985459855598565985759858598595986059861598625986359864598655986659867598685986959870598715987259873598745987559876598775987859879598805988159882598835988459885598865988759888598895989059891598925989359894598955989659897598985989959900599015990259903599045990559906599075990859909599105991159912599135991459915599165991759918599195992059921599225992359924599255992659927599285992959930599315993259933599345993559936599375993859939599405994159942599435994459945599465994759948599495995059951599525995359954599555995659957599585995959960599615996259963599645996559966599675996859969599705997159972599735997459975599765997759978599795998059981599825998359984599855998659987599885998959990599915999259993599945999559996599975999859999600006000160002600036000460005600066000760008600096001060011600126001360014600156001660017600186001960020600216002260023600246002560026600276002860029600306003160032600336003460035600366003760038600396004060041600426004360044600456004660047600486004960050600516005260053600546005560056600576005860059600606006160062600636006460065600666006760068600696007060071600726007360074600756007660077600786007960080600816008260083600846008560086600876008860089600906009160092600936009460095600966009760098600996010060101601026010360104601056010660107601086010960110601116011260113601146011560116601176011860119601206012160122601236012460125601266012760128601296013060131601326013360134601356013660137601386013960140601416014260143601446014560146601476014860149601506015160152601536015460155601566015760158601596016060161601626016360164601656016660167601686016960170601716017260173601746017560176601776017860179601806018160182601836018460185601866018760188601896019060191601926019360194601956019660197601986019960200602016020260203602046020560206602076020860209602106021160212602136021460215602166021760218602196022060221602226022360224602256022660227602286022960230602316023260233602346023560236602376023860239602406024160242602436024460245602466024760248602496025060251602526025360254602556025660257602586025960260602616026260263602646026560266602676026860269602706027160272602736027460275602766027760278602796028060281602826028360284602856028660287602886028960290602916029260293602946029560296602976029860299603006030160302603036030460305603066030760308603096031060311603126031360314603156031660317603186031960320603216032260323603246032560326603276032860329603306033160332603336033460335603366033760338603396034060341603426034360344603456034660347603486034960350603516035260353603546035560356603576035860359603606036160362603636036460365603666036760368603696037060371603726037360374603756037660377603786037960380603816038260383603846038560386603876038860389603906039160392603936039460395603966039760398603996040060401604026040360404604056040660407604086040960410604116041260413604146041560416604176041860419604206042160422604236042460425604266042760428604296043060431604326043360434604356043660437604386043960440604416044260443604446044560446604476044860449604506045160452604536045460455604566045760458604596046060461604626046360464604656046660467604686046960470604716047260473604746047560476604776047860479604806048160482604836048460485604866048760488604896049060491604926049360494604956049660497604986049960500605016050260503605046050560506605076050860509605106051160512605136051460515605166051760518605196052060521605226052360524605256052660527605286052960530605316053260533605346053560536605376053860539605406054160542605436054460545605466054760548605496055060551605526055360554605556055660557605586055960560605616056260563605646056560566605676056860569605706057160572605736057460575605766057760578605796058060581605826058360584605856058660587605886058960590605916059260593605946059560596605976059860599606006060160602606036060460605606066060760608606096061060611606126061360614606156061660617606186061960620606216062260623606246062560626606276062860629606306063160632606336063460635606366063760638606396064060641606426064360644606456064660647606486064960650606516065260653606546065560656606576065860659606606066160662606636066460665606666066760668606696067060671606726067360674606756067660677606786067960680606816068260683606846068560686606876068860689606906069160692606936069460695606966069760698606996070060701607026070360704607056070660707607086070960710607116071260713607146071560716607176071860719607206072160722607236072460725607266072760728607296073060731607326073360734607356073660737607386073960740607416074260743607446074560746607476074860749607506075160752607536075460755607566075760758607596076060761607626076360764607656076660767607686076960770607716077260773607746077560776607776077860779607806078160782607836078460785607866078760788607896079060791607926079360794607956079660797607986079960800608016080260803608046080560806608076080860809608106081160812608136081460815608166081760818608196082060821608226082360824608256082660827608286082960830608316083260833608346083560836608376083860839608406084160842608436084460845608466084760848608496085060851608526085360854608556085660857608586085960860608616086260863608646086560866608676086860869608706087160872608736087460875608766087760878608796088060881608826088360884608856088660887608886088960890608916089260893608946089560896608976089860899609006090160902609036090460905609066090760908609096091060911609126091360914609156091660917609186091960920609216092260923609246092560926609276092860929609306093160932609336093460935609366093760938609396094060941609426094360944609456094660947609486094960950609516095260953609546095560956609576095860959609606096160962609636096460965609666096760968609696097060971609726097360974609756097660977609786097960980609816098260983609846098560986609876098860989609906099160992609936099460995609966099760998609996100061001610026100361004610056100661007610086100961010610116101261013610146101561016610176101861019610206102161022610236102461025610266102761028610296103061031610326103361034610356103661037610386103961040610416104261043610446104561046610476104861049610506105161052610536105461055610566105761058610596106061061610626106361064610656106661067610686106961070610716107261073610746107561076610776107861079610806108161082610836108461085610866108761088610896109061091610926109361094610956109661097610986109961100611016110261103611046110561106611076110861109611106111161112611136111461115611166111761118611196112061121611226112361124611256112661127611286112961130611316113261133611346113561136611376113861139611406114161142611436114461145611466114761148611496115061151611526115361154611556115661157611586115961160611616116261163611646116561166611676116861169611706117161172611736117461175611766117761178611796118061181611826118361184611856118661187611886118961190611916119261193611946119561196611976119861199612006120161202612036120461205612066120761208612096121061211612126121361214612156121661217612186121961220612216122261223612246122561226612276122861229612306123161232612336123461235612366123761238612396124061241612426124361244612456124661247612486124961250612516125261253612546125561256612576125861259612606126161262612636126461265612666126761268612696127061271612726127361274612756127661277612786127961280612816128261283612846128561286612876128861289612906129161292612936129461295612966129761298612996130061301613026130361304613056130661307613086130961310613116131261313613146131561316613176131861319613206132161322613236132461325613266132761328613296133061331613326133361334613356133661337613386133961340613416134261343613446134561346613476134861349613506135161352613536135461355613566135761358613596136061361613626136361364613656136661367613686136961370613716137261373613746137561376613776137861379613806138161382613836138461385613866138761388613896139061391613926139361394613956139661397613986139961400614016140261403614046140561406614076140861409614106141161412614136141461415614166141761418614196142061421614226142361424614256142661427614286142961430614316143261433614346143561436614376143861439614406144161442614436144461445614466144761448614496145061451614526145361454614556145661457614586145961460614616146261463614646146561466614676146861469614706147161472614736147461475614766147761478614796148061481614826148361484614856148661487614886148961490614916149261493614946149561496614976149861499615006150161502615036150461505615066150761508615096151061511615126151361514615156151661517615186151961520615216152261523615246152561526615276152861529615306153161532615336153461535615366153761538615396154061541615426154361544615456154661547615486154961550615516155261553615546155561556615576155861559615606156161562615636156461565615666156761568615696157061571615726157361574615756157661577615786157961580615816158261583615846158561586615876158861589615906159161592615936159461595615966159761598615996160061601616026160361604616056160661607616086160961610616116161261613616146161561616616176161861619616206162161622616236162461625616266162761628616296163061631616326163361634616356163661637616386163961640616416164261643616446164561646616476164861649616506165161652616536165461655616566165761658616596166061661616626166361664616656166661667616686166961670616716167261673616746167561676616776167861679616806168161682616836168461685616866168761688616896169061691616926169361694616956169661697616986169961700617016170261703617046170561706617076170861709617106171161712617136171461715617166171761718617196172061721617226172361724617256172661727617286172961730617316173261733617346173561736617376173861739617406174161742617436174461745617466174761748617496175061751617526175361754617556175661757617586175961760617616176261763617646176561766617676176861769617706177161772617736177461775617766177761778617796178061781617826178361784617856178661787617886178961790617916179261793617946179561796617976179861799618006180161802618036180461805618066180761808618096181061811618126181361814618156181661817618186181961820618216182261823618246182561826618276182861829618306183161832618336183461835618366183761838618396184061841618426184361844618456184661847618486184961850618516185261853618546185561856618576185861859618606186161862618636186461865618666186761868618696187061871618726187361874618756187661877618786187961880618816188261883618846188561886618876188861889618906189161892618936189461895618966189761898618996190061901619026190361904619056190661907619086190961910619116191261913619146191561916619176191861919619206192161922619236192461925619266192761928619296193061931619326193361934619356193661937619386193961940619416194261943619446194561946619476194861949619506195161952619536195461955619566195761958619596196061961619626196361964619656196661967619686196961970619716197261973619746197561976619776197861979619806198161982619836198461985619866198761988619896199061991619926199361994619956199661997619986199962000620016200262003620046200562006620076200862009620106201162012620136201462015620166201762018620196202062021620226202362024620256202662027620286202962030620316203262033620346203562036620376203862039620406204162042620436204462045620466204762048620496205062051620526205362054620556205662057620586205962060620616206262063620646206562066620676206862069620706207162072620736207462075620766207762078620796208062081620826208362084620856208662087620886208962090620916209262093620946209562096620976209862099621006210162102621036210462105621066210762108621096211062111621126211362114621156211662117621186211962120621216212262123621246212562126621276212862129621306213162132621336213462135621366213762138621396214062141621426214362144621456214662147621486214962150621516215262153621546215562156621576215862159621606216162162621636216462165621666216762168621696217062171621726217362174621756217662177621786217962180621816218262183621846218562186621876218862189621906219162192621936219462195621966219762198621996220062201622026220362204622056220662207622086220962210622116221262213622146221562216622176221862219622206222162222622236222462225622266222762228622296223062231622326223362234622356223662237622386223962240622416224262243622446224562246622476224862249622506225162252622536225462255622566225762258622596226062261622626226362264622656226662267622686226962270622716227262273622746227562276622776227862279622806228162282622836228462285622866228762288622896229062291622926229362294622956229662297622986229962300623016230262303623046230562306623076230862309623106231162312623136231462315623166231762318623196232062321623226232362324623256232662327623286232962330623316233262333623346233562336623376233862339623406234162342623436234462345623466234762348623496235062351623526235362354623556235662357623586235962360623616236262363623646236562366623676236862369623706237162372623736237462375623766237762378623796238062381623826238362384623856238662387623886238962390623916239262393623946239562396623976239862399624006240162402624036240462405624066240762408624096241062411624126241362414624156241662417624186241962420624216242262423624246242562426624276242862429624306243162432624336243462435624366243762438624396244062441624426244362444624456244662447624486244962450624516245262453624546245562456624576245862459624606246162462624636246462465624666246762468624696247062471624726247362474624756247662477624786247962480624816248262483624846248562486624876248862489624906249162492624936249462495624966249762498624996250062501625026250362504625056250662507625086250962510625116251262513625146251562516625176251862519625206252162522625236252462525625266252762528625296253062531625326253362534625356253662537625386253962540625416254262543625446254562546625476254862549625506255162552625536255462555625566255762558625596256062561625626256362564625656256662567625686256962570625716257262573625746257562576625776257862579625806258162582625836258462585625866258762588625896259062591625926259362594625956259662597625986259962600626016260262603626046260562606626076260862609626106261162612626136261462615626166261762618626196262062621626226262362624626256262662627626286262962630626316263262633626346263562636626376263862639626406264162642626436264462645626466264762648626496265062651626526265362654626556265662657626586265962660626616266262663626646266562666626676266862669626706267162672626736267462675626766267762678626796268062681626826268362684626856268662687626886268962690626916269262693626946269562696626976269862699627006270162702627036270462705627066270762708627096271062711627126271362714627156271662717627186271962720627216272262723627246272562726627276272862729627306273162732627336273462735627366273762738627396274062741627426274362744627456274662747627486274962750627516275262753627546275562756627576275862759627606276162762627636276462765627666276762768627696277062771627726277362774627756277662777627786277962780627816278262783627846278562786627876278862789627906279162792627936279462795627966279762798627996280062801628026280362804628056280662807628086280962810628116281262813628146281562816628176281862819628206282162822628236282462825628266282762828628296283062831628326283362834628356283662837628386283962840628416284262843628446284562846628476284862849628506285162852628536285462855628566285762858628596286062861628626286362864628656286662867628686286962870628716287262873628746287562876628776287862879628806288162882628836288462885628866288762888628896289062891628926289362894628956289662897628986289962900629016290262903629046290562906629076290862909629106291162912629136291462915629166291762918629196292062921629226292362924629256292662927629286292962930629316293262933629346293562936629376293862939629406294162942629436294462945629466294762948629496295062951629526295362954629556295662957629586295962960629616296262963629646296562966629676296862969629706297162972629736297462975629766297762978629796298062981629826298362984629856298662987629886298962990629916299262993629946299562996629976299862999630006300163002630036300463005630066300763008630096301063011630126301363014630156301663017630186301963020630216302263023630246302563026630276302863029630306303163032630336303463035630366303763038630396304063041630426304363044630456304663047630486304963050630516305263053630546305563056630576305863059630606306163062630636306463065630666306763068630696307063071630726307363074630756307663077630786307963080630816308263083630846308563086630876308863089630906309163092630936309463095630966309763098630996310063101631026310363104631056310663107631086310963110631116311263113631146311563116631176311863119631206312163122631236312463125631266312763128631296313063131631326313363134631356313663137631386313963140631416314263143631446314563146631476314863149631506315163152631536315463155631566315763158631596316063161631626316363164631656316663167631686316963170631716317263173631746317563176631776317863179631806318163182631836318463185631866318763188631896319063191631926319363194631956319663197631986319963200632016320263203632046320563206632076320863209632106321163212632136321463215632166321763218632196322063221632226322363224632256322663227632286322963230632316323263233632346323563236632376323863239632406324163242632436324463245632466324763248632496325063251632526325363254632556325663257632586325963260632616326263263632646326563266632676326863269632706327163272632736327463275632766327763278632796328063281632826328363284632856328663287632886328963290632916329263293632946329563296632976329863299633006330163302633036330463305633066330763308633096331063311633126331363314633156331663317633186331963320633216332263323633246332563326633276332863329633306333163332633336333463335633366333763338633396334063341633426334363344633456334663347633486334963350633516335263353633546335563356633576335863359633606336163362633636336463365633666336763368633696337063371633726337363374633756337663377633786337963380633816338263383633846338563386633876338863389633906339163392633936339463395633966339763398633996340063401634026340363404634056340663407634086340963410634116341263413634146341563416634176341863419634206342163422634236342463425634266342763428634296343063431634326343363434634356343663437634386343963440634416344263443634446344563446634476344863449634506345163452634536345463455634566345763458634596346063461634626346363464634656346663467634686346963470634716347263473634746347563476634776347863479634806348163482634836348463485634866348763488634896349063491634926349363494634956349663497634986349963500635016350263503635046350563506635076350863509635106351163512635136351463515635166351763518635196352063521635226352363524635256352663527635286352963530635316353263533635346353563536635376353863539635406354163542635436354463545635466354763548635496355063551635526355363554635556355663557635586355963560635616356263563635646356563566635676356863569635706357163572635736357463575635766357763578635796358063581635826358363584635856358663587635886358963590635916359263593635946359563596635976359863599636006360163602636036360463605636066360763608636096361063611636126361363614636156361663617636186361963620636216362263623636246362563626636276362863629636306363163632636336363463635636366363763638636396364063641636426364363644636456364663647636486364963650636516365263653636546365563656636576365863659636606366163662636636366463665636666366763668636696367063671636726367363674636756367663677636786367963680636816368263683636846368563686636876368863689636906369163692636936369463695636966369763698636996370063701637026370363704637056370663707637086370963710637116371263713637146371563716637176371863719637206372163722637236372463725637266372763728637296373063731637326373363734637356373663737637386373963740637416374263743637446374563746637476374863749637506375163752637536375463755637566375763758637596376063761637626376363764637656376663767637686376963770637716377263773637746377563776637776377863779637806378163782637836378463785637866378763788637896379063791637926379363794637956379663797637986379963800638016380263803638046380563806638076380863809638106381163812638136381463815638166381763818638196382063821638226382363824638256382663827638286382963830638316383263833638346383563836638376383863839638406384163842638436384463845638466384763848638496385063851638526385363854638556385663857638586385963860638616386263863638646386563866638676386863869638706387163872638736387463875638766387763878638796388063881638826388363884638856388663887638886388963890638916389263893638946389563896638976389863899639006390163902639036390463905639066390763908639096391063911639126391363914639156391663917639186391963920639216392263923639246392563926639276392863929639306393163932639336393463935639366393763938639396394063941639426394363944639456394663947639486394963950639516395263953639546395563956639576395863959639606396163962639636396463965639666396763968639696397063971639726397363974639756397663977639786397963980639816398263983639846398563986639876398863989639906399163992639936399463995639966399763998639996400064001640026400364004640056400664007640086400964010640116401264013640146401564016640176401864019640206402164022640236402464025640266402764028640296403064031640326403364034640356403664037640386403964040640416404264043640446404564046640476404864049640506405164052640536405464055640566405764058640596406064061640626406364064640656406664067640686406964070640716407264073640746407564076640776407864079640806408164082640836408464085640866408764088640896409064091640926409364094640956409664097640986409964100641016410264103641046410564106641076410864109641106411164112641136411464115641166411764118641196412064121641226412364124641256412664127641286412964130641316413264133641346413564136641376413864139641406414164142641436414464145641466414764148641496415064151641526415364154641556415664157641586415964160641616416264163641646416564166641676416864169641706417164172641736417464175641766417764178641796418064181641826418364184641856418664187641886418964190641916419264193641946419564196641976419864199642006420164202642036420464205642066420764208642096421064211642126421364214642156421664217642186421964220642216422264223642246422564226642276422864229642306423164232642336423464235642366423764238642396424064241642426424364244642456424664247642486424964250642516425264253642546425564256642576425864259642606426164262642636426464265642666426764268642696427064271642726427364274642756427664277642786427964280642816428264283642846428564286642876428864289642906429164292642936429464295642966429764298642996430064301643026430364304643056430664307643086430964310643116431264313643146431564316643176431864319643206432164322643236432464325643266432764328643296433064331643326433364334643356433664337643386433964340643416434264343643446434564346643476434864349643506435164352643536435464355643566435764358643596436064361643626436364364643656436664367643686436964370643716437264373643746437564376643776437864379643806438164382643836438464385643866438764388643896439064391643926439364394643956439664397643986439964400644016440264403644046440564406644076440864409644106441164412644136441464415644166441764418644196442064421644226442364424644256442664427644286442964430644316443264433644346443564436644376443864439644406444164442644436444464445644466444764448644496445064451644526445364454644556445664457644586445964460644616446264463644646446564466644676446864469644706447164472644736447464475644766447764478644796448064481644826448364484644856448664487644886448964490644916449264493644946449564496644976449864499645006450164502645036450464505645066450764508645096451064511645126451364514645156451664517645186451964520645216452264523645246452564526645276452864529645306453164532645336453464535645366453764538645396454064541645426454364544645456454664547645486454964550645516455264553645546455564556645576455864559645606456164562645636456464565645666456764568645696457064571645726457364574645756457664577645786457964580645816458264583645846458564586645876458864589645906459164592645936459464595645966459764598645996460064601646026460364604646056460664607646086460964610646116461264613646146461564616646176461864619646206462164622646236462464625646266462764628646296463064631646326463364634646356463664637646386463964640646416464264643646446464564646646476464864649646506465164652646536465464655646566465764658646596466064661646626466364664646656466664667646686466964670646716467264673646746467564676646776467864679646806468164682646836468464685646866468764688646896469064691646926469364694646956469664697646986469964700647016470264703647046470564706647076470864709647106471164712647136471464715647166471764718647196472064721647226472364724647256472664727647286472964730647316473264733647346473564736647376473864739647406474164742647436474464745647466474764748647496475064751647526475364754647556475664757647586475964760647616476264763647646476564766647676476864769647706477164772647736477464775647766477764778647796478064781647826478364784647856478664787647886478964790647916479264793647946479564796647976479864799648006480164802648036480464805648066480764808648096481064811648126481364814648156481664817648186481964820648216482264823648246482564826648276482864829648306483164832648336483464835648366483764838648396484064841648426484364844648456484664847648486484964850648516485264853648546485564856648576485864859648606486164862648636486464865648666486764868648696487064871648726487364874648756487664877648786487964880648816488264883648846488564886648876488864889648906489164892648936489464895648966489764898648996490064901649026490364904649056490664907649086490964910649116491264913649146491564916649176491864919649206492164922649236492464925649266492764928649296493064931649326493364934649356493664937649386493964940649416494264943649446494564946649476494864949649506495164952649536495464955649566495764958649596496064961649626496364964649656496664967649686496964970649716497264973649746497564976649776497864979649806498164982649836498464985649866498764988649896499064991649926499364994649956499664997649986499965000650016500265003650046500565006650076500865009650106501165012650136501465015650166501765018650196502065021650226502365024650256502665027650286502965030650316503265033650346503565036650376503865039650406504165042650436504465045650466504765048650496505065051650526505365054650556505665057650586505965060650616506265063650646506565066650676506865069650706507165072650736507465075650766507765078650796508065081650826508365084650856508665087650886508965090650916509265093650946509565096650976509865099651006510165102651036510465105651066510765108651096511065111651126511365114651156511665117651186511965120651216512265123651246512565126651276512865129651306513165132651336513465135651366513765138651396514065141651426514365144651456514665147651486514965150651516515265153651546515565156651576515865159651606516165162651636516465165651666516765168651696517065171651726517365174651756517665177651786517965180651816518265183651846518565186651876518865189651906519165192651936519465195651966519765198651996520065201652026520365204652056520665207652086520965210652116521265213652146521565216652176521865219652206522165222652236522465225652266522765228652296523065231652326523365234652356523665237652386523965240652416524265243652446524565246652476524865249652506525165252652536525465255652566525765258652596526065261652626526365264652656526665267652686526965270652716527265273652746527565276652776527865279652806528165282652836528465285652866528765288652896529065291652926529365294652956529665297652986529965300653016530265303653046530565306653076530865309653106531165312653136531465315653166531765318653196532065321653226532365324653256532665327653286532965330653316533265333653346533565336653376533865339653406534165342653436534465345653466534765348653496535065351653526535365354653556535665357653586535965360653616536265363653646536565366653676536865369653706537165372653736537465375653766537765378653796538065381653826538365384653856538665387653886538965390653916539265393653946539565396653976539865399654006540165402654036540465405654066540765408654096541065411654126541365414654156541665417654186541965420654216542265423654246542565426654276542865429654306543165432654336543465435654366543765438654396544065441654426544365444654456544665447654486544965450654516545265453654546545565456654576545865459654606546165462654636546465465654666546765468654696547065471654726547365474654756547665477654786547965480654816548265483654846548565486654876548865489654906549165492654936549465495654966549765498654996550065501655026550365504655056550665507655086550965510655116551265513655146551565516655176551865519655206552165522655236552465525655266552765528655296553065531655326553365534655356553665537655386553965540655416554265543655446554565546655476554865549655506555165552655536555465555655566555765558655596556065561655626556365564655656556665567655686556965570655716557265573655746557565576655776557865579655806558165582655836558465585655866558765588655896559065591655926559365594655956559665597655986559965600656016560265603656046560565606656076560865609656106561165612656136561465615656166561765618656196562065621656226562365624656256562665627656286562965630656316563265633656346563565636656376563865639656406564165642656436564465645656466564765648656496565065651656526565365654656556565665657656586565965660656616566265663656646566565666656676566865669656706567165672656736567465675656766567765678656796568065681656826568365684656856568665687656886568965690656916569265693656946569565696656976569865699657006570165702657036570465705657066570765708657096571065711657126571365714657156571665717657186571965720657216572265723657246572565726657276572865729657306573165732657336573465735657366573765738657396574065741657426574365744657456574665747657486574965750657516575265753657546575565756657576575865759657606576165762657636576465765657666576765768657696577065771657726577365774657756577665777657786577965780657816578265783657846578565786657876578865789657906579165792657936579465795657966579765798657996580065801658026580365804658056580665807658086580965810658116581265813658146581565816658176581865819658206582165822658236582465825658266582765828658296583065831658326583365834658356583665837658386583965840658416584265843658446584565846658476584865849658506585165852658536585465855658566585765858658596586065861658626586365864658656586665867658686586965870658716587265873658746587565876658776587865879658806588165882658836588465885658866588765888658896589065891658926589365894658956589665897658986589965900659016590265903659046590565906659076590865909659106591165912659136591465915659166591765918659196592065921659226592365924659256592665927659286592965930659316593265933659346593565936659376593865939659406594165942659436594465945659466594765948659496595065951659526595365954659556595665957659586595965960659616596265963659646596565966659676596865969659706597165972659736597465975659766597765978659796598065981659826598365984659856598665987659886598965990659916599265993659946599565996659976599865999660006600166002660036600466005660066600766008660096601066011660126601366014660156601666017660186601966020660216602266023660246602566026660276602866029660306603166032660336603466035660366603766038660396604066041660426604366044660456604666047660486604966050660516605266053660546605566056660576605866059660606606166062660636606466065660666606766068660696607066071660726607366074660756607666077660786607966080660816608266083660846608566086660876608866089660906609166092660936609466095660966609766098660996610066101661026610366104661056610666107661086610966110661116611266113661146611566116661176611866119661206612166122661236612466125661266612766128661296613066131661326613366134661356613666137661386613966140661416614266143661446614566146661476614866149661506615166152661536615466155661566615766158661596616066161661626616366164661656616666167661686616966170661716617266173661746617566176661776617866179661806618166182661836618466185661866618766188661896619066191661926619366194661956619666197661986619966200662016620266203662046620566206662076620866209662106621166212662136621466215662166621766218662196622066221662226622366224662256622666227662286622966230662316623266233662346623566236662376623866239662406624166242662436624466245662466624766248662496625066251662526625366254662556625666257662586625966260662616626266263662646626566266662676626866269662706627166272662736627466275662766627766278662796628066281662826628366284662856628666287662886628966290662916629266293662946629566296662976629866299663006630166302663036630466305663066630766308663096631066311663126631366314663156631666317663186631966320663216632266323663246632566326663276632866329663306633166332663336633466335663366633766338663396634066341663426634366344663456634666347663486634966350663516635266353663546635566356663576635866359663606636166362663636636466365663666636766368663696637066371663726637366374663756637666377663786637966380663816638266383663846638566386663876638866389663906639166392663936639466395663966639766398663996640066401664026640366404664056640666407664086640966410664116641266413664146641566416664176641866419664206642166422664236642466425664266642766428664296643066431664326643366434664356643666437664386643966440664416644266443664446644566446664476644866449664506645166452664536645466455664566645766458664596646066461664626646366464664656646666467664686646966470664716647266473664746647566476664776647866479664806648166482664836648466485664866648766488664896649066491664926649366494664956649666497664986649966500665016650266503665046650566506665076650866509665106651166512665136651466515665166651766518665196652066521665226652366524665256652666527665286652966530665316653266533665346653566536665376653866539665406654166542665436654466545665466654766548665496655066551665526655366554665556655666557665586655966560665616656266563665646656566566665676656866569665706657166572665736657466575665766657766578665796658066581665826658366584665856658666587665886658966590665916659266593665946659566596665976659866599666006660166602666036660466605666066660766608666096661066611666126661366614666156661666617666186661966620666216662266623666246662566626666276662866629666306663166632666336663466635666366663766638666396664066641666426664366644666456664666647666486664966650666516665266653666546665566656666576665866659666606666166662666636666466665666666666766668666696667066671666726667366674666756667666677666786667966680666816668266683666846668566686666876668866689666906669166692666936669466695666966669766698666996670066701667026670366704667056670666707667086670966710667116671266713667146671566716667176671866719667206672166722667236672466725667266672766728667296673066731667326673366734667356673666737667386673966740667416674266743667446674566746667476674866749667506675166752667536675466755667566675766758667596676066761667626676366764667656676666767667686676966770667716677266773667746677566776667776677866779667806678166782667836678466785667866678766788667896679066791667926679366794667956679666797667986679966800668016680266803668046680566806668076680866809668106681166812668136681466815668166681766818668196682066821668226682366824668256682666827668286682966830668316683266833668346683566836668376683866839668406684166842668436684466845668466684766848668496685066851668526685366854668556685666857668586685966860668616686266863668646686566866668676686866869668706687166872668736687466875668766687766878668796688066881668826688366884668856688666887668886688966890668916689266893668946689566896668976689866899669006690166902669036690466905669066690766908669096691066911669126691366914669156691666917669186691966920669216692266923669246692566926669276692866929669306693166932669336693466935669366693766938669396694066941669426694366944669456694666947669486694966950669516695266953669546695566956669576695866959669606696166962669636696466965669666696766968669696697066971669726697366974669756697666977669786697966980669816698266983669846698566986669876698866989669906699166992669936699466995669966699766998669996700067001670026700367004670056700667007670086700967010670116701267013670146701567016670176701867019670206702167022670236702467025670266702767028670296703067031670326703367034670356703667037670386703967040670416704267043670446704567046670476704867049670506705167052670536705467055670566705767058670596706067061670626706367064670656706667067670686706967070670716707267073670746707567076670776707867079670806708167082670836708467085670866708767088670896709067091670926709367094670956709667097670986709967100671016710267103671046710567106671076710867109671106711167112671136711467115671166711767118671196712067121671226712367124671256712667127671286712967130671316713267133671346713567136671376713867139671406714167142671436714467145671466714767148671496715067151671526715367154671556715667157671586715967160671616716267163671646716567166671676716867169671706717167172671736717467175671766717767178671796718067181671826718367184671856718667187671886718967190671916719267193671946719567196671976719867199672006720167202672036720467205672066720767208672096721067211672126721367214672156721667217672186721967220672216722267223672246722567226672276722867229672306723167232672336723467235672366723767238672396724067241672426724367244672456724667247672486724967250672516725267253672546725567256672576725867259672606726167262672636726467265672666726767268672696727067271672726727367274672756727667277672786727967280672816728267283672846728567286672876728867289672906729167292672936729467295672966729767298672996730067301673026730367304673056730667307673086730967310673116731267313673146731567316673176731867319673206732167322673236732467325673266732767328673296733067331673326733367334673356733667337673386733967340673416734267343673446734567346673476734867349673506735167352673536735467355673566735767358673596736067361673626736367364673656736667367673686736967370673716737267373673746737567376673776737867379673806738167382673836738467385673866738767388673896739067391673926739367394673956739667397673986739967400674016740267403674046740567406674076740867409674106741167412674136741467415674166741767418674196742067421674226742367424674256742667427674286742967430674316743267433674346743567436674376743867439674406744167442674436744467445674466744767448674496745067451674526745367454674556745667457674586745967460674616746267463674646746567466674676746867469674706747167472674736747467475674766747767478674796748067481674826748367484674856748667487674886748967490674916749267493674946749567496674976749867499675006750167502675036750467505675066750767508675096751067511675126751367514675156751667517675186751967520675216752267523675246752567526675276752867529675306753167532675336753467535675366753767538675396754067541675426754367544675456754667547675486754967550675516755267553675546755567556675576755867559675606756167562675636756467565675666756767568675696757067571675726757367574675756757667577675786757967580675816758267583675846758567586675876758867589675906759167592675936759467595675966759767598675996760067601676026760367604676056760667607676086760967610676116761267613676146761567616676176761867619676206762167622676236762467625676266762767628676296763067631676326763367634676356763667637676386763967640676416764267643676446764567646676476764867649676506765167652676536765467655676566765767658676596766067661676626766367664676656766667667676686766967670676716767267673676746767567676676776767867679676806768167682676836768467685676866768767688676896769067691676926769367694676956769667697676986769967700677016770267703677046770567706677076770867709677106771167712677136771467715677166771767718677196772067721677226772367724677256772667727677286772967730677316773267733677346773567736677376773867739677406774167742677436774467745677466774767748677496775067751677526775367754677556775667757677586775967760677616776267763677646776567766677676776867769677706777167772677736777467775677766777767778677796778067781677826778367784677856778667787677886778967790677916779267793677946779567796677976779867799678006780167802678036780467805678066780767808678096781067811678126781367814678156781667817678186781967820678216782267823678246782567826678276782867829678306783167832678336783467835678366783767838678396784067841678426784367844678456784667847678486784967850678516785267853678546785567856678576785867859678606786167862678636786467865678666786767868678696787067871678726787367874678756787667877678786787967880678816788267883678846788567886678876788867889678906789167892678936789467895678966789767898678996790067901679026790367904679056790667907679086790967910679116791267913679146791567916679176791867919679206792167922679236792467925679266792767928679296793067931679326793367934679356793667937679386793967940679416794267943679446794567946679476794867949679506795167952679536795467955679566795767958679596796067961679626796367964679656796667967679686796967970679716797267973679746797567976679776797867979679806798167982679836798467985679866798767988679896799067991679926799367994679956799667997679986799968000680016800268003680046800568006680076800868009680106801168012680136801468015680166801768018680196802068021680226802368024680256802668027680286802968030680316803268033680346803568036680376803868039680406804168042680436804468045680466804768048680496805068051680526805368054680556805668057680586805968060680616806268063680646806568066680676806868069680706807168072680736807468075680766807768078680796808068081680826808368084680856808668087680886808968090680916809268093680946809568096680976809868099681006810168102681036810468105681066810768108681096811068111681126811368114681156811668117681186811968120681216812268123681246812568126681276812868129681306813168132681336813468135681366813768138681396814068141681426814368144681456814668147681486814968150681516815268153681546815568156681576815868159681606816168162681636816468165681666816768168681696817068171681726817368174681756817668177681786817968180681816818268183681846818568186681876818868189681906819168192681936819468195681966819768198681996820068201682026820368204682056820668207682086820968210682116821268213682146821568216682176821868219682206822168222682236822468225682266822768228682296823068231682326823368234682356823668237682386823968240682416824268243682446824568246682476824868249682506825168252682536825468255682566825768258682596826068261682626826368264682656826668267682686826968270682716827268273682746827568276682776827868279682806828168282682836828468285682866828768288682896829068291682926829368294682956829668297682986829968300683016830268303683046830568306683076830868309683106831168312683136831468315683166831768318683196832068321683226832368324683256832668327683286832968330683316833268333683346833568336683376833868339683406834168342683436834468345683466834768348683496835068351683526835368354683556835668357683586835968360683616836268363683646836568366683676836868369683706837168372683736837468375683766837768378683796838068381683826838368384683856838668387683886838968390683916839268393683946839568396683976839868399684006840168402684036840468405684066840768408684096841068411684126841368414684156841668417684186841968420684216842268423684246842568426684276842868429684306843168432684336843468435684366843768438684396844068441684426844368444684456844668447684486844968450684516845268453684546845568456684576845868459684606846168462684636846468465684666846768468684696847068471684726847368474684756847668477684786847968480684816848268483684846848568486684876848868489684906849168492684936849468495684966849768498684996850068501685026850368504685056850668507685086850968510685116851268513685146851568516685176851868519685206852168522685236852468525685266852768528685296853068531685326853368534685356853668537685386853968540685416854268543685446854568546685476854868549685506855168552685536855468555685566855768558685596856068561685626856368564685656856668567685686856968570685716857268573685746857568576685776857868579685806858168582685836858468585685866858768588685896859068591685926859368594685956859668597685986859968600686016860268603686046860568606686076860868609686106861168612686136861468615686166861768618686196862068621686226862368624686256862668627686286862968630686316863268633686346863568636686376863868639686406864168642686436864468645686466864768648686496865068651686526865368654686556865668657686586865968660686616866268663686646866568666686676866868669686706867168672686736867468675686766867768678686796868068681686826868368684686856868668687686886868968690686916869268693686946869568696686976869868699687006870168702687036870468705687066870768708687096871068711687126871368714687156871668717687186871968720687216872268723687246872568726687276872868729687306873168732687336873468735687366873768738687396874068741687426874368744687456874668747687486874968750687516875268753687546875568756687576875868759687606876168762687636876468765687666876768768687696877068771687726877368774687756877668777687786877968780687816878268783687846878568786687876878868789687906879168792687936879468795687966879768798687996880068801688026880368804688056880668807688086880968810688116881268813688146881568816688176881868819688206882168822688236882468825688266882768828688296883068831688326883368834688356883668837688386883968840688416884268843688446884568846688476884868849688506885168852688536885468855688566885768858688596886068861688626886368864688656886668867688686886968870688716887268873688746887568876688776887868879688806888168882688836888468885688866888768888688896889068891688926889368894688956889668897688986889968900689016890268903689046890568906689076890868909689106891168912689136891468915689166891768918689196892068921689226892368924689256892668927689286892968930689316893268933689346893568936689376893868939689406894168942689436894468945689466894768948689496895068951689526895368954689556895668957689586895968960689616896268963689646896568966689676896868969689706897168972689736897468975689766897768978689796898068981689826898368984689856898668987689886898968990689916899268993689946899568996689976899868999690006900169002690036900469005690066900769008690096901069011690126901369014690156901669017690186901969020690216902269023690246902569026690276902869029690306903169032690336903469035690366903769038690396904069041690426904369044690456904669047690486904969050690516905269053690546905569056690576905869059690606906169062690636906469065690666906769068690696907069071690726907369074690756907669077690786907969080690816908269083690846908569086690876908869089690906909169092690936909469095690966909769098690996910069101691026910369104691056910669107691086910969110691116911269113691146911569116691176911869119691206912169122691236912469125691266912769128691296913069131691326913369134691356913669137691386913969140691416914269143691446914569146691476914869149691506915169152691536915469155691566915769158691596916069161691626916369164691656916669167691686916969170691716917269173691746917569176691776917869179691806918169182691836918469185691866918769188691896919069191691926919369194691956919669197691986919969200692016920269203692046920569206692076920869209692106921169212692136921469215692166921769218692196922069221692226922369224692256922669227692286922969230692316923269233692346923569236692376923869239692406924169242692436924469245692466924769248692496925069251692526925369254692556925669257692586925969260692616926269263692646926569266692676926869269692706927169272692736927469275692766927769278692796928069281692826928369284692856928669287692886928969290692916929269293692946929569296692976929869299693006930169302693036930469305693066930769308693096931069311693126931369314693156931669317693186931969320693216932269323693246932569326693276932869329693306933169332693336933469335693366933769338693396934069341693426934369344693456934669347693486934969350693516935269353693546935569356693576935869359693606936169362693636936469365693666936769368693696937069371693726937369374693756937669377693786937969380693816938269383693846938569386693876938869389693906939169392693936939469395693966939769398693996940069401694026940369404694056940669407694086940969410694116941269413694146941569416694176941869419694206942169422694236942469425694266942769428694296943069431694326943369434694356943669437694386943969440694416944269443694446944569446694476944869449694506945169452694536945469455694566945769458694596946069461694626946369464694656946669467694686946969470694716947269473694746947569476694776947869479694806948169482694836948469485694866948769488694896949069491694926949369494694956949669497694986949969500695016950269503695046950569506695076950869509695106951169512695136951469515695166951769518695196952069521695226952369524695256952669527695286952969530695316953269533695346953569536695376953869539695406954169542695436954469545695466954769548695496955069551695526955369554695556955669557695586955969560695616956269563695646956569566695676956869569695706957169572695736957469575695766957769578695796958069581695826958369584695856958669587695886958969590695916959269593695946959569596695976959869599696006960169602696036960469605696066960769608696096961069611696126961369614696156961669617696186961969620696216962269623696246962569626696276962869629696306963169632696336963469635696366963769638696396964069641696426964369644696456964669647696486964969650696516965269653696546965569656696576965869659696606966169662696636966469665696666966769668696696967069671696726967369674696756967669677696786967969680696816968269683696846968569686696876968869689696906969169692696936969469695696966969769698696996970069701697026970369704697056970669707697086970969710697116971269713697146971569716697176971869719697206972169722697236972469725697266972769728697296973069731697326973369734697356973669737697386973969740697416974269743697446974569746697476974869749697506975169752697536975469755697566975769758697596976069761697626976369764697656976669767697686976969770697716977269773697746977569776697776977869779697806978169782697836978469785697866978769788697896979069791697926979369794697956979669797697986979969800698016980269803698046980569806698076980869809698106981169812698136981469815698166981769818698196982069821698226982369824698256982669827698286982969830698316983269833698346983569836698376983869839698406984169842698436984469845698466984769848698496985069851698526985369854698556985669857698586985969860698616986269863698646986569866698676986869869698706987169872698736987469875698766987769878698796988069881698826988369884698856988669887698886988969890698916989269893698946989569896698976989869899699006990169902699036990469905699066990769908699096991069911699126991369914699156991669917699186991969920699216992269923699246992569926699276992869929699306993169932699336993469935699366993769938699396994069941699426994369944699456994669947699486994969950699516995269953699546995569956699576995869959699606996169962699636996469965699666996769968699696997069971699726997369974699756997669977699786997969980699816998269983699846998569986699876998869989699906999169992699936999469995699966999769998699997000070001700027000370004700057000670007700087000970010700117001270013700147001570016700177001870019700207002170022700237002470025700267002770028700297003070031700327003370034700357003670037700387003970040700417004270043700447004570046700477004870049700507005170052700537005470055700567005770058700597006070061700627006370064700657006670067700687006970070700717007270073700747007570076700777007870079700807008170082700837008470085700867008770088700897009070091700927009370094700957009670097700987009970100701017010270103701047010570106701077010870109701107011170112701137011470115701167011770118701197012070121701227012370124701257012670127701287012970130701317013270133701347013570136701377013870139701407014170142701437014470145701467014770148701497015070151701527015370154701557015670157701587015970160701617016270163701647016570166701677016870169701707017170172701737017470175701767017770178701797018070181701827018370184701857018670187701887018970190701917019270193701947019570196701977019870199702007020170202702037020470205702067020770208702097021070211702127021370214702157021670217702187021970220702217022270223702247022570226702277022870229702307023170232702337023470235702367023770238702397024070241702427024370244702457024670247702487024970250702517025270253702547025570256702577025870259702607026170262702637026470265702667026770268702697027070271702727027370274702757027670277702787027970280702817028270283702847028570286702877028870289702907029170292702937029470295702967029770298702997030070301703027030370304703057030670307703087030970310703117031270313703147031570316703177031870319703207032170322703237032470325703267032770328703297033070331703327033370334703357033670337703387033970340703417034270343703447034570346703477034870349703507035170352703537035470355703567035770358703597036070361703627036370364703657036670367703687036970370703717037270373703747037570376703777037870379703807038170382703837038470385703867038770388703897039070391703927039370394703957039670397703987039970400704017040270403704047040570406704077040870409704107041170412704137041470415704167041770418704197042070421704227042370424704257042670427704287042970430704317043270433704347043570436704377043870439704407044170442704437044470445704467044770448704497045070451704527045370454704557045670457704587045970460704617046270463704647046570466704677046870469704707047170472704737047470475704767047770478704797048070481704827048370484704857048670487704887048970490704917049270493704947049570496704977049870499705007050170502705037050470505705067050770508705097051070511705127051370514705157051670517705187051970520705217052270523705247052570526705277052870529705307053170532705337053470535705367053770538705397054070541705427054370544705457054670547705487054970550705517055270553705547055570556705577055870559705607056170562705637056470565705667056770568705697057070571705727057370574705757057670577705787057970580705817058270583705847058570586705877058870589705907059170592705937059470595705967059770598705997060070601706027060370604706057060670607706087060970610706117061270613706147061570616706177061870619706207062170622706237062470625706267062770628706297063070631706327063370634706357063670637706387063970640706417064270643706447064570646706477064870649706507065170652706537065470655706567065770658706597066070661706627066370664706657066670667706687066970670706717067270673706747067570676706777067870679706807068170682706837068470685706867068770688706897069070691706927069370694706957069670697706987069970700707017070270703707047070570706707077070870709707107071170712707137071470715707167071770718707197072070721707227072370724707257072670727707287072970730707317073270733707347073570736707377073870739707407074170742707437074470745707467074770748707497075070751707527075370754707557075670757707587075970760707617076270763707647076570766707677076870769707707077170772707737077470775707767077770778707797078070781707827078370784707857078670787707887078970790707917079270793707947079570796707977079870799708007080170802708037080470805708067080770808708097081070811708127081370814708157081670817708187081970820708217082270823708247082570826708277082870829708307083170832708337083470835708367083770838708397084070841708427084370844708457084670847708487084970850708517085270853708547085570856708577085870859708607086170862708637086470865708667086770868708697087070871708727087370874708757087670877708787087970880708817088270883708847088570886708877088870889708907089170892708937089470895708967089770898708997090070901709027090370904709057090670907709087090970910709117091270913709147091570916709177091870919709207092170922709237092470925709267092770928709297093070931709327093370934709357093670937709387093970940709417094270943709447094570946709477094870949709507095170952709537095470955709567095770958709597096070961709627096370964709657096670967709687096970970709717097270973709747097570976709777097870979709807098170982709837098470985709867098770988709897099070991709927099370994709957099670997709987099971000710017100271003710047100571006710077100871009710107101171012710137101471015710167101771018710197102071021710227102371024710257102671027710287102971030710317103271033710347103571036710377103871039710407104171042710437104471045710467104771048710497105071051710527105371054710557105671057710587105971060710617106271063710647106571066710677106871069710707107171072710737107471075710767107771078710797108071081710827108371084710857108671087710887108971090710917109271093710947109571096710977109871099711007110171102711037110471105711067110771108711097111071111711127111371114711157111671117711187111971120711217112271123711247112571126711277112871129711307113171132711337113471135711367113771138711397114071141711427114371144711457114671147711487114971150711517115271153711547115571156711577115871159711607116171162711637116471165711667116771168711697117071171711727117371174711757117671177711787117971180711817118271183711847118571186711877118871189711907119171192711937119471195711967119771198711997120071201712027120371204712057120671207712087120971210712117121271213712147121571216712177121871219712207122171222712237122471225712267122771228712297123071231712327123371234712357123671237712387123971240712417124271243712447124571246712477124871249712507125171252712537125471255712567125771258712597126071261712627126371264712657126671267712687126971270712717127271273712747127571276712777127871279712807128171282712837128471285712867128771288712897129071291712927129371294712957129671297712987129971300713017130271303713047130571306713077130871309713107131171312713137131471315713167131771318713197132071321713227132371324713257132671327713287132971330713317133271333713347133571336713377133871339713407134171342713437134471345713467134771348713497135071351713527135371354713557135671357713587135971360713617136271363713647136571366713677136871369713707137171372713737137471375713767137771378713797138071381713827138371384713857138671387713887138971390713917139271393713947139571396713977139871399714007140171402714037140471405714067140771408714097141071411714127141371414714157141671417714187141971420714217142271423714247142571426714277142871429714307143171432714337143471435714367143771438714397144071441714427144371444714457144671447714487144971450714517145271453714547145571456714577145871459714607146171462714637146471465714667146771468714697147071471714727147371474714757147671477714787147971480714817148271483714847148571486714877148871489714907149171492714937149471495714967149771498714997150071501715027150371504715057150671507715087150971510715117151271513715147151571516715177151871519715207152171522715237152471525715267152771528715297153071531715327153371534715357153671537715387153971540715417154271543715447154571546715477154871549715507155171552715537155471555715567155771558715597156071561715627156371564715657156671567715687156971570715717157271573715747157571576715777157871579715807158171582715837158471585715867158771588715897159071591715927159371594715957159671597715987159971600716017160271603716047160571606716077160871609716107161171612716137161471615716167161771618716197162071621716227162371624716257162671627716287162971630716317163271633716347163571636716377163871639716407164171642716437164471645716467164771648716497165071651716527165371654716557165671657716587165971660716617166271663716647166571666716677166871669716707167171672716737167471675716767167771678716797168071681716827168371684716857168671687716887168971690716917169271693716947169571696716977169871699717007170171702717037170471705717067170771708717097171071711717127171371714717157171671717717187171971720717217172271723717247172571726717277172871729717307173171732717337173471735717367173771738717397174071741717427174371744717457174671747717487174971750717517175271753717547175571756717577175871759717607176171762717637176471765717667176771768717697177071771717727177371774717757177671777717787177971780717817178271783717847178571786717877178871789717907179171792717937179471795717967179771798717997180071801718027180371804718057180671807718087180971810718117181271813718147181571816718177181871819718207182171822718237182471825718267182771828718297183071831718327183371834718357183671837718387183971840718417184271843718447184571846718477184871849718507185171852718537185471855718567185771858718597186071861718627186371864718657186671867718687186971870718717187271873718747187571876718777187871879718807188171882718837188471885718867188771888718897189071891718927189371894718957189671897718987189971900719017190271903719047190571906719077190871909719107191171912719137191471915719167191771918719197192071921719227192371924719257192671927719287192971930719317193271933719347193571936719377193871939719407194171942719437194471945719467194771948719497195071951719527195371954719557195671957719587195971960719617196271963719647196571966719677196871969719707197171972719737197471975719767197771978719797198071981719827198371984719857198671987719887198971990719917199271993719947199571996719977199871999720007200172002720037200472005720067200772008720097201072011720127201372014720157201672017720187201972020720217202272023720247202572026720277202872029720307203172032720337203472035720367203772038720397204072041720427204372044720457204672047720487204972050720517205272053720547205572056720577205872059720607206172062720637206472065720667206772068720697207072071720727207372074720757207672077720787207972080720817208272083720847208572086720877208872089720907209172092720937209472095720967209772098720997210072101721027210372104721057210672107721087210972110721117211272113721147211572116721177211872119721207212172122721237212472125721267212772128721297213072131721327213372134721357213672137721387213972140721417214272143721447214572146721477214872149721507215172152721537215472155721567215772158721597216072161721627216372164721657216672167721687216972170721717217272173721747217572176721777217872179721807218172182721837218472185721867218772188721897219072191721927219372194721957219672197721987219972200722017220272203722047220572206722077220872209722107221172212722137221472215722167221772218722197222072221722227222372224722257222672227722287222972230722317223272233722347223572236722377223872239722407224172242722437224472245722467224772248722497225072251722527225372254722557225672257722587225972260722617226272263722647226572266722677226872269722707227172272722737227472275722767227772278722797228072281722827228372284722857228672287722887228972290722917229272293722947229572296722977229872299723007230172302723037230472305723067230772308723097231072311723127231372314723157231672317723187231972320723217232272323723247232572326723277232872329723307233172332723337233472335723367233772338723397234072341723427234372344723457234672347723487234972350723517235272353723547235572356723577235872359723607236172362723637236472365723667236772368723697237072371723727237372374723757237672377723787237972380723817238272383723847238572386723877238872389723907239172392723937239472395723967239772398723997240072401724027240372404724057240672407724087240972410724117241272413724147241572416724177241872419724207242172422724237242472425724267242772428724297243072431724327243372434724357243672437724387243972440724417244272443724447244572446724477244872449724507245172452724537245472455724567245772458724597246072461724627246372464724657246672467724687246972470724717247272473724747247572476724777247872479724807248172482724837248472485724867248772488724897249072491724927249372494724957249672497724987249972500725017250272503725047250572506725077250872509725107251172512725137251472515725167251772518725197252072521725227252372524725257252672527725287252972530725317253272533725347253572536725377253872539725407254172542725437254472545725467254772548725497255072551725527255372554725557255672557725587255972560725617256272563725647256572566725677256872569725707257172572725737257472575725767257772578725797258072581725827258372584725857258672587725887258972590725917259272593725947259572596725977259872599726007260172602726037260472605726067260772608726097261072611726127261372614726157261672617726187261972620726217262272623726247262572626726277262872629726307263172632726337263472635726367263772638726397264072641726427264372644726457264672647726487264972650726517265272653726547265572656726577265872659726607266172662726637266472665726667266772668726697267072671726727267372674726757267672677726787267972680726817268272683726847268572686726877268872689726907269172692726937269472695726967269772698726997270072701727027270372704727057270672707727087270972710727117271272713727147271572716727177271872719727207272172722727237272472725727267272772728727297273072731727327273372734727357273672737727387273972740727417274272743727447274572746727477274872749727507275172752727537275472755727567275772758727597276072761727627276372764727657276672767727687276972770727717277272773727747277572776727777277872779727807278172782727837278472785727867278772788727897279072791727927279372794727957279672797727987279972800728017280272803728047280572806728077280872809728107281172812728137281472815728167281772818728197282072821728227282372824728257282672827728287282972830728317283272833728347283572836728377283872839728407284172842728437284472845728467284772848728497285072851728527285372854728557285672857728587285972860728617286272863728647286572866728677286872869728707287172872728737287472875728767287772878728797288072881728827288372884728857288672887728887288972890728917289272893728947289572896728977289872899729007290172902729037290472905729067290772908729097291072911729127291372914729157291672917729187291972920729217292272923729247292572926729277292872929729307293172932729337293472935729367293772938729397294072941729427294372944729457294672947729487294972950729517295272953729547295572956729577295872959729607296172962729637296472965729667296772968729697297072971729727297372974729757297672977729787297972980729817298272983729847298572986729877298872989729907299172992729937299472995729967299772998729997300073001730027300373004730057300673007730087300973010730117301273013730147301573016730177301873019730207302173022730237302473025730267302773028730297303073031730327303373034730357303673037730387303973040730417304273043730447304573046730477304873049730507305173052730537305473055730567305773058730597306073061730627306373064730657306673067730687306973070730717307273073730747307573076730777307873079730807308173082730837308473085730867308773088730897309073091730927309373094730957309673097730987309973100731017310273103731047310573106731077310873109731107311173112731137311473115731167311773118731197312073121731227312373124731257312673127731287312973130731317313273133731347313573136731377313873139731407314173142731437314473145731467314773148731497315073151731527315373154731557315673157731587315973160731617316273163731647316573166731677316873169731707317173172731737317473175731767317773178731797318073181731827318373184731857318673187731887318973190731917319273193731947319573196731977319873199732007320173202732037320473205732067320773208732097321073211732127321373214732157321673217732187321973220732217322273223732247322573226732277322873229732307323173232732337323473235732367323773238732397324073241732427324373244732457324673247732487324973250732517325273253732547325573256732577325873259732607326173262732637326473265732667326773268732697327073271732727327373274732757327673277732787327973280732817328273283732847328573286732877328873289732907329173292732937329473295732967329773298732997330073301733027330373304733057330673307733087330973310733117331273313733147331573316733177331873319733207332173322733237332473325733267332773328733297333073331733327333373334733357333673337733387333973340733417334273343733447334573346733477334873349733507335173352733537335473355733567335773358733597336073361733627336373364733657336673367733687336973370733717337273373733747337573376733777337873379733807338173382733837338473385733867338773388733897339073391733927339373394733957339673397733987339973400734017340273403734047340573406734077340873409734107341173412734137341473415734167341773418734197342073421734227342373424734257342673427734287342973430734317343273433734347343573436734377343873439734407344173442734437344473445734467344773448734497345073451734527345373454734557345673457734587345973460734617346273463734647346573466734677346873469734707347173472734737347473475734767347773478734797348073481734827348373484734857348673487734887348973490734917349273493734947349573496734977349873499735007350173502735037350473505735067350773508735097351073511735127351373514735157351673517735187351973520735217352273523735247352573526735277352873529735307353173532735337353473535735367353773538735397354073541735427354373544735457354673547735487354973550735517355273553735547355573556735577355873559735607356173562735637356473565735667356773568735697357073571735727357373574735757357673577735787357973580735817358273583735847358573586735877358873589735907359173592735937359473595735967359773598735997360073601736027360373604736057360673607736087360973610736117361273613736147361573616736177361873619736207362173622736237362473625736267362773628736297363073631736327363373634736357363673637736387363973640736417364273643736447364573646736477364873649736507365173652736537365473655736567365773658736597366073661736627366373664736657366673667736687366973670736717367273673736747367573676736777367873679736807368173682736837368473685736867368773688736897369073691736927369373694736957369673697736987369973700737017370273703737047370573706737077370873709737107371173712737137371473715737167371773718737197372073721737227372373724737257372673727737287372973730737317373273733737347373573736737377373873739737407374173742737437374473745737467374773748737497375073751737527375373754737557375673757737587375973760737617376273763737647376573766737677376873769737707377173772737737377473775737767377773778737797378073781737827378373784737857378673787737887378973790737917379273793737947379573796737977379873799738007380173802738037380473805738067380773808738097381073811738127381373814738157381673817738187381973820738217382273823738247382573826738277382873829738307383173832738337383473835738367383773838738397384073841738427384373844738457384673847738487384973850738517385273853738547385573856738577385873859738607386173862738637386473865738667386773868738697387073871738727387373874738757387673877738787387973880738817388273883738847388573886738877388873889738907389173892738937389473895738967389773898738997390073901739027390373904739057390673907739087390973910739117391273913739147391573916739177391873919739207392173922739237392473925739267392773928739297393073931739327393373934739357393673937739387393973940739417394273943739447394573946739477394873949739507395173952739537395473955739567395773958739597396073961739627396373964739657396673967739687396973970739717397273973739747397573976739777397873979739807398173982739837398473985739867398773988739897399073991739927399373994739957399673997739987399974000740017400274003740047400574006740077400874009740107401174012740137401474015740167401774018740197402074021740227402374024740257402674027740287402974030740317403274033740347403574036740377403874039740407404174042740437404474045740467404774048740497405074051740527405374054740557405674057740587405974060740617406274063740647406574066740677406874069740707407174072740737407474075740767407774078740797408074081740827408374084740857408674087740887408974090740917409274093740947409574096740977409874099741007410174102741037410474105741067410774108741097411074111741127411374114741157411674117741187411974120741217412274123741247412574126741277412874129741307413174132741337413474135741367413774138741397414074141741427414374144741457414674147741487414974150741517415274153741547415574156741577415874159741607416174162741637416474165741667416774168741697417074171741727417374174741757417674177741787417974180741817418274183741847418574186741877418874189741907419174192741937419474195741967419774198741997420074201742027420374204742057420674207742087420974210742117421274213742147421574216742177421874219742207422174222742237422474225742267422774228742297423074231742327423374234742357423674237742387423974240742417424274243742447424574246742477424874249742507425174252742537425474255742567425774258742597426074261742627426374264742657426674267742687426974270742717427274273742747427574276742777427874279742807428174282742837428474285742867428774288742897429074291742927429374294742957429674297742987429974300743017430274303743047430574306743077430874309743107431174312743137431474315743167431774318743197432074321743227432374324743257432674327743287432974330743317433274333743347433574336743377433874339743407434174342743437434474345743467434774348743497435074351743527435374354743557435674357743587435974360743617436274363743647436574366743677436874369743707437174372743737437474375743767437774378743797438074381743827438374384743857438674387743887438974390743917439274393743947439574396743977439874399744007440174402744037440474405744067440774408744097441074411744127441374414744157441674417744187441974420744217442274423744247442574426744277442874429744307443174432744337443474435744367443774438744397444074441744427444374444744457444674447744487444974450744517445274453744547445574456744577445874459744607446174462744637446474465744667446774468744697447074471744727447374474744757447674477744787447974480744817448274483744847448574486744877448874489744907449174492744937449474495744967449774498744997450074501745027450374504745057450674507745087450974510745117451274513745147451574516745177451874519745207452174522745237452474525745267452774528745297453074531745327453374534745357453674537745387453974540745417454274543745447454574546745477454874549745507455174552745537455474555745567455774558745597456074561745627456374564745657456674567745687456974570745717457274573745747457574576745777457874579745807458174582745837458474585745867458774588745897459074591745927459374594745957459674597745987459974600746017460274603746047460574606746077460874609746107461174612746137461474615746167461774618746197462074621746227462374624746257462674627746287462974630746317463274633746347463574636746377463874639746407464174642746437464474645746467464774648746497465074651746527465374654746557465674657746587465974660746617466274663746647466574666746677466874669746707467174672746737467474675746767467774678746797468074681746827468374684746857468674687746887468974690746917469274693746947469574696746977469874699747007470174702747037470474705747067470774708747097471074711747127471374714747157471674717747187471974720747217472274723747247472574726747277472874729747307473174732747337473474735747367473774738747397474074741747427474374744747457474674747747487474974750747517475274753747547475574756747577475874759747607476174762747637476474765747667476774768747697477074771747727477374774747757477674777747787477974780747817478274783747847478574786747877478874789747907479174792747937479474795747967479774798747997480074801748027480374804748057480674807748087480974810748117481274813748147481574816748177481874819748207482174822748237482474825748267482774828748297483074831748327483374834748357483674837748387483974840748417484274843748447484574846748477484874849748507485174852748537485474855748567485774858748597486074861748627486374864748657486674867748687486974870748717487274873748747487574876748777487874879748807488174882748837488474885748867488774888748897489074891748927489374894748957489674897748987489974900749017490274903749047490574906749077490874909749107491174912749137491474915749167491774918749197492074921749227492374924749257492674927749287492974930749317493274933749347493574936749377493874939749407494174942749437494474945749467494774948749497495074951749527495374954749557495674957749587495974960749617496274963749647496574966749677496874969749707497174972749737497474975749767497774978749797498074981749827498374984749857498674987749887498974990749917499274993749947499574996749977499874999750007500175002750037500475005750067500775008750097501075011750127501375014750157501675017750187501975020750217502275023750247502575026750277502875029750307503175032750337503475035750367503775038750397504075041750427504375044750457504675047750487504975050750517505275053750547505575056750577505875059750607506175062750637506475065750667506775068750697507075071750727507375074750757507675077750787507975080750817508275083750847508575086750877508875089750907509175092750937509475095750967509775098750997510075101751027510375104751057510675107751087510975110751117511275113751147511575116751177511875119751207512175122751237512475125751267512775128751297513075131751327513375134751357513675137751387513975140751417514275143751447514575146751477514875149751507515175152751537515475155751567515775158751597516075161751627516375164751657516675167751687516975170751717517275173751747517575176751777517875179751807518175182751837518475185751867518775188751897519075191751927519375194751957519675197751987519975200752017520275203752047520575206752077520875209752107521175212752137521475215752167521775218752197522075221752227522375224752257522675227752287522975230752317523275233752347523575236752377523875239752407524175242752437524475245752467524775248752497525075251752527525375254752557525675257752587525975260752617526275263752647526575266752677526875269752707527175272752737527475275752767527775278752797528075281752827528375284752857528675287752887528975290752917529275293752947529575296752977529875299753007530175302753037530475305753067530775308753097531075311753127531375314753157531675317753187531975320753217532275323753247532575326753277532875329753307533175332753337533475335753367533775338753397534075341753427534375344753457534675347753487534975350753517535275353753547535575356753577535875359753607536175362753637536475365753667536775368753697537075371753727537375374753757537675377753787537975380753817538275383753847538575386753877538875389753907539175392753937539475395753967539775398753997540075401754027540375404754057540675407754087540975410754117541275413754147541575416754177541875419754207542175422754237542475425754267542775428754297543075431754327543375434754357543675437754387543975440754417544275443754447544575446754477544875449754507545175452754537545475455754567545775458754597546075461754627546375464754657546675467754687546975470754717547275473754747547575476754777547875479754807548175482754837548475485754867548775488754897549075491754927549375494754957549675497754987549975500755017550275503755047550575506755077550875509755107551175512755137551475515755167551775518755197552075521755227552375524755257552675527755287552975530755317553275533755347553575536755377553875539755407554175542755437554475545755467554775548755497555075551755527555375554755557555675557755587555975560755617556275563755647556575566755677556875569755707557175572755737557475575755767557775578755797558075581755827558375584755857558675587755887558975590755917559275593755947559575596755977559875599756007560175602756037560475605756067560775608756097561075611756127561375614756157561675617756187561975620756217562275623756247562575626756277562875629756307563175632756337563475635756367563775638756397564075641756427564375644756457564675647756487564975650756517565275653756547565575656756577565875659756607566175662756637566475665756667566775668756697567075671756727567375674756757567675677756787567975680756817568275683756847568575686756877568875689756907569175692756937569475695756967569775698756997570075701757027570375704757057570675707757087570975710757117571275713757147571575716757177571875719757207572175722757237572475725757267572775728757297573075731757327573375734757357573675737757387573975740757417574275743757447574575746757477574875749757507575175752757537575475755757567575775758757597576075761757627576375764757657576675767757687576975770757717577275773757747577575776757777577875779757807578175782757837578475785757867578775788757897579075791757927579375794757957579675797757987579975800758017580275803758047580575806758077580875809758107581175812758137581475815758167581775818758197582075821758227582375824758257582675827758287582975830758317583275833758347583575836758377583875839758407584175842758437584475845758467584775848758497585075851758527585375854758557585675857758587585975860758617586275863758647586575866758677586875869758707587175872758737587475875758767587775878758797588075881758827588375884758857588675887758887588975890758917589275893758947589575896758977589875899759007590175902759037590475905759067590775908759097591075911759127591375914759157591675917759187591975920759217592275923759247592575926759277592875929759307593175932759337593475935759367593775938759397594075941759427594375944759457594675947759487594975950759517595275953759547595575956759577595875959759607596175962759637596475965759667596775968759697597075971759727597375974759757597675977759787597975980759817598275983759847598575986759877598875989759907599175992759937599475995759967599775998759997600076001760027600376004760057600676007760087600976010760117601276013760147601576016760177601876019760207602176022760237602476025760267602776028760297603076031760327603376034760357603676037760387603976040760417604276043760447604576046760477604876049760507605176052760537605476055760567605776058760597606076061760627606376064760657606676067760687606976070760717607276073760747607576076760777607876079760807608176082760837608476085760867608776088760897609076091760927609376094760957609676097760987609976100761017610276103761047610576106761077610876109761107611176112761137611476115761167611776118761197612076121761227612376124761257612676127761287612976130761317613276133761347613576136761377613876139761407614176142761437614476145761467614776148761497615076151761527615376154761557615676157761587615976160761617616276163761647616576166761677616876169761707617176172761737617476175761767617776178761797618076181761827618376184761857618676187761887618976190761917619276193761947619576196761977619876199762007620176202762037620476205762067620776208762097621076211762127621376214762157621676217762187621976220762217622276223762247622576226762277622876229762307623176232762337623476235762367623776238762397624076241762427624376244762457624676247762487624976250762517625276253762547625576256762577625876259762607626176262762637626476265762667626776268762697627076271762727627376274762757627676277762787627976280762817628276283762847628576286762877628876289762907629176292762937629476295762967629776298762997630076301763027630376304763057630676307763087630976310763117631276313763147631576316763177631876319763207632176322763237632476325763267632776328763297633076331763327633376334763357633676337763387633976340763417634276343763447634576346763477634876349763507635176352763537635476355763567635776358763597636076361763627636376364763657636676367763687636976370763717637276373763747637576376763777637876379763807638176382763837638476385763867638776388763897639076391763927639376394763957639676397763987639976400764017640276403764047640576406764077640876409764107641176412764137641476415764167641776418764197642076421764227642376424764257642676427764287642976430764317643276433764347643576436764377643876439764407644176442764437644476445764467644776448764497645076451764527645376454764557645676457764587645976460764617646276463764647646576466764677646876469764707647176472764737647476475764767647776478764797648076481764827648376484764857648676487764887648976490764917649276493764947649576496764977649876499765007650176502765037650476505765067650776508765097651076511765127651376514765157651676517765187651976520765217652276523765247652576526765277652876529765307653176532765337653476535765367653776538765397654076541765427654376544765457654676547765487654976550765517655276553765547655576556765577655876559765607656176562765637656476565765667656776568765697657076571765727657376574765757657676577765787657976580765817658276583765847658576586765877658876589765907659176592765937659476595765967659776598765997660076601766027660376604766057660676607766087660976610766117661276613766147661576616766177661876619766207662176622766237662476625766267662776628766297663076631766327663376634766357663676637766387663976640766417664276643766447664576646766477664876649766507665176652766537665476655766567665776658766597666076661766627666376664766657666676667766687666976670766717667276673766747667576676766777667876679766807668176682766837668476685766867668776688766897669076691766927669376694766957669676697766987669976700767017670276703767047670576706767077670876709767107671176712767137671476715767167671776718767197672076721767227672376724767257672676727767287672976730767317673276733767347673576736767377673876739767407674176742767437674476745767467674776748767497675076751767527675376754767557675676757767587675976760767617676276763767647676576766767677676876769767707677176772767737677476775767767677776778767797678076781767827678376784767857678676787767887678976790767917679276793767947679576796767977679876799768007680176802768037680476805768067680776808768097681076811768127681376814768157681676817768187681976820768217682276823768247682576826768277682876829768307683176832768337683476835768367683776838768397684076841768427684376844768457684676847768487684976850768517685276853768547685576856768577685876859768607686176862768637686476865768667686776868768697687076871768727687376874768757687676877768787687976880768817688276883768847688576886768877688876889768907689176892768937689476895768967689776898768997690076901769027690376904769057690676907769087690976910769117691276913769147691576916769177691876919769207692176922769237692476925769267692776928769297693076931769327693376934769357693676937769387693976940769417694276943769447694576946769477694876949769507695176952769537695476955769567695776958769597696076961769627696376964769657696676967769687696976970769717697276973769747697576976769777697876979769807698176982769837698476985769867698776988769897699076991769927699376994769957699676997769987699977000770017700277003770047700577006770077700877009770107701177012770137701477015770167701777018770197702077021770227702377024770257702677027770287702977030770317703277033770347703577036770377703877039770407704177042770437704477045770467704777048770497705077051770527705377054770557705677057770587705977060770617706277063770647706577066770677706877069770707707177072770737707477075770767707777078770797708077081770827708377084770857708677087770887708977090770917709277093770947709577096770977709877099771007710177102771037710477105771067710777108771097711077111771127711377114771157711677117771187711977120771217712277123771247712577126771277712877129771307713177132771337713477135771367713777138771397714077141771427714377144771457714677147771487714977150771517715277153771547715577156771577715877159771607716177162771637716477165771667716777168771697717077171771727717377174771757717677177771787717977180771817718277183771847718577186771877718877189771907719177192771937719477195771967719777198771997720077201772027720377204772057720677207772087720977210772117721277213772147721577216772177721877219772207722177222772237722477225772267722777228772297723077231772327723377234772357723677237772387723977240772417724277243772447724577246772477724877249772507725177252772537725477255772567725777258772597726077261772627726377264772657726677267772687726977270772717727277273772747727577276772777727877279772807728177282772837728477285772867728777288772897729077291772927729377294772957729677297772987729977300773017730277303773047730577306773077730877309773107731177312773137731477315773167731777318773197732077321773227732377324773257732677327773287732977330773317733277333773347733577336773377733877339773407734177342773437734477345773467734777348773497735077351773527735377354773557735677357773587735977360773617736277363773647736577366773677736877369773707737177372773737737477375773767737777378773797738077381773827738377384773857738677387773887738977390773917739277393773947739577396773977739877399774007740177402774037740477405774067740777408774097741077411774127741377414774157741677417774187741977420774217742277423774247742577426774277742877429774307743177432774337743477435774367743777438774397744077441774427744377444774457744677447774487744977450774517745277453774547745577456774577745877459774607746177462774637746477465774667746777468774697747077471774727747377474774757747677477774787747977480774817748277483774847748577486774877748877489774907749177492774937749477495774967749777498774997750077501775027750377504775057750677507775087750977510775117751277513775147751577516775177751877519775207752177522775237752477525775267752777528775297753077531775327753377534775357753677537775387753977540775417754277543775447754577546775477754877549775507755177552775537755477555775567755777558775597756077561775627756377564775657756677567775687756977570775717757277573775747757577576775777757877579775807758177582775837758477585775867758777588775897759077591775927759377594775957759677597775987759977600776017760277603776047760577606776077760877609776107761177612776137761477615776167761777618776197762077621776227762377624776257762677627776287762977630776317763277633776347763577636776377763877639776407764177642776437764477645776467764777648776497765077651776527765377654776557765677657776587765977660776617766277663776647766577666776677766877669776707767177672776737767477675776767767777678776797768077681776827768377684776857768677687776887768977690776917769277693776947769577696776977769877699777007770177702777037770477705777067770777708777097771077711777127771377714777157771677717777187771977720777217772277723777247772577726777277772877729777307773177732777337773477735777367773777738777397774077741777427774377744777457774677747777487774977750777517775277753777547775577756777577775877759777607776177762777637776477765777667776777768777697777077771777727777377774777757777677777777787777977780777817778277783777847778577786777877778877789777907779177792777937779477795777967779777798777997780077801778027780377804778057780677807778087780977810778117781277813778147781577816778177781877819778207782177822778237782477825778267782777828778297783077831778327783377834778357783677837778387783977840778417784277843778447784577846778477784877849778507785177852778537785477855778567785777858778597786077861778627786377864778657786677867778687786977870778717787277873778747787577876778777787877879778807788177882778837788477885778867788777888778897789077891778927789377894778957789677897778987789977900779017790277903779047790577906779077790877909779107791177912779137791477915779167791777918779197792077921779227792377924779257792677927779287792977930779317793277933779347793577936779377793877939779407794177942779437794477945779467794777948779497795077951779527795377954779557795677957779587795977960779617796277963779647796577966779677796877969779707797177972779737797477975779767797777978779797798077981779827798377984779857798677987779887798977990779917799277993779947799577996779977799877999780007800178002780037800478005780067800778008780097801078011780127801378014780157801678017780187801978020780217802278023780247802578026780277802878029780307803178032780337803478035780367803778038780397804078041780427804378044780457804678047780487804978050780517805278053780547805578056780577805878059780607806178062780637806478065780667806778068780697807078071780727807378074780757807678077780787807978080780817808278083780847808578086780877808878089780907809178092780937809478095780967809778098780997810078101781027810378104781057810678107781087810978110781117811278113781147811578116781177811878119781207812178122781237812478125781267812778128781297813078131781327813378134781357813678137781387813978140781417814278143781447814578146781477814878149781507815178152781537815478155781567815778158781597816078161781627816378164781657816678167781687816978170781717817278173781747817578176781777817878179781807818178182781837818478185781867818778188781897819078191781927819378194781957819678197781987819978200782017820278203782047820578206782077820878209782107821178212782137821478215782167821778218782197822078221782227822378224782257822678227782287822978230782317823278233782347823578236782377823878239782407824178242782437824478245782467824778248782497825078251782527825378254782557825678257782587825978260782617826278263782647826578266782677826878269782707827178272782737827478275782767827778278782797828078281782827828378284782857828678287782887828978290782917829278293782947829578296782977829878299783007830178302783037830478305783067830778308783097831078311783127831378314783157831678317783187831978320783217832278323783247832578326783277832878329783307833178332783337833478335783367833778338783397834078341783427834378344783457834678347783487834978350783517835278353783547835578356783577835878359783607836178362783637836478365783667836778368783697837078371783727837378374783757837678377783787837978380783817838278383783847838578386783877838878389783907839178392783937839478395783967839778398783997840078401784027840378404784057840678407784087840978410784117841278413784147841578416784177841878419784207842178422784237842478425784267842778428784297843078431784327843378434784357843678437784387843978440784417844278443784447844578446784477844878449784507845178452784537845478455784567845778458784597846078461784627846378464784657846678467784687846978470784717847278473784747847578476784777847878479784807848178482784837848478485784867848778488784897849078491784927849378494784957849678497784987849978500785017850278503785047850578506785077850878509785107851178512785137851478515785167851778518785197852078521785227852378524785257852678527785287852978530785317853278533785347853578536785377853878539785407854178542785437854478545785467854778548785497855078551785527855378554785557855678557785587855978560785617856278563785647856578566785677856878569785707857178572785737857478575785767857778578785797858078581785827858378584785857858678587785887858978590785917859278593785947859578596785977859878599786007860178602786037860478605786067860778608786097861078611786127861378614786157861678617786187861978620786217862278623786247862578626786277862878629786307863178632786337863478635786367863778638786397864078641786427864378644786457864678647786487864978650786517865278653786547865578656786577865878659786607866178662786637866478665786667866778668786697867078671786727867378674786757867678677786787867978680786817868278683786847868578686786877868878689786907869178692786937869478695786967869778698786997870078701787027870378704787057870678707787087870978710787117871278713787147871578716787177871878719787207872178722787237872478725787267872778728787297873078731787327873378734787357873678737787387873978740787417874278743787447874578746787477874878749787507875178752787537875478755787567875778758787597876078761787627876378764787657876678767787687876978770787717877278773787747877578776787777877878779787807878178782787837878478785787867878778788787897879078791787927879378794787957879678797787987879978800788017880278803788047880578806788077880878809788107881178812788137881478815788167881778818788197882078821788227882378824788257882678827788287882978830788317883278833788347883578836788377883878839788407884178842788437884478845788467884778848788497885078851788527885378854788557885678857788587885978860788617886278863788647886578866788677886878869788707887178872788737887478875788767887778878788797888078881788827888378884788857888678887788887888978890788917889278893788947889578896788977889878899789007890178902789037890478905789067890778908789097891078911789127891378914789157891678917789187891978920789217892278923789247892578926789277892878929789307893178932789337893478935789367893778938789397894078941789427894378944789457894678947789487894978950789517895278953789547895578956789577895878959789607896178962789637896478965789667896778968789697897078971789727897378974789757897678977789787897978980789817898278983789847898578986789877898878989789907899178992789937899478995789967899778998789997900079001790027900379004790057900679007790087900979010790117901279013790147901579016790177901879019790207902179022790237902479025790267902779028790297903079031790327903379034790357903679037790387903979040790417904279043790447904579046790477904879049790507905179052790537905479055790567905779058790597906079061790627906379064790657906679067790687906979070790717907279073790747907579076790777907879079790807908179082790837908479085790867908779088790897909079091790927909379094790957909679097790987909979100791017910279103791047910579106791077910879109791107911179112791137911479115791167911779118791197912079121791227912379124791257912679127791287912979130791317913279133791347913579136791377913879139791407914179142791437914479145791467914779148791497915079151791527915379154791557915679157791587915979160791617916279163791647916579166791677916879169791707917179172791737917479175791767917779178791797918079181791827918379184791857918679187791887918979190791917919279193791947919579196791977919879199792007920179202792037920479205792067920779208792097921079211792127921379214792157921679217792187921979220792217922279223792247922579226792277922879229792307923179232792337923479235792367923779238792397924079241792427924379244792457924679247792487924979250792517925279253792547925579256792577925879259792607926179262792637926479265792667926779268792697927079271792727927379274792757927679277792787927979280792817928279283792847928579286792877928879289792907929179292792937929479295792967929779298792997930079301793027930379304793057930679307793087930979310793117931279313793147931579316793177931879319793207932179322793237932479325793267932779328793297933079331793327933379334793357933679337793387933979340793417934279343793447934579346793477934879349793507935179352793537935479355793567935779358793597936079361793627936379364793657936679367793687936979370793717937279373793747937579376793777937879379793807938179382793837938479385793867938779388793897939079391793927939379394793957939679397793987939979400794017940279403794047940579406794077940879409794107941179412794137941479415794167941779418794197942079421794227942379424794257942679427794287942979430794317943279433794347943579436794377943879439794407944179442794437944479445794467944779448794497945079451794527945379454794557945679457794587945979460794617946279463794647946579466794677946879469794707947179472794737947479475794767947779478794797948079481794827948379484794857948679487794887948979490794917949279493794947949579496794977949879499795007950179502795037950479505795067950779508795097951079511795127951379514795157951679517795187951979520795217952279523795247952579526795277952879529795307953179532795337953479535795367953779538795397954079541795427954379544795457954679547795487954979550795517955279553795547955579556795577955879559795607956179562795637956479565795667956779568795697957079571795727957379574795757957679577795787957979580795817958279583795847958579586795877958879589795907959179592795937959479595795967959779598795997960079601796027960379604796057960679607796087960979610796117961279613796147961579616796177961879619796207962179622796237962479625796267962779628796297963079631796327963379634796357963679637796387963979640796417964279643796447964579646796477964879649796507965179652796537965479655796567965779658796597966079661796627966379664796657966679667796687966979670796717967279673796747967579676796777967879679796807968179682796837968479685796867968779688796897969079691796927969379694796957969679697796987969979700797017970279703797047970579706797077970879709797107971179712797137971479715797167971779718797197972079721797227972379724797257972679727797287972979730797317973279733797347973579736797377973879739797407974179742797437974479745797467974779748797497975079751797527975379754797557975679757797587975979760797617976279763797647976579766797677976879769797707977179772797737977479775797767977779778797797978079781797827978379784797857978679787797887978979790797917979279793797947979579796797977979879799798007980179802798037980479805798067980779808798097981079811798127981379814798157981679817798187981979820798217982279823798247982579826798277982879829798307983179832798337983479835798367983779838798397984079841798427984379844798457984679847798487984979850798517985279853798547985579856798577985879859798607986179862798637986479865798667986779868798697987079871798727987379874798757987679877798787987979880798817988279883798847988579886798877988879889798907989179892798937989479895798967989779898798997990079901799027990379904799057990679907799087990979910799117991279913799147991579916799177991879919799207992179922799237992479925799267992779928799297993079931799327993379934799357993679937799387993979940799417994279943799447994579946799477994879949799507995179952799537995479955799567995779958799597996079961799627996379964799657996679967799687996979970799717997279973799747997579976799777997879979799807998179982799837998479985799867998779988799897999079991799927999379994799957999679997799987999980000800018000280003800048000580006800078000880009800108001180012800138001480015800168001780018800198002080021800228002380024800258002680027800288002980030800318003280033800348003580036800378003880039800408004180042800438004480045800468004780048800498005080051800528005380054800558005680057800588005980060800618006280063800648006580066800678006880069800708007180072800738007480075800768007780078800798008080081800828008380084800858008680087800888008980090800918009280093800948009580096800978009880099801008010180102801038010480105801068010780108801098011080111801128011380114801158011680117801188011980120801218012280123801248012580126801278012880129801308013180132801338013480135801368013780138801398014080141801428014380144801458014680147801488014980150801518015280153801548015580156801578015880159801608016180162801638016480165801668016780168801698017080171801728017380174801758017680177801788017980180801818018280183801848018580186801878018880189801908019180192801938019480195801968019780198801998020080201802028020380204802058020680207802088020980210802118021280213802148021580216802178021880219802208022180222802238022480225802268022780228802298023080231802328023380234802358023680237802388023980240802418024280243802448024580246802478024880249802508025180252802538025480255802568025780258802598026080261802628026380264802658026680267802688026980270802718027280273802748027580276802778027880279802808028180282802838028480285802868028780288802898029080291802928029380294802958029680297802988029980300803018030280303803048030580306803078030880309803108031180312803138031480315803168031780318803198032080321803228032380324803258032680327803288032980330803318033280333803348033580336803378033880339803408034180342803438034480345803468034780348803498035080351803528035380354803558035680357803588035980360803618036280363803648036580366803678036880369803708037180372803738037480375803768037780378803798038080381803828038380384803858038680387803888038980390803918039280393803948039580396803978039880399804008040180402804038040480405804068040780408804098041080411804128041380414804158041680417804188041980420804218042280423804248042580426804278042880429804308043180432804338043480435804368043780438804398044080441804428044380444804458044680447804488044980450804518045280453804548045580456804578045880459804608046180462804638046480465804668046780468804698047080471804728047380474804758047680477804788047980480804818048280483804848048580486804878048880489804908049180492804938049480495804968049780498804998050080501805028050380504805058050680507805088050980510805118051280513805148051580516805178051880519805208052180522805238052480525805268052780528805298053080531805328053380534805358053680537805388053980540805418054280543805448054580546805478054880549805508055180552805538055480555805568055780558805598056080561805628056380564805658056680567805688056980570805718057280573805748057580576805778057880579805808058180582805838058480585805868058780588805898059080591805928059380594805958059680597805988059980600806018060280603806048060580606806078060880609806108061180612806138061480615806168061780618806198062080621806228062380624806258062680627806288062980630806318063280633806348063580636806378063880639806408064180642806438064480645806468064780648806498065080651806528065380654806558065680657806588065980660806618066280663806648066580666806678066880669806708067180672806738067480675806768067780678806798068080681806828068380684806858068680687806888068980690806918069280693806948069580696806978069880699807008070180702807038070480705807068070780708807098071080711807128071380714807158071680717807188071980720807218072280723807248072580726807278072880729807308073180732807338073480735807368073780738807398074080741807428074380744807458074680747807488074980750807518075280753807548075580756807578075880759807608076180762807638076480765807668076780768807698077080771807728077380774807758077680777807788077980780807818078280783807848078580786807878078880789807908079180792807938079480795807968079780798807998080080801808028080380804808058080680807808088080980810808118081280813808148081580816808178081880819808208082180822808238082480825808268082780828808298083080831808328083380834808358083680837808388083980840808418084280843808448084580846808478084880849808508085180852808538085480855808568085780858808598086080861808628086380864808658086680867808688086980870808718087280873808748087580876808778087880879808808088180882808838088480885808868088780888808898089080891808928089380894808958089680897808988089980900809018090280903809048090580906809078090880909809108091180912809138091480915809168091780918809198092080921809228092380924809258092680927809288092980930809318093280933809348093580936809378093880939809408094180942809438094480945809468094780948809498095080951809528095380954809558095680957809588095980960809618096280963809648096580966809678096880969809708097180972809738097480975809768097780978809798098080981809828098380984809858098680987809888098980990809918099280993809948099580996809978099880999810008100181002810038100481005810068100781008810098101081011810128101381014810158101681017810188101981020810218102281023810248102581026810278102881029810308103181032810338103481035810368103781038810398104081041810428104381044810458104681047810488104981050810518105281053810548105581056810578105881059810608106181062810638106481065810668106781068810698107081071810728107381074810758107681077810788107981080810818108281083810848108581086810878108881089810908109181092810938109481095810968109781098810998110081101811028110381104811058110681107811088110981110811118111281113811148111581116811178111881119811208112181122811238112481125811268112781128811298113081131811328113381134811358113681137811388113981140811418114281143811448114581146811478114881149811508115181152811538115481155811568115781158811598116081161811628116381164811658116681167811688116981170811718117281173811748117581176811778117881179811808118181182811838118481185811868118781188811898119081191811928119381194811958119681197811988119981200812018120281203812048120581206812078120881209812108121181212812138121481215812168121781218812198122081221812228122381224812258122681227812288122981230812318123281233812348123581236812378123881239812408124181242812438124481245812468124781248812498125081251812528125381254812558125681257812588125981260812618126281263812648126581266812678126881269812708127181272812738127481275812768127781278812798128081281812828128381284812858128681287812888128981290812918129281293812948129581296812978129881299813008130181302813038130481305813068130781308813098131081311813128131381314813158131681317813188131981320813218132281323813248132581326813278132881329813308133181332813338133481335813368133781338813398134081341813428134381344813458134681347813488134981350813518135281353813548135581356813578135881359813608136181362813638136481365813668136781368813698137081371813728137381374813758137681377813788137981380813818138281383813848138581386813878138881389813908139181392813938139481395813968139781398813998140081401814028140381404814058140681407814088140981410814118141281413814148141581416814178141881419814208142181422814238142481425814268142781428814298143081431814328143381434814358143681437814388143981440814418144281443814448144581446814478144881449814508145181452814538145481455814568145781458814598146081461814628146381464814658146681467814688146981470814718147281473814748147581476814778147881479814808148181482814838148481485814868148781488814898149081491814928149381494814958149681497814988149981500815018150281503815048150581506815078150881509815108151181512815138151481515815168151781518815198152081521815228152381524815258152681527815288152981530815318153281533815348153581536815378153881539815408154181542815438154481545815468154781548815498155081551815528155381554815558155681557815588155981560815618156281563815648156581566815678156881569815708157181572815738157481575815768157781578815798158081581815828158381584815858158681587815888158981590815918159281593815948159581596815978159881599816008160181602816038160481605816068160781608816098161081611816128161381614816158161681617816188161981620816218162281623816248162581626816278162881629816308163181632816338163481635816368163781638816398164081641816428164381644816458164681647816488164981650816518165281653816548165581656816578165881659816608166181662816638166481665816668166781668816698167081671816728167381674816758167681677816788167981680816818168281683816848168581686816878168881689816908169181692816938169481695816968169781698816998170081701817028170381704817058170681707817088170981710817118171281713817148171581716817178171881719817208172181722817238172481725817268172781728817298173081731817328173381734817358173681737817388173981740817418174281743817448174581746817478174881749817508175181752817538175481755817568175781758817598176081761817628176381764817658176681767817688176981770817718177281773817748177581776817778177881779817808178181782817838178481785817868178781788817898179081791817928179381794817958179681797817988179981800818018180281803818048180581806818078180881809818108181181812818138181481815818168181781818818198182081821818228182381824818258182681827818288182981830818318183281833818348183581836818378183881839818408184181842818438184481845818468184781848818498185081851818528185381854818558185681857818588185981860818618186281863818648186581866818678186881869818708187181872818738187481875818768187781878818798188081881818828188381884818858188681887818888188981890818918189281893818948189581896818978189881899819008190181902819038190481905819068190781908819098191081911819128191381914819158191681917819188191981920819218192281923819248192581926819278192881929819308193181932819338193481935819368193781938819398194081941819428194381944819458194681947819488194981950819518195281953819548195581956819578195881959819608196181962819638196481965819668196781968819698197081971819728197381974819758197681977819788197981980819818198281983819848198581986819878198881989819908199181992819938199481995819968199781998819998200082001820028200382004820058200682007820088200982010820118201282013820148201582016820178201882019820208202182022820238202482025820268202782028820298203082031820328203382034820358203682037820388203982040820418204282043820448204582046820478204882049820508205182052820538205482055820568205782058820598206082061820628206382064820658206682067820688206982070820718207282073820748207582076820778207882079820808208182082820838208482085820868208782088820898209082091820928209382094820958209682097820988209982100821018210282103821048210582106821078210882109821108211182112821138211482115821168211782118821198212082121821228212382124821258212682127821288212982130821318213282133821348213582136821378213882139821408214182142821438214482145821468214782148821498215082151821528215382154821558215682157821588215982160821618216282163821648216582166821678216882169821708217182172821738217482175821768217782178821798218082181821828218382184821858218682187821888218982190821918219282193821948219582196821978219882199822008220182202822038220482205822068220782208822098221082211822128221382214822158221682217822188221982220822218222282223822248222582226822278222882229822308223182232822338223482235822368223782238822398224082241822428224382244822458224682247822488224982250822518225282253822548225582256822578225882259822608226182262822638226482265822668226782268822698227082271822728227382274822758227682277822788227982280822818228282283822848228582286822878228882289822908229182292822938229482295822968229782298822998230082301823028230382304823058230682307823088230982310823118231282313823148231582316823178231882319823208232182322823238232482325823268232782328823298233082331823328233382334823358233682337823388233982340823418234282343823448234582346823478234882349823508235182352823538235482355823568235782358823598236082361823628236382364823658236682367823688236982370823718237282373823748237582376823778237882379823808238182382823838238482385823868238782388823898239082391823928239382394823958239682397823988239982400824018240282403824048240582406824078240882409824108241182412824138241482415824168241782418824198242082421824228242382424824258242682427824288242982430824318243282433824348243582436824378243882439824408244182442824438244482445824468244782448824498245082451824528245382454824558245682457824588245982460824618246282463824648246582466824678246882469824708247182472824738247482475824768247782478824798248082481824828248382484824858248682487824888248982490824918249282493824948249582496824978249882499825008250182502825038250482505825068250782508825098251082511825128251382514825158251682517825188251982520825218252282523825248252582526825278252882529825308253182532825338253482535825368253782538825398254082541825428254382544825458254682547825488254982550825518255282553825548255582556825578255882559825608256182562825638256482565825668256782568825698257082571825728257382574825758257682577825788257982580825818258282583825848258582586825878258882589825908259182592825938259482595825968259782598825998260082601826028260382604826058260682607826088260982610826118261282613826148261582616826178261882619826208262182622826238262482625826268262782628826298263082631826328263382634826358263682637826388263982640826418264282643826448264582646826478264882649826508265182652826538265482655826568265782658826598266082661826628266382664826658266682667826688266982670826718267282673826748267582676826778267882679826808268182682826838268482685826868268782688826898269082691826928269382694826958269682697826988269982700827018270282703827048270582706827078270882709827108271182712827138271482715827168271782718827198272082721827228272382724827258272682727827288272982730827318273282733827348273582736827378273882739827408274182742827438274482745827468274782748827498275082751827528275382754827558275682757827588275982760827618276282763827648276582766827678276882769827708277182772827738277482775827768277782778827798278082781827828278382784827858278682787827888278982790827918279282793827948279582796827978279882799828008280182802828038280482805828068280782808828098281082811828128281382814828158281682817828188281982820828218282282823828248282582826828278282882829828308283182832828338283482835828368283782838828398284082841828428284382844828458284682847828488284982850828518285282853828548285582856828578285882859828608286182862828638286482865828668286782868828698287082871828728287382874828758287682877828788287982880828818288282883828848288582886828878288882889828908289182892828938289482895828968289782898828998290082901829028290382904829058290682907829088290982910829118291282913829148291582916829178291882919829208292182922829238292482925829268292782928829298293082931829328293382934829358293682937829388293982940829418294282943829448294582946829478294882949829508295182952829538295482955829568295782958829598296082961829628296382964829658296682967829688296982970829718297282973829748297582976829778297882979829808298182982829838298482985829868298782988829898299082991829928299382994829958299682997829988299983000830018300283003830048300583006830078300883009830108301183012830138301483015830168301783018830198302083021830228302383024830258302683027830288302983030830318303283033830348303583036830378303883039830408304183042830438304483045830468304783048830498305083051830528305383054830558305683057830588305983060830618306283063830648306583066830678306883069830708307183072830738307483075830768307783078830798308083081830828308383084830858308683087830888308983090830918309283093830948309583096830978309883099831008310183102831038310483105831068310783108831098311083111831128311383114831158311683117831188311983120831218312283123831248312583126831278312883129831308313183132831338313483135831368313783138831398314083141831428314383144831458314683147831488314983150831518315283153831548315583156831578315883159831608316183162831638316483165831668316783168831698317083171831728317383174831758317683177831788317983180831818318283183831848318583186831878318883189831908319183192831938319483195831968319783198831998320083201832028320383204832058320683207832088320983210832118321283213832148321583216832178321883219832208322183222832238322483225832268322783228832298323083231832328323383234832358323683237832388323983240832418324283243832448324583246832478324883249832508325183252832538325483255832568325783258832598326083261832628326383264832658326683267832688326983270832718327283273832748327583276832778327883279832808328183282832838328483285832868328783288832898329083291832928329383294832958329683297832988329983300833018330283303833048330583306833078330883309833108331183312833138331483315833168331783318833198332083321833228332383324833258332683327833288332983330833318333283333833348333583336833378333883339833408334183342833438334483345833468334783348833498335083351833528335383354833558335683357833588335983360833618336283363833648336583366833678336883369833708337183372833738337483375833768337783378833798338083381833828338383384833858338683387833888338983390833918339283393833948339583396833978339883399834008340183402834038340483405834068340783408834098341083411834128341383414834158341683417834188341983420834218342283423834248342583426834278342883429834308343183432834338343483435834368343783438834398344083441834428344383444834458344683447834488344983450834518345283453834548345583456834578345883459834608346183462834638346483465834668346783468834698347083471834728347383474834758347683477834788347983480834818348283483834848348583486834878348883489834908349183492834938349483495834968349783498834998350083501835028350383504835058350683507835088350983510835118351283513835148351583516835178351883519835208352183522835238352483525835268352783528835298353083531835328353383534835358353683537835388353983540835418354283543835448354583546835478354883549835508355183552835538355483555835568355783558835598356083561835628356383564835658356683567835688356983570835718357283573835748357583576835778357883579835808358183582835838358483585835868358783588835898359083591835928359383594835958359683597835988359983600836018360283603836048360583606836078360883609836108361183612836138361483615836168361783618836198362083621836228362383624836258362683627836288362983630836318363283633836348363583636836378363883639836408364183642836438364483645836468364783648836498365083651836528365383654836558365683657836588365983660836618366283663836648366583666836678366883669836708367183672836738367483675836768367783678836798368083681836828368383684836858368683687836888368983690836918369283693836948369583696836978369883699837008370183702837038370483705837068370783708837098371083711837128371383714837158371683717837188371983720837218372283723837248372583726837278372883729837308373183732837338373483735837368373783738837398374083741837428374383744837458374683747837488374983750837518375283753837548375583756837578375883759837608376183762837638376483765837668376783768837698377083771837728377383774837758377683777837788377983780837818378283783837848378583786837878378883789837908379183792837938379483795837968379783798837998380083801838028380383804838058380683807838088380983810838118381283813838148381583816838178381883819838208382183822838238382483825838268382783828838298383083831838328383383834838358383683837838388383983840838418384283843838448384583846838478384883849838508385183852838538385483855838568385783858838598386083861838628386383864838658386683867838688386983870838718387283873838748387583876838778387883879838808388183882838838388483885838868388783888838898389083891838928389383894838958389683897838988389983900839018390283903839048390583906839078390883909839108391183912839138391483915839168391783918839198392083921839228392383924839258392683927839288392983930839318393283933839348393583936839378393883939839408394183942839438394483945839468394783948839498395083951839528395383954839558395683957839588395983960839618396283963839648396583966839678396883969839708397183972839738397483975839768397783978839798398083981839828398383984839858398683987839888398983990839918399283993839948399583996839978399883999840008400184002840038400484005840068400784008840098401084011840128401384014840158401684017840188401984020840218402284023840248402584026840278402884029840308403184032840338403484035840368403784038840398404084041840428404384044840458404684047840488404984050840518405284053840548405584056840578405884059840608406184062840638406484065840668406784068840698407084071840728407384074840758407684077840788407984080840818408284083840848408584086840878408884089840908409184092840938409484095840968409784098840998410084101841028410384104841058410684107841088410984110841118411284113841148411584116841178411884119841208412184122841238412484125841268412784128841298413084131841328413384134841358413684137841388413984140841418414284143841448414584146841478414884149841508415184152841538415484155841568415784158841598416084161841628416384164841658416684167841688416984170841718417284173841748417584176841778417884179841808418184182841838418484185841868418784188841898419084191841928419384194841958419684197841988419984200842018420284203842048420584206842078420884209842108421184212842138421484215842168421784218842198422084221842228422384224842258422684227842288422984230842318423284233842348423584236842378423884239842408424184242842438424484245842468424784248842498425084251842528425384254842558425684257842588425984260842618426284263842648426584266842678426884269842708427184272842738427484275842768427784278842798428084281842828428384284842858428684287842888428984290842918429284293842948429584296842978429884299843008430184302843038430484305843068430784308843098431084311843128431384314843158431684317843188431984320843218432284323843248432584326843278432884329843308433184332843338433484335843368433784338843398434084341843428434384344843458434684347843488434984350843518435284353843548435584356843578435884359843608436184362843638436484365843668436784368843698437084371843728437384374843758437684377843788437984380843818438284383843848438584386843878438884389843908439184392843938439484395843968439784398843998440084401844028440384404844058440684407844088440984410844118441284413844148441584416844178441884419844208442184422844238442484425844268442784428844298443084431844328443384434844358443684437844388443984440844418444284443844448444584446844478444884449844508445184452844538445484455844568445784458844598446084461844628446384464844658446684467844688446984470844718447284473844748447584476844778447884479844808448184482844838448484485844868448784488844898449084491844928449384494844958449684497844988449984500845018450284503845048450584506845078450884509845108451184512845138451484515845168451784518845198452084521845228452384524845258452684527845288452984530845318453284533845348453584536845378453884539845408454184542845438454484545845468454784548845498455084551845528455384554845558455684557845588455984560845618456284563845648456584566845678456884569845708457184572845738457484575845768457784578845798458084581845828458384584845858458684587845888458984590845918459284593845948459584596845978459884599846008460184602846038460484605846068460784608846098461084611846128461384614846158461684617846188461984620846218462284623846248462584626846278462884629846308463184632846338463484635846368463784638846398464084641846428464384644846458464684647846488464984650846518465284653846548465584656846578465884659846608466184662846638466484665846668466784668846698467084671846728467384674846758467684677846788467984680846818468284683846848468584686846878468884689846908469184692846938469484695846968469784698846998470084701847028470384704847058470684707847088470984710847118471284713847148471584716847178471884719847208472184722847238472484725847268472784728847298473084731847328473384734847358473684737847388473984740847418474284743847448474584746847478474884749847508475184752847538475484755847568475784758847598476084761847628476384764847658476684767847688476984770847718477284773847748477584776847778477884779847808478184782847838478484785847868478784788847898479084791847928479384794847958479684797847988479984800848018480284803848048480584806848078480884809848108481184812848138481484815848168481784818848198482084821848228482384824848258482684827848288482984830848318483284833848348483584836848378483884839848408484184842848438484484845848468484784848848498485084851848528485384854848558485684857848588485984860848618486284863848648486584866848678486884869848708487184872848738487484875848768487784878848798488084881848828488384884848858488684887848888488984890848918489284893848948489584896848978489884899849008490184902849038490484905849068490784908849098491084911849128491384914849158491684917849188491984920849218492284923849248492584926849278492884929849308493184932849338493484935849368493784938849398494084941849428494384944849458494684947849488494984950849518495284953849548495584956849578495884959849608496184962849638496484965849668496784968849698497084971849728497384974849758497684977849788497984980849818498284983849848498584986849878498884989849908499184992849938499484995849968499784998849998500085001850028500385004850058500685007850088500985010850118501285013850148501585016850178501885019850208502185022850238502485025850268502785028850298503085031850328503385034850358503685037850388503985040850418504285043850448504585046850478504885049850508505185052850538505485055850568505785058850598506085061850628506385064850658506685067850688506985070850718507285073850748507585076850778507885079850808508185082850838508485085850868508785088850898509085091850928509385094850958509685097850988509985100851018510285103851048510585106851078510885109851108511185112851138511485115851168511785118851198512085121851228512385124851258512685127851288512985130851318513285133851348513585136851378513885139851408514185142851438514485145851468514785148851498515085151851528515385154851558515685157851588515985160851618516285163851648516585166851678516885169851708517185172851738517485175851768517785178851798518085181851828518385184851858518685187851888518985190851918519285193851948519585196851978519885199852008520185202852038520485205852068520785208852098521085211852128521385214852158521685217852188521985220852218522285223852248522585226852278522885229852308523185232852338523485235852368523785238852398524085241852428524385244852458524685247852488524985250852518525285253852548525585256852578525885259852608526185262852638526485265852668526785268852698527085271852728527385274852758527685277852788527985280852818528285283852848528585286852878528885289852908529185292852938529485295852968529785298852998530085301853028530385304853058530685307853088530985310853118531285313853148531585316853178531885319853208532185322853238532485325853268532785328853298533085331853328533385334853358533685337853388533985340853418534285343853448534585346853478534885349853508535185352853538535485355853568535785358853598536085361853628536385364853658536685367853688536985370853718537285373853748537585376853778537885379853808538185382853838538485385853868538785388853898539085391853928539385394853958539685397853988539985400854018540285403854048540585406854078540885409854108541185412854138541485415854168541785418854198542085421854228542385424854258542685427854288542985430854318543285433854348543585436854378543885439854408544185442854438544485445854468544785448854498545085451854528545385454854558545685457854588545985460854618546285463854648546585466854678546885469854708547185472854738547485475854768547785478854798548085481854828548385484854858548685487854888548985490854918549285493854948549585496854978549885499855008550185502855038550485505855068550785508855098551085511855128551385514855158551685517855188551985520855218552285523855248552585526855278552885529855308553185532855338553485535855368553785538855398554085541855428554385544855458554685547855488554985550855518555285553855548555585556855578555885559855608556185562855638556485565855668556785568855698557085571855728557385574855758557685577855788557985580855818558285583855848558585586855878558885589855908559185592855938559485595855968559785598855998560085601856028560385604856058560685607856088560985610856118561285613856148561585616856178561885619856208562185622856238562485625856268562785628856298563085631856328563385634856358563685637856388563985640856418564285643856448564585646856478564885649856508565185652856538565485655856568565785658856598566085661856628566385664856658566685667856688566985670856718567285673856748567585676856778567885679856808568185682856838568485685856868568785688856898569085691856928569385694856958569685697856988569985700857018570285703857048570585706857078570885709857108571185712857138571485715857168571785718857198572085721857228572385724857258572685727857288572985730857318573285733857348573585736857378573885739857408574185742857438574485745857468574785748857498575085751857528575385754857558575685757857588575985760857618576285763857648576585766857678576885769857708577185772857738577485775857768577785778857798578085781857828578385784857858578685787857888578985790857918579285793857948579585796857978579885799858008580185802858038580485805858068580785808858098581085811858128581385814858158581685817858188581985820858218582285823858248582585826858278582885829858308583185832858338583485835858368583785838858398584085841858428584385844858458584685847858488584985850858518585285853858548585585856858578585885859858608586185862858638586485865858668586785868858698587085871858728587385874858758587685877858788587985880858818588285883858848588585886858878588885889858908589185892858938589485895858968589785898858998590085901859028590385904859058590685907859088590985910859118591285913859148591585916859178591885919859208592185922859238592485925859268592785928859298593085931859328593385934859358593685937859388593985940859418594285943859448594585946859478594885949859508595185952859538595485955859568595785958859598596085961859628596385964859658596685967859688596985970859718597285973859748597585976859778597885979859808598185982859838598485985859868598785988859898599085991859928599385994859958599685997859988599986000860018600286003860048600586006860078600886009860108601186012860138601486015860168601786018860198602086021860228602386024860258602686027860288602986030860318603286033860348603586036860378603886039860408604186042860438604486045860468604786048860498605086051860528605386054860558605686057860588605986060860618606286063860648606586066860678606886069860708607186072860738607486075860768607786078860798608086081860828608386084860858608686087860888608986090860918609286093860948609586096860978609886099861008610186102861038610486105861068610786108861098611086111861128611386114861158611686117861188611986120861218612286123861248612586126861278612886129861308613186132861338613486135861368613786138861398614086141861428614386144861458614686147861488614986150861518615286153861548615586156861578615886159861608616186162861638616486165861668616786168861698617086171861728617386174861758617686177861788617986180861818618286183861848618586186861878618886189861908619186192861938619486195861968619786198861998620086201862028620386204862058620686207862088620986210862118621286213862148621586216862178621886219862208622186222862238622486225862268622786228862298623086231862328623386234862358623686237862388623986240862418624286243862448624586246862478624886249862508625186252862538625486255862568625786258862598626086261862628626386264862658626686267862688626986270862718627286273862748627586276862778627886279862808628186282862838628486285862868628786288862898629086291862928629386294862958629686297862988629986300863018630286303863048630586306863078630886309863108631186312863138631486315863168631786318863198632086321863228632386324863258632686327863288632986330863318633286333863348633586336863378633886339863408634186342863438634486345863468634786348863498635086351863528635386354863558635686357863588635986360863618636286363863648636586366863678636886369863708637186372863738637486375863768637786378863798638086381863828638386384863858638686387863888638986390863918639286393863948639586396863978639886399864008640186402864038640486405864068640786408864098641086411864128641386414864158641686417864188641986420864218642286423864248642586426864278642886429864308643186432864338643486435864368643786438864398644086441864428644386444864458644686447864488644986450864518645286453864548645586456864578645886459864608646186462864638646486465864668646786468864698647086471864728647386474864758647686477864788647986480864818648286483864848648586486864878648886489864908649186492864938649486495864968649786498864998650086501865028650386504865058650686507865088650986510865118651286513865148651586516865178651886519865208652186522865238652486525865268652786528865298653086531865328653386534865358653686537865388653986540865418654286543865448654586546865478654886549865508655186552865538655486555865568655786558865598656086561865628656386564865658656686567865688656986570865718657286573865748657586576865778657886579865808658186582865838658486585865868658786588865898659086591865928659386594865958659686597865988659986600866018660286603866048660586606866078660886609866108661186612866138661486615866168661786618866198662086621866228662386624866258662686627866288662986630866318663286633866348663586636866378663886639866408664186642866438664486645866468664786648866498665086651866528665386654866558665686657866588665986660866618666286663866648666586666866678666886669866708667186672866738667486675866768667786678866798668086681866828668386684866858668686687866888668986690866918669286693866948669586696866978669886699867008670186702867038670486705867068670786708867098671086711867128671386714867158671686717867188671986720867218672286723867248672586726867278672886729867308673186732867338673486735867368673786738867398674086741867428674386744867458674686747867488674986750867518675286753867548675586756867578675886759867608676186762867638676486765867668676786768867698677086771867728677386774867758677686777867788677986780867818678286783867848678586786867878678886789867908679186792867938679486795867968679786798867998680086801868028680386804868058680686807868088680986810868118681286813868148681586816868178681886819868208682186822868238682486825868268682786828868298683086831868328683386834868358683686837868388683986840868418684286843868448684586846868478684886849868508685186852868538685486855868568685786858868598686086861868628686386864868658686686867868688686986870868718687286873868748687586876868778687886879868808688186882868838688486885868868688786888868898689086891868928689386894868958689686897868988689986900869018690286903869048690586906869078690886909869108691186912869138691486915869168691786918869198692086921869228692386924869258692686927869288692986930869318693286933869348693586936869378693886939869408694186942869438694486945869468694786948869498695086951869528695386954869558695686957869588695986960869618696286963869648696586966869678696886969869708697186972869738697486975869768697786978869798698086981869828698386984869858698686987869888698986990869918699286993869948699586996869978699886999870008700187002870038700487005870068700787008870098701087011870128701387014870158701687017870188701987020870218702287023870248702587026870278702887029870308703187032870338703487035870368703787038870398704087041870428704387044870458704687047870488704987050870518705287053870548705587056870578705887059870608706187062870638706487065870668706787068870698707087071870728707387074870758707687077870788707987080870818708287083870848708587086870878708887089870908709187092870938709487095870968709787098870998710087101871028710387104871058710687107871088710987110871118711287113871148711587116871178711887119871208712187122871238712487125871268712787128871298713087131871328713387134871358713687137871388713987140871418714287143871448714587146871478714887149871508715187152871538715487155871568715787158871598716087161871628716387164871658716687167871688716987170871718717287173871748717587176871778717887179871808718187182871838718487185871868718787188871898719087191871928719387194871958719687197871988719987200872018720287203872048720587206872078720887209872108721187212872138721487215872168721787218872198722087221872228722387224872258722687227872288722987230872318723287233872348723587236872378723887239872408724187242872438724487245872468724787248872498725087251872528725387254872558725687257872588725987260872618726287263872648726587266872678726887269872708727187272872738727487275872768727787278872798728087281872828728387284872858728687287872888728987290872918729287293872948729587296872978729887299873008730187302873038730487305873068730787308873098731087311873128731387314873158731687317873188731987320873218732287323873248732587326873278732887329873308733187332873338733487335873368733787338873398734087341873428734387344873458734687347873488734987350873518735287353873548735587356873578735887359873608736187362873638736487365873668736787368873698737087371873728737387374873758737687377873788737987380873818738287383873848738587386873878738887389873908739187392873938739487395873968739787398873998740087401874028740387404874058740687407874088740987410874118741287413874148741587416874178741887419874208742187422874238742487425874268742787428874298743087431874328743387434874358743687437874388743987440874418744287443874448744587446874478744887449874508745187452874538745487455874568745787458874598746087461874628746387464874658746687467874688746987470874718747287473874748747587476874778747887479874808748187482874838748487485874868748787488874898749087491874928749387494874958749687497874988749987500875018750287503875048750587506875078750887509875108751187512875138751487515875168751787518875198752087521875228752387524875258752687527875288752987530875318753287533875348753587536875378753887539875408754187542875438754487545875468754787548875498755087551875528755387554875558755687557875588755987560875618756287563875648756587566875678756887569875708757187572875738757487575875768757787578875798758087581875828758387584875858758687587875888758987590875918759287593875948759587596875978759887599876008760187602876038760487605876068760787608876098761087611876128761387614876158761687617876188761987620876218762287623876248762587626876278762887629876308763187632876338763487635876368763787638876398764087641876428764387644876458764687647876488764987650876518765287653876548765587656876578765887659876608766187662876638766487665876668766787668876698767087671876728767387674876758767687677876788767987680876818768287683876848768587686876878768887689876908769187692876938769487695876968769787698876998770087701877028770387704877058770687707877088770987710877118771287713877148771587716877178771887719877208772187722877238772487725877268772787728877298773087731877328773387734877358773687737877388773987740877418774287743877448774587746877478774887749877508775187752877538775487755877568775787758877598776087761877628776387764877658776687767877688776987770877718777287773877748777587776877778777887779877808778187782877838778487785877868778787788877898779087791877928779387794877958779687797877988779987800878018780287803878048780587806878078780887809878108781187812878138781487815878168781787818878198782087821878228782387824878258782687827878288782987830878318783287833878348783587836878378783887839878408784187842878438784487845878468784787848878498785087851878528785387854878558785687857878588785987860878618786287863878648786587866878678786887869878708787187872878738787487875878768787787878878798788087881878828788387884878858788687887878888788987890878918789287893878948789587896878978789887899879008790187902879038790487905879068790787908879098791087911879128791387914879158791687917879188791987920879218792287923879248792587926879278792887929879308793187932879338793487935879368793787938879398794087941879428794387944879458794687947879488794987950879518795287953879548795587956879578795887959879608796187962879638796487965879668796787968879698797087971879728797387974879758797687977879788797987980879818798287983879848798587986879878798887989879908799187992879938799487995879968799787998879998800088001880028800388004880058800688007880088800988010880118801288013880148801588016880178801888019880208802188022880238802488025880268802788028880298803088031880328803388034880358803688037880388803988040880418804288043880448804588046880478804888049880508805188052880538805488055880568805788058880598806088061880628806388064880658806688067880688806988070880718807288073880748807588076880778807888079880808808188082880838808488085880868808788088880898809088091880928809388094880958809688097880988809988100881018810288103881048810588106881078810888109881108811188112881138811488115881168811788118881198812088121881228812388124881258812688127881288812988130881318813288133881348813588136881378813888139881408814188142881438814488145881468814788148881498815088151881528815388154881558815688157881588815988160881618816288163881648816588166881678816888169881708817188172881738817488175881768817788178881798818088181881828818388184881858818688187881888818988190881918819288193881948819588196881978819888199882008820188202882038820488205882068820788208882098821088211882128821388214882158821688217882188821988220882218822288223882248822588226882278822888229882308823188232882338823488235882368823788238882398824088241882428824388244882458824688247882488824988250882518825288253882548825588256882578825888259882608826188262882638826488265882668826788268882698827088271882728827388274882758827688277882788827988280882818828288283882848828588286882878828888289882908829188292882938829488295882968829788298882998830088301883028830388304883058830688307883088830988310883118831288313883148831588316883178831888319883208832188322883238832488325883268832788328883298833088331883328833388334883358833688337883388833988340883418834288343883448834588346883478834888349883508835188352883538835488355883568835788358883598836088361883628836388364883658836688367883688836988370883718837288373883748837588376883778837888379883808838188382883838838488385883868838788388883898839088391883928839388394883958839688397883988839988400884018840288403884048840588406884078840888409884108841188412884138841488415884168841788418884198842088421884228842388424884258842688427884288842988430884318843288433884348843588436884378843888439884408844188442884438844488445884468844788448884498845088451884528845388454884558845688457884588845988460884618846288463884648846588466884678846888469884708847188472884738847488475884768847788478884798848088481884828848388484884858848688487884888848988490884918849288493884948849588496884978849888499885008850188502885038850488505885068850788508885098851088511885128851388514885158851688517885188851988520885218852288523885248852588526885278852888529885308853188532885338853488535885368853788538885398854088541885428854388544885458854688547885488854988550885518855288553885548855588556885578855888559885608856188562885638856488565885668856788568885698857088571885728857388574885758857688577885788857988580885818858288583885848858588586885878858888589885908859188592885938859488595885968859788598885998860088601886028860388604886058860688607886088860988610886118861288613886148861588616886178861888619886208862188622886238862488625886268862788628886298863088631886328863388634886358863688637886388863988640886418864288643886448864588646886478864888649886508865188652886538865488655886568865788658886598866088661886628866388664886658866688667886688866988670886718867288673886748867588676886778867888679886808868188682886838868488685886868868788688886898869088691886928869388694886958869688697886988869988700887018870288703887048870588706887078870888709887108871188712887138871488715887168871788718887198872088721887228872388724887258872688727887288872988730887318873288733887348873588736887378873888739887408874188742887438874488745887468874788748887498875088751887528875388754887558875688757887588875988760887618876288763887648876588766887678876888769887708877188772887738877488775887768877788778887798878088781887828878388784887858878688787887888878988790887918879288793887948879588796887978879888799888008880188802888038880488805888068880788808888098881088811888128881388814888158881688817888188881988820888218882288823888248882588826888278882888829888308883188832888338883488835888368883788838888398884088841888428884388844888458884688847888488884988850888518885288853888548885588856888578885888859888608886188862888638886488865888668886788868888698887088871888728887388874888758887688877888788887988880888818888288883888848888588886888878888888889888908889188892888938889488895888968889788898888998890088901889028890388904889058890688907889088890988910889118891288913889148891588916889178891888919889208892188922889238892488925889268892788928889298893088931889328893388934889358893688937889388893988940889418894288943889448894588946889478894888949889508895188952889538895488955889568895788958889598896088961889628896388964889658896688967889688896988970889718897288973889748897588976889778897888979889808898188982889838898488985889868898788988889898899088991889928899388994889958899688997889988899989000890018900289003890048900589006890078900889009890108901189012890138901489015890168901789018890198902089021890228902389024890258902689027890288902989030890318903289033890348903589036890378903889039890408904189042890438904489045890468904789048890498905089051890528905389054890558905689057890588905989060890618906289063890648906589066890678906889069890708907189072890738907489075890768907789078890798908089081890828908389084890858908689087890888908989090890918909289093890948909589096890978909889099891008910189102891038910489105891068910789108891098911089111891128911389114891158911689117891188911989120891218912289123891248912589126891278912889129891308913189132891338913489135891368913789138891398914089141891428914389144891458914689147891488914989150891518915289153891548915589156891578915889159891608916189162891638916489165891668916789168891698917089171891728917389174891758917689177891788917989180891818918289183891848918589186891878918889189891908919189192891938919489195891968919789198891998920089201892028920389204892058920689207892088920989210892118921289213892148921589216892178921889219892208922189222892238922489225892268922789228892298923089231892328923389234892358923689237892388923989240892418924289243892448924589246892478924889249892508925189252892538925489255892568925789258892598926089261892628926389264892658926689267892688926989270892718927289273892748927589276892778927889279892808928189282892838928489285892868928789288892898929089291892928929389294892958929689297892988929989300893018930289303893048930589306893078930889309893108931189312893138931489315893168931789318893198932089321893228932389324893258932689327893288932989330893318933289333893348933589336893378933889339893408934189342893438934489345893468934789348893498935089351893528935389354893558935689357893588935989360893618936289363893648936589366893678936889369893708937189372893738937489375893768937789378893798938089381893828938389384893858938689387893888938989390893918939289393893948939589396893978939889399894008940189402894038940489405894068940789408894098941089411894128941389414894158941689417894188941989420894218942289423894248942589426894278942889429894308943189432894338943489435894368943789438894398944089441894428944389444894458944689447894488944989450894518945289453894548945589456894578945889459894608946189462894638946489465894668946789468894698947089471894728947389474894758947689477894788947989480894818948289483894848948589486894878948889489894908949189492894938949489495894968949789498894998950089501895028950389504895058950689507895088950989510895118951289513895148951589516895178951889519895208952189522895238952489525895268952789528895298953089531895328953389534895358953689537895388953989540895418954289543895448954589546895478954889549895508955189552895538955489555895568955789558895598956089561895628956389564895658956689567895688956989570895718957289573895748957589576895778957889579895808958189582895838958489585895868958789588895898959089591895928959389594895958959689597895988959989600896018960289603896048960589606896078960889609896108961189612896138961489615896168961789618896198962089621896228962389624896258962689627896288962989630896318963289633896348963589636896378963889639896408964189642896438964489645896468964789648896498965089651896528965389654896558965689657896588965989660896618966289663896648966589666896678966889669896708967189672896738967489675896768967789678896798968089681896828968389684896858968689687896888968989690896918969289693896948969589696896978969889699897008970189702897038970489705897068970789708897098971089711897128971389714897158971689717897188971989720897218972289723897248972589726897278972889729897308973189732897338973489735897368973789738897398974089741897428974389744897458974689747897488974989750897518975289753897548975589756897578975889759897608976189762897638976489765897668976789768897698977089771897728977389774897758977689777897788977989780897818978289783897848978589786897878978889789897908979189792897938979489795897968979789798897998980089801898028980389804898058980689807898088980989810898118981289813898148981589816898178981889819898208982189822898238982489825898268982789828898298983089831898328983389834898358983689837898388983989840898418984289843898448984589846898478984889849898508985189852898538985489855898568985789858898598986089861898628986389864898658986689867898688986989870898718987289873898748987589876898778987889879898808988189882898838988489885898868988789888898898989089891898928989389894898958989689897898988989989900899018990289903899048990589906899078990889909899108991189912899138991489915899168991789918899198992089921899228992389924899258992689927899288992989930899318993289933899348993589936899378993889939899408994189942899438994489945899468994789948899498995089951899528995389954899558995689957899588995989960899618996289963899648996589966899678996889969899708997189972899738997489975899768997789978899798998089981899828998389984899858998689987899888998989990899918999289993899948999589996899978999889999900009000190002900039000490005900069000790008900099001090011900129001390014900159001690017900189001990020900219002290023900249002590026900279002890029900309003190032900339003490035900369003790038900399004090041900429004390044900459004690047900489004990050900519005290053900549005590056900579005890059900609006190062900639006490065900669006790068900699007090071900729007390074900759007690077900789007990080900819008290083900849008590086900879008890089900909009190092900939009490095900969009790098900999010090101901029010390104901059010690107901089010990110901119011290113901149011590116901179011890119901209012190122901239012490125901269012790128901299013090131901329013390134901359013690137901389013990140901419014290143901449014590146901479014890149901509015190152901539015490155901569015790158901599016090161901629016390164901659016690167901689016990170901719017290173901749017590176901779017890179901809018190182901839018490185901869018790188
  1. diff -Nur linux-2.6.39.orig/crypto/Kconfig linux-2.6.39/crypto/Kconfig
  2. --- linux-2.6.39.orig/crypto/Kconfig 2011-05-19 06:06:34.000000000 +0200
  3. +++ linux-2.6.39/crypto/Kconfig 2011-07-31 11:31:52.923425588 +0200
  4. @@ -866,3 +866,6 @@
  5. source "drivers/crypto/Kconfig"
  6. endif # if CRYPTO
  7. +
  8. +source "crypto/ocf/Kconfig"
  9. +
  10. diff -Nur linux-2.6.39.orig/crypto/Kconfig.orig linux-2.6.39/crypto/Kconfig.orig
  11. --- linux-2.6.39.orig/crypto/Kconfig.orig 1970-01-01 01:00:00.000000000 +0100
  12. +++ linux-2.6.39/crypto/Kconfig.orig 2011-05-19 06:06:34.000000000 +0200
  13. @@ -0,0 +1,868 @@
  14. +#
  15. +# Generic algorithms support
  16. +#
  17. +config XOR_BLOCKS
  18. + tristate
  19. +
  20. +#
  21. +# async_tx api: hardware offloaded memory transfer/transform support
  22. +#
  23. +source "crypto/async_tx/Kconfig"
  24. +
  25. +#
  26. +# Cryptographic API Configuration
  27. +#
  28. +menuconfig CRYPTO
  29. + tristate "Cryptographic API"
  30. + help
  31. + This option provides the core Cryptographic API.
  32. +
  33. +if CRYPTO
  34. +
  35. +comment "Crypto core or helper"
  36. +
  37. +config CRYPTO_FIPS
  38. + bool "FIPS 200 compliance"
  39. + depends on CRYPTO_ANSI_CPRNG && !CRYPTO_MANAGER_DISABLE_TESTS
  40. + help
  41. + This options enables the fips boot option which is
  42. + required if you want to system to operate in a FIPS 200
  43. + certification. You should say no unless you know what
  44. + this is.
  45. +
  46. +config CRYPTO_ALGAPI
  47. + tristate
  48. + select CRYPTO_ALGAPI2
  49. + help
  50. + This option provides the API for cryptographic algorithms.
  51. +
  52. +config CRYPTO_ALGAPI2
  53. + tristate
  54. +
  55. +config CRYPTO_AEAD
  56. + tristate
  57. + select CRYPTO_AEAD2
  58. + select CRYPTO_ALGAPI
  59. +
  60. +config CRYPTO_AEAD2
  61. + tristate
  62. + select CRYPTO_ALGAPI2
  63. +
  64. +config CRYPTO_BLKCIPHER
  65. + tristate
  66. + select CRYPTO_BLKCIPHER2
  67. + select CRYPTO_ALGAPI
  68. +
  69. +config CRYPTO_BLKCIPHER2
  70. + tristate
  71. + select CRYPTO_ALGAPI2
  72. + select CRYPTO_RNG2
  73. + select CRYPTO_WORKQUEUE
  74. +
  75. +config CRYPTO_HASH
  76. + tristate
  77. + select CRYPTO_HASH2
  78. + select CRYPTO_ALGAPI
  79. +
  80. +config CRYPTO_HASH2
  81. + tristate
  82. + select CRYPTO_ALGAPI2
  83. +
  84. +config CRYPTO_RNG
  85. + tristate
  86. + select CRYPTO_RNG2
  87. + select CRYPTO_ALGAPI
  88. +
  89. +config CRYPTO_RNG2
  90. + tristate
  91. + select CRYPTO_ALGAPI2
  92. +
  93. +config CRYPTO_PCOMP
  94. + tristate
  95. + select CRYPTO_PCOMP2
  96. + select CRYPTO_ALGAPI
  97. +
  98. +config CRYPTO_PCOMP2
  99. + tristate
  100. + select CRYPTO_ALGAPI2
  101. +
  102. +config CRYPTO_MANAGER
  103. + tristate "Cryptographic algorithm manager"
  104. + select CRYPTO_MANAGER2
  105. + help
  106. + Create default cryptographic template instantiations such as
  107. + cbc(aes).
  108. +
  109. +config CRYPTO_MANAGER2
  110. + def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y)
  111. + select CRYPTO_AEAD2
  112. + select CRYPTO_HASH2
  113. + select CRYPTO_BLKCIPHER2
  114. + select CRYPTO_PCOMP2
  115. +
  116. +config CRYPTO_MANAGER_DISABLE_TESTS
  117. + bool "Disable run-time self tests"
  118. + default y
  119. + depends on CRYPTO_MANAGER2
  120. + help
  121. + Disable run-time self tests that normally take place at
  122. + algorithm registration.
  123. +
  124. +config CRYPTO_GF128MUL
  125. + tristate "GF(2^128) multiplication functions (EXPERIMENTAL)"
  126. + help
  127. + Efficient table driven implementation of multiplications in the
  128. + field GF(2^128). This is needed by some cypher modes. This
  129. + option will be selected automatically if you select such a
  130. + cipher mode. Only select this option by hand if you expect to load
  131. + an external module that requires these functions.
  132. +
  133. +config CRYPTO_NULL
  134. + tristate "Null algorithms"
  135. + select CRYPTO_ALGAPI
  136. + select CRYPTO_BLKCIPHER
  137. + select CRYPTO_HASH
  138. + help
  139. + These are 'Null' algorithms, used by IPsec, which do nothing.
  140. +
  141. +config CRYPTO_PCRYPT
  142. + tristate "Parallel crypto engine (EXPERIMENTAL)"
  143. + depends on SMP && EXPERIMENTAL
  144. + select PADATA
  145. + select CRYPTO_MANAGER
  146. + select CRYPTO_AEAD
  147. + help
  148. + This converts an arbitrary crypto algorithm into a parallel
  149. + algorithm that executes in kernel threads.
  150. +
  151. +config CRYPTO_WORKQUEUE
  152. + tristate
  153. +
  154. +config CRYPTO_CRYPTD
  155. + tristate "Software async crypto daemon"
  156. + select CRYPTO_BLKCIPHER
  157. + select CRYPTO_HASH
  158. + select CRYPTO_MANAGER
  159. + select CRYPTO_WORKQUEUE
  160. + help
  161. + This is a generic software asynchronous crypto daemon that
  162. + converts an arbitrary synchronous software crypto algorithm
  163. + into an asynchronous algorithm that executes in a kernel thread.
  164. +
  165. +config CRYPTO_AUTHENC
  166. + tristate "Authenc support"
  167. + select CRYPTO_AEAD
  168. + select CRYPTO_BLKCIPHER
  169. + select CRYPTO_MANAGER
  170. + select CRYPTO_HASH
  171. + help
  172. + Authenc: Combined mode wrapper for IPsec.
  173. + This is required for IPSec.
  174. +
  175. +config CRYPTO_TEST
  176. + tristate "Testing module"
  177. + depends on m
  178. + select CRYPTO_MANAGER
  179. + help
  180. + Quick & dirty crypto test module.
  181. +
  182. +comment "Authenticated Encryption with Associated Data"
  183. +
  184. +config CRYPTO_CCM
  185. + tristate "CCM support"
  186. + select CRYPTO_CTR
  187. + select CRYPTO_AEAD
  188. + help
  189. + Support for Counter with CBC MAC. Required for IPsec.
  190. +
  191. +config CRYPTO_GCM
  192. + tristate "GCM/GMAC support"
  193. + select CRYPTO_CTR
  194. + select CRYPTO_AEAD
  195. + select CRYPTO_GHASH
  196. + help
  197. + Support for Galois/Counter Mode (GCM) and Galois Message
  198. + Authentication Code (GMAC). Required for IPSec.
  199. +
  200. +config CRYPTO_SEQIV
  201. + tristate "Sequence Number IV Generator"
  202. + select CRYPTO_AEAD
  203. + select CRYPTO_BLKCIPHER
  204. + select CRYPTO_RNG
  205. + help
  206. + This IV generator generates an IV based on a sequence number by
  207. + xoring it with a salt. This algorithm is mainly useful for CTR
  208. +
  209. +comment "Block modes"
  210. +
  211. +config CRYPTO_CBC
  212. + tristate "CBC support"
  213. + select CRYPTO_BLKCIPHER
  214. + select CRYPTO_MANAGER
  215. + help
  216. + CBC: Cipher Block Chaining mode
  217. + This block cipher algorithm is required for IPSec.
  218. +
  219. +config CRYPTO_CTR
  220. + tristate "CTR support"
  221. + select CRYPTO_BLKCIPHER
  222. + select CRYPTO_SEQIV
  223. + select CRYPTO_MANAGER
  224. + help
  225. + CTR: Counter mode
  226. + This block cipher algorithm is required for IPSec.
  227. +
  228. +config CRYPTO_CTS
  229. + tristate "CTS support"
  230. + select CRYPTO_BLKCIPHER
  231. + help
  232. + CTS: Cipher Text Stealing
  233. + This is the Cipher Text Stealing mode as described by
  234. + Section 8 of rfc2040 and referenced by rfc3962.
  235. + (rfc3962 includes errata information in its Appendix A)
  236. + This mode is required for Kerberos gss mechanism support
  237. + for AES encryption.
  238. +
  239. +config CRYPTO_ECB
  240. + tristate "ECB support"
  241. + select CRYPTO_BLKCIPHER
  242. + select CRYPTO_MANAGER
  243. + help
  244. + ECB: Electronic CodeBook mode
  245. + This is the simplest block cipher algorithm. It simply encrypts
  246. + the input block by block.
  247. +
  248. +config CRYPTO_LRW
  249. + tristate "LRW support (EXPERIMENTAL)"
  250. + depends on EXPERIMENTAL
  251. + select CRYPTO_BLKCIPHER
  252. + select CRYPTO_MANAGER
  253. + select CRYPTO_GF128MUL
  254. + help
  255. + LRW: Liskov Rivest Wagner, a tweakable, non malleable, non movable
  256. + narrow block cipher mode for dm-crypt. Use it with cipher
  257. + specification string aes-lrw-benbi, the key must be 256, 320 or 384.
  258. + The first 128, 192 or 256 bits in the key are used for AES and the
  259. + rest is used to tie each cipher block to its logical position.
  260. +
  261. +config CRYPTO_PCBC
  262. + tristate "PCBC support"
  263. + select CRYPTO_BLKCIPHER
  264. + select CRYPTO_MANAGER
  265. + help
  266. + PCBC: Propagating Cipher Block Chaining mode
  267. + This block cipher algorithm is required for RxRPC.
  268. +
  269. +config CRYPTO_XTS
  270. + tristate "XTS support (EXPERIMENTAL)"
  271. + depends on EXPERIMENTAL
  272. + select CRYPTO_BLKCIPHER
  273. + select CRYPTO_MANAGER
  274. + select CRYPTO_GF128MUL
  275. + help
  276. + XTS: IEEE1619/D16 narrow block cipher use with aes-xts-plain,
  277. + key size 256, 384 or 512 bits. This implementation currently
  278. + can't handle a sectorsize which is not a multiple of 16 bytes.
  279. +
  280. +config CRYPTO_FPU
  281. + tristate
  282. + select CRYPTO_BLKCIPHER
  283. + select CRYPTO_MANAGER
  284. +
  285. +comment "Hash modes"
  286. +
  287. +config CRYPTO_HMAC
  288. + tristate "HMAC support"
  289. + select CRYPTO_HASH
  290. + select CRYPTO_MANAGER
  291. + help
  292. + HMAC: Keyed-Hashing for Message Authentication (RFC2104).
  293. + This is required for IPSec.
  294. +
  295. +config CRYPTO_XCBC
  296. + tristate "XCBC support"
  297. + depends on EXPERIMENTAL
  298. + select CRYPTO_HASH
  299. + select CRYPTO_MANAGER
  300. + help
  301. + XCBC: Keyed-Hashing with encryption algorithm
  302. + http://www.ietf.org/rfc/rfc3566.txt
  303. + http://csrc.nist.gov/encryption/modes/proposedmodes/
  304. + xcbc-mac/xcbc-mac-spec.pdf
  305. +
  306. +config CRYPTO_VMAC
  307. + tristate "VMAC support"
  308. + depends on EXPERIMENTAL
  309. + select CRYPTO_HASH
  310. + select CRYPTO_MANAGER
  311. + help
  312. + VMAC is a message authentication algorithm designed for
  313. + very high speed on 64-bit architectures.
  314. +
  315. + See also:
  316. + <http://fastcrypto.org/vmac>
  317. +
  318. +comment "Digest"
  319. +
  320. +config CRYPTO_CRC32C
  321. + tristate "CRC32c CRC algorithm"
  322. + select CRYPTO_HASH
  323. + help
  324. + Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used
  325. + by iSCSI for header and data digests and by others.
  326. + See Castagnoli93. Module will be crc32c.
  327. +
  328. +config CRYPTO_CRC32C_INTEL
  329. + tristate "CRC32c INTEL hardware acceleration"
  330. + depends on X86
  331. + select CRYPTO_HASH
  332. + help
  333. + In Intel processor with SSE4.2 supported, the processor will
  334. + support CRC32C implementation using hardware accelerated CRC32
  335. + instruction. This option will create 'crc32c-intel' module,
  336. + which will enable any routine to use the CRC32 instruction to
  337. + gain performance compared with software implementation.
  338. + Module will be crc32c-intel.
  339. +
  340. +config CRYPTO_GHASH
  341. + tristate "GHASH digest algorithm"
  342. + select CRYPTO_SHASH
  343. + select CRYPTO_GF128MUL
  344. + help
  345. + GHASH is message digest algorithm for GCM (Galois/Counter Mode).
  346. +
  347. +config CRYPTO_MD4
  348. + tristate "MD4 digest algorithm"
  349. + select CRYPTO_HASH
  350. + help
  351. + MD4 message digest algorithm (RFC1320).
  352. +
  353. +config CRYPTO_MD5
  354. + tristate "MD5 digest algorithm"
  355. + select CRYPTO_HASH
  356. + help
  357. + MD5 message digest algorithm (RFC1321).
  358. +
  359. +config CRYPTO_MICHAEL_MIC
  360. + tristate "Michael MIC keyed digest algorithm"
  361. + select CRYPTO_HASH
  362. + help
  363. + Michael MIC is used for message integrity protection in TKIP
  364. + (IEEE 802.11i). This algorithm is required for TKIP, but it
  365. + should not be used for other purposes because of the weakness
  366. + of the algorithm.
  367. +
  368. +config CRYPTO_RMD128
  369. + tristate "RIPEMD-128 digest algorithm"
  370. + select CRYPTO_HASH
  371. + help
  372. + RIPEMD-128 (ISO/IEC 10118-3:2004).
  373. +
  374. + RIPEMD-128 is a 128-bit cryptographic hash function. It should only
  375. + to be used as a secure replacement for RIPEMD. For other use cases
  376. + RIPEMD-160 should be used.
  377. +
  378. + Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
  379. + See <http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>
  380. +
  381. +config CRYPTO_RMD160
  382. + tristate "RIPEMD-160 digest algorithm"
  383. + select CRYPTO_HASH
  384. + help
  385. + RIPEMD-160 (ISO/IEC 10118-3:2004).
  386. +
  387. + RIPEMD-160 is a 160-bit cryptographic hash function. It is intended
  388. + to be used as a secure replacement for the 128-bit hash functions
  389. + MD4, MD5 and it's predecessor RIPEMD
  390. + (not to be confused with RIPEMD-128).
  391. +
  392. + It's speed is comparable to SHA1 and there are no known attacks
  393. + against RIPEMD-160.
  394. +
  395. + Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
  396. + See <http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>
  397. +
  398. +config CRYPTO_RMD256
  399. + tristate "RIPEMD-256 digest algorithm"
  400. + select CRYPTO_HASH
  401. + help
  402. + RIPEMD-256 is an optional extension of RIPEMD-128 with a
  403. + 256 bit hash. It is intended for applications that require
  404. + longer hash-results, without needing a larger security level
  405. + (than RIPEMD-128).
  406. +
  407. + Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
  408. + See <http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>
  409. +
  410. +config CRYPTO_RMD320
  411. + tristate "RIPEMD-320 digest algorithm"
  412. + select CRYPTO_HASH
  413. + help
  414. + RIPEMD-320 is an optional extension of RIPEMD-160 with a
  415. + 320 bit hash. It is intended for applications that require
  416. + longer hash-results, without needing a larger security level
  417. + (than RIPEMD-160).
  418. +
  419. + Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
  420. + See <http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>
  421. +
  422. +config CRYPTO_SHA1
  423. + tristate "SHA1 digest algorithm"
  424. + select CRYPTO_HASH
  425. + help
  426. + SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
  427. +
  428. +config CRYPTO_SHA256
  429. + tristate "SHA224 and SHA256 digest algorithm"
  430. + select CRYPTO_HASH
  431. + help
  432. + SHA256 secure hash standard (DFIPS 180-2).
  433. +
  434. + This version of SHA implements a 256 bit hash with 128 bits of
  435. + security against collision attacks.
  436. +
  437. + This code also includes SHA-224, a 224 bit hash with 112 bits
  438. + of security against collision attacks.
  439. +
  440. +config CRYPTO_SHA512
  441. + tristate "SHA384 and SHA512 digest algorithms"
  442. + select CRYPTO_HASH
  443. + help
  444. + SHA512 secure hash standard (DFIPS 180-2).
  445. +
  446. + This version of SHA implements a 512 bit hash with 256 bits of
  447. + security against collision attacks.
  448. +
  449. + This code also includes SHA-384, a 384 bit hash with 192 bits
  450. + of security against collision attacks.
  451. +
  452. +config CRYPTO_TGR192
  453. + tristate "Tiger digest algorithms"
  454. + select CRYPTO_HASH
  455. + help
  456. + Tiger hash algorithm 192, 160 and 128-bit hashes
  457. +
  458. + Tiger is a hash function optimized for 64-bit processors while
  459. + still having decent performance on 32-bit processors.
  460. + Tiger was developed by Ross Anderson and Eli Biham.
  461. +
  462. + See also:
  463. + <http://www.cs.technion.ac.il/~biham/Reports/Tiger/>.
  464. +
  465. +config CRYPTO_WP512
  466. + tristate "Whirlpool digest algorithms"
  467. + select CRYPTO_HASH
  468. + help
  469. + Whirlpool hash algorithm 512, 384 and 256-bit hashes
  470. +
  471. + Whirlpool-512 is part of the NESSIE cryptographic primitives.
  472. + Whirlpool will be part of the ISO/IEC 10118-3:2003(E) standard
  473. +
  474. + See also:
  475. + <http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html>
  476. +
  477. +config CRYPTO_GHASH_CLMUL_NI_INTEL
  478. + tristate "GHASH digest algorithm (CLMUL-NI accelerated)"
  479. + depends on (X86 || UML_X86) && 64BIT
  480. + select CRYPTO_SHASH
  481. + select CRYPTO_CRYPTD
  482. + help
  483. + GHASH is message digest algorithm for GCM (Galois/Counter Mode).
  484. + The implementation is accelerated by CLMUL-NI of Intel.
  485. +
  486. +comment "Ciphers"
  487. +
  488. +config CRYPTO_AES
  489. + tristate "AES cipher algorithms"
  490. + select CRYPTO_ALGAPI
  491. + help
  492. + AES cipher algorithms (FIPS-197). AES uses the Rijndael
  493. + algorithm.
  494. +
  495. + Rijndael appears to be consistently a very good performer in
  496. + both hardware and software across a wide range of computing
  497. + environments regardless of its use in feedback or non-feedback
  498. + modes. Its key setup time is excellent, and its key agility is
  499. + good. Rijndael's very low memory requirements make it very well
  500. + suited for restricted-space environments, in which it also
  501. + demonstrates excellent performance. Rijndael's operations are
  502. + among the easiest to defend against power and timing attacks.
  503. +
  504. + The AES specifies three key sizes: 128, 192 and 256 bits
  505. +
  506. + See <http://csrc.nist.gov/CryptoToolkit/aes/> for more information.
  507. +
  508. +config CRYPTO_AES_586
  509. + tristate "AES cipher algorithms (i586)"
  510. + depends on (X86 || UML_X86) && !64BIT
  511. + select CRYPTO_ALGAPI
  512. + select CRYPTO_AES
  513. + help
  514. + AES cipher algorithms (FIPS-197). AES uses the Rijndael
  515. + algorithm.
  516. +
  517. + Rijndael appears to be consistently a very good performer in
  518. + both hardware and software across a wide range of computing
  519. + environments regardless of its use in feedback or non-feedback
  520. + modes. Its key setup time is excellent, and its key agility is
  521. + good. Rijndael's very low memory requirements make it very well
  522. + suited for restricted-space environments, in which it also
  523. + demonstrates excellent performance. Rijndael's operations are
  524. + among the easiest to defend against power and timing attacks.
  525. +
  526. + The AES specifies three key sizes: 128, 192 and 256 bits
  527. +
  528. + See <http://csrc.nist.gov/encryption/aes/> for more information.
  529. +
  530. +config CRYPTO_AES_X86_64
  531. + tristate "AES cipher algorithms (x86_64)"
  532. + depends on (X86 || UML_X86) && 64BIT
  533. + select CRYPTO_ALGAPI
  534. + select CRYPTO_AES
  535. + help
  536. + AES cipher algorithms (FIPS-197). AES uses the Rijndael
  537. + algorithm.
  538. +
  539. + Rijndael appears to be consistently a very good performer in
  540. + both hardware and software across a wide range of computing
  541. + environments regardless of its use in feedback or non-feedback
  542. + modes. Its key setup time is excellent, and its key agility is
  543. + good. Rijndael's very low memory requirements make it very well
  544. + suited for restricted-space environments, in which it also
  545. + demonstrates excellent performance. Rijndael's operations are
  546. + among the easiest to defend against power and timing attacks.
  547. +
  548. + The AES specifies three key sizes: 128, 192 and 256 bits
  549. +
  550. + See <http://csrc.nist.gov/encryption/aes/> for more information.
  551. +
  552. +config CRYPTO_AES_NI_INTEL
  553. + tristate "AES cipher algorithms (AES-NI)"
  554. + depends on (X86 || UML_X86)
  555. + select CRYPTO_AES_X86_64 if 64BIT
  556. + select CRYPTO_AES_586 if !64BIT
  557. + select CRYPTO_CRYPTD
  558. + select CRYPTO_ALGAPI
  559. + select CRYPTO_FPU
  560. + help
  561. + Use Intel AES-NI instructions for AES algorithm.
  562. +
  563. + AES cipher algorithms (FIPS-197). AES uses the Rijndael
  564. + algorithm.
  565. +
  566. + Rijndael appears to be consistently a very good performer in
  567. + both hardware and software across a wide range of computing
  568. + environments regardless of its use in feedback or non-feedback
  569. + modes. Its key setup time is excellent, and its key agility is
  570. + good. Rijndael's very low memory requirements make it very well
  571. + suited for restricted-space environments, in which it also
  572. + demonstrates excellent performance. Rijndael's operations are
  573. + among the easiest to defend against power and timing attacks.
  574. +
  575. + The AES specifies three key sizes: 128, 192 and 256 bits
  576. +
  577. + See <http://csrc.nist.gov/encryption/aes/> for more information.
  578. +
  579. + In addition to AES cipher algorithm support, the acceleration
  580. + for some popular block cipher mode is supported too, including
  581. + ECB, CBC, LRW, PCBC, XTS. The 64 bit version has additional
  582. + acceleration for CTR.
  583. +
  584. +config CRYPTO_ANUBIS
  585. + tristate "Anubis cipher algorithm"
  586. + select CRYPTO_ALGAPI
  587. + help
  588. + Anubis cipher algorithm.
  589. +
  590. + Anubis is a variable key length cipher which can use keys from
  591. + 128 bits to 320 bits in length. It was evaluated as a entrant
  592. + in the NESSIE competition.
  593. +
  594. + See also:
  595. + <https://www.cosic.esat.kuleuven.be/nessie/reports/>
  596. + <http://www.larc.usp.br/~pbarreto/AnubisPage.html>
  597. +
  598. +config CRYPTO_ARC4
  599. + tristate "ARC4 cipher algorithm"
  600. + select CRYPTO_ALGAPI
  601. + help
  602. + ARC4 cipher algorithm.
  603. +
  604. + ARC4 is a stream cipher using keys ranging from 8 bits to 2048
  605. + bits in length. This algorithm is required for driver-based
  606. + WEP, but it should not be for other purposes because of the
  607. + weakness of the algorithm.
  608. +
  609. +config CRYPTO_BLOWFISH
  610. + tristate "Blowfish cipher algorithm"
  611. + select CRYPTO_ALGAPI
  612. + help
  613. + Blowfish cipher algorithm, by Bruce Schneier.
  614. +
  615. + This is a variable key length cipher which can use keys from 32
  616. + bits to 448 bits in length. It's fast, simple and specifically
  617. + designed for use on "large microprocessors".
  618. +
  619. + See also:
  620. + <http://www.schneier.com/blowfish.html>
  621. +
  622. +config CRYPTO_CAMELLIA
  623. + tristate "Camellia cipher algorithms"
  624. + depends on CRYPTO
  625. + select CRYPTO_ALGAPI
  626. + help
  627. + Camellia cipher algorithms module.
  628. +
  629. + Camellia is a symmetric key block cipher developed jointly
  630. + at NTT and Mitsubishi Electric Corporation.
  631. +
  632. + The Camellia specifies three key sizes: 128, 192 and 256 bits.
  633. +
  634. + See also:
  635. + <https://info.isl.ntt.co.jp/crypt/eng/camellia/index_s.html>
  636. +
  637. +config CRYPTO_CAST5
  638. + tristate "CAST5 (CAST-128) cipher algorithm"
  639. + select CRYPTO_ALGAPI
  640. + help
  641. + The CAST5 encryption algorithm (synonymous with CAST-128) is
  642. + described in RFC2144.
  643. +
  644. +config CRYPTO_CAST6
  645. + tristate "CAST6 (CAST-256) cipher algorithm"
  646. + select CRYPTO_ALGAPI
  647. + help
  648. + The CAST6 encryption algorithm (synonymous with CAST-256) is
  649. + described in RFC2612.
  650. +
  651. +config CRYPTO_DES
  652. + tristate "DES and Triple DES EDE cipher algorithms"
  653. + select CRYPTO_ALGAPI
  654. + help
  655. + DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
  656. +
  657. +config CRYPTO_FCRYPT
  658. + tristate "FCrypt cipher algorithm"
  659. + select CRYPTO_ALGAPI
  660. + select CRYPTO_BLKCIPHER
  661. + help
  662. + FCrypt algorithm used by RxRPC.
  663. +
  664. +config CRYPTO_KHAZAD
  665. + tristate "Khazad cipher algorithm"
  666. + select CRYPTO_ALGAPI
  667. + help
  668. + Khazad cipher algorithm.
  669. +
  670. + Khazad was a finalist in the initial NESSIE competition. It is
  671. + an algorithm optimized for 64-bit processors with good performance
  672. + on 32-bit processors. Khazad uses an 128 bit key size.
  673. +
  674. + See also:
  675. + <http://www.larc.usp.br/~pbarreto/KhazadPage.html>
  676. +
  677. +config CRYPTO_SALSA20
  678. + tristate "Salsa20 stream cipher algorithm (EXPERIMENTAL)"
  679. + depends on EXPERIMENTAL
  680. + select CRYPTO_BLKCIPHER
  681. + help
  682. + Salsa20 stream cipher algorithm.
  683. +
  684. + Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT
  685. + Stream Cipher Project. See <http://www.ecrypt.eu.org/stream/>
  686. +
  687. + The Salsa20 stream cipher algorithm is designed by Daniel J.
  688. + Bernstein <djb@cr.yp.to>. See <http://cr.yp.to/snuffle.html>
  689. +
  690. +config CRYPTO_SALSA20_586
  691. + tristate "Salsa20 stream cipher algorithm (i586) (EXPERIMENTAL)"
  692. + depends on (X86 || UML_X86) && !64BIT
  693. + depends on EXPERIMENTAL
  694. + select CRYPTO_BLKCIPHER
  695. + help
  696. + Salsa20 stream cipher algorithm.
  697. +
  698. + Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT
  699. + Stream Cipher Project. See <http://www.ecrypt.eu.org/stream/>
  700. +
  701. + The Salsa20 stream cipher algorithm is designed by Daniel J.
  702. + Bernstein <djb@cr.yp.to>. See <http://cr.yp.to/snuffle.html>
  703. +
  704. +config CRYPTO_SALSA20_X86_64
  705. + tristate "Salsa20 stream cipher algorithm (x86_64) (EXPERIMENTAL)"
  706. + depends on (X86 || UML_X86) && 64BIT
  707. + depends on EXPERIMENTAL
  708. + select CRYPTO_BLKCIPHER
  709. + help
  710. + Salsa20 stream cipher algorithm.
  711. +
  712. + Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT
  713. + Stream Cipher Project. See <http://www.ecrypt.eu.org/stream/>
  714. +
  715. + The Salsa20 stream cipher algorithm is designed by Daniel J.
  716. + Bernstein <djb@cr.yp.to>. See <http://cr.yp.to/snuffle.html>
  717. +
  718. +config CRYPTO_SEED
  719. + tristate "SEED cipher algorithm"
  720. + select CRYPTO_ALGAPI
  721. + help
  722. + SEED cipher algorithm (RFC4269).
  723. +
  724. + SEED is a 128-bit symmetric key block cipher that has been
  725. + developed by KISA (Korea Information Security Agency) as a
  726. + national standard encryption algorithm of the Republic of Korea.
  727. + It is a 16 round block cipher with the key size of 128 bit.
  728. +
  729. + See also:
  730. + <http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp>
  731. +
  732. +config CRYPTO_SERPENT
  733. + tristate "Serpent cipher algorithm"
  734. + select CRYPTO_ALGAPI
  735. + help
  736. + Serpent cipher algorithm, by Anderson, Biham & Knudsen.
  737. +
  738. + Keys are allowed to be from 0 to 256 bits in length, in steps
  739. + of 8 bits. Also includes the 'Tnepres' algorithm, a reversed
  740. + variant of Serpent for compatibility with old kerneli.org code.
  741. +
  742. + See also:
  743. + <http://www.cl.cam.ac.uk/~rja14/serpent.html>
  744. +
  745. +config CRYPTO_TEA
  746. + tristate "TEA, XTEA and XETA cipher algorithms"
  747. + select CRYPTO_ALGAPI
  748. + help
  749. + TEA cipher algorithm.
  750. +
  751. + Tiny Encryption Algorithm is a simple cipher that uses
  752. + many rounds for security. It is very fast and uses
  753. + little memory.
  754. +
  755. + Xtendend Tiny Encryption Algorithm is a modification to
  756. + the TEA algorithm to address a potential key weakness
  757. + in the TEA algorithm.
  758. +
  759. + Xtendend Encryption Tiny Algorithm is a mis-implementation
  760. + of the XTEA algorithm for compatibility purposes.
  761. +
  762. +config CRYPTO_TWOFISH
  763. + tristate "Twofish cipher algorithm"
  764. + select CRYPTO_ALGAPI
  765. + select CRYPTO_TWOFISH_COMMON
  766. + help
  767. + Twofish cipher algorithm.
  768. +
  769. + Twofish was submitted as an AES (Advanced Encryption Standard)
  770. + candidate cipher by researchers at CounterPane Systems. It is a
  771. + 16 round block cipher supporting key sizes of 128, 192, and 256
  772. + bits.
  773. +
  774. + See also:
  775. + <http://www.schneier.com/twofish.html>
  776. +
  777. +config CRYPTO_TWOFISH_COMMON
  778. + tristate
  779. + help
  780. + Common parts of the Twofish cipher algorithm shared by the
  781. + generic c and the assembler implementations.
  782. +
  783. +config CRYPTO_TWOFISH_586
  784. + tristate "Twofish cipher algorithms (i586)"
  785. + depends on (X86 || UML_X86) && !64BIT
  786. + select CRYPTO_ALGAPI
  787. + select CRYPTO_TWOFISH_COMMON
  788. + help
  789. + Twofish cipher algorithm.
  790. +
  791. + Twofish was submitted as an AES (Advanced Encryption Standard)
  792. + candidate cipher by researchers at CounterPane Systems. It is a
  793. + 16 round block cipher supporting key sizes of 128, 192, and 256
  794. + bits.
  795. +
  796. + See also:
  797. + <http://www.schneier.com/twofish.html>
  798. +
  799. +config CRYPTO_TWOFISH_X86_64
  800. + tristate "Twofish cipher algorithm (x86_64)"
  801. + depends on (X86 || UML_X86) && 64BIT
  802. + select CRYPTO_ALGAPI
  803. + select CRYPTO_TWOFISH_COMMON
  804. + help
  805. + Twofish cipher algorithm (x86_64).
  806. +
  807. + Twofish was submitted as an AES (Advanced Encryption Standard)
  808. + candidate cipher by researchers at CounterPane Systems. It is a
  809. + 16 round block cipher supporting key sizes of 128, 192, and 256
  810. + bits.
  811. +
  812. + See also:
  813. + <http://www.schneier.com/twofish.html>
  814. +
  815. +comment "Compression"
  816. +
  817. +config CRYPTO_DEFLATE
  818. + tristate "Deflate compression algorithm"
  819. + select CRYPTO_ALGAPI
  820. + select ZLIB_INFLATE
  821. + select ZLIB_DEFLATE
  822. + help
  823. + This is the Deflate algorithm (RFC1951), specified for use in
  824. + IPSec with the IPCOMP protocol (RFC3173, RFC2394).
  825. +
  826. + You will most probably want this if using IPSec.
  827. +
  828. +config CRYPTO_ZLIB
  829. + tristate "Zlib compression algorithm"
  830. + select CRYPTO_PCOMP
  831. + select ZLIB_INFLATE
  832. + select ZLIB_DEFLATE
  833. + select NLATTR
  834. + help
  835. + This is the zlib algorithm.
  836. +
  837. +config CRYPTO_LZO
  838. + tristate "LZO compression algorithm"
  839. + select CRYPTO_ALGAPI
  840. + select LZO_COMPRESS
  841. + select LZO_DECOMPRESS
  842. + help
  843. + This is the LZO algorithm.
  844. +
  845. +comment "Random Number Generation"
  846. +
  847. +config CRYPTO_ANSI_CPRNG
  848. + tristate "Pseudo Random Number Generation for Cryptographic modules"
  849. + default m
  850. + select CRYPTO_AES
  851. + select CRYPTO_RNG
  852. + help
  853. + This option enables the generic pseudo random number generator
  854. + for cryptographic modules. Uses the Algorithm specified in
  855. + ANSI X9.31 A.2.4. Note that this option must be enabled if
  856. + CRYPTO_FIPS is selected
  857. +
  858. +config CRYPTO_USER_API
  859. + tristate
  860. +
  861. +config CRYPTO_USER_API_HASH
  862. + tristate "User-space interface for hash algorithms"
  863. + depends on NET
  864. + select CRYPTO_HASH
  865. + select CRYPTO_USER_API
  866. + help
  867. + This option enables the user-spaces interface for hash
  868. + algorithms.
  869. +
  870. +config CRYPTO_USER_API_SKCIPHER
  871. + tristate "User-space interface for symmetric key cipher algorithms"
  872. + depends on NET
  873. + select CRYPTO_BLKCIPHER
  874. + select CRYPTO_USER_API
  875. + help
  876. + This option enables the user-spaces interface for symmetric
  877. + key cipher algorithms.
  878. +
  879. +source "drivers/crypto/Kconfig"
  880. +
  881. +endif # if CRYPTO
  882. diff -Nur linux-2.6.39.orig/crypto/Makefile linux-2.6.39/crypto/Makefile
  883. --- linux-2.6.39.orig/crypto/Makefile 2011-05-19 06:06:34.000000000 +0200
  884. +++ linux-2.6.39/crypto/Makefile 2011-07-31 11:31:53.014664900 +0200
  885. @@ -89,6 +89,8 @@
  886. obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
  887. obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
  888. +obj-$(CONFIG_OCF_OCF) += ocf/
  889. +
  890. #
  891. # generic algorithms and the async_tx api
  892. #
  893. diff -Nur linux-2.6.39.orig/crypto/Makefile.orig linux-2.6.39/crypto/Makefile.orig
  894. --- linux-2.6.39.orig/crypto/Makefile.orig 1970-01-01 01:00:00.000000000 +0100
  895. +++ linux-2.6.39/crypto/Makefile.orig 2011-05-19 06:06:34.000000000 +0200
  896. @@ -0,0 +1,96 @@
  897. +#
  898. +# Cryptographic API
  899. +#
  900. +
  901. +obj-$(CONFIG_CRYPTO) += crypto.o
  902. +crypto-y := api.o cipher.o compress.o
  903. +
  904. +obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o
  905. +
  906. +obj-$(CONFIG_CRYPTO_FIPS) += fips.o
  907. +
  908. +crypto_algapi-$(CONFIG_PROC_FS) += proc.o
  909. +crypto_algapi-y := algapi.o scatterwalk.o $(crypto_algapi-y)
  910. +obj-$(CONFIG_CRYPTO_ALGAPI2) += crypto_algapi.o
  911. +
  912. +obj-$(CONFIG_CRYPTO_AEAD2) += aead.o
  913. +
  914. +crypto_blkcipher-y := ablkcipher.o
  915. +crypto_blkcipher-y += blkcipher.o
  916. +obj-$(CONFIG_CRYPTO_BLKCIPHER2) += crypto_blkcipher.o
  917. +obj-$(CONFIG_CRYPTO_BLKCIPHER2) += chainiv.o
  918. +obj-$(CONFIG_CRYPTO_BLKCIPHER2) += eseqiv.o
  919. +obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o
  920. +
  921. +crypto_hash-y += ahash.o
  922. +crypto_hash-y += shash.o
  923. +obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
  924. +
  925. +obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
  926. +
  927. +cryptomgr-y := algboss.o testmgr.o
  928. +
  929. +obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
  930. +obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
  931. +obj-$(CONFIG_CRYPTO_VMAC) += vmac.o
  932. +obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o
  933. +obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
  934. +obj-$(CONFIG_CRYPTO_MD4) += md4.o
  935. +obj-$(CONFIG_CRYPTO_MD5) += md5.o
  936. +obj-$(CONFIG_CRYPTO_RMD128) += rmd128.o
  937. +obj-$(CONFIG_CRYPTO_RMD160) += rmd160.o
  938. +obj-$(CONFIG_CRYPTO_RMD256) += rmd256.o
  939. +obj-$(CONFIG_CRYPTO_RMD320) += rmd320.o
  940. +obj-$(CONFIG_CRYPTO_SHA1) += sha1_generic.o
  941. +obj-$(CONFIG_CRYPTO_SHA256) += sha256_generic.o
  942. +obj-$(CONFIG_CRYPTO_SHA512) += sha512_generic.o
  943. +obj-$(CONFIG_CRYPTO_WP512) += wp512.o
  944. +obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o
  945. +obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o
  946. +obj-$(CONFIG_CRYPTO_ECB) += ecb.o
  947. +obj-$(CONFIG_CRYPTO_CBC) += cbc.o
  948. +obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o
  949. +obj-$(CONFIG_CRYPTO_CTS) += cts.o
  950. +obj-$(CONFIG_CRYPTO_LRW) += lrw.o
  951. +obj-$(CONFIG_CRYPTO_XTS) += xts.o
  952. +obj-$(CONFIG_CRYPTO_CTR) += ctr.o
  953. +obj-$(CONFIG_CRYPTO_GCM) += gcm.o
  954. +obj-$(CONFIG_CRYPTO_CCM) += ccm.o
  955. +obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o
  956. +obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
  957. +obj-$(CONFIG_CRYPTO_DES) += des_generic.o
  958. +obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o
  959. +obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o
  960. +obj-$(CONFIG_CRYPTO_TWOFISH) += twofish_generic.o
  961. +obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o
  962. +obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o
  963. +obj-$(CONFIG_CRYPTO_AES) += aes_generic.o
  964. +obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia.o
  965. +obj-$(CONFIG_CRYPTO_CAST5) += cast5.o
  966. +obj-$(CONFIG_CRYPTO_CAST6) += cast6.o
  967. +obj-$(CONFIG_CRYPTO_ARC4) += arc4.o
  968. +obj-$(CONFIG_CRYPTO_TEA) += tea.o
  969. +obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o
  970. +obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o
  971. +obj-$(CONFIG_CRYPTO_SEED) += seed.o
  972. +obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o
  973. +obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
  974. +obj-$(CONFIG_CRYPTO_ZLIB) += zlib.o
  975. +obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
  976. +obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
  977. +obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
  978. +obj-$(CONFIG_CRYPTO_LZO) += lzo.o
  979. +obj-$(CONFIG_CRYPTO_RNG2) += rng.o
  980. +obj-$(CONFIG_CRYPTO_RNG2) += krng.o
  981. +obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o
  982. +obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
  983. +obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
  984. +obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o
  985. +obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
  986. +obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
  987. +
  988. +#
  989. +# generic algorithms and the async_tx api
  990. +#
  991. +obj-$(CONFIG_XOR_BLOCKS) += xor.o
  992. +obj-$(CONFIG_ASYNC_CORE) += async_tx/
  993. diff -Nur linux-2.6.39.orig/crypto/ocf/c7108/aes-7108.c linux-2.6.39/crypto/ocf/c7108/aes-7108.c
  994. --- linux-2.6.39.orig/crypto/ocf/c7108/aes-7108.c 1970-01-01 01:00:00.000000000 +0100
  995. +++ linux-2.6.39/crypto/ocf/c7108/aes-7108.c 2011-07-31 11:31:53.083432923 +0200
  996. @@ -0,0 +1,839 @@
  997. +/*
  998. + * Copyright (C) 2006 Micronas USA
  999. + *
  1000. + * 1. Redistributions of source code must retain the above copyright
  1001. + * notice, this list of conditions and the following disclaimer.
  1002. + * 2. Redistributions in binary form must reproduce the above copyright
  1003. + * notice, this list of conditions and the following disclaimer in the
  1004. + * documentation and/or other materials provided with the distribution.
  1005. + * 3. The name of the author may not be used to endorse or promote products
  1006. + * derived from this software without specific prior written permission.
  1007. + *
  1008. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  1009. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  1010. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  1011. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  1012. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  1013. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  1014. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  1015. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1016. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  1017. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1018. + *
  1019. + * Effort sponsored in part by the Defense Advanced Research Projects
  1020. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  1021. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  1022. + *
  1023. + */
  1024. +
  1025. +//#include <linux/config.h>
  1026. +#include <linux/module.h>
  1027. +#include <linux/init.h>
  1028. +#include <linux/list.h>
  1029. +#include <linux/slab.h>
  1030. +#include <linux/sched.h>
  1031. +#include <linux/wait.h>
  1032. +#include <linux/crypto.h>
  1033. +#include <linux/mm.h>
  1034. +#include <linux/skbuff.h>
  1035. +#include <linux/random.h>
  1036. +#include <asm/io.h>
  1037. +#include <asm/delay.h>
  1038. +//#include <asm/scatterlist.h>
  1039. +#include <linux/scatterlist.h>
  1040. +#include <linux/dma-mapping.h>
  1041. +#include <linux/highmem.h>
  1042. +#include <cryptodev.h>
  1043. +#include <uio.h>
  1044. +#include <aes-7108.h>
  1045. +
  1046. +/* Runtime mode */
  1047. +static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR;
  1048. +//static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC;
  1049. +
  1050. +static int32_t c7108_id = -1;
  1051. +static struct cipher_7108 **c7108_sessions = NULL;
  1052. +static u_int32_t c7108_sesnum = 0;
  1053. +static unsigned long iobar;
  1054. +
  1055. +/* Crypto entry points */
  1056. +static int c7108_process(void *, struct cryptop *, int);
  1057. +static int c7108_newsession(void *, u_int32_t *, struct cryptoini *);
  1058. +static int c7108_freesession(void *, u_int64_t);
  1059. +
  1060. +/* Globals */
  1061. +static int debug = 0;
  1062. +static spinlock_t csr_mutex;
  1063. +
  1064. +/* Generic controller-based lock */
  1065. +#define AES_LOCK()\
  1066. + spin_lock(&csr_mutex)
  1067. +#define AES_UNLOCK()\
  1068. + spin_unlock(&csr_mutex)
  1069. +
  1070. +/* 7108 AES register access */
  1071. +#define c7108_reg_wr8(a,d) iowrite8(d, (void*)(iobar+(a)))
  1072. +#define c7108_reg_wr16(a,d) iowrite16(d, (void*)(iobar+(a)))
  1073. +#define c7108_reg_wr32(a,d) iowrite32(d, (void*)(iobar+(a)))
  1074. +#define c7108_reg_rd8(a) ioread8((void*)(iobar+(a)))
  1075. +#define c7108_reg_rd16(a) ioread16((void*)(iobar+(a)))
  1076. +#define c7108_reg_rd32(a) ioread32((void*)(iobar+(a)))
  1077. +
  1078. +static int
  1079. +c7108_xlate_key(int klen, u8* k8ptr, u32* k32ptr)
  1080. +{
  1081. + int i, nw=0;
  1082. + nw = ((klen >= 256) ? 8 : (klen >= 192) ? 6 : 4);
  1083. + for ( i = 0; i < nw; i++) {
  1084. + k32ptr[i] = (k8ptr[i+3] << 24) | (k8ptr[i+2] << 16) |
  1085. + (k8ptr[i+1] << 8) | k8ptr[i];
  1086. +
  1087. + }
  1088. + return 0;
  1089. +}
  1090. +
  1091. +static int
  1092. +c7108_cache_key(int klen, u32* k32ptr, u8* k8ptr)
  1093. +{
  1094. + int i, nb=0;
  1095. + u8* ptr = (u8*)k32ptr;
  1096. + nb = ((klen >= 256) ? 32 : (klen >= 192) ? 24 : 16);
  1097. + for ( i = 0; i < nb; i++)
  1098. + k8ptr[i] = ptr[i];
  1099. + return 0;
  1100. +}
  1101. +
  1102. +static int
  1103. +c7108_aes_setup_dma(u32 src, u32 dst, u32 len)
  1104. +{
  1105. + if (len < 16) {
  1106. + printk("len < 16\n");
  1107. + return -10;
  1108. + }
  1109. + if (len % 16) {
  1110. + printk("len not multiple of 16\n");
  1111. + return -11;
  1112. + }
  1113. + c7108_reg_wr16(C7108_AES_DMA_SRC0_LO, (u16) src);
  1114. + c7108_reg_wr16(C7108_AES_DMA_SRC0_HI, (u16)((src & 0xffff0000) >> 16));
  1115. + c7108_reg_wr16(C7108_AES_DMA_DST0_LO, (u16) dst);
  1116. + c7108_reg_wr16(C7108_AES_DMA_DST0_HI, (u16)((dst & 0xffff0000) >> 16));
  1117. + c7108_reg_wr16(C7108_AES_DMA_LEN, (u16) ((len / 16) - 1));
  1118. +
  1119. + return 0;
  1120. +}
  1121. +
  1122. +static int
  1123. +c7108_aes_set_hw_iv(u8 iv[16])
  1124. +{
  1125. + c7108_reg_wr16(C7108_AES_IV0_LO, (u16) ((iv[1] << 8) | iv[0]));
  1126. + c7108_reg_wr16(C7108_AES_IV0_HI, (u16) ((iv[3] << 8) | iv[2]));
  1127. + c7108_reg_wr16(C7108_AES_IV1_LO, (u16) ((iv[5] << 8) | iv[4]));
  1128. + c7108_reg_wr16(C7108_AES_IV1_HI, (u16) ((iv[7] << 8) | iv[6]));
  1129. + c7108_reg_wr16(C7108_AES_IV2_LO, (u16) ((iv[9] << 8) | iv[8]));
  1130. + c7108_reg_wr16(C7108_AES_IV2_HI, (u16) ((iv[11] << 8) | iv[10]));
  1131. + c7108_reg_wr16(C7108_AES_IV3_LO, (u16) ((iv[13] << 8) | iv[12]));
  1132. + c7108_reg_wr16(C7108_AES_IV3_HI, (u16) ((iv[15] << 8) | iv[14]));
  1133. +
  1134. + return 0;
  1135. +}
  1136. +
  1137. +static void
  1138. +c7108_aes_read_dkey(u32 * dkey)
  1139. +{
  1140. + dkey[0] = (c7108_reg_rd16(C7108_AES_EKEY0_HI) << 16) |
  1141. + c7108_reg_rd16(C7108_AES_EKEY0_LO);
  1142. + dkey[1] = (c7108_reg_rd16(C7108_AES_EKEY1_HI) << 16) |
  1143. + c7108_reg_rd16(C7108_AES_EKEY1_LO);
  1144. + dkey[2] = (c7108_reg_rd16(C7108_AES_EKEY2_HI) << 16) |
  1145. + c7108_reg_rd16(C7108_AES_EKEY2_LO);
  1146. + dkey[3] = (c7108_reg_rd16(C7108_AES_EKEY3_HI) << 16) |
  1147. + c7108_reg_rd16(C7108_AES_EKEY3_LO);
  1148. + dkey[4] = (c7108_reg_rd16(C7108_AES_EKEY4_HI) << 16) |
  1149. + c7108_reg_rd16(C7108_AES_EKEY4_LO);
  1150. + dkey[5] = (c7108_reg_rd16(C7108_AES_EKEY5_HI) << 16) |
  1151. + c7108_reg_rd16(C7108_AES_EKEY5_LO);
  1152. + dkey[6] = (c7108_reg_rd16(C7108_AES_EKEY6_HI) << 16) |
  1153. + c7108_reg_rd16(C7108_AES_EKEY6_LO);
  1154. + dkey[7] = (c7108_reg_rd16(C7108_AES_EKEY7_HI) << 16) |
  1155. + c7108_reg_rd16(C7108_AES_EKEY7_LO);
  1156. +}
  1157. +
  1158. +static int
  1159. +c7108_aes_cipher(int op,
  1160. + u32 dst,
  1161. + u32 src,
  1162. + u32 len,
  1163. + int klen,
  1164. + u16 mode,
  1165. + u32 key[8],
  1166. + u8 iv[16])
  1167. +{
  1168. + int rv = 0, cnt=0;
  1169. + u16 ctrl = 0, stat = 0;
  1170. +
  1171. + AES_LOCK();
  1172. +
  1173. + /* Setup key length */
  1174. + if (klen == 128) {
  1175. + ctrl |= C7108_AES_KEY_LEN_128;
  1176. + } else if (klen == 192) {
  1177. + ctrl |= C7108_AES_KEY_LEN_192;
  1178. + } else if (klen == 256) {
  1179. + ctrl |= C7108_AES_KEY_LEN_256;
  1180. + } else {
  1181. + AES_UNLOCK();
  1182. + return -3;
  1183. + }
  1184. +
  1185. + /* Check opcode */
  1186. + if (C7108_AES_ENCRYPT == op) {
  1187. + ctrl |= C7108_AES_ENCRYPT;
  1188. + } else if (C7108_AES_DECRYPT == op) {
  1189. + ctrl |= C7108_AES_DECRYPT;
  1190. + } else {
  1191. + AES_UNLOCK();
  1192. + return -4;
  1193. + }
  1194. +
  1195. + /* check mode */
  1196. + if ( (mode != C7108_AES_CTRL_MODE_CBC) &&
  1197. + (mode != C7108_AES_CTRL_MODE_CFB) &&
  1198. + (mode != C7108_AES_CTRL_MODE_OFB) &&
  1199. + (mode != C7108_AES_CTRL_MODE_CTR) &&
  1200. + (mode != C7108_AES_CTRL_MODE_ECB) ) {
  1201. + AES_UNLOCK();
  1202. + return -5;
  1203. + }
  1204. +
  1205. + /* Now set mode */
  1206. + ctrl |= mode;
  1207. +
  1208. + /* For CFB, OFB, and CTR, neither backward key
  1209. + * expansion nor key inversion is required.
  1210. + */
  1211. + if ( (C7108_AES_DECRYPT == op) &&
  1212. + (C7108_AES_CTRL_MODE_CBC == mode ||
  1213. + C7108_AES_CTRL_MODE_ECB == mode ) ){
  1214. +
  1215. + /* Program Key */
  1216. + c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[4]);
  1217. + c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[4] >> 16));
  1218. + c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[5]);
  1219. + c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[5] >> 16));
  1220. + c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[6]);
  1221. + c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[6] >> 16));
  1222. + c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[7]);
  1223. + c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[7] >> 16));
  1224. + c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[2]);
  1225. + c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[2] >> 16));
  1226. + c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[3]);
  1227. + c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[3] >> 16));
  1228. +
  1229. +
  1230. + if (192 == klen) {
  1231. + c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[7]);
  1232. + c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[7] >> 16));
  1233. + c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[7]);
  1234. + c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[7] >> 16));
  1235. +
  1236. + } else if (256 == klen) {
  1237. + /* 256 */
  1238. + c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[0]);
  1239. + c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[0] >> 16));
  1240. + c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[1]);
  1241. + c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[1] >> 16));
  1242. +
  1243. + }
  1244. +
  1245. + } else {
  1246. + /* Program Key */
  1247. + c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[0]);
  1248. + c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[0] >> 16));
  1249. + c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[1]);
  1250. + c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[1] >> 16));
  1251. + c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[2]);
  1252. + c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[2] >> 16));
  1253. + c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[3]);
  1254. + c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[3] >> 16));
  1255. + c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[4]);
  1256. + c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[4] >> 16));
  1257. + c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[5]);
  1258. + c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[5] >> 16));
  1259. + c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[6]);
  1260. + c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[6] >> 16));
  1261. + c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[7]);
  1262. + c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[7] >> 16));
  1263. +
  1264. + }
  1265. +
  1266. + /* Set IV always */
  1267. + c7108_aes_set_hw_iv(iv);
  1268. +
  1269. + /* Program DMA addresses */
  1270. + if ((rv = c7108_aes_setup_dma(src, dst, len)) < 0) {
  1271. + AES_UNLOCK();
  1272. + return rv;
  1273. + }
  1274. +
  1275. +
  1276. + /* Start AES cipher */
  1277. + c7108_reg_wr16(C7108_AES_CTRL, ctrl | C7108_AES_GO);
  1278. +
  1279. + //printk("Ctrl: 0x%x\n", ctrl | C7108_AES_GO);
  1280. + do {
  1281. + /* TODO: interrupt mode */
  1282. + // printk("aes_stat=0x%x\n", stat);
  1283. + //udelay(100);
  1284. + } while ((cnt++ < 1000000) &&
  1285. + !((stat=c7108_reg_rd16(C7108_AES_CTRL))&C7108_AES_OP_DONE));
  1286. +
  1287. +
  1288. + if ((mode == C7108_AES_CTRL_MODE_ECB)||
  1289. + (mode == C7108_AES_CTRL_MODE_CBC)) {
  1290. + /* Save out key when the lock is held ... */
  1291. + c7108_aes_read_dkey(key);
  1292. + }
  1293. +
  1294. + AES_UNLOCK();
  1295. + return 0;
  1296. +
  1297. +}
  1298. +
  1299. +/*
  1300. + * Generate a new crypto device session.
  1301. + */
  1302. +static int
  1303. +c7108_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
  1304. +{
  1305. + struct cipher_7108 **swd;
  1306. + u_int32_t i;
  1307. + char *algo;
  1308. + int mode, xfm_type;
  1309. +
  1310. + dprintk("%s()\n", __FUNCTION__);
  1311. + if (sid == NULL || cri == NULL) {
  1312. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  1313. + return EINVAL;
  1314. + }
  1315. +
  1316. + if (c7108_sessions) {
  1317. + for (i = 1; i < c7108_sesnum; i++)
  1318. + if (c7108_sessions[i] == NULL)
  1319. + break;
  1320. + } else
  1321. + i = 1; /* NB: to silence compiler warning */
  1322. +
  1323. + if (c7108_sessions == NULL || i == c7108_sesnum) {
  1324. + if (c7108_sessions == NULL) {
  1325. + i = 1; /* We leave c7108_sessions[0] empty */
  1326. + c7108_sesnum = CRYPTO_SW_SESSIONS;
  1327. + } else
  1328. + c7108_sesnum *= 2;
  1329. +
  1330. + swd = kmalloc(c7108_sesnum * sizeof(struct cipher_7108 *),
  1331. + GFP_ATOMIC);
  1332. + if (swd == NULL) {
  1333. + /* Reset session number */
  1334. + if (c7108_sesnum == CRYPTO_SW_SESSIONS)
  1335. + c7108_sesnum = 0;
  1336. + else
  1337. + c7108_sesnum /= 2;
  1338. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  1339. + return ENOBUFS;
  1340. + }
  1341. + memset(swd, 0, c7108_sesnum * sizeof(struct cipher_7108 *));
  1342. +
  1343. + /* Copy existing sessions */
  1344. + if (c7108_sessions) {
  1345. + memcpy(swd, c7108_sessions,
  1346. + (c7108_sesnum / 2) * sizeof(struct cipher_7108 *));
  1347. + kfree(c7108_sessions);
  1348. + }
  1349. +
  1350. + c7108_sessions = swd;
  1351. +
  1352. + }
  1353. +
  1354. + swd = &c7108_sessions[i];
  1355. + *sid = i;
  1356. +
  1357. + while (cri) {
  1358. + *swd = (struct cipher_7108 *)
  1359. + kmalloc(sizeof(struct cipher_7108), GFP_ATOMIC);
  1360. + if (*swd == NULL) {
  1361. + c7108_freesession(NULL, i);
  1362. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  1363. + return ENOBUFS;
  1364. + }
  1365. + memset(*swd, 0, sizeof(struct cipher_7108));
  1366. +
  1367. + algo = NULL;
  1368. + mode = 0;
  1369. + xfm_type = HW_TYPE_CIPHER;
  1370. +
  1371. + switch (cri->cri_alg) {
  1372. +
  1373. + case CRYPTO_AES_CBC:
  1374. + algo = "aes";
  1375. + mode = CRYPTO_TFM_MODE_CBC;
  1376. + c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC;
  1377. + break;
  1378. +#if 0
  1379. + case CRYPTO_AES_CTR:
  1380. + algo = "aes_ctr";
  1381. + mode = CRYPTO_TFM_MODE_CBC;
  1382. + c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR;
  1383. + break;
  1384. + case CRYPTO_AES_ECB:
  1385. + algo = "aes_ecb";
  1386. + mode = CRYPTO_TFM_MODE_CBC;
  1387. + c7108_crypto_mode = C7108_AES_CTRL_MODE_ECB;
  1388. + break;
  1389. + case CRYPTO_AES_OFB:
  1390. + algo = "aes_ofb";
  1391. + mode = CRYPTO_TFM_MODE_CBC;
  1392. + c7108_crypto_mode = C7108_AES_CTRL_MODE_OFB;
  1393. + break;
  1394. + case CRYPTO_AES_CFB:
  1395. + algo = "aes_cfb";
  1396. + mode = CRYPTO_TFM_MODE_CBC;
  1397. + c7108_crypto_mode = C7108_AES_CTRL_MODE_CFB;
  1398. + break;
  1399. +#endif
  1400. + default:
  1401. + printk("unsupported crypto algorithm: %d\n",
  1402. + cri->cri_alg);
  1403. + return -EINVAL;
  1404. + break;
  1405. + }
  1406. +
  1407. +
  1408. + if (!algo || !*algo) {
  1409. + printk("cypher_7108_crypto: Unknown algo 0x%x\n",
  1410. + cri->cri_alg);
  1411. + c7108_freesession(NULL, i);
  1412. + return EINVAL;
  1413. + }
  1414. +
  1415. + if (xfm_type == HW_TYPE_CIPHER) {
  1416. + if (debug) {
  1417. + dprintk("%s key:", __FUNCTION__);
  1418. + for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
  1419. + dprintk("%s0x%02x", (i % 8) ? " " : "\n ",
  1420. + cri->cri_key[i]);
  1421. + dprintk("\n");
  1422. + }
  1423. +
  1424. + } else if (xfm_type == SW_TYPE_HMAC ||
  1425. + xfm_type == SW_TYPE_HASH) {
  1426. + printk("cypher_7108_crypto: HMAC unsupported!\n");
  1427. + return -EINVAL;
  1428. + c7108_freesession(NULL, i);
  1429. + } else {
  1430. + printk("cypher_7108_crypto: "
  1431. + "Unhandled xfm_type %d\n", xfm_type);
  1432. + c7108_freesession(NULL, i);
  1433. + return EINVAL;
  1434. + }
  1435. +
  1436. + (*swd)->cri_alg = cri->cri_alg;
  1437. + (*swd)->xfm_type = xfm_type;
  1438. +
  1439. + cri = cri->cri_next;
  1440. + swd = &((*swd)->next);
  1441. + }
  1442. + return 0;
  1443. +}
  1444. +
  1445. +/*
  1446. + * Free a session.
  1447. + */
  1448. +static int
  1449. +c7108_freesession(void *arg, u_int64_t tid)
  1450. +{
  1451. + struct cipher_7108 *swd;
  1452. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  1453. +
  1454. + dprintk("%s()\n", __FUNCTION__);
  1455. + if (sid > c7108_sesnum || c7108_sessions == NULL ||
  1456. + c7108_sessions[sid] == NULL) {
  1457. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  1458. + return(EINVAL);
  1459. + }
  1460. +
  1461. + /* Silently accept and return */
  1462. + if (sid == 0)
  1463. + return(0);
  1464. +
  1465. + while ((swd = c7108_sessions[sid]) != NULL) {
  1466. + c7108_sessions[sid] = swd->next;
  1467. + kfree(swd);
  1468. + }
  1469. + return 0;
  1470. +}
  1471. +
  1472. +/*
  1473. + * Process a hardware request.
  1474. + */
  1475. +static int
  1476. +c7108_process(void *arg, struct cryptop *crp, int hint)
  1477. +{
  1478. + struct cryptodesc *crd;
  1479. + struct cipher_7108 *sw;
  1480. + u_int32_t lid;
  1481. + int type;
  1482. + u32 hwkey[8];
  1483. +
  1484. +#define SCATTERLIST_MAX 16
  1485. + struct scatterlist sg[SCATTERLIST_MAX];
  1486. + int sg_num, sg_len, skip;
  1487. + struct sk_buff *skb = NULL;
  1488. + struct uio *uiop = NULL;
  1489. +
  1490. + dprintk("%s()\n", __FUNCTION__);
  1491. + /* Sanity check */
  1492. + if (crp == NULL) {
  1493. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  1494. + return EINVAL;
  1495. + }
  1496. +
  1497. + crp->crp_etype = 0;
  1498. +
  1499. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  1500. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  1501. + crp->crp_etype = EINVAL;
  1502. + goto done;
  1503. + }
  1504. +
  1505. + lid = crp->crp_sid & 0xffffffff;
  1506. + if (lid >= c7108_sesnum || lid == 0 || c7108_sessions == NULL ||
  1507. + c7108_sessions[lid] == NULL) {
  1508. + crp->crp_etype = ENOENT;
  1509. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  1510. + goto done;
  1511. + }
  1512. +
  1513. + /*
  1514. + * do some error checking outside of the loop for SKB and IOV
  1515. + * processing this leaves us with valid skb or uiop pointers
  1516. + * for later
  1517. + */
  1518. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  1519. + skb = (struct sk_buff *) crp->crp_buf;
  1520. + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
  1521. + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX",
  1522. + __FILE__, __LINE__,
  1523. + skb_shinfo(skb)->nr_frags);
  1524. + goto done;
  1525. + }
  1526. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  1527. + uiop = (struct uio *) crp->crp_buf;
  1528. + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
  1529. + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX",
  1530. + __FILE__, __LINE__,
  1531. + uiop->uio_iovcnt);
  1532. + goto done;
  1533. + }
  1534. + }
  1535. +
  1536. + /* Go through crypto descriptors, processing as we go */
  1537. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  1538. + /*
  1539. + * Find the crypto context.
  1540. + *
  1541. + * XXX Note that the logic here prevents us from having
  1542. + * XXX the same algorithm multiple times in a session
  1543. + * XXX (or rather, we can but it won't give us the right
  1544. + * XXX results). To do that, we'd need some way of differentiating
  1545. + * XXX between the various instances of an algorithm (so we can
  1546. + * XXX locate the correct crypto context).
  1547. + */
  1548. + for (sw = c7108_sessions[lid];
  1549. + sw && sw->cri_alg != crd->crd_alg;
  1550. + sw = sw->next)
  1551. + ;
  1552. +
  1553. + /* No such context ? */
  1554. + if (sw == NULL) {
  1555. + crp->crp_etype = EINVAL;
  1556. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  1557. + goto done;
  1558. + }
  1559. +
  1560. + skip = crd->crd_skip;
  1561. +
  1562. + /*
  1563. + * setup the SG list skip from the start of the buffer
  1564. + */
  1565. + memset(sg, 0, sizeof(sg));
  1566. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  1567. + int i, len;
  1568. + type = CRYPTO_BUF_SKBUF;
  1569. +
  1570. + sg_num = 0;
  1571. + sg_len = 0;
  1572. +
  1573. + if (skip < skb_headlen(skb)) {
  1574. + //sg[sg_num].page = virt_to_page(skb->data + skip);
  1575. + //sg[sg_num].offset = offset_in_page(skb->data + skip);
  1576. + len = skb_headlen(skb) - skip;
  1577. + if (len + sg_len > crd->crd_len)
  1578. + len = crd->crd_len - sg_len;
  1579. + //sg[sg_num].length = len;
  1580. + sg_set_page(&sg[sg_num], virt_to_page(skb->data + skip), len, offset_in_page(skb->data + skip));
  1581. + sg_len += sg[sg_num].length;
  1582. + sg_num++;
  1583. + skip = 0;
  1584. + } else
  1585. + skip -= skb_headlen(skb);
  1586. +
  1587. + for (i = 0; sg_len < crd->crd_len &&
  1588. + i < skb_shinfo(skb)->nr_frags &&
  1589. + sg_num < SCATTERLIST_MAX; i++) {
  1590. + if (skip < skb_shinfo(skb)->frags[i].size) {
  1591. + //sg[sg_num].page = skb_shinfo(skb)->frags[i].page;
  1592. + //sg[sg_num].offset = skb_shinfo(skb)->frags[i].page_offset + skip;
  1593. + len = skb_shinfo(skb)->frags[i].size - skip;
  1594. + if (len + sg_len > crd->crd_len)
  1595. + len = crd->crd_len - sg_len;
  1596. + //sg[sg_num].length = len;
  1597. + sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page, len, skb_shinfo(skb)->frags[i].page_offset + skip);
  1598. + sg_len += sg[sg_num].length;
  1599. + sg_num++;
  1600. + skip = 0;
  1601. + } else
  1602. + skip -= skb_shinfo(skb)->frags[i].size;
  1603. + }
  1604. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  1605. + int len;
  1606. + type = CRYPTO_BUF_IOV;
  1607. + sg_len = 0;
  1608. + for (sg_num = 0; sg_len < crd->crd_len &&
  1609. + sg_num < uiop->uio_iovcnt &&
  1610. + sg_num < SCATTERLIST_MAX; sg_num++) {
  1611. + if (skip < uiop->uio_iov[sg_num].iov_len) {
  1612. + //sg[sg_num].page = virt_to_page(uiop->uio_iov[sg_num].iov_base+skip);
  1613. + //sg[sg_num].offset = offset_in_page(uiop->uio_iov[sg_num].iov_base+skip);
  1614. + len = uiop->uio_iov[sg_num].iov_len - skip;
  1615. + if (len + sg_len > crd->crd_len)
  1616. + len = crd->crd_len - sg_len;
  1617. + //sg[sg_num].length = len;
  1618. + 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));
  1619. + sg_len += sg[sg_num].length;
  1620. + skip = 0;
  1621. + } else
  1622. + skip -= uiop->uio_iov[sg_num].iov_len;
  1623. + }
  1624. + } else {
  1625. + type = CRYPTO_BUF_CONTIG;
  1626. + //sg[0].page = virt_to_page(crp->crp_buf + skip);
  1627. + //sg[0].offset = offset_in_page(crp->crp_buf + skip);
  1628. + sg_len = (crp->crp_ilen - skip);
  1629. + if (sg_len > crd->crd_len)
  1630. + sg_len = crd->crd_len;
  1631. + //sg[0].length = sg_len;
  1632. + sg_set_page(&sg[0], virt_to_page(crp->crp_buf + skip), sg_len, offset_in_page(crp->crp_buf + skip));
  1633. + sg_num = 1;
  1634. + }
  1635. +
  1636. +
  1637. + switch (sw->xfm_type) {
  1638. +
  1639. + case HW_TYPE_CIPHER: {
  1640. +
  1641. + unsigned char iv[64];
  1642. + unsigned char *ivp = iv;
  1643. + int i;
  1644. + int ivsize = 16; /* fixed for AES */
  1645. + int blocksize = 16; /* fixed for AES */
  1646. +
  1647. + if (sg_len < blocksize) {
  1648. + crp->crp_etype = EINVAL;
  1649. + dprintk("%s,%d: EINVAL len %d < %d\n",
  1650. + __FILE__, __LINE__,
  1651. + sg_len,
  1652. + blocksize);
  1653. + goto done;
  1654. + }
  1655. +
  1656. + if (ivsize > sizeof(iv)) {
  1657. + crp->crp_etype = EINVAL;
  1658. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  1659. + goto done;
  1660. + }
  1661. +
  1662. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  1663. +
  1664. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  1665. + ivp = crd->crd_iv;
  1666. + } else {
  1667. + get_random_bytes(ivp, ivsize);
  1668. + }
  1669. + /*
  1670. + * do we have to copy the IV back to the buffer ?
  1671. + */
  1672. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  1673. + crypto_copyback(crp->crp_buf,
  1674. + crd->crd_inject,
  1675. + ivsize,
  1676. + (caddr_t)ivp);
  1677. + }
  1678. +
  1679. + c7108_xlate_key(crd->crd_klen,
  1680. + (u8*)crd->crd_key, (u32*)hwkey);
  1681. +
  1682. + /* Encrypt SG list */
  1683. + for (i = 0; i < sg_num; i++) {
  1684. + sg[i].dma_address =
  1685. + dma_map_single(NULL,
  1686. + kmap(sg_page(&sg[i])) + sg[i].offset, sg_len, DMA_BIDIRECTIONAL);
  1687. +#if 0
  1688. + printk("sg[%d]:0x%08x, off 0x%08x "
  1689. + "kmap 0x%08x phys 0x%08x\n",
  1690. + i, sg[i].page, sg[i].offset,
  1691. + kmap(sg[i].page) + sg[i].offset,
  1692. + sg[i].dma_address);
  1693. +#endif
  1694. + c7108_aes_cipher(C7108_AES_ENCRYPT,
  1695. + sg[i].dma_address,
  1696. + sg[i].dma_address,
  1697. + sg_len,
  1698. + crd->crd_klen,
  1699. + c7108_crypto_mode,
  1700. + hwkey,
  1701. + ivp);
  1702. +
  1703. + if ((c7108_crypto_mode == C7108_AES_CTRL_MODE_CBC)||
  1704. + (c7108_crypto_mode == C7108_AES_CTRL_MODE_ECB)) {
  1705. + /* Read back expanded key and cache it in key
  1706. + * context.
  1707. + * NOTE: for ECB/CBC modes only (not CTR, CFB, OFB)
  1708. + * where you set the key once.
  1709. + */
  1710. + c7108_cache_key(crd->crd_klen,
  1711. + (u32*)hwkey, (u8*)crd->crd_key);
  1712. +#if 0
  1713. + printk("%s expanded key:", __FUNCTION__);
  1714. + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
  1715. + printk("%s0x%02x", (i % 8) ? " " : "\n ",
  1716. + crd->crd_key[i]);
  1717. + printk("\n");
  1718. +#endif
  1719. + }
  1720. + }
  1721. + }
  1722. + else { /*decrypt */
  1723. +
  1724. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  1725. + ivp = crd->crd_iv;
  1726. + } else {
  1727. + crypto_copydata(crp->crp_buf, crd->crd_inject,
  1728. + ivsize, (caddr_t)ivp);
  1729. + }
  1730. +
  1731. + c7108_xlate_key(crd->crd_klen,
  1732. + (u8*)crd->crd_key, (u32*)hwkey);
  1733. +
  1734. + /* Decrypt SG list */
  1735. + for (i = 0; i < sg_num; i++) {
  1736. + sg[i].dma_address =
  1737. + dma_map_single(NULL,
  1738. + kmap(sg_page(&sg[i])) + sg[i].offset,
  1739. + sg_len, DMA_BIDIRECTIONAL);
  1740. +
  1741. +#if 0
  1742. + printk("sg[%d]:0x%08x, off 0x%08x "
  1743. + "kmap 0x%08x phys 0x%08x\n",
  1744. + i, sg[i].page, sg[i].offset,
  1745. + kmap(sg[i].page) + sg[i].offset,
  1746. + sg[i].dma_address);
  1747. +#endif
  1748. + c7108_aes_cipher(C7108_AES_DECRYPT,
  1749. + sg[i].dma_address,
  1750. + sg[i].dma_address,
  1751. + sg_len,
  1752. + crd->crd_klen,
  1753. + c7108_crypto_mode,
  1754. + hwkey,
  1755. + ivp);
  1756. + }
  1757. + }
  1758. + } break;
  1759. + case SW_TYPE_HMAC:
  1760. + case SW_TYPE_HASH:
  1761. + crp->crp_etype = EINVAL;
  1762. + goto done;
  1763. + break;
  1764. +
  1765. + case SW_TYPE_COMP:
  1766. + crp->crp_etype = EINVAL;
  1767. + goto done;
  1768. + break;
  1769. +
  1770. + default:
  1771. + /* Unknown/unsupported algorithm */
  1772. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  1773. + crp->crp_etype = EINVAL;
  1774. + goto done;
  1775. + }
  1776. + }
  1777. +
  1778. +done:
  1779. + crypto_done(crp);
  1780. + return 0;
  1781. +}
  1782. +
  1783. +static struct {
  1784. + softc_device_decl sc_dev;
  1785. +} a7108dev;
  1786. +
  1787. +static device_method_t a7108_methods = {
  1788. +/* crypto device methods */
  1789. + DEVMETHOD(cryptodev_newsession, c7108_newsession),
  1790. + DEVMETHOD(cryptodev_freesession, c7108_freesession),
  1791. + DEVMETHOD(cryptodev_process, c7108_process),
  1792. + DEVMETHOD(cryptodev_kprocess, NULL)
  1793. +};
  1794. +
  1795. +static int
  1796. +cypher_7108_crypto_init(void)
  1797. +{
  1798. + dprintk("%s(%p)\n", __FUNCTION__, cypher_7108_crypto_init);
  1799. +
  1800. + iobar = (unsigned long)ioremap(CCU_AES_REG_BASE, 0x4000);
  1801. + printk("7108: AES @ 0x%08x (0x%08x phys) %s mode\n",
  1802. + iobar, CCU_AES_REG_BASE,
  1803. + c7108_crypto_mode & C7108_AES_CTRL_MODE_CBC ? "CBC" :
  1804. + c7108_crypto_mode & C7108_AES_CTRL_MODE_ECB ? "ECB" :
  1805. + c7108_crypto_mode & C7108_AES_CTRL_MODE_CTR ? "CTR" :
  1806. + c7108_crypto_mode & C7108_AES_CTRL_MODE_CFB ? "CFB" :
  1807. + c7108_crypto_mode & C7108_AES_CTRL_MODE_OFB ? "OFB" : "???");
  1808. + csr_mutex = SPIN_LOCK_UNLOCKED;
  1809. +
  1810. + memset(&a7108dev, 0, sizeof(a7108dev));
  1811. + softc_device_init(&a7108dev, "aes7108", 0, a7108_methods);
  1812. +
  1813. + c7108_id = crypto_get_driverid(softc_get_device(&a7108dev), CRYPTOCAP_F_HARDWARE);
  1814. + if (c7108_id < 0)
  1815. + panic("7108: crypto device cannot initialize!");
  1816. +
  1817. +// crypto_register(c7108_id, CRYPTO_AES_CBC, 0, 0, c7108_newsession, c7108_freesession, c7108_process, NULL);
  1818. + crypto_register(c7108_id, CRYPTO_AES_CBC, 0, 0);
  1819. +
  1820. + return(0);
  1821. +}
  1822. +
  1823. +static void
  1824. +cypher_7108_crypto_exit(void)
  1825. +{
  1826. + dprintk("%s()\n", __FUNCTION__);
  1827. + crypto_unregister_all(c7108_id);
  1828. + c7108_id = -1;
  1829. +}
  1830. +
  1831. +module_init(cypher_7108_crypto_init);
  1832. +module_exit(cypher_7108_crypto_exit);
  1833. +
  1834. +MODULE_LICENSE("Dual BSD/GPL");
  1835. +MODULE_DESCRIPTION("Cypher 7108 Crypto (OCF module for kernel crypto)");
  1836. diff -Nur linux-2.6.39.orig/crypto/ocf/c7108/aes-7108.h linux-2.6.39/crypto/ocf/c7108/aes-7108.h
  1837. --- linux-2.6.39.orig/crypto/ocf/c7108/aes-7108.h 1970-01-01 01:00:00.000000000 +0100
  1838. +++ linux-2.6.39/crypto/ocf/c7108/aes-7108.h 2011-07-31 11:31:53.103425544 +0200
  1839. @@ -0,0 +1,134 @@
  1840. +/*
  1841. + * Copyright (C) 2006 Micronas USA
  1842. + *
  1843. + * 1. Redistributions of source code must retain the above copyright
  1844. + * notice, this list of conditions and the following disclaimer.
  1845. + * 2. Redistributions in binary form must reproduce the above copyright
  1846. + * notice, this list of conditions and the following disclaimer in the
  1847. + * documentation and/or other materials provided with the distribution.
  1848. + * 3. The name of the author may not be used to endorse or promote products
  1849. + * derived from this software without specific prior written permission.
  1850. + *
  1851. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  1852. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  1853. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  1854. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  1855. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  1856. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  1857. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  1858. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1859. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  1860. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1861. + *
  1862. + * Effort sponsored in part by the Defense Advanced Research Projects
  1863. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  1864. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  1865. + *
  1866. + */
  1867. +
  1868. +#ifndef __AES_7108_H__
  1869. +#define __AES_7108_H__
  1870. +
  1871. +/* Cypher 7108 AES Controller Hardware */
  1872. +#define CCU_REG_BASE 0x1b500000
  1873. +#define CCU_AES_REG_BASE (CCU_REG_BASE + 0x100)
  1874. +#define C7108_AES_KEY0_LO (0x0000)
  1875. +#define C7108_AES_KEY0_HI (0x0004)
  1876. +#define C7108_AES_KEY1_LO (0x0008)
  1877. +#define C7108_AES_KEY1_HI (0x000c)
  1878. +#define C7108_AES_KEY2_LO (0x0010)
  1879. +#define C7108_AES_KEY2_HI (0x0014)
  1880. +#define C7108_AES_KEY3_LO (0x0018)
  1881. +#define C7108_AES_KEY3_HI (0x001c)
  1882. +#define C7108_AES_KEY4_LO (0x0020)
  1883. +#define C7108_AES_KEY4_HI (0x0024)
  1884. +#define C7108_AES_KEY5_LO (0x0028)
  1885. +#define C7108_AES_KEY5_HI (0x002c)
  1886. +#define C7108_AES_KEY6_LO (0x0030)
  1887. +#define C7108_AES_KEY6_HI (0x0034)
  1888. +#define C7108_AES_KEY7_LO (0x0038)
  1889. +#define C7108_AES_KEY7_HI (0x003c)
  1890. +#define C7108_AES_IV0_LO (0x0040)
  1891. +#define C7108_AES_IV0_HI (0x0044)
  1892. +#define C7108_AES_IV1_LO (0x0048)
  1893. +#define C7108_AES_IV1_HI (0x004c)
  1894. +#define C7108_AES_IV2_LO (0x0050)
  1895. +#define C7108_AES_IV2_HI (0x0054)
  1896. +#define C7108_AES_IV3_LO (0x0058)
  1897. +#define C7108_AES_IV3_HI (0x005c)
  1898. +
  1899. +#define C7108_AES_DMA_SRC0_LO (0x0068) /* Bits 0:15 */
  1900. +#define C7108_AES_DMA_SRC0_HI (0x006c) /* Bits 27:16 */
  1901. +#define C7108_AES_DMA_DST0_LO (0x0070) /* Bits 0:15 */
  1902. +#define C7108_AES_DMA_DST0_HI (0x0074) /* Bits 27:16 */
  1903. +#define C7108_AES_DMA_LEN (0x0078) /*Bytes:(Count+1)x16 */
  1904. +
  1905. +/* AES/Copy engine control register */
  1906. +#define C7108_AES_CTRL (0x007c) /* AES control */
  1907. +#define C7108_AES_CTRL_RS (1<<0) /* Which set of src/dst to use */
  1908. +
  1909. +/* AES Cipher mode, controlled by setting Bits 2:0 */
  1910. +#define C7108_AES_CTRL_MODE_CBC 0
  1911. +#define C7108_AES_CTRL_MODE_CFB (1<<0)
  1912. +#define C7108_AES_CTRL_MODE_OFB (1<<1)
  1913. +#define C7108_AES_CTRL_MODE_CTR ((1<<0)|(1<<1))
  1914. +#define C7108_AES_CTRL_MODE_ECB (1<<2)
  1915. +
  1916. +/* AES Key length , Bits 5:4 */
  1917. +#define C7108_AES_KEY_LEN_128 0 /* 00 */
  1918. +#define C7108_AES_KEY_LEN_192 (1<<4) /* 01 */
  1919. +#define C7108_AES_KEY_LEN_256 (1<<5) /* 10 */
  1920. +
  1921. +/* AES Operation (crypt/decrypt), Bit 3 */
  1922. +#define C7108_AES_DECRYPT (1<<3) /* Clear for encrypt */
  1923. +#define C7108_AES_ENCRYPT 0
  1924. +#define C7108_AES_INTR (1<<13) /* Set on done trans from 0->1*/
  1925. +#define C7108_AES_GO (1<<14) /* Run */
  1926. +#define C7108_AES_OP_DONE (1<<15) /* Set when complete */
  1927. +
  1928. +
  1929. +/* Expanded key registers */
  1930. +#define C7108_AES_EKEY0_LO (0x0080)
  1931. +#define C7108_AES_EKEY0_HI (0x0084)
  1932. +#define C7108_AES_EKEY1_LO (0x0088)
  1933. +#define C7108_AES_EKEY1_HI (0x008c)
  1934. +#define C7108_AES_EKEY2_LO (0x0090)
  1935. +#define C7108_AES_EKEY2_HI (0x0094)
  1936. +#define C7108_AES_EKEY3_LO (0x0098)
  1937. +#define C7108_AES_EKEY3_HI (0x009c)
  1938. +#define C7108_AES_EKEY4_LO (0x00a0)
  1939. +#define C7108_AES_EKEY4_HI (0x00a4)
  1940. +#define C7108_AES_EKEY5_LO (0x00a8)
  1941. +#define C7108_AES_EKEY5_HI (0x00ac)
  1942. +#define C7108_AES_EKEY6_LO (0x00b0)
  1943. +#define C7108_AES_EKEY6_HI (0x00b4)
  1944. +#define C7108_AES_EKEY7_LO (0x00b8)
  1945. +#define C7108_AES_EKEY7_HI (0x00bc)
  1946. +#define C7108_AES_OK (0x00fc) /* Reset: "OK" */
  1947. +
  1948. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  1949. +
  1950. +/* Software session entry */
  1951. +
  1952. +#define HW_TYPE_CIPHER 0
  1953. +#define SW_TYPE_HMAC 1
  1954. +#define SW_TYPE_AUTH2 2
  1955. +#define SW_TYPE_HASH 3
  1956. +#define SW_TYPE_COMP 4
  1957. +
  1958. +struct cipher_7108 {
  1959. + int xfm_type;
  1960. + int cri_alg;
  1961. + union {
  1962. + struct {
  1963. + char sw_key[HMAC_BLOCK_LEN];
  1964. + int sw_klen;
  1965. + int sw_authlen;
  1966. + } hmac;
  1967. + } u;
  1968. + struct cipher_7108 *next;
  1969. +};
  1970. +
  1971. +
  1972. +
  1973. +#endif /* __C7108_AES_7108_H__ */
  1974. diff -Nur linux-2.6.39.orig/crypto/ocf/c7108/Makefile linux-2.6.39/crypto/ocf/c7108/Makefile
  1975. --- linux-2.6.39.orig/crypto/ocf/c7108/Makefile 1970-01-01 01:00:00.000000000 +0100
  1976. +++ linux-2.6.39/crypto/ocf/c7108/Makefile 2011-07-31 11:31:53.143425698 +0200
  1977. @@ -0,0 +1,12 @@
  1978. +# for SGlinux builds
  1979. +-include $(ROOTDIR)/modules/.config
  1980. +
  1981. +obj-$(CONFIG_OCF_C7108) += aes-7108.o
  1982. +
  1983. +obj ?= .
  1984. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  1985. +
  1986. +ifdef TOPDIR
  1987. +-include $(TOPDIR)/Rules.make
  1988. +endif
  1989. +
  1990. diff -Nur linux-2.6.39.orig/crypto/ocf/Config.in linux-2.6.39/crypto/ocf/Config.in
  1991. --- linux-2.6.39.orig/crypto/ocf/Config.in 1970-01-01 01:00:00.000000000 +0100
  1992. +++ linux-2.6.39/crypto/ocf/Config.in 2011-07-31 11:31:53.203897229 +0200
  1993. @@ -0,0 +1,36 @@
  1994. +#############################################################################
  1995. +
  1996. +mainmenu_option next_comment
  1997. +comment 'OCF Configuration'
  1998. +tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF
  1999. +dep_mbool ' enable fips RNG checks (fips check on RNG data before use)' \
  2000. + CONFIG_OCF_FIPS $CONFIG_OCF_OCF
  2001. +dep_mbool ' enable harvesting entropy for /dev/random' \
  2002. + CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF
  2003. +dep_tristate ' cryptodev (user space support)' \
  2004. + CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF
  2005. +dep_tristate ' cryptosoft (software crypto engine)' \
  2006. + CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF
  2007. +dep_tristate ' safenet (HW crypto engine)' \
  2008. + CONFIG_OCF_SAFE $CONFIG_OCF_OCF
  2009. +dep_tristate ' IXP4xx (HW crypto engine)' \
  2010. + CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF
  2011. +dep_mbool ' Enable IXP4xx HW to perform SHA1 and MD5 hashing (very slow)' \
  2012. + CONFIG_OCF_IXP4XX_SHA1_MD5 $CONFIG_OCF_IXP4XX
  2013. +dep_tristate ' hifn (HW crypto engine)' \
  2014. + CONFIG_OCF_HIFN $CONFIG_OCF_OCF
  2015. +dep_tristate ' talitos (HW crypto engine)' \
  2016. + CONFIG_OCF_TALITOS $CONFIG_OCF_OCF
  2017. +dep_tristate ' pasemi (HW crypto engine)' \
  2018. + CONFIG_OCF_PASEMI $CONFIG_OCF_OCF
  2019. +dep_tristate ' ep80579 (HW crypto engine)' \
  2020. + CONFIG_OCF_EP80579 $CONFIG_OCF_OCF
  2021. +dep_tristate ' Micronas c7108 (HW crypto engine)' \
  2022. + CONFIG_OCF_C7108 $CONFIG_OCF_OCF
  2023. +dep_tristate ' ocfnull (does no crypto)' \
  2024. + CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF
  2025. +dep_tristate ' ocf-bench (HW crypto in-kernel benchmark)' \
  2026. + CONFIG_OCF_BENCH $CONFIG_OCF_OCF
  2027. +endmenu
  2028. +
  2029. +#############################################################################
  2030. diff -Nur linux-2.6.39.orig/crypto/ocf/criov.c linux-2.6.39/crypto/ocf/criov.c
  2031. --- linux-2.6.39.orig/crypto/ocf/criov.c 1970-01-01 01:00:00.000000000 +0100
  2032. +++ linux-2.6.39/crypto/ocf/criov.c 2011-07-31 11:31:53.295924155 +0200
  2033. @@ -0,0 +1,215 @@
  2034. +/* $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $ */
  2035. +
  2036. +/*
  2037. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  2038. + * Copyright (C) 2006-2010 David McCullough
  2039. + * Copyright (C) 2004-2005 Intel Corporation.
  2040. + * The license and original author are listed below.
  2041. + *
  2042. + * Copyright (c) 1999 Theo de Raadt
  2043. + *
  2044. + * Redistribution and use in source and binary forms, with or without
  2045. + * modification, are permitted provided that the following conditions
  2046. + * are met:
  2047. + *
  2048. + * 1. Redistributions of source code must retain the above copyright
  2049. + * notice, this list of conditions and the following disclaimer.
  2050. + * 2. Redistributions in binary form must reproduce the above copyright
  2051. + * notice, this list of conditions and the following disclaimer in the
  2052. + * documentation and/or other materials provided with the distribution.
  2053. + * 3. The name of the author may not be used to endorse or promote products
  2054. + * derived from this software without specific prior written permission.
  2055. + *
  2056. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  2057. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  2058. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  2059. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  2060. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  2061. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  2062. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  2063. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  2064. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  2065. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2066. + *
  2067. +__FBSDID("$FreeBSD: src/sys/opencrypto/criov.c,v 1.5 2006/06/04 22:15:13 pjd Exp $");
  2068. + */
  2069. +
  2070. +#ifndef AUTOCONF_INCLUDED
  2071. +#include <linux/config.h>
  2072. +#endif
  2073. +#include <linux/module.h>
  2074. +#include <linux/init.h>
  2075. +#include <linux/slab.h>
  2076. +#include <linux/uio.h>
  2077. +#include <linux/skbuff.h>
  2078. +#include <linux/kernel.h>
  2079. +#include <linux/mm.h>
  2080. +#include <asm/io.h>
  2081. +
  2082. +#include <uio.h>
  2083. +#include <cryptodev.h>
  2084. +
  2085. +/*
  2086. + * This macro is only for avoiding code duplication, as we need to skip
  2087. + * given number of bytes in the same way in three functions below.
  2088. + */
  2089. +#define CUIO_SKIP() do { \
  2090. + KASSERT(off >= 0, ("%s: off %d < 0", __func__, off)); \
  2091. + KASSERT(len >= 0, ("%s: len %d < 0", __func__, len)); \
  2092. + while (off > 0) { \
  2093. + KASSERT(iol >= 0, ("%s: empty in skip", __func__)); \
  2094. + if (off < iov->iov_len) \
  2095. + break; \
  2096. + off -= iov->iov_len; \
  2097. + iol--; \
  2098. + iov++; \
  2099. + } \
  2100. +} while (0)
  2101. +
  2102. +void
  2103. +cuio_copydata(struct uio* uio, int off, int len, caddr_t cp)
  2104. +{
  2105. + struct iovec *iov = uio->uio_iov;
  2106. + int iol = uio->uio_iovcnt;
  2107. + unsigned count;
  2108. +
  2109. + CUIO_SKIP();
  2110. + while (len > 0) {
  2111. + KASSERT(iol >= 0, ("%s: empty", __func__));
  2112. + count = min((int)(iov->iov_len - off), len);
  2113. + memcpy(cp, ((caddr_t)iov->iov_base) + off, count);
  2114. + len -= count;
  2115. + cp += count;
  2116. + off = 0;
  2117. + iol--;
  2118. + iov++;
  2119. + }
  2120. +}
  2121. +
  2122. +void
  2123. +cuio_copyback(struct uio* uio, int off, int len, caddr_t cp)
  2124. +{
  2125. + struct iovec *iov = uio->uio_iov;
  2126. + int iol = uio->uio_iovcnt;
  2127. + unsigned count;
  2128. +
  2129. + CUIO_SKIP();
  2130. + while (len > 0) {
  2131. + KASSERT(iol >= 0, ("%s: empty", __func__));
  2132. + count = min((int)(iov->iov_len - off), len);
  2133. + memcpy(((caddr_t)iov->iov_base) + off, cp, count);
  2134. + len -= count;
  2135. + cp += count;
  2136. + off = 0;
  2137. + iol--;
  2138. + iov++;
  2139. + }
  2140. +}
  2141. +
  2142. +/*
  2143. + * Return a pointer to iov/offset of location in iovec list.
  2144. + */
  2145. +struct iovec *
  2146. +cuio_getptr(struct uio *uio, int loc, int *off)
  2147. +{
  2148. + struct iovec *iov = uio->uio_iov;
  2149. + int iol = uio->uio_iovcnt;
  2150. +
  2151. + while (loc >= 0) {
  2152. + /* Normal end of search */
  2153. + if (loc < iov->iov_len) {
  2154. + *off = loc;
  2155. + return (iov);
  2156. + }
  2157. +
  2158. + loc -= iov->iov_len;
  2159. + if (iol == 0) {
  2160. + if (loc == 0) {
  2161. + /* Point at the end of valid data */
  2162. + *off = iov->iov_len;
  2163. + return (iov);
  2164. + } else
  2165. + return (NULL);
  2166. + } else {
  2167. + iov++, iol--;
  2168. + }
  2169. + }
  2170. +
  2171. + return (NULL);
  2172. +}
  2173. +
  2174. +EXPORT_SYMBOL(cuio_copyback);
  2175. +EXPORT_SYMBOL(cuio_copydata);
  2176. +EXPORT_SYMBOL(cuio_getptr);
  2177. +
  2178. +
  2179. +static void
  2180. +skb_copy_bits_back(struct sk_buff *skb, int offset, caddr_t cp, int len)
  2181. +{
  2182. + int i;
  2183. + if (offset < skb_headlen(skb)) {
  2184. + memcpy(skb->data + offset, cp, min_t(int, skb_headlen(skb), len));
  2185. + len -= skb_headlen(skb);
  2186. + cp += skb_headlen(skb);
  2187. + }
  2188. + offset -= skb_headlen(skb);
  2189. + for (i = 0; len > 0 && i < skb_shinfo(skb)->nr_frags; i++) {
  2190. + if (offset < skb_shinfo(skb)->frags[i].size) {
  2191. + memcpy(page_address(skb_shinfo(skb)->frags[i].page) +
  2192. + skb_shinfo(skb)->frags[i].page_offset,
  2193. + cp, min_t(int, skb_shinfo(skb)->frags[i].size, len));
  2194. + len -= skb_shinfo(skb)->frags[i].size;
  2195. + cp += skb_shinfo(skb)->frags[i].size;
  2196. + }
  2197. + offset -= skb_shinfo(skb)->frags[i].size;
  2198. + }
  2199. +}
  2200. +
  2201. +void
  2202. +crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in)
  2203. +{
  2204. +
  2205. + if ((flags & CRYPTO_F_SKBUF) != 0)
  2206. + skb_copy_bits_back((struct sk_buff *)buf, off, in, size);
  2207. + else if ((flags & CRYPTO_F_IOV) != 0)
  2208. + cuio_copyback((struct uio *)buf, off, size, in);
  2209. + else
  2210. + bcopy(in, buf + off, size);
  2211. +}
  2212. +
  2213. +void
  2214. +crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out)
  2215. +{
  2216. +
  2217. + if ((flags & CRYPTO_F_SKBUF) != 0)
  2218. + skb_copy_bits((struct sk_buff *)buf, off, out, size);
  2219. + else if ((flags & CRYPTO_F_IOV) != 0)
  2220. + cuio_copydata((struct uio *)buf, off, size, out);
  2221. + else
  2222. + bcopy(buf + off, out, size);
  2223. +}
  2224. +
  2225. +int
  2226. +crypto_apply(int flags, caddr_t buf, int off, int len,
  2227. + int (*f)(void *, void *, u_int), void *arg)
  2228. +{
  2229. +#if 0
  2230. + int error;
  2231. +
  2232. + if ((flags & CRYPTO_F_SKBUF) != 0)
  2233. + error = XXXXXX((struct mbuf *)buf, off, len, f, arg);
  2234. + else if ((flags & CRYPTO_F_IOV) != 0)
  2235. + error = cuio_apply((struct uio *)buf, off, len, f, arg);
  2236. + else
  2237. + error = (*f)(arg, buf + off, len);
  2238. + return (error);
  2239. +#else
  2240. + KASSERT(0, ("crypto_apply not implemented!\n"));
  2241. +#endif
  2242. + return 0;
  2243. +}
  2244. +
  2245. +EXPORT_SYMBOL(crypto_copyback);
  2246. +EXPORT_SYMBOL(crypto_copydata);
  2247. +EXPORT_SYMBOL(crypto_apply);
  2248. +
  2249. diff -Nur linux-2.6.39.orig/crypto/ocf/crypto.c linux-2.6.39/crypto/ocf/crypto.c
  2250. --- linux-2.6.39.orig/crypto/ocf/crypto.c 1970-01-01 01:00:00.000000000 +0100
  2251. +++ linux-2.6.39/crypto/ocf/crypto.c 2011-07-31 11:31:53.353516125 +0200
  2252. @@ -0,0 +1,1784 @@
  2253. +/*-
  2254. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  2255. + * Copyright (C) 2006-2010 David McCullough
  2256. + * Copyright (C) 2004-2005 Intel Corporation.
  2257. + * The license and original author are listed below.
  2258. + *
  2259. + * Redistribution and use in source and binary forms, with or without
  2260. + * Copyright (c) 2002-2006 Sam Leffler. All rights reserved.
  2261. + *
  2262. + * modification, are permitted provided that the following conditions
  2263. + * are met:
  2264. + * 1. Redistributions of source code must retain the above copyright
  2265. + * notice, this list of conditions and the following disclaimer.
  2266. + * 2. Redistributions in binary form must reproduce the above copyright
  2267. + * notice, this list of conditions and the following disclaimer in the
  2268. + * documentation and/or other materials provided with the distribution.
  2269. + *
  2270. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  2271. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  2272. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  2273. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  2274. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  2275. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  2276. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  2277. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  2278. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  2279. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2280. + */
  2281. +
  2282. +#if 0
  2283. +#include <sys/cdefs.h>
  2284. +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.27 2007/03/21 03:42:51 sam Exp $");
  2285. +#endif
  2286. +
  2287. +/*
  2288. + * Cryptographic Subsystem.
  2289. + *
  2290. + * This code is derived from the Openbsd Cryptographic Framework (OCF)
  2291. + * that has the copyright shown below. Very little of the original
  2292. + * code remains.
  2293. + */
  2294. +/*-
  2295. + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
  2296. + *
  2297. + * This code was written by Angelos D. Keromytis in Athens, Greece, in
  2298. + * February 2000. Network Security Technologies Inc. (NSTI) kindly
  2299. + * supported the development of this code.
  2300. + *
  2301. + * Copyright (c) 2000, 2001 Angelos D. Keromytis
  2302. + *
  2303. + * Permission to use, copy, and modify this software with or without fee
  2304. + * is hereby granted, provided that this entire notice is included in
  2305. + * all source code copies of any software which is or includes a copy or
  2306. + * modification of this software.
  2307. + *
  2308. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
  2309. + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
  2310. + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
  2311. + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
  2312. + * PURPOSE.
  2313. + *
  2314. +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp Exp $");
  2315. + */
  2316. +
  2317. +
  2318. +#ifndef AUTOCONF_INCLUDED
  2319. +#include <linux/config.h>
  2320. +#endif
  2321. +#include <linux/module.h>
  2322. +#include <linux/init.h>
  2323. +#include <linux/list.h>
  2324. +#include <linux/slab.h>
  2325. +#include <linux/wait.h>
  2326. +#include <linux/sched.h>
  2327. +#include <linux/spinlock.h>
  2328. +#include <linux/version.h>
  2329. +#include <cryptodev.h>
  2330. +
  2331. +/*
  2332. + * keep track of whether or not we have been initialised, a big
  2333. + * issue if we are linked into the kernel and a driver gets started before
  2334. + * us
  2335. + */
  2336. +static int crypto_initted = 0;
  2337. +
  2338. +/*
  2339. + * Crypto drivers register themselves by allocating a slot in the
  2340. + * crypto_drivers table with crypto_get_driverid() and then registering
  2341. + * each algorithm they support with crypto_register() and crypto_kregister().
  2342. + */
  2343. +
  2344. +/*
  2345. + * lock on driver table
  2346. + * we track its state as spin_is_locked does not do anything on non-SMP boxes
  2347. + */
  2348. +static spinlock_t crypto_drivers_lock;
  2349. +static int crypto_drivers_locked; /* for non-SMP boxes */
  2350. +
  2351. +#define CRYPTO_DRIVER_LOCK() \
  2352. + ({ \
  2353. + spin_lock_irqsave(&crypto_drivers_lock, d_flags); \
  2354. + crypto_drivers_locked = 1; \
  2355. + dprintk("%s,%d: DRIVER_LOCK()\n", __FILE__, __LINE__); \
  2356. + })
  2357. +#define CRYPTO_DRIVER_UNLOCK() \
  2358. + ({ \
  2359. + dprintk("%s,%d: DRIVER_UNLOCK()\n", __FILE__, __LINE__); \
  2360. + crypto_drivers_locked = 0; \
  2361. + spin_unlock_irqrestore(&crypto_drivers_lock, d_flags); \
  2362. + })
  2363. +#define CRYPTO_DRIVER_ASSERT() \
  2364. + ({ \
  2365. + if (!crypto_drivers_locked) { \
  2366. + dprintk("%s,%d: DRIVER_ASSERT!\n", __FILE__, __LINE__); \
  2367. + } \
  2368. + })
  2369. +
  2370. +/*
  2371. + * Crypto device/driver capabilities structure.
  2372. + *
  2373. + * Synchronization:
  2374. + * (d) - protected by CRYPTO_DRIVER_LOCK()
  2375. + * (q) - protected by CRYPTO_Q_LOCK()
  2376. + * Not tagged fields are read-only.
  2377. + */
  2378. +struct cryptocap {
  2379. + device_t cc_dev; /* (d) device/driver */
  2380. + u_int32_t cc_sessions; /* (d) # of sessions */
  2381. + u_int32_t cc_koperations; /* (d) # os asym operations */
  2382. + /*
  2383. + * Largest possible operator length (in bits) for each type of
  2384. + * encryption algorithm. XXX not used
  2385. + */
  2386. + u_int16_t cc_max_op_len[CRYPTO_ALGORITHM_MAX + 1];
  2387. + u_int8_t cc_alg[CRYPTO_ALGORITHM_MAX + 1];
  2388. + u_int8_t cc_kalg[CRK_ALGORITHM_MAX + 1];
  2389. +
  2390. + int cc_flags; /* (d) flags */
  2391. +#define CRYPTOCAP_F_CLEANUP 0x80000000 /* needs resource cleanup */
  2392. + int cc_qblocked; /* (q) symmetric q blocked */
  2393. + int cc_kqblocked; /* (q) asymmetric q blocked */
  2394. +
  2395. + int cc_unqblocked; /* (q) symmetric q blocked */
  2396. + int cc_unkqblocked; /* (q) asymmetric q blocked */
  2397. +};
  2398. +static struct cryptocap *crypto_drivers = NULL;
  2399. +static int crypto_drivers_num = 0;
  2400. +
  2401. +/*
  2402. + * There are two queues for crypto requests; one for symmetric (e.g.
  2403. + * cipher) operations and one for asymmetric (e.g. MOD)operations.
  2404. + * A single mutex is used to lock access to both queues. We could
  2405. + * have one per-queue but having one simplifies handling of block/unblock
  2406. + * operations.
  2407. + */
  2408. +static int crp_sleep = 0;
  2409. +static LIST_HEAD(crp_q); /* request queues */
  2410. +static LIST_HEAD(crp_kq);
  2411. +
  2412. +static spinlock_t crypto_q_lock;
  2413. +
  2414. +int crypto_all_qblocked = 0; /* protect with Q_LOCK */
  2415. +module_param(crypto_all_qblocked, int, 0444);
  2416. +MODULE_PARM_DESC(crypto_all_qblocked, "Are all crypto queues blocked");
  2417. +
  2418. +int crypto_all_kqblocked = 0; /* protect with Q_LOCK */
  2419. +module_param(crypto_all_kqblocked, int, 0444);
  2420. +MODULE_PARM_DESC(crypto_all_kqblocked, "Are all asym crypto queues blocked");
  2421. +
  2422. +#define CRYPTO_Q_LOCK() \
  2423. + ({ \
  2424. + spin_lock_irqsave(&crypto_q_lock, q_flags); \
  2425. + dprintk("%s,%d: Q_LOCK()\n", __FILE__, __LINE__); \
  2426. + })
  2427. +#define CRYPTO_Q_UNLOCK() \
  2428. + ({ \
  2429. + dprintk("%s,%d: Q_UNLOCK()\n", __FILE__, __LINE__); \
  2430. + spin_unlock_irqrestore(&crypto_q_lock, q_flags); \
  2431. + })
  2432. +
  2433. +/*
  2434. + * There are two queues for processing completed crypto requests; one
  2435. + * for the symmetric and one for the asymmetric ops. We only need one
  2436. + * but have two to avoid type futzing (cryptop vs. cryptkop). A single
  2437. + * mutex is used to lock access to both queues. Note that this lock
  2438. + * must be separate from the lock on request queues to insure driver
  2439. + * callbacks don't generate lock order reversals.
  2440. + */
  2441. +static LIST_HEAD(crp_ret_q); /* callback queues */
  2442. +static LIST_HEAD(crp_ret_kq);
  2443. +
  2444. +static spinlock_t crypto_ret_q_lock;
  2445. +#define CRYPTO_RETQ_LOCK() \
  2446. + ({ \
  2447. + spin_lock_irqsave(&crypto_ret_q_lock, r_flags); \
  2448. + dprintk("%s,%d: RETQ_LOCK\n", __FILE__, __LINE__); \
  2449. + })
  2450. +#define CRYPTO_RETQ_UNLOCK() \
  2451. + ({ \
  2452. + dprintk("%s,%d: RETQ_UNLOCK\n", __FILE__, __LINE__); \
  2453. + spin_unlock_irqrestore(&crypto_ret_q_lock, r_flags); \
  2454. + })
  2455. +#define CRYPTO_RETQ_EMPTY() (list_empty(&crp_ret_q) && list_empty(&crp_ret_kq))
  2456. +
  2457. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  2458. +static kmem_cache_t *cryptop_zone;
  2459. +static kmem_cache_t *cryptodesc_zone;
  2460. +#else
  2461. +static struct kmem_cache *cryptop_zone;
  2462. +static struct kmem_cache *cryptodesc_zone;
  2463. +#endif
  2464. +
  2465. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
  2466. +#include <linux/sched.h>
  2467. +#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
  2468. +#endif
  2469. +
  2470. +#define debug crypto_debug
  2471. +int crypto_debug = 0;
  2472. +module_param(crypto_debug, int, 0644);
  2473. +MODULE_PARM_DESC(crypto_debug, "Enable debug");
  2474. +EXPORT_SYMBOL(crypto_debug);
  2475. +
  2476. +/*
  2477. + * Maximum number of outstanding crypto requests before we start
  2478. + * failing requests. We need this to prevent DOS when too many
  2479. + * requests are arriving for us to keep up. Otherwise we will
  2480. + * run the system out of memory. Since crypto is slow, we are
  2481. + * usually the bottleneck that needs to say, enough is enough.
  2482. + *
  2483. + * We cannot print errors when this condition occurs, we are already too
  2484. + * slow, printing anything will just kill us
  2485. + */
  2486. +
  2487. +static int crypto_q_cnt = 0;
  2488. +module_param(crypto_q_cnt, int, 0444);
  2489. +MODULE_PARM_DESC(crypto_q_cnt,
  2490. + "Current number of outstanding crypto requests");
  2491. +
  2492. +static int crypto_q_max = 1000;
  2493. +module_param(crypto_q_max, int, 0644);
  2494. +MODULE_PARM_DESC(crypto_q_max,
  2495. + "Maximum number of outstanding crypto requests");
  2496. +
  2497. +#define bootverbose crypto_verbose
  2498. +static int crypto_verbose = 0;
  2499. +module_param(crypto_verbose, int, 0644);
  2500. +MODULE_PARM_DESC(crypto_verbose,
  2501. + "Enable verbose crypto startup");
  2502. +
  2503. +int crypto_usercrypto = 1; /* userland may do crypto reqs */
  2504. +module_param(crypto_usercrypto, int, 0644);
  2505. +MODULE_PARM_DESC(crypto_usercrypto,
  2506. + "Enable/disable user-mode access to crypto support");
  2507. +
  2508. +int crypto_userasymcrypto = 1; /* userland may do asym crypto reqs */
  2509. +module_param(crypto_userasymcrypto, int, 0644);
  2510. +MODULE_PARM_DESC(crypto_userasymcrypto,
  2511. + "Enable/disable user-mode access to asymmetric crypto support");
  2512. +
  2513. +int crypto_devallowsoft = 0; /* only use hardware crypto */
  2514. +module_param(crypto_devallowsoft, int, 0644);
  2515. +MODULE_PARM_DESC(crypto_devallowsoft,
  2516. + "Enable/disable use of software crypto support");
  2517. +
  2518. +/*
  2519. + * This parameter controls the maximum number of crypto operations to
  2520. + * do consecutively in the crypto kernel thread before scheduling to allow
  2521. + * other processes to run. Without it, it is possible to get into a
  2522. + * situation where the crypto thread never allows any other processes to run.
  2523. + * Default to 1000 which should be less than one second.
  2524. + */
  2525. +static int crypto_max_loopcount = 1000;
  2526. +module_param(crypto_max_loopcount, int, 0644);
  2527. +MODULE_PARM_DESC(crypto_max_loopcount,
  2528. + "Maximum number of crypto ops to do before yielding to other processes");
  2529. +
  2530. +static pid_t cryptoproc = (pid_t) -1;
  2531. +static struct completion cryptoproc_exited;
  2532. +static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait);
  2533. +static pid_t cryptoretproc = (pid_t) -1;
  2534. +static struct completion cryptoretproc_exited;
  2535. +static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait);
  2536. +
  2537. +static int crypto_proc(void *arg);
  2538. +static int crypto_ret_proc(void *arg);
  2539. +static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);
  2540. +static int crypto_kinvoke(struct cryptkop *krp, int flags);
  2541. +static void crypto_exit(void);
  2542. +static int crypto_init(void);
  2543. +
  2544. +static struct cryptostats cryptostats;
  2545. +
  2546. +static struct cryptocap *
  2547. +crypto_checkdriver(u_int32_t hid)
  2548. +{
  2549. + if (crypto_drivers == NULL)
  2550. + return NULL;
  2551. + return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]);
  2552. +}
  2553. +
  2554. +/*
  2555. + * Compare a driver's list of supported algorithms against another
  2556. + * list; return non-zero if all algorithms are supported.
  2557. + */
  2558. +static int
  2559. +driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri)
  2560. +{
  2561. + const struct cryptoini *cr;
  2562. +
  2563. + /* See if all the algorithms are supported. */
  2564. + for (cr = cri; cr; cr = cr->cri_next)
  2565. + if (cap->cc_alg[cr->cri_alg] == 0)
  2566. + return 0;
  2567. + return 1;
  2568. +}
  2569. +
  2570. +/*
  2571. + * Select a driver for a new session that supports the specified
  2572. + * algorithms and, optionally, is constrained according to the flags.
  2573. + * The algorithm we use here is pretty stupid; just use the
  2574. + * first driver that supports all the algorithms we need. If there
  2575. + * are multiple drivers we choose the driver with the fewest active
  2576. + * sessions. We prefer hardware-backed drivers to software ones.
  2577. + *
  2578. + * XXX We need more smarts here (in real life too, but that's
  2579. + * XXX another story altogether).
  2580. + */
  2581. +static struct cryptocap *
  2582. +crypto_select_driver(const struct cryptoini *cri, int flags)
  2583. +{
  2584. + struct cryptocap *cap, *best;
  2585. + int match, hid;
  2586. +
  2587. + CRYPTO_DRIVER_ASSERT();
  2588. +
  2589. + /*
  2590. + * Look first for hardware crypto devices if permitted.
  2591. + */
  2592. + if (flags & CRYPTOCAP_F_HARDWARE)
  2593. + match = CRYPTOCAP_F_HARDWARE;
  2594. + else
  2595. + match = CRYPTOCAP_F_SOFTWARE;
  2596. + best = NULL;
  2597. +again:
  2598. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  2599. + cap = &crypto_drivers[hid];
  2600. + /*
  2601. + * If it's not initialized, is in the process of
  2602. + * going away, or is not appropriate (hardware
  2603. + * or software based on match), then skip.
  2604. + */
  2605. + if (cap->cc_dev == NULL ||
  2606. + (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
  2607. + (cap->cc_flags & match) == 0)
  2608. + continue;
  2609. +
  2610. + /* verify all the algorithms are supported. */
  2611. + if (driver_suitable(cap, cri)) {
  2612. + if (best == NULL ||
  2613. + cap->cc_sessions < best->cc_sessions)
  2614. + best = cap;
  2615. + }
  2616. + }
  2617. + if (best != NULL)
  2618. + return best;
  2619. + if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
  2620. + /* sort of an Algol 68-style for loop */
  2621. + match = CRYPTOCAP_F_SOFTWARE;
  2622. + goto again;
  2623. + }
  2624. + return best;
  2625. +}
  2626. +
  2627. +/*
  2628. + * Create a new session. The crid argument specifies a crypto
  2629. + * driver to use or constraints on a driver to select (hardware
  2630. + * only, software only, either). Whatever driver is selected
  2631. + * must be capable of the requested crypto algorithms.
  2632. + */
  2633. +int
  2634. +crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid)
  2635. +{
  2636. + struct cryptocap *cap;
  2637. + u_int32_t hid, lid;
  2638. + int err;
  2639. + unsigned long d_flags;
  2640. +
  2641. + CRYPTO_DRIVER_LOCK();
  2642. + if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  2643. + /*
  2644. + * Use specified driver; verify it is capable.
  2645. + */
  2646. + cap = crypto_checkdriver(crid);
  2647. + if (cap != NULL && !driver_suitable(cap, cri))
  2648. + cap = NULL;
  2649. + } else {
  2650. + /*
  2651. + * No requested driver; select based on crid flags.
  2652. + */
  2653. + cap = crypto_select_driver(cri, crid);
  2654. + /*
  2655. + * if NULL then can't do everything in one session.
  2656. + * XXX Fix this. We need to inject a "virtual" session
  2657. + * XXX layer right about here.
  2658. + */
  2659. + }
  2660. + if (cap != NULL) {
  2661. + /* Call the driver initialization routine. */
  2662. + hid = cap - crypto_drivers;
  2663. + lid = hid; /* Pass the driver ID. */
  2664. + cap->cc_sessions++;
  2665. + CRYPTO_DRIVER_UNLOCK();
  2666. + err = CRYPTODEV_NEWSESSION(cap->cc_dev, &lid, cri);
  2667. + CRYPTO_DRIVER_LOCK();
  2668. + if (err == 0) {
  2669. + (*sid) = (cap->cc_flags & 0xff000000)
  2670. + | (hid & 0x00ffffff);
  2671. + (*sid) <<= 32;
  2672. + (*sid) |= (lid & 0xffffffff);
  2673. + } else
  2674. + cap->cc_sessions--;
  2675. + } else
  2676. + err = EINVAL;
  2677. + CRYPTO_DRIVER_UNLOCK();
  2678. + return err;
  2679. +}
  2680. +
  2681. +static void
  2682. +crypto_remove(struct cryptocap *cap)
  2683. +{
  2684. + CRYPTO_DRIVER_ASSERT();
  2685. + if (cap->cc_sessions == 0 && cap->cc_koperations == 0)
  2686. + bzero(cap, sizeof(*cap));
  2687. +}
  2688. +
  2689. +/*
  2690. + * Delete an existing session (or a reserved session on an unregistered
  2691. + * driver).
  2692. + */
  2693. +int
  2694. +crypto_freesession(u_int64_t sid)
  2695. +{
  2696. + struct cryptocap *cap;
  2697. + u_int32_t hid;
  2698. + int err = 0;
  2699. + unsigned long d_flags;
  2700. +
  2701. + dprintk("%s()\n", __FUNCTION__);
  2702. + CRYPTO_DRIVER_LOCK();
  2703. +
  2704. + if (crypto_drivers == NULL) {
  2705. + err = EINVAL;
  2706. + goto done;
  2707. + }
  2708. +
  2709. + /* Determine two IDs. */
  2710. + hid = CRYPTO_SESID2HID(sid);
  2711. +
  2712. + if (hid >= crypto_drivers_num) {
  2713. + dprintk("%s - INVALID DRIVER NUM %d\n", __FUNCTION__, hid);
  2714. + err = ENOENT;
  2715. + goto done;
  2716. + }
  2717. + cap = &crypto_drivers[hid];
  2718. +
  2719. + if (cap->cc_dev) {
  2720. + CRYPTO_DRIVER_UNLOCK();
  2721. + /* Call the driver cleanup routine, if available, unlocked. */
  2722. + err = CRYPTODEV_FREESESSION(cap->cc_dev, sid);
  2723. + CRYPTO_DRIVER_LOCK();
  2724. + }
  2725. +
  2726. + if (cap->cc_sessions)
  2727. + cap->cc_sessions--;
  2728. +
  2729. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
  2730. + crypto_remove(cap);
  2731. +
  2732. +done:
  2733. + CRYPTO_DRIVER_UNLOCK();
  2734. + return err;
  2735. +}
  2736. +
  2737. +/*
  2738. + * Return an unused driver id. Used by drivers prior to registering
  2739. + * support for the algorithms they handle.
  2740. + */
  2741. +int32_t
  2742. +crypto_get_driverid(device_t dev, int flags)
  2743. +{
  2744. + struct cryptocap *newdrv;
  2745. + int i;
  2746. + unsigned long d_flags;
  2747. +
  2748. + if ((flags & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  2749. + printf("%s: no flags specified when registering driver\n",
  2750. + device_get_nameunit(dev));
  2751. + return -1;
  2752. + }
  2753. +
  2754. + CRYPTO_DRIVER_LOCK();
  2755. +
  2756. + for (i = 0; i < crypto_drivers_num; i++) {
  2757. + if (crypto_drivers[i].cc_dev == NULL &&
  2758. + (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0) {
  2759. + break;
  2760. + }
  2761. + }
  2762. +
  2763. + /* Out of entries, allocate some more. */
  2764. + if (i == crypto_drivers_num) {
  2765. + /* Be careful about wrap-around. */
  2766. + if (2 * crypto_drivers_num <= crypto_drivers_num) {
  2767. + CRYPTO_DRIVER_UNLOCK();
  2768. + printk("crypto: driver count wraparound!\n");
  2769. + return -1;
  2770. + }
  2771. +
  2772. + newdrv = kmalloc(2 * crypto_drivers_num * sizeof(struct cryptocap),
  2773. + GFP_KERNEL);
  2774. + if (newdrv == NULL) {
  2775. + CRYPTO_DRIVER_UNLOCK();
  2776. + printk("crypto: no space to expand driver table!\n");
  2777. + return -1;
  2778. + }
  2779. +
  2780. + memcpy(newdrv, crypto_drivers,
  2781. + crypto_drivers_num * sizeof(struct cryptocap));
  2782. + memset(&newdrv[crypto_drivers_num], 0,
  2783. + crypto_drivers_num * sizeof(struct cryptocap));
  2784. +
  2785. + crypto_drivers_num *= 2;
  2786. +
  2787. + kfree(crypto_drivers);
  2788. + crypto_drivers = newdrv;
  2789. + }
  2790. +
  2791. + /* NB: state is zero'd on free */
  2792. + crypto_drivers[i].cc_sessions = 1; /* Mark */
  2793. + crypto_drivers[i].cc_dev = dev;
  2794. + crypto_drivers[i].cc_flags = flags;
  2795. + if (bootverbose)
  2796. + printf("crypto: assign %s driver id %u, flags %u\n",
  2797. + device_get_nameunit(dev), i, flags);
  2798. +
  2799. + CRYPTO_DRIVER_UNLOCK();
  2800. +
  2801. + return i;
  2802. +}
  2803. +
  2804. +/*
  2805. + * Lookup a driver by name. We match against the full device
  2806. + * name and unit, and against just the name. The latter gives
  2807. + * us a simple widlcarding by device name. On success return the
  2808. + * driver/hardware identifier; otherwise return -1.
  2809. + */
  2810. +int
  2811. +crypto_find_driver(const char *match)
  2812. +{
  2813. + int i, len = strlen(match);
  2814. + unsigned long d_flags;
  2815. +
  2816. + CRYPTO_DRIVER_LOCK();
  2817. + for (i = 0; i < crypto_drivers_num; i++) {
  2818. + device_t dev = crypto_drivers[i].cc_dev;
  2819. + if (dev == NULL ||
  2820. + (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP))
  2821. + continue;
  2822. + if (strncmp(match, device_get_nameunit(dev), len) == 0 ||
  2823. + strncmp(match, device_get_name(dev), len) == 0)
  2824. + break;
  2825. + }
  2826. + CRYPTO_DRIVER_UNLOCK();
  2827. + return i < crypto_drivers_num ? i : -1;
  2828. +}
  2829. +
  2830. +/*
  2831. + * Return the device_t for the specified driver or NULL
  2832. + * if the driver identifier is invalid.
  2833. + */
  2834. +device_t
  2835. +crypto_find_device_byhid(int hid)
  2836. +{
  2837. + struct cryptocap *cap = crypto_checkdriver(hid);
  2838. + return cap != NULL ? cap->cc_dev : NULL;
  2839. +}
  2840. +
  2841. +/*
  2842. + * Return the device/driver capabilities.
  2843. + */
  2844. +int
  2845. +crypto_getcaps(int hid)
  2846. +{
  2847. + struct cryptocap *cap = crypto_checkdriver(hid);
  2848. + return cap != NULL ? cap->cc_flags : 0;
  2849. +}
  2850. +
  2851. +/*
  2852. + * Register support for a key-related algorithm. This routine
  2853. + * is called once for each algorithm supported a driver.
  2854. + */
  2855. +int
  2856. +crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags)
  2857. +{
  2858. + struct cryptocap *cap;
  2859. + int err;
  2860. + unsigned long d_flags;
  2861. +
  2862. + dprintk("%s()\n", __FUNCTION__);
  2863. + CRYPTO_DRIVER_LOCK();
  2864. +
  2865. + cap = crypto_checkdriver(driverid);
  2866. + if (cap != NULL &&
  2867. + (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {
  2868. + /*
  2869. + * XXX Do some performance testing to determine placing.
  2870. + * XXX We probably need an auxiliary data structure that
  2871. + * XXX describes relative performances.
  2872. + */
  2873. +
  2874. + cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
  2875. + if (bootverbose)
  2876. + printf("crypto: %s registers key alg %u flags %u\n"
  2877. + , device_get_nameunit(cap->cc_dev)
  2878. + , kalg
  2879. + , flags
  2880. + );
  2881. + err = 0;
  2882. + } else
  2883. + err = EINVAL;
  2884. +
  2885. + CRYPTO_DRIVER_UNLOCK();
  2886. + return err;
  2887. +}
  2888. +
  2889. +/*
  2890. + * Register support for a non-key-related algorithm. This routine
  2891. + * is called once for each such algorithm supported by a driver.
  2892. + */
  2893. +int
  2894. +crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
  2895. + u_int32_t flags)
  2896. +{
  2897. + struct cryptocap *cap;
  2898. + int err;
  2899. + unsigned long d_flags;
  2900. +
  2901. + dprintk("%s(id=0x%x, alg=%d, maxoplen=%d, flags=0x%x)\n", __FUNCTION__,
  2902. + driverid, alg, maxoplen, flags);
  2903. +
  2904. + CRYPTO_DRIVER_LOCK();
  2905. +
  2906. + cap = crypto_checkdriver(driverid);
  2907. + /* NB: algorithms are in the range [1..max] */
  2908. + if (cap != NULL &&
  2909. + (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) {
  2910. + /*
  2911. + * XXX Do some performance testing to determine placing.
  2912. + * XXX We probably need an auxiliary data structure that
  2913. + * XXX describes relative performances.
  2914. + */
  2915. +
  2916. + cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
  2917. + cap->cc_max_op_len[alg] = maxoplen;
  2918. + if (bootverbose)
  2919. + printf("crypto: %s registers alg %u flags %u maxoplen %u\n"
  2920. + , device_get_nameunit(cap->cc_dev)
  2921. + , alg
  2922. + , flags
  2923. + , maxoplen
  2924. + );
  2925. + cap->cc_sessions = 0; /* Unmark */
  2926. + err = 0;
  2927. + } else
  2928. + err = EINVAL;
  2929. +
  2930. + CRYPTO_DRIVER_UNLOCK();
  2931. + return err;
  2932. +}
  2933. +
  2934. +static void
  2935. +driver_finis(struct cryptocap *cap)
  2936. +{
  2937. + u_int32_t ses, kops;
  2938. +
  2939. + CRYPTO_DRIVER_ASSERT();
  2940. +
  2941. + ses = cap->cc_sessions;
  2942. + kops = cap->cc_koperations;
  2943. + bzero(cap, sizeof(*cap));
  2944. + if (ses != 0 || kops != 0) {
  2945. + /*
  2946. + * If there are pending sessions,
  2947. + * just mark as invalid.
  2948. + */
  2949. + cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
  2950. + cap->cc_sessions = ses;
  2951. + cap->cc_koperations = kops;
  2952. + }
  2953. +}
  2954. +
  2955. +/*
  2956. + * Unregister a crypto driver. If there are pending sessions using it,
  2957. + * leave enough information around so that subsequent calls using those
  2958. + * sessions will correctly detect the driver has been unregistered and
  2959. + * reroute requests.
  2960. + */
  2961. +int
  2962. +crypto_unregister(u_int32_t driverid, int alg)
  2963. +{
  2964. + struct cryptocap *cap;
  2965. + int i, err;
  2966. + unsigned long d_flags;
  2967. +
  2968. + dprintk("%s()\n", __FUNCTION__);
  2969. + CRYPTO_DRIVER_LOCK();
  2970. +
  2971. + cap = crypto_checkdriver(driverid);
  2972. + if (cap != NULL &&
  2973. + (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) &&
  2974. + cap->cc_alg[alg] != 0) {
  2975. + cap->cc_alg[alg] = 0;
  2976. + cap->cc_max_op_len[alg] = 0;
  2977. +
  2978. + /* Was this the last algorithm ? */
  2979. + for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
  2980. + if (cap->cc_alg[i] != 0)
  2981. + break;
  2982. +
  2983. + if (i == CRYPTO_ALGORITHM_MAX + 1)
  2984. + driver_finis(cap);
  2985. + err = 0;
  2986. + } else
  2987. + err = EINVAL;
  2988. + CRYPTO_DRIVER_UNLOCK();
  2989. + return err;
  2990. +}
  2991. +
  2992. +/*
  2993. + * Unregister all algorithms associated with a crypto driver.
  2994. + * If there are pending sessions using it, leave enough information
  2995. + * around so that subsequent calls using those sessions will
  2996. + * correctly detect the driver has been unregistered and reroute
  2997. + * requests.
  2998. + */
  2999. +int
  3000. +crypto_unregister_all(u_int32_t driverid)
  3001. +{
  3002. + struct cryptocap *cap;
  3003. + int err;
  3004. + unsigned long d_flags;
  3005. +
  3006. + dprintk("%s()\n", __FUNCTION__);
  3007. + CRYPTO_DRIVER_LOCK();
  3008. + cap = crypto_checkdriver(driverid);
  3009. + if (cap != NULL) {
  3010. + driver_finis(cap);
  3011. + err = 0;
  3012. + } else
  3013. + err = EINVAL;
  3014. + CRYPTO_DRIVER_UNLOCK();
  3015. +
  3016. + return err;
  3017. +}
  3018. +
  3019. +/*
  3020. + * Clear blockage on a driver. The what parameter indicates whether
  3021. + * the driver is now ready for cryptop's and/or cryptokop's.
  3022. + */
  3023. +int
  3024. +crypto_unblock(u_int32_t driverid, int what)
  3025. +{
  3026. + struct cryptocap *cap;
  3027. + int err;
  3028. + unsigned long q_flags;
  3029. +
  3030. + CRYPTO_Q_LOCK();
  3031. + cap = crypto_checkdriver(driverid);
  3032. + if (cap != NULL) {
  3033. + if (what & CRYPTO_SYMQ) {
  3034. + cap->cc_qblocked = 0;
  3035. + cap->cc_unqblocked = 0;
  3036. + crypto_all_qblocked = 0;
  3037. + }
  3038. + if (what & CRYPTO_ASYMQ) {
  3039. + cap->cc_kqblocked = 0;
  3040. + cap->cc_unkqblocked = 0;
  3041. + crypto_all_kqblocked = 0;
  3042. + }
  3043. + if (crp_sleep)
  3044. + wake_up_interruptible(&cryptoproc_wait);
  3045. + err = 0;
  3046. + } else
  3047. + err = EINVAL;
  3048. + CRYPTO_Q_UNLOCK(); //DAVIDM should this be a driver lock
  3049. +
  3050. + return err;
  3051. +}
  3052. +
  3053. +/*
  3054. + * Add a crypto request to a queue, to be processed by the kernel thread.
  3055. + */
  3056. +int
  3057. +crypto_dispatch(struct cryptop *crp)
  3058. +{
  3059. + struct cryptocap *cap;
  3060. + int result = -1;
  3061. + unsigned long q_flags;
  3062. +
  3063. + dprintk("%s()\n", __FUNCTION__);
  3064. +
  3065. + cryptostats.cs_ops++;
  3066. +
  3067. + CRYPTO_Q_LOCK();
  3068. + if (crypto_q_cnt >= crypto_q_max) {
  3069. + CRYPTO_Q_UNLOCK();
  3070. + cryptostats.cs_drops++;
  3071. + return ENOMEM;
  3072. + }
  3073. + crypto_q_cnt++;
  3074. +
  3075. + /* make sure we are starting a fresh run on this crp. */
  3076. + crp->crp_flags &= ~CRYPTO_F_DONE;
  3077. + crp->crp_etype = 0;
  3078. +
  3079. + /*
  3080. + * Caller marked the request to be processed immediately; dispatch
  3081. + * it directly to the driver unless the driver is currently blocked.
  3082. + */
  3083. + if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
  3084. + int hid = CRYPTO_SESID2HID(crp->crp_sid);
  3085. + cap = crypto_checkdriver(hid);
  3086. + /* Driver cannot disappear when there is an active session. */
  3087. + KASSERT(cap != NULL, ("%s: Driver disappeared.", __func__));
  3088. + if (!cap->cc_qblocked) {
  3089. + crypto_all_qblocked = 0;
  3090. + crypto_drivers[hid].cc_unqblocked = 1;
  3091. + CRYPTO_Q_UNLOCK();
  3092. + result = crypto_invoke(cap, crp, 0);
  3093. + CRYPTO_Q_LOCK();
  3094. + if (result == ERESTART)
  3095. + if (crypto_drivers[hid].cc_unqblocked)
  3096. + crypto_drivers[hid].cc_qblocked = 1;
  3097. + crypto_drivers[hid].cc_unqblocked = 0;
  3098. + }
  3099. + }
  3100. + if (result == ERESTART) {
  3101. + /*
  3102. + * The driver ran out of resources, mark the
  3103. + * driver ``blocked'' for cryptop's and put
  3104. + * the request back in the queue. It would
  3105. + * best to put the request back where we got
  3106. + * it but that's hard so for now we put it
  3107. + * at the front. This should be ok; putting
  3108. + * it at the end does not work.
  3109. + */
  3110. + list_add(&crp->crp_next, &crp_q);
  3111. + cryptostats.cs_blocks++;
  3112. + result = 0;
  3113. + } else if (result == -1) {
  3114. + TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
  3115. + result = 0;
  3116. + }
  3117. + if (crp_sleep)
  3118. + wake_up_interruptible(&cryptoproc_wait);
  3119. + CRYPTO_Q_UNLOCK();
  3120. + return result;
  3121. +}
  3122. +
  3123. +/*
  3124. + * Add an asymetric crypto request to a queue,
  3125. + * to be processed by the kernel thread.
  3126. + */
  3127. +int
  3128. +crypto_kdispatch(struct cryptkop *krp)
  3129. +{
  3130. + int error;
  3131. + unsigned long q_flags;
  3132. +
  3133. + cryptostats.cs_kops++;
  3134. +
  3135. + error = crypto_kinvoke(krp, krp->krp_crid);
  3136. + if (error == ERESTART) {
  3137. + CRYPTO_Q_LOCK();
  3138. + TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
  3139. + if (crp_sleep)
  3140. + wake_up_interruptible(&cryptoproc_wait);
  3141. + CRYPTO_Q_UNLOCK();
  3142. + error = 0;
  3143. + }
  3144. + return error;
  3145. +}
  3146. +
  3147. +/*
  3148. + * Verify a driver is suitable for the specified operation.
  3149. + */
  3150. +static __inline int
  3151. +kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp)
  3152. +{
  3153. + return (cap->cc_kalg[krp->krp_op] & CRYPTO_ALG_FLAG_SUPPORTED) != 0;
  3154. +}
  3155. +
  3156. +/*
  3157. + * Select a driver for an asym operation. The driver must
  3158. + * support the necessary algorithm. The caller can constrain
  3159. + * which device is selected with the flags parameter. The
  3160. + * algorithm we use here is pretty stupid; just use the first
  3161. + * driver that supports the algorithms we need. If there are
  3162. + * multiple suitable drivers we choose the driver with the
  3163. + * fewest active operations. We prefer hardware-backed
  3164. + * drivers to software ones when either may be used.
  3165. + */
  3166. +static struct cryptocap *
  3167. +crypto_select_kdriver(const struct cryptkop *krp, int flags)
  3168. +{
  3169. + struct cryptocap *cap, *best, *blocked;
  3170. + int match, hid;
  3171. +
  3172. + CRYPTO_DRIVER_ASSERT();
  3173. +
  3174. + /*
  3175. + * Look first for hardware crypto devices if permitted.
  3176. + */
  3177. + if (flags & CRYPTOCAP_F_HARDWARE)
  3178. + match = CRYPTOCAP_F_HARDWARE;
  3179. + else
  3180. + match = CRYPTOCAP_F_SOFTWARE;
  3181. + best = NULL;
  3182. + blocked = NULL;
  3183. +again:
  3184. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  3185. + cap = &crypto_drivers[hid];
  3186. + /*
  3187. + * If it's not initialized, is in the process of
  3188. + * going away, or is not appropriate (hardware
  3189. + * or software based on match), then skip.
  3190. + */
  3191. + if (cap->cc_dev == NULL ||
  3192. + (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
  3193. + (cap->cc_flags & match) == 0)
  3194. + continue;
  3195. +
  3196. + /* verify all the algorithms are supported. */
  3197. + if (kdriver_suitable(cap, krp)) {
  3198. + if (best == NULL ||
  3199. + cap->cc_koperations < best->cc_koperations)
  3200. + best = cap;
  3201. + }
  3202. + }
  3203. + if (best != NULL)
  3204. + return best;
  3205. + if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
  3206. + /* sort of an Algol 68-style for loop */
  3207. + match = CRYPTOCAP_F_SOFTWARE;
  3208. + goto again;
  3209. + }
  3210. + return best;
  3211. +}
  3212. +
  3213. +/*
  3214. + * Dispatch an assymetric crypto request.
  3215. + */
  3216. +static int
  3217. +crypto_kinvoke(struct cryptkop *krp, int crid)
  3218. +{
  3219. + struct cryptocap *cap = NULL;
  3220. + int error;
  3221. + unsigned long d_flags;
  3222. +
  3223. + KASSERT(krp != NULL, ("%s: krp == NULL", __func__));
  3224. + KASSERT(krp->krp_callback != NULL,
  3225. + ("%s: krp->crp_callback == NULL", __func__));
  3226. +
  3227. + CRYPTO_DRIVER_LOCK();
  3228. + if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  3229. + cap = crypto_checkdriver(crid);
  3230. + if (cap != NULL) {
  3231. + /*
  3232. + * Driver present, it must support the necessary
  3233. + * algorithm and, if s/w drivers are excluded,
  3234. + * it must be registered as hardware-backed.
  3235. + */
  3236. + if (!kdriver_suitable(cap, krp) ||
  3237. + (!crypto_devallowsoft &&
  3238. + (cap->cc_flags & CRYPTOCAP_F_HARDWARE) == 0))
  3239. + cap = NULL;
  3240. + }
  3241. + } else {
  3242. + /*
  3243. + * No requested driver; select based on crid flags.
  3244. + */
  3245. + if (!crypto_devallowsoft) /* NB: disallow s/w drivers */
  3246. + crid &= ~CRYPTOCAP_F_SOFTWARE;
  3247. + cap = crypto_select_kdriver(krp, crid);
  3248. + }
  3249. + if (cap != NULL && !cap->cc_kqblocked) {
  3250. + krp->krp_hid = cap - crypto_drivers;
  3251. + cap->cc_koperations++;
  3252. + CRYPTO_DRIVER_UNLOCK();
  3253. + error = CRYPTODEV_KPROCESS(cap->cc_dev, krp, 0);
  3254. + CRYPTO_DRIVER_LOCK();
  3255. + if (error == ERESTART) {
  3256. + cap->cc_koperations--;
  3257. + CRYPTO_DRIVER_UNLOCK();
  3258. + return (error);
  3259. + }
  3260. + /* return the actual device used */
  3261. + krp->krp_crid = krp->krp_hid;
  3262. + } else {
  3263. + /*
  3264. + * NB: cap is !NULL if device is blocked; in
  3265. + * that case return ERESTART so the operation
  3266. + * is resubmitted if possible.
  3267. + */
  3268. + error = (cap == NULL) ? ENODEV : ERESTART;
  3269. + }
  3270. + CRYPTO_DRIVER_UNLOCK();
  3271. +
  3272. + if (error) {
  3273. + krp->krp_status = error;
  3274. + crypto_kdone(krp);
  3275. + }
  3276. + return 0;
  3277. +}
  3278. +
  3279. +
  3280. +/*
  3281. + * Dispatch a crypto request to the appropriate crypto devices.
  3282. + */
  3283. +static int
  3284. +crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint)
  3285. +{
  3286. + KASSERT(crp != NULL, ("%s: crp == NULL", __func__));
  3287. + KASSERT(crp->crp_callback != NULL,
  3288. + ("%s: crp->crp_callback == NULL", __func__));
  3289. + KASSERT(crp->crp_desc != NULL, ("%s: crp->crp_desc == NULL", __func__));
  3290. +
  3291. + dprintk("%s()\n", __FUNCTION__);
  3292. +
  3293. +#ifdef CRYPTO_TIMING
  3294. + if (crypto_timing)
  3295. + crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);
  3296. +#endif
  3297. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) {
  3298. + struct cryptodesc *crd;
  3299. + u_int64_t nid;
  3300. +
  3301. + /*
  3302. + * Driver has unregistered; migrate the session and return
  3303. + * an error to the caller so they'll resubmit the op.
  3304. + *
  3305. + * XXX: What if there are more already queued requests for this
  3306. + * session?
  3307. + */
  3308. + crypto_freesession(crp->crp_sid);
  3309. +
  3310. + for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
  3311. + crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
  3312. +
  3313. + /* XXX propagate flags from initial session? */
  3314. + if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI),
  3315. + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE) == 0)
  3316. + crp->crp_sid = nid;
  3317. +
  3318. + crp->crp_etype = EAGAIN;
  3319. + crypto_done(crp);
  3320. + return 0;
  3321. + } else {
  3322. + /*
  3323. + * Invoke the driver to process the request.
  3324. + */
  3325. + return CRYPTODEV_PROCESS(cap->cc_dev, crp, hint);
  3326. + }
  3327. +}
  3328. +
  3329. +/*
  3330. + * Release a set of crypto descriptors.
  3331. + */
  3332. +void
  3333. +crypto_freereq(struct cryptop *crp)
  3334. +{
  3335. + struct cryptodesc *crd;
  3336. +
  3337. + if (crp == NULL)
  3338. + return;
  3339. +
  3340. +#ifdef DIAGNOSTIC
  3341. + {
  3342. + struct cryptop *crp2;
  3343. + unsigned long q_flags;
  3344. +
  3345. + CRYPTO_Q_LOCK();
  3346. + TAILQ_FOREACH(crp2, &crp_q, crp_next) {
  3347. + KASSERT(crp2 != crp,
  3348. + ("Freeing cryptop from the crypto queue (%p).",
  3349. + crp));
  3350. + }
  3351. + CRYPTO_Q_UNLOCK();
  3352. + CRYPTO_RETQ_LOCK();
  3353. + TAILQ_FOREACH(crp2, &crp_ret_q, crp_next) {
  3354. + KASSERT(crp2 != crp,
  3355. + ("Freeing cryptop from the return queue (%p).",
  3356. + crp));
  3357. + }
  3358. + CRYPTO_RETQ_UNLOCK();
  3359. + }
  3360. +#endif
  3361. +
  3362. + while ((crd = crp->crp_desc) != NULL) {
  3363. + crp->crp_desc = crd->crd_next;
  3364. + kmem_cache_free(cryptodesc_zone, crd);
  3365. + }
  3366. + kmem_cache_free(cryptop_zone, crp);
  3367. +}
  3368. +
  3369. +/*
  3370. + * Acquire a set of crypto descriptors.
  3371. + */
  3372. +struct cryptop *
  3373. +crypto_getreq(int num)
  3374. +{
  3375. + struct cryptodesc *crd;
  3376. + struct cryptop *crp;
  3377. +
  3378. + crp = kmem_cache_alloc(cryptop_zone, SLAB_ATOMIC);
  3379. + if (crp != NULL) {
  3380. + memset(crp, 0, sizeof(*crp));
  3381. + INIT_LIST_HEAD(&crp->crp_next);
  3382. + init_waitqueue_head(&crp->crp_waitq);
  3383. + while (num--) {
  3384. + crd = kmem_cache_alloc(cryptodesc_zone, SLAB_ATOMIC);
  3385. + if (crd == NULL) {
  3386. + crypto_freereq(crp);
  3387. + return NULL;
  3388. + }
  3389. + memset(crd, 0, sizeof(*crd));
  3390. + crd->crd_next = crp->crp_desc;
  3391. + crp->crp_desc = crd;
  3392. + }
  3393. + }
  3394. + return crp;
  3395. +}
  3396. +
  3397. +/*
  3398. + * Invoke the callback on behalf of the driver.
  3399. + */
  3400. +void
  3401. +crypto_done(struct cryptop *crp)
  3402. +{
  3403. + unsigned long q_flags;
  3404. +
  3405. + dprintk("%s()\n", __FUNCTION__);
  3406. + if ((crp->crp_flags & CRYPTO_F_DONE) == 0) {
  3407. + crp->crp_flags |= CRYPTO_F_DONE;
  3408. + CRYPTO_Q_LOCK();
  3409. + crypto_q_cnt--;
  3410. + CRYPTO_Q_UNLOCK();
  3411. + } else
  3412. + printk("crypto: crypto_done op already done, flags 0x%x",
  3413. + crp->crp_flags);
  3414. + if (crp->crp_etype != 0)
  3415. + cryptostats.cs_errs++;
  3416. + /*
  3417. + * CBIMM means unconditionally do the callback immediately;
  3418. + * CBIFSYNC means do the callback immediately only if the
  3419. + * operation was done synchronously. Both are used to avoid
  3420. + * doing extraneous context switches; the latter is mostly
  3421. + * used with the software crypto driver.
  3422. + */
  3423. + if ((crp->crp_flags & CRYPTO_F_CBIMM) ||
  3424. + ((crp->crp_flags & CRYPTO_F_CBIFSYNC) &&
  3425. + (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC))) {
  3426. + /*
  3427. + * Do the callback directly. This is ok when the
  3428. + * callback routine does very little (e.g. the
  3429. + * /dev/crypto callback method just does a wakeup).
  3430. + */
  3431. + crp->crp_callback(crp);
  3432. + } else {
  3433. + unsigned long r_flags;
  3434. + /*
  3435. + * Normal case; queue the callback for the thread.
  3436. + */
  3437. + CRYPTO_RETQ_LOCK();
  3438. + if (CRYPTO_RETQ_EMPTY())
  3439. + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
  3440. + TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
  3441. + CRYPTO_RETQ_UNLOCK();
  3442. + }
  3443. +}
  3444. +
  3445. +/*
  3446. + * Invoke the callback on behalf of the driver.
  3447. + */
  3448. +void
  3449. +crypto_kdone(struct cryptkop *krp)
  3450. +{
  3451. + struct cryptocap *cap;
  3452. + unsigned long d_flags;
  3453. +
  3454. + if ((krp->krp_flags & CRYPTO_KF_DONE) != 0)
  3455. + printk("crypto: crypto_kdone op already done, flags 0x%x",
  3456. + krp->krp_flags);
  3457. + krp->krp_flags |= CRYPTO_KF_DONE;
  3458. + if (krp->krp_status != 0)
  3459. + cryptostats.cs_kerrs++;
  3460. +
  3461. + CRYPTO_DRIVER_LOCK();
  3462. + /* XXX: What if driver is loaded in the meantime? */
  3463. + if (krp->krp_hid < crypto_drivers_num) {
  3464. + cap = &crypto_drivers[krp->krp_hid];
  3465. + cap->cc_koperations--;
  3466. + KASSERT(cap->cc_koperations >= 0, ("cc_koperations < 0"));
  3467. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
  3468. + crypto_remove(cap);
  3469. + }
  3470. + CRYPTO_DRIVER_UNLOCK();
  3471. +
  3472. + /*
  3473. + * CBIMM means unconditionally do the callback immediately;
  3474. + * This is used to avoid doing extraneous context switches
  3475. + */
  3476. + if ((krp->krp_flags & CRYPTO_KF_CBIMM)) {
  3477. + /*
  3478. + * Do the callback directly. This is ok when the
  3479. + * callback routine does very little (e.g. the
  3480. + * /dev/crypto callback method just does a wakeup).
  3481. + */
  3482. + krp->krp_callback(krp);
  3483. + } else {
  3484. + unsigned long r_flags;
  3485. + /*
  3486. + * Normal case; queue the callback for the thread.
  3487. + */
  3488. + CRYPTO_RETQ_LOCK();
  3489. + if (CRYPTO_RETQ_EMPTY())
  3490. + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
  3491. + TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
  3492. + CRYPTO_RETQ_UNLOCK();
  3493. + }
  3494. +}
  3495. +
  3496. +int
  3497. +crypto_getfeat(int *featp)
  3498. +{
  3499. + int hid, kalg, feat = 0;
  3500. + unsigned long d_flags;
  3501. +
  3502. + CRYPTO_DRIVER_LOCK();
  3503. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  3504. + const struct cryptocap *cap = &crypto_drivers[hid];
  3505. +
  3506. + if ((cap->cc_flags & CRYPTOCAP_F_SOFTWARE) &&
  3507. + !crypto_devallowsoft) {
  3508. + continue;
  3509. + }
  3510. + for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
  3511. + if (cap->cc_kalg[kalg] & CRYPTO_ALG_FLAG_SUPPORTED)
  3512. + feat |= 1 << kalg;
  3513. + }
  3514. + CRYPTO_DRIVER_UNLOCK();
  3515. + *featp = feat;
  3516. + return (0);
  3517. +}
  3518. +
  3519. +/*
  3520. + * Crypto thread, dispatches crypto requests.
  3521. + */
  3522. +static int
  3523. +crypto_proc(void *arg)
  3524. +{
  3525. + struct cryptop *crp, *submit;
  3526. + struct cryptkop *krp, *krpp;
  3527. + struct cryptocap *cap;
  3528. + u_int32_t hid;
  3529. + int result, hint;
  3530. + unsigned long q_flags;
  3531. + int loopcount = 0;
  3532. +
  3533. + ocf_daemonize("crypto");
  3534. +
  3535. + CRYPTO_Q_LOCK();
  3536. + for (;;) {
  3537. + /*
  3538. + * we need to make sure we don't get into a busy loop with nothing
  3539. + * to do, the two crypto_all_*blocked vars help us find out when
  3540. + * we are all full and can do nothing on any driver or Q. If so we
  3541. + * wait for an unblock.
  3542. + */
  3543. + crypto_all_qblocked = !list_empty(&crp_q);
  3544. +
  3545. + /*
  3546. + * Find the first element in the queue that can be
  3547. + * processed and look-ahead to see if multiple ops
  3548. + * are ready for the same driver.
  3549. + */
  3550. + submit = NULL;
  3551. + hint = 0;
  3552. + list_for_each_entry(crp, &crp_q, crp_next) {
  3553. + hid = CRYPTO_SESID2HID(crp->crp_sid);
  3554. + cap = crypto_checkdriver(hid);
  3555. + /*
  3556. + * Driver cannot disappear when there is an active
  3557. + * session.
  3558. + */
  3559. + KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
  3560. + __func__, __LINE__));
  3561. + if (cap == NULL || cap->cc_dev == NULL) {
  3562. + /* Op needs to be migrated, process it. */
  3563. + if (submit == NULL)
  3564. + submit = crp;
  3565. + break;
  3566. + }
  3567. + if (!cap->cc_qblocked) {
  3568. + if (submit != NULL) {
  3569. + /*
  3570. + * We stop on finding another op,
  3571. + * regardless whether its for the same
  3572. + * driver or not. We could keep
  3573. + * searching the queue but it might be
  3574. + * better to just use a per-driver
  3575. + * queue instead.
  3576. + */
  3577. + if (CRYPTO_SESID2HID(submit->crp_sid) == hid)
  3578. + hint = CRYPTO_HINT_MORE;
  3579. + break;
  3580. + } else {
  3581. + submit = crp;
  3582. + if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)
  3583. + break;
  3584. + /* keep scanning for more are q'd */
  3585. + }
  3586. + }
  3587. + }
  3588. + if (submit != NULL) {
  3589. + hid = CRYPTO_SESID2HID(submit->crp_sid);
  3590. + crypto_all_qblocked = 0;
  3591. + list_del(&submit->crp_next);
  3592. + crypto_drivers[hid].cc_unqblocked = 1;
  3593. + cap = crypto_checkdriver(hid);
  3594. + CRYPTO_Q_UNLOCK();
  3595. + KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
  3596. + __func__, __LINE__));
  3597. + result = crypto_invoke(cap, submit, hint);
  3598. + CRYPTO_Q_LOCK();
  3599. + if (result == ERESTART) {
  3600. + /*
  3601. + * The driver ran out of resources, mark the
  3602. + * driver ``blocked'' for cryptop's and put
  3603. + * the request back in the queue. It would
  3604. + * best to put the request back where we got
  3605. + * it but that's hard so for now we put it
  3606. + * at the front. This should be ok; putting
  3607. + * it at the end does not work.
  3608. + */
  3609. + /* XXX validate sid again? */
  3610. + list_add(&submit->crp_next, &crp_q);
  3611. + cryptostats.cs_blocks++;
  3612. + if (crypto_drivers[hid].cc_unqblocked)
  3613. + crypto_drivers[hid].cc_qblocked=0;
  3614. + crypto_drivers[hid].cc_unqblocked=0;
  3615. + }
  3616. + crypto_drivers[hid].cc_unqblocked = 0;
  3617. + }
  3618. +
  3619. + crypto_all_kqblocked = !list_empty(&crp_kq);
  3620. +
  3621. + /* As above, but for key ops */
  3622. + krp = NULL;
  3623. + list_for_each_entry(krpp, &crp_kq, krp_next) {
  3624. + cap = crypto_checkdriver(krpp->krp_hid);
  3625. + if (cap == NULL || cap->cc_dev == NULL) {
  3626. + /*
  3627. + * Operation needs to be migrated, invalidate
  3628. + * the assigned device so it will reselect a
  3629. + * new one below. Propagate the original
  3630. + * crid selection flags if supplied.
  3631. + */
  3632. + krp->krp_hid = krp->krp_crid &
  3633. + (CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE);
  3634. + if (krp->krp_hid == 0)
  3635. + krp->krp_hid =
  3636. + CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE;
  3637. + break;
  3638. + }
  3639. + if (!cap->cc_kqblocked) {
  3640. + krp = krpp;
  3641. + break;
  3642. + }
  3643. + }
  3644. + if (krp != NULL) {
  3645. + crypto_all_kqblocked = 0;
  3646. + list_del(&krp->krp_next);
  3647. + crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
  3648. + CRYPTO_Q_UNLOCK();
  3649. + result = crypto_kinvoke(krp, krp->krp_hid);
  3650. + CRYPTO_Q_LOCK();
  3651. + if (result == ERESTART) {
  3652. + /*
  3653. + * The driver ran out of resources, mark the
  3654. + * driver ``blocked'' for cryptkop's and put
  3655. + * the request back in the queue. It would
  3656. + * best to put the request back where we got
  3657. + * it but that's hard so for now we put it
  3658. + * at the front. This should be ok; putting
  3659. + * it at the end does not work.
  3660. + */
  3661. + /* XXX validate sid again? */
  3662. + list_add(&krp->krp_next, &crp_kq);
  3663. + cryptostats.cs_kblocks++;
  3664. + } else
  3665. + crypto_drivers[krp->krp_hid].cc_kqblocked = 0;
  3666. + }
  3667. +
  3668. + if (submit == NULL && krp == NULL) {
  3669. + /*
  3670. + * Nothing more to be processed. Sleep until we're
  3671. + * woken because there are more ops to process.
  3672. + * This happens either by submission or by a driver
  3673. + * becoming unblocked and notifying us through
  3674. + * crypto_unblock. Note that when we wakeup we
  3675. + * start processing each queue again from the
  3676. + * front. It's not clear that it's important to
  3677. + * preserve this ordering since ops may finish
  3678. + * out of order if dispatched to different devices
  3679. + * and some become blocked while others do not.
  3680. + */
  3681. + dprintk("%s - sleeping (qe=%d qb=%d kqe=%d kqb=%d)\n",
  3682. + __FUNCTION__,
  3683. + list_empty(&crp_q), crypto_all_qblocked,
  3684. + list_empty(&crp_kq), crypto_all_kqblocked);
  3685. + loopcount = 0;
  3686. + CRYPTO_Q_UNLOCK();
  3687. + crp_sleep = 1;
  3688. + wait_event_interruptible(cryptoproc_wait,
  3689. + !(list_empty(&crp_q) || crypto_all_qblocked) ||
  3690. + !(list_empty(&crp_kq) || crypto_all_kqblocked) ||
  3691. + cryptoproc == (pid_t) -1);
  3692. + crp_sleep = 0;
  3693. + if (signal_pending (current)) {
  3694. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  3695. + spin_lock_irq(&current->sigmask_lock);
  3696. +#endif
  3697. + flush_signals(current);
  3698. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  3699. + spin_unlock_irq(&current->sigmask_lock);
  3700. +#endif
  3701. + }
  3702. + CRYPTO_Q_LOCK();
  3703. + dprintk("%s - awake\n", __FUNCTION__);
  3704. + if (cryptoproc == (pid_t) -1)
  3705. + break;
  3706. + cryptostats.cs_intrs++;
  3707. + } else if (loopcount > crypto_max_loopcount) {
  3708. + /*
  3709. + * Give other processes a chance to run if we've
  3710. + * been using the CPU exclusively for a while.
  3711. + */
  3712. + loopcount = 0;
  3713. + schedule();
  3714. + }
  3715. + loopcount++;
  3716. + }
  3717. + CRYPTO_Q_UNLOCK();
  3718. + complete_and_exit(&cryptoproc_exited, 0);
  3719. +}
  3720. +
  3721. +/*
  3722. + * Crypto returns thread, does callbacks for processed crypto requests.
  3723. + * Callbacks are done here, rather than in the crypto drivers, because
  3724. + * callbacks typically are expensive and would slow interrupt handling.
  3725. + */
  3726. +static int
  3727. +crypto_ret_proc(void *arg)
  3728. +{
  3729. + struct cryptop *crpt;
  3730. + struct cryptkop *krpt;
  3731. + unsigned long r_flags;
  3732. +
  3733. + ocf_daemonize("crypto_ret");
  3734. +
  3735. + CRYPTO_RETQ_LOCK();
  3736. + for (;;) {
  3737. + /* Harvest return q's for completed ops */
  3738. + crpt = NULL;
  3739. + if (!list_empty(&crp_ret_q))
  3740. + crpt = list_entry(crp_ret_q.next, typeof(*crpt), crp_next);
  3741. + if (crpt != NULL)
  3742. + list_del(&crpt->crp_next);
  3743. +
  3744. + krpt = NULL;
  3745. + if (!list_empty(&crp_ret_kq))
  3746. + krpt = list_entry(crp_ret_kq.next, typeof(*krpt), krp_next);
  3747. + if (krpt != NULL)
  3748. + list_del(&krpt->krp_next);
  3749. +
  3750. + if (crpt != NULL || krpt != NULL) {
  3751. + CRYPTO_RETQ_UNLOCK();
  3752. + /*
  3753. + * Run callbacks unlocked.
  3754. + */
  3755. + if (crpt != NULL)
  3756. + crpt->crp_callback(crpt);
  3757. + if (krpt != NULL)
  3758. + krpt->krp_callback(krpt);
  3759. + CRYPTO_RETQ_LOCK();
  3760. + } else {
  3761. + /*
  3762. + * Nothing more to be processed. Sleep until we're
  3763. + * woken because there are more returns to process.
  3764. + */
  3765. + dprintk("%s - sleeping\n", __FUNCTION__);
  3766. + CRYPTO_RETQ_UNLOCK();
  3767. + wait_event_interruptible(cryptoretproc_wait,
  3768. + cryptoretproc == (pid_t) -1 ||
  3769. + !list_empty(&crp_ret_q) ||
  3770. + !list_empty(&crp_ret_kq));
  3771. + if (signal_pending (current)) {
  3772. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  3773. + spin_lock_irq(&current->sigmask_lock);
  3774. +#endif
  3775. + flush_signals(current);
  3776. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  3777. + spin_unlock_irq(&current->sigmask_lock);
  3778. +#endif
  3779. + }
  3780. + CRYPTO_RETQ_LOCK();
  3781. + dprintk("%s - awake\n", __FUNCTION__);
  3782. + if (cryptoretproc == (pid_t) -1) {
  3783. + dprintk("%s - EXITING!\n", __FUNCTION__);
  3784. + break;
  3785. + }
  3786. + cryptostats.cs_rets++;
  3787. + }
  3788. + }
  3789. + CRYPTO_RETQ_UNLOCK();
  3790. + complete_and_exit(&cryptoretproc_exited, 0);
  3791. +}
  3792. +
  3793. +
  3794. +#if 0 /* should put this into /proc or something */
  3795. +static void
  3796. +db_show_drivers(void)
  3797. +{
  3798. + int hid;
  3799. +
  3800. + db_printf("%12s %4s %4s %8s %2s %2s\n"
  3801. + , "Device"
  3802. + , "Ses"
  3803. + , "Kops"
  3804. + , "Flags"
  3805. + , "QB"
  3806. + , "KB"
  3807. + );
  3808. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  3809. + const struct cryptocap *cap = &crypto_drivers[hid];
  3810. + if (cap->cc_dev == NULL)
  3811. + continue;
  3812. + db_printf("%-12s %4u %4u %08x %2u %2u\n"
  3813. + , device_get_nameunit(cap->cc_dev)
  3814. + , cap->cc_sessions
  3815. + , cap->cc_koperations
  3816. + , cap->cc_flags
  3817. + , cap->cc_qblocked
  3818. + , cap->cc_kqblocked
  3819. + );
  3820. + }
  3821. +}
  3822. +
  3823. +DB_SHOW_COMMAND(crypto, db_show_crypto)
  3824. +{
  3825. + struct cryptop *crp;
  3826. +
  3827. + db_show_drivers();
  3828. + db_printf("\n");
  3829. +
  3830. + db_printf("%4s %8s %4s %4s %4s %4s %8s %8s\n",
  3831. + "HID", "Caps", "Ilen", "Olen", "Etype", "Flags",
  3832. + "Desc", "Callback");
  3833. + TAILQ_FOREACH(crp, &crp_q, crp_next) {
  3834. + db_printf("%4u %08x %4u %4u %4u %04x %8p %8p\n"
  3835. + , (int) CRYPTO_SESID2HID(crp->crp_sid)
  3836. + , (int) CRYPTO_SESID2CAPS(crp->crp_sid)
  3837. + , crp->crp_ilen, crp->crp_olen
  3838. + , crp->crp_etype
  3839. + , crp->crp_flags
  3840. + , crp->crp_desc
  3841. + , crp->crp_callback
  3842. + );
  3843. + }
  3844. + if (!TAILQ_EMPTY(&crp_ret_q)) {
  3845. + db_printf("\n%4s %4s %4s %8s\n",
  3846. + "HID", "Etype", "Flags", "Callback");
  3847. + TAILQ_FOREACH(crp, &crp_ret_q, crp_next) {
  3848. + db_printf("%4u %4u %04x %8p\n"
  3849. + , (int) CRYPTO_SESID2HID(crp->crp_sid)
  3850. + , crp->crp_etype
  3851. + , crp->crp_flags
  3852. + , crp->crp_callback
  3853. + );
  3854. + }
  3855. + }
  3856. +}
  3857. +
  3858. +DB_SHOW_COMMAND(kcrypto, db_show_kcrypto)
  3859. +{
  3860. + struct cryptkop *krp;
  3861. +
  3862. + db_show_drivers();
  3863. + db_printf("\n");
  3864. +
  3865. + db_printf("%4s %5s %4s %4s %8s %4s %8s\n",
  3866. + "Op", "Status", "#IP", "#OP", "CRID", "HID", "Callback");
  3867. + TAILQ_FOREACH(krp, &crp_kq, krp_next) {
  3868. + db_printf("%4u %5u %4u %4u %08x %4u %8p\n"
  3869. + , krp->krp_op
  3870. + , krp->krp_status
  3871. + , krp->krp_iparams, krp->krp_oparams
  3872. + , krp->krp_crid, krp->krp_hid
  3873. + , krp->krp_callback
  3874. + );
  3875. + }
  3876. + if (!TAILQ_EMPTY(&crp_ret_q)) {
  3877. + db_printf("%4s %5s %8s %4s %8s\n",
  3878. + "Op", "Status", "CRID", "HID", "Callback");
  3879. + TAILQ_FOREACH(krp, &crp_ret_kq, krp_next) {
  3880. + db_printf("%4u %5u %08x %4u %8p\n"
  3881. + , krp->krp_op
  3882. + , krp->krp_status
  3883. + , krp->krp_crid, krp->krp_hid
  3884. + , krp->krp_callback
  3885. + );
  3886. + }
  3887. + }
  3888. +}
  3889. +#endif
  3890. +
  3891. +
  3892. +static int
  3893. +crypto_init(void)
  3894. +{
  3895. + int error;
  3896. +
  3897. + dprintk("%s(%p)\n", __FUNCTION__, (void *) crypto_init);
  3898. +
  3899. + if (crypto_initted)
  3900. + return 0;
  3901. + crypto_initted = 1;
  3902. +
  3903. + spin_lock_init(&crypto_drivers_lock);
  3904. + spin_lock_init(&crypto_q_lock);
  3905. + spin_lock_init(&crypto_ret_q_lock);
  3906. +
  3907. + cryptop_zone = kmem_cache_create("cryptop", sizeof(struct cryptop),
  3908. + 0, SLAB_HWCACHE_ALIGN, NULL
  3909. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  3910. + , NULL
  3911. +#endif
  3912. + );
  3913. +
  3914. + cryptodesc_zone = kmem_cache_create("cryptodesc", sizeof(struct cryptodesc),
  3915. + 0, SLAB_HWCACHE_ALIGN, NULL
  3916. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  3917. + , NULL
  3918. +#endif
  3919. + );
  3920. +
  3921. + if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
  3922. + printk("crypto: crypto_init cannot setup crypto zones\n");
  3923. + error = ENOMEM;
  3924. + goto bad;
  3925. + }
  3926. +
  3927. + crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
  3928. + crypto_drivers = kmalloc(crypto_drivers_num * sizeof(struct cryptocap),
  3929. + GFP_KERNEL);
  3930. + if (crypto_drivers == NULL) {
  3931. + printk("crypto: crypto_init cannot setup crypto drivers\n");
  3932. + error = ENOMEM;
  3933. + goto bad;
  3934. + }
  3935. +
  3936. + memset(crypto_drivers, 0, crypto_drivers_num * sizeof(struct cryptocap));
  3937. +
  3938. + init_completion(&cryptoproc_exited);
  3939. + init_completion(&cryptoretproc_exited);
  3940. +
  3941. + cryptoproc = 0; /* to avoid race condition where proc runs first */
  3942. + cryptoproc = kernel_thread(crypto_proc, NULL, CLONE_FS|CLONE_FILES);
  3943. + if (cryptoproc < 0) {
  3944. + error = cryptoproc;
  3945. + printk("crypto: crypto_init cannot start crypto thread; error %d",
  3946. + error);
  3947. + goto bad;
  3948. + }
  3949. +
  3950. + cryptoretproc = 0; /* to avoid race condition where proc runs first */
  3951. + cryptoretproc = kernel_thread(crypto_ret_proc, NULL, CLONE_FS|CLONE_FILES);
  3952. + if (cryptoretproc < 0) {
  3953. + error = cryptoretproc;
  3954. + printk("crypto: crypto_init cannot start cryptoret thread; error %d",
  3955. + error);
  3956. + goto bad;
  3957. + }
  3958. +
  3959. + return 0;
  3960. +bad:
  3961. + crypto_exit();
  3962. + return error;
  3963. +}
  3964. +
  3965. +
  3966. +static void
  3967. +crypto_exit(void)
  3968. +{
  3969. + pid_t p;
  3970. + unsigned long d_flags;
  3971. +
  3972. + dprintk("%s()\n", __FUNCTION__);
  3973. +
  3974. + /*
  3975. + * Terminate any crypto threads.
  3976. + */
  3977. +
  3978. + CRYPTO_DRIVER_LOCK();
  3979. + p = cryptoproc;
  3980. + cryptoproc = (pid_t) -1;
  3981. + kill_proc(p, SIGTERM, 1);
  3982. + wake_up_interruptible(&cryptoproc_wait);
  3983. + CRYPTO_DRIVER_UNLOCK();
  3984. +
  3985. + wait_for_completion(&cryptoproc_exited);
  3986. +
  3987. + CRYPTO_DRIVER_LOCK();
  3988. + p = cryptoretproc;
  3989. + cryptoretproc = (pid_t) -1;
  3990. + kill_proc(p, SIGTERM, 1);
  3991. + wake_up_interruptible(&cryptoretproc_wait);
  3992. + CRYPTO_DRIVER_UNLOCK();
  3993. +
  3994. + wait_for_completion(&cryptoretproc_exited);
  3995. +
  3996. + /* XXX flush queues??? */
  3997. +
  3998. + /*
  3999. + * Reclaim dynamically allocated resources.
  4000. + */
  4001. + if (crypto_drivers != NULL)
  4002. + kfree(crypto_drivers);
  4003. +
  4004. + if (cryptodesc_zone != NULL)
  4005. + kmem_cache_destroy(cryptodesc_zone);
  4006. + if (cryptop_zone != NULL)
  4007. + kmem_cache_destroy(cryptop_zone);
  4008. +}
  4009. +
  4010. +
  4011. +EXPORT_SYMBOL(crypto_newsession);
  4012. +EXPORT_SYMBOL(crypto_freesession);
  4013. +EXPORT_SYMBOL(crypto_get_driverid);
  4014. +EXPORT_SYMBOL(crypto_kregister);
  4015. +EXPORT_SYMBOL(crypto_register);
  4016. +EXPORT_SYMBOL(crypto_unregister);
  4017. +EXPORT_SYMBOL(crypto_unregister_all);
  4018. +EXPORT_SYMBOL(crypto_unblock);
  4019. +EXPORT_SYMBOL(crypto_dispatch);
  4020. +EXPORT_SYMBOL(crypto_kdispatch);
  4021. +EXPORT_SYMBOL(crypto_freereq);
  4022. +EXPORT_SYMBOL(crypto_getreq);
  4023. +EXPORT_SYMBOL(crypto_done);
  4024. +EXPORT_SYMBOL(crypto_kdone);
  4025. +EXPORT_SYMBOL(crypto_getfeat);
  4026. +EXPORT_SYMBOL(crypto_userasymcrypto);
  4027. +EXPORT_SYMBOL(crypto_getcaps);
  4028. +EXPORT_SYMBOL(crypto_find_driver);
  4029. +EXPORT_SYMBOL(crypto_find_device_byhid);
  4030. +
  4031. +module_init(crypto_init);
  4032. +module_exit(crypto_exit);
  4033. +
  4034. +MODULE_LICENSE("BSD");
  4035. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  4036. +MODULE_DESCRIPTION("OCF (OpenBSD Cryptographic Framework)");
  4037. diff -Nur linux-2.6.39.orig/crypto/ocf/cryptocteon/cavium_crypto.c linux-2.6.39/crypto/ocf/cryptocteon/cavium_crypto.c
  4038. --- linux-2.6.39.orig/crypto/ocf/cryptocteon/cavium_crypto.c 1970-01-01 01:00:00.000000000 +0100
  4039. +++ linux-2.6.39/crypto/ocf/cryptocteon/cavium_crypto.c 2011-07-31 11:31:53.423416093 +0200
  4040. @@ -0,0 +1,2283 @@
  4041. +/*
  4042. + * Copyright (c) 2009 David McCullough <david.mccullough@securecomputing.com>
  4043. + *
  4044. + * Copyright (c) 2003-2007 Cavium Networks (support@cavium.com). All rights
  4045. + * reserved.
  4046. + *
  4047. + * Redistribution and use in source and binary forms, with or without
  4048. + * modification, are permitted provided that the following conditions are met:
  4049. + * 1. Redistributions of source code must retain the above copyright notice,
  4050. + * this list of conditions and the following disclaimer.
  4051. + * 2. Redistributions in binary form must reproduce the above copyright notice,
  4052. + * this list of conditions and the following disclaimer in the documentation
  4053. + * and/or other materials provided with the distribution.
  4054. + * 3. All advertising materials mentioning features or use of this software
  4055. + * must display the following acknowledgement:
  4056. + * This product includes software developed by Cavium Networks
  4057. + * 4. Cavium Networks' name may not be used to endorse or promote products
  4058. + * derived from this software without specific prior written permission.
  4059. + *
  4060. + * This Software, including technical data, may be subject to U.S. export
  4061. + * control laws, including the U.S. Export Administration Act and its
  4062. + * associated regulations, and may be subject to export or import regulations
  4063. + * in other countries. You warrant that You will comply strictly in all
  4064. + * respects with all such regulations and acknowledge that you have the
  4065. + * responsibility to obtain licenses to export, re-export or import the
  4066. + * Software.
  4067. + *
  4068. + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" AND
  4069. + * WITH ALL FAULTS AND CAVIUM MAKES NO PROMISES, REPRESENTATIONS OR WARRANTIES,
  4070. + * EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE
  4071. + * SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
  4072. + * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
  4073. + * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
  4074. + * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
  4075. + * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
  4076. + * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
  4077. + * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
  4078. +*/
  4079. +/****************************************************************************/
  4080. +
  4081. +#include <linux/scatterlist.h>
  4082. +#include <asm/octeon/octeon.h>
  4083. +#include "octeon-asm.h"
  4084. +
  4085. +/****************************************************************************/
  4086. +
  4087. +extern unsigned long octeon_crypto_enable(struct octeon_cop2_state *);
  4088. +extern void octeon_crypto_disable(struct octeon_cop2_state *, unsigned long);
  4089. +
  4090. +#define SG_INIT(s, p, i, l) \
  4091. + { \
  4092. + (i) = 0; \
  4093. + (l) = (s)[0].length; \
  4094. + (p) = (typeof(p)) sg_virt((s)); \
  4095. + CVMX_PREFETCH0((p)); \
  4096. + }
  4097. +
  4098. +#define SG_CONSUME(s, p, i, l) \
  4099. + { \
  4100. + (p)++; \
  4101. + (l) -= sizeof(*(p)); \
  4102. + if ((l) < 0) { \
  4103. + dprintk("%s, %d: l = %d\n", __FILE__, __LINE__, l); \
  4104. + } else if ((l) == 0) { \
  4105. + (i)++; \
  4106. + (l) = (s)[0].length; \
  4107. + (p) = (typeof(p)) sg_virt(s); \
  4108. + CVMX_PREFETCH0((p)); \
  4109. + } \
  4110. + }
  4111. +
  4112. +#define ESP_HEADER_LENGTH 8
  4113. +#define DES_CBC_IV_LENGTH 8
  4114. +#define AES_CBC_IV_LENGTH 16
  4115. +#define ESP_HMAC_LEN 12
  4116. +
  4117. +#define ESP_HEADER_LENGTH 8
  4118. +#define DES_CBC_IV_LENGTH 8
  4119. +
  4120. +/****************************************************************************/
  4121. +
  4122. +#define CVM_LOAD_SHA_UNIT(dat, next) { \
  4123. + if (next == 0) { \
  4124. + next = 1; \
  4125. + CVMX_MT_HSH_DAT (dat, 0); \
  4126. + } else if (next == 1) { \
  4127. + next = 2; \
  4128. + CVMX_MT_HSH_DAT (dat, 1); \
  4129. + } else if (next == 2) { \
  4130. + next = 3; \
  4131. + CVMX_MT_HSH_DAT (dat, 2); \
  4132. + } else if (next == 3) { \
  4133. + next = 4; \
  4134. + CVMX_MT_HSH_DAT (dat, 3); \
  4135. + } else if (next == 4) { \
  4136. + next = 5; \
  4137. + CVMX_MT_HSH_DAT (dat, 4); \
  4138. + } else if (next == 5) { \
  4139. + next = 6; \
  4140. + CVMX_MT_HSH_DAT (dat, 5); \
  4141. + } else if (next == 6) { \
  4142. + next = 7; \
  4143. + CVMX_MT_HSH_DAT (dat, 6); \
  4144. + } else { \
  4145. + CVMX_MT_HSH_STARTSHA (dat); \
  4146. + next = 0; \
  4147. + } \
  4148. +}
  4149. +
  4150. +#define CVM_LOAD2_SHA_UNIT(dat1, dat2, next) { \
  4151. + if (next == 0) { \
  4152. + CVMX_MT_HSH_DAT (dat1, 0); \
  4153. + CVMX_MT_HSH_DAT (dat2, 1); \
  4154. + next = 2; \
  4155. + } else if (next == 1) { \
  4156. + CVMX_MT_HSH_DAT (dat1, 1); \
  4157. + CVMX_MT_HSH_DAT (dat2, 2); \
  4158. + next = 3; \
  4159. + } else if (next == 2) { \
  4160. + CVMX_MT_HSH_DAT (dat1, 2); \
  4161. + CVMX_MT_HSH_DAT (dat2, 3); \
  4162. + next = 4; \
  4163. + } else if (next == 3) { \
  4164. + CVMX_MT_HSH_DAT (dat1, 3); \
  4165. + CVMX_MT_HSH_DAT (dat2, 4); \
  4166. + next = 5; \
  4167. + } else if (next == 4) { \
  4168. + CVMX_MT_HSH_DAT (dat1, 4); \
  4169. + CVMX_MT_HSH_DAT (dat2, 5); \
  4170. + next = 6; \
  4171. + } else if (next == 5) { \
  4172. + CVMX_MT_HSH_DAT (dat1, 5); \
  4173. + CVMX_MT_HSH_DAT (dat2, 6); \
  4174. + next = 7; \
  4175. + } else if (next == 6) { \
  4176. + CVMX_MT_HSH_DAT (dat1, 6); \
  4177. + CVMX_MT_HSH_STARTSHA (dat2); \
  4178. + next = 0; \
  4179. + } else { \
  4180. + CVMX_MT_HSH_STARTSHA (dat1); \
  4181. + CVMX_MT_HSH_DAT (dat2, 0); \
  4182. + next = 1; \
  4183. + } \
  4184. +}
  4185. +
  4186. +/****************************************************************************/
  4187. +
  4188. +#define CVM_LOAD_MD5_UNIT(dat, next) { \
  4189. + if (next == 0) { \
  4190. + next = 1; \
  4191. + CVMX_MT_HSH_DAT (dat, 0); \
  4192. + } else if (next == 1) { \
  4193. + next = 2; \
  4194. + CVMX_MT_HSH_DAT (dat, 1); \
  4195. + } else if (next == 2) { \
  4196. + next = 3; \
  4197. + CVMX_MT_HSH_DAT (dat, 2); \
  4198. + } else if (next == 3) { \
  4199. + next = 4; \
  4200. + CVMX_MT_HSH_DAT (dat, 3); \
  4201. + } else if (next == 4) { \
  4202. + next = 5; \
  4203. + CVMX_MT_HSH_DAT (dat, 4); \
  4204. + } else if (next == 5) { \
  4205. + next = 6; \
  4206. + CVMX_MT_HSH_DAT (dat, 5); \
  4207. + } else if (next == 6) { \
  4208. + next = 7; \
  4209. + CVMX_MT_HSH_DAT (dat, 6); \
  4210. + } else { \
  4211. + CVMX_MT_HSH_STARTMD5 (dat); \
  4212. + next = 0; \
  4213. + } \
  4214. +}
  4215. +
  4216. +#define CVM_LOAD2_MD5_UNIT(dat1, dat2, next) { \
  4217. + if (next == 0) { \
  4218. + CVMX_MT_HSH_DAT (dat1, 0); \
  4219. + CVMX_MT_HSH_DAT (dat2, 1); \
  4220. + next = 2; \
  4221. + } else if (next == 1) { \
  4222. + CVMX_MT_HSH_DAT (dat1, 1); \
  4223. + CVMX_MT_HSH_DAT (dat2, 2); \
  4224. + next = 3; \
  4225. + } else if (next == 2) { \
  4226. + CVMX_MT_HSH_DAT (dat1, 2); \
  4227. + CVMX_MT_HSH_DAT (dat2, 3); \
  4228. + next = 4; \
  4229. + } else if (next == 3) { \
  4230. + CVMX_MT_HSH_DAT (dat1, 3); \
  4231. + CVMX_MT_HSH_DAT (dat2, 4); \
  4232. + next = 5; \
  4233. + } else if (next == 4) { \
  4234. + CVMX_MT_HSH_DAT (dat1, 4); \
  4235. + CVMX_MT_HSH_DAT (dat2, 5); \
  4236. + next = 6; \
  4237. + } else if (next == 5) { \
  4238. + CVMX_MT_HSH_DAT (dat1, 5); \
  4239. + CVMX_MT_HSH_DAT (dat2, 6); \
  4240. + next = 7; \
  4241. + } else if (next == 6) { \
  4242. + CVMX_MT_HSH_DAT (dat1, 6); \
  4243. + CVMX_MT_HSH_STARTMD5 (dat2); \
  4244. + next = 0; \
  4245. + } else { \
  4246. + CVMX_MT_HSH_STARTMD5 (dat1); \
  4247. + CVMX_MT_HSH_DAT (dat2, 0); \
  4248. + next = 1; \
  4249. + } \
  4250. +}
  4251. +
  4252. +/****************************************************************************/
  4253. +
  4254. +static inline uint64_t
  4255. +swap64(uint64_t a)
  4256. +{
  4257. + return ((a >> 56) |
  4258. + (((a >> 48) & 0xfful) << 8) |
  4259. + (((a >> 40) & 0xfful) << 16) |
  4260. + (((a >> 32) & 0xfful) << 24) |
  4261. + (((a >> 24) & 0xfful) << 32) |
  4262. + (((a >> 16) & 0xfful) << 40) |
  4263. + (((a >> 8) & 0xfful) << 48) | (((a >> 0) & 0xfful) << 56));
  4264. +}
  4265. +
  4266. +/****************************************************************************/
  4267. +
  4268. +void
  4269. +octo_calc_hash(__u8 auth, unsigned char *key, uint64_t *inner, uint64_t *outer)
  4270. +{
  4271. + uint8_t hash_key[64];
  4272. + uint64_t *key1;
  4273. + register uint64_t xor1 = 0x3636363636363636ULL;
  4274. + register uint64_t xor2 = 0x5c5c5c5c5c5c5c5cULL;
  4275. + struct octeon_cop2_state state;
  4276. + unsigned long flags;
  4277. +
  4278. + dprintk("%s()\n", __FUNCTION__);
  4279. +
  4280. + memset(hash_key, 0, sizeof(hash_key));
  4281. + memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));
  4282. + key1 = (uint64_t *) hash_key;
  4283. + flags = octeon_crypto_enable(&state);
  4284. + if (auth) {
  4285. + CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);
  4286. + CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);
  4287. + CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);
  4288. + } else {
  4289. + CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);
  4290. + CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);
  4291. + }
  4292. +
  4293. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 0);
  4294. + key1++;
  4295. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 1);
  4296. + key1++;
  4297. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 2);
  4298. + key1++;
  4299. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 3);
  4300. + key1++;
  4301. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 4);
  4302. + key1++;
  4303. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 5);
  4304. + key1++;
  4305. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 6);
  4306. + key1++;
  4307. + if (auth)
  4308. + CVMX_MT_HSH_STARTSHA((*key1 ^ xor1));
  4309. + else
  4310. + CVMX_MT_HSH_STARTMD5((*key1 ^ xor1));
  4311. +
  4312. + CVMX_MF_HSH_IV(inner[0], 0);
  4313. + CVMX_MF_HSH_IV(inner[1], 1);
  4314. + if (auth) {
  4315. + inner[2] = 0;
  4316. + CVMX_MF_HSH_IV(((uint64_t *) inner)[2], 2);
  4317. + }
  4318. +
  4319. + memset(hash_key, 0, sizeof(hash_key));
  4320. + memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));
  4321. + key1 = (uint64_t *) hash_key;
  4322. + if (auth) {
  4323. + CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);
  4324. + CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);
  4325. + CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);
  4326. + } else {
  4327. + CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);
  4328. + CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);
  4329. + }
  4330. +
  4331. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 0);
  4332. + key1++;
  4333. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 1);
  4334. + key1++;
  4335. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 2);
  4336. + key1++;
  4337. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 3);
  4338. + key1++;
  4339. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 4);
  4340. + key1++;
  4341. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 5);
  4342. + key1++;
  4343. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 6);
  4344. + key1++;
  4345. + if (auth)
  4346. + CVMX_MT_HSH_STARTSHA((*key1 ^ xor2));
  4347. + else
  4348. + CVMX_MT_HSH_STARTMD5((*key1 ^ xor2));
  4349. +
  4350. + CVMX_MF_HSH_IV(outer[0], 0);
  4351. + CVMX_MF_HSH_IV(outer[1], 1);
  4352. + if (auth) {
  4353. + outer[2] = 0;
  4354. + CVMX_MF_HSH_IV(outer[2], 2);
  4355. + }
  4356. + octeon_crypto_disable(&state, flags);
  4357. + return;
  4358. +}
  4359. +
  4360. +/****************************************************************************/
  4361. +/* DES functions */
  4362. +
  4363. +int
  4364. +octo_des_cbc_encrypt(
  4365. + struct octo_sess *od,
  4366. + struct scatterlist *sg, int sg_len,
  4367. + int auth_off, int auth_len,
  4368. + int crypt_off, int crypt_len,
  4369. + int icv_off, uint8_t *ivp)
  4370. +{
  4371. + uint64_t *data;
  4372. + int data_i, data_l;
  4373. + struct octeon_cop2_state state;
  4374. + unsigned long flags;
  4375. +
  4376. + dprintk("%s()\n", __FUNCTION__);
  4377. +
  4378. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4379. + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
  4380. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4381. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4382. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4383. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4384. + return -EINVAL;
  4385. + }
  4386. +
  4387. + SG_INIT(sg, data, data_i, data_l);
  4388. +
  4389. + CVMX_PREFETCH0(ivp);
  4390. + CVMX_PREFETCH0(od->octo_enckey);
  4391. +
  4392. + flags = octeon_crypto_enable(&state);
  4393. +
  4394. + /* load 3DES Key */
  4395. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4396. + if (od->octo_encklen == 24) {
  4397. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4398. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4399. + } else if (od->octo_encklen == 8) {
  4400. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  4401. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  4402. + } else {
  4403. + octeon_crypto_disable(&state, flags);
  4404. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4405. + return -EINVAL;
  4406. + }
  4407. +
  4408. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  4409. +
  4410. + while (crypt_off > 0) {
  4411. + SG_CONSUME(sg, data, data_i, data_l);
  4412. + crypt_off -= 8;
  4413. + }
  4414. +
  4415. + while (crypt_len > 0) {
  4416. + CVMX_MT_3DES_ENC_CBC(*data);
  4417. + CVMX_MF_3DES_RESULT(*data);
  4418. + SG_CONSUME(sg, data, data_i, data_l);
  4419. + crypt_len -= 8;
  4420. + }
  4421. +
  4422. + octeon_crypto_disable(&state, flags);
  4423. + return 0;
  4424. +}
  4425. +
  4426. +
  4427. +int
  4428. +octo_des_cbc_decrypt(
  4429. + struct octo_sess *od,
  4430. + struct scatterlist *sg, int sg_len,
  4431. + int auth_off, int auth_len,
  4432. + int crypt_off, int crypt_len,
  4433. + int icv_off, uint8_t *ivp)
  4434. +{
  4435. + uint64_t *data;
  4436. + int data_i, data_l;
  4437. + struct octeon_cop2_state state;
  4438. + unsigned long flags;
  4439. +
  4440. + dprintk("%s()\n", __FUNCTION__);
  4441. +
  4442. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4443. + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
  4444. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4445. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4446. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4447. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4448. + return -EINVAL;
  4449. + }
  4450. +
  4451. + SG_INIT(sg, data, data_i, data_l);
  4452. +
  4453. + CVMX_PREFETCH0(ivp);
  4454. + CVMX_PREFETCH0(od->octo_enckey);
  4455. +
  4456. + flags = octeon_crypto_enable(&state);
  4457. +
  4458. + /* load 3DES Key */
  4459. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4460. + if (od->octo_encklen == 24) {
  4461. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4462. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4463. + } else if (od->octo_encklen == 8) {
  4464. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  4465. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  4466. + } else {
  4467. + octeon_crypto_disable(&state, flags);
  4468. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4469. + return -EINVAL;
  4470. + }
  4471. +
  4472. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  4473. +
  4474. + while (crypt_off > 0) {
  4475. + SG_CONSUME(sg, data, data_i, data_l);
  4476. + crypt_off -= 8;
  4477. + }
  4478. +
  4479. + while (crypt_len > 0) {
  4480. + CVMX_MT_3DES_DEC_CBC(*data);
  4481. + CVMX_MF_3DES_RESULT(*data);
  4482. + SG_CONSUME(sg, data, data_i, data_l);
  4483. + crypt_len -= 8;
  4484. + }
  4485. +
  4486. + octeon_crypto_disable(&state, flags);
  4487. + return 0;
  4488. +}
  4489. +
  4490. +/****************************************************************************/
  4491. +/* AES functions */
  4492. +
  4493. +int
  4494. +octo_aes_cbc_encrypt(
  4495. + struct octo_sess *od,
  4496. + struct scatterlist *sg, int sg_len,
  4497. + int auth_off, int auth_len,
  4498. + int crypt_off, int crypt_len,
  4499. + int icv_off, uint8_t *ivp)
  4500. +{
  4501. + uint64_t *data, *pdata;
  4502. + int data_i, data_l;
  4503. + struct octeon_cop2_state state;
  4504. + unsigned long flags;
  4505. +
  4506. + dprintk("%s()\n", __FUNCTION__);
  4507. +
  4508. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4509. + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
  4510. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4511. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4512. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4513. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4514. + return -EINVAL;
  4515. + }
  4516. +
  4517. + SG_INIT(sg, data, data_i, data_l);
  4518. +
  4519. + CVMX_PREFETCH0(ivp);
  4520. + CVMX_PREFETCH0(od->octo_enckey);
  4521. +
  4522. + flags = octeon_crypto_enable(&state);
  4523. +
  4524. + /* load AES Key */
  4525. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4526. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4527. +
  4528. + if (od->octo_encklen == 16) {
  4529. + CVMX_MT_AES_KEY(0x0, 2);
  4530. + CVMX_MT_AES_KEY(0x0, 3);
  4531. + } else if (od->octo_encklen == 24) {
  4532. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4533. + CVMX_MT_AES_KEY(0x0, 3);
  4534. + } else if (od->octo_encklen == 32) {
  4535. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4536. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  4537. + } else {
  4538. + octeon_crypto_disable(&state, flags);
  4539. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4540. + return -EINVAL;
  4541. + }
  4542. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  4543. +
  4544. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  4545. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  4546. +
  4547. + while (crypt_off > 0) {
  4548. + SG_CONSUME(sg, data, data_i, data_l);
  4549. + crypt_off -= 8;
  4550. + }
  4551. +
  4552. + while (crypt_len > 0) {
  4553. + pdata = data;
  4554. + CVMX_MT_AES_ENC_CBC0(*data);
  4555. + SG_CONSUME(sg, data, data_i, data_l);
  4556. + CVMX_MT_AES_ENC_CBC1(*data);
  4557. + CVMX_MF_AES_RESULT(*pdata, 0);
  4558. + CVMX_MF_AES_RESULT(*data, 1);
  4559. + SG_CONSUME(sg, data, data_i, data_l);
  4560. + crypt_len -= 16;
  4561. + }
  4562. +
  4563. + octeon_crypto_disable(&state, flags);
  4564. + return 0;
  4565. +}
  4566. +
  4567. +
  4568. +int
  4569. +octo_aes_cbc_decrypt(
  4570. + struct octo_sess *od,
  4571. + struct scatterlist *sg, int sg_len,
  4572. + int auth_off, int auth_len,
  4573. + int crypt_off, int crypt_len,
  4574. + int icv_off, uint8_t *ivp)
  4575. +{
  4576. + uint64_t *data, *pdata;
  4577. + int data_i, data_l;
  4578. + struct octeon_cop2_state state;
  4579. + unsigned long flags;
  4580. +
  4581. + dprintk("%s()\n", __FUNCTION__);
  4582. +
  4583. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4584. + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
  4585. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4586. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4587. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4588. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4589. + return -EINVAL;
  4590. + }
  4591. +
  4592. + SG_INIT(sg, data, data_i, data_l);
  4593. +
  4594. + CVMX_PREFETCH0(ivp);
  4595. + CVMX_PREFETCH0(od->octo_enckey);
  4596. +
  4597. + flags = octeon_crypto_enable(&state);
  4598. +
  4599. + /* load AES Key */
  4600. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4601. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4602. +
  4603. + if (od->octo_encklen == 16) {
  4604. + CVMX_MT_AES_KEY(0x0, 2);
  4605. + CVMX_MT_AES_KEY(0x0, 3);
  4606. + } else if (od->octo_encklen == 24) {
  4607. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4608. + CVMX_MT_AES_KEY(0x0, 3);
  4609. + } else if (od->octo_encklen == 32) {
  4610. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4611. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  4612. + } else {
  4613. + octeon_crypto_disable(&state, flags);
  4614. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4615. + return -EINVAL;
  4616. + }
  4617. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  4618. +
  4619. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  4620. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  4621. +
  4622. + while (crypt_off > 0) {
  4623. + SG_CONSUME(sg, data, data_i, data_l);
  4624. + crypt_off -= 8;
  4625. + }
  4626. +
  4627. + while (crypt_len > 0) {
  4628. + pdata = data;
  4629. + CVMX_MT_AES_DEC_CBC0(*data);
  4630. + SG_CONSUME(sg, data, data_i, data_l);
  4631. + CVMX_MT_AES_DEC_CBC1(*data);
  4632. + CVMX_MF_AES_RESULT(*pdata, 0);
  4633. + CVMX_MF_AES_RESULT(*data, 1);
  4634. + SG_CONSUME(sg, data, data_i, data_l);
  4635. + crypt_len -= 16;
  4636. + }
  4637. +
  4638. + octeon_crypto_disable(&state, flags);
  4639. + return 0;
  4640. +}
  4641. +
  4642. +/****************************************************************************/
  4643. +/* MD5 */
  4644. +
  4645. +int
  4646. +octo_null_md5_encrypt(
  4647. + struct octo_sess *od,
  4648. + struct scatterlist *sg, int sg_len,
  4649. + int auth_off, int auth_len,
  4650. + int crypt_off, int crypt_len,
  4651. + int icv_off, uint8_t *ivp)
  4652. +{
  4653. + register int next = 0;
  4654. + uint64_t *data;
  4655. + uint64_t tmp1, tmp2;
  4656. + int data_i, data_l, alen = auth_len;
  4657. + struct octeon_cop2_state state;
  4658. + unsigned long flags;
  4659. +
  4660. + dprintk("%s()\n", __FUNCTION__);
  4661. +
  4662. + if (unlikely(od == NULL || sg==NULL || sg_len==0 ||
  4663. + (auth_off & 0x7) || (auth_off + auth_len > sg_len))) {
  4664. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4665. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4666. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4667. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4668. + return -EINVAL;
  4669. + }
  4670. +
  4671. + SG_INIT(sg, data, data_i, data_l);
  4672. +
  4673. + flags = octeon_crypto_enable(&state);
  4674. +
  4675. + /* Load MD5 IV */
  4676. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  4677. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  4678. +
  4679. + while (auth_off > 0) {
  4680. + SG_CONSUME(sg, data, data_i, data_l);
  4681. + auth_off -= 8;
  4682. + }
  4683. +
  4684. + while (auth_len > 0) {
  4685. + CVM_LOAD_MD5_UNIT(*data, next);
  4686. + auth_len -= 8;
  4687. + SG_CONSUME(sg, data, data_i, data_l);
  4688. + }
  4689. +
  4690. + /* finish the hash */
  4691. + CVMX_PREFETCH0(od->octo_hmouter);
  4692. +#if 0
  4693. + if (unlikely(inplen)) {
  4694. + uint64_t tmp = 0;
  4695. + uint8_t *p = (uint8_t *) & tmp;
  4696. + p[inplen] = 0x80;
  4697. + do {
  4698. + inplen--;
  4699. + p[inplen] = ((uint8_t *) data)[inplen];
  4700. + } while (inplen);
  4701. + CVM_LOAD_MD5_UNIT(tmp, next);
  4702. + } else {
  4703. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  4704. + }
  4705. +#else
  4706. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  4707. +#endif
  4708. +
  4709. + /* Finish Inner hash */
  4710. + while (next != 7) {
  4711. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  4712. + }
  4713. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  4714. + CVM_LOAD_MD5_UNIT(tmp1, next);
  4715. +
  4716. + /* Get the inner hash of HMAC */
  4717. + CVMX_MF_HSH_IV(tmp1, 0);
  4718. + CVMX_MF_HSH_IV(tmp2, 1);
  4719. +
  4720. + /* Initialize hash unit */
  4721. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  4722. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  4723. +
  4724. + CVMX_MT_HSH_DAT(tmp1, 0);
  4725. + CVMX_MT_HSH_DAT(tmp2, 1);
  4726. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  4727. + CVMX_MT_HSH_DATZ(3);
  4728. + CVMX_MT_HSH_DATZ(4);
  4729. + CVMX_MT_HSH_DATZ(5);
  4730. + CVMX_MT_HSH_DATZ(6);
  4731. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  4732. + CVMX_MT_HSH_STARTMD5(tmp1);
  4733. +
  4734. + /* save the HMAC */
  4735. + SG_INIT(sg, data, data_i, data_l);
  4736. + while (icv_off > 0) {
  4737. + SG_CONSUME(sg, data, data_i, data_l);
  4738. + icv_off -= 8;
  4739. + }
  4740. + CVMX_MF_HSH_IV(*data, 0);
  4741. + SG_CONSUME(sg, data, data_i, data_l);
  4742. + CVMX_MF_HSH_IV(tmp1, 1);
  4743. + *(uint32_t *)data = (uint32_t) (tmp1 >> 32);
  4744. +
  4745. + octeon_crypto_disable(&state, flags);
  4746. + return 0;
  4747. +}
  4748. +
  4749. +/****************************************************************************/
  4750. +/* SHA1 */
  4751. +
  4752. +int
  4753. +octo_null_sha1_encrypt(
  4754. + struct octo_sess *od,
  4755. + struct scatterlist *sg, int sg_len,
  4756. + int auth_off, int auth_len,
  4757. + int crypt_off, int crypt_len,
  4758. + int icv_off, uint8_t *ivp)
  4759. +{
  4760. + register int next = 0;
  4761. + uint64_t *data;
  4762. + uint64_t tmp1, tmp2, tmp3;
  4763. + int data_i, data_l, alen = auth_len;
  4764. + struct octeon_cop2_state state;
  4765. + unsigned long flags;
  4766. +
  4767. + dprintk("%s()\n", __FUNCTION__);
  4768. +
  4769. + if (unlikely(od == NULL || sg==NULL || sg_len==0 ||
  4770. + (auth_off & 0x7) || (auth_off + auth_len > sg_len))) {
  4771. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4772. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4773. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4774. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4775. + return -EINVAL;
  4776. + }
  4777. +
  4778. + SG_INIT(sg, data, data_i, data_l);
  4779. +
  4780. + flags = octeon_crypto_enable(&state);
  4781. +
  4782. + /* Load SHA1 IV */
  4783. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  4784. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  4785. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  4786. +
  4787. + while (auth_off > 0) {
  4788. + SG_CONSUME(sg, data, data_i, data_l);
  4789. + auth_off -= 8;
  4790. + }
  4791. +
  4792. + while (auth_len > 0) {
  4793. + CVM_LOAD_SHA_UNIT(*data, next);
  4794. + auth_len -= 8;
  4795. + SG_CONSUME(sg, data, data_i, data_l);
  4796. + }
  4797. +
  4798. + /* finish the hash */
  4799. + CVMX_PREFETCH0(od->octo_hmouter);
  4800. +#if 0
  4801. + if (unlikely(inplen)) {
  4802. + uint64_t tmp = 0;
  4803. + uint8_t *p = (uint8_t *) & tmp;
  4804. + p[inplen] = 0x80;
  4805. + do {
  4806. + inplen--;
  4807. + p[inplen] = ((uint8_t *) data)[inplen];
  4808. + } while (inplen);
  4809. + CVM_LOAD_MD5_UNIT(tmp, next);
  4810. + } else {
  4811. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  4812. + }
  4813. +#else
  4814. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  4815. +#endif
  4816. +
  4817. + /* Finish Inner hash */
  4818. + while (next != 7) {
  4819. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  4820. + }
  4821. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  4822. +
  4823. + /* Get the inner hash of HMAC */
  4824. + CVMX_MF_HSH_IV(tmp1, 0);
  4825. + CVMX_MF_HSH_IV(tmp2, 1);
  4826. + tmp3 = 0;
  4827. + CVMX_MF_HSH_IV(tmp3, 2);
  4828. +
  4829. + /* Initialize hash unit */
  4830. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  4831. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  4832. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  4833. +
  4834. + CVMX_MT_HSH_DAT(tmp1, 0);
  4835. + CVMX_MT_HSH_DAT(tmp2, 1);
  4836. + tmp3 |= 0x0000000080000000;
  4837. + CVMX_MT_HSH_DAT(tmp3, 2);
  4838. + CVMX_MT_HSH_DATZ(3);
  4839. + CVMX_MT_HSH_DATZ(4);
  4840. + CVMX_MT_HSH_DATZ(5);
  4841. + CVMX_MT_HSH_DATZ(6);
  4842. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  4843. +
  4844. + /* save the HMAC */
  4845. + SG_INIT(sg, data, data_i, data_l);
  4846. + while (icv_off > 0) {
  4847. + SG_CONSUME(sg, data, data_i, data_l);
  4848. + icv_off -= 8;
  4849. + }
  4850. + CVMX_MF_HSH_IV(*data, 0);
  4851. + SG_CONSUME(sg, data, data_i, data_l);
  4852. + CVMX_MF_HSH_IV(tmp1, 1);
  4853. + *(uint32_t *)data = (uint32_t) (tmp1 >> 32);
  4854. +
  4855. + octeon_crypto_disable(&state, flags);
  4856. + return 0;
  4857. +}
  4858. +
  4859. +/****************************************************************************/
  4860. +/* DES MD5 */
  4861. +
  4862. +int
  4863. +octo_des_cbc_md5_encrypt(
  4864. + struct octo_sess *od,
  4865. + struct scatterlist *sg, int sg_len,
  4866. + int auth_off, int auth_len,
  4867. + int crypt_off, int crypt_len,
  4868. + int icv_off, uint8_t *ivp)
  4869. +{
  4870. + register int next = 0;
  4871. + union {
  4872. + uint32_t data32[2];
  4873. + uint64_t data64[1];
  4874. + } mydata;
  4875. + uint64_t *data = &mydata.data64[0];
  4876. + uint32_t *data32;
  4877. + uint64_t tmp1, tmp2;
  4878. + int data_i, data_l, alen = auth_len;
  4879. + struct octeon_cop2_state state;
  4880. + unsigned long flags;
  4881. +
  4882. + dprintk("%s()\n", __FUNCTION__);
  4883. +
  4884. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4885. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  4886. + (crypt_len & 0x7) ||
  4887. + (auth_len & 0x7) ||
  4888. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  4889. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4890. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4891. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4892. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4893. + return -EINVAL;
  4894. + }
  4895. +
  4896. + SG_INIT(sg, data32, data_i, data_l);
  4897. +
  4898. + CVMX_PREFETCH0(ivp);
  4899. + CVMX_PREFETCH0(od->octo_enckey);
  4900. +
  4901. + flags = octeon_crypto_enable(&state);
  4902. +
  4903. + /* load 3DES Key */
  4904. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4905. + if (od->octo_encklen == 24) {
  4906. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4907. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4908. + } else if (od->octo_encklen == 8) {
  4909. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  4910. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  4911. + } else {
  4912. + octeon_crypto_disable(&state, flags);
  4913. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4914. + return -EINVAL;
  4915. + }
  4916. +
  4917. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  4918. +
  4919. + /* Load MD5 IV */
  4920. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  4921. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  4922. +
  4923. + while (crypt_off > 0 && auth_off > 0) {
  4924. + SG_CONSUME(sg, data32, data_i, data_l);
  4925. + crypt_off -= 4;
  4926. + auth_off -= 4;
  4927. + }
  4928. +
  4929. + while (crypt_len > 0 || auth_len > 0) {
  4930. + uint32_t *first = data32;
  4931. + mydata.data32[0] = *first;
  4932. + SG_CONSUME(sg, data32, data_i, data_l);
  4933. + mydata.data32[1] = *data32;
  4934. + if (crypt_off <= 0) {
  4935. + if (crypt_len > 0) {
  4936. + CVMX_MT_3DES_ENC_CBC(*data);
  4937. + CVMX_MF_3DES_RESULT(*data);
  4938. + crypt_len -= 8;
  4939. + }
  4940. + } else
  4941. + crypt_off -= 8;
  4942. + if (auth_off <= 0) {
  4943. + if (auth_len > 0) {
  4944. + CVM_LOAD_MD5_UNIT(*data, next);
  4945. + auth_len -= 8;
  4946. + }
  4947. + } else
  4948. + auth_off -= 8;
  4949. + *first = mydata.data32[0];
  4950. + *data32 = mydata.data32[1];
  4951. + SG_CONSUME(sg, data32, data_i, data_l);
  4952. + }
  4953. +
  4954. + /* finish the hash */
  4955. + CVMX_PREFETCH0(od->octo_hmouter);
  4956. +#if 0
  4957. + if (unlikely(inplen)) {
  4958. + uint64_t tmp = 0;
  4959. + uint8_t *p = (uint8_t *) & tmp;
  4960. + p[inplen] = 0x80;
  4961. + do {
  4962. + inplen--;
  4963. + p[inplen] = ((uint8_t *) data)[inplen];
  4964. + } while (inplen);
  4965. + CVM_LOAD_MD5_UNIT(tmp, next);
  4966. + } else {
  4967. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  4968. + }
  4969. +#else
  4970. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  4971. +#endif
  4972. +
  4973. + /* Finish Inner hash */
  4974. + while (next != 7) {
  4975. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  4976. + }
  4977. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  4978. + CVM_LOAD_MD5_UNIT(tmp1, next);
  4979. +
  4980. + /* Get the inner hash of HMAC */
  4981. + CVMX_MF_HSH_IV(tmp1, 0);
  4982. + CVMX_MF_HSH_IV(tmp2, 1);
  4983. +
  4984. + /* Initialize hash unit */
  4985. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  4986. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  4987. +
  4988. + CVMX_MT_HSH_DAT(tmp1, 0);
  4989. + CVMX_MT_HSH_DAT(tmp2, 1);
  4990. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  4991. + CVMX_MT_HSH_DATZ(3);
  4992. + CVMX_MT_HSH_DATZ(4);
  4993. + CVMX_MT_HSH_DATZ(5);
  4994. + CVMX_MT_HSH_DATZ(6);
  4995. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  4996. + CVMX_MT_HSH_STARTMD5(tmp1);
  4997. +
  4998. + /* save the HMAC */
  4999. + SG_INIT(sg, data32, data_i, data_l);
  5000. + while (icv_off > 0) {
  5001. + SG_CONSUME(sg, data32, data_i, data_l);
  5002. + icv_off -= 4;
  5003. + }
  5004. + CVMX_MF_HSH_IV(tmp1, 0);
  5005. + *data32 = (uint32_t) (tmp1 >> 32);
  5006. + SG_CONSUME(sg, data32, data_i, data_l);
  5007. + *data32 = (uint32_t) tmp1;
  5008. + SG_CONSUME(sg, data32, data_i, data_l);
  5009. + CVMX_MF_HSH_IV(tmp1, 1);
  5010. + *data32 = (uint32_t) (tmp1 >> 32);
  5011. +
  5012. + octeon_crypto_disable(&state, flags);
  5013. + return 0;
  5014. +}
  5015. +
  5016. +int
  5017. +octo_des_cbc_md5_decrypt(
  5018. + struct octo_sess *od,
  5019. + struct scatterlist *sg, int sg_len,
  5020. + int auth_off, int auth_len,
  5021. + int crypt_off, int crypt_len,
  5022. + int icv_off, uint8_t *ivp)
  5023. +{
  5024. + register int next = 0;
  5025. + union {
  5026. + uint32_t data32[2];
  5027. + uint64_t data64[1];
  5028. + } mydata;
  5029. + uint64_t *data = &mydata.data64[0];
  5030. + uint32_t *data32;
  5031. + uint64_t tmp1, tmp2;
  5032. + int data_i, data_l, alen = auth_len;
  5033. + struct octeon_cop2_state state;
  5034. + unsigned long flags;
  5035. +
  5036. + dprintk("%s()\n", __FUNCTION__);
  5037. +
  5038. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  5039. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  5040. + (crypt_len & 0x7) ||
  5041. + (auth_len & 0x7) ||
  5042. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  5043. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5044. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5045. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5046. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5047. + return -EINVAL;
  5048. + }
  5049. +
  5050. + SG_INIT(sg, data32, data_i, data_l);
  5051. +
  5052. + CVMX_PREFETCH0(ivp);
  5053. + CVMX_PREFETCH0(od->octo_enckey);
  5054. +
  5055. + flags = octeon_crypto_enable(&state);
  5056. +
  5057. + /* load 3DES Key */
  5058. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  5059. + if (od->octo_encklen == 24) {
  5060. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  5061. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5062. + } else if (od->octo_encklen == 8) {
  5063. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  5064. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  5065. + } else {
  5066. + octeon_crypto_disable(&state, flags);
  5067. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  5068. + return -EINVAL;
  5069. + }
  5070. +
  5071. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  5072. +
  5073. + /* Load MD5 IV */
  5074. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5075. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5076. +
  5077. + while (crypt_off > 0 && auth_off > 0) {
  5078. + SG_CONSUME(sg, data32, data_i, data_l);
  5079. + crypt_off -= 4;
  5080. + auth_off -= 4;
  5081. + }
  5082. +
  5083. + while (crypt_len > 0 || auth_len > 0) {
  5084. + uint32_t *first = data32;
  5085. + mydata.data32[0] = *first;
  5086. + SG_CONSUME(sg, data32, data_i, data_l);
  5087. + mydata.data32[1] = *data32;
  5088. + if (auth_off <= 0) {
  5089. + if (auth_len > 0) {
  5090. + CVM_LOAD_MD5_UNIT(*data, next);
  5091. + auth_len -= 8;
  5092. + }
  5093. + } else
  5094. + auth_off -= 8;
  5095. + if (crypt_off <= 0) {
  5096. + if (crypt_len > 0) {
  5097. + CVMX_MT_3DES_DEC_CBC(*data);
  5098. + CVMX_MF_3DES_RESULT(*data);
  5099. + crypt_len -= 8;
  5100. + }
  5101. + } else
  5102. + crypt_off -= 8;
  5103. + *first = mydata.data32[0];
  5104. + *data32 = mydata.data32[1];
  5105. + SG_CONSUME(sg, data32, data_i, data_l);
  5106. + }
  5107. +
  5108. + /* finish the hash */
  5109. + CVMX_PREFETCH0(od->octo_hmouter);
  5110. +#if 0
  5111. + if (unlikely(inplen)) {
  5112. + uint64_t tmp = 0;
  5113. + uint8_t *p = (uint8_t *) & tmp;
  5114. + p[inplen] = 0x80;
  5115. + do {
  5116. + inplen--;
  5117. + p[inplen] = ((uint8_t *) data)[inplen];
  5118. + } while (inplen);
  5119. + CVM_LOAD_MD5_UNIT(tmp, next);
  5120. + } else {
  5121. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5122. + }
  5123. +#else
  5124. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5125. +#endif
  5126. +
  5127. + /* Finish Inner hash */
  5128. + while (next != 7) {
  5129. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  5130. + }
  5131. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  5132. + CVM_LOAD_MD5_UNIT(tmp1, next);
  5133. +
  5134. + /* Get the inner hash of HMAC */
  5135. + CVMX_MF_HSH_IV(tmp1, 0);
  5136. + CVMX_MF_HSH_IV(tmp2, 1);
  5137. +
  5138. + /* Initialize hash unit */
  5139. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  5140. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  5141. +
  5142. + CVMX_MT_HSH_DAT(tmp1, 0);
  5143. + CVMX_MT_HSH_DAT(tmp2, 1);
  5144. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  5145. + CVMX_MT_HSH_DATZ(3);
  5146. + CVMX_MT_HSH_DATZ(4);
  5147. + CVMX_MT_HSH_DATZ(5);
  5148. + CVMX_MT_HSH_DATZ(6);
  5149. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  5150. + CVMX_MT_HSH_STARTMD5(tmp1);
  5151. +
  5152. + /* save the HMAC */
  5153. + SG_INIT(sg, data32, data_i, data_l);
  5154. + while (icv_off > 0) {
  5155. + SG_CONSUME(sg, data32, data_i, data_l);
  5156. + icv_off -= 4;
  5157. + }
  5158. + CVMX_MF_HSH_IV(tmp1, 0);
  5159. + *data32 = (uint32_t) (tmp1 >> 32);
  5160. + SG_CONSUME(sg, data32, data_i, data_l);
  5161. + *data32 = (uint32_t) tmp1;
  5162. + SG_CONSUME(sg, data32, data_i, data_l);
  5163. + CVMX_MF_HSH_IV(tmp1, 1);
  5164. + *data32 = (uint32_t) (tmp1 >> 32);
  5165. +
  5166. + octeon_crypto_disable(&state, flags);
  5167. + return 0;
  5168. +}
  5169. +
  5170. +/****************************************************************************/
  5171. +/* DES SHA */
  5172. +
  5173. +int
  5174. +octo_des_cbc_sha1_encrypt(
  5175. + struct octo_sess *od,
  5176. + struct scatterlist *sg, int sg_len,
  5177. + int auth_off, int auth_len,
  5178. + int crypt_off, int crypt_len,
  5179. + int icv_off, uint8_t *ivp)
  5180. +{
  5181. + register int next = 0;
  5182. + union {
  5183. + uint32_t data32[2];
  5184. + uint64_t data64[1];
  5185. + } mydata;
  5186. + uint64_t *data = &mydata.data64[0];
  5187. + uint32_t *data32;
  5188. + uint64_t tmp1, tmp2, tmp3;
  5189. + int data_i, data_l, alen = auth_len;
  5190. + struct octeon_cop2_state state;
  5191. + unsigned long flags;
  5192. +
  5193. + dprintk("%s()\n", __FUNCTION__);
  5194. +
  5195. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  5196. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  5197. + (crypt_len & 0x7) ||
  5198. + (auth_len & 0x7) ||
  5199. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  5200. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5201. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5202. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5203. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5204. + return -EINVAL;
  5205. + }
  5206. +
  5207. + SG_INIT(sg, data32, data_i, data_l);
  5208. +
  5209. + CVMX_PREFETCH0(ivp);
  5210. + CVMX_PREFETCH0(od->octo_enckey);
  5211. +
  5212. + flags = octeon_crypto_enable(&state);
  5213. +
  5214. + /* load 3DES Key */
  5215. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  5216. + if (od->octo_encklen == 24) {
  5217. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  5218. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5219. + } else if (od->octo_encklen == 8) {
  5220. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  5221. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  5222. + } else {
  5223. + octeon_crypto_disable(&state, flags);
  5224. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  5225. + return -EINVAL;
  5226. + }
  5227. +
  5228. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  5229. +
  5230. + /* Load SHA1 IV */
  5231. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5232. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5233. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  5234. +
  5235. + while (crypt_off > 0 && auth_off > 0) {
  5236. + SG_CONSUME(sg, data32, data_i, data_l);
  5237. + crypt_off -= 4;
  5238. + auth_off -= 4;
  5239. + }
  5240. +
  5241. + while (crypt_len > 0 || auth_len > 0) {
  5242. + uint32_t *first = data32;
  5243. + mydata.data32[0] = *first;
  5244. + SG_CONSUME(sg, data32, data_i, data_l);
  5245. + mydata.data32[1] = *data32;
  5246. + if (crypt_off <= 0) {
  5247. + if (crypt_len > 0) {
  5248. + CVMX_MT_3DES_ENC_CBC(*data);
  5249. + CVMX_MF_3DES_RESULT(*data);
  5250. + crypt_len -= 8;
  5251. + }
  5252. + } else
  5253. + crypt_off -= 8;
  5254. + if (auth_off <= 0) {
  5255. + if (auth_len > 0) {
  5256. + CVM_LOAD_SHA_UNIT(*data, next);
  5257. + auth_len -= 8;
  5258. + }
  5259. + } else
  5260. + auth_off -= 8;
  5261. + *first = mydata.data32[0];
  5262. + *data32 = mydata.data32[1];
  5263. + SG_CONSUME(sg, data32, data_i, data_l);
  5264. + }
  5265. +
  5266. + /* finish the hash */
  5267. + CVMX_PREFETCH0(od->octo_hmouter);
  5268. +#if 0
  5269. + if (unlikely(inplen)) {
  5270. + uint64_t tmp = 0;
  5271. + uint8_t *p = (uint8_t *) & tmp;
  5272. + p[inplen] = 0x80;
  5273. + do {
  5274. + inplen--;
  5275. + p[inplen] = ((uint8_t *) data)[inplen];
  5276. + } while (inplen);
  5277. + CVM_LOAD_SHA_UNIT(tmp, next);
  5278. + } else {
  5279. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  5280. + }
  5281. +#else
  5282. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  5283. +#endif
  5284. +
  5285. + /* Finish Inner hash */
  5286. + while (next != 7) {
  5287. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  5288. + }
  5289. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  5290. +
  5291. + /* Get the inner hash of HMAC */
  5292. + CVMX_MF_HSH_IV(tmp1, 0);
  5293. + CVMX_MF_HSH_IV(tmp2, 1);
  5294. + tmp3 = 0;
  5295. + CVMX_MF_HSH_IV(tmp3, 2);
  5296. +
  5297. + /* Initialize hash unit */
  5298. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  5299. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  5300. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  5301. +
  5302. + CVMX_MT_HSH_DAT(tmp1, 0);
  5303. + CVMX_MT_HSH_DAT(tmp2, 1);
  5304. + tmp3 |= 0x0000000080000000;
  5305. + CVMX_MT_HSH_DAT(tmp3, 2);
  5306. + CVMX_MT_HSH_DATZ(3);
  5307. + CVMX_MT_HSH_DATZ(4);
  5308. + CVMX_MT_HSH_DATZ(5);
  5309. + CVMX_MT_HSH_DATZ(6);
  5310. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  5311. +
  5312. + /* save the HMAC */
  5313. + SG_INIT(sg, data32, data_i, data_l);
  5314. + while (icv_off > 0) {
  5315. + SG_CONSUME(sg, data32, data_i, data_l);
  5316. + icv_off -= 4;
  5317. + }
  5318. + CVMX_MF_HSH_IV(tmp1, 0);
  5319. + *data32 = (uint32_t) (tmp1 >> 32);
  5320. + SG_CONSUME(sg, data32, data_i, data_l);
  5321. + *data32 = (uint32_t) tmp1;
  5322. + SG_CONSUME(sg, data32, data_i, data_l);
  5323. + CVMX_MF_HSH_IV(tmp1, 1);
  5324. + *data32 = (uint32_t) (tmp1 >> 32);
  5325. +
  5326. + octeon_crypto_disable(&state, flags);
  5327. + return 0;
  5328. +}
  5329. +
  5330. +int
  5331. +octo_des_cbc_sha1_decrypt(
  5332. + struct octo_sess *od,
  5333. + struct scatterlist *sg, int sg_len,
  5334. + int auth_off, int auth_len,
  5335. + int crypt_off, int crypt_len,
  5336. + int icv_off, uint8_t *ivp)
  5337. +{
  5338. + register int next = 0;
  5339. + union {
  5340. + uint32_t data32[2];
  5341. + uint64_t data64[1];
  5342. + } mydata;
  5343. + uint64_t *data = &mydata.data64[0];
  5344. + uint32_t *data32;
  5345. + uint64_t tmp1, tmp2, tmp3;
  5346. + int data_i, data_l, alen = auth_len;
  5347. + struct octeon_cop2_state state;
  5348. + unsigned long flags;
  5349. +
  5350. + dprintk("%s()\n", __FUNCTION__);
  5351. +
  5352. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  5353. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  5354. + (crypt_len & 0x7) ||
  5355. + (auth_len & 0x7) ||
  5356. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  5357. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5358. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5359. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5360. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5361. + return -EINVAL;
  5362. + }
  5363. +
  5364. + SG_INIT(sg, data32, data_i, data_l);
  5365. +
  5366. + CVMX_PREFETCH0(ivp);
  5367. + CVMX_PREFETCH0(od->octo_enckey);
  5368. +
  5369. + flags = octeon_crypto_enable(&state);
  5370. +
  5371. + /* load 3DES Key */
  5372. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  5373. + if (od->octo_encklen == 24) {
  5374. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  5375. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5376. + } else if (od->octo_encklen == 8) {
  5377. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  5378. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  5379. + } else {
  5380. + octeon_crypto_disable(&state, flags);
  5381. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  5382. + return -EINVAL;
  5383. + }
  5384. +
  5385. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  5386. +
  5387. + /* Load SHA1 IV */
  5388. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5389. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5390. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  5391. +
  5392. + while (crypt_off > 0 && auth_off > 0) {
  5393. + SG_CONSUME(sg, data32, data_i, data_l);
  5394. + crypt_off -= 4;
  5395. + auth_off -= 4;
  5396. + }
  5397. +
  5398. + while (crypt_len > 0 || auth_len > 0) {
  5399. + uint32_t *first = data32;
  5400. + mydata.data32[0] = *first;
  5401. + SG_CONSUME(sg, data32, data_i, data_l);
  5402. + mydata.data32[1] = *data32;
  5403. + if (auth_off <= 0) {
  5404. + if (auth_len > 0) {
  5405. + CVM_LOAD_SHA_UNIT(*data, next);
  5406. + auth_len -= 8;
  5407. + }
  5408. + } else
  5409. + auth_off -= 8;
  5410. + if (crypt_off <= 0) {
  5411. + if (crypt_len > 0) {
  5412. + CVMX_MT_3DES_DEC_CBC(*data);
  5413. + CVMX_MF_3DES_RESULT(*data);
  5414. + crypt_len -= 8;
  5415. + }
  5416. + } else
  5417. + crypt_off -= 8;
  5418. + *first = mydata.data32[0];
  5419. + *data32 = mydata.data32[1];
  5420. + SG_CONSUME(sg, data32, data_i, data_l);
  5421. + }
  5422. +
  5423. + /* finish the hash */
  5424. + CVMX_PREFETCH0(od->octo_hmouter);
  5425. +#if 0
  5426. + if (unlikely(inplen)) {
  5427. + uint64_t tmp = 0;
  5428. + uint8_t *p = (uint8_t *) & tmp;
  5429. + p[inplen] = 0x80;
  5430. + do {
  5431. + inplen--;
  5432. + p[inplen] = ((uint8_t *) data)[inplen];
  5433. + } while (inplen);
  5434. + CVM_LOAD_SHA_UNIT(tmp, next);
  5435. + } else {
  5436. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  5437. + }
  5438. +#else
  5439. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  5440. +#endif
  5441. +
  5442. + /* Finish Inner hash */
  5443. + while (next != 7) {
  5444. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  5445. + }
  5446. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  5447. +
  5448. + /* Get the inner hash of HMAC */
  5449. + CVMX_MF_HSH_IV(tmp1, 0);
  5450. + CVMX_MF_HSH_IV(tmp2, 1);
  5451. + tmp3 = 0;
  5452. + CVMX_MF_HSH_IV(tmp3, 2);
  5453. +
  5454. + /* Initialize hash unit */
  5455. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  5456. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  5457. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  5458. +
  5459. + CVMX_MT_HSH_DAT(tmp1, 0);
  5460. + CVMX_MT_HSH_DAT(tmp2, 1);
  5461. + tmp3 |= 0x0000000080000000;
  5462. + CVMX_MT_HSH_DAT(tmp3, 2);
  5463. + CVMX_MT_HSH_DATZ(3);
  5464. + CVMX_MT_HSH_DATZ(4);
  5465. + CVMX_MT_HSH_DATZ(5);
  5466. + CVMX_MT_HSH_DATZ(6);
  5467. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  5468. + /* save the HMAC */
  5469. + SG_INIT(sg, data32, data_i, data_l);
  5470. + while (icv_off > 0) {
  5471. + SG_CONSUME(sg, data32, data_i, data_l);
  5472. + icv_off -= 4;
  5473. + }
  5474. + CVMX_MF_HSH_IV(tmp1, 0);
  5475. + *data32 = (uint32_t) (tmp1 >> 32);
  5476. + SG_CONSUME(sg, data32, data_i, data_l);
  5477. + *data32 = (uint32_t) tmp1;
  5478. + SG_CONSUME(sg, data32, data_i, data_l);
  5479. + CVMX_MF_HSH_IV(tmp1, 1);
  5480. + *data32 = (uint32_t) (tmp1 >> 32);
  5481. +
  5482. + octeon_crypto_disable(&state, flags);
  5483. + return 0;
  5484. +}
  5485. +
  5486. +/****************************************************************************/
  5487. +/* AES MD5 */
  5488. +
  5489. +int
  5490. +octo_aes_cbc_md5_encrypt(
  5491. + struct octo_sess *od,
  5492. + struct scatterlist *sg, int sg_len,
  5493. + int auth_off, int auth_len,
  5494. + int crypt_off, int crypt_len,
  5495. + int icv_off, uint8_t *ivp)
  5496. +{
  5497. + register int next = 0;
  5498. + union {
  5499. + uint32_t data32[2];
  5500. + uint64_t data64[1];
  5501. + } mydata[2];
  5502. + uint64_t *pdata = &mydata[0].data64[0];
  5503. + uint64_t *data = &mydata[1].data64[0];
  5504. + uint32_t *data32;
  5505. + uint64_t tmp1, tmp2;
  5506. + int data_i, data_l, alen = auth_len;
  5507. + struct octeon_cop2_state state;
  5508. + unsigned long flags;
  5509. +
  5510. + dprintk("%s()\n", __FUNCTION__);
  5511. +
  5512. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  5513. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  5514. + (crypt_len & 0x7) ||
  5515. + (auth_len & 0x7) ||
  5516. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  5517. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5518. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5519. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5520. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5521. + return -EINVAL;
  5522. + }
  5523. +
  5524. + SG_INIT(sg, data32, data_i, data_l);
  5525. +
  5526. + CVMX_PREFETCH0(ivp);
  5527. + CVMX_PREFETCH0(od->octo_enckey);
  5528. +
  5529. + flags = octeon_crypto_enable(&state);
  5530. +
  5531. + /* load AES Key */
  5532. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  5533. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  5534. +
  5535. + if (od->octo_encklen == 16) {
  5536. + CVMX_MT_AES_KEY(0x0, 2);
  5537. + CVMX_MT_AES_KEY(0x0, 3);
  5538. + } else if (od->octo_encklen == 24) {
  5539. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5540. + CVMX_MT_AES_KEY(0x0, 3);
  5541. + } else if (od->octo_encklen == 32) {
  5542. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5543. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  5544. + } else {
  5545. + octeon_crypto_disable(&state, flags);
  5546. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  5547. + return -EINVAL;
  5548. + }
  5549. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  5550. +
  5551. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  5552. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  5553. +
  5554. + /* Load MD5 IV */
  5555. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5556. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5557. +
  5558. + while (crypt_off > 0 && auth_off > 0) {
  5559. + SG_CONSUME(sg, data32, data_i, data_l);
  5560. + crypt_off -= 4;
  5561. + auth_off -= 4;
  5562. + }
  5563. +
  5564. + /* align auth and crypt */
  5565. + while (crypt_off > 0 && auth_len > 0) {
  5566. + mydata[0].data32[0] = *data32;
  5567. + SG_CONSUME(sg, data32, data_i, data_l);
  5568. + mydata[0].data32[1] = *data32;
  5569. + SG_CONSUME(sg, data32, data_i, data_l);
  5570. + CVM_LOAD_MD5_UNIT(*pdata, next);
  5571. + crypt_off -= 8;
  5572. + auth_len -= 8;
  5573. + }
  5574. +
  5575. + while (crypt_len > 0) {
  5576. + uint32_t *pdata32[3];
  5577. +
  5578. + pdata32[0] = data32;
  5579. + mydata[0].data32[0] = *data32;
  5580. + SG_CONSUME(sg, data32, data_i, data_l);
  5581. +
  5582. + pdata32[1] = data32;
  5583. + mydata[0].data32[1] = *data32;
  5584. + SG_CONSUME(sg, data32, data_i, data_l);
  5585. +
  5586. + pdata32[2] = data32;
  5587. + mydata[1].data32[0] = *data32;
  5588. + SG_CONSUME(sg, data32, data_i, data_l);
  5589. +
  5590. + mydata[1].data32[1] = *data32;
  5591. +
  5592. + CVMX_MT_AES_ENC_CBC0(*pdata);
  5593. + CVMX_MT_AES_ENC_CBC1(*data);
  5594. + CVMX_MF_AES_RESULT(*pdata, 0);
  5595. + CVMX_MF_AES_RESULT(*data, 1);
  5596. + crypt_len -= 16;
  5597. +
  5598. + if (auth_len > 0) {
  5599. + CVM_LOAD_MD5_UNIT(*pdata, next);
  5600. + auth_len -= 8;
  5601. + }
  5602. + if (auth_len > 0) {
  5603. + CVM_LOAD_MD5_UNIT(*data, next);
  5604. + auth_len -= 8;
  5605. + }
  5606. +
  5607. + *pdata32[0] = mydata[0].data32[0];
  5608. + *pdata32[1] = mydata[0].data32[1];
  5609. + *pdata32[2] = mydata[1].data32[0];
  5610. + *data32 = mydata[1].data32[1];
  5611. +
  5612. + SG_CONSUME(sg, data32, data_i, data_l);
  5613. + }
  5614. +
  5615. + /* finish any left over hashing */
  5616. + while (auth_len > 0) {
  5617. + mydata[0].data32[0] = *data32;
  5618. + SG_CONSUME(sg, data32, data_i, data_l);
  5619. + mydata[0].data32[1] = *data32;
  5620. + SG_CONSUME(sg, data32, data_i, data_l);
  5621. + CVM_LOAD_MD5_UNIT(*pdata, next);
  5622. + auth_len -= 8;
  5623. + }
  5624. +
  5625. + /* finish the hash */
  5626. + CVMX_PREFETCH0(od->octo_hmouter);
  5627. +#if 0
  5628. + if (unlikely(inplen)) {
  5629. + uint64_t tmp = 0;
  5630. + uint8_t *p = (uint8_t *) & tmp;
  5631. + p[inplen] = 0x80;
  5632. + do {
  5633. + inplen--;
  5634. + p[inplen] = ((uint8_t *) data)[inplen];
  5635. + } while (inplen);
  5636. + CVM_LOAD_MD5_UNIT(tmp, next);
  5637. + } else {
  5638. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5639. + }
  5640. +#else
  5641. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5642. +#endif
  5643. +
  5644. + /* Finish Inner hash */
  5645. + while (next != 7) {
  5646. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  5647. + }
  5648. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  5649. + CVM_LOAD_MD5_UNIT(tmp1, next);
  5650. +
  5651. + /* Get the inner hash of HMAC */
  5652. + CVMX_MF_HSH_IV(tmp1, 0);
  5653. + CVMX_MF_HSH_IV(tmp2, 1);
  5654. +
  5655. + /* Initialize hash unit */
  5656. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  5657. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  5658. +
  5659. + CVMX_MT_HSH_DAT(tmp1, 0);
  5660. + CVMX_MT_HSH_DAT(tmp2, 1);
  5661. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  5662. + CVMX_MT_HSH_DATZ(3);
  5663. + CVMX_MT_HSH_DATZ(4);
  5664. + CVMX_MT_HSH_DATZ(5);
  5665. + CVMX_MT_HSH_DATZ(6);
  5666. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  5667. + CVMX_MT_HSH_STARTMD5(tmp1);
  5668. +
  5669. + /* save the HMAC */
  5670. + SG_INIT(sg, data32, data_i, data_l);
  5671. + while (icv_off > 0) {
  5672. + SG_CONSUME(sg, data32, data_i, data_l);
  5673. + icv_off -= 4;
  5674. + }
  5675. + CVMX_MF_HSH_IV(tmp1, 0);
  5676. + *data32 = (uint32_t) (tmp1 >> 32);
  5677. + SG_CONSUME(sg, data32, data_i, data_l);
  5678. + *data32 = (uint32_t) tmp1;
  5679. + SG_CONSUME(sg, data32, data_i, data_l);
  5680. + CVMX_MF_HSH_IV(tmp1, 1);
  5681. + *data32 = (uint32_t) (tmp1 >> 32);
  5682. +
  5683. + octeon_crypto_disable(&state, flags);
  5684. + return 0;
  5685. +}
  5686. +
  5687. +int
  5688. +octo_aes_cbc_md5_decrypt(
  5689. + struct octo_sess *od,
  5690. + struct scatterlist *sg, int sg_len,
  5691. + int auth_off, int auth_len,
  5692. + int crypt_off, int crypt_len,
  5693. + int icv_off, uint8_t *ivp)
  5694. +{
  5695. + register int next = 0;
  5696. + union {
  5697. + uint32_t data32[2];
  5698. + uint64_t data64[1];
  5699. + } mydata[2];
  5700. + uint64_t *pdata = &mydata[0].data64[0];
  5701. + uint64_t *data = &mydata[1].data64[0];
  5702. + uint32_t *data32;
  5703. + uint64_t tmp1, tmp2;
  5704. + int data_i, data_l, alen = auth_len;
  5705. + struct octeon_cop2_state state;
  5706. + unsigned long flags;
  5707. +
  5708. + dprintk("%s()\n", __FUNCTION__);
  5709. +
  5710. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  5711. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  5712. + (crypt_len & 0x7) ||
  5713. + (auth_len & 0x7) ||
  5714. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  5715. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5716. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5717. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5718. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5719. + return -EINVAL;
  5720. + }
  5721. +
  5722. + SG_INIT(sg, data32, data_i, data_l);
  5723. +
  5724. + CVMX_PREFETCH0(ivp);
  5725. + CVMX_PREFETCH0(od->octo_enckey);
  5726. +
  5727. + flags = octeon_crypto_enable(&state);
  5728. +
  5729. + /* load AES Key */
  5730. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  5731. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  5732. +
  5733. + if (od->octo_encklen == 16) {
  5734. + CVMX_MT_AES_KEY(0x0, 2);
  5735. + CVMX_MT_AES_KEY(0x0, 3);
  5736. + } else if (od->octo_encklen == 24) {
  5737. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5738. + CVMX_MT_AES_KEY(0x0, 3);
  5739. + } else if (od->octo_encklen == 32) {
  5740. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5741. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  5742. + } else {
  5743. + octeon_crypto_disable(&state, flags);
  5744. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  5745. + return -EINVAL;
  5746. + }
  5747. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  5748. +
  5749. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  5750. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  5751. +
  5752. + /* Load MD5 IV */
  5753. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5754. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5755. +
  5756. + while (crypt_off > 0 && auth_off > 0) {
  5757. + SG_CONSUME(sg, data32, data_i, data_l);
  5758. + crypt_off -= 4;
  5759. + auth_off -= 4;
  5760. + }
  5761. +
  5762. + /* align auth and crypt */
  5763. + while (crypt_off > 0 && auth_len > 0) {
  5764. + mydata[0].data32[0] = *data32;
  5765. + SG_CONSUME(sg, data32, data_i, data_l);
  5766. + mydata[0].data32[1] = *data32;
  5767. + SG_CONSUME(sg, data32, data_i, data_l);
  5768. + CVM_LOAD_MD5_UNIT(*pdata, next);
  5769. + crypt_off -= 8;
  5770. + auth_len -= 8;
  5771. + }
  5772. +
  5773. + while (crypt_len > 0) {
  5774. + uint32_t *pdata32[3];
  5775. +
  5776. + pdata32[0] = data32;
  5777. + mydata[0].data32[0] = *data32;
  5778. + SG_CONSUME(sg, data32, data_i, data_l);
  5779. + pdata32[1] = data32;
  5780. + mydata[0].data32[1] = *data32;
  5781. + SG_CONSUME(sg, data32, data_i, data_l);
  5782. + pdata32[2] = data32;
  5783. + mydata[1].data32[0] = *data32;
  5784. + SG_CONSUME(sg, data32, data_i, data_l);
  5785. + mydata[1].data32[1] = *data32;
  5786. +
  5787. + if (auth_len > 0) {
  5788. + CVM_LOAD_MD5_UNIT(*pdata, next);
  5789. + auth_len -= 8;
  5790. + }
  5791. +
  5792. + if (auth_len > 0) {
  5793. + CVM_LOAD_MD5_UNIT(*data, next);
  5794. + auth_len -= 8;
  5795. + }
  5796. +
  5797. + CVMX_MT_AES_DEC_CBC0(*pdata);
  5798. + CVMX_MT_AES_DEC_CBC1(*data);
  5799. + CVMX_MF_AES_RESULT(*pdata, 0);
  5800. + CVMX_MF_AES_RESULT(*data, 1);
  5801. + crypt_len -= 16;
  5802. +
  5803. + *pdata32[0] = mydata[0].data32[0];
  5804. + *pdata32[1] = mydata[0].data32[1];
  5805. + *pdata32[2] = mydata[1].data32[0];
  5806. + *data32 = mydata[1].data32[1];
  5807. +
  5808. + SG_CONSUME(sg, data32, data_i, data_l);
  5809. + }
  5810. +
  5811. + /* finish left over hash if any */
  5812. + while (auth_len > 0) {
  5813. + mydata[0].data32[0] = *data32;
  5814. + SG_CONSUME(sg, data32, data_i, data_l);
  5815. + mydata[0].data32[1] = *data32;
  5816. + SG_CONSUME(sg, data32, data_i, data_l);
  5817. + CVM_LOAD_MD5_UNIT(*pdata, next);
  5818. + auth_len -= 8;
  5819. + }
  5820. +
  5821. +
  5822. + /* finish the hash */
  5823. + CVMX_PREFETCH0(od->octo_hmouter);
  5824. +#if 0
  5825. + if (unlikely(inplen)) {
  5826. + uint64_t tmp = 0;
  5827. + uint8_t *p = (uint8_t *) & tmp;
  5828. + p[inplen] = 0x80;
  5829. + do {
  5830. + inplen--;
  5831. + p[inplen] = ((uint8_t *) data)[inplen];
  5832. + } while (inplen);
  5833. + CVM_LOAD_MD5_UNIT(tmp, next);
  5834. + } else {
  5835. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5836. + }
  5837. +#else
  5838. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5839. +#endif
  5840. +
  5841. + /* Finish Inner hash */
  5842. + while (next != 7) {
  5843. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  5844. + }
  5845. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  5846. + CVM_LOAD_MD5_UNIT(tmp1, next);
  5847. +
  5848. + /* Get the inner hash of HMAC */
  5849. + CVMX_MF_HSH_IV(tmp1, 0);
  5850. + CVMX_MF_HSH_IV(tmp2, 1);
  5851. +
  5852. + /* Initialize hash unit */
  5853. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  5854. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  5855. +
  5856. + CVMX_MT_HSH_DAT(tmp1, 0);
  5857. + CVMX_MT_HSH_DAT(tmp2, 1);
  5858. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  5859. + CVMX_MT_HSH_DATZ(3);
  5860. + CVMX_MT_HSH_DATZ(4);
  5861. + CVMX_MT_HSH_DATZ(5);
  5862. + CVMX_MT_HSH_DATZ(6);
  5863. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  5864. + CVMX_MT_HSH_STARTMD5(tmp1);
  5865. +
  5866. + /* save the HMAC */
  5867. + SG_INIT(sg, data32, data_i, data_l);
  5868. + while (icv_off > 0) {
  5869. + SG_CONSUME(sg, data32, data_i, data_l);
  5870. + icv_off -= 4;
  5871. + }
  5872. + CVMX_MF_HSH_IV(tmp1, 0);
  5873. + *data32 = (uint32_t) (tmp1 >> 32);
  5874. + SG_CONSUME(sg, data32, data_i, data_l);
  5875. + *data32 = (uint32_t) tmp1;
  5876. + SG_CONSUME(sg, data32, data_i, data_l);
  5877. + CVMX_MF_HSH_IV(tmp1, 1);
  5878. + *data32 = (uint32_t) (tmp1 >> 32);
  5879. +
  5880. + octeon_crypto_disable(&state, flags);
  5881. + return 0;
  5882. +}
  5883. +
  5884. +/****************************************************************************/
  5885. +/* AES SHA1 */
  5886. +
  5887. +int
  5888. +octo_aes_cbc_sha1_encrypt(
  5889. + struct octo_sess *od,
  5890. + struct scatterlist *sg, int sg_len,
  5891. + int auth_off, int auth_len,
  5892. + int crypt_off, int crypt_len,
  5893. + int icv_off, uint8_t *ivp)
  5894. +{
  5895. + register int next = 0;
  5896. + union {
  5897. + uint32_t data32[2];
  5898. + uint64_t data64[1];
  5899. + } mydata[2];
  5900. + uint64_t *pdata = &mydata[0].data64[0];
  5901. + uint64_t *data = &mydata[1].data64[0];
  5902. + uint32_t *data32;
  5903. + uint64_t tmp1, tmp2, tmp3;
  5904. + int data_i, data_l, alen = auth_len;
  5905. + struct octeon_cop2_state state;
  5906. + unsigned long flags;
  5907. +
  5908. + dprintk("%s(a_off=%d a_len=%d c_off=%d c_len=%d icv_off=%d)\n",
  5909. + __FUNCTION__, auth_off, auth_len, crypt_off, crypt_len, icv_off);
  5910. +
  5911. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  5912. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  5913. + (crypt_len & 0x7) ||
  5914. + (auth_len & 0x7) ||
  5915. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  5916. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5917. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5918. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5919. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5920. + return -EINVAL;
  5921. + }
  5922. +
  5923. + SG_INIT(sg, data32, data_i, data_l);
  5924. +
  5925. + CVMX_PREFETCH0(ivp);
  5926. + CVMX_PREFETCH0(od->octo_enckey);
  5927. +
  5928. + flags = octeon_crypto_enable(&state);
  5929. +
  5930. + /* load AES Key */
  5931. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  5932. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  5933. +
  5934. + if (od->octo_encklen == 16) {
  5935. + CVMX_MT_AES_KEY(0x0, 2);
  5936. + CVMX_MT_AES_KEY(0x0, 3);
  5937. + } else if (od->octo_encklen == 24) {
  5938. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5939. + CVMX_MT_AES_KEY(0x0, 3);
  5940. + } else if (od->octo_encklen == 32) {
  5941. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5942. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  5943. + } else {
  5944. + octeon_crypto_disable(&state, flags);
  5945. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  5946. + return -EINVAL;
  5947. + }
  5948. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  5949. +
  5950. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  5951. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  5952. +
  5953. + /* Load SHA IV */
  5954. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5955. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5956. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  5957. +
  5958. + while (crypt_off > 0 && auth_off > 0) {
  5959. + SG_CONSUME(sg, data32, data_i, data_l);
  5960. + crypt_off -= 4;
  5961. + auth_off -= 4;
  5962. + }
  5963. +
  5964. + /* align auth and crypt */
  5965. + while (crypt_off > 0 && auth_len > 0) {
  5966. + mydata[0].data32[0] = *data32;
  5967. + SG_CONSUME(sg, data32, data_i, data_l);
  5968. + mydata[0].data32[1] = *data32;
  5969. + SG_CONSUME(sg, data32, data_i, data_l);
  5970. + CVM_LOAD_SHA_UNIT(*pdata, next);
  5971. + crypt_off -= 8;
  5972. + auth_len -= 8;
  5973. + }
  5974. +
  5975. + while (crypt_len > 0) {
  5976. + uint32_t *pdata32[3];
  5977. +
  5978. + pdata32[0] = data32;
  5979. + mydata[0].data32[0] = *data32;
  5980. + SG_CONSUME(sg, data32, data_i, data_l);
  5981. + pdata32[1] = data32;
  5982. + mydata[0].data32[1] = *data32;
  5983. + SG_CONSUME(sg, data32, data_i, data_l);
  5984. + pdata32[2] = data32;
  5985. + mydata[1].data32[0] = *data32;
  5986. + SG_CONSUME(sg, data32, data_i, data_l);
  5987. + mydata[1].data32[1] = *data32;
  5988. +
  5989. + CVMX_MT_AES_ENC_CBC0(*pdata);
  5990. + CVMX_MT_AES_ENC_CBC1(*data);
  5991. + CVMX_MF_AES_RESULT(*pdata, 0);
  5992. + CVMX_MF_AES_RESULT(*data, 1);
  5993. + crypt_len -= 16;
  5994. +
  5995. + if (auth_len > 0) {
  5996. + CVM_LOAD_SHA_UNIT(*pdata, next);
  5997. + auth_len -= 8;
  5998. + }
  5999. + if (auth_len > 0) {
  6000. + CVM_LOAD_SHA_UNIT(*data, next);
  6001. + auth_len -= 8;
  6002. + }
  6003. +
  6004. + *pdata32[0] = mydata[0].data32[0];
  6005. + *pdata32[1] = mydata[0].data32[1];
  6006. + *pdata32[2] = mydata[1].data32[0];
  6007. + *data32 = mydata[1].data32[1];
  6008. +
  6009. + SG_CONSUME(sg, data32, data_i, data_l);
  6010. + }
  6011. +
  6012. + /* finish and hashing */
  6013. + while (auth_len > 0) {
  6014. + mydata[0].data32[0] = *data32;
  6015. + SG_CONSUME(sg, data32, data_i, data_l);
  6016. + mydata[0].data32[1] = *data32;
  6017. + SG_CONSUME(sg, data32, data_i, data_l);
  6018. + CVM_LOAD_SHA_UNIT(*pdata, next);
  6019. + auth_len -= 8;
  6020. + }
  6021. +
  6022. + /* finish the hash */
  6023. + CVMX_PREFETCH0(od->octo_hmouter);
  6024. +#if 0
  6025. + if (unlikely(inplen)) {
  6026. + uint64_t tmp = 0;
  6027. + uint8_t *p = (uint8_t *) & tmp;
  6028. + p[inplen] = 0x80;
  6029. + do {
  6030. + inplen--;
  6031. + p[inplen] = ((uint8_t *) data)[inplen];
  6032. + } while (inplen);
  6033. + CVM_LOAD_SHA_UNIT(tmp, next);
  6034. + } else {
  6035. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  6036. + }
  6037. +#else
  6038. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  6039. +#endif
  6040. +
  6041. + /* Finish Inner hash */
  6042. + while (next != 7) {
  6043. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  6044. + }
  6045. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  6046. +
  6047. + /* Get the inner hash of HMAC */
  6048. + CVMX_MF_HSH_IV(tmp1, 0);
  6049. + CVMX_MF_HSH_IV(tmp2, 1);
  6050. + tmp3 = 0;
  6051. + CVMX_MF_HSH_IV(tmp3, 2);
  6052. +
  6053. + /* Initialize hash unit */
  6054. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  6055. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  6056. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  6057. +
  6058. + CVMX_MT_HSH_DAT(tmp1, 0);
  6059. + CVMX_MT_HSH_DAT(tmp2, 1);
  6060. + tmp3 |= 0x0000000080000000;
  6061. + CVMX_MT_HSH_DAT(tmp3, 2);
  6062. + CVMX_MT_HSH_DATZ(3);
  6063. + CVMX_MT_HSH_DATZ(4);
  6064. + CVMX_MT_HSH_DATZ(5);
  6065. + CVMX_MT_HSH_DATZ(6);
  6066. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  6067. +
  6068. + /* finish the hash */
  6069. + CVMX_PREFETCH0(od->octo_hmouter);
  6070. +#if 0
  6071. + if (unlikely(inplen)) {
  6072. + uint64_t tmp = 0;
  6073. + uint8_t *p = (uint8_t *) & tmp;
  6074. + p[inplen] = 0x80;
  6075. + do {
  6076. + inplen--;
  6077. + p[inplen] = ((uint8_t *) data)[inplen];
  6078. + } while (inplen);
  6079. + CVM_LOAD_MD5_UNIT(tmp, next);
  6080. + } else {
  6081. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  6082. + }
  6083. +#else
  6084. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  6085. +#endif
  6086. +
  6087. + /* save the HMAC */
  6088. + SG_INIT(sg, data32, data_i, data_l);
  6089. + while (icv_off > 0) {
  6090. + SG_CONSUME(sg, data32, data_i, data_l);
  6091. + icv_off -= 4;
  6092. + }
  6093. + CVMX_MF_HSH_IV(tmp1, 0);
  6094. + *data32 = (uint32_t) (tmp1 >> 32);
  6095. + SG_CONSUME(sg, data32, data_i, data_l);
  6096. + *data32 = (uint32_t) tmp1;
  6097. + SG_CONSUME(sg, data32, data_i, data_l);
  6098. + CVMX_MF_HSH_IV(tmp1, 1);
  6099. + *data32 = (uint32_t) (tmp1 >> 32);
  6100. +
  6101. + octeon_crypto_disable(&state, flags);
  6102. + return 0;
  6103. +}
  6104. +
  6105. +int
  6106. +octo_aes_cbc_sha1_decrypt(
  6107. + struct octo_sess *od,
  6108. + struct scatterlist *sg, int sg_len,
  6109. + int auth_off, int auth_len,
  6110. + int crypt_off, int crypt_len,
  6111. + int icv_off, uint8_t *ivp)
  6112. +{
  6113. + register int next = 0;
  6114. + union {
  6115. + uint32_t data32[2];
  6116. + uint64_t data64[1];
  6117. + } mydata[2];
  6118. + uint64_t *pdata = &mydata[0].data64[0];
  6119. + uint64_t *data = &mydata[1].data64[0];
  6120. + uint32_t *data32;
  6121. + uint64_t tmp1, tmp2, tmp3;
  6122. + int data_i, data_l, alen = auth_len;
  6123. + struct octeon_cop2_state state;
  6124. + unsigned long flags;
  6125. +
  6126. + dprintk("%s(a_off=%d a_len=%d c_off=%d c_len=%d icv_off=%d)\n",
  6127. + __FUNCTION__, auth_off, auth_len, crypt_off, crypt_len, icv_off);
  6128. +
  6129. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  6130. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  6131. + (crypt_len & 0x7) ||
  6132. + (auth_len & 0x7) ||
  6133. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  6134. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  6135. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  6136. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  6137. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  6138. + return -EINVAL;
  6139. + }
  6140. +
  6141. + SG_INIT(sg, data32, data_i, data_l);
  6142. +
  6143. + CVMX_PREFETCH0(ivp);
  6144. + CVMX_PREFETCH0(od->octo_enckey);
  6145. +
  6146. + flags = octeon_crypto_enable(&state);
  6147. +
  6148. + /* load AES Key */
  6149. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  6150. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  6151. +
  6152. + if (od->octo_encklen == 16) {
  6153. + CVMX_MT_AES_KEY(0x0, 2);
  6154. + CVMX_MT_AES_KEY(0x0, 3);
  6155. + } else if (od->octo_encklen == 24) {
  6156. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  6157. + CVMX_MT_AES_KEY(0x0, 3);
  6158. + } else if (od->octo_encklen == 32) {
  6159. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  6160. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  6161. + } else {
  6162. + octeon_crypto_disable(&state, flags);
  6163. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  6164. + return -EINVAL;
  6165. + }
  6166. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  6167. +
  6168. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  6169. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  6170. +
  6171. + /* Load SHA1 IV */
  6172. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  6173. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  6174. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  6175. +
  6176. + while (crypt_off > 0 && auth_off > 0) {
  6177. + SG_CONSUME(sg, data32, data_i, data_l);
  6178. + crypt_off -= 4;
  6179. + auth_off -= 4;
  6180. + }
  6181. +
  6182. + /* align auth and crypt */
  6183. + while (crypt_off > 0 && auth_len > 0) {
  6184. + mydata[0].data32[0] = *data32;
  6185. + SG_CONSUME(sg, data32, data_i, data_l);
  6186. + mydata[0].data32[1] = *data32;
  6187. + SG_CONSUME(sg, data32, data_i, data_l);
  6188. + CVM_LOAD_SHA_UNIT(*pdata, next);
  6189. + crypt_off -= 8;
  6190. + auth_len -= 8;
  6191. + }
  6192. +
  6193. + while (crypt_len > 0) {
  6194. + uint32_t *pdata32[3];
  6195. +
  6196. + pdata32[0] = data32;
  6197. + mydata[0].data32[0] = *data32;
  6198. + SG_CONSUME(sg, data32, data_i, data_l);
  6199. + pdata32[1] = data32;
  6200. + mydata[0].data32[1] = *data32;
  6201. + SG_CONSUME(sg, data32, data_i, data_l);
  6202. + pdata32[2] = data32;
  6203. + mydata[1].data32[0] = *data32;
  6204. + SG_CONSUME(sg, data32, data_i, data_l);
  6205. + mydata[1].data32[1] = *data32;
  6206. +
  6207. + if (auth_len > 0) {
  6208. + CVM_LOAD_SHA_UNIT(*pdata, next);
  6209. + auth_len -= 8;
  6210. + }
  6211. + if (auth_len > 0) {
  6212. + CVM_LOAD_SHA_UNIT(*data, next);
  6213. + auth_len -= 8;
  6214. + }
  6215. +
  6216. + CVMX_MT_AES_DEC_CBC0(*pdata);
  6217. + CVMX_MT_AES_DEC_CBC1(*data);
  6218. + CVMX_MF_AES_RESULT(*pdata, 0);
  6219. + CVMX_MF_AES_RESULT(*data, 1);
  6220. + crypt_len -= 16;
  6221. +
  6222. + *pdata32[0] = mydata[0].data32[0];
  6223. + *pdata32[1] = mydata[0].data32[1];
  6224. + *pdata32[2] = mydata[1].data32[0];
  6225. + *data32 = mydata[1].data32[1];
  6226. +
  6227. + SG_CONSUME(sg, data32, data_i, data_l);
  6228. + }
  6229. +
  6230. + /* finish and leftover hashing */
  6231. + while (auth_len > 0) {
  6232. + mydata[0].data32[0] = *data32;
  6233. + SG_CONSUME(sg, data32, data_i, data_l);
  6234. + mydata[0].data32[1] = *data32;
  6235. + SG_CONSUME(sg, data32, data_i, data_l);
  6236. + CVM_LOAD_SHA_UNIT(*pdata, next);
  6237. + auth_len -= 8;
  6238. + }
  6239. +
  6240. + /* finish the hash */
  6241. + CVMX_PREFETCH0(od->octo_hmouter);
  6242. +#if 0
  6243. + if (unlikely(inplen)) {
  6244. + uint64_t tmp = 0;
  6245. + uint8_t *p = (uint8_t *) & tmp;
  6246. + p[inplen] = 0x80;
  6247. + do {
  6248. + inplen--;
  6249. + p[inplen] = ((uint8_t *) data)[inplen];
  6250. + } while (inplen);
  6251. + CVM_LOAD_SHA_UNIT(tmp, next);
  6252. + } else {
  6253. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  6254. + }
  6255. +#else
  6256. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  6257. +#endif
  6258. +
  6259. + /* Finish Inner hash */
  6260. + while (next != 7) {
  6261. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  6262. + }
  6263. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  6264. +
  6265. + /* Get the inner hash of HMAC */
  6266. + CVMX_MF_HSH_IV(tmp1, 0);
  6267. + CVMX_MF_HSH_IV(tmp2, 1);
  6268. + tmp3 = 0;
  6269. + CVMX_MF_HSH_IV(tmp3, 2);
  6270. +
  6271. + /* Initialize hash unit */
  6272. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  6273. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  6274. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  6275. +
  6276. + CVMX_MT_HSH_DAT(tmp1, 0);
  6277. + CVMX_MT_HSH_DAT(tmp2, 1);
  6278. + tmp3 |= 0x0000000080000000;
  6279. + CVMX_MT_HSH_DAT(tmp3, 2);
  6280. + CVMX_MT_HSH_DATZ(3);
  6281. + CVMX_MT_HSH_DATZ(4);
  6282. + CVMX_MT_HSH_DATZ(5);
  6283. + CVMX_MT_HSH_DATZ(6);
  6284. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  6285. +
  6286. + /* finish the hash */
  6287. + CVMX_PREFETCH0(od->octo_hmouter);
  6288. +#if 0
  6289. + if (unlikely(inplen)) {
  6290. + uint64_t tmp = 0;
  6291. + uint8_t *p = (uint8_t *) & tmp;
  6292. + p[inplen] = 0x80;
  6293. + do {
  6294. + inplen--;
  6295. + p[inplen] = ((uint8_t *) data)[inplen];
  6296. + } while (inplen);
  6297. + CVM_LOAD_MD5_UNIT(tmp, next);
  6298. + } else {
  6299. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  6300. + }
  6301. +#else
  6302. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  6303. +#endif
  6304. +
  6305. + /* save the HMAC */
  6306. + SG_INIT(sg, data32, data_i, data_l);
  6307. + while (icv_off > 0) {
  6308. + SG_CONSUME(sg, data32, data_i, data_l);
  6309. + icv_off -= 4;
  6310. + }
  6311. + CVMX_MF_HSH_IV(tmp1, 0);
  6312. + *data32 = (uint32_t) (tmp1 >> 32);
  6313. + SG_CONSUME(sg, data32, data_i, data_l);
  6314. + *data32 = (uint32_t) tmp1;
  6315. + SG_CONSUME(sg, data32, data_i, data_l);
  6316. + CVMX_MF_HSH_IV(tmp1, 1);
  6317. + *data32 = (uint32_t) (tmp1 >> 32);
  6318. +
  6319. + octeon_crypto_disable(&state, flags);
  6320. + return 0;
  6321. +}
  6322. +
  6323. +/****************************************************************************/
  6324. diff -Nur linux-2.6.39.orig/crypto/ocf/cryptocteon/cryptocteon.c linux-2.6.39/crypto/ocf/cryptocteon/cryptocteon.c
  6325. --- linux-2.6.39.orig/crypto/ocf/cryptocteon/cryptocteon.c 1970-01-01 01:00:00.000000000 +0100
  6326. +++ linux-2.6.39/crypto/ocf/cryptocteon/cryptocteon.c 2011-07-31 11:31:53.583903727 +0200
  6327. @@ -0,0 +1,574 @@
  6328. +/*
  6329. + * Octeon Crypto for OCF
  6330. + *
  6331. + * Written by David McCullough <david_mccullough@mcafee.com>
  6332. + * Copyright (C) 2009-2010 David McCullough
  6333. + *
  6334. + * LICENSE TERMS
  6335. + *
  6336. + * The free distribution and use of this software in both source and binary
  6337. + * form is allowed (with or without changes) provided that:
  6338. + *
  6339. + * 1. distributions of this source code include the above copyright
  6340. + * notice, this list of conditions and the following disclaimer;
  6341. + *
  6342. + * 2. distributions in binary form include the above copyright
  6343. + * notice, this list of conditions and the following disclaimer
  6344. + * in the documentation and/or other associated materials;
  6345. + *
  6346. + * 3. the copyright holder's name is not used to endorse products
  6347. + * built using this software without specific written permission.
  6348. + *
  6349. + * DISCLAIMER
  6350. + *
  6351. + * This software is provided 'as is' with no explicit or implied warranties
  6352. + * in respect of its properties, including, but not limited to, correctness
  6353. + * and/or fitness for purpose.
  6354. + * ---------------------------------------------------------------------------
  6355. + */
  6356. +
  6357. +#ifndef AUTOCONF_INCLUDED
  6358. +#include <linux/config.h>
  6359. +#endif
  6360. +#include <linux/module.h>
  6361. +#include <linux/init.h>
  6362. +#include <linux/list.h>
  6363. +#include <linux/slab.h>
  6364. +#include <linux/sched.h>
  6365. +#include <linux/wait.h>
  6366. +#include <linux/crypto.h>
  6367. +#include <linux/mm.h>
  6368. +#include <linux/skbuff.h>
  6369. +#include <linux/random.h>
  6370. +#include <linux/scatterlist.h>
  6371. +
  6372. +#include <cryptodev.h>
  6373. +#include <uio.h>
  6374. +
  6375. +struct {
  6376. + softc_device_decl sc_dev;
  6377. +} octo_softc;
  6378. +
  6379. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  6380. +
  6381. +struct octo_sess {
  6382. + int octo_encalg;
  6383. + #define MAX_CIPHER_KEYLEN 64
  6384. + char octo_enckey[MAX_CIPHER_KEYLEN];
  6385. + int octo_encklen;
  6386. +
  6387. + int octo_macalg;
  6388. + #define MAX_HASH_KEYLEN 64
  6389. + char octo_mackey[MAX_HASH_KEYLEN];
  6390. + int octo_macklen;
  6391. + int octo_mackey_set;
  6392. +
  6393. + int octo_mlen;
  6394. + int octo_ivsize;
  6395. +
  6396. +#if 0
  6397. + int (*octo_decrypt)(struct scatterlist *sg, int sg_len,
  6398. + uint8_t *key, int key_len, uint8_t * iv,
  6399. + uint64_t *hminner, uint64_t *hmouter);
  6400. +
  6401. + int (*octo_encrypt)(struct scatterlist *sg, int sg_len,
  6402. + uint8_t *key, int key_len, uint8_t * iv,
  6403. + uint64_t *hminner, uint64_t *hmouter);
  6404. +#else
  6405. + int (*octo_encrypt)(struct octo_sess *od,
  6406. + struct scatterlist *sg, int sg_len,
  6407. + int auth_off, int auth_len,
  6408. + int crypt_off, int crypt_len,
  6409. + int icv_off, uint8_t *ivp);
  6410. + int (*octo_decrypt)(struct octo_sess *od,
  6411. + struct scatterlist *sg, int sg_len,
  6412. + int auth_off, int auth_len,
  6413. + int crypt_off, int crypt_len,
  6414. + int icv_off, uint8_t *ivp);
  6415. +#endif
  6416. +
  6417. + uint64_t octo_hminner[3];
  6418. + uint64_t octo_hmouter[3];
  6419. +};
  6420. +
  6421. +int32_t octo_id = -1;
  6422. +module_param(octo_id, int, 0444);
  6423. +MODULE_PARM_DESC(octo_id, "Read-Only OCF ID for cryptocteon driver");
  6424. +
  6425. +static struct octo_sess **octo_sessions = NULL;
  6426. +static u_int32_t octo_sesnum = 0;
  6427. +
  6428. +static int octo_process(device_t, struct cryptop *, int);
  6429. +static int octo_newsession(device_t, u_int32_t *, struct cryptoini *);
  6430. +static int octo_freesession(device_t, u_int64_t);
  6431. +
  6432. +static device_method_t octo_methods = {
  6433. + /* crypto device methods */
  6434. + DEVMETHOD(cryptodev_newsession, octo_newsession),
  6435. + DEVMETHOD(cryptodev_freesession,octo_freesession),
  6436. + DEVMETHOD(cryptodev_process, octo_process),
  6437. +};
  6438. +
  6439. +#define debug octo_debug
  6440. +int octo_debug = 0;
  6441. +module_param(octo_debug, int, 0644);
  6442. +MODULE_PARM_DESC(octo_debug, "Enable debug");
  6443. +
  6444. +
  6445. +#include "cavium_crypto.c"
  6446. +
  6447. +
  6448. +/*
  6449. + * Generate a new octo session. We artifically limit it to a single
  6450. + * hash/cipher or hash-cipher combo just to make it easier, most callers
  6451. + * do not expect more than this anyway.
  6452. + */
  6453. +static int
  6454. +octo_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  6455. +{
  6456. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  6457. + struct octo_sess **ocd;
  6458. + int i;
  6459. +
  6460. + dprintk("%s()\n", __FUNCTION__);
  6461. + if (sid == NULL || cri == NULL) {
  6462. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  6463. + return EINVAL;
  6464. + }
  6465. +
  6466. + /*
  6467. + * To keep it simple, we only handle hash, cipher or hash/cipher in a
  6468. + * session, you cannot currently do multiple ciphers/hashes in one
  6469. + * session even though it would be possibel to code this driver to
  6470. + * handle it.
  6471. + */
  6472. + for (i = 0, c = cri; c && i < 2; i++) {
  6473. + if (c->cri_alg == CRYPTO_MD5_HMAC ||
  6474. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  6475. + c->cri_alg == CRYPTO_NULL_HMAC) {
  6476. + if (macini) {
  6477. + break;
  6478. + }
  6479. + macini = c;
  6480. + }
  6481. + if (c->cri_alg == CRYPTO_DES_CBC ||
  6482. + c->cri_alg == CRYPTO_3DES_CBC ||
  6483. + c->cri_alg == CRYPTO_AES_CBC ||
  6484. + c->cri_alg == CRYPTO_NULL_CBC) {
  6485. + if (encini) {
  6486. + break;
  6487. + }
  6488. + encini = c;
  6489. + }
  6490. + c = c->cri_next;
  6491. + }
  6492. + if (!macini && !encini) {
  6493. + dprintk("%s,%d - EINVAL bad cipher/hash or combination\n",
  6494. + __FILE__, __LINE__);
  6495. + return EINVAL;
  6496. + }
  6497. + if (c) {
  6498. + dprintk("%s,%d - EINVAL cannot handle chained cipher/hash combos\n",
  6499. + __FILE__, __LINE__);
  6500. + return EINVAL;
  6501. + }
  6502. +
  6503. + /*
  6504. + * So we have something we can do, lets setup the session
  6505. + */
  6506. +
  6507. + if (octo_sessions) {
  6508. + for (i = 1; i < octo_sesnum; i++)
  6509. + if (octo_sessions[i] == NULL)
  6510. + break;
  6511. + } else
  6512. + i = 1; /* NB: to silence compiler warning */
  6513. +
  6514. + if (octo_sessions == NULL || i == octo_sesnum) {
  6515. + if (octo_sessions == NULL) {
  6516. + i = 1; /* We leave octo_sessions[0] empty */
  6517. + octo_sesnum = CRYPTO_SW_SESSIONS;
  6518. + } else
  6519. + octo_sesnum *= 2;
  6520. +
  6521. + ocd = kmalloc(octo_sesnum * sizeof(struct octo_sess *), SLAB_ATOMIC);
  6522. + if (ocd == NULL) {
  6523. + /* Reset session number */
  6524. + if (octo_sesnum == CRYPTO_SW_SESSIONS)
  6525. + octo_sesnum = 0;
  6526. + else
  6527. + octo_sesnum /= 2;
  6528. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  6529. + return ENOBUFS;
  6530. + }
  6531. + memset(ocd, 0, octo_sesnum * sizeof(struct octo_sess *));
  6532. +
  6533. + /* Copy existing sessions */
  6534. + if (octo_sessions) {
  6535. + memcpy(ocd, octo_sessions,
  6536. + (octo_sesnum / 2) * sizeof(struct octo_sess *));
  6537. + kfree(octo_sessions);
  6538. + }
  6539. +
  6540. + octo_sessions = ocd;
  6541. + }
  6542. +
  6543. + ocd = &octo_sessions[i];
  6544. + *sid = i;
  6545. +
  6546. +
  6547. + *ocd = (struct octo_sess *) kmalloc(sizeof(struct octo_sess), SLAB_ATOMIC);
  6548. + if (*ocd == NULL) {
  6549. + octo_freesession(NULL, i);
  6550. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  6551. + return ENOBUFS;
  6552. + }
  6553. + memset(*ocd, 0, sizeof(struct octo_sess));
  6554. +
  6555. + if (encini && encini->cri_key) {
  6556. + (*ocd)->octo_encklen = (encini->cri_klen + 7) / 8;
  6557. + memcpy((*ocd)->octo_enckey, encini->cri_key, (*ocd)->octo_encklen);
  6558. + }
  6559. +
  6560. + if (macini && macini->cri_key) {
  6561. + (*ocd)->octo_macklen = (macini->cri_klen + 7) / 8;
  6562. + memcpy((*ocd)->octo_mackey, macini->cri_key, (*ocd)->octo_macklen);
  6563. + }
  6564. +
  6565. + (*ocd)->octo_mlen = 0;
  6566. + if (encini && encini->cri_mlen)
  6567. + (*ocd)->octo_mlen = encini->cri_mlen;
  6568. + else if (macini && macini->cri_mlen)
  6569. + (*ocd)->octo_mlen = macini->cri_mlen;
  6570. + else
  6571. + (*ocd)->octo_mlen = 12;
  6572. +
  6573. + /*
  6574. + * point c at the enc if it exists, otherwise the mac
  6575. + */
  6576. + c = encini ? encini : macini;
  6577. +
  6578. + switch (c->cri_alg) {
  6579. + case CRYPTO_DES_CBC:
  6580. + case CRYPTO_3DES_CBC:
  6581. + (*ocd)->octo_ivsize = 8;
  6582. + switch (macini ? macini->cri_alg : -1) {
  6583. + case CRYPTO_MD5_HMAC:
  6584. + (*ocd)->octo_encrypt = octo_des_cbc_md5_encrypt;
  6585. + (*ocd)->octo_decrypt = octo_des_cbc_md5_decrypt;
  6586. + octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
  6587. + (*ocd)->octo_hmouter);
  6588. + break;
  6589. + case CRYPTO_SHA1_HMAC:
  6590. + (*ocd)->octo_encrypt = octo_des_cbc_sha1_encrypt;
  6591. + (*ocd)->octo_decrypt = octo_des_cbc_sha1_encrypt;
  6592. + octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
  6593. + (*ocd)->octo_hmouter);
  6594. + break;
  6595. + case -1:
  6596. + (*ocd)->octo_encrypt = octo_des_cbc_encrypt;
  6597. + (*ocd)->octo_decrypt = octo_des_cbc_decrypt;
  6598. + break;
  6599. + default:
  6600. + octo_freesession(NULL, i);
  6601. + dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
  6602. + return EINVAL;
  6603. + }
  6604. + break;
  6605. + case CRYPTO_AES_CBC:
  6606. + (*ocd)->octo_ivsize = 16;
  6607. + switch (macini ? macini->cri_alg : -1) {
  6608. + case CRYPTO_MD5_HMAC:
  6609. + (*ocd)->octo_encrypt = octo_aes_cbc_md5_encrypt;
  6610. + (*ocd)->octo_decrypt = octo_aes_cbc_md5_decrypt;
  6611. + octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
  6612. + (*ocd)->octo_hmouter);
  6613. + break;
  6614. + case CRYPTO_SHA1_HMAC:
  6615. + (*ocd)->octo_encrypt = octo_aes_cbc_sha1_encrypt;
  6616. + (*ocd)->octo_decrypt = octo_aes_cbc_sha1_decrypt;
  6617. + octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
  6618. + (*ocd)->octo_hmouter);
  6619. + break;
  6620. + case -1:
  6621. + (*ocd)->octo_encrypt = octo_aes_cbc_encrypt;
  6622. + (*ocd)->octo_decrypt = octo_aes_cbc_decrypt;
  6623. + break;
  6624. + default:
  6625. + octo_freesession(NULL, i);
  6626. + dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
  6627. + return EINVAL;
  6628. + }
  6629. + break;
  6630. + case CRYPTO_MD5_HMAC:
  6631. + (*ocd)->octo_encrypt = octo_null_md5_encrypt;
  6632. + (*ocd)->octo_decrypt = octo_null_md5_encrypt;
  6633. + octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
  6634. + (*ocd)->octo_hmouter);
  6635. + break;
  6636. + case CRYPTO_SHA1_HMAC:
  6637. + (*ocd)->octo_encrypt = octo_null_sha1_encrypt;
  6638. + (*ocd)->octo_decrypt = octo_null_sha1_encrypt;
  6639. + octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
  6640. + (*ocd)->octo_hmouter);
  6641. + break;
  6642. + default:
  6643. + octo_freesession(NULL, i);
  6644. + dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
  6645. + return EINVAL;
  6646. + }
  6647. +
  6648. + (*ocd)->octo_encalg = encini ? encini->cri_alg : -1;
  6649. + (*ocd)->octo_macalg = macini ? macini->cri_alg : -1;
  6650. +
  6651. + return 0;
  6652. +}
  6653. +
  6654. +/*
  6655. + * Free a session.
  6656. + */
  6657. +static int
  6658. +octo_freesession(device_t dev, u_int64_t tid)
  6659. +{
  6660. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  6661. +
  6662. + dprintk("%s()\n", __FUNCTION__);
  6663. + if (sid > octo_sesnum || octo_sessions == NULL ||
  6664. + octo_sessions[sid] == NULL) {
  6665. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  6666. + return(EINVAL);
  6667. + }
  6668. +
  6669. + /* Silently accept and return */
  6670. + if (sid == 0)
  6671. + return(0);
  6672. +
  6673. + if (octo_sessions[sid])
  6674. + kfree(octo_sessions[sid]);
  6675. + octo_sessions[sid] = NULL;
  6676. + return 0;
  6677. +}
  6678. +
  6679. +/*
  6680. + * Process a request.
  6681. + */
  6682. +static int
  6683. +octo_process(device_t dev, struct cryptop *crp, int hint)
  6684. +{
  6685. + struct cryptodesc *crd;
  6686. + struct octo_sess *od;
  6687. + u_int32_t lid;
  6688. +#define SCATTERLIST_MAX 16
  6689. + struct scatterlist sg[SCATTERLIST_MAX];
  6690. + int sg_num, sg_len;
  6691. + struct sk_buff *skb = NULL;
  6692. + struct uio *uiop = NULL;
  6693. + struct cryptodesc *enccrd = NULL, *maccrd = NULL;
  6694. + unsigned char *ivp = NULL;
  6695. + unsigned char iv_data[HASH_MAX_LEN];
  6696. + int auth_off = 0, auth_len = 0, crypt_off = 0, crypt_len = 0, icv_off = 0;
  6697. +
  6698. + dprintk("%s()\n", __FUNCTION__);
  6699. + /* Sanity check */
  6700. + if (crp == NULL) {
  6701. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  6702. + return EINVAL;
  6703. + }
  6704. +
  6705. + crp->crp_etype = 0;
  6706. +
  6707. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  6708. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  6709. + crp->crp_etype = EINVAL;
  6710. + goto done;
  6711. + }
  6712. +
  6713. + lid = crp->crp_sid & 0xffffffff;
  6714. + if (lid >= octo_sesnum || lid == 0 || octo_sessions == NULL ||
  6715. + octo_sessions[lid] == NULL) {
  6716. + crp->crp_etype = ENOENT;
  6717. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  6718. + goto done;
  6719. + }
  6720. + od = octo_sessions[lid];
  6721. +
  6722. + /*
  6723. + * do some error checking outside of the loop for SKB and IOV processing
  6724. + * this leaves us with valid skb or uiop pointers for later
  6725. + */
  6726. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  6727. + skb = (struct sk_buff *) crp->crp_buf;
  6728. + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
  6729. + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
  6730. + skb_shinfo(skb)->nr_frags);
  6731. + goto done;
  6732. + }
  6733. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  6734. + uiop = (struct uio *) crp->crp_buf;
  6735. + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
  6736. + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
  6737. + uiop->uio_iovcnt);
  6738. + goto done;
  6739. + }
  6740. + }
  6741. +
  6742. + /* point our enccrd and maccrd appropriately */
  6743. + crd = crp->crp_desc;
  6744. + if (crd->crd_alg == od->octo_encalg) enccrd = crd;
  6745. + if (crd->crd_alg == od->octo_macalg) maccrd = crd;
  6746. + crd = crd->crd_next;
  6747. + if (crd) {
  6748. + if (crd->crd_alg == od->octo_encalg) enccrd = crd;
  6749. + if (crd->crd_alg == od->octo_macalg) maccrd = crd;
  6750. + crd = crd->crd_next;
  6751. + }
  6752. + if (crd) {
  6753. + crp->crp_etype = EINVAL;
  6754. + dprintk("%s,%d: ENOENT - descriptors do not match session\n",
  6755. + __FILE__, __LINE__);
  6756. + goto done;
  6757. + }
  6758. +
  6759. + if (enccrd) {
  6760. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  6761. + ivp = enccrd->crd_iv;
  6762. + } else {
  6763. + ivp = iv_data;
  6764. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  6765. + enccrd->crd_inject, od->octo_ivsize, (caddr_t) ivp);
  6766. + }
  6767. +
  6768. + if (maccrd) {
  6769. + auth_off = maccrd->crd_skip;
  6770. + auth_len = maccrd->crd_len;
  6771. + icv_off = maccrd->crd_inject;
  6772. + }
  6773. +
  6774. + crypt_off = enccrd->crd_skip;
  6775. + crypt_len = enccrd->crd_len;
  6776. + } else { /* if (maccrd) */
  6777. + auth_off = maccrd->crd_skip;
  6778. + auth_len = maccrd->crd_len;
  6779. + icv_off = maccrd->crd_inject;
  6780. + }
  6781. +
  6782. +
  6783. + /*
  6784. + * setup the SG list to cover the buffer
  6785. + */
  6786. + memset(sg, 0, sizeof(sg));
  6787. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  6788. + int i, len;
  6789. +
  6790. + sg_num = 0;
  6791. + sg_len = 0;
  6792. +
  6793. + len = skb_headlen(skb);
  6794. + sg_set_page(&sg[sg_num], virt_to_page(skb->data), len,
  6795. + offset_in_page(skb->data));
  6796. + sg_len += len;
  6797. + sg_num++;
  6798. +
  6799. + for (i = 0; i < skb_shinfo(skb)->nr_frags && sg_num < SCATTERLIST_MAX;
  6800. + i++) {
  6801. + len = skb_shinfo(skb)->frags[i].size;
  6802. + sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page,
  6803. + len, skb_shinfo(skb)->frags[i].page_offset);
  6804. + sg_len += len;
  6805. + sg_num++;
  6806. + }
  6807. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  6808. + int len;
  6809. +
  6810. + sg_len = 0;
  6811. + for (sg_num = 0; sg_len < crp->crp_ilen &&
  6812. + sg_num < uiop->uio_iovcnt &&
  6813. + sg_num < SCATTERLIST_MAX; sg_num++) {
  6814. + len = uiop->uio_iov[sg_num].iov_len;
  6815. + sg_set_page(&sg[sg_num],
  6816. + virt_to_page(uiop->uio_iov[sg_num].iov_base), len,
  6817. + offset_in_page(uiop->uio_iov[sg_num].iov_base));
  6818. + sg_len += len;
  6819. + }
  6820. + } else {
  6821. + sg_len = crp->crp_ilen;
  6822. + sg_set_page(&sg[0], virt_to_page(crp->crp_buf), sg_len,
  6823. + offset_in_page(crp->crp_buf));
  6824. + sg_num = 1;
  6825. + }
  6826. +
  6827. +
  6828. + /*
  6829. + * setup a new explicit key
  6830. + */
  6831. + if (enccrd) {
  6832. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  6833. + od->octo_encklen = (enccrd->crd_klen + 7) / 8;
  6834. + memcpy(od->octo_enckey, enccrd->crd_key, od->octo_encklen);
  6835. + }
  6836. + }
  6837. + if (maccrd) {
  6838. + if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  6839. + od->octo_macklen = (maccrd->crd_klen + 7) / 8;
  6840. + memcpy(od->octo_mackey, maccrd->crd_key, od->octo_macklen);
  6841. + od->octo_mackey_set = 0;
  6842. + }
  6843. + if (!od->octo_mackey_set) {
  6844. + octo_calc_hash(maccrd->crd_alg == CRYPTO_MD5_HMAC ? 0 : 1,
  6845. + maccrd->crd_key, od->octo_hminner, od->octo_hmouter);
  6846. + od->octo_mackey_set = 1;
  6847. + }
  6848. + }
  6849. +
  6850. +
  6851. + if (!enccrd || (enccrd->crd_flags & CRD_F_ENCRYPT))
  6852. + (*od->octo_encrypt)(od, sg, sg_len,
  6853. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  6854. + else
  6855. + (*od->octo_decrypt)(od, sg, sg_len,
  6856. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  6857. +
  6858. +done:
  6859. + crypto_done(crp);
  6860. + return 0;
  6861. +}
  6862. +
  6863. +static int
  6864. +cryptocteon_init(void)
  6865. +{
  6866. + dprintk("%s(%p)\n", __FUNCTION__, cryptocteon_init);
  6867. +
  6868. + softc_device_init(&octo_softc, "cryptocteon", 0, octo_methods);
  6869. +
  6870. + octo_id = crypto_get_driverid(softc_get_device(&octo_softc),
  6871. + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SYNC);
  6872. + if (octo_id < 0) {
  6873. + printk("Cryptocteon device cannot initialize!");
  6874. + return -ENODEV;
  6875. + }
  6876. +
  6877. + crypto_register(octo_id, CRYPTO_MD5_HMAC, 0,0);
  6878. + crypto_register(octo_id, CRYPTO_SHA1_HMAC, 0,0);
  6879. + //crypto_register(octo_id, CRYPTO_MD5, 0,0);
  6880. + //crypto_register(octo_id, CRYPTO_SHA1, 0,0);
  6881. + crypto_register(octo_id, CRYPTO_DES_CBC, 0,0);
  6882. + crypto_register(octo_id, CRYPTO_3DES_CBC, 0,0);
  6883. + crypto_register(octo_id, CRYPTO_AES_CBC, 0,0);
  6884. +
  6885. + return(0);
  6886. +}
  6887. +
  6888. +static void
  6889. +cryptocteon_exit(void)
  6890. +{
  6891. + dprintk("%s()\n", __FUNCTION__);
  6892. + crypto_unregister_all(octo_id);
  6893. + octo_id = -1;
  6894. +}
  6895. +
  6896. +module_init(cryptocteon_init);
  6897. +module_exit(cryptocteon_exit);
  6898. +
  6899. +MODULE_LICENSE("BSD");
  6900. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  6901. +MODULE_DESCRIPTION("Cryptocteon (OCF module for Cavium OCTEON crypto)");
  6902. diff -Nur linux-2.6.39.orig/crypto/ocf/cryptocteon/Makefile linux-2.6.39/crypto/ocf/cryptocteon/Makefile
  6903. --- linux-2.6.39.orig/crypto/ocf/cryptocteon/Makefile 1970-01-01 01:00:00.000000000 +0100
  6904. +++ linux-2.6.39/crypto/ocf/cryptocteon/Makefile 2011-07-31 11:31:53.633421731 +0200
  6905. @@ -0,0 +1,17 @@
  6906. +# for SGlinux builds
  6907. +-include $(ROOTDIR)/modules/.config
  6908. +
  6909. +obj-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon.o
  6910. +
  6911. +obj ?= .
  6912. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  6913. +
  6914. +ifdef CONFIG_OCF_CRYPTOCTEON
  6915. +# you need the cavium crypto component installed
  6916. +EXTRA_CFLAGS += -I$(ROOTDIR)/prop/include
  6917. +endif
  6918. +
  6919. +ifdef TOPDIR
  6920. +-include $(TOPDIR)/Rules.make
  6921. +endif
  6922. +
  6923. diff -Nur linux-2.6.39.orig/crypto/ocf/cryptodev.c linux-2.6.39/crypto/ocf/cryptodev.c
  6924. --- linux-2.6.39.orig/crypto/ocf/cryptodev.c 1970-01-01 01:00:00.000000000 +0100
  6925. +++ linux-2.6.39/crypto/ocf/cryptodev.c 2011-07-31 11:31:53.693904315 +0200
  6926. @@ -0,0 +1,1060 @@
  6927. +/* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */
  6928. +
  6929. +/*-
  6930. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  6931. + * Copyright (C) 2006-2010 David McCullough
  6932. + * Copyright (C) 2004-2005 Intel Corporation.
  6933. + * The license and original author are listed below.
  6934. + *
  6935. + * Copyright (c) 2001 Theo de Raadt
  6936. + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
  6937. + *
  6938. + * Redistribution and use in source and binary forms, with or without
  6939. + * modification, are permitted provided that the following conditions
  6940. + * are met:
  6941. + *
  6942. + * 1. Redistributions of source code must retain the above copyright
  6943. + * notice, this list of conditions and the following disclaimer.
  6944. + * 2. Redistributions in binary form must reproduce the above copyright
  6945. + * notice, this list of conditions and the following disclaimer in the
  6946. + * documentation and/or other materials provided with the distribution.
  6947. + * 3. The name of the author may not be used to endorse or promote products
  6948. + * derived from this software without specific prior written permission.
  6949. + *
  6950. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  6951. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  6952. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  6953. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  6954. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  6955. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  6956. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  6957. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  6958. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  6959. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  6960. + *
  6961. + * Effort sponsored in part by the Defense Advanced Research Projects
  6962. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  6963. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  6964. + *
  6965. +__FBSDID("$FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.34 2007/05/09 19:37:02 gnn Exp $");
  6966. + */
  6967. +
  6968. +#ifndef AUTOCONF_INCLUDED
  6969. +#include <linux/config.h>
  6970. +#endif
  6971. +#include <linux/types.h>
  6972. +#include <linux/time.h>
  6973. +#include <linux/delay.h>
  6974. +#include <linux/list.h>
  6975. +#include <linux/init.h>
  6976. +#include <linux/sched.h>
  6977. +#include <linux/unistd.h>
  6978. +#include <linux/module.h>
  6979. +#include <linux/wait.h>
  6980. +#include <linux/slab.h>
  6981. +#include <linux/fs.h>
  6982. +#include <linux/dcache.h>
  6983. +#include <linux/file.h>
  6984. +#include <linux/mount.h>
  6985. +#include <linux/miscdevice.h>
  6986. +#include <linux/version.h>
  6987. +#include <asm/uaccess.h>
  6988. +
  6989. +#include <cryptodev.h>
  6990. +#include <uio.h>
  6991. +
  6992. +extern asmlinkage long sys_dup(unsigned int fildes);
  6993. +
  6994. +#define debug cryptodev_debug
  6995. +int cryptodev_debug = 0;
  6996. +module_param(cryptodev_debug, int, 0644);
  6997. +MODULE_PARM_DESC(cryptodev_debug, "Enable cryptodev debug");
  6998. +
  6999. +struct csession_info {
  7000. + u_int16_t blocksize;
  7001. + u_int16_t minkey, maxkey;
  7002. +
  7003. + u_int16_t keysize;
  7004. + /* u_int16_t hashsize; */
  7005. + u_int16_t authsize;
  7006. + u_int16_t authkey;
  7007. + /* u_int16_t ctxsize; */
  7008. +};
  7009. +
  7010. +struct csession {
  7011. + struct list_head list;
  7012. + u_int64_t sid;
  7013. + u_int32_t ses;
  7014. +
  7015. + wait_queue_head_t waitq;
  7016. +
  7017. + u_int32_t cipher;
  7018. +
  7019. + u_int32_t mac;
  7020. +
  7021. + caddr_t key;
  7022. + int keylen;
  7023. + u_char tmp_iv[EALG_MAX_BLOCK_LEN];
  7024. +
  7025. + caddr_t mackey;
  7026. + int mackeylen;
  7027. +
  7028. + struct csession_info info;
  7029. +
  7030. + struct iovec iovec;
  7031. + struct uio uio;
  7032. + int error;
  7033. +};
  7034. +
  7035. +struct fcrypt {
  7036. + struct list_head csessions;
  7037. + int sesn;
  7038. +};
  7039. +
  7040. +static struct csession *csefind(struct fcrypt *, u_int);
  7041. +static int csedelete(struct fcrypt *, struct csession *);
  7042. +static struct csession *cseadd(struct fcrypt *, struct csession *);
  7043. +static struct csession *csecreate(struct fcrypt *, u_int64_t,
  7044. + struct cryptoini *crie, struct cryptoini *cria, struct csession_info *);
  7045. +static int csefree(struct csession *);
  7046. +
  7047. +static int cryptodev_op(struct csession *, struct crypt_op *);
  7048. +static int cryptodev_key(struct crypt_kop *);
  7049. +static int cryptodev_find(struct crypt_find_op *);
  7050. +
  7051. +static int cryptodev_cb(void *);
  7052. +static int cryptodev_open(struct inode *inode, struct file *filp);
  7053. +
  7054. +/*
  7055. + * Check a crypto identifier to see if it requested
  7056. + * a valid crid and it's capabilities match.
  7057. + */
  7058. +static int
  7059. +checkcrid(int crid)
  7060. +{
  7061. + int hid = crid & ~(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
  7062. + int typ = crid & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
  7063. + int caps = 0;
  7064. +
  7065. + /* if the user hasn't selected a driver, then just call newsession */
  7066. + if (hid == 0 && typ != 0)
  7067. + return 0;
  7068. +
  7069. + caps = crypto_getcaps(hid);
  7070. +
  7071. + /* didn't find anything with capabilities */
  7072. + if (caps == 0) {
  7073. + dprintk("%s: hid=%x typ=%x not matched\n", __FUNCTION__, hid, typ);
  7074. + return EINVAL;
  7075. + }
  7076. +
  7077. + /* the user didn't specify SW or HW, so the driver is ok */
  7078. + if (typ == 0)
  7079. + return 0;
  7080. +
  7081. + /* if the type specified didn't match */
  7082. + if (typ != (caps & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE))) {
  7083. + dprintk("%s: hid=%x typ=%x caps=%x not matched\n", __FUNCTION__,
  7084. + hid, typ, caps);
  7085. + return EINVAL;
  7086. + }
  7087. +
  7088. + return 0;
  7089. +}
  7090. +
  7091. +static int
  7092. +cryptodev_op(struct csession *cse, struct crypt_op *cop)
  7093. +{
  7094. + struct cryptop *crp = NULL;
  7095. + struct cryptodesc *crde = NULL, *crda = NULL;
  7096. + int error = 0;
  7097. +
  7098. + dprintk("%s()\n", __FUNCTION__);
  7099. + if (cop->len > CRYPTO_MAX_DATA_LEN) {
  7100. + dprintk("%s: %d > %d\n", __FUNCTION__, cop->len, CRYPTO_MAX_DATA_LEN);
  7101. + return (E2BIG);
  7102. + }
  7103. +
  7104. + if (cse->info.blocksize && (cop->len % cse->info.blocksize) != 0) {
  7105. + dprintk("%s: blocksize=%d len=%d\n", __FUNCTION__, cse->info.blocksize,
  7106. + cop->len);
  7107. + return (EINVAL);
  7108. + }
  7109. +
  7110. + cse->uio.uio_iov = &cse->iovec;
  7111. + cse->uio.uio_iovcnt = 1;
  7112. + cse->uio.uio_offset = 0;
  7113. +#if 0
  7114. + cse->uio.uio_resid = cop->len;
  7115. + cse->uio.uio_segflg = UIO_SYSSPACE;
  7116. + cse->uio.uio_rw = UIO_WRITE;
  7117. + cse->uio.uio_td = td;
  7118. +#endif
  7119. + cse->uio.uio_iov[0].iov_len = cop->len;
  7120. + if (cse->info.authsize)
  7121. + cse->uio.uio_iov[0].iov_len += cse->info.authsize;
  7122. + cse->uio.uio_iov[0].iov_base = kmalloc(cse->uio.uio_iov[0].iov_len,
  7123. + GFP_KERNEL);
  7124. +
  7125. + if (cse->uio.uio_iov[0].iov_base == NULL) {
  7126. + dprintk("%s: iov_base kmalloc(%d) failed\n", __FUNCTION__,
  7127. + (int)cse->uio.uio_iov[0].iov_len);
  7128. + return (ENOMEM);
  7129. + }
  7130. +
  7131. + crp = crypto_getreq((cse->info.blocksize != 0) + (cse->info.authsize != 0));
  7132. + if (crp == NULL) {
  7133. + dprintk("%s: ENOMEM\n", __FUNCTION__);
  7134. + error = ENOMEM;
  7135. + goto bail;
  7136. + }
  7137. +
  7138. + if (cse->info.authsize && cse->info.blocksize) {
  7139. + if (cop->op == COP_ENCRYPT) {
  7140. + crde = crp->crp_desc;
  7141. + crda = crde->crd_next;
  7142. + } else {
  7143. + crda = crp->crp_desc;
  7144. + crde = crda->crd_next;
  7145. + }
  7146. + } else if (cse->info.authsize) {
  7147. + crda = crp->crp_desc;
  7148. + } else if (cse->info.blocksize) {
  7149. + crde = crp->crp_desc;
  7150. + } else {
  7151. + dprintk("%s: bad request\n", __FUNCTION__);
  7152. + error = EINVAL;
  7153. + goto bail;
  7154. + }
  7155. +
  7156. + if ((error = copy_from_user(cse->uio.uio_iov[0].iov_base, cop->src,
  7157. + cop->len))) {
  7158. + dprintk("%s: bad copy\n", __FUNCTION__);
  7159. + goto bail;
  7160. + }
  7161. +
  7162. + if (crda) {
  7163. + crda->crd_skip = 0;
  7164. + crda->crd_len = cop->len;
  7165. + crda->crd_inject = cop->len;
  7166. +
  7167. + crda->crd_alg = cse->mac;
  7168. + crda->crd_key = cse->mackey;
  7169. + crda->crd_klen = cse->mackeylen * 8;
  7170. + }
  7171. +
  7172. + if (crde) {
  7173. + if (cop->op == COP_ENCRYPT)
  7174. + crde->crd_flags |= CRD_F_ENCRYPT;
  7175. + else
  7176. + crde->crd_flags &= ~CRD_F_ENCRYPT;
  7177. + crde->crd_len = cop->len;
  7178. + crde->crd_inject = 0;
  7179. +
  7180. + crde->crd_alg = cse->cipher;
  7181. + crde->crd_key = cse->key;
  7182. + crde->crd_klen = cse->keylen * 8;
  7183. + }
  7184. +
  7185. + crp->crp_ilen = cse->uio.uio_iov[0].iov_len;
  7186. + crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
  7187. + | (cop->flags & COP_F_BATCH);
  7188. + crp->crp_buf = (caddr_t)&cse->uio;
  7189. + crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;
  7190. + crp->crp_sid = cse->sid;
  7191. + crp->crp_opaque = (void *)cse;
  7192. +
  7193. + if (cop->iv) {
  7194. + if (crde == NULL) {
  7195. + error = EINVAL;
  7196. + dprintk("%s no crde\n", __FUNCTION__);
  7197. + goto bail;
  7198. + }
  7199. + if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  7200. + error = EINVAL;
  7201. + dprintk("%s arc4 with IV\n", __FUNCTION__);
  7202. + goto bail;
  7203. + }
  7204. + if ((error = copy_from_user(cse->tmp_iv, cop->iv,
  7205. + cse->info.blocksize))) {
  7206. + dprintk("%s bad iv copy\n", __FUNCTION__);
  7207. + goto bail;
  7208. + }
  7209. + memcpy(crde->crd_iv, cse->tmp_iv, cse->info.blocksize);
  7210. + crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
  7211. + crde->crd_skip = 0;
  7212. + } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  7213. + crde->crd_skip = 0;
  7214. + } else if (crde) {
  7215. + crde->crd_flags |= CRD_F_IV_PRESENT;
  7216. + crde->crd_skip = cse->info.blocksize;
  7217. + crde->crd_len -= cse->info.blocksize;
  7218. + }
  7219. +
  7220. + if (cop->mac && crda == NULL) {
  7221. + error = EINVAL;
  7222. + dprintk("%s no crda\n", __FUNCTION__);
  7223. + goto bail;
  7224. + }
  7225. +
  7226. + /*
  7227. + * Let the dispatch run unlocked, then, interlock against the
  7228. + * callback before checking if the operation completed and going
  7229. + * to sleep. This insures drivers don't inherit our lock which
  7230. + * results in a lock order reversal between crypto_dispatch forced
  7231. + * entry and the crypto_done callback into us.
  7232. + */
  7233. + error = crypto_dispatch(crp);
  7234. + if (error) {
  7235. + dprintk("%s error in crypto_dispatch\n", __FUNCTION__);
  7236. + goto bail;
  7237. + }
  7238. +
  7239. + dprintk("%s about to WAIT\n", __FUNCTION__);
  7240. + /*
  7241. + * we really need to wait for driver to complete to maintain
  7242. + * state, luckily interrupts will be remembered
  7243. + */
  7244. + do {
  7245. + error = wait_event_interruptible(crp->crp_waitq,
  7246. + ((crp->crp_flags & CRYPTO_F_DONE) != 0));
  7247. + /*
  7248. + * we can't break out of this loop or we will leave behind
  7249. + * a huge mess, however, staying here means if your driver
  7250. + * is broken user applications can hang and not be killed.
  7251. + * The solution, fix your driver :-)
  7252. + */
  7253. + if (error) {
  7254. + schedule();
  7255. + error = 0;
  7256. + }
  7257. + } while ((crp->crp_flags & CRYPTO_F_DONE) == 0);
  7258. + dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
  7259. +
  7260. + if (crp->crp_etype != 0) {
  7261. + error = crp->crp_etype;
  7262. + dprintk("%s error in crp processing\n", __FUNCTION__);
  7263. + goto bail;
  7264. + }
  7265. +
  7266. + if (cse->error) {
  7267. + error = cse->error;
  7268. + dprintk("%s error in cse processing\n", __FUNCTION__);
  7269. + goto bail;
  7270. + }
  7271. +
  7272. + if (cop->dst && (error = copy_to_user(cop->dst,
  7273. + cse->uio.uio_iov[0].iov_base, cop->len))) {
  7274. + dprintk("%s bad dst copy\n", __FUNCTION__);
  7275. + goto bail;
  7276. + }
  7277. +
  7278. + if (cop->mac &&
  7279. + (error=copy_to_user(cop->mac,
  7280. + (caddr_t)cse->uio.uio_iov[0].iov_base + cop->len,
  7281. + cse->info.authsize))) {
  7282. + dprintk("%s bad mac copy\n", __FUNCTION__);
  7283. + goto bail;
  7284. + }
  7285. +
  7286. +bail:
  7287. + if (crp)
  7288. + crypto_freereq(crp);
  7289. + if (cse->uio.uio_iov[0].iov_base)
  7290. + kfree(cse->uio.uio_iov[0].iov_base);
  7291. +
  7292. + return (error);
  7293. +}
  7294. +
  7295. +static int
  7296. +cryptodev_cb(void *op)
  7297. +{
  7298. + struct cryptop *crp = (struct cryptop *) op;
  7299. + struct csession *cse = (struct csession *)crp->crp_opaque;
  7300. + int error;
  7301. +
  7302. + dprintk("%s()\n", __FUNCTION__);
  7303. + error = crp->crp_etype;
  7304. + if (error == EAGAIN) {
  7305. + crp->crp_flags &= ~CRYPTO_F_DONE;
  7306. +#ifdef NOTYET
  7307. + /*
  7308. + * DAVIDM I am fairly sure that we should turn this into a batch
  7309. + * request to stop bad karma/lockup, revisit
  7310. + */
  7311. + crp->crp_flags |= CRYPTO_F_BATCH;
  7312. +#endif
  7313. + return crypto_dispatch(crp);
  7314. + }
  7315. + if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
  7316. + cse->error = error;
  7317. + wake_up_interruptible(&crp->crp_waitq);
  7318. + }
  7319. + return (0);
  7320. +}
  7321. +
  7322. +static int
  7323. +cryptodevkey_cb(void *op)
  7324. +{
  7325. + struct cryptkop *krp = (struct cryptkop *) op;
  7326. + dprintk("%s()\n", __FUNCTION__);
  7327. + wake_up_interruptible(&krp->krp_waitq);
  7328. + return (0);
  7329. +}
  7330. +
  7331. +static int
  7332. +cryptodev_key(struct crypt_kop *kop)
  7333. +{
  7334. + struct cryptkop *krp = NULL;
  7335. + int error = EINVAL;
  7336. + int in, out, size, i;
  7337. +
  7338. + dprintk("%s()\n", __FUNCTION__);
  7339. + if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
  7340. + dprintk("%s params too big\n", __FUNCTION__);
  7341. + return (EFBIG);
  7342. + }
  7343. +
  7344. + in = kop->crk_iparams;
  7345. + out = kop->crk_oparams;
  7346. + switch (kop->crk_op) {
  7347. + case CRK_MOD_EXP:
  7348. + if (in == 3 && out == 1)
  7349. + break;
  7350. + return (EINVAL);
  7351. + case CRK_MOD_EXP_CRT:
  7352. + if (in == 6 && out == 1)
  7353. + break;
  7354. + return (EINVAL);
  7355. + case CRK_DSA_SIGN:
  7356. + if (in == 5 && out == 2)
  7357. + break;
  7358. + return (EINVAL);
  7359. + case CRK_DSA_VERIFY:
  7360. + if (in == 7 && out == 0)
  7361. + break;
  7362. + return (EINVAL);
  7363. + case CRK_DH_COMPUTE_KEY:
  7364. + if (in == 3 && out == 1)
  7365. + break;
  7366. + return (EINVAL);
  7367. + default:
  7368. + return (EINVAL);
  7369. + }
  7370. +
  7371. + krp = (struct cryptkop *)kmalloc(sizeof *krp, GFP_KERNEL);
  7372. + if (!krp)
  7373. + return (ENOMEM);
  7374. + bzero(krp, sizeof *krp);
  7375. + krp->krp_op = kop->crk_op;
  7376. + krp->krp_status = kop->crk_status;
  7377. + krp->krp_iparams = kop->crk_iparams;
  7378. + krp->krp_oparams = kop->crk_oparams;
  7379. + krp->krp_crid = kop->crk_crid;
  7380. + krp->krp_status = 0;
  7381. + krp->krp_flags = CRYPTO_KF_CBIMM;
  7382. + krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
  7383. + init_waitqueue_head(&krp->krp_waitq);
  7384. +
  7385. + for (i = 0; i < CRK_MAXPARAM; i++)
  7386. + krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
  7387. + for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
  7388. + size = (krp->krp_param[i].crp_nbits + 7) / 8;
  7389. + if (size == 0)
  7390. + continue;
  7391. + krp->krp_param[i].crp_p = (caddr_t) kmalloc(size, GFP_KERNEL);
  7392. + if (i >= krp->krp_iparams)
  7393. + continue;
  7394. + error = copy_from_user(krp->krp_param[i].crp_p,
  7395. + kop->crk_param[i].crp_p, size);
  7396. + if (error)
  7397. + goto fail;
  7398. + }
  7399. +
  7400. + error = crypto_kdispatch(krp);
  7401. + if (error)
  7402. + goto fail;
  7403. +
  7404. + do {
  7405. + error = wait_event_interruptible(krp->krp_waitq,
  7406. + ((krp->krp_flags & CRYPTO_KF_DONE) != 0));
  7407. + /*
  7408. + * we can't break out of this loop or we will leave behind
  7409. + * a huge mess, however, staying here means if your driver
  7410. + * is broken user applications can hang and not be killed.
  7411. + * The solution, fix your driver :-)
  7412. + */
  7413. + if (error) {
  7414. + schedule();
  7415. + error = 0;
  7416. + }
  7417. + } while ((krp->krp_flags & CRYPTO_KF_DONE) == 0);
  7418. +
  7419. + dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
  7420. +
  7421. + kop->crk_crid = krp->krp_crid; /* device that did the work */
  7422. + if (krp->krp_status != 0) {
  7423. + error = krp->krp_status;
  7424. + goto fail;
  7425. + }
  7426. +
  7427. + for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
  7428. + size = (krp->krp_param[i].crp_nbits + 7) / 8;
  7429. + if (size == 0)
  7430. + continue;
  7431. + error = copy_to_user(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p,
  7432. + size);
  7433. + if (error)
  7434. + goto fail;
  7435. + }
  7436. +
  7437. +fail:
  7438. + if (krp) {
  7439. + kop->crk_status = krp->krp_status;
  7440. + for (i = 0; i < CRK_MAXPARAM; i++) {
  7441. + if (krp->krp_param[i].crp_p)
  7442. + kfree(krp->krp_param[i].crp_p);
  7443. + }
  7444. + kfree(krp);
  7445. + }
  7446. + return (error);
  7447. +}
  7448. +
  7449. +static int
  7450. +cryptodev_find(struct crypt_find_op *find)
  7451. +{
  7452. + device_t dev;
  7453. +
  7454. + if (find->crid != -1) {
  7455. + dev = crypto_find_device_byhid(find->crid);
  7456. + if (dev == NULL)
  7457. + return (ENOENT);
  7458. + strlcpy(find->name, device_get_nameunit(dev),
  7459. + sizeof(find->name));
  7460. + } else {
  7461. + find->crid = crypto_find_driver(find->name);
  7462. + if (find->crid == -1)
  7463. + return (ENOENT);
  7464. + }
  7465. + return (0);
  7466. +}
  7467. +
  7468. +static struct csession *
  7469. +csefind(struct fcrypt *fcr, u_int ses)
  7470. +{
  7471. + struct csession *cse;
  7472. +
  7473. + dprintk("%s()\n", __FUNCTION__);
  7474. + list_for_each_entry(cse, &fcr->csessions, list)
  7475. + if (cse->ses == ses)
  7476. + return (cse);
  7477. + return (NULL);
  7478. +}
  7479. +
  7480. +static int
  7481. +csedelete(struct fcrypt *fcr, struct csession *cse_del)
  7482. +{
  7483. + struct csession *cse;
  7484. +
  7485. + dprintk("%s()\n", __FUNCTION__);
  7486. + list_for_each_entry(cse, &fcr->csessions, list) {
  7487. + if (cse == cse_del) {
  7488. + list_del(&cse->list);
  7489. + return (1);
  7490. + }
  7491. + }
  7492. + return (0);
  7493. +}
  7494. +
  7495. +static struct csession *
  7496. +cseadd(struct fcrypt *fcr, struct csession *cse)
  7497. +{
  7498. + dprintk("%s()\n", __FUNCTION__);
  7499. + list_add_tail(&cse->list, &fcr->csessions);
  7500. + cse->ses = fcr->sesn++;
  7501. + return (cse);
  7502. +}
  7503. +
  7504. +static struct csession *
  7505. +csecreate(struct fcrypt *fcr, u_int64_t sid, struct cryptoini *crie,
  7506. + struct cryptoini *cria, struct csession_info *info)
  7507. +{
  7508. + struct csession *cse;
  7509. +
  7510. + dprintk("%s()\n", __FUNCTION__);
  7511. + cse = (struct csession *) kmalloc(sizeof(struct csession), GFP_KERNEL);
  7512. + if (cse == NULL)
  7513. + return NULL;
  7514. + memset(cse, 0, sizeof(struct csession));
  7515. +
  7516. + INIT_LIST_HEAD(&cse->list);
  7517. + init_waitqueue_head(&cse->waitq);
  7518. +
  7519. + cse->key = crie->cri_key;
  7520. + cse->keylen = crie->cri_klen/8;
  7521. + cse->mackey = cria->cri_key;
  7522. + cse->mackeylen = cria->cri_klen/8;
  7523. + cse->sid = sid;
  7524. + cse->cipher = crie->cri_alg;
  7525. + cse->mac = cria->cri_alg;
  7526. + cse->info = *info;
  7527. + cseadd(fcr, cse);
  7528. + return (cse);
  7529. +}
  7530. +
  7531. +static int
  7532. +csefree(struct csession *cse)
  7533. +{
  7534. + int error;
  7535. +
  7536. + dprintk("%s()\n", __FUNCTION__);
  7537. + error = crypto_freesession(cse->sid);
  7538. + if (cse->key)
  7539. + kfree(cse->key);
  7540. + if (cse->mackey)
  7541. + kfree(cse->mackey);
  7542. + kfree(cse);
  7543. + return(error);
  7544. +}
  7545. +
  7546. +static int
  7547. +cryptodev_ioctl(
  7548. + struct inode *inode,
  7549. + struct file *filp,
  7550. + unsigned int cmd,
  7551. + unsigned long arg)
  7552. +{
  7553. + struct cryptoini cria, crie;
  7554. + struct fcrypt *fcr = filp->private_data;
  7555. + struct csession *cse;
  7556. + struct csession_info info;
  7557. + struct session2_op sop;
  7558. + struct crypt_op cop;
  7559. + struct crypt_kop kop;
  7560. + struct crypt_find_op fop;
  7561. + u_int64_t sid;
  7562. + u_int32_t ses = 0;
  7563. + int feat, fd, error = 0, crid;
  7564. + mm_segment_t fs;
  7565. +
  7566. + dprintk("%s(cmd=%x arg=%lx)\n", __FUNCTION__, cmd, arg);
  7567. +
  7568. + switch (cmd) {
  7569. +
  7570. + case CRIOGET: {
  7571. + dprintk("%s(CRIOGET)\n", __FUNCTION__);
  7572. + fs = get_fs();
  7573. + set_fs(get_ds());
  7574. + for (fd = 0; fd < files_fdtable(current->files)->max_fds; fd++)
  7575. + if (files_fdtable(current->files)->fd[fd] == filp)
  7576. + break;
  7577. + fd = sys_dup(fd);
  7578. + set_fs(fs);
  7579. + put_user(fd, (int *) arg);
  7580. + return IS_ERR_VALUE(fd) ? fd : 0;
  7581. + }
  7582. +
  7583. +#define CIOCGSESSSTR (cmd == CIOCGSESSION ? "CIOCGSESSION" : "CIOCGSESSION2")
  7584. + case CIOCGSESSION:
  7585. + case CIOCGSESSION2:
  7586. + dprintk("%s(%s)\n", __FUNCTION__, CIOCGSESSSTR);
  7587. + memset(&crie, 0, sizeof(crie));
  7588. + memset(&cria, 0, sizeof(cria));
  7589. + memset(&info, 0, sizeof(info));
  7590. + memset(&sop, 0, sizeof(sop));
  7591. +
  7592. + if (copy_from_user(&sop, (void*)arg, (cmd == CIOCGSESSION) ?
  7593. + sizeof(struct session_op) : sizeof(sop))) {
  7594. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  7595. + error = EFAULT;
  7596. + goto bail;
  7597. + }
  7598. +
  7599. + switch (sop.cipher) {
  7600. + case 0:
  7601. + dprintk("%s(%s) - no cipher\n", __FUNCTION__, CIOCGSESSSTR);
  7602. + break;
  7603. + case CRYPTO_NULL_CBC:
  7604. + info.blocksize = NULL_BLOCK_LEN;
  7605. + info.minkey = NULL_MIN_KEY_LEN;
  7606. + info.maxkey = NULL_MAX_KEY_LEN;
  7607. + break;
  7608. + case CRYPTO_DES_CBC:
  7609. + info.blocksize = DES_BLOCK_LEN;
  7610. + info.minkey = DES_MIN_KEY_LEN;
  7611. + info.maxkey = DES_MAX_KEY_LEN;
  7612. + break;
  7613. + case CRYPTO_3DES_CBC:
  7614. + info.blocksize = DES3_BLOCK_LEN;
  7615. + info.minkey = DES3_MIN_KEY_LEN;
  7616. + info.maxkey = DES3_MAX_KEY_LEN;
  7617. + break;
  7618. + case CRYPTO_BLF_CBC:
  7619. + info.blocksize = BLOWFISH_BLOCK_LEN;
  7620. + info.minkey = BLOWFISH_MIN_KEY_LEN;
  7621. + info.maxkey = BLOWFISH_MAX_KEY_LEN;
  7622. + break;
  7623. + case CRYPTO_CAST_CBC:
  7624. + info.blocksize = CAST128_BLOCK_LEN;
  7625. + info.minkey = CAST128_MIN_KEY_LEN;
  7626. + info.maxkey = CAST128_MAX_KEY_LEN;
  7627. + break;
  7628. + case CRYPTO_SKIPJACK_CBC:
  7629. + info.blocksize = SKIPJACK_BLOCK_LEN;
  7630. + info.minkey = SKIPJACK_MIN_KEY_LEN;
  7631. + info.maxkey = SKIPJACK_MAX_KEY_LEN;
  7632. + break;
  7633. + case CRYPTO_AES_CBC:
  7634. + info.blocksize = AES_BLOCK_LEN;
  7635. + info.minkey = AES_MIN_KEY_LEN;
  7636. + info.maxkey = AES_MAX_KEY_LEN;
  7637. + break;
  7638. + case CRYPTO_ARC4:
  7639. + info.blocksize = ARC4_BLOCK_LEN;
  7640. + info.minkey = ARC4_MIN_KEY_LEN;
  7641. + info.maxkey = ARC4_MAX_KEY_LEN;
  7642. + break;
  7643. + case CRYPTO_CAMELLIA_CBC:
  7644. + info.blocksize = CAMELLIA_BLOCK_LEN;
  7645. + info.minkey = CAMELLIA_MIN_KEY_LEN;
  7646. + info.maxkey = CAMELLIA_MAX_KEY_LEN;
  7647. + break;
  7648. + default:
  7649. + dprintk("%s(%s) - bad cipher\n", __FUNCTION__, CIOCGSESSSTR);
  7650. + error = EINVAL;
  7651. + goto bail;
  7652. + }
  7653. +
  7654. + switch (sop.mac) {
  7655. + case 0:
  7656. + dprintk("%s(%s) - no mac\n", __FUNCTION__, CIOCGSESSSTR);
  7657. + break;
  7658. + case CRYPTO_NULL_HMAC:
  7659. + info.authsize = NULL_HASH_LEN;
  7660. + break;
  7661. + case CRYPTO_MD5:
  7662. + info.authsize = MD5_HASH_LEN;
  7663. + break;
  7664. + case CRYPTO_SHA1:
  7665. + info.authsize = SHA1_HASH_LEN;
  7666. + break;
  7667. + case CRYPTO_SHA2_256:
  7668. + info.authsize = SHA2_256_HASH_LEN;
  7669. + break;
  7670. + case CRYPTO_SHA2_384:
  7671. + info.authsize = SHA2_384_HASH_LEN;
  7672. + break;
  7673. + case CRYPTO_SHA2_512:
  7674. + info.authsize = SHA2_512_HASH_LEN;
  7675. + break;
  7676. + case CRYPTO_RIPEMD160:
  7677. + info.authsize = RIPEMD160_HASH_LEN;
  7678. + break;
  7679. + case CRYPTO_MD5_HMAC:
  7680. + info.authsize = MD5_HASH_LEN;
  7681. + info.authkey = 16;
  7682. + break;
  7683. + case CRYPTO_SHA1_HMAC:
  7684. + info.authsize = SHA1_HASH_LEN;
  7685. + info.authkey = 20;
  7686. + break;
  7687. + case CRYPTO_SHA2_256_HMAC:
  7688. + info.authsize = SHA2_256_HASH_LEN;
  7689. + info.authkey = 32;
  7690. + break;
  7691. + case CRYPTO_SHA2_384_HMAC:
  7692. + info.authsize = SHA2_384_HASH_LEN;
  7693. + info.authkey = 48;
  7694. + break;
  7695. + case CRYPTO_SHA2_512_HMAC:
  7696. + info.authsize = SHA2_512_HASH_LEN;
  7697. + info.authkey = 64;
  7698. + break;
  7699. + case CRYPTO_RIPEMD160_HMAC:
  7700. + info.authsize = RIPEMD160_HASH_LEN;
  7701. + info.authkey = 20;
  7702. + break;
  7703. + default:
  7704. + dprintk("%s(%s) - bad mac\n", __FUNCTION__, CIOCGSESSSTR);
  7705. + error = EINVAL;
  7706. + goto bail;
  7707. + }
  7708. +
  7709. + if (info.blocksize) {
  7710. + crie.cri_alg = sop.cipher;
  7711. + crie.cri_klen = sop.keylen * 8;
  7712. + if ((info.maxkey && sop.keylen > info.maxkey) ||
  7713. + sop.keylen < info.minkey) {
  7714. + dprintk("%s(%s) - bad key\n", __FUNCTION__, CIOCGSESSSTR);
  7715. + error = EINVAL;
  7716. + goto bail;
  7717. + }
  7718. +
  7719. + crie.cri_key = (u_int8_t *) kmalloc(crie.cri_klen/8+1, GFP_KERNEL);
  7720. + if (copy_from_user(crie.cri_key, sop.key,
  7721. + crie.cri_klen/8)) {
  7722. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  7723. + error = EFAULT;
  7724. + goto bail;
  7725. + }
  7726. + if (info.authsize)
  7727. + crie.cri_next = &cria;
  7728. + }
  7729. +
  7730. + if (info.authsize) {
  7731. + cria.cri_alg = sop.mac;
  7732. + cria.cri_klen = sop.mackeylen * 8;
  7733. + if (info.authkey && sop.mackeylen != info.authkey) {
  7734. + dprintk("%s(%s) - mackeylen %d != %d\n", __FUNCTION__,
  7735. + CIOCGSESSSTR, sop.mackeylen, info.authkey);
  7736. + error = EINVAL;
  7737. + goto bail;
  7738. + }
  7739. +
  7740. + if (cria.cri_klen) {
  7741. + cria.cri_key = (u_int8_t *) kmalloc(cria.cri_klen/8,GFP_KERNEL);
  7742. + if (copy_from_user(cria.cri_key, sop.mackey,
  7743. + cria.cri_klen / 8)) {
  7744. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  7745. + error = EFAULT;
  7746. + goto bail;
  7747. + }
  7748. + }
  7749. + }
  7750. +
  7751. + /* NB: CIOGSESSION2 has the crid */
  7752. + if (cmd == CIOCGSESSION2) {
  7753. + crid = sop.crid;
  7754. + error = checkcrid(crid);
  7755. + if (error) {
  7756. + dprintk("%s(%s) - checkcrid %x\n", __FUNCTION__,
  7757. + CIOCGSESSSTR, error);
  7758. + goto bail;
  7759. + }
  7760. + } else {
  7761. + /* allow either HW or SW to be used */
  7762. + crid = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
  7763. + }
  7764. + error = crypto_newsession(&sid, (info.blocksize ? &crie : &cria), crid);
  7765. + if (error) {
  7766. + dprintk("%s(%s) - newsession %d\n",__FUNCTION__,CIOCGSESSSTR,error);
  7767. + goto bail;
  7768. + }
  7769. +
  7770. + cse = csecreate(fcr, sid, &crie, &cria, &info);
  7771. + if (cse == NULL) {
  7772. + crypto_freesession(sid);
  7773. + error = EINVAL;
  7774. + dprintk("%s(%s) - csecreate failed\n", __FUNCTION__, CIOCGSESSSTR);
  7775. + goto bail;
  7776. + }
  7777. + sop.ses = cse->ses;
  7778. +
  7779. + if (cmd == CIOCGSESSION2) {
  7780. + /* return hardware/driver id */
  7781. + sop.crid = CRYPTO_SESID2HID(cse->sid);
  7782. + }
  7783. +
  7784. + if (copy_to_user((void*)arg, &sop, (cmd == CIOCGSESSION) ?
  7785. + sizeof(struct session_op) : sizeof(sop))) {
  7786. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  7787. + error = EFAULT;
  7788. + }
  7789. +bail:
  7790. + if (error) {
  7791. + dprintk("%s(%s) - bail %d\n", __FUNCTION__, CIOCGSESSSTR, error);
  7792. + if (crie.cri_key)
  7793. + kfree(crie.cri_key);
  7794. + if (cria.cri_key)
  7795. + kfree(cria.cri_key);
  7796. + }
  7797. + break;
  7798. + case CIOCFSESSION:
  7799. + dprintk("%s(CIOCFSESSION)\n", __FUNCTION__);
  7800. + get_user(ses, (uint32_t*)arg);
  7801. + cse = csefind(fcr, ses);
  7802. + if (cse == NULL) {
  7803. + error = EINVAL;
  7804. + dprintk("%s(CIOCFSESSION) - Fail %d\n", __FUNCTION__, error);
  7805. + break;
  7806. + }
  7807. + csedelete(fcr, cse);
  7808. + error = csefree(cse);
  7809. + break;
  7810. + case CIOCCRYPT:
  7811. + dprintk("%s(CIOCCRYPT)\n", __FUNCTION__);
  7812. + if(copy_from_user(&cop, (void*)arg, sizeof(cop))) {
  7813. + dprintk("%s(CIOCCRYPT) - bad copy\n", __FUNCTION__);
  7814. + error = EFAULT;
  7815. + goto bail;
  7816. + }
  7817. + cse = csefind(fcr, cop.ses);
  7818. + if (cse == NULL) {
  7819. + error = EINVAL;
  7820. + dprintk("%s(CIOCCRYPT) - Fail %d\n", __FUNCTION__, error);
  7821. + break;
  7822. + }
  7823. + error = cryptodev_op(cse, &cop);
  7824. + if(copy_to_user((void*)arg, &cop, sizeof(cop))) {
  7825. + dprintk("%s(CIOCCRYPT) - bad return copy\n", __FUNCTION__);
  7826. + error = EFAULT;
  7827. + goto bail;
  7828. + }
  7829. + break;
  7830. + case CIOCKEY:
  7831. + case CIOCKEY2:
  7832. + dprintk("%s(CIOCKEY)\n", __FUNCTION__);
  7833. + if (!crypto_userasymcrypto)
  7834. + return (EPERM); /* XXX compat? */
  7835. + if(copy_from_user(&kop, (void*)arg, sizeof(kop))) {
  7836. + dprintk("%s(CIOCKEY) - bad copy\n", __FUNCTION__);
  7837. + error = EFAULT;
  7838. + goto bail;
  7839. + }
  7840. + if (cmd == CIOCKEY) {
  7841. + /* NB: crypto core enforces s/w driver use */
  7842. + kop.crk_crid =
  7843. + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
  7844. + }
  7845. + error = cryptodev_key(&kop);
  7846. + if(copy_to_user((void*)arg, &kop, sizeof(kop))) {
  7847. + dprintk("%s(CIOCGKEY) - bad return copy\n", __FUNCTION__);
  7848. + error = EFAULT;
  7849. + goto bail;
  7850. + }
  7851. + break;
  7852. + case CIOCASYMFEAT:
  7853. + dprintk("%s(CIOCASYMFEAT)\n", __FUNCTION__);
  7854. + if (!crypto_userasymcrypto) {
  7855. + /*
  7856. + * NB: if user asym crypto operations are
  7857. + * not permitted return "no algorithms"
  7858. + * so well-behaved applications will just
  7859. + * fallback to doing them in software.
  7860. + */
  7861. + feat = 0;
  7862. + } else
  7863. + error = crypto_getfeat(&feat);
  7864. + if (!error) {
  7865. + error = copy_to_user((void*)arg, &feat, sizeof(feat));
  7866. + }
  7867. + break;
  7868. + case CIOCFINDDEV:
  7869. + if (copy_from_user(&fop, (void*)arg, sizeof(fop))) {
  7870. + dprintk("%s(CIOCFINDDEV) - bad copy\n", __FUNCTION__);
  7871. + error = EFAULT;
  7872. + goto bail;
  7873. + }
  7874. + error = cryptodev_find(&fop);
  7875. + if (copy_to_user((void*)arg, &fop, sizeof(fop))) {
  7876. + dprintk("%s(CIOCFINDDEV) - bad return copy\n", __FUNCTION__);
  7877. + error = EFAULT;
  7878. + goto bail;
  7879. + }
  7880. + break;
  7881. + default:
  7882. + dprintk("%s(unknown ioctl 0x%x)\n", __FUNCTION__, cmd);
  7883. + error = EINVAL;
  7884. + break;
  7885. + }
  7886. + return(-error);
  7887. +}
  7888. +
  7889. +#ifdef HAVE_UNLOCKED_IOCTL
  7890. +static long
  7891. +cryptodev_unlocked_ioctl(
  7892. + struct file *filp,
  7893. + unsigned int cmd,
  7894. + unsigned long arg)
  7895. +{
  7896. + return cryptodev_ioctl(NULL, filp, cmd, arg);
  7897. +}
  7898. +#endif
  7899. +
  7900. +static int
  7901. +cryptodev_open(struct inode *inode, struct file *filp)
  7902. +{
  7903. + struct fcrypt *fcr;
  7904. +
  7905. + dprintk("%s()\n", __FUNCTION__);
  7906. + if (filp->private_data) {
  7907. + printk("cryptodev: Private data already exists !\n");
  7908. + return(0);
  7909. + }
  7910. +
  7911. + fcr = kmalloc(sizeof(*fcr), GFP_KERNEL);
  7912. + if (!fcr) {
  7913. + dprintk("%s() - malloc failed\n", __FUNCTION__);
  7914. + return(-ENOMEM);
  7915. + }
  7916. + memset(fcr, 0, sizeof(*fcr));
  7917. +
  7918. + INIT_LIST_HEAD(&fcr->csessions);
  7919. + filp->private_data = fcr;
  7920. + return(0);
  7921. +}
  7922. +
  7923. +static int
  7924. +cryptodev_release(struct inode *inode, struct file *filp)
  7925. +{
  7926. + struct fcrypt *fcr = filp->private_data;
  7927. + struct csession *cse, *tmp;
  7928. +
  7929. + dprintk("%s()\n", __FUNCTION__);
  7930. + if (!filp) {
  7931. + printk("cryptodev: No private data on release\n");
  7932. + return(0);
  7933. + }
  7934. +
  7935. + list_for_each_entry_safe(cse, tmp, &fcr->csessions, list) {
  7936. + list_del(&cse->list);
  7937. + (void)csefree(cse);
  7938. + }
  7939. + filp->private_data = NULL;
  7940. + kfree(fcr);
  7941. + return(0);
  7942. +}
  7943. +
  7944. +static struct file_operations cryptodev_fops = {
  7945. + .owner = THIS_MODULE,
  7946. + .open = cryptodev_open,
  7947. + .release = cryptodev_release,
  7948. +#ifdef HAVE_UNLOCKED_IOCTL
  7949. + .unlocked_ioctl = cryptodev_unlocked_ioctl,
  7950. +#endif
  7951. +};
  7952. +
  7953. +static struct miscdevice cryptodev = {
  7954. + .minor = CRYPTODEV_MINOR,
  7955. + .name = "crypto",
  7956. + .fops = &cryptodev_fops,
  7957. +};
  7958. +
  7959. +static int __init
  7960. +cryptodev_init(void)
  7961. +{
  7962. + int rc;
  7963. +
  7964. + dprintk("%s(%p)\n", __FUNCTION__, cryptodev_init);
  7965. + rc = misc_register(&cryptodev);
  7966. + if (rc) {
  7967. + printk(KERN_ERR "cryptodev: registration of /dev/crypto failed\n");
  7968. + return(rc);
  7969. + }
  7970. +
  7971. + return(0);
  7972. +}
  7973. +
  7974. +static void __exit
  7975. +cryptodev_exit(void)
  7976. +{
  7977. + dprintk("%s()\n", __FUNCTION__);
  7978. + misc_deregister(&cryptodev);
  7979. +}
  7980. +
  7981. +module_init(cryptodev_init);
  7982. +module_exit(cryptodev_exit);
  7983. +
  7984. +MODULE_LICENSE("BSD");
  7985. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  7986. +MODULE_DESCRIPTION("Cryptodev (user interface to OCF)");
  7987. diff -Nur linux-2.6.39.orig/crypto/ocf/cryptodev.h linux-2.6.39/crypto/ocf/cryptodev.h
  7988. --- linux-2.6.39.orig/crypto/ocf/cryptodev.h 1970-01-01 01:00:00.000000000 +0100
  7989. +++ linux-2.6.39/crypto/ocf/cryptodev.h 2011-07-31 11:31:53.743486891 +0200
  7990. @@ -0,0 +1,479 @@
  7991. +/* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.25 2007/05/09 19:37:02 gnn Exp $ */
  7992. +/* $OpenBSD: cryptodev.h,v 1.31 2002/06/11 11:14:29 beck Exp $ */
  7993. +
  7994. +/*-
  7995. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  7996. + * Copyright (C) 2006-2010 David McCullough
  7997. + * Copyright (C) 2004-2005 Intel Corporation.
  7998. + * The license and original author are listed below.
  7999. + *
  8000. + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
  8001. + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
  8002. + *
  8003. + * This code was written by Angelos D. Keromytis in Athens, Greece, in
  8004. + * February 2000. Network Security Technologies Inc. (NSTI) kindly
  8005. + * supported the development of this code.
  8006. + *
  8007. + * Copyright (c) 2000 Angelos D. Keromytis
  8008. + *
  8009. + * Permission to use, copy, and modify this software with or without fee
  8010. + * is hereby granted, provided that this entire notice is included in
  8011. + * all source code copies of any software which is or includes a copy or
  8012. + * modification of this software.
  8013. + *
  8014. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
  8015. + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
  8016. + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
  8017. + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
  8018. + * PURPOSE.
  8019. + *
  8020. + * Copyright (c) 2001 Theo de Raadt
  8021. + *
  8022. + * Redistribution and use in source and binary forms, with or without
  8023. + * modification, are permitted provided that the following conditions
  8024. + * are met:
  8025. + *
  8026. + * 1. Redistributions of source code must retain the above copyright
  8027. + * notice, this list of conditions and the following disclaimer.
  8028. + * 2. Redistributions in binary form must reproduce the above copyright
  8029. + * notice, this list of conditions and the following disclaimer in the
  8030. + * documentation and/or other materials provided with the distribution.
  8031. + * 3. The name of the author may not be used to endorse or promote products
  8032. + * derived from this software without specific prior written permission.
  8033. + *
  8034. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  8035. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  8036. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  8037. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  8038. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  8039. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  8040. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  8041. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  8042. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  8043. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  8044. + *
  8045. + * Effort sponsored in part by the Defense Advanced Research Projects
  8046. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  8047. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  8048. + *
  8049. + */
  8050. +
  8051. +#ifndef _CRYPTO_CRYPTO_H_
  8052. +#define _CRYPTO_CRYPTO_H_
  8053. +
  8054. +/* Some initial values */
  8055. +#define CRYPTO_DRIVERS_INITIAL 4
  8056. +#define CRYPTO_SW_SESSIONS 32
  8057. +
  8058. +/* Hash values */
  8059. +#define NULL_HASH_LEN 0
  8060. +#define MD5_HASH_LEN 16
  8061. +#define SHA1_HASH_LEN 20
  8062. +#define RIPEMD160_HASH_LEN 20
  8063. +#define SHA2_256_HASH_LEN 32
  8064. +#define SHA2_384_HASH_LEN 48
  8065. +#define SHA2_512_HASH_LEN 64
  8066. +#define MD5_KPDK_HASH_LEN 16
  8067. +#define SHA1_KPDK_HASH_LEN 20
  8068. +/* Maximum hash algorithm result length */
  8069. +#define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */
  8070. +
  8071. +/* HMAC values */
  8072. +#define NULL_HMAC_BLOCK_LEN 1
  8073. +#define MD5_HMAC_BLOCK_LEN 64
  8074. +#define SHA1_HMAC_BLOCK_LEN 64
  8075. +#define RIPEMD160_HMAC_BLOCK_LEN 64
  8076. +#define SHA2_256_HMAC_BLOCK_LEN 64
  8077. +#define SHA2_384_HMAC_BLOCK_LEN 128
  8078. +#define SHA2_512_HMAC_BLOCK_LEN 128
  8079. +/* Maximum HMAC block length */
  8080. +#define HMAC_MAX_BLOCK_LEN SHA2_512_HMAC_BLOCK_LEN /* Keep this updated */
  8081. +#define HMAC_IPAD_VAL 0x36
  8082. +#define HMAC_OPAD_VAL 0x5C
  8083. +
  8084. +/* Encryption algorithm block sizes */
  8085. +#define NULL_BLOCK_LEN 1
  8086. +#define DES_BLOCK_LEN 8
  8087. +#define DES3_BLOCK_LEN 8
  8088. +#define BLOWFISH_BLOCK_LEN 8
  8089. +#define SKIPJACK_BLOCK_LEN 8
  8090. +#define CAST128_BLOCK_LEN 8
  8091. +#define RIJNDAEL128_BLOCK_LEN 16
  8092. +#define AES_BLOCK_LEN RIJNDAEL128_BLOCK_LEN
  8093. +#define CAMELLIA_BLOCK_LEN 16
  8094. +#define ARC4_BLOCK_LEN 1
  8095. +#define EALG_MAX_BLOCK_LEN AES_BLOCK_LEN /* Keep this updated */
  8096. +
  8097. +/* Encryption algorithm min and max key sizes */
  8098. +#define NULL_MIN_KEY_LEN 0
  8099. +#define NULL_MAX_KEY_LEN 0
  8100. +#define DES_MIN_KEY_LEN 8
  8101. +#define DES_MAX_KEY_LEN 8
  8102. +#define DES3_MIN_KEY_LEN 24
  8103. +#define DES3_MAX_KEY_LEN 24
  8104. +#define BLOWFISH_MIN_KEY_LEN 4
  8105. +#define BLOWFISH_MAX_KEY_LEN 56
  8106. +#define SKIPJACK_MIN_KEY_LEN 10
  8107. +#define SKIPJACK_MAX_KEY_LEN 10
  8108. +#define CAST128_MIN_KEY_LEN 5
  8109. +#define CAST128_MAX_KEY_LEN 16
  8110. +#define RIJNDAEL128_MIN_KEY_LEN 16
  8111. +#define RIJNDAEL128_MAX_KEY_LEN 32
  8112. +#define AES_MIN_KEY_LEN RIJNDAEL128_MIN_KEY_LEN
  8113. +#define AES_MAX_KEY_LEN RIJNDAEL128_MAX_KEY_LEN
  8114. +#define CAMELLIA_MIN_KEY_LEN 16
  8115. +#define CAMELLIA_MAX_KEY_LEN 32
  8116. +#define ARC4_MIN_KEY_LEN 1
  8117. +#define ARC4_MAX_KEY_LEN 256
  8118. +
  8119. +/* Max size of data that can be processed */
  8120. +#define CRYPTO_MAX_DATA_LEN 64*1024 - 1
  8121. +
  8122. +#define CRYPTO_ALGORITHM_MIN 1
  8123. +#define CRYPTO_DES_CBC 1
  8124. +#define CRYPTO_3DES_CBC 2
  8125. +#define CRYPTO_BLF_CBC 3
  8126. +#define CRYPTO_CAST_CBC 4
  8127. +#define CRYPTO_SKIPJACK_CBC 5
  8128. +#define CRYPTO_MD5_HMAC 6
  8129. +#define CRYPTO_SHA1_HMAC 7
  8130. +#define CRYPTO_RIPEMD160_HMAC 8
  8131. +#define CRYPTO_MD5_KPDK 9
  8132. +#define CRYPTO_SHA1_KPDK 10
  8133. +#define CRYPTO_RIJNDAEL128_CBC 11 /* 128 bit blocksize */
  8134. +#define CRYPTO_AES_CBC 11 /* 128 bit blocksize -- the same as above */
  8135. +#define CRYPTO_ARC4 12
  8136. +#define CRYPTO_MD5 13
  8137. +#define CRYPTO_SHA1 14
  8138. +#define CRYPTO_NULL_HMAC 15
  8139. +#define CRYPTO_NULL_CBC 16
  8140. +#define CRYPTO_DEFLATE_COMP 17 /* Deflate compression algorithm */
  8141. +#define CRYPTO_SHA2_256_HMAC 18
  8142. +#define CRYPTO_SHA2_384_HMAC 19
  8143. +#define CRYPTO_SHA2_512_HMAC 20
  8144. +#define CRYPTO_CAMELLIA_CBC 21
  8145. +#define CRYPTO_SHA2_256 22
  8146. +#define CRYPTO_SHA2_384 23
  8147. +#define CRYPTO_SHA2_512 24
  8148. +#define CRYPTO_RIPEMD160 25
  8149. +#define CRYPTO_ALGORITHM_MAX 25 /* Keep updated - see below */
  8150. +
  8151. +/* Algorithm flags */
  8152. +#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
  8153. +#define CRYPTO_ALG_FLAG_RNG_ENABLE 0x02 /* Has HW RNG for DH/DSA */
  8154. +#define CRYPTO_ALG_FLAG_DSA_SHA 0x04 /* Can do SHA on msg */
  8155. +
  8156. +/*
  8157. + * Crypto driver/device flags. They can set in the crid
  8158. + * parameter when creating a session or submitting a key
  8159. + * op to affect the device/driver assigned. If neither
  8160. + * of these are specified then the crid is assumed to hold
  8161. + * the driver id of an existing (and suitable) device that
  8162. + * must be used to satisfy the request.
  8163. + */
  8164. +#define CRYPTO_FLAG_HARDWARE 0x01000000 /* hardware accelerated */
  8165. +#define CRYPTO_FLAG_SOFTWARE 0x02000000 /* software implementation */
  8166. +
  8167. +/* NB: deprecated */
  8168. +struct session_op {
  8169. + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
  8170. + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
  8171. +
  8172. + u_int32_t keylen; /* cipher key */
  8173. + caddr_t key;
  8174. + int mackeylen; /* mac key */
  8175. + caddr_t mackey;
  8176. +
  8177. + u_int32_t ses; /* returns: session # */
  8178. +};
  8179. +
  8180. +struct session2_op {
  8181. + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
  8182. + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
  8183. +
  8184. + u_int32_t keylen; /* cipher key */
  8185. + caddr_t key;
  8186. + int mackeylen; /* mac key */
  8187. + caddr_t mackey;
  8188. +
  8189. + u_int32_t ses; /* returns: session # */
  8190. + int crid; /* driver id + flags (rw) */
  8191. + int pad[4]; /* for future expansion */
  8192. +};
  8193. +
  8194. +struct crypt_op {
  8195. + u_int32_t ses;
  8196. + u_int16_t op; /* i.e. COP_ENCRYPT */
  8197. +#define COP_NONE 0
  8198. +#define COP_ENCRYPT 1
  8199. +#define COP_DECRYPT 2
  8200. + u_int16_t flags;
  8201. +#define COP_F_BATCH 0x0008 /* Batch op if possible */
  8202. + u_int len;
  8203. + caddr_t src, dst; /* become iov[] inside kernel */
  8204. + caddr_t mac; /* must be big enough for chosen MAC */
  8205. + caddr_t iv;
  8206. +};
  8207. +
  8208. +/*
  8209. + * Parameters for looking up a crypto driver/device by
  8210. + * device name or by id. The latter are returned for
  8211. + * created sessions (crid) and completed key operations.
  8212. + */
  8213. +struct crypt_find_op {
  8214. + int crid; /* driver id + flags */
  8215. + char name[32]; /* device/driver name */
  8216. +};
  8217. +
  8218. +/* bignum parameter, in packed bytes, ... */
  8219. +struct crparam {
  8220. + caddr_t crp_p;
  8221. + u_int crp_nbits;
  8222. +};
  8223. +
  8224. +#define CRK_MAXPARAM 8
  8225. +
  8226. +struct crypt_kop {
  8227. + u_int crk_op; /* ie. CRK_MOD_EXP or other */
  8228. + u_int crk_status; /* return status */
  8229. + u_short crk_iparams; /* # of input parameters */
  8230. + u_short crk_oparams; /* # of output parameters */
  8231. + u_int crk_crid; /* NB: only used by CIOCKEY2 (rw) */
  8232. + struct crparam crk_param[CRK_MAXPARAM];
  8233. +};
  8234. +#define CRK_ALGORITM_MIN 0
  8235. +#define CRK_MOD_EXP 0
  8236. +#define CRK_MOD_EXP_CRT 1
  8237. +#define CRK_DSA_SIGN 2
  8238. +#define CRK_DSA_VERIFY 3
  8239. +#define CRK_DH_COMPUTE_KEY 4
  8240. +#define CRK_ALGORITHM_MAX 4 /* Keep updated - see below */
  8241. +
  8242. +#define CRF_MOD_EXP (1 << CRK_MOD_EXP)
  8243. +#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT)
  8244. +#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN)
  8245. +#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY)
  8246. +#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
  8247. +
  8248. +/*
  8249. + * done against open of /dev/crypto, to get a cloned descriptor.
  8250. + * Please use F_SETFD against the cloned descriptor.
  8251. + */
  8252. +#define CRIOGET _IOWR('c', 100, u_int32_t)
  8253. +#define CRIOASYMFEAT CIOCASYMFEAT
  8254. +#define CRIOFINDDEV CIOCFINDDEV
  8255. +
  8256. +/* the following are done against the cloned descriptor */
  8257. +#define CIOCGSESSION _IOWR('c', 101, struct session_op)
  8258. +#define CIOCFSESSION _IOW('c', 102, u_int32_t)
  8259. +#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
  8260. +#define CIOCKEY _IOWR('c', 104, struct crypt_kop)
  8261. +#define CIOCASYMFEAT _IOR('c', 105, u_int32_t)
  8262. +#define CIOCGSESSION2 _IOWR('c', 106, struct session2_op)
  8263. +#define CIOCKEY2 _IOWR('c', 107, struct crypt_kop)
  8264. +#define CIOCFINDDEV _IOWR('c', 108, struct crypt_find_op)
  8265. +
  8266. +struct cryptotstat {
  8267. + struct timespec acc; /* total accumulated time */
  8268. + struct timespec min; /* min time */
  8269. + struct timespec max; /* max time */
  8270. + u_int32_t count; /* number of observations */
  8271. +};
  8272. +
  8273. +struct cryptostats {
  8274. + u_int32_t cs_ops; /* symmetric crypto ops submitted */
  8275. + u_int32_t cs_errs; /* symmetric crypto ops that failed */
  8276. + u_int32_t cs_kops; /* asymetric/key ops submitted */
  8277. + u_int32_t cs_kerrs; /* asymetric/key ops that failed */
  8278. + u_int32_t cs_intrs; /* crypto swi thread activations */
  8279. + u_int32_t cs_rets; /* crypto return thread activations */
  8280. + u_int32_t cs_blocks; /* symmetric op driver block */
  8281. + u_int32_t cs_kblocks; /* symmetric op driver block */
  8282. + /*
  8283. + * When CRYPTO_TIMING is defined at compile time and the
  8284. + * sysctl debug.crypto is set to 1, the crypto system will
  8285. + * accumulate statistics about how long it takes to process
  8286. + * crypto requests at various points during processing.
  8287. + */
  8288. + struct cryptotstat cs_invoke; /* crypto_dipsatch -> crypto_invoke */
  8289. + struct cryptotstat cs_done; /* crypto_invoke -> crypto_done */
  8290. + struct cryptotstat cs_cb; /* crypto_done -> callback */
  8291. + struct cryptotstat cs_finis; /* callback -> callback return */
  8292. +
  8293. + u_int32_t cs_drops; /* crypto ops dropped due to congestion */
  8294. +};
  8295. +
  8296. +#ifdef __KERNEL__
  8297. +
  8298. +/* Standard initialization structure beginning */
  8299. +struct cryptoini {
  8300. + int cri_alg; /* Algorithm to use */
  8301. + int cri_klen; /* Key length, in bits */
  8302. + int cri_mlen; /* Number of bytes we want from the
  8303. + entire hash. 0 means all. */
  8304. + caddr_t cri_key; /* key to use */
  8305. + u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */
  8306. + struct cryptoini *cri_next;
  8307. +};
  8308. +
  8309. +/* Describe boundaries of a single crypto operation */
  8310. +struct cryptodesc {
  8311. + int crd_skip; /* How many bytes to ignore from start */
  8312. + int crd_len; /* How many bytes to process */
  8313. + int crd_inject; /* Where to inject results, if applicable */
  8314. + int crd_flags;
  8315. +
  8316. +#define CRD_F_ENCRYPT 0x01 /* Set when doing encryption */
  8317. +#define CRD_F_IV_PRESENT 0x02 /* When encrypting, IV is already in
  8318. + place, so don't copy. */
  8319. +#define CRD_F_IV_EXPLICIT 0x04 /* IV explicitly provided */
  8320. +#define CRD_F_DSA_SHA_NEEDED 0x08 /* Compute SHA-1 of buffer for DSA */
  8321. +#define CRD_F_KEY_EXPLICIT 0x10 /* Key explicitly provided */
  8322. +#define CRD_F_COMP 0x0f /* Set when doing compression */
  8323. +
  8324. + struct cryptoini CRD_INI; /* Initialization/context data */
  8325. +#define crd_iv CRD_INI.cri_iv
  8326. +#define crd_key CRD_INI.cri_key
  8327. +#define crd_alg CRD_INI.cri_alg
  8328. +#define crd_klen CRD_INI.cri_klen
  8329. +#define crd_mlen CRD_INI.cri_mlen
  8330. +
  8331. + struct cryptodesc *crd_next;
  8332. +};
  8333. +
  8334. +/* Structure describing complete operation */
  8335. +struct cryptop {
  8336. + struct list_head crp_next;
  8337. + wait_queue_head_t crp_waitq;
  8338. +
  8339. + u_int64_t crp_sid; /* Session ID */
  8340. + int crp_ilen; /* Input data total length */
  8341. + int crp_olen; /* Result total length */
  8342. +
  8343. + int crp_etype; /*
  8344. + * Error type (zero means no error).
  8345. + * All error codes except EAGAIN
  8346. + * indicate possible data corruption (as in,
  8347. + * the data have been touched). On all
  8348. + * errors, the crp_sid may have changed
  8349. + * (reset to a new one), so the caller
  8350. + * should always check and use the new
  8351. + * value on future requests.
  8352. + */
  8353. + int crp_flags;
  8354. +
  8355. +#define CRYPTO_F_SKBUF 0x0001 /* Input/output are skbuf chains */
  8356. +#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
  8357. +#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
  8358. +#define CRYPTO_F_BATCH 0x0008 /* Batch op if possible */
  8359. +#define CRYPTO_F_CBIMM 0x0010 /* Do callback immediately */
  8360. +#define CRYPTO_F_DONE 0x0020 /* Operation completed */
  8361. +#define CRYPTO_F_CBIFSYNC 0x0040 /* Do CBIMM if op is synchronous */
  8362. +
  8363. + caddr_t crp_buf; /* Data to be processed */
  8364. + caddr_t crp_opaque; /* Opaque pointer, passed along */
  8365. + struct cryptodesc *crp_desc; /* Linked list of processing descriptors */
  8366. +
  8367. + int (*crp_callback)(struct cryptop *); /* Callback function */
  8368. +};
  8369. +
  8370. +#define CRYPTO_BUF_CONTIG 0x0
  8371. +#define CRYPTO_BUF_IOV 0x1
  8372. +#define CRYPTO_BUF_SKBUF 0x2
  8373. +
  8374. +#define CRYPTO_OP_DECRYPT 0x0
  8375. +#define CRYPTO_OP_ENCRYPT 0x1
  8376. +
  8377. +/*
  8378. + * Hints passed to process methods.
  8379. + */
  8380. +#define CRYPTO_HINT_MORE 0x1 /* more ops coming shortly */
  8381. +
  8382. +struct cryptkop {
  8383. + struct list_head krp_next;
  8384. + wait_queue_head_t krp_waitq;
  8385. +
  8386. + int krp_flags;
  8387. +#define CRYPTO_KF_DONE 0x0001 /* Operation completed */
  8388. +#define CRYPTO_KF_CBIMM 0x0002 /* Do callback immediately */
  8389. +
  8390. + u_int krp_op; /* ie. CRK_MOD_EXP or other */
  8391. + u_int krp_status; /* return status */
  8392. + u_short krp_iparams; /* # of input parameters */
  8393. + u_short krp_oparams; /* # of output parameters */
  8394. + u_int krp_crid; /* desired device, etc. */
  8395. + u_int32_t krp_hid;
  8396. + struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
  8397. + int (*krp_callback)(struct cryptkop *);
  8398. +};
  8399. +
  8400. +#include <ocf-compat.h>
  8401. +
  8402. +/*
  8403. + * Session ids are 64 bits. The lower 32 bits contain a "local id" which
  8404. + * is a driver-private session identifier. The upper 32 bits contain a
  8405. + * "hardware id" used by the core crypto code to identify the driver and
  8406. + * a copy of the driver's capabilities that can be used by client code to
  8407. + * optimize operation.
  8408. + */
  8409. +#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0x00ffffff)
  8410. +#define CRYPTO_SESID2CAPS(_sid) (((_sid) >> 32) & 0xff000000)
  8411. +#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
  8412. +
  8413. +extern int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard);
  8414. +extern int crypto_freesession(u_int64_t sid);
  8415. +#define CRYPTOCAP_F_HARDWARE CRYPTO_FLAG_HARDWARE
  8416. +#define CRYPTOCAP_F_SOFTWARE CRYPTO_FLAG_SOFTWARE
  8417. +#define CRYPTOCAP_F_SYNC 0x04000000 /* operates synchronously */
  8418. +extern int32_t crypto_get_driverid(device_t dev, int flags);
  8419. +extern int crypto_find_driver(const char *);
  8420. +extern device_t crypto_find_device_byhid(int hid);
  8421. +extern int crypto_getcaps(int hid);
  8422. +extern int crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
  8423. + u_int32_t flags);
  8424. +extern int crypto_kregister(u_int32_t, int, u_int32_t);
  8425. +extern int crypto_unregister(u_int32_t driverid, int alg);
  8426. +extern int crypto_unregister_all(u_int32_t driverid);
  8427. +extern int crypto_dispatch(struct cryptop *crp);
  8428. +extern int crypto_kdispatch(struct cryptkop *);
  8429. +#define CRYPTO_SYMQ 0x1
  8430. +#define CRYPTO_ASYMQ 0x2
  8431. +extern int crypto_unblock(u_int32_t, int);
  8432. +extern void crypto_done(struct cryptop *crp);
  8433. +extern void crypto_kdone(struct cryptkop *);
  8434. +extern int crypto_getfeat(int *);
  8435. +
  8436. +extern void crypto_freereq(struct cryptop *crp);
  8437. +extern struct cryptop *crypto_getreq(int num);
  8438. +
  8439. +extern int crypto_usercrypto; /* userland may do crypto requests */
  8440. +extern int crypto_userasymcrypto; /* userland may do asym crypto reqs */
  8441. +extern int crypto_devallowsoft; /* only use hardware crypto */
  8442. +
  8443. +/*
  8444. + * random number support, crypto_unregister_all will unregister
  8445. + */
  8446. +extern int crypto_rregister(u_int32_t driverid,
  8447. + int (*read_random)(void *arg, u_int32_t *buf, int len), void *arg);
  8448. +extern int crypto_runregister_all(u_int32_t driverid);
  8449. +
  8450. +/*
  8451. + * Crypto-related utility routines used mainly by drivers.
  8452. + *
  8453. + * XXX these don't really belong here; but for now they're
  8454. + * kept apart from the rest of the system.
  8455. + */
  8456. +struct uio;
  8457. +extern void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp);
  8458. +extern void cuio_copyback(struct uio* uio, int off, int len, caddr_t cp);
  8459. +extern struct iovec *cuio_getptr(struct uio *uio, int loc, int *off);
  8460. +
  8461. +extern void crypto_copyback(int flags, caddr_t buf, int off, int size,
  8462. + caddr_t in);
  8463. +extern void crypto_copydata(int flags, caddr_t buf, int off, int size,
  8464. + caddr_t out);
  8465. +extern int crypto_apply(int flags, caddr_t buf, int off, int len,
  8466. + int (*f)(void *, void *, u_int), void *arg);
  8467. +
  8468. +#endif /* __KERNEL__ */
  8469. +#endif /* _CRYPTO_CRYPTO_H_ */
  8470. diff -Nur linux-2.6.39.orig/crypto/ocf/cryptosoft.c linux-2.6.39/crypto/ocf/cryptosoft.c
  8471. --- linux-2.6.39.orig/crypto/ocf/cryptosoft.c 1970-01-01 01:00:00.000000000 +0100
  8472. +++ linux-2.6.39/crypto/ocf/cryptosoft.c 2011-07-31 11:31:53.783528522 +0200
  8473. @@ -0,0 +1,1210 @@
  8474. +/*
  8475. + * An OCF module that uses the linux kernel cryptoapi, based on the
  8476. + * original cryptosoft for BSD by Angelos D. Keromytis (angelos@cis.upenn.edu)
  8477. + * but is mostly unrecognisable,
  8478. + *
  8479. + * Written by David McCullough <david_mccullough@mcafee.com>
  8480. + * Copyright (C) 2004-2010 David McCullough
  8481. + * Copyright (C) 2004-2005 Intel Corporation.
  8482. + *
  8483. + * LICENSE TERMS
  8484. + *
  8485. + * The free distribution and use of this software in both source and binary
  8486. + * form is allowed (with or without changes) provided that:
  8487. + *
  8488. + * 1. distributions of this source code include the above copyright
  8489. + * notice, this list of conditions and the following disclaimer;
  8490. + *
  8491. + * 2. distributions in binary form include the above copyright
  8492. + * notice, this list of conditions and the following disclaimer
  8493. + * in the documentation and/or other associated materials;
  8494. + *
  8495. + * 3. the copyright holder's name is not used to endorse products
  8496. + * built using this software without specific written permission.
  8497. + *
  8498. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  8499. + * may be distributed under the terms of the GNU General Public License (GPL),
  8500. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  8501. + *
  8502. + * DISCLAIMER
  8503. + *
  8504. + * This software is provided 'as is' with no explicit or implied warranties
  8505. + * in respect of its properties, including, but not limited to, correctness
  8506. + * and/or fitness for purpose.
  8507. + * ---------------------------------------------------------------------------
  8508. + */
  8509. +
  8510. +#ifndef AUTOCONF_INCLUDED
  8511. +#include <linux/config.h>
  8512. +#endif
  8513. +#include <linux/module.h>
  8514. +#include <linux/init.h>
  8515. +#include <linux/list.h>
  8516. +#include <linux/slab.h>
  8517. +#include <linux/sched.h>
  8518. +#include <linux/wait.h>
  8519. +#include <linux/crypto.h>
  8520. +#include <linux/mm.h>
  8521. +#include <linux/skbuff.h>
  8522. +#include <linux/random.h>
  8523. +#include <linux/version.h>
  8524. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
  8525. +#include <linux/scatterlist.h>
  8526. +#endif
  8527. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
  8528. +#include <crypto/hash.h>
  8529. +#endif
  8530. +
  8531. +#include <cryptodev.h>
  8532. +#include <uio.h>
  8533. +
  8534. +struct {
  8535. + softc_device_decl sc_dev;
  8536. +} swcr_softc;
  8537. +
  8538. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  8539. +
  8540. +#define SW_TYPE_CIPHER 0x01
  8541. +#define SW_TYPE_HMAC 0x02
  8542. +#define SW_TYPE_HASH 0x04
  8543. +#define SW_TYPE_COMP 0x08
  8544. +#define SW_TYPE_BLKCIPHER 0x10
  8545. +#define SW_TYPE_ALG_MASK 0x1f
  8546. +
  8547. +#define SW_TYPE_ASYNC 0x8000
  8548. +
  8549. +/* We change some of the above if we have an async interface */
  8550. +
  8551. +#define SW_TYPE_ALG_AMASK (SW_TYPE_ALG_MASK | SW_TYPE_ASYNC)
  8552. +
  8553. +#define SW_TYPE_ABLKCIPHER (SW_TYPE_BLKCIPHER | SW_TYPE_ASYNC)
  8554. +#define SW_TYPE_AHASH (SW_TYPE_HASH | SW_TYPE_ASYNC)
  8555. +#define SW_TYPE_AHMAC (SW_TYPE_HMAC | SW_TYPE_ASYNC)
  8556. +
  8557. +#define SCATTERLIST_MAX 16
  8558. +
  8559. +struct swcr_data {
  8560. + int sw_type;
  8561. + int sw_alg;
  8562. + struct crypto_tfm *sw_tfm;
  8563. + union {
  8564. + struct {
  8565. + char *sw_key;
  8566. + int sw_klen;
  8567. + int sw_mlen;
  8568. + } hmac;
  8569. + void *sw_comp_buf;
  8570. + } u;
  8571. + struct swcr_data *sw_next;
  8572. +};
  8573. +
  8574. +struct swcr_req {
  8575. + struct swcr_data *sw_head;
  8576. + struct swcr_data *sw;
  8577. + struct cryptop *crp;
  8578. + struct cryptodesc *crd;
  8579. + struct scatterlist sg[SCATTERLIST_MAX];
  8580. + unsigned char iv[EALG_MAX_BLOCK_LEN];
  8581. + char result[HASH_MAX_LEN];
  8582. + void *crypto_req;
  8583. +};
  8584. +
  8585. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  8586. +static kmem_cache_t *swcr_req_cache;
  8587. +#else
  8588. +static struct kmem_cache *swcr_req_cache;
  8589. +#endif
  8590. +
  8591. +#ifndef CRYPTO_TFM_MODE_CBC
  8592. +/*
  8593. + * As of linux-2.6.21 this is no longer defined, and presumably no longer
  8594. + * needed to be passed into the crypto core code.
  8595. + */
  8596. +#define CRYPTO_TFM_MODE_CBC 0
  8597. +#define CRYPTO_TFM_MODE_ECB 0
  8598. +#endif
  8599. +
  8600. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
  8601. + /*
  8602. + * Linux 2.6.19 introduced a new Crypto API, setup macro's to convert new
  8603. + * API into old API.
  8604. + */
  8605. +
  8606. + /* Symmetric/Block Cipher */
  8607. + struct blkcipher_desc
  8608. + {
  8609. + struct crypto_tfm *tfm;
  8610. + void *info;
  8611. + };
  8612. + #define ecb(X) #X , CRYPTO_TFM_MODE_ECB
  8613. + #define cbc(X) #X , CRYPTO_TFM_MODE_CBC
  8614. + #define crypto_has_blkcipher(X, Y, Z) crypto_alg_available(X, 0)
  8615. + #define crypto_blkcipher_cast(X) X
  8616. + #define crypto_blkcipher_tfm(X) X
  8617. + #define crypto_alloc_blkcipher(X, Y, Z) crypto_alloc_tfm(X, mode)
  8618. + #define crypto_blkcipher_ivsize(X) crypto_tfm_alg_ivsize(X)
  8619. + #define crypto_blkcipher_blocksize(X) crypto_tfm_alg_blocksize(X)
  8620. + #define crypto_blkcipher_setkey(X, Y, Z) crypto_cipher_setkey(X, Y, Z)
  8621. + #define crypto_blkcipher_encrypt_iv(W, X, Y, Z) \
  8622. + crypto_cipher_encrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
  8623. + #define crypto_blkcipher_decrypt_iv(W, X, Y, Z) \
  8624. + crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
  8625. + #define crypto_blkcipher_set_flags(x, y) /* nop */
  8626. +
  8627. + /* Hash/HMAC/Digest */
  8628. + struct hash_desc
  8629. + {
  8630. + struct crypto_tfm *tfm;
  8631. + };
  8632. + #define hmac(X) #X , 0
  8633. + #define crypto_has_hash(X, Y, Z) crypto_alg_available(X, 0)
  8634. + #define crypto_hash_cast(X) X
  8635. + #define crypto_hash_tfm(X) X
  8636. + #define crypto_alloc_hash(X, Y, Z) crypto_alloc_tfm(X, mode)
  8637. + #define crypto_hash_digestsize(X) crypto_tfm_alg_digestsize(X)
  8638. + #define crypto_hash_digest(W, X, Y, Z) \
  8639. + crypto_digest_digest((W)->tfm, X, sg_num, Z)
  8640. +
  8641. + /* Asymmetric Cipher */
  8642. + #define crypto_has_cipher(X, Y, Z) crypto_alg_available(X, 0)
  8643. +
  8644. + /* Compression */
  8645. + #define crypto_has_comp(X, Y, Z) crypto_alg_available(X, 0)
  8646. + #define crypto_comp_tfm(X) X
  8647. + #define crypto_comp_cast(X) X
  8648. + #define crypto_alloc_comp(X, Y, Z) crypto_alloc_tfm(X, mode)
  8649. + #define plain(X) #X , 0
  8650. +#else
  8651. + #define ecb(X) "ecb(" #X ")" , 0
  8652. + #define cbc(X) "cbc(" #X ")" , 0
  8653. + #define hmac(X) "hmac(" #X ")" , 0
  8654. + #define plain(X) #X , 0
  8655. +#endif /* if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
  8656. +
  8657. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
  8658. +/* no ablkcipher in older kernels */
  8659. +#define crypto_alloc_ablkcipher(a,b,c) (NULL)
  8660. +#define crypto_ablkcipher_tfm(x) ((struct crypto_tfm *)(x))
  8661. +#define crypto_ablkcipher_set_flags(a, b) /* nop */
  8662. +#define crypto_ablkcipher_setkey(x, y, z) (-EINVAL)
  8663. +#define crypto_has_ablkcipher(a,b,c) (0)
  8664. +#else
  8665. +#define HAVE_ABLKCIPHER
  8666. +#endif
  8667. +
  8668. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
  8669. +/* no ahash in older kernels */
  8670. +#define crypto_ahash_tfm(x) ((struct crypto_tfm *)(x))
  8671. +#define crypto_alloc_ahash(a,b,c) (NULL)
  8672. +#define crypto_ahash_digestsize(x) 0
  8673. +#else
  8674. +#define HAVE_AHASH
  8675. +#endif
  8676. +
  8677. +struct crypto_details {
  8678. + char *alg_name;
  8679. + int mode;
  8680. + int sw_type;
  8681. +};
  8682. +
  8683. +static struct crypto_details crypto_details[] = {
  8684. + [CRYPTO_DES_CBC] = { cbc(des), SW_TYPE_BLKCIPHER, },
  8685. + [CRYPTO_3DES_CBC] = { cbc(des3_ede), SW_TYPE_BLKCIPHER, },
  8686. + [CRYPTO_BLF_CBC] = { cbc(blowfish), SW_TYPE_BLKCIPHER, },
  8687. + [CRYPTO_CAST_CBC] = { cbc(cast5), SW_TYPE_BLKCIPHER, },
  8688. + [CRYPTO_SKIPJACK_CBC] = { cbc(skipjack), SW_TYPE_BLKCIPHER, },
  8689. + [CRYPTO_MD5_HMAC] = { hmac(md5), SW_TYPE_HMAC, },
  8690. + [CRYPTO_SHA1_HMAC] = { hmac(sha1), SW_TYPE_HMAC, },
  8691. + [CRYPTO_RIPEMD160_HMAC] = { hmac(ripemd160), SW_TYPE_HMAC, },
  8692. + [CRYPTO_MD5_KPDK] = { plain(md5-kpdk), SW_TYPE_HASH, },
  8693. + [CRYPTO_SHA1_KPDK] = { plain(sha1-kpdk), SW_TYPE_HASH, },
  8694. + [CRYPTO_AES_CBC] = { cbc(aes), SW_TYPE_BLKCIPHER, },
  8695. + [CRYPTO_ARC4] = { ecb(arc4), SW_TYPE_BLKCIPHER, },
  8696. + [CRYPTO_MD5] = { plain(md5), SW_TYPE_HASH, },
  8697. + [CRYPTO_SHA1] = { plain(sha1), SW_TYPE_HASH, },
  8698. + [CRYPTO_NULL_HMAC] = { hmac(digest_null), SW_TYPE_HMAC, },
  8699. + [CRYPTO_NULL_CBC] = { cbc(cipher_null), SW_TYPE_BLKCIPHER, },
  8700. + [CRYPTO_DEFLATE_COMP] = { plain(deflate), SW_TYPE_COMP, },
  8701. + [CRYPTO_SHA2_256_HMAC] = { hmac(sha256), SW_TYPE_HMAC, },
  8702. + [CRYPTO_SHA2_384_HMAC] = { hmac(sha384), SW_TYPE_HMAC, },
  8703. + [CRYPTO_SHA2_512_HMAC] = { hmac(sha512), SW_TYPE_HMAC, },
  8704. + [CRYPTO_CAMELLIA_CBC] = { cbc(camellia), SW_TYPE_BLKCIPHER, },
  8705. + [CRYPTO_SHA2_256] = { plain(sha256), SW_TYPE_HASH, },
  8706. + [CRYPTO_SHA2_384] = { plain(sha384), SW_TYPE_HASH, },
  8707. + [CRYPTO_SHA2_512] = { plain(sha512), SW_TYPE_HASH, },
  8708. + [CRYPTO_RIPEMD160] = { plain(ripemd160), SW_TYPE_HASH, },
  8709. +};
  8710. +
  8711. +int32_t swcr_id = -1;
  8712. +module_param(swcr_id, int, 0444);
  8713. +MODULE_PARM_DESC(swcr_id, "Read-Only OCF ID for cryptosoft driver");
  8714. +
  8715. +int swcr_fail_if_compression_grows = 1;
  8716. +module_param(swcr_fail_if_compression_grows, int, 0644);
  8717. +MODULE_PARM_DESC(swcr_fail_if_compression_grows,
  8718. + "Treat compression that results in more data as a failure");
  8719. +
  8720. +int swcr_no_ahash = 0;
  8721. +module_param(swcr_no_ahash, int, 0644);
  8722. +MODULE_PARM_DESC(swcr_no_ahash,
  8723. + "Do not use async hash/hmac even if available");
  8724. +
  8725. +int swcr_no_ablk = 0;
  8726. +module_param(swcr_no_ablk, int, 0644);
  8727. +MODULE_PARM_DESC(swcr_no_ablk,
  8728. + "Do not use async blk ciphers even if available");
  8729. +
  8730. +static struct swcr_data **swcr_sessions = NULL;
  8731. +static u_int32_t swcr_sesnum = 0;
  8732. +
  8733. +static int swcr_process(device_t, struct cryptop *, int);
  8734. +static int swcr_newsession(device_t, u_int32_t *, struct cryptoini *);
  8735. +static int swcr_freesession(device_t, u_int64_t);
  8736. +
  8737. +static device_method_t swcr_methods = {
  8738. + /* crypto device methods */
  8739. + DEVMETHOD(cryptodev_newsession, swcr_newsession),
  8740. + DEVMETHOD(cryptodev_freesession,swcr_freesession),
  8741. + DEVMETHOD(cryptodev_process, swcr_process),
  8742. +};
  8743. +
  8744. +#define debug swcr_debug
  8745. +int swcr_debug = 0;
  8746. +module_param(swcr_debug, int, 0644);
  8747. +MODULE_PARM_DESC(swcr_debug, "Enable debug");
  8748. +
  8749. +static void swcr_process_req(struct swcr_req *req);
  8750. +
  8751. +/*
  8752. + * Generate a new software session.
  8753. + */
  8754. +static int
  8755. +swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  8756. +{
  8757. + struct swcr_data **swd;
  8758. + u_int32_t i;
  8759. + int error;
  8760. + char *algo;
  8761. + int mode;
  8762. +
  8763. + dprintk("%s()\n", __FUNCTION__);
  8764. + if (sid == NULL || cri == NULL) {
  8765. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  8766. + return EINVAL;
  8767. + }
  8768. +
  8769. + if (swcr_sessions) {
  8770. + for (i = 1; i < swcr_sesnum; i++)
  8771. + if (swcr_sessions[i] == NULL)
  8772. + break;
  8773. + } else
  8774. + i = 1; /* NB: to silence compiler warning */
  8775. +
  8776. + if (swcr_sessions == NULL || i == swcr_sesnum) {
  8777. + if (swcr_sessions == NULL) {
  8778. + i = 1; /* We leave swcr_sessions[0] empty */
  8779. + swcr_sesnum = CRYPTO_SW_SESSIONS;
  8780. + } else
  8781. + swcr_sesnum *= 2;
  8782. +
  8783. + swd = kmalloc(swcr_sesnum * sizeof(struct swcr_data *), SLAB_ATOMIC);
  8784. + if (swd == NULL) {
  8785. + /* Reset session number */
  8786. + if (swcr_sesnum == CRYPTO_SW_SESSIONS)
  8787. + swcr_sesnum = 0;
  8788. + else
  8789. + swcr_sesnum /= 2;
  8790. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  8791. + return ENOBUFS;
  8792. + }
  8793. + memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *));
  8794. +
  8795. + /* Copy existing sessions */
  8796. + if (swcr_sessions) {
  8797. + memcpy(swd, swcr_sessions,
  8798. + (swcr_sesnum / 2) * sizeof(struct swcr_data *));
  8799. + kfree(swcr_sessions);
  8800. + }
  8801. +
  8802. + swcr_sessions = swd;
  8803. + }
  8804. +
  8805. + swd = &swcr_sessions[i];
  8806. + *sid = i;
  8807. +
  8808. + while (cri) {
  8809. + *swd = (struct swcr_data *) kmalloc(sizeof(struct swcr_data),
  8810. + SLAB_ATOMIC);
  8811. + if (*swd == NULL) {
  8812. + swcr_freesession(NULL, i);
  8813. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  8814. + return ENOBUFS;
  8815. + }
  8816. + memset(*swd, 0, sizeof(struct swcr_data));
  8817. +
  8818. + if (cri->cri_alg < 0 ||
  8819. + cri->cri_alg>=sizeof(crypto_details)/sizeof(crypto_details[0])){
  8820. + printk("cryptosoft: Unknown algorithm 0x%x\n", cri->cri_alg);
  8821. + swcr_freesession(NULL, i);
  8822. + return EINVAL;
  8823. + }
  8824. +
  8825. + algo = crypto_details[cri->cri_alg].alg_name;
  8826. + if (!algo || !*algo) {
  8827. + printk("cryptosoft: Unsupported algorithm 0x%x\n", cri->cri_alg);
  8828. + swcr_freesession(NULL, i);
  8829. + return EINVAL;
  8830. + }
  8831. +
  8832. + mode = crypto_details[cri->cri_alg].mode;
  8833. + (*swd)->sw_type = crypto_details[cri->cri_alg].sw_type;
  8834. + (*swd)->sw_alg = cri->cri_alg;
  8835. +
  8836. + /* Algorithm specific configuration */
  8837. + switch (cri->cri_alg) {
  8838. + case CRYPTO_NULL_CBC:
  8839. + cri->cri_klen = 0; /* make it work with crypto API */
  8840. + break;
  8841. + default:
  8842. + break;
  8843. + }
  8844. +
  8845. + if ((*swd)->sw_type & SW_TYPE_BLKCIPHER) {
  8846. + dprintk("%s crypto_alloc_*blkcipher(%s, 0x%x)\n", __FUNCTION__,
  8847. + algo, mode);
  8848. +
  8849. + /* try async first */
  8850. + (*swd)->sw_tfm = swcr_no_ablk ? NULL :
  8851. + crypto_ablkcipher_tfm(crypto_alloc_ablkcipher(algo, 0, 0));
  8852. + if ((*swd)->sw_tfm) {
  8853. + dprintk("%s %s cipher is async\n", __FUNCTION__, algo);
  8854. + (*swd)->sw_type |= SW_TYPE_ASYNC;
  8855. + } else {
  8856. + dprintk("%s %s cipher is sync\n", __FUNCTION__, algo);
  8857. + (*swd)->sw_tfm = crypto_blkcipher_tfm(
  8858. + crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC));
  8859. + }
  8860. + if (!(*swd)->sw_tfm) {
  8861. + dprintk("cryptosoft: crypto_alloc_blkcipher failed(%s, 0x%x)\n",
  8862. + algo,mode);
  8863. + swcr_freesession(NULL, i);
  8864. + return EINVAL;
  8865. + }
  8866. +
  8867. + if (debug) {
  8868. + dprintk("%s key:cri->cri_klen=%d,(cri->cri_klen + 7)/8=%d",
  8869. + __FUNCTION__, cri->cri_klen, (cri->cri_klen + 7) / 8);
  8870. + for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
  8871. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  8872. + cri->cri_key[i] & 0xff);
  8873. + dprintk("\n");
  8874. + }
  8875. + if ((*swd)->sw_type & SW_TYPE_ASYNC) {
  8876. + /* OCF doesn't enforce keys */
  8877. + crypto_ablkcipher_set_flags(
  8878. + __crypto_ablkcipher_cast((*swd)->sw_tfm),
  8879. + CRYPTO_TFM_REQ_WEAK_KEY);
  8880. + error = crypto_ablkcipher_setkey(
  8881. + __crypto_ablkcipher_cast((*swd)->sw_tfm),
  8882. + cri->cri_key, (cri->cri_klen + 7) / 8);
  8883. + } else {
  8884. + /* OCF doesn't enforce keys */
  8885. + crypto_blkcipher_set_flags(
  8886. + crypto_blkcipher_cast((*swd)->sw_tfm),
  8887. + CRYPTO_TFM_REQ_WEAK_KEY);
  8888. + error = crypto_blkcipher_setkey(
  8889. + crypto_blkcipher_cast((*swd)->sw_tfm),
  8890. + cri->cri_key, (cri->cri_klen + 7) / 8);
  8891. + }
  8892. + if (error) {
  8893. + printk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n", error,
  8894. + (*swd)->sw_tfm->crt_flags);
  8895. + swcr_freesession(NULL, i);
  8896. + return error;
  8897. + }
  8898. + } else if ((*swd)->sw_type & (SW_TYPE_HMAC | SW_TYPE_HASH)) {
  8899. + dprintk("%s crypto_alloc_*hash(%s, 0x%x)\n", __FUNCTION__,
  8900. + algo, mode);
  8901. +
  8902. + /* try async first */
  8903. + (*swd)->sw_tfm = swcr_no_ahash ? NULL :
  8904. + crypto_ahash_tfm(crypto_alloc_ahash(algo, 0, 0));
  8905. + if ((*swd)->sw_tfm) {
  8906. + dprintk("%s %s hash is async\n", __FUNCTION__, algo);
  8907. + (*swd)->sw_type |= SW_TYPE_ASYNC;
  8908. + } else {
  8909. + dprintk("%s %s hash is sync\n", __FUNCTION__, algo);
  8910. + (*swd)->sw_tfm = crypto_hash_tfm(
  8911. + crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC));
  8912. + }
  8913. +
  8914. + if (!(*swd)->sw_tfm) {
  8915. + dprintk("cryptosoft: crypto_alloc_hash failed(%s,0x%x)\n",
  8916. + algo, mode);
  8917. + swcr_freesession(NULL, i);
  8918. + return EINVAL;
  8919. + }
  8920. +
  8921. + (*swd)->u.hmac.sw_klen = (cri->cri_klen + 7) / 8;
  8922. + (*swd)->u.hmac.sw_key = (char *)kmalloc((*swd)->u.hmac.sw_klen,
  8923. + SLAB_ATOMIC);
  8924. + if ((*swd)->u.hmac.sw_key == NULL) {
  8925. + swcr_freesession(NULL, i);
  8926. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  8927. + return ENOBUFS;
  8928. + }
  8929. + memcpy((*swd)->u.hmac.sw_key, cri->cri_key, (*swd)->u.hmac.sw_klen);
  8930. + if (cri->cri_mlen) {
  8931. + (*swd)->u.hmac.sw_mlen = cri->cri_mlen;
  8932. + } else if ((*swd)->sw_type & SW_TYPE_ASYNC) {
  8933. + (*swd)->u.hmac.sw_mlen = crypto_ahash_digestsize(
  8934. + __crypto_ahash_cast((*swd)->sw_tfm));
  8935. + } else {
  8936. + (*swd)->u.hmac.sw_mlen = crypto_hash_digestsize(
  8937. + crypto_hash_cast((*swd)->sw_tfm));
  8938. + }
  8939. + } else if ((*swd)->sw_type & SW_TYPE_COMP) {
  8940. + (*swd)->sw_tfm = crypto_comp_tfm(
  8941. + crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC));
  8942. + if (!(*swd)->sw_tfm) {
  8943. + dprintk("cryptosoft: crypto_alloc_comp failed(%s,0x%x)\n",
  8944. + algo, mode);
  8945. + swcr_freesession(NULL, i);
  8946. + return EINVAL;
  8947. + }
  8948. + (*swd)->u.sw_comp_buf = kmalloc(CRYPTO_MAX_DATA_LEN, SLAB_ATOMIC);
  8949. + if ((*swd)->u.sw_comp_buf == NULL) {
  8950. + swcr_freesession(NULL, i);
  8951. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  8952. + return ENOBUFS;
  8953. + }
  8954. + } else {
  8955. + printk("cryptosoft: Unhandled sw_type %d\n", (*swd)->sw_type);
  8956. + swcr_freesession(NULL, i);
  8957. + return EINVAL;
  8958. + }
  8959. +
  8960. + cri = cri->cri_next;
  8961. + swd = &((*swd)->sw_next);
  8962. + }
  8963. + return 0;
  8964. +}
  8965. +
  8966. +/*
  8967. + * Free a session.
  8968. + */
  8969. +static int
  8970. +swcr_freesession(device_t dev, u_int64_t tid)
  8971. +{
  8972. + struct swcr_data *swd;
  8973. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  8974. +
  8975. + dprintk("%s()\n", __FUNCTION__);
  8976. + if (sid > swcr_sesnum || swcr_sessions == NULL ||
  8977. + swcr_sessions[sid] == NULL) {
  8978. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8979. + return(EINVAL);
  8980. + }
  8981. +
  8982. + /* Silently accept and return */
  8983. + if (sid == 0)
  8984. + return(0);
  8985. +
  8986. + while ((swd = swcr_sessions[sid]) != NULL) {
  8987. + swcr_sessions[sid] = swd->sw_next;
  8988. + if (swd->sw_tfm) {
  8989. + switch (swd->sw_type & SW_TYPE_ALG_AMASK) {
  8990. +#ifdef HAVE_AHASH
  8991. + case SW_TYPE_AHMAC:
  8992. + case SW_TYPE_AHASH:
  8993. + crypto_free_ahash(__crypto_ahash_cast(swd->sw_tfm));
  8994. + break;
  8995. +#endif
  8996. +#ifdef HAVE_ABLKCIPHER
  8997. + case SW_TYPE_ABLKCIPHER:
  8998. + crypto_free_ablkcipher(__crypto_ablkcipher_cast(swd->sw_tfm));
  8999. + break;
  9000. +#endif
  9001. + case SW_TYPE_BLKCIPHER:
  9002. + crypto_free_blkcipher(crypto_blkcipher_cast(swd->sw_tfm));
  9003. + break;
  9004. + case SW_TYPE_HMAC:
  9005. + case SW_TYPE_HASH:
  9006. + crypto_free_hash(crypto_hash_cast(swd->sw_tfm));
  9007. + break;
  9008. + case SW_TYPE_COMP:
  9009. + crypto_free_comp(crypto_comp_cast(swd->sw_tfm));
  9010. + default:
  9011. + crypto_free_tfm(swd->sw_tfm);
  9012. + break;
  9013. + }
  9014. + swd->sw_tfm = NULL;
  9015. + }
  9016. + if (swd->sw_type & SW_TYPE_COMP) {
  9017. + if (swd->u.sw_comp_buf)
  9018. + kfree(swd->u.sw_comp_buf);
  9019. + } else {
  9020. + if (swd->u.hmac.sw_key)
  9021. + kfree(swd->u.hmac.sw_key);
  9022. + }
  9023. + kfree(swd);
  9024. + }
  9025. + return 0;
  9026. +}
  9027. +
  9028. +#if defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH)
  9029. +/* older kernels had no async interface */
  9030. +
  9031. +static void swcr_process_callback(struct crypto_async_request *creq, int err)
  9032. +{
  9033. + struct swcr_req *req = creq->data;
  9034. +
  9035. + dprintk("%s()\n", __FUNCTION__);
  9036. + if (err) {
  9037. + if (err == -EINPROGRESS)
  9038. + return;
  9039. + dprintk("%s() fail %d\n", __FUNCTION__, -err);
  9040. + req->crp->crp_etype = -err;
  9041. + goto done;
  9042. + }
  9043. +
  9044. + switch (req->sw->sw_type & SW_TYPE_ALG_AMASK) {
  9045. + case SW_TYPE_AHMAC:
  9046. + case SW_TYPE_AHASH:
  9047. + crypto_copyback(req->crp->crp_flags, req->crp->crp_buf,
  9048. + req->crd->crd_inject, req->sw->u.hmac.sw_mlen, req->result);
  9049. + ahash_request_free(req->crypto_req);
  9050. + break;
  9051. + case SW_TYPE_ABLKCIPHER:
  9052. + ablkcipher_request_free(req->crypto_req);
  9053. + break;
  9054. + default:
  9055. + req->crp->crp_etype = EINVAL;
  9056. + goto done;
  9057. + }
  9058. +
  9059. + req->crd = req->crd->crd_next;
  9060. + if (req->crd) {
  9061. + swcr_process_req(req);
  9062. + return;
  9063. + }
  9064. +
  9065. +done:
  9066. + dprintk("%s crypto_done %p\n", __FUNCTION__, req);
  9067. + crypto_done(req->crp);
  9068. + kmem_cache_free(swcr_req_cache, req);
  9069. +}
  9070. +#endif /* defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH) */
  9071. +
  9072. +
  9073. +static void swcr_process_req(struct swcr_req *req)
  9074. +{
  9075. + struct swcr_data *sw;
  9076. + struct cryptop *crp = req->crp;
  9077. + struct cryptodesc *crd = req->crd;
  9078. + struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
  9079. + struct uio *uiop = (struct uio *) crp->crp_buf;
  9080. + int sg_num, sg_len, skip;
  9081. +
  9082. + dprintk("%s()\n", __FUNCTION__);
  9083. +
  9084. + /*
  9085. + * Find the crypto context.
  9086. + *
  9087. + * XXX Note that the logic here prevents us from having
  9088. + * XXX the same algorithm multiple times in a session
  9089. + * XXX (or rather, we can but it won't give us the right
  9090. + * XXX results). To do that, we'd need some way of differentiating
  9091. + * XXX between the various instances of an algorithm (so we can
  9092. + * XXX locate the correct crypto context).
  9093. + */
  9094. + for (sw = req->sw_head; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next)
  9095. + ;
  9096. +
  9097. + /* No such context ? */
  9098. + if (sw == NULL) {
  9099. + crp->crp_etype = EINVAL;
  9100. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  9101. + goto done;
  9102. + }
  9103. +
  9104. + req->sw = sw;
  9105. + skip = crd->crd_skip;
  9106. +
  9107. + /*
  9108. + * setup the SG list skip from the start of the buffer
  9109. + */
  9110. + memset(req->sg, 0, sizeof(req->sg));
  9111. + sg_init_table(req->sg, SCATTERLIST_MAX);
  9112. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  9113. + int i, len;
  9114. +
  9115. + sg_num = 0;
  9116. + sg_len = 0;
  9117. +
  9118. + if (skip < skb_headlen(skb)) {
  9119. + len = skb_headlen(skb) - skip;
  9120. + if (len + sg_len > crd->crd_len)
  9121. + len = crd->crd_len - sg_len;
  9122. + sg_set_page(&req->sg[sg_num],
  9123. + virt_to_page(skb->data + skip), len,
  9124. + offset_in_page(skb->data + skip));
  9125. + sg_len += len;
  9126. + sg_num++;
  9127. + skip = 0;
  9128. + } else
  9129. + skip -= skb_headlen(skb);
  9130. +
  9131. + for (i = 0; sg_len < crd->crd_len &&
  9132. + i < skb_shinfo(skb)->nr_frags &&
  9133. + sg_num < SCATTERLIST_MAX; i++) {
  9134. + if (skip < skb_shinfo(skb)->frags[i].size) {
  9135. + len = skb_shinfo(skb)->frags[i].size - skip;
  9136. + if (len + sg_len > crd->crd_len)
  9137. + len = crd->crd_len - sg_len;
  9138. + sg_set_page(&req->sg[sg_num],
  9139. + skb_shinfo(skb)->frags[i].page,
  9140. + len,
  9141. + skb_shinfo(skb)->frags[i].page_offset + skip);
  9142. + sg_len += len;
  9143. + sg_num++;
  9144. + skip = 0;
  9145. + } else
  9146. + skip -= skb_shinfo(skb)->frags[i].size;
  9147. + }
  9148. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  9149. + int len;
  9150. +
  9151. + sg_len = 0;
  9152. + for (sg_num = 0; sg_len < crd->crd_len &&
  9153. + sg_num < uiop->uio_iovcnt &&
  9154. + sg_num < SCATTERLIST_MAX; sg_num++) {
  9155. + if (skip <= uiop->uio_iov[sg_num].iov_len) {
  9156. + len = uiop->uio_iov[sg_num].iov_len - skip;
  9157. + if (len + sg_len > crd->crd_len)
  9158. + len = crd->crd_len - sg_len;
  9159. + sg_set_page(&req->sg[sg_num],
  9160. + virt_to_page(uiop->uio_iov[sg_num].iov_base+skip),
  9161. + len,
  9162. + offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
  9163. + sg_len += len;
  9164. + skip = 0;
  9165. + } else
  9166. + skip -= uiop->uio_iov[sg_num].iov_len;
  9167. + }
  9168. + } else {
  9169. + sg_len = (crp->crp_ilen - skip);
  9170. + if (sg_len > crd->crd_len)
  9171. + sg_len = crd->crd_len;
  9172. + sg_set_page(&req->sg[0], virt_to_page(crp->crp_buf + skip),
  9173. + sg_len, offset_in_page(crp->crp_buf + skip));
  9174. + sg_num = 1;
  9175. + }
  9176. +
  9177. + switch (sw->sw_type & SW_TYPE_ALG_AMASK) {
  9178. +
  9179. +#ifdef HAVE_AHASH
  9180. + case SW_TYPE_AHMAC:
  9181. + case SW_TYPE_AHASH:
  9182. + {
  9183. + int ret;
  9184. +
  9185. + /* check we have room for the result */
  9186. + if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
  9187. + dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
  9188. + "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
  9189. + crd->crd_inject, sw->u.hmac.sw_mlen);
  9190. + crp->crp_etype = EINVAL;
  9191. + goto done;
  9192. + }
  9193. +
  9194. + req->crypto_req =
  9195. + ahash_request_alloc(__crypto_ahash_cast(sw->sw_tfm),GFP_KERNEL);
  9196. + if (!req->crypto_req) {
  9197. + crp->crp_etype = ENOMEM;
  9198. + dprintk("%s,%d: ENOMEM ahash_request_alloc", __FILE__, __LINE__);
  9199. + goto done;
  9200. + }
  9201. +
  9202. + ahash_request_set_callback(req->crypto_req,
  9203. + CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
  9204. +
  9205. + memset(req->result, 0, sizeof(req->result));
  9206. +
  9207. + if (sw->sw_type & SW_TYPE_AHMAC)
  9208. + crypto_ahash_setkey(__crypto_ahash_cast(sw->sw_tfm),
  9209. + sw->u.hmac.sw_key, sw->u.hmac.sw_klen);
  9210. + ahash_request_set_crypt(req->crypto_req, req->sg, req->result, sg_len);
  9211. + ret = crypto_ahash_digest(req->crypto_req);
  9212. + switch (ret) {
  9213. + case -EINPROGRESS:
  9214. + case -EBUSY:
  9215. + return;
  9216. + default:
  9217. + case 0:
  9218. + dprintk("hash OP %s %d\n", ret ? "failed" : "success", ret);
  9219. + crp->crp_etype = ret;
  9220. + ahash_request_free(req->crypto_req);
  9221. + goto done;
  9222. + }
  9223. + } break;
  9224. +#endif /* HAVE_AHASH */
  9225. +
  9226. +#ifdef HAVE_ABLKCIPHER
  9227. + case SW_TYPE_ABLKCIPHER: {
  9228. + int ret;
  9229. + unsigned char *ivp = req->iv;
  9230. + int ivsize =
  9231. + crypto_ablkcipher_ivsize(__crypto_ablkcipher_cast(sw->sw_tfm));
  9232. +
  9233. + if (sg_len < crypto_ablkcipher_blocksize(
  9234. + __crypto_ablkcipher_cast(sw->sw_tfm))) {
  9235. + crp->crp_etype = EINVAL;
  9236. + dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
  9237. + sg_len, crypto_ablkcipher_blocksize(
  9238. + __crypto_ablkcipher_cast(sw->sw_tfm)));
  9239. + goto done;
  9240. + }
  9241. +
  9242. + if (ivsize > sizeof(req->iv)) {
  9243. + crp->crp_etype = EINVAL;
  9244. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  9245. + goto done;
  9246. + }
  9247. +
  9248. + req->crypto_req = ablkcipher_request_alloc(
  9249. + __crypto_ablkcipher_cast(sw->sw_tfm), GFP_KERNEL);
  9250. + if (!req->crypto_req) {
  9251. + crp->crp_etype = ENOMEM;
  9252. + dprintk("%s,%d: ENOMEM ablkcipher_request_alloc",
  9253. + __FILE__, __LINE__);
  9254. + goto done;
  9255. + }
  9256. +
  9257. + ablkcipher_request_set_callback(req->crypto_req,
  9258. + CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
  9259. +
  9260. + if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
  9261. + int i, error;
  9262. +
  9263. + if (debug) {
  9264. + dprintk("%s key:", __FUNCTION__);
  9265. + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
  9266. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  9267. + crd->crd_key[i] & 0xff);
  9268. + dprintk("\n");
  9269. + }
  9270. + /* OCF doesn't enforce keys */
  9271. + crypto_ablkcipher_set_flags(__crypto_ablkcipher_cast(sw->sw_tfm),
  9272. + CRYPTO_TFM_REQ_WEAK_KEY);
  9273. + error = crypto_ablkcipher_setkey(
  9274. + __crypto_ablkcipher_cast(sw->sw_tfm), crd->crd_key,
  9275. + (crd->crd_klen + 7) / 8);
  9276. + if (error) {
  9277. + dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
  9278. + error, sw->sw_tfm->crt_flags);
  9279. + crp->crp_etype = -error;
  9280. + }
  9281. + }
  9282. +
  9283. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  9284. +
  9285. + if (crd->crd_flags & CRD_F_IV_EXPLICIT)
  9286. + ivp = crd->crd_iv;
  9287. + else
  9288. + get_random_bytes(ivp, ivsize);
  9289. + /*
  9290. + * do we have to copy the IV back to the buffer ?
  9291. + */
  9292. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  9293. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  9294. + crd->crd_inject, ivsize, (caddr_t)ivp);
  9295. + }
  9296. + ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
  9297. + sg_len, ivp);
  9298. + ret = crypto_ablkcipher_encrypt(req->crypto_req);
  9299. +
  9300. + } else { /*decrypt */
  9301. +
  9302. + if (crd->crd_flags & CRD_F_IV_EXPLICIT)
  9303. + ivp = crd->crd_iv;
  9304. + else
  9305. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  9306. + crd->crd_inject, ivsize, (caddr_t)ivp);
  9307. + ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
  9308. + sg_len, ivp);
  9309. + ret = crypto_ablkcipher_decrypt(req->crypto_req);
  9310. + }
  9311. +
  9312. + switch (ret) {
  9313. + case -EINPROGRESS:
  9314. + case -EBUSY:
  9315. + return;
  9316. + default:
  9317. + case 0:
  9318. + dprintk("crypto OP %s %d\n", ret ? "failed" : "success", ret);
  9319. + crp->crp_etype = ret;
  9320. + goto done;
  9321. + }
  9322. + } break;
  9323. +#endif /* HAVE_ABLKCIPHER */
  9324. +
  9325. + case SW_TYPE_BLKCIPHER: {
  9326. + unsigned char iv[EALG_MAX_BLOCK_LEN];
  9327. + unsigned char *ivp = iv;
  9328. + struct blkcipher_desc desc;
  9329. + int ivsize = crypto_blkcipher_ivsize(crypto_blkcipher_cast(sw->sw_tfm));
  9330. +
  9331. + if (sg_len < crypto_blkcipher_blocksize(
  9332. + crypto_blkcipher_cast(sw->sw_tfm))) {
  9333. + crp->crp_etype = EINVAL;
  9334. + dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
  9335. + sg_len, crypto_blkcipher_blocksize(
  9336. + crypto_blkcipher_cast(sw->sw_tfm)));
  9337. + goto done;
  9338. + }
  9339. +
  9340. + if (ivsize > sizeof(iv)) {
  9341. + crp->crp_etype = EINVAL;
  9342. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  9343. + goto done;
  9344. + }
  9345. +
  9346. + if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
  9347. + int i, error;
  9348. +
  9349. + if (debug) {
  9350. + dprintk("%s key:", __FUNCTION__);
  9351. + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
  9352. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  9353. + crd->crd_key[i] & 0xff);
  9354. + dprintk("\n");
  9355. + }
  9356. + /* OCF doesn't enforce keys */
  9357. + crypto_blkcipher_set_flags(crypto_blkcipher_cast(sw->sw_tfm),
  9358. + CRYPTO_TFM_REQ_WEAK_KEY);
  9359. + error = crypto_blkcipher_setkey(
  9360. + crypto_blkcipher_cast(sw->sw_tfm), crd->crd_key,
  9361. + (crd->crd_klen + 7) / 8);
  9362. + if (error) {
  9363. + dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
  9364. + error, sw->sw_tfm->crt_flags);
  9365. + crp->crp_etype = -error;
  9366. + }
  9367. + }
  9368. +
  9369. + memset(&desc, 0, sizeof(desc));
  9370. + desc.tfm = crypto_blkcipher_cast(sw->sw_tfm);
  9371. +
  9372. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  9373. +
  9374. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  9375. + ivp = crd->crd_iv;
  9376. + } else {
  9377. + get_random_bytes(ivp, ivsize);
  9378. + }
  9379. + /*
  9380. + * do we have to copy the IV back to the buffer ?
  9381. + */
  9382. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  9383. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  9384. + crd->crd_inject, ivsize, (caddr_t)ivp);
  9385. + }
  9386. + desc.info = ivp;
  9387. + crypto_blkcipher_encrypt_iv(&desc, req->sg, req->sg, sg_len);
  9388. +
  9389. + } else { /*decrypt */
  9390. +
  9391. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  9392. + ivp = crd->crd_iv;
  9393. + } else {
  9394. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  9395. + crd->crd_inject, ivsize, (caddr_t)ivp);
  9396. + }
  9397. + desc.info = ivp;
  9398. + crypto_blkcipher_decrypt_iv(&desc, req->sg, req->sg, sg_len);
  9399. + }
  9400. + } break;
  9401. +
  9402. + case SW_TYPE_HMAC:
  9403. + case SW_TYPE_HASH:
  9404. + {
  9405. + char result[HASH_MAX_LEN];
  9406. + struct hash_desc desc;
  9407. +
  9408. + /* check we have room for the result */
  9409. + if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
  9410. + dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
  9411. + "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
  9412. + crd->crd_inject, sw->u.hmac.sw_mlen);
  9413. + crp->crp_etype = EINVAL;
  9414. + goto done;
  9415. + }
  9416. +
  9417. + memset(&desc, 0, sizeof(desc));
  9418. + desc.tfm = crypto_hash_cast(sw->sw_tfm);
  9419. +
  9420. + memset(result, 0, sizeof(result));
  9421. +
  9422. + if (sw->sw_type & SW_TYPE_HMAC) {
  9423. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
  9424. + crypto_hmac(sw->sw_tfm, sw->u.hmac.sw_key, &sw->u.hmac.sw_klen,
  9425. + req->sg, sg_num, result);
  9426. +#else
  9427. + crypto_hash_setkey(desc.tfm, sw->u.hmac.sw_key,
  9428. + sw->u.hmac.sw_klen);
  9429. + crypto_hash_digest(&desc, req->sg, sg_len, result);
  9430. +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
  9431. +
  9432. + } else { /* SW_TYPE_HASH */
  9433. + crypto_hash_digest(&desc, req->sg, sg_len, result);
  9434. + }
  9435. +
  9436. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  9437. + crd->crd_inject, sw->u.hmac.sw_mlen, result);
  9438. + }
  9439. + break;
  9440. +
  9441. + case SW_TYPE_COMP: {
  9442. + void *ibuf = NULL;
  9443. + void *obuf = sw->u.sw_comp_buf;
  9444. + int ilen = sg_len, olen = CRYPTO_MAX_DATA_LEN;
  9445. + int ret = 0;
  9446. +
  9447. + /*
  9448. + * we need to use an additional copy if there is more than one
  9449. + * input chunk since the kernel comp routines do not handle
  9450. + * SG yet. Otherwise we just use the input buffer as is.
  9451. + * Rather than allocate another buffer we just split the tmp
  9452. + * buffer we already have.
  9453. + * Perhaps we should just use zlib directly ?
  9454. + */
  9455. + if (sg_num > 1) {
  9456. + int blk;
  9457. +
  9458. + ibuf = obuf;
  9459. + for (blk = 0; blk < sg_num; blk++) {
  9460. + memcpy(obuf, sg_virt(&req->sg[blk]),
  9461. + req->sg[blk].length);
  9462. + obuf += req->sg[blk].length;
  9463. + }
  9464. + olen -= sg_len;
  9465. + } else
  9466. + ibuf = sg_virt(&req->sg[0]);
  9467. +
  9468. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* compress */
  9469. + ret = crypto_comp_compress(crypto_comp_cast(sw->sw_tfm),
  9470. + ibuf, ilen, obuf, &olen);
  9471. + if (!ret && olen > crd->crd_len) {
  9472. + dprintk("cryptosoft: ERANGE compress %d into %d\n",
  9473. + crd->crd_len, olen);
  9474. + if (swcr_fail_if_compression_grows)
  9475. + ret = ERANGE;
  9476. + }
  9477. + } else { /* decompress */
  9478. + ret = crypto_comp_decompress(crypto_comp_cast(sw->sw_tfm),
  9479. + ibuf, ilen, obuf, &olen);
  9480. + if (!ret && (olen + crd->crd_inject) > crp->crp_olen) {
  9481. + dprintk("cryptosoft: ETOOSMALL decompress %d into %d, "
  9482. + "space for %d,at offset %d\n",
  9483. + crd->crd_len, olen, crp->crp_olen, crd->crd_inject);
  9484. + ret = ETOOSMALL;
  9485. + }
  9486. + }
  9487. + if (ret)
  9488. + dprintk("%s,%d: ret = %d\n", __FILE__, __LINE__, ret);
  9489. +
  9490. + /*
  9491. + * on success copy result back,
  9492. + * linux crpyto API returns -errno, we need to fix that
  9493. + */
  9494. + crp->crp_etype = ret < 0 ? -ret : ret;
  9495. + if (ret == 0) {
  9496. + /* copy back the result and return it's size */
  9497. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  9498. + crd->crd_inject, olen, obuf);
  9499. + crp->crp_olen = olen;
  9500. + }
  9501. +
  9502. +
  9503. + } break;
  9504. +
  9505. + default:
  9506. + /* Unknown/unsupported algorithm */
  9507. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  9508. + crp->crp_etype = EINVAL;
  9509. + goto done;
  9510. + }
  9511. +
  9512. +done:
  9513. + crypto_done(crp);
  9514. + kmem_cache_free(swcr_req_cache, req);
  9515. +}
  9516. +
  9517. +
  9518. +/*
  9519. + * Process a crypto request.
  9520. + */
  9521. +static int
  9522. +swcr_process(device_t dev, struct cryptop *crp, int hint)
  9523. +{
  9524. + struct swcr_req *req = NULL;
  9525. + u_int32_t lid;
  9526. +
  9527. + dprintk("%s()\n", __FUNCTION__);
  9528. + /* Sanity check */
  9529. + if (crp == NULL) {
  9530. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  9531. + return EINVAL;
  9532. + }
  9533. +
  9534. + crp->crp_etype = 0;
  9535. +
  9536. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  9537. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  9538. + crp->crp_etype = EINVAL;
  9539. + goto done;
  9540. + }
  9541. +
  9542. + lid = crp->crp_sid & 0xffffffff;
  9543. + if (lid >= swcr_sesnum || lid == 0 || swcr_sessions == NULL ||
  9544. + swcr_sessions[lid] == NULL) {
  9545. + crp->crp_etype = ENOENT;
  9546. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  9547. + goto done;
  9548. + }
  9549. +
  9550. + /*
  9551. + * do some error checking outside of the loop for SKB and IOV processing
  9552. + * this leaves us with valid skb or uiop pointers for later
  9553. + */
  9554. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  9555. + struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
  9556. + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
  9557. + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
  9558. + skb_shinfo(skb)->nr_frags);
  9559. + goto done;
  9560. + }
  9561. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  9562. + struct uio *uiop = (struct uio *) crp->crp_buf;
  9563. + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
  9564. + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
  9565. + uiop->uio_iovcnt);
  9566. + goto done;
  9567. + }
  9568. + }
  9569. +
  9570. + /*
  9571. + * setup a new request ready for queuing
  9572. + */
  9573. + req = kmem_cache_alloc(swcr_req_cache, SLAB_ATOMIC);
  9574. + if (req == NULL) {
  9575. + dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
  9576. + crp->crp_etype = ENOMEM;
  9577. + goto done;
  9578. + }
  9579. + memset(req, 0, sizeof(*req));
  9580. +
  9581. + req->sw_head = swcr_sessions[lid];
  9582. + req->crp = crp;
  9583. + req->crd = crp->crp_desc;
  9584. +
  9585. + swcr_process_req(req);
  9586. + return 0;
  9587. +
  9588. +done:
  9589. + crypto_done(crp);
  9590. + if (req)
  9591. + kmem_cache_free(swcr_req_cache, req);
  9592. + return 0;
  9593. +}
  9594. +
  9595. +
  9596. +static int
  9597. +cryptosoft_init(void)
  9598. +{
  9599. + int i, sw_type, mode;
  9600. + char *algo;
  9601. +
  9602. + dprintk("%s(%p)\n", __FUNCTION__, cryptosoft_init);
  9603. +
  9604. + swcr_req_cache = kmem_cache_create("cryptosoft_req",
  9605. + sizeof(struct swcr_req), 0, SLAB_HWCACHE_ALIGN, NULL
  9606. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  9607. + , NULL
  9608. +#endif
  9609. + );
  9610. + if (!swcr_req_cache) {
  9611. + printk("cryptosoft: failed to create request cache\n");
  9612. + return -ENOENT;
  9613. + }
  9614. +
  9615. + softc_device_init(&swcr_softc, "cryptosoft", 0, swcr_methods);
  9616. +
  9617. + swcr_id = crypto_get_driverid(softc_get_device(&swcr_softc),
  9618. + CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
  9619. + if (swcr_id < 0) {
  9620. + printk("cryptosoft: Software crypto device cannot initialize!");
  9621. + return -ENODEV;
  9622. + }
  9623. +
  9624. +#define REGISTER(alg) \
  9625. + crypto_register(swcr_id, alg, 0,0)
  9626. +
  9627. + for (i = 0; i < sizeof(crypto_details)/sizeof(crypto_details[0]); i++) {
  9628. + int found;
  9629. +
  9630. + algo = crypto_details[i].alg_name;
  9631. + if (!algo || !*algo) {
  9632. + dprintk("%s:Algorithm %d not supported\n", __FUNCTION__, i);
  9633. + continue;
  9634. + }
  9635. +
  9636. + mode = crypto_details[i].mode;
  9637. + sw_type = crypto_details[i].sw_type;
  9638. +
  9639. + found = 0;
  9640. + switch (sw_type & SW_TYPE_ALG_MASK) {
  9641. + case SW_TYPE_CIPHER:
  9642. + found = crypto_has_cipher(algo, 0, CRYPTO_ALG_ASYNC);
  9643. + break;
  9644. + case SW_TYPE_HMAC:
  9645. + found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
  9646. + break;
  9647. + case SW_TYPE_HASH:
  9648. + found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
  9649. + break;
  9650. + case SW_TYPE_COMP:
  9651. + found = crypto_has_comp(algo, 0, CRYPTO_ALG_ASYNC);
  9652. + break;
  9653. + case SW_TYPE_BLKCIPHER:
  9654. + found = crypto_has_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);
  9655. + if (!found && !swcr_no_ablk)
  9656. + found = crypto_has_ablkcipher(algo, 0, 0);
  9657. + break;
  9658. + }
  9659. + if (found) {
  9660. + REGISTER(i);
  9661. + } else {
  9662. + dprintk("%s:Algorithm Type %d not supported (algorithm %d:'%s')\n",
  9663. + __FUNCTION__, sw_type, i, algo);
  9664. + }
  9665. + }
  9666. + return 0;
  9667. +}
  9668. +
  9669. +static void
  9670. +cryptosoft_exit(void)
  9671. +{
  9672. + dprintk("%s()\n", __FUNCTION__);
  9673. + crypto_unregister_all(swcr_id);
  9674. + swcr_id = -1;
  9675. + kmem_cache_destroy(swcr_req_cache);
  9676. +}
  9677. +
  9678. +late_initcall(cryptosoft_init);
  9679. +module_exit(cryptosoft_exit);
  9680. +
  9681. +MODULE_LICENSE("Dual BSD/GPL");
  9682. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  9683. +MODULE_DESCRIPTION("Cryptosoft (OCF module for kernel crypto)");
  9684. diff -Nur linux-2.6.39.orig/crypto/ocf/ep80579/icp_asym.c linux-2.6.39/crypto/ocf/ep80579/icp_asym.c
  9685. --- linux-2.6.39.orig/crypto/ocf/ep80579/icp_asym.c 1970-01-01 01:00:00.000000000 +0100
  9686. +++ linux-2.6.39/crypto/ocf/ep80579/icp_asym.c 2011-07-31 11:31:53.843638287 +0200
  9687. @@ -0,0 +1,1334 @@
  9688. +/***************************************************************************
  9689. + *
  9690. + * This file is provided under a dual BSD/GPLv2 license. When using or
  9691. + * redistributing this file, you may do so under either license.
  9692. + *
  9693. + * GPL LICENSE SUMMARY
  9694. + *
  9695. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  9696. + *
  9697. + * This program is free software; you can redistribute it and/or modify
  9698. + * it under the terms of version 2 of the GNU General Public License as
  9699. + * published by the Free Software Foundation.
  9700. + *
  9701. + * This program is distributed in the hope that it will be useful, but
  9702. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  9703. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  9704. + * General Public License for more details.
  9705. + *
  9706. + * You should have received a copy of the GNU General Public License
  9707. + * along with this program; if not, write to the Free Software
  9708. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  9709. + * The full GNU General Public License is included in this distribution
  9710. + * in the file called LICENSE.GPL.
  9711. + *
  9712. + * Contact Information:
  9713. + * Intel Corporation
  9714. + *
  9715. + * BSD LICENSE
  9716. + *
  9717. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  9718. + * All rights reserved.
  9719. + *
  9720. + * Redistribution and use in source and binary forms, with or without
  9721. + * modification, are permitted provided that the following conditions
  9722. + * are met:
  9723. + *
  9724. + * * Redistributions of source code must retain the above copyright
  9725. + * notice, this list of conditions and the following disclaimer.
  9726. + * * Redistributions in binary form must reproduce the above copyright
  9727. + * notice, this list of conditions and the following disclaimer in
  9728. + * the documentation and/or other materials provided with the
  9729. + * distribution.
  9730. + * * Neither the name of Intel Corporation nor the names of its
  9731. + * contributors may be used to endorse or promote products derived
  9732. + * from this software without specific prior written permission.
  9733. + *
  9734. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  9735. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  9736. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  9737. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9738. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  9739. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9740. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  9741. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  9742. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  9743. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  9744. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  9745. + *
  9746. + *
  9747. + * version: Security.L.1.0.2-229
  9748. + *
  9749. + ***************************************************************************/
  9750. +
  9751. +#include "icp_ocf.h"
  9752. +
  9753. +/*The following define values (containing the word 'INDEX') are used to find
  9754. +the index of each input buffer of the crypto_kop struct (see OCF cryptodev.h).
  9755. +These values were found through analysis of the OCF OpenSSL patch. If the
  9756. +calling program uses different input buffer positions, these defines will have
  9757. +to be changed.*/
  9758. +
  9759. +/*DIFFIE HELLMAN buffer index values*/
  9760. +#define ICP_DH_KRP_PARAM_PRIME_INDEX (0)
  9761. +#define ICP_DH_KRP_PARAM_BASE_INDEX (1)
  9762. +#define ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX (2)
  9763. +#define ICP_DH_KRP_PARAM_RESULT_INDEX (3)
  9764. +
  9765. +/*MOD EXP buffer index values*/
  9766. +#define ICP_MOD_EXP_KRP_PARAM_BASE_INDEX (0)
  9767. +#define ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX (1)
  9768. +#define ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX (2)
  9769. +#define ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX (3)
  9770. +
  9771. +/*MOD EXP CRT buffer index values*/
  9772. +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX (0)
  9773. +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX (1)
  9774. +#define ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX (2)
  9775. +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX (3)
  9776. +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX (4)
  9777. +#define ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX (5)
  9778. +#define ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX (6)
  9779. +
  9780. +/*DSA sign buffer index values*/
  9781. +#define ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX (0)
  9782. +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX (1)
  9783. +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX (2)
  9784. +#define ICP_DSA_SIGN_KRP_PARAM_G_INDEX (3)
  9785. +#define ICP_DSA_SIGN_KRP_PARAM_X_INDEX (4)
  9786. +#define ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX (5)
  9787. +#define ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX (6)
  9788. +
  9789. +/*DSA verify buffer index values*/
  9790. +#define ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX (0)
  9791. +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX (1)
  9792. +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX (2)
  9793. +#define ICP_DSA_VERIFY_KRP_PARAM_G_INDEX (3)
  9794. +#define ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX (4)
  9795. +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX (5)
  9796. +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX (6)
  9797. +
  9798. +/*DSA sign prime Q vs random number K size check values*/
  9799. +#define DONT_RUN_LESS_THAN_CHECK (0)
  9800. +#define FAIL_A_IS_GREATER_THAN_B (1)
  9801. +#define FAIL_A_IS_EQUAL_TO_B (1)
  9802. +#define SUCCESS_A_IS_LESS_THAN_B (0)
  9803. +#define DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS (500)
  9804. +
  9805. +/* We need to set a cryptokp success value just in case it is set or allocated
  9806. + and not set to zero outside of this module */
  9807. +#define CRYPTO_OP_SUCCESS (0)
  9808. +
  9809. +/*Function to compute Diffie Hellman (DH) phase 1 or phase 2 key values*/
  9810. +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp);
  9811. +
  9812. +/*Function to compute a Modular Exponentiation (Mod Exp)*/
  9813. +static int icp_ocfDrvModExp(struct cryptkop *krp);
  9814. +
  9815. +/*Function to compute a Mod Exp using the Chinease Remainder Theorem*/
  9816. +static int icp_ocfDrvModExpCRT(struct cryptkop *krp);
  9817. +
  9818. +/*Helper function to compute whether the first big number argument is less than
  9819. + the second big number argument */
  9820. +static int
  9821. +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck);
  9822. +
  9823. +/*Function to sign an input with DSA R and S keys*/
  9824. +static int icp_ocfDrvDsaSign(struct cryptkop *krp);
  9825. +
  9826. +/*Function to Verify a DSA buffer signature*/
  9827. +static int icp_ocfDrvDsaVerify(struct cryptkop *krp);
  9828. +
  9829. +/*Callback function for DH operation*/
  9830. +static void
  9831. +icp_ocfDrvDhP1CallBack(void *callbackTag,
  9832. + CpaStatus status,
  9833. + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV);
  9834. +
  9835. +/*Callback function for ME operation*/
  9836. +static void
  9837. +icp_ocfDrvModExpCallBack(void *callbackTag,
  9838. + CpaStatus status,
  9839. + void *pOpData, CpaFlatBuffer * pResult);
  9840. +
  9841. +/*Callback function for ME CRT operation*/
  9842. +static void
  9843. +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
  9844. + CpaStatus status,
  9845. + void *pOpData, CpaFlatBuffer * pOutputData);
  9846. +
  9847. +/*Callback function for DSA sign operation*/
  9848. +static void
  9849. +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
  9850. + CpaStatus status,
  9851. + void *pOpData,
  9852. + CpaBoolean protocolStatus,
  9853. + CpaFlatBuffer * pR, CpaFlatBuffer * pS);
  9854. +
  9855. +/*Callback function for DSA Verify operation*/
  9856. +static void
  9857. +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
  9858. + CpaStatus status,
  9859. + void *pOpData, CpaBoolean verifyStatus);
  9860. +
  9861. +/* Name : icp_ocfDrvPkeProcess
  9862. + *
  9863. + * Description : This function will choose which PKE process to follow
  9864. + * based on the input arguments
  9865. + */
  9866. +int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint)
  9867. +{
  9868. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  9869. +
  9870. + if (NULL == krp) {
  9871. + DPRINTK("%s(): Invalid input parameters, cryptkop = %p\n",
  9872. + __FUNCTION__, krp);
  9873. + return EINVAL;
  9874. + }
  9875. +
  9876. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  9877. + krp->krp_status = ECANCELED;
  9878. + return ECANCELED;
  9879. + }
  9880. +
  9881. + switch (krp->krp_op) {
  9882. + case CRK_DH_COMPUTE_KEY:
  9883. + DPRINTK("%s() doing DH_COMPUTE_KEY\n", __FUNCTION__);
  9884. + lacStatus = icp_ocfDrvDHComputeKey(krp);
  9885. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9886. + EPRINTK("%s(): icp_ocfDrvDHComputeKey failed "
  9887. + "(%d).\n", __FUNCTION__, lacStatus);
  9888. + krp->krp_status = ECANCELED;
  9889. + return ECANCELED;
  9890. + }
  9891. +
  9892. + break;
  9893. +
  9894. + case CRK_MOD_EXP:
  9895. + DPRINTK("%s() doing MOD_EXP \n", __FUNCTION__);
  9896. + lacStatus = icp_ocfDrvModExp(krp);
  9897. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9898. + EPRINTK("%s(): icp_ocfDrvModExp failed (%d).\n",
  9899. + __FUNCTION__, lacStatus);
  9900. + krp->krp_status = ECANCELED;
  9901. + return ECANCELED;
  9902. + }
  9903. +
  9904. + break;
  9905. +
  9906. + case CRK_MOD_EXP_CRT:
  9907. + DPRINTK("%s() doing MOD_EXP_CRT \n", __FUNCTION__);
  9908. + lacStatus = icp_ocfDrvModExpCRT(krp);
  9909. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9910. + EPRINTK("%s(): icp_ocfDrvModExpCRT "
  9911. + "failed (%d).\n", __FUNCTION__, lacStatus);
  9912. + krp->krp_status = ECANCELED;
  9913. + return ECANCELED;
  9914. + }
  9915. +
  9916. + break;
  9917. +
  9918. + case CRK_DSA_SIGN:
  9919. + DPRINTK("%s() doing DSA_SIGN \n", __FUNCTION__);
  9920. + lacStatus = icp_ocfDrvDsaSign(krp);
  9921. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9922. + EPRINTK("%s(): icp_ocfDrvDsaSign "
  9923. + "failed (%d).\n", __FUNCTION__, lacStatus);
  9924. + krp->krp_status = ECANCELED;
  9925. + return ECANCELED;
  9926. + }
  9927. +
  9928. + break;
  9929. +
  9930. + case CRK_DSA_VERIFY:
  9931. + DPRINTK("%s() doing DSA_VERIFY \n", __FUNCTION__);
  9932. + lacStatus = icp_ocfDrvDsaVerify(krp);
  9933. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9934. + EPRINTK("%s(): icp_ocfDrvDsaVerify "
  9935. + "failed (%d).\n", __FUNCTION__, lacStatus);
  9936. + krp->krp_status = ECANCELED;
  9937. + return ECANCELED;
  9938. + }
  9939. +
  9940. + break;
  9941. +
  9942. + default:
  9943. + EPRINTK("%s(): Asymettric function not "
  9944. + "supported (%d).\n", __FUNCTION__, krp->krp_op);
  9945. + krp->krp_status = EOPNOTSUPP;
  9946. + return EOPNOTSUPP;
  9947. + }
  9948. +
  9949. + return ICP_OCF_DRV_STATUS_SUCCESS;
  9950. +}
  9951. +
  9952. +/* Name : icp_ocfDrvSwapBytes
  9953. + *
  9954. + * Description : This function is used to swap the byte order of a buffer.
  9955. + * It has been seen that in general we are passed little endian byte order
  9956. + * buffers, but LAC only accepts big endian byte order buffers.
  9957. + */
  9958. +static void inline icp_ocfDrvSwapBytes(u_int8_t * num, u_int32_t buff_len_bytes)
  9959. +{
  9960. +
  9961. + int i;
  9962. + u_int8_t *end_ptr;
  9963. + u_int8_t hold_val;
  9964. +
  9965. + end_ptr = num + (buff_len_bytes - 1);
  9966. + buff_len_bytes = buff_len_bytes >> 1;
  9967. + for (i = 0; i < buff_len_bytes; i++) {
  9968. + hold_val = *num;
  9969. + *num = *end_ptr;
  9970. + num++;
  9971. + *end_ptr = hold_val;
  9972. + end_ptr--;
  9973. + }
  9974. +}
  9975. +
  9976. +/* Name : icp_ocfDrvDHComputeKey
  9977. + *
  9978. + * Description : This function will map Diffie Hellman calls from OCF
  9979. + * to the LAC API. OCF uses this function for Diffie Hellman Phase1 and
  9980. + * Phase2. LAC has a separate Diffie Hellman Phase2 call, however both phases
  9981. + * break down to a modular exponentiation.
  9982. + */
  9983. +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp)
  9984. +{
  9985. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  9986. + void *callbackTag = NULL;
  9987. + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
  9988. + CpaFlatBuffer *pLocalOctetStringPV = NULL;
  9989. + uint32_t dh_prime_len_bytes = 0, dh_prime_len_bits = 0;
  9990. +
  9991. + /* Input checks - check prime is a multiple of 8 bits to allow for
  9992. + allocation later */
  9993. + dh_prime_len_bits =
  9994. + (krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_nbits);
  9995. +
  9996. + /* LAC can reject prime lengths based on prime key sizes, we just
  9997. + need to make sure we can allocate space for the base and
  9998. + exponent buffers correctly */
  9999. + if ((dh_prime_len_bits % NUM_BITS_IN_BYTE) != 0) {
  10000. + APRINTK("%s(): Warning Prime number buffer size is not a "
  10001. + "multiple of 8 bits\n", __FUNCTION__);
  10002. + }
  10003. +
  10004. + /* Result storage space should be the same size as the prime as this
  10005. + value can take up the same amount of storage space */
  10006. + if (dh_prime_len_bits !=
  10007. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits) {
  10008. + DPRINTK("%s(): Return Buffer must be the same size "
  10009. + "as the Prime buffer\n", __FUNCTION__);
  10010. + krp->krp_status = EINVAL;
  10011. + return EINVAL;
  10012. + }
  10013. + /* Switch to size in bytes */
  10014. + BITS_TO_BYTES(dh_prime_len_bytes, dh_prime_len_bits);
  10015. +
  10016. + callbackTag = krp;
  10017. +
  10018. +/*All allocations are set to ICP_M_NOWAIT due to the possibility of getting
  10019. +called in interrupt context*/
  10020. + pPhase1OpData = icp_kmem_cache_zalloc(drvDH_zone, ICP_M_NOWAIT);
  10021. + if (NULL == pPhase1OpData) {
  10022. + APRINTK("%s():Failed to get memory for key gen data\n",
  10023. + __FUNCTION__);
  10024. + krp->krp_status = ENOMEM;
  10025. + return ENOMEM;
  10026. + }
  10027. +
  10028. + pLocalOctetStringPV =
  10029. + icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  10030. + if (NULL == pLocalOctetStringPV) {
  10031. + APRINTK("%s():Failed to get memory for pLocalOctetStringPV\n",
  10032. + __FUNCTION__);
  10033. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  10034. + krp->krp_status = ENOMEM;
  10035. + return ENOMEM;
  10036. + }
  10037. +
  10038. + /* Link parameters */
  10039. + pPhase1OpData->primeP.pData =
  10040. + krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_p;
  10041. +
  10042. + pPhase1OpData->primeP.dataLenInBytes = dh_prime_len_bytes;
  10043. +
  10044. + icp_ocfDrvSwapBytes(pPhase1OpData->primeP.pData, dh_prime_len_bytes);
  10045. +
  10046. + pPhase1OpData->baseG.pData =
  10047. + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_p;
  10048. +
  10049. + BITS_TO_BYTES(pPhase1OpData->baseG.dataLenInBytes,
  10050. + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_nbits);
  10051. +
  10052. + icp_ocfDrvSwapBytes(pPhase1OpData->baseG.pData,
  10053. + pPhase1OpData->baseG.dataLenInBytes);
  10054. +
  10055. + pPhase1OpData->privateValueX.pData =
  10056. + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].crp_p;
  10057. +
  10058. + BITS_TO_BYTES(pPhase1OpData->privateValueX.dataLenInBytes,
  10059. + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].
  10060. + crp_nbits);
  10061. +
  10062. + icp_ocfDrvSwapBytes(pPhase1OpData->privateValueX.pData,
  10063. + pPhase1OpData->privateValueX.dataLenInBytes);
  10064. +
  10065. + /* Output parameters */
  10066. + pLocalOctetStringPV->pData =
  10067. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_p;
  10068. +
  10069. + BITS_TO_BYTES(pLocalOctetStringPV->dataLenInBytes,
  10070. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits);
  10071. +
  10072. + lacStatus = cpaCyDhKeyGenPhase1(CPA_INSTANCE_HANDLE_SINGLE,
  10073. + icp_ocfDrvDhP1CallBack,
  10074. + callbackTag, pPhase1OpData,
  10075. + pLocalOctetStringPV);
  10076. +
  10077. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10078. + EPRINTK("%s(): DH Phase 1 Key Gen failed (%d).\n",
  10079. + __FUNCTION__, lacStatus);
  10080. + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
  10081. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  10082. + }
  10083. +
  10084. + return lacStatus;
  10085. +}
  10086. +
  10087. +/* Name : icp_ocfDrvModExp
  10088. + *
  10089. + * Description : This function will map ordinary Modular Exponentiation calls
  10090. + * from OCF to the LAC API.
  10091. + *
  10092. + */
  10093. +static int icp_ocfDrvModExp(struct cryptkop *krp)
  10094. +{
  10095. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  10096. + void *callbackTag = NULL;
  10097. + CpaCyLnModExpOpData *pModExpOpData = NULL;
  10098. + CpaFlatBuffer *pResult = NULL;
  10099. +
  10100. + if ((krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits %
  10101. + NUM_BITS_IN_BYTE) != 0) {
  10102. + DPRINTK("%s(): Warning - modulus buffer size (%d) is not a "
  10103. + "multiple of 8 bits\n", __FUNCTION__,
  10104. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
  10105. + crp_nbits);
  10106. + }
  10107. +
  10108. + /* Result storage space should be the same size as the prime as this
  10109. + value can take up the same amount of storage space */
  10110. + if (krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits >
  10111. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_nbits) {
  10112. + APRINTK("%s(): Return Buffer size must be the same or"
  10113. + " greater than the Modulus buffer\n", __FUNCTION__);
  10114. + krp->krp_status = EINVAL;
  10115. + return EINVAL;
  10116. + }
  10117. +
  10118. + callbackTag = krp;
  10119. +
  10120. + pModExpOpData = icp_kmem_cache_zalloc(drvLnModExp_zone, ICP_M_NOWAIT);
  10121. + if (NULL == pModExpOpData) {
  10122. + APRINTK("%s():Failed to get memory for key gen data\n",
  10123. + __FUNCTION__);
  10124. + krp->krp_status = ENOMEM;
  10125. + return ENOMEM;
  10126. + }
  10127. +
  10128. + pResult = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  10129. + if (NULL == pResult) {
  10130. + APRINTK("%s():Failed to get memory for ModExp result\n",
  10131. + __FUNCTION__);
  10132. + ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);
  10133. + krp->krp_status = ENOMEM;
  10134. + return ENOMEM;
  10135. + }
  10136. +
  10137. + /* Link parameters */
  10138. + pModExpOpData->modulus.pData =
  10139. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_p;
  10140. + BITS_TO_BYTES(pModExpOpData->modulus.dataLenInBytes,
  10141. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
  10142. + crp_nbits);
  10143. +
  10144. + icp_ocfDrvSwapBytes(pModExpOpData->modulus.pData,
  10145. + pModExpOpData->modulus.dataLenInBytes);
  10146. +
  10147. + DPRINTK("%s : base (%d)\n", __FUNCTION__, krp->
  10148. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits);
  10149. + pModExpOpData->base.pData =
  10150. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_p;
  10151. + BITS_TO_BYTES(pModExpOpData->base.dataLenInBytes,
  10152. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  10153. + crp_nbits);
  10154. + icp_ocfDrvSwapBytes(pModExpOpData->base.pData,
  10155. + pModExpOpData->base.dataLenInBytes);
  10156. +
  10157. + pModExpOpData->exponent.pData =
  10158. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].crp_p;
  10159. + BITS_TO_BYTES(pModExpOpData->exponent.dataLenInBytes,
  10160. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].
  10161. + crp_nbits);
  10162. +
  10163. + icp_ocfDrvSwapBytes(pModExpOpData->exponent.pData,
  10164. + pModExpOpData->exponent.dataLenInBytes);
  10165. + /* Output parameters */
  10166. + pResult->pData =
  10167. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_p,
  10168. + BITS_TO_BYTES(pResult->dataLenInBytes,
  10169. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].
  10170. + crp_nbits);
  10171. +
  10172. + lacStatus = cpaCyLnModExp(CPA_INSTANCE_HANDLE_SINGLE,
  10173. + icp_ocfDrvModExpCallBack,
  10174. + callbackTag, pModExpOpData, pResult);
  10175. +
  10176. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10177. + EPRINTK("%s(): Mod Exp Operation failed (%d).\n",
  10178. + __FUNCTION__, lacStatus);
  10179. + krp->krp_status = ECANCELED;
  10180. + icp_ocfDrvFreeFlatBuffer(pResult);
  10181. + ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);
  10182. + }
  10183. +
  10184. + return lacStatus;
  10185. +}
  10186. +
  10187. +/* Name : icp_ocfDrvModExpCRT
  10188. + *
  10189. + * Description : This function will map ordinary Modular Exponentiation Chinese
  10190. + * Remainder Theorem implementaion calls from OCF to the LAC API.
  10191. + *
  10192. + * Note : Mod Exp CRT for this driver is accelerated through LAC RSA type 2
  10193. + * decrypt operation. Therefore P and Q input values must always be prime
  10194. + * numbers. Although basic primality checks are done in LAC, it is up to the
  10195. + * user to do any correct prime number checking before passing the inputs.
  10196. + */
  10197. +static int icp_ocfDrvModExpCRT(struct cryptkop *krp)
  10198. +{
  10199. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  10200. + CpaCyRsaDecryptOpData *rsaDecryptOpData = NULL;
  10201. + void *callbackTag = NULL;
  10202. + CpaFlatBuffer *pOutputData = NULL;
  10203. +
  10204. + /*Parameter input checks are all done by LAC, no need to repeat
  10205. + them here. */
  10206. + callbackTag = krp;
  10207. +
  10208. + rsaDecryptOpData =
  10209. + icp_kmem_cache_zalloc(drvRSADecrypt_zone, ICP_M_NOWAIT);
  10210. + if (NULL == rsaDecryptOpData) {
  10211. + APRINTK("%s():Failed to get memory"
  10212. + " for MOD EXP CRT Op data struct\n", __FUNCTION__);
  10213. + krp->krp_status = ENOMEM;
  10214. + return ENOMEM;
  10215. + }
  10216. +
  10217. + rsaDecryptOpData->pRecipientPrivateKey
  10218. + = icp_kmem_cache_zalloc(drvRSAPrivateKey_zone, ICP_M_NOWAIT);
  10219. + if (NULL == rsaDecryptOpData->pRecipientPrivateKey) {
  10220. + APRINTK("%s():Failed to get memory for MOD EXP CRT"
  10221. + " private key values struct\n", __FUNCTION__);
  10222. + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
  10223. + krp->krp_status = ENOMEM;
  10224. + return ENOMEM;
  10225. + }
  10226. +
  10227. + rsaDecryptOpData->pRecipientPrivateKey->
  10228. + version = CPA_CY_RSA_VERSION_TWO_PRIME;
  10229. + rsaDecryptOpData->pRecipientPrivateKey->
  10230. + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
  10231. +
  10232. + pOutputData = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  10233. + if (NULL == pOutputData) {
  10234. + APRINTK("%s():Failed to get memory"
  10235. + " for MOD EXP CRT output data\n", __FUNCTION__);
  10236. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  10237. + rsaDecryptOpData->pRecipientPrivateKey);
  10238. + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
  10239. + krp->krp_status = ENOMEM;
  10240. + return ENOMEM;
  10241. + }
  10242. +
  10243. + rsaDecryptOpData->pRecipientPrivateKey->
  10244. + version = CPA_CY_RSA_VERSION_TWO_PRIME;
  10245. + rsaDecryptOpData->pRecipientPrivateKey->
  10246. + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
  10247. +
  10248. + /* Link parameters */
  10249. + rsaDecryptOpData->inputData.pData =
  10250. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].crp_p;
  10251. + BITS_TO_BYTES(rsaDecryptOpData->inputData.dataLenInBytes,
  10252. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].
  10253. + crp_nbits);
  10254. +
  10255. + icp_ocfDrvSwapBytes(rsaDecryptOpData->inputData.pData,
  10256. + rsaDecryptOpData->inputData.dataLenInBytes);
  10257. +
  10258. + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime1P.pData =
  10259. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].crp_p;
  10260. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  10261. + prime1P.dataLenInBytes,
  10262. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].
  10263. + crp_nbits);
  10264. +
  10265. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  10266. + privateKeyRep2.prime1P.pData,
  10267. + rsaDecryptOpData->pRecipientPrivateKey->
  10268. + privateKeyRep2.prime1P.dataLenInBytes);
  10269. +
  10270. + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime2Q.pData =
  10271. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  10272. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  10273. + prime2Q.dataLenInBytes,
  10274. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].
  10275. + crp_nbits);
  10276. +
  10277. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  10278. + privateKeyRep2.prime2Q.pData,
  10279. + rsaDecryptOpData->pRecipientPrivateKey->
  10280. + privateKeyRep2.prime2Q.dataLenInBytes);
  10281. +
  10282. + rsaDecryptOpData->pRecipientPrivateKey->
  10283. + privateKeyRep2.exponent1Dp.pData =
  10284. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].crp_p;
  10285. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  10286. + exponent1Dp.dataLenInBytes,
  10287. + krp->
  10288. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].
  10289. + crp_nbits);
  10290. +
  10291. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  10292. + privateKeyRep2.exponent1Dp.pData,
  10293. + rsaDecryptOpData->pRecipientPrivateKey->
  10294. + privateKeyRep2.exponent1Dp.dataLenInBytes);
  10295. +
  10296. + rsaDecryptOpData->pRecipientPrivateKey->
  10297. + privateKeyRep2.exponent2Dq.pData =
  10298. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].crp_p;
  10299. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
  10300. + privateKeyRep2.exponent2Dq.dataLenInBytes,
  10301. + krp->
  10302. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].
  10303. + crp_nbits);
  10304. +
  10305. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  10306. + privateKeyRep2.exponent2Dq.pData,
  10307. + rsaDecryptOpData->pRecipientPrivateKey->
  10308. + privateKeyRep2.exponent2Dq.dataLenInBytes);
  10309. +
  10310. + rsaDecryptOpData->pRecipientPrivateKey->
  10311. + privateKeyRep2.coefficientQInv.pData =
  10312. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].crp_p;
  10313. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
  10314. + privateKeyRep2.coefficientQInv.dataLenInBytes,
  10315. + krp->
  10316. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].
  10317. + crp_nbits);
  10318. +
  10319. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  10320. + privateKeyRep2.coefficientQInv.pData,
  10321. + rsaDecryptOpData->pRecipientPrivateKey->
  10322. + privateKeyRep2.coefficientQInv.dataLenInBytes);
  10323. +
  10324. + /* Output Parameter */
  10325. + pOutputData->pData =
  10326. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].crp_p;
  10327. + BITS_TO_BYTES(pOutputData->dataLenInBytes,
  10328. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].
  10329. + crp_nbits);
  10330. +
  10331. + lacStatus = cpaCyRsaDecrypt(CPA_INSTANCE_HANDLE_SINGLE,
  10332. + icp_ocfDrvModExpCRTCallBack,
  10333. + callbackTag, rsaDecryptOpData, pOutputData);
  10334. +
  10335. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10336. + EPRINTK("%s(): Mod Exp CRT Operation failed (%d).\n",
  10337. + __FUNCTION__, lacStatus);
  10338. + krp->krp_status = ECANCELED;
  10339. + icp_ocfDrvFreeFlatBuffer(pOutputData);
  10340. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  10341. + rsaDecryptOpData->pRecipientPrivateKey);
  10342. + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
  10343. + }
  10344. +
  10345. + return lacStatus;
  10346. +}
  10347. +
  10348. +/* Name : icp_ocfDrvCheckALessThanB
  10349. + *
  10350. + * Description : This function will check whether the first argument is less
  10351. + * than the second. It is used to check whether the DSA RS sign Random K
  10352. + * value is less than the Prime Q value (as defined in the specification)
  10353. + *
  10354. + */
  10355. +static int
  10356. +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck)
  10357. +{
  10358. +
  10359. + uint8_t *MSB_K = pK->pData;
  10360. + uint8_t *MSB_Q = pQ->pData;
  10361. + uint32_t buffer_lengths_in_bytes = pQ->dataLenInBytes;
  10362. +
  10363. + if (DONT_RUN_LESS_THAN_CHECK == *doCheck) {
  10364. + return FAIL_A_IS_GREATER_THAN_B;
  10365. + }
  10366. +
  10367. +/*Check MSBs
  10368. +if A == B, check next MSB
  10369. +if A > B, return A_IS_GREATER_THAN_B
  10370. +if A < B, return A_IS_LESS_THAN_B (success)
  10371. +*/
  10372. + while (*MSB_K == *MSB_Q) {
  10373. + MSB_K++;
  10374. + MSB_Q++;
  10375. +
  10376. + buffer_lengths_in_bytes--;
  10377. + if (0 == buffer_lengths_in_bytes) {
  10378. + DPRINTK("%s() Buffers have equal value!!\n",
  10379. + __FUNCTION__);
  10380. + return FAIL_A_IS_EQUAL_TO_B;
  10381. + }
  10382. +
  10383. + }
  10384. +
  10385. + if (*MSB_K < *MSB_Q) {
  10386. + return SUCCESS_A_IS_LESS_THAN_B;
  10387. + } else {
  10388. + return FAIL_A_IS_GREATER_THAN_B;
  10389. + }
  10390. +
  10391. +}
  10392. +
  10393. +/* Name : icp_ocfDrvDsaSign
  10394. + *
  10395. + * Description : This function will map DSA RS Sign from OCF to the LAC API.
  10396. + *
  10397. + * NOTE: From looking at OCF patch to OpenSSL and even the number of input
  10398. + * parameters, OCF expects us to generate the random seed value. This value
  10399. + * is generated and passed to LAC, however the number is discared in the
  10400. + * callback and not returned to the user.
  10401. + */
  10402. +static int icp_ocfDrvDsaSign(struct cryptkop *krp)
  10403. +{
  10404. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  10405. + CpaCyDsaRSSignOpData *dsaRsSignOpData = NULL;
  10406. + void *callbackTag = NULL;
  10407. + CpaCyRandGenOpData randGenOpData;
  10408. + int primeQSizeInBytes = 0;
  10409. + int doCheck = 0;
  10410. + CpaFlatBuffer randData;
  10411. + CpaBoolean protocolStatus = CPA_FALSE;
  10412. + CpaFlatBuffer *pR = NULL;
  10413. + CpaFlatBuffer *pS = NULL;
  10414. +
  10415. + callbackTag = krp;
  10416. +
  10417. + BITS_TO_BYTES(primeQSizeInBytes,
  10418. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
  10419. + crp_nbits);
  10420. +
  10421. + if (DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES != primeQSizeInBytes) {
  10422. + APRINTK("%s(): DSA PRIME Q size not equal to the "
  10423. + "FIPS defined 20bytes, = %d\n",
  10424. + __FUNCTION__, primeQSizeInBytes);
  10425. + krp->krp_status = EDOM;
  10426. + return EDOM;
  10427. + }
  10428. +
  10429. + dsaRsSignOpData =
  10430. + icp_kmem_cache_zalloc(drvDSARSSign_zone, ICP_M_NOWAIT);
  10431. + if (NULL == dsaRsSignOpData) {
  10432. + APRINTK("%s():Failed to get memory"
  10433. + " for DSA RS Sign Op data struct\n", __FUNCTION__);
  10434. + krp->krp_status = ENOMEM;
  10435. + return ENOMEM;
  10436. + }
  10437. +
  10438. + dsaRsSignOpData->K.pData =
  10439. + icp_kmem_cache_alloc(drvDSARSSignKValue_zone, ICP_M_NOWAIT);
  10440. +
  10441. + if (NULL == dsaRsSignOpData->K.pData) {
  10442. + APRINTK("%s():Failed to get memory"
  10443. + " for DSA RS Sign Op Random value\n", __FUNCTION__);
  10444. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  10445. + krp->krp_status = ENOMEM;
  10446. + return ENOMEM;
  10447. + }
  10448. +
  10449. + pR = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  10450. + if (NULL == pR) {
  10451. + APRINTK("%s():Failed to get memory"
  10452. + " for DSA signature R\n", __FUNCTION__);
  10453. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  10454. + dsaRsSignOpData->K.pData);
  10455. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  10456. + krp->krp_status = ENOMEM;
  10457. + return ENOMEM;
  10458. + }
  10459. +
  10460. + pS = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  10461. + if (NULL == pS) {
  10462. + APRINTK("%s():Failed to get memory"
  10463. + " for DSA signature S\n", __FUNCTION__);
  10464. + icp_ocfDrvFreeFlatBuffer(pR);
  10465. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  10466. + dsaRsSignOpData->K.pData);
  10467. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  10468. + krp->krp_status = ENOMEM;
  10469. + return ENOMEM;
  10470. + }
  10471. +
  10472. + /*link prime number parameter for ease of processing */
  10473. + dsaRsSignOpData->P.pData =
  10474. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].crp_p;
  10475. + BITS_TO_BYTES(dsaRsSignOpData->P.dataLenInBytes,
  10476. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].
  10477. + crp_nbits);
  10478. +
  10479. + icp_ocfDrvSwapBytes(dsaRsSignOpData->P.pData,
  10480. + dsaRsSignOpData->P.dataLenInBytes);
  10481. +
  10482. + dsaRsSignOpData->Q.pData =
  10483. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  10484. + BITS_TO_BYTES(dsaRsSignOpData->Q.dataLenInBytes,
  10485. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
  10486. + crp_nbits);
  10487. +
  10488. + icp_ocfDrvSwapBytes(dsaRsSignOpData->Q.pData,
  10489. + dsaRsSignOpData->Q.dataLenInBytes);
  10490. +
  10491. + /*generate random number with equal buffer size to Prime value Q,
  10492. + but value less than Q */
  10493. + dsaRsSignOpData->K.dataLenInBytes = dsaRsSignOpData->Q.dataLenInBytes;
  10494. +
  10495. + randGenOpData.generateBits = CPA_TRUE;
  10496. + randGenOpData.lenInBytes = dsaRsSignOpData->K.dataLenInBytes;
  10497. +
  10498. + icp_ocfDrvPtrAndLenToFlatBuffer(dsaRsSignOpData->K.pData,
  10499. + dsaRsSignOpData->K.dataLenInBytes,
  10500. + &randData);
  10501. +
  10502. + doCheck = 0;
  10503. + while (icp_ocfDrvCheckALessThanB(&(dsaRsSignOpData->K),
  10504. + &(dsaRsSignOpData->Q), &doCheck)) {
  10505. +
  10506. + if (CPA_STATUS_SUCCESS
  10507. + != cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  10508. + NULL, NULL, &randGenOpData, &randData)) {
  10509. + APRINTK("%s(): ERROR - Failed to generate DSA RS Sign K"
  10510. + "value\n", __FUNCTION__);
  10511. + icp_ocfDrvFreeFlatBuffer(pS);
  10512. + icp_ocfDrvFreeFlatBuffer(pR);
  10513. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  10514. + dsaRsSignOpData->K.pData);
  10515. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  10516. + krp->krp_status = EAGAIN;
  10517. + return EAGAIN;
  10518. + }
  10519. +
  10520. + doCheck++;
  10521. + if (DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS == doCheck) {
  10522. + APRINTK("%s(): ERROR - Failed to find DSA RS Sign K "
  10523. + "value less than Q value\n", __FUNCTION__);
  10524. + icp_ocfDrvFreeFlatBuffer(pS);
  10525. + icp_ocfDrvFreeFlatBuffer(pR);
  10526. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  10527. + dsaRsSignOpData->K.pData);
  10528. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  10529. + krp->krp_status = EAGAIN;
  10530. + return EAGAIN;
  10531. + }
  10532. +
  10533. + }
  10534. + /*Rand Data - no need to swap bytes for pK */
  10535. +
  10536. + /* Link parameters */
  10537. + dsaRsSignOpData->G.pData =
  10538. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_p;
  10539. + BITS_TO_BYTES(dsaRsSignOpData->G.dataLenInBytes,
  10540. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_nbits);
  10541. +
  10542. + icp_ocfDrvSwapBytes(dsaRsSignOpData->G.pData,
  10543. + dsaRsSignOpData->G.dataLenInBytes);
  10544. +
  10545. + dsaRsSignOpData->X.pData =
  10546. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_p;
  10547. + BITS_TO_BYTES(dsaRsSignOpData->X.dataLenInBytes,
  10548. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_nbits);
  10549. + icp_ocfDrvSwapBytes(dsaRsSignOpData->X.pData,
  10550. + dsaRsSignOpData->X.dataLenInBytes);
  10551. +
  10552. + /*OpenSSL dgst parameter is left in big endian byte order,
  10553. + therefore no byte swap is required */
  10554. + dsaRsSignOpData->M.pData =
  10555. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].crp_p;
  10556. + BITS_TO_BYTES(dsaRsSignOpData->M.dataLenInBytes,
  10557. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].
  10558. + crp_nbits);
  10559. +
  10560. + /* Output Parameters */
  10561. + pS->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].crp_p;
  10562. + BITS_TO_BYTES(pS->dataLenInBytes,
  10563. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].
  10564. + crp_nbits);
  10565. +
  10566. + pR->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].crp_p;
  10567. + BITS_TO_BYTES(pR->dataLenInBytes,
  10568. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].
  10569. + crp_nbits);
  10570. +
  10571. + lacStatus = cpaCyDsaSignRS(CPA_INSTANCE_HANDLE_SINGLE,
  10572. + icp_ocfDrvDsaRSSignCallBack,
  10573. + callbackTag, dsaRsSignOpData,
  10574. + &protocolStatus, pR, pS);
  10575. +
  10576. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10577. + EPRINTK("%s(): DSA RS Sign Operation failed (%d).\n",
  10578. + __FUNCTION__, lacStatus);
  10579. + krp->krp_status = ECANCELED;
  10580. + icp_ocfDrvFreeFlatBuffer(pS);
  10581. + icp_ocfDrvFreeFlatBuffer(pR);
  10582. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  10583. + dsaRsSignOpData->K.pData);
  10584. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  10585. + }
  10586. +
  10587. + return lacStatus;
  10588. +}
  10589. +
  10590. +/* Name : icp_ocfDrvDsaVerify
  10591. + *
  10592. + * Description : This function will map DSA RS Verify from OCF to the LAC API.
  10593. + *
  10594. + */
  10595. +static int icp_ocfDrvDsaVerify(struct cryptkop *krp)
  10596. +{
  10597. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  10598. + CpaCyDsaVerifyOpData *dsaVerifyOpData = NULL;
  10599. + void *callbackTag = NULL;
  10600. + CpaBoolean verifyStatus = CPA_FALSE;
  10601. +
  10602. + callbackTag = krp;
  10603. +
  10604. + dsaVerifyOpData =
  10605. + icp_kmem_cache_zalloc(drvDSAVerify_zone, ICP_M_NOWAIT);
  10606. + if (NULL == dsaVerifyOpData) {
  10607. + APRINTK("%s():Failed to get memory"
  10608. + " for DSA Verify Op data struct\n", __FUNCTION__);
  10609. + krp->krp_status = ENOMEM;
  10610. + return ENOMEM;
  10611. + }
  10612. +
  10613. + /* Link parameters */
  10614. + dsaVerifyOpData->P.pData =
  10615. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].crp_p;
  10616. + BITS_TO_BYTES(dsaVerifyOpData->P.dataLenInBytes,
  10617. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].
  10618. + crp_nbits);
  10619. + icp_ocfDrvSwapBytes(dsaVerifyOpData->P.pData,
  10620. + dsaVerifyOpData->P.dataLenInBytes);
  10621. +
  10622. + dsaVerifyOpData->Q.pData =
  10623. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  10624. + BITS_TO_BYTES(dsaVerifyOpData->Q.dataLenInBytes,
  10625. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].
  10626. + crp_nbits);
  10627. + icp_ocfDrvSwapBytes(dsaVerifyOpData->Q.pData,
  10628. + dsaVerifyOpData->Q.dataLenInBytes);
  10629. +
  10630. + dsaVerifyOpData->G.pData =
  10631. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].crp_p;
  10632. + BITS_TO_BYTES(dsaVerifyOpData->G.dataLenInBytes,
  10633. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].
  10634. + crp_nbits);
  10635. + icp_ocfDrvSwapBytes(dsaVerifyOpData->G.pData,
  10636. + dsaVerifyOpData->G.dataLenInBytes);
  10637. +
  10638. + dsaVerifyOpData->Y.pData =
  10639. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].crp_p;
  10640. + BITS_TO_BYTES(dsaVerifyOpData->Y.dataLenInBytes,
  10641. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].
  10642. + crp_nbits);
  10643. + icp_ocfDrvSwapBytes(dsaVerifyOpData->Y.pData,
  10644. + dsaVerifyOpData->Y.dataLenInBytes);
  10645. +
  10646. + /*OpenSSL dgst parameter is left in big endian byte order,
  10647. + therefore no byte swap is required */
  10648. + dsaVerifyOpData->M.pData =
  10649. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].crp_p;
  10650. + BITS_TO_BYTES(dsaVerifyOpData->M.dataLenInBytes,
  10651. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].
  10652. + crp_nbits);
  10653. +
  10654. + dsaVerifyOpData->R.pData =
  10655. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].crp_p;
  10656. + BITS_TO_BYTES(dsaVerifyOpData->R.dataLenInBytes,
  10657. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].
  10658. + crp_nbits);
  10659. + icp_ocfDrvSwapBytes(dsaVerifyOpData->R.pData,
  10660. + dsaVerifyOpData->R.dataLenInBytes);
  10661. +
  10662. + dsaVerifyOpData->S.pData =
  10663. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].crp_p;
  10664. + BITS_TO_BYTES(dsaVerifyOpData->S.dataLenInBytes,
  10665. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].
  10666. + crp_nbits);
  10667. + icp_ocfDrvSwapBytes(dsaVerifyOpData->S.pData,
  10668. + dsaVerifyOpData->S.dataLenInBytes);
  10669. +
  10670. + lacStatus = cpaCyDsaVerify(CPA_INSTANCE_HANDLE_SINGLE,
  10671. + icp_ocfDrvDsaVerifyCallBack,
  10672. + callbackTag, dsaVerifyOpData, &verifyStatus);
  10673. +
  10674. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10675. + EPRINTK("%s(): DSA Verify Operation failed (%d).\n",
  10676. + __FUNCTION__, lacStatus);
  10677. + ICP_CACHE_FREE(drvDSAVerify_zone, dsaVerifyOpData);
  10678. + krp->krp_status = ECANCELED;
  10679. + }
  10680. +
  10681. + return lacStatus;
  10682. +}
  10683. +
  10684. +/* Name : icp_ocfDrvDhP1Callback
  10685. + *
  10686. + * Description : When this function returns it signifies that the LAC
  10687. + * component has completed the DH operation.
  10688. + */
  10689. +static void
  10690. +icp_ocfDrvDhP1CallBack(void *callbackTag,
  10691. + CpaStatus status,
  10692. + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV)
  10693. +{
  10694. + struct cryptkop *krp = NULL;
  10695. + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
  10696. +
  10697. + if (NULL == callbackTag) {
  10698. + DPRINTK("%s(): Invalid input parameters - "
  10699. + "callbackTag data is NULL\n", __FUNCTION__);
  10700. + return;
  10701. + }
  10702. + krp = (struct cryptkop *)callbackTag;
  10703. +
  10704. + if (NULL == pOpData) {
  10705. + DPRINTK("%s(): Invalid input parameters - "
  10706. + "Operation Data is NULL\n", __FUNCTION__);
  10707. + krp->krp_status = ECANCELED;
  10708. + crypto_kdone(krp);
  10709. + return;
  10710. + }
  10711. + pPhase1OpData = (CpaCyDhPhase1KeyGenOpData *) pOpData;
  10712. +
  10713. + if (NULL == pLocalOctetStringPV) {
  10714. + DPRINTK("%s(): Invalid input parameters - "
  10715. + "pLocalOctetStringPV Data is NULL\n", __FUNCTION__);
  10716. + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
  10717. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  10718. + krp->krp_status = ECANCELED;
  10719. + crypto_kdone(krp);
  10720. + return;
  10721. + }
  10722. +
  10723. + if (CPA_STATUS_SUCCESS == status) {
  10724. + krp->krp_status = CRYPTO_OP_SUCCESS;
  10725. + } else {
  10726. + APRINTK("%s(): Diffie Hellman Phase1 Key Gen failed - "
  10727. + "Operation Status = %d\n", __FUNCTION__, status);
  10728. + krp->krp_status = ECANCELED;
  10729. + }
  10730. +
  10731. + icp_ocfDrvSwapBytes(pLocalOctetStringPV->pData,
  10732. + pLocalOctetStringPV->dataLenInBytes);
  10733. +
  10734. + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
  10735. + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
  10736. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  10737. +
  10738. + crypto_kdone(krp);
  10739. +
  10740. + return;
  10741. +}
  10742. +
  10743. +/* Name : icp_ocfDrvModExpCallBack
  10744. + *
  10745. + * Description : When this function returns it signifies that the LAC
  10746. + * component has completed the Mod Exp operation.
  10747. + */
  10748. +static void
  10749. +icp_ocfDrvModExpCallBack(void *callbackTag,
  10750. + CpaStatus status,
  10751. + void *pOpdata, CpaFlatBuffer * pResult)
  10752. +{
  10753. + struct cryptkop *krp = NULL;
  10754. + CpaCyLnModExpOpData *pLnModExpOpData = NULL;
  10755. +
  10756. + if (NULL == callbackTag) {
  10757. + DPRINTK("%s(): Invalid input parameters - "
  10758. + "callbackTag data is NULL\n", __FUNCTION__);
  10759. + return;
  10760. + }
  10761. + krp = (struct cryptkop *)callbackTag;
  10762. +
  10763. + if (NULL == pOpdata) {
  10764. + DPRINTK("%s(): Invalid Mod Exp input parameters - "
  10765. + "Operation Data is NULL\n", __FUNCTION__);
  10766. + krp->krp_status = ECANCELED;
  10767. + crypto_kdone(krp);
  10768. + return;
  10769. + }
  10770. + pLnModExpOpData = (CpaCyLnModExpOpData *) pOpdata;
  10771. +
  10772. + if (NULL == pResult) {
  10773. + DPRINTK("%s(): Invalid input parameters - "
  10774. + "pResult data is NULL\n", __FUNCTION__);
  10775. + krp->krp_status = ECANCELED;
  10776. + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
  10777. + ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);
  10778. + crypto_kdone(krp);
  10779. + return;
  10780. + }
  10781. +
  10782. + if (CPA_STATUS_SUCCESS == status) {
  10783. + krp->krp_status = CRYPTO_OP_SUCCESS;
  10784. + } else {
  10785. + APRINTK("%s(): LAC Mod Exp Operation failed - "
  10786. + "Operation Status = %d\n", __FUNCTION__, status);
  10787. + krp->krp_status = ECANCELED;
  10788. + }
  10789. +
  10790. + icp_ocfDrvSwapBytes(pResult->pData, pResult->dataLenInBytes);
  10791. +
  10792. + /*switch base size value back to original */
  10793. + if (pLnModExpOpData->base.pData ==
  10794. + (uint8_t *) & (krp->
  10795. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  10796. + crp_nbits)) {
  10797. + *((uint32_t *) pLnModExpOpData->base.pData) =
  10798. + ntohl(*((uint32_t *) pLnModExpOpData->base.pData));
  10799. + }
  10800. + icp_ocfDrvFreeFlatBuffer(pResult);
  10801. + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
  10802. + ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);
  10803. +
  10804. + crypto_kdone(krp);
  10805. +
  10806. + return;
  10807. +
  10808. +}
  10809. +
  10810. +/* Name : icp_ocfDrvModExpCRTCallBack
  10811. + *
  10812. + * Description : When this function returns it signifies that the LAC
  10813. + * component has completed the Mod Exp CRT operation.
  10814. + */
  10815. +static void
  10816. +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
  10817. + CpaStatus status,
  10818. + void *pOpData, CpaFlatBuffer * pOutputData)
  10819. +{
  10820. + struct cryptkop *krp = NULL;
  10821. + CpaCyRsaDecryptOpData *pDecryptData = NULL;
  10822. +
  10823. + if (NULL == callbackTag) {
  10824. + DPRINTK("%s(): Invalid input parameters - "
  10825. + "callbackTag data is NULL\n", __FUNCTION__);
  10826. + return;
  10827. + }
  10828. +
  10829. + krp = (struct cryptkop *)callbackTag;
  10830. +
  10831. + if (NULL == pOpData) {
  10832. + DPRINTK("%s(): Invalid input parameters - "
  10833. + "Operation Data is NULL\n", __FUNCTION__);
  10834. + krp->krp_status = ECANCELED;
  10835. + crypto_kdone(krp);
  10836. + return;
  10837. + }
  10838. + pDecryptData = (CpaCyRsaDecryptOpData *) pOpData;
  10839. +
  10840. + if (NULL == pOutputData) {
  10841. + DPRINTK("%s(): Invalid input parameter - "
  10842. + "pOutputData is NULL\n", __FUNCTION__);
  10843. + memset(pDecryptData->pRecipientPrivateKey, 0,
  10844. + sizeof(CpaCyRsaPrivateKey));
  10845. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  10846. + pDecryptData->pRecipientPrivateKey);
  10847. + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
  10848. + ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);
  10849. + krp->krp_status = ECANCELED;
  10850. + crypto_kdone(krp);
  10851. + return;
  10852. + }
  10853. +
  10854. + if (CPA_STATUS_SUCCESS == status) {
  10855. + krp->krp_status = CRYPTO_OP_SUCCESS;
  10856. + } else {
  10857. + APRINTK("%s(): LAC Mod Exp CRT operation failed - "
  10858. + "Operation Status = %d\n", __FUNCTION__, status);
  10859. + krp->krp_status = ECANCELED;
  10860. + }
  10861. +
  10862. + icp_ocfDrvSwapBytes(pOutputData->pData, pOutputData->dataLenInBytes);
  10863. +
  10864. + icp_ocfDrvFreeFlatBuffer(pOutputData);
  10865. + memset(pDecryptData->pRecipientPrivateKey, 0,
  10866. + sizeof(CpaCyRsaPrivateKey));
  10867. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  10868. + pDecryptData->pRecipientPrivateKey);
  10869. + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
  10870. + ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);
  10871. +
  10872. + crypto_kdone(krp);
  10873. +
  10874. + return;
  10875. +}
  10876. +
  10877. +/* Name : icp_ocfDrvDsaRSSignCallBack
  10878. + *
  10879. + * Description : When this function returns it signifies that the LAC
  10880. + * component has completed the DSA RS sign operation.
  10881. + */
  10882. +static void
  10883. +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
  10884. + CpaStatus status,
  10885. + void *pOpData,
  10886. + CpaBoolean protocolStatus,
  10887. + CpaFlatBuffer * pR, CpaFlatBuffer * pS)
  10888. +{
  10889. + struct cryptkop *krp = NULL;
  10890. + CpaCyDsaRSSignOpData *pSignData = NULL;
  10891. +
  10892. + if (NULL == callbackTag) {
  10893. + DPRINTK("%s(): Invalid input parameters - "
  10894. + "callbackTag data is NULL\n", __FUNCTION__);
  10895. + return;
  10896. + }
  10897. +
  10898. + krp = (struct cryptkop *)callbackTag;
  10899. +
  10900. + if (NULL == pOpData) {
  10901. + DPRINTK("%s(): Invalid input parameters - "
  10902. + "Operation Data is NULL\n", __FUNCTION__);
  10903. + krp->krp_status = ECANCELED;
  10904. + crypto_kdone(krp);
  10905. + return;
  10906. + }
  10907. + pSignData = (CpaCyDsaRSSignOpData *) pOpData;
  10908. +
  10909. + if (NULL == pR) {
  10910. + DPRINTK("%s(): Invalid input parameter - "
  10911. + "pR sign is NULL\n", __FUNCTION__);
  10912. + icp_ocfDrvFreeFlatBuffer(pS);
  10913. + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
  10914. + krp->krp_status = ECANCELED;
  10915. + crypto_kdone(krp);
  10916. + return;
  10917. + }
  10918. +
  10919. + if (NULL == pS) {
  10920. + DPRINTK("%s(): Invalid input parameter - "
  10921. + "pS sign is NULL\n", __FUNCTION__);
  10922. + icp_ocfDrvFreeFlatBuffer(pR);
  10923. + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
  10924. + krp->krp_status = ECANCELED;
  10925. + crypto_kdone(krp);
  10926. + return;
  10927. + }
  10928. +
  10929. + if (CPA_STATUS_SUCCESS != status) {
  10930. + APRINTK("%s(): LAC DSA RS Sign operation failed - "
  10931. + "Operation Status = %d\n", __FUNCTION__, status);
  10932. + krp->krp_status = ECANCELED;
  10933. + } else {
  10934. + krp->krp_status = CRYPTO_OP_SUCCESS;
  10935. +
  10936. + if (CPA_TRUE != protocolStatus) {
  10937. + DPRINTK("%s(): LAC DSA RS Sign operation failed due "
  10938. + "to protocol error\n", __FUNCTION__);
  10939. + krp->krp_status = EIO;
  10940. + }
  10941. + }
  10942. +
  10943. + /* Swap bytes only when the callback status is successful and
  10944. + protocolStatus is set to true */
  10945. + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == protocolStatus) {
  10946. + icp_ocfDrvSwapBytes(pR->pData, pR->dataLenInBytes);
  10947. + icp_ocfDrvSwapBytes(pS->pData, pS->dataLenInBytes);
  10948. + }
  10949. +
  10950. + icp_ocfDrvFreeFlatBuffer(pR);
  10951. + icp_ocfDrvFreeFlatBuffer(pS);
  10952. + memset(pSignData->K.pData, 0, pSignData->K.dataLenInBytes);
  10953. + ICP_CACHE_FREE(drvDSARSSignKValue_zone, pSignData->K.pData);
  10954. + memset(pSignData, 0, sizeof(CpaCyDsaRSSignOpData));
  10955. + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
  10956. + crypto_kdone(krp);
  10957. +
  10958. + return;
  10959. +}
  10960. +
  10961. +/* Name : icp_ocfDrvDsaVerifyCallback
  10962. + *
  10963. + * Description : When this function returns it signifies that the LAC
  10964. + * component has completed the DSA Verify operation.
  10965. + */
  10966. +static void
  10967. +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
  10968. + CpaStatus status,
  10969. + void *pOpData, CpaBoolean verifyStatus)
  10970. +{
  10971. +
  10972. + struct cryptkop *krp = NULL;
  10973. + CpaCyDsaVerifyOpData *pVerData = NULL;
  10974. +
  10975. + if (NULL == callbackTag) {
  10976. + DPRINTK("%s(): Invalid input parameters - "
  10977. + "callbackTag data is NULL\n", __FUNCTION__);
  10978. + return;
  10979. + }
  10980. +
  10981. + krp = (struct cryptkop *)callbackTag;
  10982. +
  10983. + if (NULL == pOpData) {
  10984. + DPRINTK("%s(): Invalid input parameters - "
  10985. + "Operation Data is NULL\n", __FUNCTION__);
  10986. + krp->krp_status = ECANCELED;
  10987. + crypto_kdone(krp);
  10988. + return;
  10989. + }
  10990. + pVerData = (CpaCyDsaVerifyOpData *) pOpData;
  10991. +
  10992. + if (CPA_STATUS_SUCCESS != status) {
  10993. + APRINTK("%s(): LAC DSA Verify operation failed - "
  10994. + "Operation Status = %d\n", __FUNCTION__, status);
  10995. + krp->krp_status = ECANCELED;
  10996. + } else {
  10997. + krp->krp_status = CRYPTO_OP_SUCCESS;
  10998. +
  10999. + if (CPA_TRUE != verifyStatus) {
  11000. + DPRINTK("%s(): DSA signature invalid\n", __FUNCTION__);
  11001. + krp->krp_status = EIO;
  11002. + }
  11003. + }
  11004. +
  11005. + /* Swap bytes only when the callback status is successful and
  11006. + verifyStatus is set to true */
  11007. + /*Just swapping back the key values for now. Possibly all
  11008. + swapped buffers need to be reverted */
  11009. + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == verifyStatus) {
  11010. + icp_ocfDrvSwapBytes(pVerData->R.pData,
  11011. + pVerData->R.dataLenInBytes);
  11012. + icp_ocfDrvSwapBytes(pVerData->S.pData,
  11013. + pVerData->S.dataLenInBytes);
  11014. + }
  11015. +
  11016. + memset(pVerData, 0, sizeof(CpaCyDsaVerifyOpData));
  11017. + ICP_CACHE_FREE(drvDSAVerify_zone, pVerData);
  11018. + crypto_kdone(krp);
  11019. +
  11020. + return;
  11021. +}
  11022. diff -Nur linux-2.6.39.orig/crypto/ocf/ep80579/icp_common.c linux-2.6.39/crypto/ocf/ep80579/icp_common.c
  11023. --- linux-2.6.39.orig/crypto/ocf/ep80579/icp_common.c 1970-01-01 01:00:00.000000000 +0100
  11024. +++ linux-2.6.39/crypto/ocf/ep80579/icp_common.c 2011-07-31 11:31:53.903427275 +0200
  11025. @@ -0,0 +1,773 @@
  11026. +/*************************************************************************
  11027. + *
  11028. + * This file is provided under a dual BSD/GPLv2 license. When using or
  11029. + * redistributing this file, you may do so under either license.
  11030. + *
  11031. + * GPL LICENSE SUMMARY
  11032. + *
  11033. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  11034. + *
  11035. + * This program is free software; you can redistribute it and/or modify
  11036. + * it under the terms of version 2 of the GNU General Public License as
  11037. + * published by the Free Software Foundation.
  11038. + *
  11039. + * This program is distributed in the hope that it will be useful, but
  11040. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  11041. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11042. + * General Public License for more details.
  11043. + *
  11044. + * You should have received a copy of the GNU General Public License
  11045. + * along with this program; if not, write to the Free Software
  11046. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  11047. + * The full GNU General Public License is included in this distribution
  11048. + * in the file called LICENSE.GPL.
  11049. + *
  11050. + * Contact Information:
  11051. + * Intel Corporation
  11052. + *
  11053. + * BSD LICENSE
  11054. + *
  11055. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  11056. + * All rights reserved.
  11057. + *
  11058. + * Redistribution and use in source and binary forms, with or without
  11059. + * modification, are permitted provided that the following conditions
  11060. + * are met:
  11061. + *
  11062. + * * Redistributions of source code must retain the above copyright
  11063. + * notice, this list of conditions and the following disclaimer.
  11064. + * * Redistributions in binary form must reproduce the above copyright
  11065. + * notice, this list of conditions and the following disclaimer in
  11066. + * the documentation and/or other materials provided with the
  11067. + * distribution.
  11068. + * * Neither the name of Intel Corporation nor the names of its
  11069. + * contributors may be used to endorse or promote products derived
  11070. + * from this software without specific prior written permission.
  11071. + *
  11072. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  11073. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  11074. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  11075. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  11076. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  11077. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11078. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  11079. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11080. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  11081. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  11082. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  11083. + *
  11084. + *
  11085. + * version: Security.L.1.0.2-229
  11086. + *
  11087. + ***************************************************************************/
  11088. +
  11089. +/*
  11090. + * An OCF module that uses Intel® QuickAssist Integrated Accelerator to do the
  11091. + * crypto.
  11092. + *
  11093. + * This driver requires the ICP Access Library that is available from Intel in
  11094. + * order to operate.
  11095. + */
  11096. +
  11097. +#include "icp_ocf.h"
  11098. +
  11099. +#define ICP_OCF_COMP_NAME "ICP_OCF"
  11100. +#define ICP_OCF_VER_MAIN (2)
  11101. +#define ICP_OCF_VER_MJR (1)
  11102. +#define ICP_OCF_VER_MNR (0)
  11103. +
  11104. +#define MAX_DEREG_RETRIES (100)
  11105. +#define DEFAULT_DEREG_RETRIES (10)
  11106. +#define DEFAULT_DEREG_DELAY_IN_JIFFIES (10)
  11107. +
  11108. +/* This defines the maximum number of sessions possible between OCF
  11109. + and the OCF EP80579 Driver. If set to zero, there is no limit. */
  11110. +#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT (0)
  11111. +#define NUM_SUPPORTED_CAPABILITIES (21)
  11112. +
  11113. +/*Slab zone names*/
  11114. +#define ICP_SESSION_DATA_NAME "icp_ocf.SesDat"
  11115. +#define ICP_OP_DATA_NAME "icp_ocf.OpDat"
  11116. +#define ICP_DH_NAME "icp_ocf.DH"
  11117. +#define ICP_MODEXP_NAME "icp_ocf.ModExp"
  11118. +#define ICP_RSA_DECRYPT_NAME "icp_ocf.RSAdec"
  11119. +#define ICP_RSA_PKEY_NAME "icp_ocf.RSApk"
  11120. +#define ICP_DSA_SIGN_NAME "icp_ocf.DSAsg"
  11121. +#define ICP_DSA_VER_NAME "icp_ocf.DSAver"
  11122. +#define ICP_RAND_VAL_NAME "icp_ocf.DSArnd"
  11123. +#define ICP_FLAT_BUFF_NAME "icp_ocf.FB"
  11124. +
  11125. +/*Slabs zones*/
  11126. +icp_kmem_cache drvSessionData_zone = NULL;
  11127. +icp_kmem_cache drvOpData_zone = NULL;
  11128. +icp_kmem_cache drvDH_zone = NULL;
  11129. +icp_kmem_cache drvLnModExp_zone = NULL;
  11130. +icp_kmem_cache drvRSADecrypt_zone = NULL;
  11131. +icp_kmem_cache drvRSAPrivateKey_zone = NULL;
  11132. +icp_kmem_cache drvDSARSSign_zone = NULL;
  11133. +icp_kmem_cache drvDSARSSignKValue_zone = NULL;
  11134. +icp_kmem_cache drvDSAVerify_zone = NULL;
  11135. +
  11136. +/*Slab zones for flatbuffers and bufferlist*/
  11137. +icp_kmem_cache drvFlatBuffer_zone = NULL;
  11138. +
  11139. +static inline int icp_cache_null_check(void)
  11140. +{
  11141. + return (drvSessionData_zone && drvOpData_zone
  11142. + && drvDH_zone && drvLnModExp_zone && drvRSADecrypt_zone
  11143. + && drvRSAPrivateKey_zone && drvDSARSSign_zone
  11144. + && drvDSARSSign_zone && drvDSARSSignKValue_zone
  11145. + && drvDSAVerify_zone && drvFlatBuffer_zone);
  11146. +}
  11147. +
  11148. +/*Function to free all allocated slab caches before exiting the module*/
  11149. +static void icp_ocfDrvFreeCaches(void);
  11150. +
  11151. +int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  11152. +
  11153. +/* Module parameter - gives the number of times LAC deregistration shall be
  11154. + re-tried */
  11155. +int num_dereg_retries = DEFAULT_DEREG_RETRIES;
  11156. +
  11157. +/* Module parameter - gives the delay time in jiffies before a LAC session
  11158. + shall be attempted to be deregistered again */
  11159. +int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES;
  11160. +
  11161. +/* Module parameter - gives the maximum number of sessions possible between
  11162. + OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
  11163. +int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT;
  11164. +
  11165. +/* This is set when the module is removed from the system, no further
  11166. + processing can take place if this is set */
  11167. +icp_atomic_t icp_ocfDrvIsExiting = ICP_ATOMIC_INIT(0);
  11168. +
  11169. +/* This is used to show how many lac sessions were not deregistered*/
  11170. +icp_atomic_t lac_session_failed_dereg_count = ICP_ATOMIC_INIT(0);
  11171. +
  11172. +/* This is used to track the number of registered sessions between OCF and
  11173. + * and the OCF EP80579 driver, when max_session is set to value other than
  11174. + * zero. This ensures that the max_session set for the OCF and the driver
  11175. + * is equal to the LAC registered sessions */
  11176. +icp_atomic_t num_ocf_to_drv_registered_sessions = ICP_ATOMIC_INIT(0);
  11177. +
  11178. +/* Head of linked list used to store session data */
  11179. +icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
  11180. +icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
  11181. +
  11182. +icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
  11183. +
  11184. +/*Below pointer is only used in linux, FreeBSD uses the name to
  11185. +create its own variable name*/
  11186. +icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ = NULL;
  11187. +ICP_WORKQUEUE_DEFINE_THREAD(icp_ocfDrvFreeLacSessionWorkQ);
  11188. +
  11189. +struct icp_drvBuffListInfo defBuffListInfo;
  11190. +
  11191. +/* Name : icp_ocfDrvInit
  11192. + *
  11193. + * Description : This function will register all the symmetric and asymmetric
  11194. + * functionality that will be accelerated by the hardware. It will also
  11195. + * get a unique driver ID from the OCF and initialise all slab caches
  11196. + */
  11197. +ICP_MODULE_INIT_FUNC(icp_ocfDrvInit)
  11198. +{
  11199. + int ocfStatus = 0;
  11200. +
  11201. + IPRINTK("=== %s ver %d.%d.%d ===\n", ICP_OCF_COMP_NAME,
  11202. + ICP_OCF_VER_MAIN, ICP_OCF_VER_MJR, ICP_OCF_VER_MNR);
  11203. +
  11204. + if (MAX_DEREG_RETRIES < num_dereg_retries) {
  11205. + EPRINTK("Session deregistration retry count set to greater "
  11206. + "than %d", MAX_DEREG_RETRIES);
  11207. + icp_module_return_code(EINVAL);
  11208. + }
  11209. +
  11210. + /* Initialize and Start the Cryptographic component */
  11211. + if (CPA_STATUS_SUCCESS !=
  11212. + cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) {
  11213. + EPRINTK("Failed to initialize and start the instance "
  11214. + "of the Cryptographic component.\n");
  11215. + return icp_module_return_code(EINVAL);
  11216. + }
  11217. +
  11218. + icp_spin_lock_init(&icp_ocfDrvSymSessInfoListSpinlock);
  11219. +
  11220. + /* Set the default size of BufferList to allocate */
  11221. + memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo));
  11222. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  11223. + icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS,
  11224. + &defBuffListInfo)) {
  11225. + EPRINTK("Failed to get bufferlist memory info.\n");
  11226. + return icp_module_return_code(ENOMEM);
  11227. + }
  11228. +
  11229. + /*Register OCF EP80579 Driver with OCF */
  11230. + icp_ocfDrvDriverId = ICP_CRYPTO_GET_DRIVERID();
  11231. +
  11232. + if (icp_ocfDrvDriverId < 0) {
  11233. + EPRINTK("%s : ICP driver failed to register with OCF!\n",
  11234. + __FUNCTION__);
  11235. + return icp_module_return_code(ENODEV);
  11236. + }
  11237. +
  11238. + /*Create all the slab caches used by the OCF EP80579 Driver */
  11239. + drvSessionData_zone =
  11240. + ICP_CACHE_CREATE(ICP_SESSION_DATA_NAME, struct icp_drvSessionData);
  11241. +
  11242. + /*
  11243. + * Allocation of the OpData includes the allocation space for meta data.
  11244. + * The memory after the opData structure is reserved for this meta data.
  11245. + */
  11246. + drvOpData_zone =
  11247. + icp_kmem_cache_create(ICP_OP_DATA_NAME,
  11248. + sizeof(struct icp_drvOpData) +
  11249. + defBuffListInfo.metaSize,
  11250. + ICP_KERNEL_CACHE_ALIGN,
  11251. + ICP_KERNEL_CACHE_NOINIT);
  11252. +
  11253. + drvDH_zone = ICP_CACHE_CREATE(ICP_DH_NAME, CpaCyDhPhase1KeyGenOpData);
  11254. +
  11255. + drvLnModExp_zone =
  11256. + ICP_CACHE_CREATE(ICP_MODEXP_NAME, CpaCyLnModExpOpData);
  11257. +
  11258. + drvRSADecrypt_zone =
  11259. + ICP_CACHE_CREATE(ICP_RSA_DECRYPT_NAME, CpaCyRsaDecryptOpData);
  11260. +
  11261. + drvRSAPrivateKey_zone =
  11262. + ICP_CACHE_CREATE(ICP_RSA_PKEY_NAME, CpaCyRsaPrivateKey);
  11263. +
  11264. + drvDSARSSign_zone =
  11265. + ICP_CACHE_CREATE(ICP_DSA_SIGN_NAME, CpaCyDsaRSSignOpData);
  11266. +
  11267. + /*too awkward to use a macro here */
  11268. + drvDSARSSignKValue_zone =
  11269. + ICP_CACHE_CREATE(ICP_RAND_VAL_NAME,
  11270. + DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES);
  11271. +
  11272. + drvDSAVerify_zone =
  11273. + ICP_CACHE_CREATE(ICP_DSA_VER_NAME, CpaCyDsaVerifyOpData);
  11274. +
  11275. + drvFlatBuffer_zone =
  11276. + ICP_CACHE_CREATE(ICP_FLAT_BUFF_NAME, CpaFlatBuffer);
  11277. +
  11278. + if (0 == icp_cache_null_check()) {
  11279. + icp_ocfDrvFreeCaches();
  11280. + EPRINTK("%s() line %d: Not enough memory!\n",
  11281. + __FUNCTION__, __LINE__);
  11282. + return ENOMEM;
  11283. + }
  11284. +
  11285. + /* Register the ICP symmetric crypto support. */
  11286. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_NULL_CBC, ocfStatus);
  11287. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_DES_CBC, ocfStatus);
  11288. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_3DES_CBC, ocfStatus);
  11289. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_AES_CBC, ocfStatus);
  11290. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_ARC4, ocfStatus);
  11291. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5, ocfStatus);
  11292. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5_HMAC, ocfStatus);
  11293. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1, ocfStatus);
  11294. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1_HMAC, ocfStatus);
  11295. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256, ocfStatus);
  11296. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256_HMAC,
  11297. + ocfStatus);
  11298. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384, ocfStatus);
  11299. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384_HMAC,
  11300. + ocfStatus);
  11301. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512, ocfStatus);
  11302. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512_HMAC,
  11303. + ocfStatus);
  11304. +
  11305. + /* Register the ICP asymmetric algorithm support */
  11306. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DH_COMPUTE_KEY,
  11307. + ocfStatus);
  11308. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP, ocfStatus);
  11309. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP_CRT, ocfStatus);
  11310. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_SIGN, ocfStatus);
  11311. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_VERIFY, ocfStatus);
  11312. +
  11313. + /* Register the ICP random number generator support */
  11314. + ICP_REG_RAND_WITH_OCF(icp_ocfDrvDriverId,
  11315. + icp_ocfDrvReadRandom, NULL, ocfStatus);
  11316. +
  11317. + if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) {
  11318. + DPRINTK("%s: Failed to register any device capabilities\n",
  11319. + __FUNCTION__);
  11320. + icp_ocfDrvFreeCaches();
  11321. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  11322. + return icp_module_return_code(ECANCELED);
  11323. + }
  11324. +
  11325. + DPRINTK("%s: Registered %d of %d device capabilities\n",
  11326. + __FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES);
  11327. +
  11328. + /*Session data linked list used during module exit */
  11329. + ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);
  11330. + ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);
  11331. +
  11332. + ICP_WORKQUEUE_CREATE(icp_ocfDrvFreeLacSessionWorkQ, "icpwq");
  11333. + if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
  11334. + EPRINTK("%s: Failed to create single "
  11335. + "thread workqueue\n", __FUNCTION__);
  11336. + icp_ocfDrvFreeCaches();
  11337. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  11338. + return icp_module_return_code(ENOMEM);
  11339. + }
  11340. +
  11341. + return icp_module_return_code(0);
  11342. +}
  11343. +
  11344. +/* Name : icp_ocfDrvExit
  11345. + *
  11346. + * Description : This function will deregister all the symmetric sessions
  11347. + * registered with the LAC component. It will also deregister all symmetric
  11348. + * and asymmetric functionality that can be accelerated by the hardware via OCF
  11349. + * and random number generation if it is enabled.
  11350. + */
  11351. +ICP_MODULE_EXIT_FUNC(icp_ocfDrvExit)
  11352. +{
  11353. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  11354. + struct icp_drvSessionData *sessionData = NULL;
  11355. + struct icp_drvSessionData *tempSessionData = NULL;
  11356. + int i, remaining_delay_time_in_jiffies = 0;
  11357. +
  11358. + /* For FreeBSD the invariant macro below makes function to return */
  11359. + /* with EBUSY value in the case of any session which has been regi- */
  11360. + /* stered with LAC not being deregistered. */
  11361. + /* The Linux implementation is empty since it is purely to compensate */
  11362. + /* for a limitation of the FreeBSD 7.1 Opencrypto framework. */
  11363. +
  11364. + ICP_MODULE_EXIT_INV();
  11365. +
  11366. + /* There is a possibility of a process or new session command being */
  11367. + /* sent before this variable is incremented. The aim of this variable */
  11368. + /* is to stop a loop of calls creating a deadlock situation which */
  11369. + /* would prevent the driver from exiting. */
  11370. + icp_atomic_set(&icp_ocfDrvIsExiting, 1);
  11371. +
  11372. + /*Existing sessions will be routed to another driver after these calls */
  11373. + crypto_unregister_all(icp_ocfDrvDriverId);
  11374. + crypto_runregister_all(icp_ocfDrvDriverId);
  11375. +
  11376. + if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
  11377. + DPRINTK("%s: workqueue already "
  11378. + "destroyed, therefore module exit "
  11379. + " function already called. Exiting.\n", __FUNCTION__);
  11380. + return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
  11381. + }
  11382. + /*If any sessions are waiting to be deregistered, do that. This also
  11383. + flushes the work queue */
  11384. + ICP_WORKQUEUE_DESTROY(icp_ocfDrvFreeLacSessionWorkQ);
  11385. +
  11386. + /*ENTER CRITICAL SECTION */
  11387. + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  11388. +
  11389. + ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
  11390. + &icp_ocfDrvGlobalSymListHead, listNode) {
  11391. + for (i = 0; i < num_dereg_retries; i++) {
  11392. + /*No harm if bad input - LAC will handle error cases */
  11393. + if (ICP_SESSION_RUNNING == tempSessionData->inUse) {
  11394. + lacStatus =
  11395. + cpaCySymRemoveSession
  11396. + (CPA_INSTANCE_HANDLE_SINGLE,
  11397. + tempSessionData->sessHandle);
  11398. + if (CPA_STATUS_SUCCESS == lacStatus) {
  11399. + /* Succesfully deregistered */
  11400. + break;
  11401. + } else if (CPA_STATUS_RETRY != lacStatus) {
  11402. + icp_atomic_inc
  11403. + (&lac_session_failed_dereg_count);
  11404. + break;
  11405. + }
  11406. +
  11407. + /*schedule_timout returns the time left for completion if
  11408. + * this task is set to TASK_INTERRUPTIBLE */
  11409. + remaining_delay_time_in_jiffies =
  11410. + dereg_retry_delay_in_jiffies;
  11411. + while (0 > remaining_delay_time_in_jiffies) {
  11412. + remaining_delay_time_in_jiffies =
  11413. + icp_schedule_timeout
  11414. + (&icp_ocfDrvSymSessInfoListSpinlock,
  11415. + remaining_delay_time_in_jiffies);
  11416. + }
  11417. +
  11418. + DPRINTK
  11419. + ("%s(): Retry %d to deregistrate the session\n",
  11420. + __FUNCTION__, i);
  11421. + }
  11422. + }
  11423. +
  11424. + /*remove from current list */
  11425. + ICP_LIST_DEL(tempSessionData, listNode);
  11426. + /*add to free mem linked list */
  11427. + ICP_LIST_ADD(tempSessionData,
  11428. + &icp_ocfDrvGlobalSymListHead_FreeMemList,
  11429. + listNode);
  11430. +
  11431. + }
  11432. +
  11433. + /*EXIT CRITICAL SECTION */
  11434. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  11435. +
  11436. + /*set back to initial values */
  11437. + sessionData = NULL;
  11438. + /*still have a reference in our list! */
  11439. + tempSessionData = NULL;
  11440. + /*free memory */
  11441. +
  11442. + ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
  11443. + &icp_ocfDrvGlobalSymListHead_FreeMemList,
  11444. + listNode) {
  11445. +
  11446. + ICP_LIST_DEL(tempSessionData, listNode);
  11447. + /* Free allocated CpaCySymSessionCtx */
  11448. + if (NULL != tempSessionData->sessHandle) {
  11449. + icp_kfree(tempSessionData->sessHandle);
  11450. + }
  11451. + memset(tempSessionData, 0, sizeof(struct icp_drvSessionData));
  11452. + ICP_CACHE_FREE(drvSessionData_zone, tempSessionData);
  11453. + }
  11454. +
  11455. + if (0 != icp_atomic_read(&lac_session_failed_dereg_count)) {
  11456. + DPRINTK("%s(): %d LAC sessions were not deregistered "
  11457. + "correctly. This is not a clean exit! \n",
  11458. + __FUNCTION__,
  11459. + icp_atomic_read(&lac_session_failed_dereg_count));
  11460. + }
  11461. +
  11462. + icp_ocfDrvFreeCaches();
  11463. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  11464. +
  11465. + icp_spin_lock_destroy(&icp_ocfDrvSymSessInfoListSpinlock);
  11466. +
  11467. + /* Shutdown the Cryptographic component */
  11468. + lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE);
  11469. + if (CPA_STATUS_SUCCESS != lacStatus) {
  11470. + DPRINTK("%s(): Failed to stop instance of the "
  11471. + "Cryptographic component.(status == %d)\n",
  11472. + __FUNCTION__, lacStatus);
  11473. + }
  11474. +
  11475. + return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
  11476. +}
  11477. +
  11478. +/* Name : icp_ocfDrvFreeCaches
  11479. + *
  11480. + * Description : This function deregisters all slab caches
  11481. + */
  11482. +static void icp_ocfDrvFreeCaches(void)
  11483. +{
  11484. + icp_atomic_set(&icp_ocfDrvIsExiting, 1);
  11485. +
  11486. + /*Sym Zones */
  11487. + ICP_CACHE_DESTROY(drvSessionData_zone);
  11488. + ICP_CACHE_DESTROY(drvOpData_zone);
  11489. +
  11490. + /*Asym zones */
  11491. + ICP_CACHE_DESTROY(drvDH_zone);
  11492. + ICP_CACHE_DESTROY(drvLnModExp_zone);
  11493. + ICP_CACHE_DESTROY(drvRSADecrypt_zone);
  11494. + ICP_CACHE_DESTROY(drvRSAPrivateKey_zone);
  11495. + ICP_CACHE_DESTROY(drvDSARSSignKValue_zone);
  11496. + ICP_CACHE_DESTROY(drvDSARSSign_zone);
  11497. + ICP_CACHE_DESTROY(drvDSAVerify_zone);
  11498. +
  11499. + /*FlatBuffer and BufferList Zones */
  11500. + ICP_CACHE_DESTROY(drvFlatBuffer_zone);
  11501. +
  11502. +}
  11503. +
  11504. +/* Name : icp_ocfDrvDeregRetry
  11505. + *
  11506. + * Description : This function will try to farm the session deregistration
  11507. + * off to a work queue. If it fails, nothing more can be done and it
  11508. + * returns an error
  11509. + */
  11510. +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
  11511. +{
  11512. + struct icp_ocfDrvFreeLacSession *workstore = NULL;
  11513. +
  11514. + DPRINTK("%s(): Retry - Deregistering session (%p)\n",
  11515. + __FUNCTION__, sessionToDeregister);
  11516. +
  11517. + /*make sure the session is not available to be allocated during this
  11518. + process */
  11519. + icp_atomic_inc(&lac_session_failed_dereg_count);
  11520. +
  11521. + /*Farm off to work queue */
  11522. + workstore =
  11523. + icp_kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), ICP_M_NOWAIT);
  11524. + if (NULL == workstore) {
  11525. + DPRINTK("%s(): unable to free session - no memory available "
  11526. + "for work queue\n", __FUNCTION__);
  11527. + return ENOMEM;
  11528. + }
  11529. +
  11530. + workstore->sessionToDeregister = sessionToDeregister;
  11531. +
  11532. + icp_init_work(&(workstore->work),
  11533. + icp_ocfDrvDeferedFreeLacSessionTaskFn, workstore);
  11534. +
  11535. + ICP_WORKQUEUE_ENQUEUE(icp_ocfDrvFreeLacSessionWorkQ,
  11536. + &(workstore->work));
  11537. +
  11538. + return ICP_OCF_DRV_STATUS_SUCCESS;
  11539. +
  11540. +}
  11541. +
  11542. +/* Name : icp_ocfDrvDeferedFreeLacSessionProcess
  11543. + *
  11544. + * Description : This function will retry (module input parameter)
  11545. + * 'num_dereg_retries' times to deregister any symmetric session that recieves a
  11546. + * CPA_STATUS_RETRY message from the LAC component. This function is run in
  11547. + * Thread context because it is called from a worker thread
  11548. + */
  11549. +void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
  11550. +{
  11551. + struct icp_ocfDrvFreeLacSession *workstore = NULL;
  11552. + CpaCySymSessionCtx sessionToDeregister = NULL;
  11553. + int i = 0;
  11554. + int remaining_delay_time_in_jiffies = 0;
  11555. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  11556. +
  11557. + workstore = (struct icp_ocfDrvFreeLacSession *)arg;
  11558. + if (NULL == workstore) {
  11559. + DPRINTK("%s() function called with null parameter \n",
  11560. + __FUNCTION__);
  11561. + return;
  11562. + }
  11563. +
  11564. + sessionToDeregister = workstore->sessionToDeregister;
  11565. + icp_kfree(workstore);
  11566. +
  11567. + /*if exiting, give deregistration one more blast only */
  11568. + if (icp_atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {
  11569. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  11570. + sessionToDeregister);
  11571. +
  11572. + if (lacStatus != CPA_STATUS_SUCCESS) {
  11573. + DPRINTK("%s() Failed to Dereg LAC session %p "
  11574. + "during module exit\n", __FUNCTION__,
  11575. + sessionToDeregister);
  11576. + return;
  11577. + }
  11578. +
  11579. + icp_atomic_dec(&lac_session_failed_dereg_count);
  11580. + return;
  11581. + }
  11582. +
  11583. + for (i = 0; i <= num_dereg_retries; i++) {
  11584. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  11585. + sessionToDeregister);
  11586. +
  11587. + if (lacStatus == CPA_STATUS_SUCCESS) {
  11588. + icp_atomic_dec(&lac_session_failed_dereg_count);
  11589. + return;
  11590. + }
  11591. + if (lacStatus != CPA_STATUS_RETRY) {
  11592. + DPRINTK("%s() Failed to deregister session - lacStatus "
  11593. + " = %d", __FUNCTION__, lacStatus);
  11594. + break;
  11595. + }
  11596. +
  11597. + /*schedule_timout returns the time left for completion if this
  11598. + task is set to TASK_INTERRUPTIBLE */
  11599. + remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies;
  11600. + while (0 < remaining_delay_time_in_jiffies) {
  11601. + remaining_delay_time_in_jiffies =
  11602. + icp_schedule_timeout(NULL,
  11603. + remaining_delay_time_in_jiffies);
  11604. + }
  11605. +
  11606. + }
  11607. +
  11608. + DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__);
  11609. + DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__,
  11610. + icp_atomic_read(&lac_session_failed_dereg_count));
  11611. +}
  11612. +
  11613. +/* Name : icp_ocfDrvPtrAndLenToFlatBuffer
  11614. + *
  11615. + * Description : This function converts a "pointer and length" buffer
  11616. + * structure to Fredericksburg Flat Buffer (CpaFlatBuffer) format.
  11617. + *
  11618. + * This function assumes that the data passed in are valid.
  11619. + */
  11620. +inline void
  11621. +icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
  11622. + CpaFlatBuffer * pFlatBuffer)
  11623. +{
  11624. + pFlatBuffer->pData = pData;
  11625. + pFlatBuffer->dataLenInBytes = len;
  11626. +}
  11627. +
  11628. +/* Name : icp_ocfDrvPtrAndLenToBufferList
  11629. + *
  11630. + * Description : This function converts a "pointer and length" buffer
  11631. + * structure to Fredericksburg Scatter/Gather Buffer (CpaBufferList) format.
  11632. + *
  11633. + * This function assumes that the data passed in are valid.
  11634. + */
  11635. +inline void
  11636. +icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
  11637. + CpaBufferList * pBufferList)
  11638. +{
  11639. + pBufferList->numBuffers = 1;
  11640. + pBufferList->pBuffers->pData = pDataIn;
  11641. + pBufferList->pBuffers->dataLenInBytes = length;
  11642. +}
  11643. +
  11644. +/* Name : icp_ocfDrvBufferListToPtrAndLen
  11645. + *
  11646. + * Description : This function converts Fredericksburg Scatter/Gather Buffer
  11647. + * (CpaBufferList) format to a "pointer and length" buffer structure.
  11648. + *
  11649. + * This function assumes that the data passed in are valid.
  11650. + */
  11651. +inline void
  11652. +icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
  11653. + void **ppDataOut, uint32_t * pLength)
  11654. +{
  11655. + *ppDataOut = pBufferList->pBuffers->pData;
  11656. + *pLength = pBufferList->pBuffers->dataLenInBytes;
  11657. +}
  11658. +
  11659. +/* Name : icp_ocfDrvBufferListMemInfo
  11660. + *
  11661. + * Description : This function will set the number of flat buffers in
  11662. + * bufferlist, the size of memory to allocate for the pPrivateMetaData
  11663. + * member of the CpaBufferList.
  11664. + */
  11665. +int
  11666. +icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
  11667. + struct icp_drvBuffListInfo *buffListInfo)
  11668. +{
  11669. + buffListInfo->numBuffers = numBuffers;
  11670. +
  11671. + if (CPA_STATUS_SUCCESS !=
  11672. + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  11673. + buffListInfo->numBuffers,
  11674. + &(buffListInfo->metaSize))) {
  11675. + EPRINTK("%s() Failed to get buffer list meta size.\n",
  11676. + __FUNCTION__);
  11677. + return ICP_OCF_DRV_STATUS_FAIL;
  11678. + }
  11679. +
  11680. + return ICP_OCF_DRV_STATUS_SUCCESS;
  11681. +}
  11682. +
  11683. +/* Name : icp_ocfDrvFreeFlatBuffer
  11684. + *
  11685. + * Description : This function will deallocate flat buffer.
  11686. + */
  11687. +inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)
  11688. +{
  11689. + if (pFlatBuffer != NULL) {
  11690. + memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer));
  11691. + ICP_CACHE_FREE(drvFlatBuffer_zone, pFlatBuffer);
  11692. + }
  11693. +}
  11694. +
  11695. +/* Name : icp_ocfDrvAllocMetaData
  11696. + *
  11697. + * Description : This function will allocate memory for the
  11698. + * pPrivateMetaData member of CpaBufferList.
  11699. + */
  11700. +inline int
  11701. +icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
  11702. + struct icp_drvOpData *pOpData)
  11703. +{
  11704. + Cpa32U metaSize = 0;
  11705. +
  11706. + if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  11707. + uint8_t *pOpDataStartAddr = (uint8_t *) pOpData;
  11708. +
  11709. + if (0 == defBuffListInfo.metaSize) {
  11710. + pBufferList->pPrivateMetaData = NULL;
  11711. + return ICP_OCF_DRV_STATUS_SUCCESS;
  11712. + }
  11713. + /*
  11714. + * The meta data allocation has been included as part of the
  11715. + * op data. It has been pre-allocated in memory just after the
  11716. + * icp_drvOpData structure.
  11717. + */
  11718. + pBufferList->pPrivateMetaData = (void *)(pOpDataStartAddr +
  11719. + sizeof(struct
  11720. + icp_drvOpData));
  11721. + } else {
  11722. + if (CPA_STATUS_SUCCESS !=
  11723. + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  11724. + pBufferList->numBuffers,
  11725. + &metaSize)) {
  11726. + EPRINTK("%s() Failed to get buffer list meta size.\n",
  11727. + __FUNCTION__);
  11728. + return ICP_OCF_DRV_STATUS_FAIL;
  11729. + }
  11730. +
  11731. + if (0 == metaSize) {
  11732. + pBufferList->pPrivateMetaData = NULL;
  11733. + return ICP_OCF_DRV_STATUS_SUCCESS;
  11734. + }
  11735. +
  11736. + pBufferList->pPrivateMetaData =
  11737. + icp_kmalloc(metaSize, ICP_M_NOWAIT);
  11738. + }
  11739. + if (NULL == pBufferList->pPrivateMetaData) {
  11740. + EPRINTK("%s() Failed to allocate pPrivateMetaData.\n",
  11741. + __FUNCTION__);
  11742. + return ICP_OCF_DRV_STATUS_FAIL;
  11743. + }
  11744. +
  11745. + return ICP_OCF_DRV_STATUS_SUCCESS;
  11746. +}
  11747. +
  11748. +/* Name : icp_ocfDrvFreeMetaData
  11749. + *
  11750. + * Description : This function will deallocate pPrivateMetaData memory.
  11751. + */
  11752. +inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList)
  11753. +{
  11754. + if (NULL == pBufferList->pPrivateMetaData) {
  11755. + return;
  11756. + }
  11757. +
  11758. + /*
  11759. + * Only free the meta data if the BufferList has more than
  11760. + * ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS number of buffers.
  11761. + * Otherwise, the meta data shall be freed when the icp_drvOpData is
  11762. + * freed.
  11763. + */
  11764. + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers) {
  11765. + icp_kfree(pBufferList->pPrivateMetaData);
  11766. + }
  11767. +}
  11768. +
  11769. +/* Module declaration, init and exit functions */
  11770. +ICP_DECLARE_MODULE(icp_ocf, icp_ocfDrvInit, icp_ocfDrvExit);
  11771. +ICP_MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");
  11772. +ICP_MODULE_VERSION(icp_ocf, ICP_OCF_VER_MJR);
  11773. +ICP_MODULE_LICENSE("Dual BSD/GPL");
  11774. +ICP_MODULE_AUTHOR("Intel");
  11775. +
  11776. +/* Module parameters */
  11777. +ICP_MODULE_PARAM_INT(icp_ocf, num_dereg_retries,
  11778. + "Number of times to retry LAC Sym Session Deregistration. "
  11779. + "Default 10, Max 100");
  11780. +ICP_MODULE_PARAM_INT(icp_ocf, dereg_retry_delay_in_jiffies, "Delay in jiffies "
  11781. + "(added to a schedule() function call) before a LAC Sym "
  11782. + "Session Dereg is retried. Default 10");
  11783. +ICP_MODULE_PARAM_INT(icp_ocf, max_sessions,
  11784. + "This sets the maximum number of sessions "
  11785. + "between OCF and this driver. If this value is set to zero,"
  11786. + "max session count checking is disabled. Default is zero(0)");
  11787. +
  11788. +/* Module dependencies */
  11789. +#define MODULE_MIN_VER 1
  11790. +#define CRYPTO_MAX_VER 3
  11791. +#define LAC_MAX_VER 2
  11792. +
  11793. +ICP_MODULE_DEPEND(icp_ocf, crypto, MODULE_MIN_VER, MODULE_MIN_VER,
  11794. + CRYPTO_MAX_VER);
  11795. +ICP_MODULE_DEPEND(icp_ocf, cryptodev, MODULE_MIN_VER, MODULE_MIN_VER,
  11796. + CRYPTO_MAX_VER);
  11797. +ICP_MODULE_DEPEND(icp_ocf, icp_crypto, MODULE_MIN_VER, MODULE_MIN_VER,
  11798. + LAC_MAX_VER);
  11799. diff -Nur linux-2.6.39.orig/crypto/ocf/ep80579/icp_ocf.h linux-2.6.39/crypto/ocf/ep80579/icp_ocf.h
  11800. --- linux-2.6.39.orig/crypto/ocf/ep80579/icp_ocf.h 1970-01-01 01:00:00.000000000 +0100
  11801. +++ linux-2.6.39/crypto/ocf/ep80579/icp_ocf.h 2011-07-31 11:31:53.934826868 +0200
  11802. @@ -0,0 +1,376 @@
  11803. +/***************************************************************************
  11804. + *
  11805. + * This file is provided under a dual BSD/GPLv2 license. When using or
  11806. + * redistributing this file, you may do so under either license.
  11807. + *
  11808. + * GPL LICENSE SUMMARY
  11809. + *
  11810. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  11811. + *
  11812. + * This program is free software; you can redistribute it and/or modify
  11813. + * it under the terms of version 2 of the GNU General Public License as
  11814. + * published by the Free Software Foundation.
  11815. + *
  11816. + * This program is distributed in the hope that it will be useful, but
  11817. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  11818. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11819. + * General Public License for more details.
  11820. + *
  11821. + * You should have received a copy of the GNU General Public License
  11822. + * along with this program; if not, write to the Free Software
  11823. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  11824. + * The full GNU General Public License is included in this distribution
  11825. + * in the file called LICENSE.GPL.
  11826. + *
  11827. + * Contact Information:
  11828. + * Intel Corporation
  11829. + *
  11830. + * BSD LICENSE
  11831. + *
  11832. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  11833. + * All rights reserved.
  11834. + *
  11835. + * Redistribution and use in source and binary forms, with or without
  11836. + * modification, are permitted provided that the following conditions
  11837. + * are met:
  11838. + *
  11839. + * * Redistributions of source code must retain the above copyright
  11840. + * notice, this list of conditions and the following disclaimer.
  11841. + * * Redistributions in binary form must reproduce the above copyright
  11842. + * notice, this list of conditions and the following disclaimer in
  11843. + * the documentation and/or other materials provided with the
  11844. + * distribution.
  11845. + * * Neither the name of Intel Corporation nor the names of its
  11846. + * contributors may be used to endorse or promote products derived
  11847. + * from this software without specific prior written permission.
  11848. + *
  11849. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  11850. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  11851. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  11852. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  11853. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  11854. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11855. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  11856. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11857. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  11858. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  11859. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  11860. + *
  11861. + *
  11862. + * version: Security.L.1.0.2-229
  11863. + *
  11864. + ***************************************************************************/
  11865. +
  11866. +/*
  11867. + * OCF driver header file for the Intel ICP processor.
  11868. + */
  11869. +
  11870. +#ifndef ICP_OCF_H_
  11871. +#define ICP_OCF_H_
  11872. +
  11873. +#include <cpa.h>
  11874. +#include <cpa_cy_im.h>
  11875. +#include <cpa_cy_sym.h>
  11876. +#include <cpa_cy_rand.h>
  11877. +#include <cpa_cy_dh.h>
  11878. +#include <cpa_cy_rsa.h>
  11879. +#include <cpa_cy_ln.h>
  11880. +#include <cpa_cy_common.h>
  11881. +#include <cpa_cy_dsa.h>
  11882. +
  11883. +#include "icp_os.h"
  11884. +
  11885. +#define NUM_BITS_IN_BYTE (8)
  11886. +#define NUM_BITS_IN_BYTE_MINUS_ONE (NUM_BITS_IN_BYTE -1)
  11887. +#define INVALID_DRIVER_ID (-1)
  11888. +#define RETURN_RAND_NUM_GEN_FAILED (-1)
  11889. +
  11890. +/*This is the max block cipher initialisation vector*/
  11891. +#define MAX_IV_LEN_IN_BYTES (20)
  11892. +/*This is used to check whether the OCF to this driver session limit has
  11893. + been disabled*/
  11894. +#define NO_OCF_TO_DRV_MAX_SESSIONS (0)
  11895. +
  11896. +/*OCF values mapped here*/
  11897. +#define ICP_SHA1_DIGEST_SIZE_IN_BYTES (SHA1_HASH_LEN)
  11898. +#define ICP_SHA256_DIGEST_SIZE_IN_BYTES (SHA2_256_HASH_LEN)
  11899. +#define ICP_SHA384_DIGEST_SIZE_IN_BYTES (SHA2_384_HASH_LEN)
  11900. +#define ICP_SHA512_DIGEST_SIZE_IN_BYTES (SHA2_512_HASH_LEN)
  11901. +#define ICP_MD5_DIGEST_SIZE_IN_BYTES (MD5_HASH_LEN)
  11902. +#define ARC4_COUNTER_LEN (ARC4_BLOCK_LEN)
  11903. +
  11904. +#define OCF_REGISTRATION_STATUS_SUCCESS (0)
  11905. +#define OCF_ZERO_FUNCTIONALITY_REGISTERED (0)
  11906. +#define ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR (0)
  11907. +#define ICP_OCF_DRV_STATUS_SUCCESS (0)
  11908. +#define ICP_OCF_DRV_STATUS_FAIL (1)
  11909. +
  11910. +/*Turn on/off debug options*/
  11911. +#define ICP_OCF_PRINT_DEBUG_MESSAGES (0)
  11912. +#define ICP_OCF_PRINT_KERN_ALERT (1)
  11913. +#define ICP_OCF_PRINT_KERN_ERRS (1)
  11914. +
  11915. +#if ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  11916. +#define DPRINTK(args...) \
  11917. +{ \
  11918. + ICP_IPRINTK(args); \
  11919. +}
  11920. +
  11921. +#else //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  11922. +
  11923. +#define DPRINTK(args...)
  11924. +
  11925. +#endif //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  11926. +
  11927. +#if ICP_OCF_PRINT_KERN_ALERT == 1
  11928. +#define APRINTK(args...) \
  11929. +{ \
  11930. + ICP_APRINTK(args); \
  11931. +}
  11932. +
  11933. +#else //ICP_OCF_PRINT_KERN_ALERT == 1
  11934. +
  11935. +#define APRINTK(args...)
  11936. +
  11937. +#endif //ICP_OCF_PRINT_KERN_ALERT == 1
  11938. +
  11939. +#if ICP_OCF_PRINT_KERN_ERRS == 1
  11940. +#define EPRINTK(args...) \
  11941. +{ \
  11942. + ICP_EPRINTK(args); \
  11943. +}
  11944. +
  11945. +#else //ICP_OCF_PRINT_KERN_ERRS == 1
  11946. +
  11947. +#define EPRINTK(args...)
  11948. +
  11949. +#endif //ICP_OCF_PRINT_KERN_ERRS == 1
  11950. +
  11951. +#define IPRINTK(args...) \
  11952. +{ \
  11953. + ICP_IPRINTK(args); \
  11954. +}
  11955. +
  11956. +/*DSA Prime Q size in bytes (as defined in the standard) */
  11957. +#define DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES (20)
  11958. +
  11959. +#define BITS_TO_BYTES(bytes, bits) \
  11960. + bytes = (bits + NUM_BITS_IN_BYTE_MINUS_ONE) / NUM_BITS_IN_BYTE
  11961. +
  11962. +typedef enum {
  11963. + ICP_OCF_DRV_ALG_CIPHER = 0,
  11964. + ICP_OCF_DRV_ALG_HASH
  11965. +} icp_ocf_drv_alg_type_t;
  11966. +
  11967. +typedef ICP_LIST_HEAD(icp_drvSessionListHead_s,
  11968. + icp_drvSessionData) icp_drvSessionListHead_t;
  11969. +
  11970. +/*Values used to derisk chances of performs being called against
  11971. +deregistered sessions (for which the slab page has been reclaimed)
  11972. +This is not a fix - since page frames are reclaimed from a slab, one cannot
  11973. +rely on that memory not being re-used by another app.*/
  11974. +typedef enum {
  11975. + ICP_SESSION_INITIALISED = 0x5C5C5C,
  11976. + ICP_SESSION_RUNNING = 0x005C00,
  11977. + ICP_SESSION_DEREGISTERED = 0xC5C5C5
  11978. +} usage_derisk;
  11979. +
  11980. +/* This struct is required for deferred session
  11981. + deregistration as a work queue function can
  11982. + only have one argument*/
  11983. +struct icp_ocfDrvFreeLacSession {
  11984. + CpaCySymSessionCtx sessionToDeregister;
  11985. + icp_workstruct work;
  11986. +};
  11987. +
  11988. +/*
  11989. +This is the OCF<->OCF_DRV session object:
  11990. +
  11991. +1.listNode
  11992. + The first member is a listNode. These session objects are added to a linked
  11993. + list in order to make it easier to remove them all at session exit time.
  11994. +
  11995. +2.inUse
  11996. + The second member is used to give the session object state and derisk the
  11997. + possibility of OCF batch calls executing against a deregistered session (as
  11998. + described above).
  11999. +
  12000. +3.sessHandle
  12001. + The third member is a LAC<->OCF_DRV session handle (initialised with the first
  12002. + perform request for that session).
  12003. +
  12004. +4.lacSessCtx
  12005. + The fourth is the LAC session context. All the parameters for this structure
  12006. + are only known when the first perform request for this session occurs. That is
  12007. + why the OCF EP80579 Driver only registers a new LAC session at perform time
  12008. +*/
  12009. +struct icp_drvSessionData {
  12010. + ICP_LIST_ENTRY(icp_drvSessionData) listNode;
  12011. + usage_derisk inUse;
  12012. + CpaCySymSessionCtx sessHandle;
  12013. + CpaCySymSessionSetupData lacSessCtx;
  12014. +};
  12015. +
  12016. +/* These are all defined in icp_common.c */
  12017. +extern icp_atomic_t lac_session_failed_dereg_count;
  12018. +extern icp_atomic_t icp_ocfDrvIsExiting;
  12019. +extern icp_atomic_t num_ocf_to_drv_registered_sessions;
  12020. +
  12021. +extern int32_t icp_ocfDrvDriverId;
  12022. +
  12023. +extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
  12024. +extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
  12025. +extern icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ;
  12026. +extern icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
  12027. +
  12028. +/*Slab zones for symettric functionality, instantiated in icp_common.c*/
  12029. +extern icp_kmem_cache drvSessionData_zone;
  12030. +extern icp_kmem_cache drvOpData_zone;
  12031. +
  12032. +/*Slabs zones for asymettric functionality, instantiated in icp_common.c*/
  12033. +extern icp_kmem_cache drvDH_zone;
  12034. +extern icp_kmem_cache drvLnModExp_zone;
  12035. +extern icp_kmem_cache drvRSADecrypt_zone;
  12036. +extern icp_kmem_cache drvRSAPrivateKey_zone;
  12037. +extern icp_kmem_cache drvDSARSSign_zone;
  12038. +extern icp_kmem_cache drvDSARSSignKValue_zone;
  12039. +extern icp_kmem_cache drvDSAVerify_zone;
  12040. +
  12041. +/* Module parameters defined in icp_cpmmon.c*/
  12042. +
  12043. +/* Module parameters - gives the number of times LAC deregistration shall be
  12044. + re-tried */
  12045. +extern int num_dereg_retries;
  12046. +
  12047. +/* Module parameter - gives the delay time in jiffies before a LAC session
  12048. + shall be attempted to be deregistered again */
  12049. +extern int dereg_retry_delay_in_jiffies;
  12050. +
  12051. +/* Module parameter - gives the maximum number of sessions possible between
  12052. + OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
  12053. +extern int max_sessions;
  12054. +
  12055. +/*Slab zones for flatbuffers and bufferlist*/
  12056. +extern icp_kmem_cache drvFlatBuffer_zone;
  12057. +
  12058. +#define ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS (16)
  12059. +
  12060. +struct icp_drvBuffListInfo {
  12061. + Cpa16U numBuffers;
  12062. + Cpa32U metaSize;
  12063. + Cpa32U metaOffset;
  12064. + Cpa32U buffListSize;
  12065. +};
  12066. +
  12067. +extern struct icp_drvBuffListInfo defBuffListInfo;
  12068. +
  12069. +/* This struct is used to keep a reference to the relevant node in the list
  12070. + of sessionData structs, to the buffer type required by OCF and to the OCF
  12071. + provided crp struct that needs to be returned. All this info is needed in
  12072. + the callback function.*/
  12073. +struct icp_drvOpData {
  12074. + CpaCySymOpData lacOpData;
  12075. + uint32_t digestSizeInBytes;
  12076. + struct cryptop *crp;
  12077. + uint8_t bufferType;
  12078. + uint8_t ivData[MAX_IV_LEN_IN_BYTES];
  12079. + uint16_t numBufferListArray;
  12080. + CpaBufferList srcBuffer;
  12081. + CpaFlatBuffer bufferListArray[ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS];
  12082. + CpaBoolean verifyResult;
  12083. +};
  12084. +
  12085. +/* Create a new session between OCF and this driver*/
  12086. +int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sild,
  12087. + struct cryptoini *cri);
  12088. +
  12089. +/* Free a session between this driver and the Quick Assist Framework*/
  12090. +int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid);
  12091. +
  12092. +/* Defer freeing a Quick Assist session*/
  12093. +void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg);
  12094. +
  12095. +/* Process OCF cryptographic request for a symmetric algorithm*/
  12096. +int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint);
  12097. +
  12098. +/* Process OCF cryptographic request for an asymmetric algorithm*/
  12099. +int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint);
  12100. +
  12101. +/* Populate a buffer with random data*/
  12102. +int icp_ocfDrvReadRandom(void *arg, uint32_t * buf, int maxwords);
  12103. +
  12104. +/* Retry Quick Assist session deregistration*/
  12105. +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister);
  12106. +
  12107. +/* Convert an OS scatter gather list to a CPA buffer list*/
  12108. +int icp_ocfDrvPacketBuffToBufferList(icp_packet_buffer_t * pPacketBuffer,
  12109. + CpaBufferList * bufferList);
  12110. +
  12111. +/* Convert a CPA buffer list to an OS scatter gather list*/
  12112. +int icp_ocfDrvBufferListToPacketBuff(CpaBufferList * bufferList,
  12113. + icp_packet_buffer_t ** pPacketBuffer);
  12114. +
  12115. +/* Get the number of buffers in an OS scatter gather list*/
  12116. +uint16_t icp_ocfDrvGetPacketBuffFrags(icp_packet_buffer_t * pPacketBuffer);
  12117. +
  12118. +/* Convert a single OS buffer to a CPA Flat Buffer*/
  12119. +void icp_ocfDrvSinglePacketBuffToFlatBuffer(icp_packet_buffer_t * pPacketBuffer,
  12120. + CpaFlatBuffer * pFlatBuffer);
  12121. +
  12122. +/* Add pointer and length to a CPA Flat Buffer structure*/
  12123. +void icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
  12124. + CpaFlatBuffer * pFlatBuffer);
  12125. +
  12126. +/* Convert pointer and length values to a CPA buffer list*/
  12127. +void icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
  12128. + CpaBufferList * pBufferList);
  12129. +
  12130. +/* Convert a CPA buffer list to pointer and length values*/
  12131. +void icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
  12132. + void **ppDataOut, uint32_t * pLength);
  12133. +
  12134. +/* Set the number of flat buffers in bufferlist and the size of memory
  12135. + to allocate for the pPrivateMetaData member of the CpaBufferList.*/
  12136. +int icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
  12137. + struct icp_drvBuffListInfo *buffListInfo);
  12138. +
  12139. +/* Find pointer position of the digest within an OS scatter gather list*/
  12140. +uint8_t *icp_ocfDrvPacketBufferDigestPointerFind(struct icp_drvOpData
  12141. + *drvOpData,
  12142. + int offsetInBytes,
  12143. + uint32_t digestSizeInBytes);
  12144. +
  12145. +/*This top level function is used to find a pointer to where a digest is
  12146. + stored/needs to be inserted. */
  12147. +uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData *drvOpData,
  12148. + struct cryptodesc *crp_desc);
  12149. +
  12150. +/* Free a CPA flat buffer*/
  12151. +void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer);
  12152. +
  12153. +/* This function will allocate memory for the pPrivateMetaData
  12154. + member of CpaBufferList. */
  12155. +int icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
  12156. + struct icp_drvOpData *pOpData);
  12157. +
  12158. +/* Free data allocated for the pPrivateMetaData
  12159. + member of CpaBufferList.*/
  12160. +void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList);
  12161. +
  12162. +#define ICP_CACHE_CREATE(cache_ID, cache_name) \
  12163. + icp_kmem_cache_create(cache_ID, sizeof(cache_name),ICP_KERNEL_CACHE_ALIGN,\
  12164. + ICP_KERNEL_CACHE_NOINIT)
  12165. +
  12166. +#define ICP_CACHE_FREE(args...) \
  12167. + icp_kmem_cache_free (args)
  12168. +
  12169. +#define ICP_CACHE_DESTROY(slab_zone)\
  12170. +{\
  12171. + if(NULL != slab_zone){\
  12172. + icp_kmem_cache_destroy(slab_zone);\
  12173. + slab_zone = NULL;\
  12174. + }\
  12175. +}
  12176. +
  12177. +#endif
  12178. +/* ICP_OCF_H_ */
  12179. diff -Nur linux-2.6.39.orig/crypto/ocf/ep80579/icp_sym.c linux-2.6.39/crypto/ocf/ep80579/icp_sym.c
  12180. --- linux-2.6.39.orig/crypto/ocf/ep80579/icp_sym.c 1970-01-01 01:00:00.000000000 +0100
  12181. +++ linux-2.6.39/crypto/ocf/ep80579/icp_sym.c 2011-07-31 11:31:53.993903094 +0200
  12182. @@ -0,0 +1,1153 @@
  12183. +/***************************************************************************
  12184. + *
  12185. + * This file is provided under a dual BSD/GPLv2 license. When using or
  12186. + * redistributing this file, you may do so under either license.
  12187. + *
  12188. + * GPL LICENSE SUMMARY
  12189. + *
  12190. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  12191. + *
  12192. + * This program is free software; you can redistribute it and/or modify
  12193. + * it under the terms of version 2 of the GNU General Public License as
  12194. + * published by the Free Software Foundation.
  12195. + *
  12196. + * This program is distributed in the hope that it will be useful, but
  12197. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  12198. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12199. + * General Public License for more details.
  12200. + *
  12201. + * You should have received a copy of the GNU General Public License
  12202. + * along with this program; if not, write to the Free Software
  12203. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  12204. + * The full GNU General Public License is included in this distribution
  12205. + * in the file called LICENSE.GPL.
  12206. + *
  12207. + * Contact Information:
  12208. + * Intel Corporation
  12209. + *
  12210. + * BSD LICENSE
  12211. + *
  12212. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  12213. + * All rights reserved.
  12214. + *
  12215. + * Redistribution and use in source and binary forms, with or without
  12216. + * modification, are permitted provided that the following conditions
  12217. + * are met:
  12218. + *
  12219. + * * Redistributions of source code must retain the above copyright
  12220. + * notice, this list of conditions and the following disclaimer.
  12221. + * * Redistributions in binary form must reproduce the above copyright
  12222. + * notice, this list of conditions and the following disclaimer in
  12223. + * the documentation and/or other materials provided with the
  12224. + * distribution.
  12225. + * * Neither the name of Intel Corporation nor the names of its
  12226. + * contributors may be used to endorse or promote products derived
  12227. + * from this software without specific prior written permission.
  12228. + *
  12229. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12230. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12231. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  12232. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  12233. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  12234. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  12235. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12236. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12237. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12238. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  12239. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12240. + *
  12241. + *
  12242. + * version: Security.L.1.0.2-229
  12243. + *
  12244. + ***************************************************************************/
  12245. +/*
  12246. + * An OCF module that uses the API for Intel® QuickAssist Technology to do the
  12247. + * cryptography.
  12248. + *
  12249. + * This driver requires the ICP Access Library that is available from Intel in
  12250. + * order to operate.
  12251. + */
  12252. +
  12253. +#include "icp_ocf.h"
  12254. +
  12255. +/*This is the call back function for all symmetric cryptographic processes.
  12256. + Its main functionality is to free driver crypto operation structure and to
  12257. + call back to OCF*/
  12258. +static void
  12259. +icp_ocfDrvSymCallBack(void *callbackTag,
  12260. + CpaStatus status,
  12261. + const CpaCySymOp operationType,
  12262. + void *pOpData,
  12263. + CpaBufferList * pDstBuffer, CpaBoolean verifyResult);
  12264. +
  12265. +/*This function is used to extract crypto processing information from the OCF
  12266. + inputs, so as that it may be passed onto LAC*/
  12267. +static int
  12268. +icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  12269. + struct cryptodesc *crp_desc);
  12270. +
  12271. +/*This function checks whether the crp_desc argument pertains to a digest or a
  12272. + cipher operation*/
  12273. +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc);
  12274. +
  12275. +/*This function copies all the passed in session context information and stores
  12276. + it in a LAC context structure*/
  12277. +static int
  12278. +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  12279. + CpaCySymSessionSetupData * lacSessCtx);
  12280. +
  12281. +/*This function is used to free an OCF->OCF_DRV session object*/
  12282. +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData);
  12283. +
  12284. +/*max IOV buffs supported in a UIO structure*/
  12285. +#define NUM_IOV_SUPPORTED (1)
  12286. +
  12287. +/* Name : icp_ocfDrvSymCallBack
  12288. + *
  12289. + * Description : When this function returns it signifies that the LAC
  12290. + * component has completed the relevant symmetric operation.
  12291. + *
  12292. + * Notes : The callbackTag is a pointer to an icp_drvOpData. This memory
  12293. + * object was passed to LAC for the cryptographic processing and contains all
  12294. + * the relevant information for cleaning up buffer handles etc. so that the
  12295. + * OCF EP80579 Driver portion of this crypto operation can be fully completed.
  12296. + */
  12297. +static void
  12298. +icp_ocfDrvSymCallBack(void *callbackTag,
  12299. + CpaStatus status,
  12300. + const CpaCySymOp operationType,
  12301. + void *pOpData,
  12302. + CpaBufferList * pDstBuffer, CpaBoolean verifyResult)
  12303. +{
  12304. + struct cryptop *crp = NULL;
  12305. + struct icp_drvOpData *temp_drvOpData =
  12306. + (struct icp_drvOpData *)callbackTag;
  12307. + uint64_t *tempBasePtr = NULL;
  12308. + uint32_t tempLen = 0;
  12309. +
  12310. + if (NULL == temp_drvOpData) {
  12311. + DPRINTK("%s(): The callback from the LAC component"
  12312. + " has failed due to Null userOpaque data"
  12313. + "(status == %d).\n", __FUNCTION__, status);
  12314. + DPRINTK("%s(): Unable to call OCF back! \n", __FUNCTION__);
  12315. + return;
  12316. + }
  12317. +
  12318. + crp = temp_drvOpData->crp;
  12319. + crp->crp_etype = ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR;
  12320. +
  12321. + if (NULL == pOpData) {
  12322. + DPRINTK("%s(): The callback from the LAC component"
  12323. + " has failed due to Null Symmetric Op data"
  12324. + "(status == %d).\n", __FUNCTION__, status);
  12325. + crp->crp_etype = ECANCELED;
  12326. + crypto_done(crp);
  12327. + return;
  12328. + }
  12329. +
  12330. + if (NULL == pDstBuffer) {
  12331. + DPRINTK("%s(): The callback from the LAC component"
  12332. + " has failed due to Null Dst Bufferlist data"
  12333. + "(status == %d).\n", __FUNCTION__, status);
  12334. + crp->crp_etype = ECANCELED;
  12335. + crypto_done(crp);
  12336. + return;
  12337. + }
  12338. +
  12339. + if (CPA_STATUS_SUCCESS == status) {
  12340. +
  12341. + if (temp_drvOpData->bufferType == ICP_CRYPTO_F_PACKET_BUF) {
  12342. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  12343. + icp_ocfDrvBufferListToPacketBuff(pDstBuffer,
  12344. + (icp_packet_buffer_t
  12345. + **)
  12346. + & (crp->crp_buf))) {
  12347. + EPRINTK("%s(): BufferList to SkBuff "
  12348. + "conversion error.\n", __FUNCTION__);
  12349. + crp->crp_etype = EPERM;
  12350. + }
  12351. + } else {
  12352. + icp_ocfDrvBufferListToPtrAndLen(pDstBuffer,
  12353. + (void **)&tempBasePtr,
  12354. + &tempLen);
  12355. + crp->crp_olen = (int)tempLen;
  12356. + }
  12357. +
  12358. + } else {
  12359. + DPRINTK("%s(): The callback from the LAC component has failed"
  12360. + "(status == %d).\n", __FUNCTION__, status);
  12361. +
  12362. + crp->crp_etype = ECANCELED;
  12363. + }
  12364. +
  12365. + if (temp_drvOpData->numBufferListArray >
  12366. + ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  12367. + icp_kfree(pDstBuffer->pBuffers);
  12368. + }
  12369. + icp_ocfDrvFreeMetaData(pDstBuffer);
  12370. + ICP_CACHE_FREE(drvOpData_zone, temp_drvOpData);
  12371. +
  12372. + /* Invoke the OCF callback function */
  12373. + crypto_done(crp);
  12374. +
  12375. + return;
  12376. +}
  12377. +
  12378. +/* Name : icp_ocfDrvNewSession
  12379. + *
  12380. + * Description : This function will create a new Driver<->OCF session
  12381. + *
  12382. + * Notes : LAC session registration happens during the first perform call.
  12383. + * That is the first time we know all information about a given session.
  12384. + */
  12385. +int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sid,
  12386. + struct cryptoini *cri)
  12387. +{
  12388. + struct icp_drvSessionData *sessionData = NULL;
  12389. + uint32_t delete_session = 0;
  12390. +
  12391. + /* The SID passed in should be our driver ID. We can return the */
  12392. + /* local ID (LID) which is a unique identifier which we can use */
  12393. + /* to differentiate between the encrypt/decrypt LAC session handles */
  12394. + if (NULL == sid) {
  12395. + EPRINTK("%s(): Invalid input parameters - NULL sid.\n",
  12396. + __FUNCTION__);
  12397. + return EINVAL;
  12398. + }
  12399. +
  12400. + if (NULL == cri) {
  12401. + EPRINTK("%s(): Invalid input parameters - NULL cryptoini.\n",
  12402. + __FUNCTION__);
  12403. + return EINVAL;
  12404. + }
  12405. +
  12406. + if (icp_ocfDrvDriverId != *sid) {
  12407. + EPRINTK("%s(): Invalid input parameters - bad driver ID\n",
  12408. + __FUNCTION__);
  12409. + EPRINTK("\t sid = 0x08%p \n \t cri = 0x08%p \n", sid, cri);
  12410. + return EINVAL;
  12411. + }
  12412. +
  12413. + sessionData = icp_kmem_cache_zalloc(drvSessionData_zone, ICP_M_NOWAIT);
  12414. + if (NULL == sessionData) {
  12415. + DPRINTK("%s():No memory for Session Data\n", __FUNCTION__);
  12416. + return ENOMEM;
  12417. + }
  12418. +
  12419. + /*ENTER CRITICAL SECTION */
  12420. + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  12421. + /*put this check in the spinlock so no new sessions can be added to the
  12422. + linked list when we are exiting */
  12423. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  12424. + delete_session++;
  12425. +
  12426. + } else if (NO_OCF_TO_DRV_MAX_SESSIONS != max_sessions) {
  12427. + if (icp_atomic_read(&num_ocf_to_drv_registered_sessions) >=
  12428. + (max_sessions -
  12429. + icp_atomic_read(&lac_session_failed_dereg_count))) {
  12430. + delete_session++;
  12431. + } else {
  12432. + icp_atomic_inc(&num_ocf_to_drv_registered_sessions);
  12433. + /* Add to session data linked list */
  12434. + ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
  12435. + listNode);
  12436. + }
  12437. +
  12438. + } else if (NO_OCF_TO_DRV_MAX_SESSIONS == max_sessions) {
  12439. + ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
  12440. + listNode);
  12441. + }
  12442. +
  12443. + sessionData->inUse = ICP_SESSION_INITIALISED;
  12444. +
  12445. + /*EXIT CRITICAL SECTION */
  12446. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  12447. +
  12448. + if (delete_session) {
  12449. + DPRINTK("%s():No Session handles available\n", __FUNCTION__);
  12450. + ICP_CACHE_FREE(drvSessionData_zone, sessionData);
  12451. + return EPERM;
  12452. + }
  12453. +
  12454. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  12455. + icp_ocfDrvAlgorithmSetup(cri, &(sessionData->lacSessCtx))) {
  12456. + DPRINTK("%s():algorithm not supported\n", __FUNCTION__);
  12457. + icp_ocfDrvFreeOCFSession(sessionData);
  12458. + return EINVAL;
  12459. + }
  12460. +
  12461. + if (cri->cri_next) {
  12462. + if (cri->cri_next->cri_next != NULL) {
  12463. + DPRINTK("%s():only two chained algorithms supported\n",
  12464. + __FUNCTION__);
  12465. + icp_ocfDrvFreeOCFSession(sessionData);
  12466. + return EPERM;
  12467. + }
  12468. +
  12469. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  12470. + icp_ocfDrvAlgorithmSetup(cri->cri_next,
  12471. + &(sessionData->lacSessCtx))) {
  12472. + DPRINTK("%s():second algorithm not supported\n",
  12473. + __FUNCTION__);
  12474. + icp_ocfDrvFreeOCFSession(sessionData);
  12475. + return EINVAL;
  12476. + }
  12477. +
  12478. + sessionData->lacSessCtx.symOperation =
  12479. + CPA_CY_SYM_OP_ALGORITHM_CHAINING;
  12480. + }
  12481. +
  12482. + *sid = (uint32_t) sessionData;
  12483. +
  12484. + return ICP_OCF_DRV_STATUS_SUCCESS;
  12485. +}
  12486. +
  12487. +/* Name : icp_ocfDrvAlgorithmSetup
  12488. + *
  12489. + * Description : This function builds the session context data from the
  12490. + * information supplied through OCF. Algorithm chain order and whether the
  12491. + * session is Encrypt/Decrypt can only be found out at perform time however, so
  12492. + * the session is registered with LAC at that time.
  12493. + */
  12494. +static int
  12495. +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  12496. + CpaCySymSessionSetupData * lacSessCtx)
  12497. +{
  12498. +
  12499. + lacSessCtx->sessionPriority = CPA_CY_PRIORITY_NORMAL;
  12500. +
  12501. + switch (cri->cri_alg) {
  12502. +
  12503. + case CRYPTO_NULL_CBC:
  12504. + DPRINTK("%s(): NULL CBC\n", __FUNCTION__);
  12505. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  12506. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  12507. + CPA_CY_SYM_CIPHER_NULL;
  12508. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  12509. + cri->cri_klen / NUM_BITS_IN_BYTE;
  12510. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  12511. + break;
  12512. +
  12513. + case CRYPTO_DES_CBC:
  12514. + DPRINTK("%s(): DES CBC\n", __FUNCTION__);
  12515. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  12516. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  12517. + CPA_CY_SYM_CIPHER_DES_CBC;
  12518. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  12519. + cri->cri_klen / NUM_BITS_IN_BYTE;
  12520. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  12521. + break;
  12522. +
  12523. + case CRYPTO_3DES_CBC:
  12524. + DPRINTK("%s(): 3DES CBC\n", __FUNCTION__);
  12525. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  12526. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  12527. + CPA_CY_SYM_CIPHER_3DES_CBC;
  12528. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  12529. + cri->cri_klen / NUM_BITS_IN_BYTE;
  12530. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  12531. + break;
  12532. +
  12533. + case CRYPTO_AES_CBC:
  12534. + DPRINTK("%s(): AES CBC\n", __FUNCTION__);
  12535. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  12536. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  12537. + CPA_CY_SYM_CIPHER_AES_CBC;
  12538. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  12539. + cri->cri_klen / NUM_BITS_IN_BYTE;
  12540. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  12541. + break;
  12542. +
  12543. + case CRYPTO_ARC4:
  12544. + DPRINTK("%s(): ARC4\n", __FUNCTION__);
  12545. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  12546. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  12547. + CPA_CY_SYM_CIPHER_ARC4;
  12548. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  12549. + cri->cri_klen / NUM_BITS_IN_BYTE;
  12550. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  12551. + break;
  12552. +
  12553. + case CRYPTO_SHA1:
  12554. + DPRINTK("%s(): SHA1\n", __FUNCTION__);
  12555. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  12556. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  12557. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  12558. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  12559. + (cri->cri_mlen ?
  12560. + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  12561. +
  12562. + break;
  12563. +
  12564. + case CRYPTO_SHA1_HMAC:
  12565. + DPRINTK("%s(): SHA1_HMAC\n", __FUNCTION__);
  12566. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  12567. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  12568. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  12569. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  12570. + (cri->cri_mlen ?
  12571. + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  12572. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  12573. + cri->cri_key;
  12574. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  12575. + cri->cri_klen / NUM_BITS_IN_BYTE;
  12576. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  12577. +
  12578. + break;
  12579. +
  12580. + case CRYPTO_SHA2_256:
  12581. + DPRINTK("%s(): SHA256\n", __FUNCTION__);
  12582. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  12583. + lacSessCtx->hashSetupData.hashAlgorithm =
  12584. + CPA_CY_SYM_HASH_SHA256;
  12585. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  12586. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  12587. + (cri->cri_mlen ?
  12588. + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  12589. +
  12590. + break;
  12591. +
  12592. + case CRYPTO_SHA2_256_HMAC:
  12593. + DPRINTK("%s(): SHA256_HMAC\n", __FUNCTION__);
  12594. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  12595. + lacSessCtx->hashSetupData.hashAlgorithm =
  12596. + CPA_CY_SYM_HASH_SHA256;
  12597. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  12598. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  12599. + (cri->cri_mlen ?
  12600. + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  12601. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  12602. + cri->cri_key;
  12603. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  12604. + cri->cri_klen / NUM_BITS_IN_BYTE;
  12605. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  12606. +
  12607. + break;
  12608. +
  12609. + case CRYPTO_SHA2_384:
  12610. + DPRINTK("%s(): SHA384\n", __FUNCTION__);
  12611. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  12612. + lacSessCtx->hashSetupData.hashAlgorithm =
  12613. + CPA_CY_SYM_HASH_SHA384;
  12614. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  12615. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  12616. + (cri->cri_mlen ?
  12617. + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  12618. +
  12619. + break;
  12620. +
  12621. + case CRYPTO_SHA2_384_HMAC:
  12622. + DPRINTK("%s(): SHA384_HMAC\n", __FUNCTION__);
  12623. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  12624. + lacSessCtx->hashSetupData.hashAlgorithm =
  12625. + CPA_CY_SYM_HASH_SHA384;
  12626. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  12627. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  12628. + (cri->cri_mlen ?
  12629. + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  12630. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  12631. + cri->cri_key;
  12632. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  12633. + cri->cri_klen / NUM_BITS_IN_BYTE;
  12634. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  12635. +
  12636. + break;
  12637. +
  12638. + case CRYPTO_SHA2_512:
  12639. + DPRINTK("%s(): SHA512\n", __FUNCTION__);
  12640. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  12641. + lacSessCtx->hashSetupData.hashAlgorithm =
  12642. + CPA_CY_SYM_HASH_SHA512;
  12643. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  12644. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  12645. + (cri->cri_mlen ?
  12646. + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  12647. +
  12648. + break;
  12649. +
  12650. + case CRYPTO_SHA2_512_HMAC:
  12651. + DPRINTK("%s(): SHA512_HMAC\n", __FUNCTION__);
  12652. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  12653. + lacSessCtx->hashSetupData.hashAlgorithm =
  12654. + CPA_CY_SYM_HASH_SHA512;
  12655. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  12656. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  12657. + (cri->cri_mlen ?
  12658. + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  12659. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  12660. + cri->cri_key;
  12661. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  12662. + cri->cri_klen / NUM_BITS_IN_BYTE;
  12663. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  12664. +
  12665. + break;
  12666. +
  12667. + case CRYPTO_MD5:
  12668. + DPRINTK("%s(): MD5\n", __FUNCTION__);
  12669. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  12670. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  12671. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  12672. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  12673. + (cri->cri_mlen ?
  12674. + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  12675. +
  12676. + break;
  12677. +
  12678. + case CRYPTO_MD5_HMAC:
  12679. + DPRINTK("%s(): MD5_HMAC\n", __FUNCTION__);
  12680. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  12681. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  12682. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  12683. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  12684. + (cri->cri_mlen ?
  12685. + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  12686. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  12687. + cri->cri_key;
  12688. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  12689. + cri->cri_klen / NUM_BITS_IN_BYTE;
  12690. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  12691. +
  12692. + break;
  12693. +
  12694. + default:
  12695. + DPRINTK("%s(): ALG Setup FAIL\n", __FUNCTION__);
  12696. + return ICP_OCF_DRV_STATUS_FAIL;
  12697. + }
  12698. +
  12699. + return ICP_OCF_DRV_STATUS_SUCCESS;
  12700. +}
  12701. +
  12702. +/* Name : icp_ocfDrvFreeOCFSession
  12703. + *
  12704. + * Description : This function deletes all existing Session data representing
  12705. + * the Cryptographic session established between OCF and this driver. This
  12706. + * also includes freeing the memory allocated for the session context. The
  12707. + * session object is also removed from the session linked list.
  12708. + */
  12709. +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData)
  12710. +{
  12711. +
  12712. + sessionData->inUse = ICP_SESSION_DEREGISTERED;
  12713. +
  12714. + /*ENTER CRITICAL SECTION */
  12715. + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  12716. +
  12717. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  12718. + /*If the Driver is exiting, allow that process to
  12719. + handle any deletions */
  12720. + /*EXIT CRITICAL SECTION */
  12721. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  12722. + return;
  12723. + }
  12724. +
  12725. + icp_atomic_dec(&num_ocf_to_drv_registered_sessions);
  12726. +
  12727. + ICP_LIST_DEL(sessionData, listNode);
  12728. +
  12729. + /*EXIT CRITICAL SECTION */
  12730. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  12731. +
  12732. + if (NULL != sessionData->sessHandle) {
  12733. + icp_kfree(sessionData->sessHandle);
  12734. + }
  12735. + ICP_CACHE_FREE(drvSessionData_zone, sessionData);
  12736. +}
  12737. +
  12738. +/* Name : icp_ocfDrvFreeLACSession
  12739. + *
  12740. + * Description : This attempts to deregister a LAC session. If it fails, the
  12741. + * deregistation retry function is called.
  12742. + */
  12743. +int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid)
  12744. +{
  12745. + CpaCySymSessionCtx sessionToDeregister = NULL;
  12746. + struct icp_drvSessionData *sessionData = NULL;
  12747. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  12748. + int retval = 0;
  12749. +
  12750. + sessionData = (struct icp_drvSessionData *)CRYPTO_SESID2LID(sid);
  12751. + if (NULL == sessionData) {
  12752. + EPRINTK("%s(): OCF Free session called with Null Session ID.\n",
  12753. + __FUNCTION__);
  12754. + return EINVAL;
  12755. + }
  12756. +
  12757. + sessionToDeregister = sessionData->sessHandle;
  12758. +
  12759. + if ((ICP_SESSION_INITIALISED != sessionData->inUse) &&
  12760. + (ICP_SESSION_RUNNING != sessionData->inUse) &&
  12761. + (ICP_SESSION_DEREGISTERED != sessionData->inUse)) {
  12762. + DPRINTK("%s() Session not initialised.\n", __FUNCTION__);
  12763. + return EINVAL;
  12764. + }
  12765. +
  12766. + if (ICP_SESSION_RUNNING == sessionData->inUse) {
  12767. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  12768. + sessionToDeregister);
  12769. + if (CPA_STATUS_RETRY == lacStatus) {
  12770. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  12771. + icp_ocfDrvDeregRetry(&sessionToDeregister)) {
  12772. + /* the retry function increments the
  12773. + dereg failed count */
  12774. + DPRINTK("%s(): LAC failed to deregister the "
  12775. + "session. (localSessionId= %p)\n",
  12776. + __FUNCTION__, sessionToDeregister);
  12777. + retval = EPERM;
  12778. + }
  12779. +
  12780. + } else if (CPA_STATUS_SUCCESS != lacStatus) {
  12781. + DPRINTK("%s(): LAC failed to deregister the session. "
  12782. + "localSessionId= %p, lacStatus = %d\n",
  12783. + __FUNCTION__, sessionToDeregister, lacStatus);
  12784. + icp_atomic_inc(&lac_session_failed_dereg_count);
  12785. + retval = EPERM;
  12786. + }
  12787. + } else {
  12788. + DPRINTK("%s() Session not registered with LAC.\n",
  12789. + __FUNCTION__);
  12790. + }
  12791. +
  12792. + icp_ocfDrvFreeOCFSession(sessionData);
  12793. + return retval;
  12794. +
  12795. +}
  12796. +
  12797. +/* Name : icp_ocfDrvAlgCheck
  12798. + *
  12799. + * Description : This function checks whether the cryptodesc argument pertains
  12800. + * to a sym or hash function
  12801. + */
  12802. +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc)
  12803. +{
  12804. +
  12805. + if (crp_desc->crd_alg == CRYPTO_3DES_CBC ||
  12806. + crp_desc->crd_alg == CRYPTO_AES_CBC ||
  12807. + crp_desc->crd_alg == CRYPTO_DES_CBC ||
  12808. + crp_desc->crd_alg == CRYPTO_NULL_CBC ||
  12809. + crp_desc->crd_alg == CRYPTO_ARC4) {
  12810. + return ICP_OCF_DRV_ALG_CIPHER;
  12811. + }
  12812. +
  12813. + return ICP_OCF_DRV_ALG_HASH;
  12814. +}
  12815. +
  12816. +/* Name : icp_ocfDrvSymProcess
  12817. + *
  12818. + * Description : This function will map symmetric functionality calls from OCF
  12819. + * to the LAC API. It will also allocate memory to store the session context.
  12820. + *
  12821. + * Notes: If it is the first perform call for a given session, then a LAC
  12822. + * session is registered. After the session is registered, no checks as
  12823. + * to whether session paramaters have changed (e.g. alg chain order) are
  12824. + * done.
  12825. + */
  12826. +int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint)
  12827. +{
  12828. + struct icp_drvSessionData *sessionData = NULL;
  12829. + struct icp_drvOpData *drvOpData = NULL;
  12830. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  12831. + Cpa32U sessionCtxSizeInBytes = 0;
  12832. +
  12833. + if (NULL == crp) {
  12834. + DPRINTK("%s(): Invalid input parameters, cryptop is NULL\n",
  12835. + __FUNCTION__);
  12836. + return EINVAL;
  12837. + }
  12838. +
  12839. + if (NULL == crp->crp_desc) {
  12840. + DPRINTK("%s(): Invalid input parameters, no crp_desc attached "
  12841. + "to crp\n", __FUNCTION__);
  12842. + crp->crp_etype = EINVAL;
  12843. + return EINVAL;
  12844. + }
  12845. +
  12846. + if (NULL == crp->crp_buf) {
  12847. + DPRINTK("%s(): Invalid input parameters, no buffer attached "
  12848. + "to crp\n", __FUNCTION__);
  12849. + crp->crp_etype = EINVAL;
  12850. + return EINVAL;
  12851. + }
  12852. +
  12853. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  12854. + crp->crp_etype = EFAULT;
  12855. + return EFAULT;
  12856. + }
  12857. +
  12858. + sessionData = (struct icp_drvSessionData *)
  12859. + (CRYPTO_SESID2LID(crp->crp_sid));
  12860. + if (NULL == sessionData) {
  12861. + DPRINTK("%s(): Invalid input parameters, Null Session ID \n",
  12862. + __FUNCTION__);
  12863. + crp->crp_etype = EINVAL;
  12864. + return EINVAL;
  12865. + }
  12866. +
  12867. +/*If we get a request against a deregisted session, cancel operation*/
  12868. + if (ICP_SESSION_DEREGISTERED == sessionData->inUse) {
  12869. + DPRINTK("%s(): Session ID %d was deregistered \n",
  12870. + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  12871. + crp->crp_etype = EFAULT;
  12872. + return EFAULT;
  12873. + }
  12874. +
  12875. +/*If none of the session states are set, then the session structure was either
  12876. + not initialised properly or we are reading from a freed memory area (possible
  12877. + due to OCF batch mode not removing queued requests against deregistered
  12878. + sessions*/
  12879. + if (ICP_SESSION_INITIALISED != sessionData->inUse &&
  12880. + ICP_SESSION_RUNNING != sessionData->inUse) {
  12881. + DPRINTK("%s(): Session - ID %d - not properly initialised or "
  12882. + "memory freed back to the kernel \n",
  12883. + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  12884. + crp->crp_etype = EINVAL;
  12885. + return EINVAL;
  12886. + }
  12887. +
  12888. + /*For the below checks, remember error checking is already done in LAC.
  12889. + We're not validating inputs subsequent to registration */
  12890. + if (sessionData->inUse == ICP_SESSION_INITIALISED) {
  12891. + DPRINTK("%s(): Initialising session\n", __FUNCTION__);
  12892. +
  12893. + if (NULL != crp->crp_desc->crd_next) {
  12894. + if (ICP_OCF_DRV_ALG_CIPHER ==
  12895. + icp_ocfDrvAlgCheck(crp->crp_desc)) {
  12896. +
  12897. + sessionData->lacSessCtx.algChainOrder =
  12898. + CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
  12899. +
  12900. + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  12901. + sessionData->lacSessCtx.cipherSetupData.
  12902. + cipherDirection =
  12903. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  12904. + } else {
  12905. + sessionData->lacSessCtx.cipherSetupData.
  12906. + cipherDirection =
  12907. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  12908. + }
  12909. + } else {
  12910. + sessionData->lacSessCtx.algChainOrder =
  12911. + CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
  12912. +
  12913. + if (crp->crp_desc->crd_next->crd_flags &
  12914. + CRD_F_ENCRYPT) {
  12915. + sessionData->lacSessCtx.cipherSetupData.
  12916. + cipherDirection =
  12917. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  12918. + } else {
  12919. + sessionData->lacSessCtx.cipherSetupData.
  12920. + cipherDirection =
  12921. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  12922. + }
  12923. +
  12924. + }
  12925. +
  12926. + } else if (ICP_OCF_DRV_ALG_CIPHER ==
  12927. + icp_ocfDrvAlgCheck(crp->crp_desc)) {
  12928. + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  12929. + sessionData->lacSessCtx.cipherSetupData.
  12930. + cipherDirection =
  12931. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  12932. + } else {
  12933. + sessionData->lacSessCtx.cipherSetupData.
  12934. + cipherDirection =
  12935. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  12936. + }
  12937. +
  12938. + }
  12939. +
  12940. + /*No action required for standalone Auth here */
  12941. +
  12942. + /* Allocate memory for SymSessionCtx before the Session Registration */
  12943. + lacStatus =
  12944. + cpaCySymSessionCtxGetSize(CPA_INSTANCE_HANDLE_SINGLE,
  12945. + &(sessionData->lacSessCtx),
  12946. + &sessionCtxSizeInBytes);
  12947. + if (CPA_STATUS_SUCCESS != lacStatus) {
  12948. + EPRINTK("%s(): cpaCySymSessionCtxGetSize failed - %d\n",
  12949. + __FUNCTION__, lacStatus);
  12950. + crp->crp_etype = EINVAL;
  12951. + return EINVAL;
  12952. + }
  12953. + sessionData->sessHandle =
  12954. + icp_kmalloc(sessionCtxSizeInBytes, ICP_M_NOWAIT);
  12955. + if (NULL == sessionData->sessHandle) {
  12956. + EPRINTK
  12957. + ("%s(): Failed to get memory for SymSessionCtx\n",
  12958. + __FUNCTION__);
  12959. + crp->crp_etype = ENOMEM;
  12960. + return ENOMEM;
  12961. + }
  12962. +
  12963. + lacStatus = cpaCySymInitSession(CPA_INSTANCE_HANDLE_SINGLE,
  12964. + icp_ocfDrvSymCallBack,
  12965. + &(sessionData->lacSessCtx),
  12966. + sessionData->sessHandle);
  12967. +
  12968. + if (CPA_STATUS_SUCCESS != lacStatus) {
  12969. + EPRINTK("%s(): cpaCySymInitSession failed -%d \n",
  12970. + __FUNCTION__, lacStatus);
  12971. + crp->crp_etype = EFAULT;
  12972. + return EFAULT;
  12973. + }
  12974. +
  12975. + sessionData->inUse = ICP_SESSION_RUNNING;
  12976. + }
  12977. +
  12978. + drvOpData = icp_kmem_cache_zalloc(drvOpData_zone, ICP_M_NOWAIT);
  12979. + if (NULL == drvOpData) {
  12980. + EPRINTK("%s():Failed to get memory for drvOpData\n",
  12981. + __FUNCTION__);
  12982. + crp->crp_etype = ENOMEM;
  12983. + return ENOMEM;
  12984. + }
  12985. +
  12986. + drvOpData->lacOpData.pSessionCtx = sessionData->sessHandle;
  12987. + drvOpData->digestSizeInBytes = sessionData->lacSessCtx.hashSetupData.
  12988. + digestResultLenInBytes;
  12989. + drvOpData->crp = crp;
  12990. +
  12991. + /* Set the default buffer list array memory allocation */
  12992. + drvOpData->srcBuffer.pBuffers = drvOpData->bufferListArray;
  12993. + drvOpData->numBufferListArray = ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS;
  12994. +
  12995. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  12996. + icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->crp_desc)) {
  12997. + crp->crp_etype = EINVAL;
  12998. + goto err;
  12999. + }
  13000. +
  13001. + if (drvOpData->crp->crp_desc->crd_next != NULL) {
  13002. + if (icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->
  13003. + crp_desc->crd_next)) {
  13004. + crp->crp_etype = EINVAL;
  13005. + goto err;
  13006. + }
  13007. +
  13008. + }
  13009. +
  13010. + /*
  13011. + * Allocate buffer list array memory if the data fragment is more than
  13012. + * the default number (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) and not
  13013. + * calculated already
  13014. + */
  13015. + if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  13016. + if (NULL == drvOpData->lacOpData.pDigestResult) {
  13017. + drvOpData->numBufferListArray =
  13018. + icp_ocfDrvGetPacketBuffFrags((icp_packet_buffer_t *)
  13019. + crp->crp_buf);
  13020. + }
  13021. +
  13022. + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS <
  13023. + drvOpData->numBufferListArray) {
  13024. + DPRINTK("%s() numBufferListArray more than default\n",
  13025. + __FUNCTION__);
  13026. + drvOpData->srcBuffer.pBuffers = NULL;
  13027. + drvOpData->srcBuffer.pBuffers =
  13028. + icp_kmalloc(drvOpData->numBufferListArray *
  13029. + sizeof(CpaFlatBuffer), ICP_M_NOWAIT);
  13030. + if (NULL == drvOpData->srcBuffer.pBuffers) {
  13031. + EPRINTK("%s() Failed to get memory for "
  13032. + "pBuffers\n", __FUNCTION__);
  13033. + ICP_CACHE_FREE(drvOpData_zone, drvOpData);
  13034. + crp->crp_etype = ENOMEM;
  13035. + return ENOMEM;
  13036. + }
  13037. + }
  13038. + }
  13039. +
  13040. + /*
  13041. + * Check the type of buffer structure we got and convert it into
  13042. + * CpaBufferList format.
  13043. + */
  13044. + if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  13045. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  13046. + icp_ocfDrvPacketBuffToBufferList((icp_packet_buffer_t *)
  13047. + crp->crp_buf,
  13048. + &(drvOpData->srcBuffer))) {
  13049. + EPRINTK("%s():Failed to translate from packet buffer "
  13050. + "to bufferlist\n", __FUNCTION__);
  13051. + crp->crp_etype = EINVAL;
  13052. + goto err;
  13053. + }
  13054. +
  13055. + drvOpData->bufferType = ICP_CRYPTO_F_PACKET_BUF;
  13056. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  13057. + /* OCF only supports IOV of one entry. */
  13058. + if (NUM_IOV_SUPPORTED ==
  13059. + ((struct uio *)(crp->crp_buf))->uio_iovcnt) {
  13060. +
  13061. + icp_ocfDrvPtrAndLenToBufferList(((struct uio *)(crp->
  13062. + crp_buf))->
  13063. + uio_iov[0].iov_base,
  13064. + ((struct uio *)(crp->
  13065. + crp_buf))->
  13066. + uio_iov[0].iov_len,
  13067. + &(drvOpData->
  13068. + srcBuffer));
  13069. +
  13070. + drvOpData->bufferType = CRYPTO_F_IOV;
  13071. +
  13072. + } else {
  13073. + DPRINTK("%s():Unable to handle IOVs with lengths of "
  13074. + "greater than one!\n", __FUNCTION__);
  13075. + crp->crp_etype = EINVAL;
  13076. + goto err;
  13077. + }
  13078. +
  13079. + } else {
  13080. + icp_ocfDrvPtrAndLenToBufferList(crp->crp_buf,
  13081. + crp->crp_ilen,
  13082. + &(drvOpData->srcBuffer));
  13083. +
  13084. + drvOpData->bufferType = CRYPTO_BUF_CONTIG;
  13085. + }
  13086. +
  13087. + /* Allocate srcBuffer's private meta data */
  13088. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  13089. + icp_ocfDrvAllocMetaData(&(drvOpData->srcBuffer), drvOpData)) {
  13090. + EPRINTK("%s() icp_ocfDrvAllocMetaData failed\n", __FUNCTION__);
  13091. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  13092. + crp->crp_etype = EINVAL;
  13093. + goto err;
  13094. + }
  13095. +
  13096. + /* Perform "in-place" crypto operation */
  13097. + lacStatus = cpaCySymPerformOp(CPA_INSTANCE_HANDLE_SINGLE,
  13098. + (void *)drvOpData,
  13099. + &(drvOpData->lacOpData),
  13100. + &(drvOpData->srcBuffer),
  13101. + &(drvOpData->srcBuffer),
  13102. + &(drvOpData->verifyResult));
  13103. + if (CPA_STATUS_RETRY == lacStatus) {
  13104. + DPRINTK("%s(): cpaCySymPerformOp retry, lacStatus = %d\n",
  13105. + __FUNCTION__, lacStatus);
  13106. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  13107. + crp->crp_etype = ERESTART;
  13108. + goto err;
  13109. + }
  13110. + if (CPA_STATUS_SUCCESS != lacStatus) {
  13111. + EPRINTK("%s(): cpaCySymPerformOp failed, lacStatus = %d\n",
  13112. + __FUNCTION__, lacStatus);
  13113. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  13114. + crp->crp_etype = EINVAL;
  13115. + goto err;
  13116. + }
  13117. +
  13118. + return 0; //OCF success status value
  13119. +
  13120. + err:
  13121. + if (drvOpData->numBufferListArray > ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  13122. + icp_kfree(drvOpData->srcBuffer.pBuffers);
  13123. + }
  13124. + icp_ocfDrvFreeMetaData(&(drvOpData->srcBuffer));
  13125. + ICP_CACHE_FREE(drvOpData_zone, drvOpData);
  13126. +
  13127. + return crp->crp_etype;
  13128. +}
  13129. +
  13130. +/* Name : icp_ocfDrvProcessDataSetup
  13131. + *
  13132. + * Description : This function will setup all the cryptographic operation data
  13133. + * that is required by LAC to execute the operation.
  13134. + */
  13135. +static int icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  13136. + struct cryptodesc *crp_desc)
  13137. +{
  13138. + CpaCyRandGenOpData randGenOpData;
  13139. + CpaFlatBuffer randData;
  13140. +
  13141. + drvOpData->lacOpData.packetType = CPA_CY_SYM_PACKET_TYPE_FULL;
  13142. +
  13143. + /* Convert from the cryptop to the ICP LAC crypto parameters */
  13144. + switch (crp_desc->crd_alg) {
  13145. + case CRYPTO_NULL_CBC:
  13146. + drvOpData->lacOpData.
  13147. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  13148. + drvOpData->lacOpData.
  13149. + messageLenToCipherInBytes = crp_desc->crd_len;
  13150. + drvOpData->verifyResult = CPA_FALSE;
  13151. + drvOpData->lacOpData.ivLenInBytes = NULL_BLOCK_LEN;
  13152. + break;
  13153. + case CRYPTO_DES_CBC:
  13154. + drvOpData->lacOpData.
  13155. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  13156. + drvOpData->lacOpData.
  13157. + messageLenToCipherInBytes = crp_desc->crd_len;
  13158. + drvOpData->verifyResult = CPA_FALSE;
  13159. + drvOpData->lacOpData.ivLenInBytes = DES_BLOCK_LEN;
  13160. + break;
  13161. + case CRYPTO_3DES_CBC:
  13162. + drvOpData->lacOpData.
  13163. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  13164. + drvOpData->lacOpData.
  13165. + messageLenToCipherInBytes = crp_desc->crd_len;
  13166. + drvOpData->verifyResult = CPA_FALSE;
  13167. + drvOpData->lacOpData.ivLenInBytes = DES3_BLOCK_LEN;
  13168. + break;
  13169. + case CRYPTO_ARC4:
  13170. + drvOpData->lacOpData.
  13171. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  13172. + drvOpData->lacOpData.
  13173. + messageLenToCipherInBytes = crp_desc->crd_len;
  13174. + drvOpData->verifyResult = CPA_FALSE;
  13175. + drvOpData->lacOpData.ivLenInBytes = ARC4_COUNTER_LEN;
  13176. + break;
  13177. + case CRYPTO_AES_CBC:
  13178. + drvOpData->lacOpData.
  13179. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  13180. + drvOpData->lacOpData.
  13181. + messageLenToCipherInBytes = crp_desc->crd_len;
  13182. + drvOpData->verifyResult = CPA_FALSE;
  13183. + drvOpData->lacOpData.ivLenInBytes = RIJNDAEL128_BLOCK_LEN;
  13184. + break;
  13185. + case CRYPTO_SHA1:
  13186. + case CRYPTO_SHA1_HMAC:
  13187. + case CRYPTO_SHA2_256:
  13188. + case CRYPTO_SHA2_256_HMAC:
  13189. + case CRYPTO_SHA2_384:
  13190. + case CRYPTO_SHA2_384_HMAC:
  13191. + case CRYPTO_SHA2_512:
  13192. + case CRYPTO_SHA2_512_HMAC:
  13193. + case CRYPTO_MD5:
  13194. + case CRYPTO_MD5_HMAC:
  13195. + drvOpData->lacOpData.
  13196. + hashStartSrcOffsetInBytes = crp_desc->crd_skip;
  13197. + drvOpData->lacOpData.
  13198. + messageLenToHashInBytes = crp_desc->crd_len;
  13199. + drvOpData->lacOpData.
  13200. + pDigestResult =
  13201. + icp_ocfDrvDigestPointerFind(drvOpData, crp_desc);
  13202. +
  13203. + if (NULL == drvOpData->lacOpData.pDigestResult) {
  13204. + DPRINTK("%s(): ERROR - could not calculate "
  13205. + "Digest Result memory address\n", __FUNCTION__);
  13206. + return ICP_OCF_DRV_STATUS_FAIL;
  13207. + }
  13208. +
  13209. + drvOpData->lacOpData.digestVerify = CPA_FALSE;
  13210. + break;
  13211. + default:
  13212. + DPRINTK("%s(): Crypto process error - algorithm not "
  13213. + "found \n", __FUNCTION__);
  13214. + return ICP_OCF_DRV_STATUS_FAIL;
  13215. + }
  13216. +
  13217. + /* Figure out what the IV is supposed to be */
  13218. + if ((crp_desc->crd_alg == CRYPTO_DES_CBC) ||
  13219. + (crp_desc->crd_alg == CRYPTO_3DES_CBC) ||
  13220. + (crp_desc->crd_alg == CRYPTO_AES_CBC)) {
  13221. + /*ARC4 doesn't use an IV */
  13222. + if (crp_desc->crd_flags & CRD_F_IV_EXPLICIT) {
  13223. + /* Explicit IV provided to OCF */
  13224. + drvOpData->lacOpData.pIv = crp_desc->crd_iv;
  13225. + } else {
  13226. + /* IV is not explicitly provided to OCF */
  13227. +
  13228. + /* Point the LAC OP Data IV pointer to our allocated
  13229. + storage location for this session. */
  13230. + drvOpData->lacOpData.pIv = drvOpData->ivData;
  13231. +
  13232. + if ((crp_desc->crd_flags & CRD_F_ENCRYPT) &&
  13233. + ((crp_desc->crd_flags & CRD_F_IV_PRESENT) == 0)) {
  13234. +
  13235. + /* Encrypting - need to create IV */
  13236. + randGenOpData.generateBits = CPA_TRUE;
  13237. + randGenOpData.lenInBytes = MAX_IV_LEN_IN_BYTES;
  13238. +
  13239. + icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *)
  13240. + drvOpData->
  13241. + ivData,
  13242. + MAX_IV_LEN_IN_BYTES,
  13243. + &randData);
  13244. +
  13245. + if (CPA_STATUS_SUCCESS !=
  13246. + cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  13247. + NULL, NULL,
  13248. + &randGenOpData, &randData)) {
  13249. + DPRINTK("%s(): ERROR - Failed to"
  13250. + " generate"
  13251. + " Initialisation Vector\n",
  13252. + __FUNCTION__);
  13253. + return ICP_OCF_DRV_STATUS_FAIL;
  13254. + }
  13255. +
  13256. + crypto_copyback(drvOpData->crp->
  13257. + crp_flags,
  13258. + drvOpData->crp->crp_buf,
  13259. + crp_desc->crd_inject,
  13260. + drvOpData->lacOpData.
  13261. + ivLenInBytes,
  13262. + (caddr_t) (drvOpData->lacOpData.
  13263. + pIv));
  13264. + } else {
  13265. + /* Reading IV from buffer */
  13266. + crypto_copydata(drvOpData->crp->
  13267. + crp_flags,
  13268. + drvOpData->crp->crp_buf,
  13269. + crp_desc->crd_inject,
  13270. + drvOpData->lacOpData.
  13271. + ivLenInBytes,
  13272. + (caddr_t) (drvOpData->lacOpData.
  13273. + pIv));
  13274. + }
  13275. +
  13276. + }
  13277. +
  13278. + }
  13279. +
  13280. + return ICP_OCF_DRV_STATUS_SUCCESS;
  13281. +}
  13282. +
  13283. +/* Name : icp_ocfDrvDigestPointerFind
  13284. + *
  13285. + * Description : This function is used to find the memory address of where the
  13286. + * digest information shall be stored in. Input buffer types are an skbuff, iov
  13287. + * or flat buffer. The address is found using the buffer data start address and
  13288. + * an offset.
  13289. + *
  13290. + * Note: In the case of a linux skbuff, the digest address may exist within
  13291. + * a memory space linked to from the start buffer. These linked memory spaces
  13292. + * must be traversed by the data length offset in order to find the digest start
  13293. + * address. Whether there is enough space for the digest must also be checked.
  13294. + */
  13295. +uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData * drvOpData,
  13296. + struct cryptodesc * crp_desc)
  13297. +{
  13298. +
  13299. + int offsetInBytes = crp_desc->crd_inject;
  13300. + uint32_t digestSizeInBytes = drvOpData->digestSizeInBytes;
  13301. + uint8_t *flat_buffer_base = NULL;
  13302. + int flat_buffer_length = 0;
  13303. +
  13304. + if (drvOpData->crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  13305. +
  13306. + return icp_ocfDrvPacketBufferDigestPointerFind(drvOpData,
  13307. + offsetInBytes,
  13308. + digestSizeInBytes);
  13309. +
  13310. + } else {
  13311. + /* IOV or flat buffer */
  13312. + if (drvOpData->crp->crp_flags & CRYPTO_F_IOV) {
  13313. + /*single IOV check has already been done */
  13314. + flat_buffer_base = ((struct uio *)
  13315. + (drvOpData->crp->crp_buf))->
  13316. + uio_iov[0].iov_base;
  13317. + flat_buffer_length = ((struct uio *)
  13318. + (drvOpData->crp->crp_buf))->
  13319. + uio_iov[0].iov_len;
  13320. + } else {
  13321. + flat_buffer_base = (uint8_t *) drvOpData->crp->crp_buf;
  13322. + flat_buffer_length = drvOpData->crp->crp_ilen;
  13323. + }
  13324. +
  13325. + if (flat_buffer_length < (offsetInBytes + digestSizeInBytes)) {
  13326. + DPRINTK("%s() Not enough space for Digest "
  13327. + "(IOV/Flat Buffer) \n", __FUNCTION__);
  13328. + return NULL;
  13329. + } else {
  13330. + return (uint8_t *) (flat_buffer_base + offsetInBytes);
  13331. + }
  13332. + }
  13333. + DPRINTK("%s() Should not reach this point\n", __FUNCTION__);
  13334. + return NULL;
  13335. +}
  13336. diff -Nur linux-2.6.39.orig/crypto/ocf/ep80579/Makefile linux-2.6.39/crypto/ocf/ep80579/Makefile
  13337. --- linux-2.6.39.orig/crypto/ocf/ep80579/Makefile 1970-01-01 01:00:00.000000000 +0100
  13338. +++ linux-2.6.39/crypto/ocf/ep80579/Makefile 2011-07-31 11:31:54.063418329 +0200
  13339. @@ -0,0 +1,119 @@
  13340. +#########################################################################
  13341. +#
  13342. +# Targets supported
  13343. +# all - builds everything and installs
  13344. +# install - identical to all
  13345. +# depend - build dependencies
  13346. +# clean - clears derived objects except the .depend files
  13347. +# distclean- clears all derived objects and the .depend file
  13348. +#
  13349. +# @par
  13350. +# This file is provided under a dual BSD/GPLv2 license. When using or
  13351. +# redistributing this file, you may do so under either license.
  13352. +#
  13353. +# GPL LICENSE SUMMARY
  13354. +#
  13355. +# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  13356. +#
  13357. +# This program is free software; you can redistribute it and/or modify
  13358. +# it under the terms of version 2 of the GNU General Public License as
  13359. +# published by the Free Software Foundation.
  13360. +#
  13361. +# This program is distributed in the hope that it will be useful, but
  13362. +# WITHOUT ANY WARRANTY; without even the implied warranty of
  13363. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13364. +# General Public License for more details.
  13365. +#
  13366. +# You should have received a copy of the GNU General Public License
  13367. +# along with this program; if not, write to the Free Software
  13368. +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  13369. +# The full GNU General Public License is included in this distribution
  13370. +# in the file called LICENSE.GPL.
  13371. +#
  13372. +# Contact Information:
  13373. +# Intel Corporation
  13374. +#
  13375. +# BSD LICENSE
  13376. +#
  13377. +# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  13378. +# All rights reserved.
  13379. +#
  13380. +# Redistribution and use in source and binary forms, with or without
  13381. +# modification, are permitted provided that the following conditions
  13382. +# are met:
  13383. +#
  13384. +# * Redistributions of source code must retain the above copyright
  13385. +# notice, this list of conditions and the following disclaimer.
  13386. +# * Redistributions in binary form must reproduce the above copyright
  13387. +# notice, this list of conditions and the following disclaimer in
  13388. +# the documentation and/or other materials provided with the
  13389. +# distribution.
  13390. +# * Neither the name of Intel Corporation nor the names of its
  13391. +# contributors may be used to endorse or promote products derived
  13392. +# from this software without specific prior written permission.
  13393. +#
  13394. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13395. +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13396. +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  13397. +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  13398. +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  13399. +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  13400. +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  13401. +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13402. +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  13403. +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13404. +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  13405. +#
  13406. +#
  13407. +# version: Security.L.1.0.2-229
  13408. +############################################################################
  13409. +
  13410. +
  13411. +####################Common variables and definitions########################
  13412. +
  13413. +ifndef ICP_ROOT
  13414. +$(warning ICP_ROOT is undefined. Please set the path to EP80579 release package directory \
  13415. + "-> setenv ICP_ROOT <path>")
  13416. +all fastdep:
  13417. + :
  13418. +else
  13419. +
  13420. +ifndef KERNEL_SOURCE_ROOT
  13421. +$(error KERNEL_SOURCE_ROOT is undefined. Please set the path to the kernel source directory \
  13422. + "-> setenv KERNEL_SOURCE_ROOT <path>")
  13423. +endif
  13424. +
  13425. +# Ensure The ENV_DIR environmental var is defined.
  13426. +ifndef ICP_ENV_DIR
  13427. +$(error ICP_ENV_DIR is undefined. Please set the path to EP80579 driver environment.mk file \
  13428. + "-> setenv ICP_ENV_DIR <path>")
  13429. +endif
  13430. +
  13431. +#Add your project environment Makefile
  13432. +include ${ICP_ENV_DIR}/environment.mk
  13433. +
  13434. +#include the makefile with all the default and common Make variable definitions
  13435. +include ${ICP_BUILDSYSTEM_PATH}/build_files/common.mk
  13436. +
  13437. +#Add the name for the executable, Library or Module output definitions
  13438. +OUTPUT_NAME= icp_ocf
  13439. +
  13440. +# List of Source Files to be compiled
  13441. +SOURCES= icp_common.c icp_sym.c icp_asym.c icp_ocf_linux.c
  13442. +
  13443. +#common includes between all supported OSes
  13444. +INCLUDES= -I ${ICP_API_DIR} -I${ICP_LAC_API} \
  13445. +-I${ICP_OCF_SRC_DIR}
  13446. +
  13447. +# The location of the os level makefile needs to be changed.
  13448. +include ${ICP_ENV_DIR}/${ICP_OS}_${ICP_OS_LEVEL}.mk
  13449. +
  13450. +# On the line directly below list the outputs you wish to build for,
  13451. +# e.g "lib_static lib_shared exe module" as shown below
  13452. +install: module
  13453. +
  13454. +###################Include rules makefiles########################
  13455. +include ${ICP_BUILDSYSTEM_PATH}/build_files/rules.mk
  13456. +###################End of Rules inclusion#########################
  13457. +
  13458. +endif
  13459. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/hifn7751.c linux-2.6.39/crypto/ocf/hifn/hifn7751.c
  13460. --- linux-2.6.39.orig/crypto/ocf/hifn/hifn7751.c 1970-01-01 01:00:00.000000000 +0100
  13461. +++ linux-2.6.39/crypto/ocf/hifn/hifn7751.c 2011-07-31 11:31:54.083652242 +0200
  13462. @@ -0,0 +1,2976 @@
  13463. +/* $OpenBSD: hifn7751.c,v 1.120 2002/05/17 00:33:34 deraadt Exp $ */
  13464. +
  13465. +/*-
  13466. + * Invertex AEON / Hifn 7751 driver
  13467. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  13468. + * Copyright (c) 1999 Theo de Raadt
  13469. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  13470. + * http://www.netsec.net
  13471. + * Copyright (c) 2003 Hifn Inc.
  13472. + *
  13473. + * This driver is based on a previous driver by Invertex, for which they
  13474. + * requested: Please send any comments, feedback, bug-fixes, or feature
  13475. + * requests to software@invertex.com.
  13476. + *
  13477. + * Redistribution and use in source and binary forms, with or without
  13478. + * modification, are permitted provided that the following conditions
  13479. + * are met:
  13480. + *
  13481. + * 1. Redistributions of source code must retain the above copyright
  13482. + * notice, this list of conditions and the following disclaimer.
  13483. + * 2. Redistributions in binary form must reproduce the above copyright
  13484. + * notice, this list of conditions and the following disclaimer in the
  13485. + * documentation and/or other materials provided with the distribution.
  13486. + * 3. The name of the author may not be used to endorse or promote products
  13487. + * derived from this software without specific prior written permission.
  13488. + *
  13489. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  13490. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  13491. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  13492. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  13493. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  13494. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  13495. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13496. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  13497. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  13498. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  13499. + *
  13500. + * Effort sponsored in part by the Defense Advanced Research Projects
  13501. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  13502. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  13503. + *
  13504. + *
  13505. +__FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam Exp $");
  13506. + */
  13507. +
  13508. +/*
  13509. + * Driver for various Hifn encryption processors.
  13510. + */
  13511. +#ifndef AUTOCONF_INCLUDED
  13512. +#include <linux/config.h>
  13513. +#endif
  13514. +#include <linux/module.h>
  13515. +#include <linux/init.h>
  13516. +#include <linux/list.h>
  13517. +#include <linux/slab.h>
  13518. +#include <linux/wait.h>
  13519. +#include <linux/sched.h>
  13520. +#include <linux/pci.h>
  13521. +#include <linux/delay.h>
  13522. +#include <linux/interrupt.h>
  13523. +#include <linux/spinlock.h>
  13524. +#include <linux/random.h>
  13525. +#include <linux/version.h>
  13526. +#include <linux/skbuff.h>
  13527. +#include <asm/io.h>
  13528. +
  13529. +#include <cryptodev.h>
  13530. +#include <uio.h>
  13531. +#include <hifn/hifn7751reg.h>
  13532. +#include <hifn/hifn7751var.h>
  13533. +
  13534. +#if 1
  13535. +#define DPRINTF(a...) if (hifn_debug) { \
  13536. + printk("%s: ", sc ? \
  13537. + device_get_nameunit(sc->sc_dev) : "hifn"); \
  13538. + printk(a); \
  13539. + } else
  13540. +#else
  13541. +#define DPRINTF(a...)
  13542. +#endif
  13543. +
  13544. +static inline int
  13545. +pci_get_revid(struct pci_dev *dev)
  13546. +{
  13547. + u8 rid = 0;
  13548. + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
  13549. + return rid;
  13550. +}
  13551. +
  13552. +static struct hifn_stats hifnstats;
  13553. +
  13554. +#define debug hifn_debug
  13555. +int hifn_debug = 0;
  13556. +module_param(hifn_debug, int, 0644);
  13557. +MODULE_PARM_DESC(hifn_debug, "Enable debug");
  13558. +
  13559. +int hifn_maxbatch = 1;
  13560. +module_param(hifn_maxbatch, int, 0644);
  13561. +MODULE_PARM_DESC(hifn_maxbatch, "max ops to batch w/o interrupt");
  13562. +
  13563. +int hifn_cache_linesize = 0x10;
  13564. +module_param(hifn_cache_linesize, int, 0444);
  13565. +MODULE_PARM_DESC(hifn_cache_linesize, "PCI config cache line size");
  13566. +
  13567. +#ifdef MODULE_PARM
  13568. +char *hifn_pllconfig = NULL;
  13569. +MODULE_PARM(hifn_pllconfig, "s");
  13570. +#else
  13571. +char hifn_pllconfig[32]; /* This setting is RO after loading */
  13572. +module_param_string(hifn_pllconfig, hifn_pllconfig, 32, 0444);
  13573. +#endif
  13574. +MODULE_PARM_DESC(hifn_pllconfig, "PLL config, ie., pci66, ext33, ...");
  13575. +
  13576. +#ifdef HIFN_VULCANDEV
  13577. +#include <sys/conf.h>
  13578. +#include <sys/uio.h>
  13579. +
  13580. +static struct cdevsw vulcanpk_cdevsw; /* forward declaration */
  13581. +#endif
  13582. +
  13583. +/*
  13584. + * Prototypes and count for the pci_device structure
  13585. + */
  13586. +static int hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent);
  13587. +static void hifn_remove(struct pci_dev *dev);
  13588. +
  13589. +static int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);
  13590. +static int hifn_freesession(device_t, u_int64_t);
  13591. +static int hifn_process(device_t, struct cryptop *, int);
  13592. +
  13593. +static device_method_t hifn_methods = {
  13594. + /* crypto device methods */
  13595. + DEVMETHOD(cryptodev_newsession, hifn_newsession),
  13596. + DEVMETHOD(cryptodev_freesession,hifn_freesession),
  13597. + DEVMETHOD(cryptodev_process, hifn_process),
  13598. +};
  13599. +
  13600. +static void hifn_reset_board(struct hifn_softc *, int);
  13601. +static void hifn_reset_puc(struct hifn_softc *);
  13602. +static void hifn_puc_wait(struct hifn_softc *);
  13603. +static int hifn_enable_crypto(struct hifn_softc *);
  13604. +static void hifn_set_retry(struct hifn_softc *sc);
  13605. +static void hifn_init_dma(struct hifn_softc *);
  13606. +static void hifn_init_pci_registers(struct hifn_softc *);
  13607. +static int hifn_sramsize(struct hifn_softc *);
  13608. +static int hifn_dramsize(struct hifn_softc *);
  13609. +static int hifn_ramtype(struct hifn_softc *);
  13610. +static void hifn_sessions(struct hifn_softc *);
  13611. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  13612. +static irqreturn_t hifn_intr(int irq, void *arg);
  13613. +#else
  13614. +static irqreturn_t hifn_intr(int irq, void *arg, struct pt_regs *regs);
  13615. +#endif
  13616. +static u_int hifn_write_command(struct hifn_command *, u_int8_t *);
  13617. +static u_int32_t hifn_next_signature(u_int32_t a, u_int cnt);
  13618. +static void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *);
  13619. +static int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int);
  13620. +static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);
  13621. +static int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *);
  13622. +static int hifn_dmamap_load_src(struct hifn_softc *, struct hifn_command *);
  13623. +static int hifn_dmamap_load_dst(struct hifn_softc *, struct hifn_command *);
  13624. +static int hifn_init_pubrng(struct hifn_softc *);
  13625. +static void hifn_tick(unsigned long arg);
  13626. +static void hifn_abort(struct hifn_softc *);
  13627. +static void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *);
  13628. +
  13629. +static void hifn_write_reg_0(struct hifn_softc *, bus_size_t, u_int32_t);
  13630. +static void hifn_write_reg_1(struct hifn_softc *, bus_size_t, u_int32_t);
  13631. +
  13632. +#ifdef CONFIG_OCF_RANDOMHARVEST
  13633. +static int hifn_read_random(void *arg, u_int32_t *buf, int len);
  13634. +#endif
  13635. +
  13636. +#define HIFN_MAX_CHIPS 8
  13637. +static struct hifn_softc *hifn_chip_idx[HIFN_MAX_CHIPS];
  13638. +
  13639. +static __inline u_int32_t
  13640. +READ_REG_0(struct hifn_softc *sc, bus_size_t reg)
  13641. +{
  13642. + u_int32_t v = readl(sc->sc_bar0 + reg);
  13643. + sc->sc_bar0_lastreg = (bus_size_t) -1;
  13644. + return (v);
  13645. +}
  13646. +#define WRITE_REG_0(sc, reg, val) hifn_write_reg_0(sc, reg, val)
  13647. +
  13648. +static __inline u_int32_t
  13649. +READ_REG_1(struct hifn_softc *sc, bus_size_t reg)
  13650. +{
  13651. + u_int32_t v = readl(sc->sc_bar1 + reg);
  13652. + sc->sc_bar1_lastreg = (bus_size_t) -1;
  13653. + return (v);
  13654. +}
  13655. +#define WRITE_REG_1(sc, reg, val) hifn_write_reg_1(sc, reg, val)
  13656. +
  13657. +/*
  13658. + * map in a given buffer (great on some arches :-)
  13659. + */
  13660. +
  13661. +static int
  13662. +pci_map_uio(struct hifn_softc *sc, struct hifn_operand *buf, struct uio *uio)
  13663. +{
  13664. + struct iovec *iov = uio->uio_iov;
  13665. +
  13666. + DPRINTF("%s()\n", __FUNCTION__);
  13667. +
  13668. + buf->mapsize = 0;
  13669. + for (buf->nsegs = 0; buf->nsegs < uio->uio_iovcnt; ) {
  13670. + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
  13671. + iov->iov_base, iov->iov_len,
  13672. + PCI_DMA_BIDIRECTIONAL);
  13673. + buf->segs[buf->nsegs].ds_len = iov->iov_len;
  13674. + buf->mapsize += iov->iov_len;
  13675. + iov++;
  13676. + buf->nsegs++;
  13677. + }
  13678. + /* identify this buffer by the first segment */
  13679. + buf->map = (void *) buf->segs[0].ds_addr;
  13680. + return(0);
  13681. +}
  13682. +
  13683. +/*
  13684. + * map in a given sk_buff
  13685. + */
  13686. +
  13687. +static int
  13688. +pci_map_skb(struct hifn_softc *sc,struct hifn_operand *buf,struct sk_buff *skb)
  13689. +{
  13690. + int i;
  13691. +
  13692. + DPRINTF("%s()\n", __FUNCTION__);
  13693. +
  13694. + buf->mapsize = 0;
  13695. +
  13696. + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
  13697. + skb->data, skb_headlen(skb), PCI_DMA_BIDIRECTIONAL);
  13698. + buf->segs[0].ds_len = skb_headlen(skb);
  13699. + buf->mapsize += buf->segs[0].ds_len;
  13700. +
  13701. + buf->nsegs = 1;
  13702. +
  13703. + for (i = 0; i < skb_shinfo(skb)->nr_frags; ) {
  13704. + buf->segs[buf->nsegs].ds_len = skb_shinfo(skb)->frags[i].size;
  13705. + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
  13706. + page_address(skb_shinfo(skb)->frags[i].page) +
  13707. + skb_shinfo(skb)->frags[i].page_offset,
  13708. + buf->segs[buf->nsegs].ds_len, PCI_DMA_BIDIRECTIONAL);
  13709. + buf->mapsize += buf->segs[buf->nsegs].ds_len;
  13710. + buf->nsegs++;
  13711. + }
  13712. +
  13713. + /* identify this buffer by the first segment */
  13714. + buf->map = (void *) buf->segs[0].ds_addr;
  13715. + return(0);
  13716. +}
  13717. +
  13718. +/*
  13719. + * map in a given contiguous buffer
  13720. + */
  13721. +
  13722. +static int
  13723. +pci_map_buf(struct hifn_softc *sc,struct hifn_operand *buf, void *b, int len)
  13724. +{
  13725. + DPRINTF("%s()\n", __FUNCTION__);
  13726. +
  13727. + buf->mapsize = 0;
  13728. + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
  13729. + b, len, PCI_DMA_BIDIRECTIONAL);
  13730. + buf->segs[0].ds_len = len;
  13731. + buf->mapsize += buf->segs[0].ds_len;
  13732. + buf->nsegs = 1;
  13733. +
  13734. + /* identify this buffer by the first segment */
  13735. + buf->map = (void *) buf->segs[0].ds_addr;
  13736. + return(0);
  13737. +}
  13738. +
  13739. +#if 0 /* not needed at this time */
  13740. +static void
  13741. +pci_sync_iov(struct hifn_softc *sc, struct hifn_operand *buf)
  13742. +{
  13743. + int i;
  13744. +
  13745. + DPRINTF("%s()\n", __FUNCTION__);
  13746. + for (i = 0; i < buf->nsegs; i++)
  13747. + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
  13748. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  13749. +}
  13750. +#endif
  13751. +
  13752. +static void
  13753. +pci_unmap_buf(struct hifn_softc *sc, struct hifn_operand *buf)
  13754. +{
  13755. + int i;
  13756. + DPRINTF("%s()\n", __FUNCTION__);
  13757. + for (i = 0; i < buf->nsegs; i++) {
  13758. + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
  13759. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  13760. + buf->segs[i].ds_addr = 0;
  13761. + buf->segs[i].ds_len = 0;
  13762. + }
  13763. + buf->nsegs = 0;
  13764. + buf->mapsize = 0;
  13765. + buf->map = 0;
  13766. +}
  13767. +
  13768. +static const char*
  13769. +hifn_partname(struct hifn_softc *sc)
  13770. +{
  13771. + /* XXX sprintf numbers when not decoded */
  13772. + switch (pci_get_vendor(sc->sc_pcidev)) {
  13773. + case PCI_VENDOR_HIFN:
  13774. + switch (pci_get_device(sc->sc_pcidev)) {
  13775. + case PCI_PRODUCT_HIFN_6500: return "Hifn 6500";
  13776. + case PCI_PRODUCT_HIFN_7751: return "Hifn 7751";
  13777. + case PCI_PRODUCT_HIFN_7811: return "Hifn 7811";
  13778. + case PCI_PRODUCT_HIFN_7951: return "Hifn 7951";
  13779. + case PCI_PRODUCT_HIFN_7955: return "Hifn 7955";
  13780. + case PCI_PRODUCT_HIFN_7956: return "Hifn 7956";
  13781. + }
  13782. + return "Hifn unknown-part";
  13783. + case PCI_VENDOR_INVERTEX:
  13784. + switch (pci_get_device(sc->sc_pcidev)) {
  13785. + case PCI_PRODUCT_INVERTEX_AEON: return "Invertex AEON";
  13786. + }
  13787. + return "Invertex unknown-part";
  13788. + case PCI_VENDOR_NETSEC:
  13789. + switch (pci_get_device(sc->sc_pcidev)) {
  13790. + case PCI_PRODUCT_NETSEC_7751: return "NetSec 7751";
  13791. + }
  13792. + return "NetSec unknown-part";
  13793. + }
  13794. + return "Unknown-vendor unknown-part";
  13795. +}
  13796. +
  13797. +static u_int
  13798. +checkmaxmin(struct pci_dev *dev, const char *what, u_int v, u_int min, u_int max)
  13799. +{
  13800. + struct hifn_softc *sc = pci_get_drvdata(dev);
  13801. + if (v > max) {
  13802. + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
  13803. + "using max %u\n", what, v, max);
  13804. + v = max;
  13805. + } else if (v < min) {
  13806. + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
  13807. + "using min %u\n", what, v, min);
  13808. + v = min;
  13809. + }
  13810. + return v;
  13811. +}
  13812. +
  13813. +/*
  13814. + * Select PLL configuration for 795x parts. This is complicated in
  13815. + * that we cannot determine the optimal parameters without user input.
  13816. + * The reference clock is derived from an external clock through a
  13817. + * multiplier. The external clock is either the host bus (i.e. PCI)
  13818. + * or an external clock generator. When using the PCI bus we assume
  13819. + * the clock is either 33 or 66 MHz; for an external source we cannot
  13820. + * tell the speed.
  13821. + *
  13822. + * PLL configuration is done with a string: "pci" for PCI bus, or "ext"
  13823. + * for an external source, followed by the frequency. We calculate
  13824. + * the appropriate multiplier and PLL register contents accordingly.
  13825. + * When no configuration is given we default to "pci66" since that
  13826. + * always will allow the card to work. If a card is using the PCI
  13827. + * bus clock and in a 33MHz slot then it will be operating at half
  13828. + * speed until the correct information is provided.
  13829. + *
  13830. + * We use a default setting of "ext66" because according to Mike Ham
  13831. + * of HiFn, almost every board in existence has an external crystal
  13832. + * populated at 66Mhz. Using PCI can be a problem on modern motherboards,
  13833. + * because PCI33 can have clocks from 0 to 33Mhz, and some have
  13834. + * non-PCI-compliant spread-spectrum clocks, which can confuse the pll.
  13835. + */
  13836. +static void
  13837. +hifn_getpllconfig(struct pci_dev *dev, u_int *pll)
  13838. +{
  13839. + const char *pllspec = hifn_pllconfig;
  13840. + u_int freq, mul, fl, fh;
  13841. + u_int32_t pllconfig;
  13842. + char *nxt;
  13843. +
  13844. + if (pllspec == NULL)
  13845. + pllspec = "ext66";
  13846. + fl = 33, fh = 66;
  13847. + pllconfig = 0;
  13848. + if (strncmp(pllspec, "ext", 3) == 0) {
  13849. + pllspec += 3;
  13850. + pllconfig |= HIFN_PLL_REF_SEL;
  13851. + switch (pci_get_device(dev)) {
  13852. + case PCI_PRODUCT_HIFN_7955:
  13853. + case PCI_PRODUCT_HIFN_7956:
  13854. + fl = 20, fh = 100;
  13855. + break;
  13856. +#ifdef notyet
  13857. + case PCI_PRODUCT_HIFN_7954:
  13858. + fl = 20, fh = 66;
  13859. + break;
  13860. +#endif
  13861. + }
  13862. + } else if (strncmp(pllspec, "pci", 3) == 0)
  13863. + pllspec += 3;
  13864. + freq = strtoul(pllspec, &nxt, 10);
  13865. + if (nxt == pllspec)
  13866. + freq = 66;
  13867. + else
  13868. + freq = checkmaxmin(dev, "frequency", freq, fl, fh);
  13869. + /*
  13870. + * Calculate multiplier. We target a Fck of 266 MHz,
  13871. + * allowing only even values, possibly rounded down.
  13872. + * Multipliers > 8 must set the charge pump current.
  13873. + */
  13874. + mul = checkmaxmin(dev, "PLL divisor", (266 / freq) &~ 1, 2, 12);
  13875. + pllconfig |= (mul / 2 - 1) << HIFN_PLL_ND_SHIFT;
  13876. + if (mul > 8)
  13877. + pllconfig |= HIFN_PLL_IS;
  13878. + *pll = pllconfig;
  13879. +}
  13880. +
  13881. +/*
  13882. + * Attach an interface that successfully probed.
  13883. + */
  13884. +static int
  13885. +hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  13886. +{
  13887. + struct hifn_softc *sc = NULL;
  13888. + char rbase;
  13889. + u_int16_t ena, rev;
  13890. + int rseg, rc;
  13891. + unsigned long mem_start, mem_len;
  13892. + static int num_chips = 0;
  13893. +
  13894. + DPRINTF("%s()\n", __FUNCTION__);
  13895. +
  13896. + if (pci_enable_device(dev) < 0)
  13897. + return(-ENODEV);
  13898. +
  13899. + if (pci_set_mwi(dev))
  13900. + return(-ENODEV);
  13901. +
  13902. + if (!dev->irq) {
  13903. + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
  13904. + pci_disable_device(dev);
  13905. + return(-ENODEV);
  13906. + }
  13907. +
  13908. + sc = (struct hifn_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  13909. + if (!sc)
  13910. + return(-ENOMEM);
  13911. + memset(sc, 0, sizeof(*sc));
  13912. +
  13913. + softc_device_init(sc, "hifn", num_chips, hifn_methods);
  13914. +
  13915. + sc->sc_pcidev = dev;
  13916. + sc->sc_irq = -1;
  13917. + sc->sc_cid = -1;
  13918. + sc->sc_num = num_chips++;
  13919. + if (sc->sc_num < HIFN_MAX_CHIPS)
  13920. + hifn_chip_idx[sc->sc_num] = sc;
  13921. +
  13922. + pci_set_drvdata(sc->sc_pcidev, sc);
  13923. +
  13924. + spin_lock_init(&sc->sc_mtx);
  13925. +
  13926. + /* XXX handle power management */
  13927. +
  13928. + /*
  13929. + * The 7951 and 795x have a random number generator and
  13930. + * public key support; note this.
  13931. + */
  13932. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  13933. + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7951 ||
  13934. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
  13935. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956))
  13936. + sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC;
  13937. + /*
  13938. + * The 7811 has a random number generator and
  13939. + * we also note it's identity 'cuz of some quirks.
  13940. + */
  13941. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  13942. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7811)
  13943. + sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG;
  13944. +
  13945. + /*
  13946. + * The 795x parts support AES.
  13947. + */
  13948. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  13949. + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
  13950. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956)) {
  13951. + sc->sc_flags |= HIFN_IS_7956 | HIFN_HAS_AES;
  13952. + /*
  13953. + * Select PLL configuration. This depends on the
  13954. + * bus and board design and must be manually configured
  13955. + * if the default setting is unacceptable.
  13956. + */
  13957. + hifn_getpllconfig(dev, &sc->sc_pllconfig);
  13958. + }
  13959. +
  13960. + /*
  13961. + * Setup PCI resources. Note that we record the bus
  13962. + * tag and handle for each register mapping, this is
  13963. + * used by the READ_REG_0, WRITE_REG_0, READ_REG_1,
  13964. + * and WRITE_REG_1 macros throughout the driver.
  13965. + */
  13966. + mem_start = pci_resource_start(sc->sc_pcidev, 0);
  13967. + mem_len = pci_resource_len(sc->sc_pcidev, 0);
  13968. + sc->sc_bar0 = (ocf_iomem_t) ioremap(mem_start, mem_len);
  13969. + if (!sc->sc_bar0) {
  13970. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 0);
  13971. + goto fail;
  13972. + }
  13973. + sc->sc_bar0_lastreg = (bus_size_t) -1;
  13974. +
  13975. + mem_start = pci_resource_start(sc->sc_pcidev, 1);
  13976. + mem_len = pci_resource_len(sc->sc_pcidev, 1);
  13977. + sc->sc_bar1 = (ocf_iomem_t) ioremap(mem_start, mem_len);
  13978. + if (!sc->sc_bar1) {
  13979. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 1);
  13980. + goto fail;
  13981. + }
  13982. + sc->sc_bar1_lastreg = (bus_size_t) -1;
  13983. +
  13984. + /* fix up the bus size */
  13985. + if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
  13986. + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
  13987. + goto fail;
  13988. + }
  13989. + if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
  13990. + device_printf(sc->sc_dev,
  13991. + "No usable consistent DMA configuration, aborting.\n");
  13992. + goto fail;
  13993. + }
  13994. +
  13995. + hifn_set_retry(sc);
  13996. +
  13997. + /*
  13998. + * Setup the area where the Hifn DMA's descriptors
  13999. + * and associated data structures.
  14000. + */
  14001. + sc->sc_dma = (struct hifn_dma *) pci_alloc_consistent(dev,
  14002. + sizeof(*sc->sc_dma),
  14003. + &sc->sc_dma_physaddr);
  14004. + if (!sc->sc_dma) {
  14005. + device_printf(sc->sc_dev, "cannot alloc sc_dma\n");
  14006. + goto fail;
  14007. + }
  14008. + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
  14009. +
  14010. + /*
  14011. + * Reset the board and do the ``secret handshake''
  14012. + * to enable the crypto support. Then complete the
  14013. + * initialization procedure by setting up the interrupt
  14014. + * and hooking in to the system crypto support so we'll
  14015. + * get used for system services like the crypto device,
  14016. + * IPsec, RNG device, etc.
  14017. + */
  14018. + hifn_reset_board(sc, 0);
  14019. +
  14020. + if (hifn_enable_crypto(sc) != 0) {
  14021. + device_printf(sc->sc_dev, "crypto enabling failed\n");
  14022. + goto fail;
  14023. + }
  14024. + hifn_reset_puc(sc);
  14025. +
  14026. + hifn_init_dma(sc);
  14027. + hifn_init_pci_registers(sc);
  14028. +
  14029. + pci_set_master(sc->sc_pcidev);
  14030. +
  14031. + /* XXX can't dynamically determine ram type for 795x; force dram */
  14032. + if (sc->sc_flags & HIFN_IS_7956)
  14033. + sc->sc_drammodel = 1;
  14034. + else if (hifn_ramtype(sc))
  14035. + goto fail;
  14036. +
  14037. + if (sc->sc_drammodel == 0)
  14038. + hifn_sramsize(sc);
  14039. + else
  14040. + hifn_dramsize(sc);
  14041. +
  14042. + /*
  14043. + * Workaround for NetSec 7751 rev A: half ram size because two
  14044. + * of the address lines were left floating
  14045. + */
  14046. + if (pci_get_vendor(dev) == PCI_VENDOR_NETSEC &&
  14047. + pci_get_device(dev) == PCI_PRODUCT_NETSEC_7751 &&
  14048. + pci_get_revid(dev) == 0x61) /*XXX???*/
  14049. + sc->sc_ramsize >>= 1;
  14050. +
  14051. + /*
  14052. + * Arrange the interrupt line.
  14053. + */
  14054. + rc = request_irq(dev->irq, hifn_intr, IRQF_SHARED, "hifn", sc);
  14055. + if (rc) {
  14056. + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
  14057. + goto fail;
  14058. + }
  14059. + sc->sc_irq = dev->irq;
  14060. +
  14061. + hifn_sessions(sc);
  14062. +
  14063. + /*
  14064. + * NB: Keep only the low 16 bits; this masks the chip id
  14065. + * from the 7951.
  14066. + */
  14067. + rev = READ_REG_1(sc, HIFN_1_REVID) & 0xffff;
  14068. +
  14069. + rseg = sc->sc_ramsize / 1024;
  14070. + rbase = 'K';
  14071. + if (sc->sc_ramsize >= (1024 * 1024)) {
  14072. + rbase = 'M';
  14073. + rseg /= 1024;
  14074. + }
  14075. + device_printf(sc->sc_dev, "%s, rev %u, %d%cB %cram",
  14076. + hifn_partname(sc), rev,
  14077. + rseg, rbase, sc->sc_drammodel ? 'd' : 's');
  14078. + if (sc->sc_flags & HIFN_IS_7956)
  14079. + printf(", pll=0x%x<%s clk, %ux mult>",
  14080. + sc->sc_pllconfig,
  14081. + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
  14082. + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
  14083. + printf("\n");
  14084. +
  14085. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  14086. + if (sc->sc_cid < 0) {
  14087. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  14088. + goto fail;
  14089. + }
  14090. +
  14091. + WRITE_REG_0(sc, HIFN_0_PUCNFG,
  14092. + READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID);
  14093. + ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  14094. +
  14095. + switch (ena) {
  14096. + case HIFN_PUSTAT_ENA_2:
  14097. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  14098. + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
  14099. + if (sc->sc_flags & HIFN_HAS_AES)
  14100. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  14101. + /*FALLTHROUGH*/
  14102. + case HIFN_PUSTAT_ENA_1:
  14103. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  14104. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  14105. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  14106. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  14107. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  14108. + break;
  14109. + }
  14110. +
  14111. + if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG))
  14112. + hifn_init_pubrng(sc);
  14113. +
  14114. + init_timer(&sc->sc_tickto);
  14115. + sc->sc_tickto.function = hifn_tick;
  14116. + sc->sc_tickto.data = (unsigned long) sc->sc_num;
  14117. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  14118. +
  14119. + return (0);
  14120. +
  14121. +fail:
  14122. + if (sc->sc_cid >= 0)
  14123. + crypto_unregister_all(sc->sc_cid);
  14124. + if (sc->sc_irq != -1)
  14125. + free_irq(sc->sc_irq, sc);
  14126. + if (sc->sc_dma) {
  14127. + /* Turn off DMA polling */
  14128. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  14129. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  14130. +
  14131. + pci_free_consistent(sc->sc_pcidev,
  14132. + sizeof(*sc->sc_dma),
  14133. + sc->sc_dma, sc->sc_dma_physaddr);
  14134. + }
  14135. + kfree(sc);
  14136. + return (-ENXIO);
  14137. +}
  14138. +
  14139. +/*
  14140. + * Detach an interface that successfully probed.
  14141. + */
  14142. +static void
  14143. +hifn_remove(struct pci_dev *dev)
  14144. +{
  14145. + struct hifn_softc *sc = pci_get_drvdata(dev);
  14146. + unsigned long l_flags;
  14147. +
  14148. + DPRINTF("%s()\n", __FUNCTION__);
  14149. +
  14150. + KASSERT(sc != NULL, ("hifn_detach: null software carrier!"));
  14151. +
  14152. + /* disable interrupts */
  14153. + HIFN_LOCK(sc);
  14154. + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
  14155. + HIFN_UNLOCK(sc);
  14156. +
  14157. + /*XXX other resources */
  14158. + del_timer_sync(&sc->sc_tickto);
  14159. +
  14160. + /* Turn off DMA polling */
  14161. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  14162. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  14163. +
  14164. + crypto_unregister_all(sc->sc_cid);
  14165. +
  14166. + free_irq(sc->sc_irq, sc);
  14167. +
  14168. + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
  14169. + sc->sc_dma, sc->sc_dma_physaddr);
  14170. +}
  14171. +
  14172. +
  14173. +static int
  14174. +hifn_init_pubrng(struct hifn_softc *sc)
  14175. +{
  14176. + int i;
  14177. +
  14178. + DPRINTF("%s()\n", __FUNCTION__);
  14179. +
  14180. + if ((sc->sc_flags & HIFN_IS_7811) == 0) {
  14181. + /* Reset 7951 public key/rng engine */
  14182. + WRITE_REG_1(sc, HIFN_1_PUB_RESET,
  14183. + READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET);
  14184. +
  14185. + for (i = 0; i < 100; i++) {
  14186. + DELAY(1000);
  14187. + if ((READ_REG_1(sc, HIFN_1_PUB_RESET) &
  14188. + HIFN_PUBRST_RESET) == 0)
  14189. + break;
  14190. + }
  14191. +
  14192. + if (i == 100) {
  14193. + device_printf(sc->sc_dev, "public key init failed\n");
  14194. + return (1);
  14195. + }
  14196. + }
  14197. +
  14198. + /* Enable the rng, if available */
  14199. +#ifdef CONFIG_OCF_RANDOMHARVEST
  14200. + if (sc->sc_flags & HIFN_HAS_RNG) {
  14201. + if (sc->sc_flags & HIFN_IS_7811) {
  14202. + u_int32_t r;
  14203. + r = READ_REG_1(sc, HIFN_1_7811_RNGENA);
  14204. + if (r & HIFN_7811_RNGENA_ENA) {
  14205. + r &= ~HIFN_7811_RNGENA_ENA;
  14206. + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
  14207. + }
  14208. + WRITE_REG_1(sc, HIFN_1_7811_RNGCFG,
  14209. + HIFN_7811_RNGCFG_DEFL);
  14210. + r |= HIFN_7811_RNGENA_ENA;
  14211. + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
  14212. + } else
  14213. + WRITE_REG_1(sc, HIFN_1_RNG_CONFIG,
  14214. + READ_REG_1(sc, HIFN_1_RNG_CONFIG) |
  14215. + HIFN_RNGCFG_ENA);
  14216. +
  14217. + sc->sc_rngfirst = 1;
  14218. + crypto_rregister(sc->sc_cid, hifn_read_random, sc);
  14219. + }
  14220. +#endif
  14221. +
  14222. + /* Enable public key engine, if available */
  14223. + if (sc->sc_flags & HIFN_HAS_PUBLIC) {
  14224. + WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE);
  14225. + sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;
  14226. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  14227. +#ifdef HIFN_VULCANDEV
  14228. + sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0,
  14229. + UID_ROOT, GID_WHEEL, 0666,
  14230. + "vulcanpk");
  14231. + sc->sc_pkdev->si_drv1 = sc;
  14232. +#endif
  14233. + }
  14234. +
  14235. + return (0);
  14236. +}
  14237. +
  14238. +#ifdef CONFIG_OCF_RANDOMHARVEST
  14239. +static int
  14240. +hifn_read_random(void *arg, u_int32_t *buf, int len)
  14241. +{
  14242. + struct hifn_softc *sc = (struct hifn_softc *) arg;
  14243. + u_int32_t sts;
  14244. + int i, rc = 0;
  14245. +
  14246. + if (len <= 0)
  14247. + return rc;
  14248. +
  14249. + if (sc->sc_flags & HIFN_IS_7811) {
  14250. + /* ONLY VALID ON 7811!!!! */
  14251. + for (i = 0; i < 5; i++) {
  14252. + sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS);
  14253. + if (sts & HIFN_7811_RNGSTS_UFL) {
  14254. + device_printf(sc->sc_dev,
  14255. + "RNG underflow: disabling\n");
  14256. + /* DAVIDM perhaps return -1 */
  14257. + break;
  14258. + }
  14259. + if ((sts & HIFN_7811_RNGSTS_RDY) == 0)
  14260. + break;
  14261. +
  14262. + /*
  14263. + * There are at least two words in the RNG FIFO
  14264. + * at this point.
  14265. + */
  14266. + if (rc < len)
  14267. + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
  14268. + if (rc < len)
  14269. + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
  14270. + }
  14271. + } else
  14272. + buf[rc++] = READ_REG_1(sc, HIFN_1_RNG_DATA);
  14273. +
  14274. + /* NB: discard first data read */
  14275. + if (sc->sc_rngfirst) {
  14276. + sc->sc_rngfirst = 0;
  14277. + rc = 0;
  14278. + }
  14279. +
  14280. + return(rc);
  14281. +}
  14282. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  14283. +
  14284. +static void
  14285. +hifn_puc_wait(struct hifn_softc *sc)
  14286. +{
  14287. + int i;
  14288. + int reg = HIFN_0_PUCTRL;
  14289. +
  14290. + if (sc->sc_flags & HIFN_IS_7956) {
  14291. + reg = HIFN_0_PUCTRL2;
  14292. + }
  14293. +
  14294. + for (i = 5000; i > 0; i--) {
  14295. + DELAY(1);
  14296. + if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET))
  14297. + break;
  14298. + }
  14299. + if (!i)
  14300. + device_printf(sc->sc_dev, "proc unit did not reset(0x%x)\n",
  14301. + READ_REG_0(sc, HIFN_0_PUCTRL));
  14302. +}
  14303. +
  14304. +/*
  14305. + * Reset the processing unit.
  14306. + */
  14307. +static void
  14308. +hifn_reset_puc(struct hifn_softc *sc)
  14309. +{
  14310. + /* Reset processing unit */
  14311. + int reg = HIFN_0_PUCTRL;
  14312. +
  14313. + if (sc->sc_flags & HIFN_IS_7956) {
  14314. + reg = HIFN_0_PUCTRL2;
  14315. + }
  14316. + WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA);
  14317. +
  14318. + hifn_puc_wait(sc);
  14319. +}
  14320. +
  14321. +/*
  14322. + * Set the Retry and TRDY registers; note that we set them to
  14323. + * zero because the 7811 locks up when forced to retry (section
  14324. + * 3.6 of "Specification Update SU-0014-04". Not clear if we
  14325. + * should do this for all Hifn parts, but it doesn't seem to hurt.
  14326. + */
  14327. +static void
  14328. +hifn_set_retry(struct hifn_softc *sc)
  14329. +{
  14330. + DPRINTF("%s()\n", __FUNCTION__);
  14331. + /* NB: RETRY only responds to 8-bit reads/writes */
  14332. + pci_write_config_byte(sc->sc_pcidev, HIFN_RETRY_TIMEOUT, 0);
  14333. + pci_write_config_dword(sc->sc_pcidev, HIFN_TRDY_TIMEOUT, 0);
  14334. + /* piggy back the cache line setting here */
  14335. + pci_write_config_byte(sc->sc_pcidev, PCI_CACHE_LINE_SIZE, hifn_cache_linesize);
  14336. +}
  14337. +
  14338. +/*
  14339. + * Resets the board. Values in the regesters are left as is
  14340. + * from the reset (i.e. initial values are assigned elsewhere).
  14341. + */
  14342. +static void
  14343. +hifn_reset_board(struct hifn_softc *sc, int full)
  14344. +{
  14345. + u_int32_t reg;
  14346. +
  14347. + DPRINTF("%s()\n", __FUNCTION__);
  14348. + /*
  14349. + * Set polling in the DMA configuration register to zero. 0x7 avoids
  14350. + * resetting the board and zeros out the other fields.
  14351. + */
  14352. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  14353. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  14354. +
  14355. + /*
  14356. + * Now that polling has been disabled, we have to wait 1 ms
  14357. + * before resetting the board.
  14358. + */
  14359. + DELAY(1000);
  14360. +
  14361. + /* Reset the DMA unit */
  14362. + if (full) {
  14363. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MODE);
  14364. + DELAY(1000);
  14365. + } else {
  14366. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG,
  14367. + HIFN_DMACNFG_MODE | HIFN_DMACNFG_MSTRESET);
  14368. + hifn_reset_puc(sc);
  14369. + }
  14370. +
  14371. + KASSERT(sc->sc_dma != NULL, ("hifn_reset_board: null DMA tag!"));
  14372. + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
  14373. +
  14374. + /* Bring dma unit out of reset */
  14375. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  14376. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  14377. +
  14378. + hifn_puc_wait(sc);
  14379. + hifn_set_retry(sc);
  14380. +
  14381. + if (sc->sc_flags & HIFN_IS_7811) {
  14382. + for (reg = 0; reg < 1000; reg++) {
  14383. + if (READ_REG_1(sc, HIFN_1_7811_MIPSRST) &
  14384. + HIFN_MIPSRST_CRAMINIT)
  14385. + break;
  14386. + DELAY(1000);
  14387. + }
  14388. + if (reg == 1000)
  14389. + device_printf(sc->sc_dev, ": cram init timeout\n");
  14390. + } else {
  14391. + /* set up DMA configuration register #2 */
  14392. + /* turn off all PK and BAR0 swaps */
  14393. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG2,
  14394. + (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)|
  14395. + (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)|
  14396. + (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)|
  14397. + (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT));
  14398. + }
  14399. +}
  14400. +
  14401. +static u_int32_t
  14402. +hifn_next_signature(u_int32_t a, u_int cnt)
  14403. +{
  14404. + int i;
  14405. + u_int32_t v;
  14406. +
  14407. + for (i = 0; i < cnt; i++) {
  14408. +
  14409. + /* get the parity */
  14410. + v = a & 0x80080125;
  14411. + v ^= v >> 16;
  14412. + v ^= v >> 8;
  14413. + v ^= v >> 4;
  14414. + v ^= v >> 2;
  14415. + v ^= v >> 1;
  14416. +
  14417. + a = (v & 1) ^ (a << 1);
  14418. + }
  14419. +
  14420. + return a;
  14421. +}
  14422. +
  14423. +
  14424. +/*
  14425. + * Checks to see if crypto is already enabled. If crypto isn't enable,
  14426. + * "hifn_enable_crypto" is called to enable it. The check is important,
  14427. + * as enabling crypto twice will lock the board.
  14428. + */
  14429. +static int
  14430. +hifn_enable_crypto(struct hifn_softc *sc)
  14431. +{
  14432. + u_int32_t dmacfg, ramcfg, encl, addr, i;
  14433. + char offtbl[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  14434. + 0x00, 0x00, 0x00, 0x00 };
  14435. +
  14436. + DPRINTF("%s()\n", __FUNCTION__);
  14437. +
  14438. + ramcfg = READ_REG_0(sc, HIFN_0_PUCNFG);
  14439. + dmacfg = READ_REG_1(sc, HIFN_1_DMA_CNFG);
  14440. +
  14441. + /*
  14442. + * The RAM config register's encrypt level bit needs to be set before
  14443. + * every read performed on the encryption level register.
  14444. + */
  14445. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
  14446. +
  14447. + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  14448. +
  14449. + /*
  14450. + * Make sure we don't re-unlock. Two unlocks kills chip until the
  14451. + * next reboot.
  14452. + */
  14453. + if (encl == HIFN_PUSTAT_ENA_1 || encl == HIFN_PUSTAT_ENA_2) {
  14454. +#ifdef HIFN_DEBUG
  14455. + if (hifn_debug)
  14456. + device_printf(sc->sc_dev,
  14457. + "Strong crypto already enabled!\n");
  14458. +#endif
  14459. + goto report;
  14460. + }
  14461. +
  14462. + if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) {
  14463. +#ifdef HIFN_DEBUG
  14464. + if (hifn_debug)
  14465. + device_printf(sc->sc_dev,
  14466. + "Unknown encryption level 0x%x\n", encl);
  14467. +#endif
  14468. + return 1;
  14469. + }
  14470. +
  14471. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_UNLOCK |
  14472. + HIFN_DMACNFG_MSTRESET | HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  14473. + DELAY(1000);
  14474. + addr = READ_REG_1(sc, HIFN_UNLOCK_SECRET1);
  14475. + DELAY(1000);
  14476. + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, 0);
  14477. + DELAY(1000);
  14478. +
  14479. + for (i = 0; i <= 12; i++) {
  14480. + addr = hifn_next_signature(addr, offtbl[i] + 0x101);
  14481. + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, addr);
  14482. +
  14483. + DELAY(1000);
  14484. + }
  14485. +
  14486. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
  14487. + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  14488. +
  14489. +#ifdef HIFN_DEBUG
  14490. + if (hifn_debug) {
  14491. + if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2)
  14492. + device_printf(sc->sc_dev, "Engine is permanently "
  14493. + "locked until next system reset!\n");
  14494. + else
  14495. + device_printf(sc->sc_dev, "Engine enabled "
  14496. + "successfully!\n");
  14497. + }
  14498. +#endif
  14499. +
  14500. +report:
  14501. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg);
  14502. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg);
  14503. +
  14504. + switch (encl) {
  14505. + case HIFN_PUSTAT_ENA_1:
  14506. + case HIFN_PUSTAT_ENA_2:
  14507. + break;
  14508. + case HIFN_PUSTAT_ENA_0:
  14509. + default:
  14510. + device_printf(sc->sc_dev, "disabled\n");
  14511. + break;
  14512. + }
  14513. +
  14514. + return 0;
  14515. +}
  14516. +
  14517. +/*
  14518. + * Give initial values to the registers listed in the "Register Space"
  14519. + * section of the HIFN Software Development reference manual.
  14520. + */
  14521. +static void
  14522. +hifn_init_pci_registers(struct hifn_softc *sc)
  14523. +{
  14524. + DPRINTF("%s()\n", __FUNCTION__);
  14525. +
  14526. + /* write fixed values needed by the Initialization registers */
  14527. + WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);
  14528. + WRITE_REG_0(sc, HIFN_0_FIFOCNFG, HIFN_FIFOCNFG_THRESHOLD);
  14529. + WRITE_REG_0(sc, HIFN_0_PUIER, HIFN_PUIER_DSTOVER);
  14530. +
  14531. + /* write all 4 ring address registers */
  14532. + WRITE_REG_1(sc, HIFN_1_DMA_CRAR, sc->sc_dma_physaddr +
  14533. + offsetof(struct hifn_dma, cmdr[0]));
  14534. + WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dma_physaddr +
  14535. + offsetof(struct hifn_dma, srcr[0]));
  14536. + WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dma_physaddr +
  14537. + offsetof(struct hifn_dma, dstr[0]));
  14538. + WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dma_physaddr +
  14539. + offsetof(struct hifn_dma, resr[0]));
  14540. +
  14541. + DELAY(2000);
  14542. +
  14543. + /* write status register */
  14544. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  14545. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS |
  14546. + HIFN_DMACSR_S_CTRL_DIS | HIFN_DMACSR_C_CTRL_DIS |
  14547. + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_D_DONE | HIFN_DMACSR_D_LAST |
  14548. + HIFN_DMACSR_D_WAIT | HIFN_DMACSR_D_OVER |
  14549. + HIFN_DMACSR_R_ABORT | HIFN_DMACSR_R_DONE | HIFN_DMACSR_R_LAST |
  14550. + HIFN_DMACSR_R_WAIT | HIFN_DMACSR_R_OVER |
  14551. + HIFN_DMACSR_S_ABORT | HIFN_DMACSR_S_DONE | HIFN_DMACSR_S_LAST |
  14552. + HIFN_DMACSR_S_WAIT |
  14553. + HIFN_DMACSR_C_ABORT | HIFN_DMACSR_C_DONE | HIFN_DMACSR_C_LAST |
  14554. + HIFN_DMACSR_C_WAIT |
  14555. + HIFN_DMACSR_ENGINE |
  14556. + ((sc->sc_flags & HIFN_HAS_PUBLIC) ?
  14557. + HIFN_DMACSR_PUBDONE : 0) |
  14558. + ((sc->sc_flags & HIFN_IS_7811) ?
  14559. + HIFN_DMACSR_ILLW | HIFN_DMACSR_ILLR : 0));
  14560. +
  14561. + sc->sc_d_busy = sc->sc_r_busy = sc->sc_s_busy = sc->sc_c_busy = 0;
  14562. + sc->sc_dmaier |= HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_ABORT |
  14563. + HIFN_DMAIER_D_OVER | HIFN_DMAIER_R_OVER |
  14564. + HIFN_DMAIER_S_ABORT | HIFN_DMAIER_D_ABORT | HIFN_DMAIER_R_ABORT |
  14565. + ((sc->sc_flags & HIFN_IS_7811) ?
  14566. + HIFN_DMAIER_ILLW | HIFN_DMAIER_ILLR : 0);
  14567. + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
  14568. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  14569. +
  14570. +
  14571. + if (sc->sc_flags & HIFN_IS_7956) {
  14572. + u_int32_t pll;
  14573. +
  14574. + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
  14575. + HIFN_PUCNFG_TCALLPHASES |
  14576. + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32);
  14577. +
  14578. + /* turn off the clocks and insure bypass is set */
  14579. + pll = READ_REG_1(sc, HIFN_1_PLL);
  14580. + pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL))
  14581. + | HIFN_PLL_BP | HIFN_PLL_MBSET;
  14582. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  14583. + DELAY(10*1000); /* 10ms */
  14584. +
  14585. + /* change configuration */
  14586. + pll = (pll &~ HIFN_PLL_CONFIG) | sc->sc_pllconfig;
  14587. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  14588. + DELAY(10*1000); /* 10ms */
  14589. +
  14590. + /* disable bypass */
  14591. + pll &= ~HIFN_PLL_BP;
  14592. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  14593. + /* enable clocks with new configuration */
  14594. + pll |= HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL;
  14595. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  14596. + } else {
  14597. + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
  14598. + HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES |
  14599. + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 |
  14600. + (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM));
  14601. + }
  14602. +
  14603. + WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER);
  14604. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  14605. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST |
  14606. + ((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) |
  14607. + ((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL));
  14608. +}
  14609. +
  14610. +/*
  14611. + * The maximum number of sessions supported by the card
  14612. + * is dependent on the amount of context ram, which
  14613. + * encryption algorithms are enabled, and how compression
  14614. + * is configured. This should be configured before this
  14615. + * routine is called.
  14616. + */
  14617. +static void
  14618. +hifn_sessions(struct hifn_softc *sc)
  14619. +{
  14620. + u_int32_t pucnfg;
  14621. + int ctxsize;
  14622. +
  14623. + DPRINTF("%s()\n", __FUNCTION__);
  14624. +
  14625. + pucnfg = READ_REG_0(sc, HIFN_0_PUCNFG);
  14626. +
  14627. + if (pucnfg & HIFN_PUCNFG_COMPSING) {
  14628. + if (pucnfg & HIFN_PUCNFG_ENCCNFG)
  14629. + ctxsize = 128;
  14630. + else
  14631. + ctxsize = 512;
  14632. + /*
  14633. + * 7955/7956 has internal context memory of 32K
  14634. + */
  14635. + if (sc->sc_flags & HIFN_IS_7956)
  14636. + sc->sc_maxses = 32768 / ctxsize;
  14637. + else
  14638. + sc->sc_maxses = 1 +
  14639. + ((sc->sc_ramsize - 32768) / ctxsize);
  14640. + } else
  14641. + sc->sc_maxses = sc->sc_ramsize / 16384;
  14642. +
  14643. + if (sc->sc_maxses > 2048)
  14644. + sc->sc_maxses = 2048;
  14645. +}
  14646. +
  14647. +/*
  14648. + * Determine ram type (sram or dram). Board should be just out of a reset
  14649. + * state when this is called.
  14650. + */
  14651. +static int
  14652. +hifn_ramtype(struct hifn_softc *sc)
  14653. +{
  14654. + u_int8_t data[8], dataexpect[8];
  14655. + int i;
  14656. +
  14657. + for (i = 0; i < sizeof(data); i++)
  14658. + data[i] = dataexpect[i] = 0x55;
  14659. + if (hifn_writeramaddr(sc, 0, data))
  14660. + return (-1);
  14661. + if (hifn_readramaddr(sc, 0, data))
  14662. + return (-1);
  14663. + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
  14664. + sc->sc_drammodel = 1;
  14665. + return (0);
  14666. + }
  14667. +
  14668. + for (i = 0; i < sizeof(data); i++)
  14669. + data[i] = dataexpect[i] = 0xaa;
  14670. + if (hifn_writeramaddr(sc, 0, data))
  14671. + return (-1);
  14672. + if (hifn_readramaddr(sc, 0, data))
  14673. + return (-1);
  14674. + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
  14675. + sc->sc_drammodel = 1;
  14676. + return (0);
  14677. + }
  14678. +
  14679. + return (0);
  14680. +}
  14681. +
  14682. +#define HIFN_SRAM_MAX (32 << 20)
  14683. +#define HIFN_SRAM_STEP_SIZE 16384
  14684. +#define HIFN_SRAM_GRANULARITY (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)
  14685. +
  14686. +static int
  14687. +hifn_sramsize(struct hifn_softc *sc)
  14688. +{
  14689. + u_int32_t a;
  14690. + u_int8_t data[8];
  14691. + u_int8_t dataexpect[sizeof(data)];
  14692. + int32_t i;
  14693. +
  14694. + for (i = 0; i < sizeof(data); i++)
  14695. + data[i] = dataexpect[i] = i ^ 0x5a;
  14696. +
  14697. + for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) {
  14698. + a = i * HIFN_SRAM_STEP_SIZE;
  14699. + bcopy(&i, data, sizeof(i));
  14700. + hifn_writeramaddr(sc, a, data);
  14701. + }
  14702. +
  14703. + for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) {
  14704. + a = i * HIFN_SRAM_STEP_SIZE;
  14705. + bcopy(&i, dataexpect, sizeof(i));
  14706. + if (hifn_readramaddr(sc, a, data) < 0)
  14707. + return (0);
  14708. + if (bcmp(data, dataexpect, sizeof(data)) != 0)
  14709. + return (0);
  14710. + sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE;
  14711. + }
  14712. +
  14713. + return (0);
  14714. +}
  14715. +
  14716. +/*
  14717. + * XXX For dram boards, one should really try all of the
  14718. + * HIFN_PUCNFG_DSZ_*'s. This just assumes that PUCNFG
  14719. + * is already set up correctly.
  14720. + */
  14721. +static int
  14722. +hifn_dramsize(struct hifn_softc *sc)
  14723. +{
  14724. + u_int32_t cnfg;
  14725. +
  14726. + if (sc->sc_flags & HIFN_IS_7956) {
  14727. + /*
  14728. + * 7955/7956 have a fixed internal ram of only 32K.
  14729. + */
  14730. + sc->sc_ramsize = 32768;
  14731. + } else {
  14732. + cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) &
  14733. + HIFN_PUCNFG_DRAMMASK;
  14734. + sc->sc_ramsize = 1 << ((cnfg >> 13) + 18);
  14735. + }
  14736. + return (0);
  14737. +}
  14738. +
  14739. +static void
  14740. +hifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, int *dstp, int *resp)
  14741. +{
  14742. + struct hifn_dma *dma = sc->sc_dma;
  14743. +
  14744. + DPRINTF("%s()\n", __FUNCTION__);
  14745. +
  14746. + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
  14747. + dma->cmdi = 0;
  14748. + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  14749. + wmb();
  14750. + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
  14751. + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
  14752. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  14753. + }
  14754. + *cmdp = dma->cmdi++;
  14755. + dma->cmdk = dma->cmdi;
  14756. +
  14757. + if (dma->srci == HIFN_D_SRC_RSIZE) {
  14758. + dma->srci = 0;
  14759. + dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  14760. + wmb();
  14761. + dma->srcr[HIFN_D_SRC_RSIZE].l |= htole32(HIFN_D_VALID);
  14762. + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
  14763. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  14764. + }
  14765. + *srcp = dma->srci++;
  14766. + dma->srck = dma->srci;
  14767. +
  14768. + if (dma->dsti == HIFN_D_DST_RSIZE) {
  14769. + dma->dsti = 0;
  14770. + dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  14771. + wmb();
  14772. + dma->dstr[HIFN_D_DST_RSIZE].l |= htole32(HIFN_D_VALID);
  14773. + HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE,
  14774. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  14775. + }
  14776. + *dstp = dma->dsti++;
  14777. + dma->dstk = dma->dsti;
  14778. +
  14779. + if (dma->resi == HIFN_D_RES_RSIZE) {
  14780. + dma->resi = 0;
  14781. + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  14782. + wmb();
  14783. + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
  14784. + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
  14785. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  14786. + }
  14787. + *resp = dma->resi++;
  14788. + dma->resk = dma->resi;
  14789. +}
  14790. +
  14791. +static int
  14792. +hifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
  14793. +{
  14794. + struct hifn_dma *dma = sc->sc_dma;
  14795. + hifn_base_command_t wc;
  14796. + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
  14797. + int r, cmdi, resi, srci, dsti;
  14798. +
  14799. + DPRINTF("%s()\n", __FUNCTION__);
  14800. +
  14801. + wc.masks = htole16(3 << 13);
  14802. + wc.session_num = htole16(addr >> 14);
  14803. + wc.total_source_count = htole16(8);
  14804. + wc.total_dest_count = htole16(addr & 0x3fff);
  14805. +
  14806. + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
  14807. +
  14808. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  14809. + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
  14810. + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
  14811. +
  14812. + /* build write command */
  14813. + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
  14814. + *(hifn_base_command_t *)dma->command_bufs[cmdi] = wc;
  14815. + bcopy(data, &dma->test_src, sizeof(dma->test_src));
  14816. +
  14817. + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr
  14818. + + offsetof(struct hifn_dma, test_src));
  14819. + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr
  14820. + + offsetof(struct hifn_dma, test_dst));
  14821. +
  14822. + dma->cmdr[cmdi].l = htole32(16 | masks);
  14823. + dma->srcr[srci].l = htole32(8 | masks);
  14824. + dma->dstr[dsti].l = htole32(4 | masks);
  14825. + dma->resr[resi].l = htole32(4 | masks);
  14826. +
  14827. + for (r = 10000; r >= 0; r--) {
  14828. + DELAY(10);
  14829. + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
  14830. + break;
  14831. + }
  14832. + if (r == 0) {
  14833. + device_printf(sc->sc_dev, "writeramaddr -- "
  14834. + "result[%d](addr %d) still valid\n", resi, addr);
  14835. + r = -1;
  14836. + return (-1);
  14837. + } else
  14838. + r = 0;
  14839. +
  14840. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  14841. + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
  14842. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
  14843. +
  14844. + return (r);
  14845. +}
  14846. +
  14847. +static int
  14848. +hifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
  14849. +{
  14850. + struct hifn_dma *dma = sc->sc_dma;
  14851. + hifn_base_command_t rc;
  14852. + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
  14853. + int r, cmdi, srci, dsti, resi;
  14854. +
  14855. + DPRINTF("%s()\n", __FUNCTION__);
  14856. +
  14857. + rc.masks = htole16(2 << 13);
  14858. + rc.session_num = htole16(addr >> 14);
  14859. + rc.total_source_count = htole16(addr & 0x3fff);
  14860. + rc.total_dest_count = htole16(8);
  14861. +
  14862. + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
  14863. +
  14864. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  14865. + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
  14866. + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
  14867. +
  14868. + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
  14869. + *(hifn_base_command_t *)dma->command_bufs[cmdi] = rc;
  14870. +
  14871. + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr +
  14872. + offsetof(struct hifn_dma, test_src));
  14873. + dma->test_src = 0;
  14874. + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr +
  14875. + offsetof(struct hifn_dma, test_dst));
  14876. + dma->test_dst = 0;
  14877. + dma->cmdr[cmdi].l = htole32(8 | masks);
  14878. + dma->srcr[srci].l = htole32(8 | masks);
  14879. + dma->dstr[dsti].l = htole32(8 | masks);
  14880. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks);
  14881. +
  14882. + for (r = 10000; r >= 0; r--) {
  14883. + DELAY(10);
  14884. + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
  14885. + break;
  14886. + }
  14887. + if (r == 0) {
  14888. + device_printf(sc->sc_dev, "readramaddr -- "
  14889. + "result[%d](addr %d) still valid\n", resi, addr);
  14890. + r = -1;
  14891. + } else {
  14892. + r = 0;
  14893. + bcopy(&dma->test_dst, data, sizeof(dma->test_dst));
  14894. + }
  14895. +
  14896. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  14897. + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
  14898. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
  14899. +
  14900. + return (r);
  14901. +}
  14902. +
  14903. +/*
  14904. + * Initialize the descriptor rings.
  14905. + */
  14906. +static void
  14907. +hifn_init_dma(struct hifn_softc *sc)
  14908. +{
  14909. + struct hifn_dma *dma = sc->sc_dma;
  14910. + int i;
  14911. +
  14912. + DPRINTF("%s()\n", __FUNCTION__);
  14913. +
  14914. + hifn_set_retry(sc);
  14915. +
  14916. + /* initialize static pointer values */
  14917. + for (i = 0; i < HIFN_D_CMD_RSIZE; i++)
  14918. + dma->cmdr[i].p = htole32(sc->sc_dma_physaddr +
  14919. + offsetof(struct hifn_dma, command_bufs[i][0]));
  14920. + for (i = 0; i < HIFN_D_RES_RSIZE; i++)
  14921. + dma->resr[i].p = htole32(sc->sc_dma_physaddr +
  14922. + offsetof(struct hifn_dma, result_bufs[i][0]));
  14923. +
  14924. + dma->cmdr[HIFN_D_CMD_RSIZE].p =
  14925. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, cmdr[0]));
  14926. + dma->srcr[HIFN_D_SRC_RSIZE].p =
  14927. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, srcr[0]));
  14928. + dma->dstr[HIFN_D_DST_RSIZE].p =
  14929. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, dstr[0]));
  14930. + dma->resr[HIFN_D_RES_RSIZE].p =
  14931. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, resr[0]));
  14932. +
  14933. + dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0;
  14934. + dma->cmdi = dma->srci = dma->dsti = dma->resi = 0;
  14935. + dma->cmdk = dma->srck = dma->dstk = dma->resk = 0;
  14936. +}
  14937. +
  14938. +/*
  14939. + * Writes out the raw command buffer space. Returns the
  14940. + * command buffer size.
  14941. + */
  14942. +static u_int
  14943. +hifn_write_command(struct hifn_command *cmd, u_int8_t *buf)
  14944. +{
  14945. + struct hifn_softc *sc = NULL;
  14946. + u_int8_t *buf_pos;
  14947. + hifn_base_command_t *base_cmd;
  14948. + hifn_mac_command_t *mac_cmd;
  14949. + hifn_crypt_command_t *cry_cmd;
  14950. + int using_mac, using_crypt, len, ivlen;
  14951. + u_int32_t dlen, slen;
  14952. +
  14953. + DPRINTF("%s()\n", __FUNCTION__);
  14954. +
  14955. + buf_pos = buf;
  14956. + using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC;
  14957. + using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT;
  14958. +
  14959. + base_cmd = (hifn_base_command_t *)buf_pos;
  14960. + base_cmd->masks = htole16(cmd->base_masks);
  14961. + slen = cmd->src_mapsize;
  14962. + if (cmd->sloplen)
  14963. + dlen = cmd->dst_mapsize - cmd->sloplen + sizeof(u_int32_t);
  14964. + else
  14965. + dlen = cmd->dst_mapsize;
  14966. + base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO);
  14967. + base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);
  14968. + dlen >>= 16;
  14969. + slen >>= 16;
  14970. + base_cmd->session_num = htole16(
  14971. + ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |
  14972. + ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));
  14973. + buf_pos += sizeof(hifn_base_command_t);
  14974. +
  14975. + if (using_mac) {
  14976. + mac_cmd = (hifn_mac_command_t *)buf_pos;
  14977. + dlen = cmd->maccrd->crd_len;
  14978. + mac_cmd->source_count = htole16(dlen & 0xffff);
  14979. + dlen >>= 16;
  14980. + mac_cmd->masks = htole16(cmd->mac_masks |
  14981. + ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M));
  14982. + mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip);
  14983. + mac_cmd->reserved = 0;
  14984. + buf_pos += sizeof(hifn_mac_command_t);
  14985. + }
  14986. +
  14987. + if (using_crypt) {
  14988. + cry_cmd = (hifn_crypt_command_t *)buf_pos;
  14989. + dlen = cmd->enccrd->crd_len;
  14990. + cry_cmd->source_count = htole16(dlen & 0xffff);
  14991. + dlen >>= 16;
  14992. + cry_cmd->masks = htole16(cmd->cry_masks |
  14993. + ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M));
  14994. + cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip);
  14995. + cry_cmd->reserved = 0;
  14996. + buf_pos += sizeof(hifn_crypt_command_t);
  14997. + }
  14998. +
  14999. + if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) {
  15000. + bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH);
  15001. + buf_pos += HIFN_MAC_KEY_LENGTH;
  15002. + }
  15003. +
  15004. + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) {
  15005. + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
  15006. + case HIFN_CRYPT_CMD_ALG_3DES:
  15007. + bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH);
  15008. + buf_pos += HIFN_3DES_KEY_LENGTH;
  15009. + break;
  15010. + case HIFN_CRYPT_CMD_ALG_DES:
  15011. + bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH);
  15012. + buf_pos += HIFN_DES_KEY_LENGTH;
  15013. + break;
  15014. + case HIFN_CRYPT_CMD_ALG_RC4:
  15015. + len = 256;
  15016. + do {
  15017. + int clen;
  15018. +
  15019. + clen = MIN(cmd->cklen, len);
  15020. + bcopy(cmd->ck, buf_pos, clen);
  15021. + len -= clen;
  15022. + buf_pos += clen;
  15023. + } while (len > 0);
  15024. + bzero(buf_pos, 4);
  15025. + buf_pos += 4;
  15026. + break;
  15027. + case HIFN_CRYPT_CMD_ALG_AES:
  15028. + /*
  15029. + * AES keys are variable 128, 192 and
  15030. + * 256 bits (16, 24 and 32 bytes).
  15031. + */
  15032. + bcopy(cmd->ck, buf_pos, cmd->cklen);
  15033. + buf_pos += cmd->cklen;
  15034. + break;
  15035. + }
  15036. + }
  15037. +
  15038. + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) {
  15039. + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
  15040. + case HIFN_CRYPT_CMD_ALG_AES:
  15041. + ivlen = HIFN_AES_IV_LENGTH;
  15042. + break;
  15043. + default:
  15044. + ivlen = HIFN_IV_LENGTH;
  15045. + break;
  15046. + }
  15047. + bcopy(cmd->iv, buf_pos, ivlen);
  15048. + buf_pos += ivlen;
  15049. + }
  15050. +
  15051. + if ((cmd->base_masks & (HIFN_BASE_CMD_MAC|HIFN_BASE_CMD_CRYPT)) == 0) {
  15052. + bzero(buf_pos, 8);
  15053. + buf_pos += 8;
  15054. + }
  15055. +
  15056. + return (buf_pos - buf);
  15057. +}
  15058. +
  15059. +static int
  15060. +hifn_dmamap_aligned(struct hifn_operand *op)
  15061. +{
  15062. + struct hifn_softc *sc = NULL;
  15063. + int i;
  15064. +
  15065. + DPRINTF("%s()\n", __FUNCTION__);
  15066. +
  15067. + for (i = 0; i < op->nsegs; i++) {
  15068. + if (op->segs[i].ds_addr & 3)
  15069. + return (0);
  15070. + if ((i != (op->nsegs - 1)) && (op->segs[i].ds_len & 3))
  15071. + return (0);
  15072. + }
  15073. + return (1);
  15074. +}
  15075. +
  15076. +static __inline int
  15077. +hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx)
  15078. +{
  15079. + struct hifn_dma *dma = sc->sc_dma;
  15080. +
  15081. + if (++idx == HIFN_D_DST_RSIZE) {
  15082. + dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
  15083. + HIFN_D_MASKDONEIRQ);
  15084. + HIFN_DSTR_SYNC(sc, idx,
  15085. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15086. + idx = 0;
  15087. + }
  15088. + return (idx);
  15089. +}
  15090. +
  15091. +static int
  15092. +hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
  15093. +{
  15094. + struct hifn_dma *dma = sc->sc_dma;
  15095. + struct hifn_operand *dst = &cmd->dst;
  15096. + u_int32_t p, l;
  15097. + int idx, used = 0, i;
  15098. +
  15099. + DPRINTF("%s()\n", __FUNCTION__);
  15100. +
  15101. + idx = dma->dsti;
  15102. + for (i = 0; i < dst->nsegs - 1; i++) {
  15103. + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
  15104. + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ | dst->segs[i].ds_len);
  15105. + wmb();
  15106. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  15107. + HIFN_DSTR_SYNC(sc, idx,
  15108. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15109. + used++;
  15110. +
  15111. + idx = hifn_dmamap_dstwrap(sc, idx);
  15112. + }
  15113. +
  15114. + if (cmd->sloplen == 0) {
  15115. + p = dst->segs[i].ds_addr;
  15116. + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
  15117. + dst->segs[i].ds_len;
  15118. + } else {
  15119. + p = sc->sc_dma_physaddr +
  15120. + offsetof(struct hifn_dma, slop[cmd->slopidx]);
  15121. + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
  15122. + sizeof(u_int32_t);
  15123. +
  15124. + if ((dst->segs[i].ds_len - cmd->sloplen) != 0) {
  15125. + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
  15126. + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ |
  15127. + (dst->segs[i].ds_len - cmd->sloplen));
  15128. + wmb();
  15129. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  15130. + HIFN_DSTR_SYNC(sc, idx,
  15131. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15132. + used++;
  15133. +
  15134. + idx = hifn_dmamap_dstwrap(sc, idx);
  15135. + }
  15136. + }
  15137. + dma->dstr[idx].p = htole32(p);
  15138. + dma->dstr[idx].l = htole32(l);
  15139. + wmb();
  15140. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  15141. + HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15142. + used++;
  15143. +
  15144. + idx = hifn_dmamap_dstwrap(sc, idx);
  15145. +
  15146. + dma->dsti = idx;
  15147. + dma->dstu += used;
  15148. + return (idx);
  15149. +}
  15150. +
  15151. +static __inline int
  15152. +hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx)
  15153. +{
  15154. + struct hifn_dma *dma = sc->sc_dma;
  15155. +
  15156. + if (++idx == HIFN_D_SRC_RSIZE) {
  15157. + dma->srcr[idx].l = htole32(HIFN_D_VALID |
  15158. + HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
  15159. + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
  15160. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  15161. + idx = 0;
  15162. + }
  15163. + return (idx);
  15164. +}
  15165. +
  15166. +static int
  15167. +hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)
  15168. +{
  15169. + struct hifn_dma *dma = sc->sc_dma;
  15170. + struct hifn_operand *src = &cmd->src;
  15171. + int idx, i;
  15172. + u_int32_t last = 0;
  15173. +
  15174. + DPRINTF("%s()\n", __FUNCTION__);
  15175. +
  15176. + idx = dma->srci;
  15177. + for (i = 0; i < src->nsegs; i++) {
  15178. + if (i == src->nsegs - 1)
  15179. + last = HIFN_D_LAST;
  15180. +
  15181. + dma->srcr[idx].p = htole32(src->segs[i].ds_addr);
  15182. + dma->srcr[idx].l = htole32(src->segs[i].ds_len |
  15183. + HIFN_D_MASKDONEIRQ | last);
  15184. + wmb();
  15185. + dma->srcr[idx].l |= htole32(HIFN_D_VALID);
  15186. + HIFN_SRCR_SYNC(sc, idx,
  15187. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  15188. +
  15189. + idx = hifn_dmamap_srcwrap(sc, idx);
  15190. + }
  15191. + dma->srci = idx;
  15192. + dma->srcu += src->nsegs;
  15193. + return (idx);
  15194. +}
  15195. +
  15196. +
  15197. +static int
  15198. +hifn_crypto(
  15199. + struct hifn_softc *sc,
  15200. + struct hifn_command *cmd,
  15201. + struct cryptop *crp,
  15202. + int hint)
  15203. +{
  15204. + struct hifn_dma *dma = sc->sc_dma;
  15205. + u_int32_t cmdlen, csr;
  15206. + int cmdi, resi, err = 0;
  15207. + unsigned long l_flags;
  15208. +
  15209. + DPRINTF("%s()\n", __FUNCTION__);
  15210. +
  15211. + /*
  15212. + * need 1 cmd, and 1 res
  15213. + *
  15214. + * NB: check this first since it's easy.
  15215. + */
  15216. + HIFN_LOCK(sc);
  15217. + if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE ||
  15218. + (dma->resu + 1) > HIFN_D_RES_RSIZE) {
  15219. +#ifdef HIFN_DEBUG
  15220. + if (hifn_debug) {
  15221. + device_printf(sc->sc_dev,
  15222. + "cmd/result exhaustion, cmdu %u resu %u\n",
  15223. + dma->cmdu, dma->resu);
  15224. + }
  15225. +#endif
  15226. + hifnstats.hst_nomem_cr++;
  15227. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  15228. + HIFN_UNLOCK(sc);
  15229. + return (ERESTART);
  15230. + }
  15231. +
  15232. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  15233. + if (pci_map_skb(sc, &cmd->src, cmd->src_skb)) {
  15234. + hifnstats.hst_nomem_load++;
  15235. + err = ENOMEM;
  15236. + goto err_srcmap1;
  15237. + }
  15238. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  15239. + if (pci_map_uio(sc, &cmd->src, cmd->src_io)) {
  15240. + hifnstats.hst_nomem_load++;
  15241. + err = ENOMEM;
  15242. + goto err_srcmap1;
  15243. + }
  15244. + } else {
  15245. + if (pci_map_buf(sc, &cmd->src, cmd->src_buf, crp->crp_ilen)) {
  15246. + hifnstats.hst_nomem_load++;
  15247. + err = ENOMEM;
  15248. + goto err_srcmap1;
  15249. + }
  15250. + }
  15251. +
  15252. + if (hifn_dmamap_aligned(&cmd->src)) {
  15253. + cmd->sloplen = cmd->src_mapsize & 3;
  15254. + cmd->dst = cmd->src;
  15255. + } else {
  15256. + if (crp->crp_flags & CRYPTO_F_IOV) {
  15257. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15258. + err = EINVAL;
  15259. + goto err_srcmap;
  15260. + } else if (crp->crp_flags & CRYPTO_F_SKBUF) {
  15261. +#ifdef NOTYET
  15262. + int totlen, len;
  15263. + struct mbuf *m, *m0, *mlast;
  15264. +
  15265. + KASSERT(cmd->dst_m == cmd->src_m,
  15266. + ("hifn_crypto: dst_m initialized improperly"));
  15267. + hifnstats.hst_unaligned++;
  15268. + /*
  15269. + * Source is not aligned on a longword boundary.
  15270. + * Copy the data to insure alignment. If we fail
  15271. + * to allocate mbufs or clusters while doing this
  15272. + * we return ERESTART so the operation is requeued
  15273. + * at the crypto later, but only if there are
  15274. + * ops already posted to the hardware; otherwise we
  15275. + * have no guarantee that we'll be re-entered.
  15276. + */
  15277. + totlen = cmd->src_mapsize;
  15278. + if (cmd->src_m->m_flags & M_PKTHDR) {
  15279. + len = MHLEN;
  15280. + MGETHDR(m0, M_DONTWAIT, MT_DATA);
  15281. + if (m0 && !m_dup_pkthdr(m0, cmd->src_m, M_DONTWAIT)) {
  15282. + m_free(m0);
  15283. + m0 = NULL;
  15284. + }
  15285. + } else {
  15286. + len = MLEN;
  15287. + MGET(m0, M_DONTWAIT, MT_DATA);
  15288. + }
  15289. + if (m0 == NULL) {
  15290. + hifnstats.hst_nomem_mbuf++;
  15291. + err = dma->cmdu ? ERESTART : ENOMEM;
  15292. + goto err_srcmap;
  15293. + }
  15294. + if (totlen >= MINCLSIZE) {
  15295. + MCLGET(m0, M_DONTWAIT);
  15296. + if ((m0->m_flags & M_EXT) == 0) {
  15297. + hifnstats.hst_nomem_mcl++;
  15298. + err = dma->cmdu ? ERESTART : ENOMEM;
  15299. + m_freem(m0);
  15300. + goto err_srcmap;
  15301. + }
  15302. + len = MCLBYTES;
  15303. + }
  15304. + totlen -= len;
  15305. + m0->m_pkthdr.len = m0->m_len = len;
  15306. + mlast = m0;
  15307. +
  15308. + while (totlen > 0) {
  15309. + MGET(m, M_DONTWAIT, MT_DATA);
  15310. + if (m == NULL) {
  15311. + hifnstats.hst_nomem_mbuf++;
  15312. + err = dma->cmdu ? ERESTART : ENOMEM;
  15313. + m_freem(m0);
  15314. + goto err_srcmap;
  15315. + }
  15316. + len = MLEN;
  15317. + if (totlen >= MINCLSIZE) {
  15318. + MCLGET(m, M_DONTWAIT);
  15319. + if ((m->m_flags & M_EXT) == 0) {
  15320. + hifnstats.hst_nomem_mcl++;
  15321. + err = dma->cmdu ? ERESTART : ENOMEM;
  15322. + mlast->m_next = m;
  15323. + m_freem(m0);
  15324. + goto err_srcmap;
  15325. + }
  15326. + len = MCLBYTES;
  15327. + }
  15328. +
  15329. + m->m_len = len;
  15330. + m0->m_pkthdr.len += len;
  15331. + totlen -= len;
  15332. +
  15333. + mlast->m_next = m;
  15334. + mlast = m;
  15335. + }
  15336. + cmd->dst_m = m0;
  15337. +#else
  15338. + device_printf(sc->sc_dev,
  15339. + "%s,%d: CRYPTO_F_SKBUF unaligned not implemented\n",
  15340. + __FILE__, __LINE__);
  15341. + err = EINVAL;
  15342. + goto err_srcmap;
  15343. +#endif
  15344. + } else {
  15345. + device_printf(sc->sc_dev,
  15346. + "%s,%d: unaligned contig buffers not implemented\n",
  15347. + __FILE__, __LINE__);
  15348. + err = EINVAL;
  15349. + goto err_srcmap;
  15350. + }
  15351. + }
  15352. +
  15353. + if (cmd->dst_map == NULL) {
  15354. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  15355. + if (pci_map_skb(sc, &cmd->dst, cmd->dst_skb)) {
  15356. + hifnstats.hst_nomem_map++;
  15357. + err = ENOMEM;
  15358. + goto err_dstmap1;
  15359. + }
  15360. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  15361. + if (pci_map_uio(sc, &cmd->dst, cmd->dst_io)) {
  15362. + hifnstats.hst_nomem_load++;
  15363. + err = ENOMEM;
  15364. + goto err_dstmap1;
  15365. + }
  15366. + } else {
  15367. + if (pci_map_buf(sc, &cmd->dst, cmd->dst_buf, crp->crp_ilen)) {
  15368. + hifnstats.hst_nomem_load++;
  15369. + err = ENOMEM;
  15370. + goto err_dstmap1;
  15371. + }
  15372. + }
  15373. + }
  15374. +
  15375. +#ifdef HIFN_DEBUG
  15376. + if (hifn_debug) {
  15377. + device_printf(sc->sc_dev,
  15378. + "Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",
  15379. + READ_REG_1(sc, HIFN_1_DMA_CSR),
  15380. + READ_REG_1(sc, HIFN_1_DMA_IER),
  15381. + dma->cmdu, dma->srcu, dma->dstu, dma->resu,
  15382. + cmd->src_nsegs, cmd->dst_nsegs);
  15383. + }
  15384. +#endif
  15385. +
  15386. +#if 0
  15387. + if (cmd->src_map == cmd->dst_map) {
  15388. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  15389. + BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
  15390. + } else {
  15391. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  15392. + BUS_DMASYNC_PREWRITE);
  15393. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  15394. + BUS_DMASYNC_PREREAD);
  15395. + }
  15396. +#endif
  15397. +
  15398. + /*
  15399. + * need N src, and N dst
  15400. + */
  15401. + if ((dma->srcu + cmd->src_nsegs) > HIFN_D_SRC_RSIZE ||
  15402. + (dma->dstu + cmd->dst_nsegs + 1) > HIFN_D_DST_RSIZE) {
  15403. +#ifdef HIFN_DEBUG
  15404. + if (hifn_debug) {
  15405. + device_printf(sc->sc_dev,
  15406. + "src/dst exhaustion, srcu %u+%u dstu %u+%u\n",
  15407. + dma->srcu, cmd->src_nsegs,
  15408. + dma->dstu, cmd->dst_nsegs);
  15409. + }
  15410. +#endif
  15411. + hifnstats.hst_nomem_sd++;
  15412. + err = ERESTART;
  15413. + goto err_dstmap;
  15414. + }
  15415. +
  15416. + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
  15417. + dma->cmdi = 0;
  15418. + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  15419. + wmb();
  15420. + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
  15421. + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
  15422. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  15423. + }
  15424. + cmdi = dma->cmdi++;
  15425. + cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]);
  15426. + HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE);
  15427. +
  15428. + /* .p for command/result already set */
  15429. + dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_LAST |
  15430. + HIFN_D_MASKDONEIRQ);
  15431. + wmb();
  15432. + dma->cmdr[cmdi].l |= htole32(HIFN_D_VALID);
  15433. + HIFN_CMDR_SYNC(sc, cmdi,
  15434. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  15435. + dma->cmdu++;
  15436. +
  15437. + /*
  15438. + * We don't worry about missing an interrupt (which a "command wait"
  15439. + * interrupt salvages us from), unless there is more than one command
  15440. + * in the queue.
  15441. + */
  15442. + if (dma->cmdu > 1) {
  15443. + sc->sc_dmaier |= HIFN_DMAIER_C_WAIT;
  15444. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  15445. + }
  15446. +
  15447. + hifnstats.hst_ipackets++;
  15448. + hifnstats.hst_ibytes += cmd->src_mapsize;
  15449. +
  15450. + hifn_dmamap_load_src(sc, cmd);
  15451. +
  15452. + /*
  15453. + * Unlike other descriptors, we don't mask done interrupt from
  15454. + * result descriptor.
  15455. + */
  15456. +#ifdef HIFN_DEBUG
  15457. + if (hifn_debug)
  15458. + device_printf(sc->sc_dev, "load res\n");
  15459. +#endif
  15460. + if (dma->resi == HIFN_D_RES_RSIZE) {
  15461. + dma->resi = 0;
  15462. + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  15463. + wmb();
  15464. + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
  15465. + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
  15466. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15467. + }
  15468. + resi = dma->resi++;
  15469. + KASSERT(dma->hifn_commands[resi] == NULL,
  15470. + ("hifn_crypto: command slot %u busy", resi));
  15471. + dma->hifn_commands[resi] = cmd;
  15472. + HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD);
  15473. + if ((hint & CRYPTO_HINT_MORE) && sc->sc_curbatch < hifn_maxbatch) {
  15474. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT |
  15475. + HIFN_D_LAST | HIFN_D_MASKDONEIRQ);
  15476. + wmb();
  15477. + dma->resr[resi].l |= htole32(HIFN_D_VALID);
  15478. + sc->sc_curbatch++;
  15479. + if (sc->sc_curbatch > hifnstats.hst_maxbatch)
  15480. + hifnstats.hst_maxbatch = sc->sc_curbatch;
  15481. + hifnstats.hst_totbatch++;
  15482. + } else {
  15483. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | HIFN_D_LAST);
  15484. + wmb();
  15485. + dma->resr[resi].l |= htole32(HIFN_D_VALID);
  15486. + sc->sc_curbatch = 0;
  15487. + }
  15488. + HIFN_RESR_SYNC(sc, resi,
  15489. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15490. + dma->resu++;
  15491. +
  15492. + if (cmd->sloplen)
  15493. + cmd->slopidx = resi;
  15494. +
  15495. + hifn_dmamap_load_dst(sc, cmd);
  15496. +
  15497. + csr = 0;
  15498. + if (sc->sc_c_busy == 0) {
  15499. + csr |= HIFN_DMACSR_C_CTRL_ENA;
  15500. + sc->sc_c_busy = 1;
  15501. + }
  15502. + if (sc->sc_s_busy == 0) {
  15503. + csr |= HIFN_DMACSR_S_CTRL_ENA;
  15504. + sc->sc_s_busy = 1;
  15505. + }
  15506. + if (sc->sc_r_busy == 0) {
  15507. + csr |= HIFN_DMACSR_R_CTRL_ENA;
  15508. + sc->sc_r_busy = 1;
  15509. + }
  15510. + if (sc->sc_d_busy == 0) {
  15511. + csr |= HIFN_DMACSR_D_CTRL_ENA;
  15512. + sc->sc_d_busy = 1;
  15513. + }
  15514. + if (csr)
  15515. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, csr);
  15516. +
  15517. +#ifdef HIFN_DEBUG
  15518. + if (hifn_debug) {
  15519. + device_printf(sc->sc_dev, "command: stat %8x ier %8x\n",
  15520. + READ_REG_1(sc, HIFN_1_DMA_CSR),
  15521. + READ_REG_1(sc, HIFN_1_DMA_IER));
  15522. + }
  15523. +#endif
  15524. +
  15525. + sc->sc_active = 5;
  15526. + HIFN_UNLOCK(sc);
  15527. + KASSERT(err == 0, ("hifn_crypto: success with error %u", err));
  15528. + return (err); /* success */
  15529. +
  15530. +err_dstmap:
  15531. + if (cmd->src_map != cmd->dst_map)
  15532. + pci_unmap_buf(sc, &cmd->dst);
  15533. +err_dstmap1:
  15534. +err_srcmap:
  15535. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  15536. + if (cmd->src_skb != cmd->dst_skb)
  15537. +#ifdef NOTYET
  15538. + m_freem(cmd->dst_m);
  15539. +#else
  15540. + device_printf(sc->sc_dev,
  15541. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  15542. + __FILE__, __LINE__);
  15543. +#endif
  15544. + }
  15545. + pci_unmap_buf(sc, &cmd->src);
  15546. +err_srcmap1:
  15547. + HIFN_UNLOCK(sc);
  15548. + return (err);
  15549. +}
  15550. +
  15551. +static void
  15552. +hifn_tick(unsigned long arg)
  15553. +{
  15554. + struct hifn_softc *sc;
  15555. + unsigned long l_flags;
  15556. +
  15557. + if (arg >= HIFN_MAX_CHIPS)
  15558. + return;
  15559. + sc = hifn_chip_idx[arg];
  15560. + if (!sc)
  15561. + return;
  15562. +
  15563. + HIFN_LOCK(sc);
  15564. + if (sc->sc_active == 0) {
  15565. + struct hifn_dma *dma = sc->sc_dma;
  15566. + u_int32_t r = 0;
  15567. +
  15568. + if (dma->cmdu == 0 && sc->sc_c_busy) {
  15569. + sc->sc_c_busy = 0;
  15570. + r |= HIFN_DMACSR_C_CTRL_DIS;
  15571. + }
  15572. + if (dma->srcu == 0 && sc->sc_s_busy) {
  15573. + sc->sc_s_busy = 0;
  15574. + r |= HIFN_DMACSR_S_CTRL_DIS;
  15575. + }
  15576. + if (dma->dstu == 0 && sc->sc_d_busy) {
  15577. + sc->sc_d_busy = 0;
  15578. + r |= HIFN_DMACSR_D_CTRL_DIS;
  15579. + }
  15580. + if (dma->resu == 0 && sc->sc_r_busy) {
  15581. + sc->sc_r_busy = 0;
  15582. + r |= HIFN_DMACSR_R_CTRL_DIS;
  15583. + }
  15584. + if (r)
  15585. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, r);
  15586. + } else
  15587. + sc->sc_active--;
  15588. + HIFN_UNLOCK(sc);
  15589. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  15590. +}
  15591. +
  15592. +static irqreturn_t
  15593. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  15594. +hifn_intr(int irq, void *arg)
  15595. +#else
  15596. +hifn_intr(int irq, void *arg, struct pt_regs *regs)
  15597. +#endif
  15598. +{
  15599. + struct hifn_softc *sc = arg;
  15600. + struct hifn_dma *dma;
  15601. + u_int32_t dmacsr, restart;
  15602. + int i, u;
  15603. + unsigned long l_flags;
  15604. +
  15605. + dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);
  15606. +
  15607. + /* Nothing in the DMA unit interrupted */
  15608. + if ((dmacsr & sc->sc_dmaier) == 0)
  15609. + return IRQ_NONE;
  15610. +
  15611. + HIFN_LOCK(sc);
  15612. +
  15613. + dma = sc->sc_dma;
  15614. +
  15615. +#ifdef HIFN_DEBUG
  15616. + if (hifn_debug) {
  15617. + device_printf(sc->sc_dev,
  15618. + "irq: stat %08x ien %08x damier %08x i %d/%d/%d/%d k %d/%d/%d/%d u %d/%d/%d/%d\n",
  15619. + dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER), sc->sc_dmaier,
  15620. + dma->cmdi, dma->srci, dma->dsti, dma->resi,
  15621. + dma->cmdk, dma->srck, dma->dstk, dma->resk,
  15622. + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
  15623. + }
  15624. +#endif
  15625. +
  15626. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier);
  15627. +
  15628. + if ((sc->sc_flags & HIFN_HAS_PUBLIC) &&
  15629. + (dmacsr & HIFN_DMACSR_PUBDONE))
  15630. + WRITE_REG_1(sc, HIFN_1_PUB_STATUS,
  15631. + READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE);
  15632. +
  15633. + restart = dmacsr & (HIFN_DMACSR_D_OVER | HIFN_DMACSR_R_OVER);
  15634. + if (restart)
  15635. + device_printf(sc->sc_dev, "overrun %x\n", dmacsr);
  15636. +
  15637. + if (sc->sc_flags & HIFN_IS_7811) {
  15638. + if (dmacsr & HIFN_DMACSR_ILLR)
  15639. + device_printf(sc->sc_dev, "illegal read\n");
  15640. + if (dmacsr & HIFN_DMACSR_ILLW)
  15641. + device_printf(sc->sc_dev, "illegal write\n");
  15642. + }
  15643. +
  15644. + restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT |
  15645. + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT);
  15646. + if (restart) {
  15647. + device_printf(sc->sc_dev, "abort, resetting.\n");
  15648. + hifnstats.hst_abort++;
  15649. + hifn_abort(sc);
  15650. + HIFN_UNLOCK(sc);
  15651. + return IRQ_HANDLED;
  15652. + }
  15653. +
  15654. + if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->cmdu == 0)) {
  15655. + /*
  15656. + * If no slots to process and we receive a "waiting on
  15657. + * command" interrupt, we disable the "waiting on command"
  15658. + * (by clearing it).
  15659. + */
  15660. + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
  15661. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  15662. + }
  15663. +
  15664. + /* clear the rings */
  15665. + i = dma->resk; u = dma->resu;
  15666. + while (u != 0) {
  15667. + HIFN_RESR_SYNC(sc, i,
  15668. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  15669. + if (dma->resr[i].l & htole32(HIFN_D_VALID)) {
  15670. + HIFN_RESR_SYNC(sc, i,
  15671. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15672. + break;
  15673. + }
  15674. +
  15675. + if (i != HIFN_D_RES_RSIZE) {
  15676. + struct hifn_command *cmd;
  15677. + u_int8_t *macbuf = NULL;
  15678. +
  15679. + HIFN_RES_SYNC(sc, i, BUS_DMASYNC_POSTREAD);
  15680. + cmd = dma->hifn_commands[i];
  15681. + KASSERT(cmd != NULL,
  15682. + ("hifn_intr: null command slot %u", i));
  15683. + dma->hifn_commands[i] = NULL;
  15684. +
  15685. + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
  15686. + macbuf = dma->result_bufs[i];
  15687. + macbuf += 12;
  15688. + }
  15689. +
  15690. + hifn_callback(sc, cmd, macbuf);
  15691. + hifnstats.hst_opackets++;
  15692. + u--;
  15693. + }
  15694. +
  15695. + if (++i == (HIFN_D_RES_RSIZE + 1))
  15696. + i = 0;
  15697. + }
  15698. + dma->resk = i; dma->resu = u;
  15699. +
  15700. + i = dma->srck; u = dma->srcu;
  15701. + while (u != 0) {
  15702. + if (i == HIFN_D_SRC_RSIZE)
  15703. + i = 0;
  15704. + HIFN_SRCR_SYNC(sc, i,
  15705. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  15706. + if (dma->srcr[i].l & htole32(HIFN_D_VALID)) {
  15707. + HIFN_SRCR_SYNC(sc, i,
  15708. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15709. + break;
  15710. + }
  15711. + i++, u--;
  15712. + }
  15713. + dma->srck = i; dma->srcu = u;
  15714. +
  15715. + i = dma->cmdk; u = dma->cmdu;
  15716. + while (u != 0) {
  15717. + HIFN_CMDR_SYNC(sc, i,
  15718. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  15719. + if (dma->cmdr[i].l & htole32(HIFN_D_VALID)) {
  15720. + HIFN_CMDR_SYNC(sc, i,
  15721. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15722. + break;
  15723. + }
  15724. + if (i != HIFN_D_CMD_RSIZE) {
  15725. + u--;
  15726. + HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE);
  15727. + }
  15728. + if (++i == (HIFN_D_CMD_RSIZE + 1))
  15729. + i = 0;
  15730. + }
  15731. + dma->cmdk = i; dma->cmdu = u;
  15732. +
  15733. + HIFN_UNLOCK(sc);
  15734. +
  15735. + if (sc->sc_needwakeup) { /* XXX check high watermark */
  15736. + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
  15737. +#ifdef HIFN_DEBUG
  15738. + if (hifn_debug)
  15739. + device_printf(sc->sc_dev,
  15740. + "wakeup crypto (%x) u %d/%d/%d/%d\n",
  15741. + sc->sc_needwakeup,
  15742. + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
  15743. +#endif
  15744. + sc->sc_needwakeup &= ~wakeup;
  15745. + crypto_unblock(sc->sc_cid, wakeup);
  15746. + }
  15747. +
  15748. + return IRQ_HANDLED;
  15749. +}
  15750. +
  15751. +/*
  15752. + * Allocate a new 'session' and return an encoded session id. 'sidp'
  15753. + * contains our registration id, and should contain an encoded session
  15754. + * id on successful allocation.
  15755. + */
  15756. +static int
  15757. +hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  15758. +{
  15759. + struct hifn_softc *sc = device_get_softc(dev);
  15760. + struct cryptoini *c;
  15761. + int mac = 0, cry = 0, sesn;
  15762. + struct hifn_session *ses = NULL;
  15763. + unsigned long l_flags;
  15764. +
  15765. + DPRINTF("%s()\n", __FUNCTION__);
  15766. +
  15767. + KASSERT(sc != NULL, ("hifn_newsession: null softc"));
  15768. + if (sidp == NULL || cri == NULL || sc == NULL) {
  15769. + DPRINTF("%s,%d: %s - EINVAL\n", __FILE__, __LINE__, __FUNCTION__);
  15770. + return (EINVAL);
  15771. + }
  15772. +
  15773. + HIFN_LOCK(sc);
  15774. + if (sc->sc_sessions == NULL) {
  15775. + ses = sc->sc_sessions = (struct hifn_session *)kmalloc(sizeof(*ses),
  15776. + SLAB_ATOMIC);
  15777. + if (ses == NULL) {
  15778. + HIFN_UNLOCK(sc);
  15779. + return (ENOMEM);
  15780. + }
  15781. + sesn = 0;
  15782. + sc->sc_nsessions = 1;
  15783. + } else {
  15784. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  15785. + if (!sc->sc_sessions[sesn].hs_used) {
  15786. + ses = &sc->sc_sessions[sesn];
  15787. + break;
  15788. + }
  15789. + }
  15790. +
  15791. + if (ses == NULL) {
  15792. + sesn = sc->sc_nsessions;
  15793. + ses = (struct hifn_session *)kmalloc((sesn + 1) * sizeof(*ses),
  15794. + SLAB_ATOMIC);
  15795. + if (ses == NULL) {
  15796. + HIFN_UNLOCK(sc);
  15797. + return (ENOMEM);
  15798. + }
  15799. + bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
  15800. + bzero(sc->sc_sessions, sesn * sizeof(*ses));
  15801. + kfree(sc->sc_sessions);
  15802. + sc->sc_sessions = ses;
  15803. + ses = &sc->sc_sessions[sesn];
  15804. + sc->sc_nsessions++;
  15805. + }
  15806. + }
  15807. + HIFN_UNLOCK(sc);
  15808. +
  15809. + bzero(ses, sizeof(*ses));
  15810. + ses->hs_used = 1;
  15811. +
  15812. + for (c = cri; c != NULL; c = c->cri_next) {
  15813. + switch (c->cri_alg) {
  15814. + case CRYPTO_MD5:
  15815. + case CRYPTO_SHA1:
  15816. + case CRYPTO_MD5_HMAC:
  15817. + case CRYPTO_SHA1_HMAC:
  15818. + if (mac) {
  15819. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15820. + return (EINVAL);
  15821. + }
  15822. + mac = 1;
  15823. + ses->hs_mlen = c->cri_mlen;
  15824. + if (ses->hs_mlen == 0) {
  15825. + switch (c->cri_alg) {
  15826. + case CRYPTO_MD5:
  15827. + case CRYPTO_MD5_HMAC:
  15828. + ses->hs_mlen = 16;
  15829. + break;
  15830. + case CRYPTO_SHA1:
  15831. + case CRYPTO_SHA1_HMAC:
  15832. + ses->hs_mlen = 20;
  15833. + break;
  15834. + }
  15835. + }
  15836. + break;
  15837. + case CRYPTO_DES_CBC:
  15838. + case CRYPTO_3DES_CBC:
  15839. + case CRYPTO_AES_CBC:
  15840. + /* XXX this may read fewer, does it matter? */
  15841. + read_random(ses->hs_iv,
  15842. + c->cri_alg == CRYPTO_AES_CBC ?
  15843. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  15844. + /*FALLTHROUGH*/
  15845. + case CRYPTO_ARC4:
  15846. + if (cry) {
  15847. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15848. + return (EINVAL);
  15849. + }
  15850. + cry = 1;
  15851. + break;
  15852. + default:
  15853. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15854. + return (EINVAL);
  15855. + }
  15856. + }
  15857. + if (mac == 0 && cry == 0) {
  15858. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15859. + return (EINVAL);
  15860. + }
  15861. +
  15862. + *sidp = HIFN_SID(device_get_unit(sc->sc_dev), sesn);
  15863. +
  15864. + return (0);
  15865. +}
  15866. +
  15867. +/*
  15868. + * Deallocate a session.
  15869. + * XXX this routine should run a zero'd mac/encrypt key into context ram.
  15870. + * XXX to blow away any keys already stored there.
  15871. + */
  15872. +static int
  15873. +hifn_freesession(device_t dev, u_int64_t tid)
  15874. +{
  15875. + struct hifn_softc *sc = device_get_softc(dev);
  15876. + int session, error;
  15877. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  15878. + unsigned long l_flags;
  15879. +
  15880. + DPRINTF("%s()\n", __FUNCTION__);
  15881. +
  15882. + KASSERT(sc != NULL, ("hifn_freesession: null softc"));
  15883. + if (sc == NULL) {
  15884. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15885. + return (EINVAL);
  15886. + }
  15887. +
  15888. + HIFN_LOCK(sc);
  15889. + session = HIFN_SESSION(sid);
  15890. + if (session < sc->sc_nsessions) {
  15891. + bzero(&sc->sc_sessions[session], sizeof(struct hifn_session));
  15892. + error = 0;
  15893. + } else {
  15894. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15895. + error = EINVAL;
  15896. + }
  15897. + HIFN_UNLOCK(sc);
  15898. +
  15899. + return (error);
  15900. +}
  15901. +
  15902. +static int
  15903. +hifn_process(device_t dev, struct cryptop *crp, int hint)
  15904. +{
  15905. + struct hifn_softc *sc = device_get_softc(dev);
  15906. + struct hifn_command *cmd = NULL;
  15907. + int session, err, ivlen;
  15908. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  15909. +
  15910. + DPRINTF("%s()\n", __FUNCTION__);
  15911. +
  15912. + if (crp == NULL || crp->crp_callback == NULL) {
  15913. + hifnstats.hst_invalid++;
  15914. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15915. + return (EINVAL);
  15916. + }
  15917. + session = HIFN_SESSION(crp->crp_sid);
  15918. +
  15919. + if (sc == NULL || session >= sc->sc_nsessions) {
  15920. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15921. + err = EINVAL;
  15922. + goto errout;
  15923. + }
  15924. +
  15925. + cmd = kmalloc(sizeof(struct hifn_command), SLAB_ATOMIC);
  15926. + if (cmd == NULL) {
  15927. + hifnstats.hst_nomem++;
  15928. + err = ENOMEM;
  15929. + goto errout;
  15930. + }
  15931. + memset(cmd, 0, sizeof(*cmd));
  15932. +
  15933. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  15934. + cmd->src_skb = (struct sk_buff *)crp->crp_buf;
  15935. + cmd->dst_skb = (struct sk_buff *)crp->crp_buf;
  15936. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  15937. + cmd->src_io = (struct uio *)crp->crp_buf;
  15938. + cmd->dst_io = (struct uio *)crp->crp_buf;
  15939. + } else {
  15940. + cmd->src_buf = crp->crp_buf;
  15941. + cmd->dst_buf = crp->crp_buf;
  15942. + }
  15943. +
  15944. + crd1 = crp->crp_desc;
  15945. + if (crd1 == NULL) {
  15946. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15947. + err = EINVAL;
  15948. + goto errout;
  15949. + }
  15950. + crd2 = crd1->crd_next;
  15951. +
  15952. + if (crd2 == NULL) {
  15953. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  15954. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  15955. + crd1->crd_alg == CRYPTO_SHA1 ||
  15956. + crd1->crd_alg == CRYPTO_MD5) {
  15957. + maccrd = crd1;
  15958. + enccrd = NULL;
  15959. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  15960. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  15961. + crd1->crd_alg == CRYPTO_AES_CBC ||
  15962. + crd1->crd_alg == CRYPTO_ARC4) {
  15963. + if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0)
  15964. + cmd->base_masks |= HIFN_BASE_CMD_DECODE;
  15965. + maccrd = NULL;
  15966. + enccrd = crd1;
  15967. + } else {
  15968. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15969. + err = EINVAL;
  15970. + goto errout;
  15971. + }
  15972. + } else {
  15973. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  15974. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  15975. + crd1->crd_alg == CRYPTO_MD5 ||
  15976. + crd1->crd_alg == CRYPTO_SHA1) &&
  15977. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  15978. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  15979. + crd2->crd_alg == CRYPTO_AES_CBC ||
  15980. + crd2->crd_alg == CRYPTO_ARC4) &&
  15981. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  15982. + cmd->base_masks = HIFN_BASE_CMD_DECODE;
  15983. + maccrd = crd1;
  15984. + enccrd = crd2;
  15985. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  15986. + crd1->crd_alg == CRYPTO_ARC4 ||
  15987. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  15988. + crd1->crd_alg == CRYPTO_AES_CBC) &&
  15989. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  15990. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  15991. + crd2->crd_alg == CRYPTO_MD5 ||
  15992. + crd2->crd_alg == CRYPTO_SHA1) &&
  15993. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  15994. + enccrd = crd1;
  15995. + maccrd = crd2;
  15996. + } else {
  15997. + /*
  15998. + * We cannot order the 7751 as requested
  15999. + */
  16000. + DPRINTF("%s,%d: %s %d,%d,%d - EINVAL\n",__FILE__,__LINE__,__FUNCTION__, crd1->crd_alg, crd2->crd_alg, crd1->crd_flags & CRD_F_ENCRYPT);
  16001. + err = EINVAL;
  16002. + goto errout;
  16003. + }
  16004. + }
  16005. +
  16006. + if (enccrd) {
  16007. + cmd->enccrd = enccrd;
  16008. + cmd->base_masks |= HIFN_BASE_CMD_CRYPT;
  16009. + switch (enccrd->crd_alg) {
  16010. + case CRYPTO_ARC4:
  16011. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4;
  16012. + break;
  16013. + case CRYPTO_DES_CBC:
  16014. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES |
  16015. + HIFN_CRYPT_CMD_MODE_CBC |
  16016. + HIFN_CRYPT_CMD_NEW_IV;
  16017. + break;
  16018. + case CRYPTO_3DES_CBC:
  16019. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES |
  16020. + HIFN_CRYPT_CMD_MODE_CBC |
  16021. + HIFN_CRYPT_CMD_NEW_IV;
  16022. + break;
  16023. + case CRYPTO_AES_CBC:
  16024. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES |
  16025. + HIFN_CRYPT_CMD_MODE_CBC |
  16026. + HIFN_CRYPT_CMD_NEW_IV;
  16027. + break;
  16028. + default:
  16029. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16030. + err = EINVAL;
  16031. + goto errout;
  16032. + }
  16033. + if (enccrd->crd_alg != CRYPTO_ARC4) {
  16034. + ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ?
  16035. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  16036. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  16037. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  16038. + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
  16039. + else
  16040. + bcopy(sc->sc_sessions[session].hs_iv,
  16041. + cmd->iv, ivlen);
  16042. +
  16043. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT)
  16044. + == 0) {
  16045. + crypto_copyback(crp->crp_flags,
  16046. + crp->crp_buf, enccrd->crd_inject,
  16047. + ivlen, cmd->iv);
  16048. + }
  16049. + } else {
  16050. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  16051. + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
  16052. + else {
  16053. + crypto_copydata(crp->crp_flags,
  16054. + crp->crp_buf, enccrd->crd_inject,
  16055. + ivlen, cmd->iv);
  16056. + }
  16057. + }
  16058. + }
  16059. +
  16060. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
  16061. + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
  16062. + cmd->ck = enccrd->crd_key;
  16063. + cmd->cklen = enccrd->crd_klen >> 3;
  16064. + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
  16065. +
  16066. + /*
  16067. + * Need to specify the size for the AES key in the masks.
  16068. + */
  16069. + if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) ==
  16070. + HIFN_CRYPT_CMD_ALG_AES) {
  16071. + switch (cmd->cklen) {
  16072. + case 16:
  16073. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128;
  16074. + break;
  16075. + case 24:
  16076. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192;
  16077. + break;
  16078. + case 32:
  16079. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256;
  16080. + break;
  16081. + default:
  16082. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16083. + err = EINVAL;
  16084. + goto errout;
  16085. + }
  16086. + }
  16087. + }
  16088. +
  16089. + if (maccrd) {
  16090. + cmd->maccrd = maccrd;
  16091. + cmd->base_masks |= HIFN_BASE_CMD_MAC;
  16092. +
  16093. + switch (maccrd->crd_alg) {
  16094. + case CRYPTO_MD5:
  16095. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
  16096. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
  16097. + HIFN_MAC_CMD_POS_IPSEC;
  16098. + break;
  16099. + case CRYPTO_MD5_HMAC:
  16100. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
  16101. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
  16102. + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
  16103. + break;
  16104. + case CRYPTO_SHA1:
  16105. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
  16106. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
  16107. + HIFN_MAC_CMD_POS_IPSEC;
  16108. + break;
  16109. + case CRYPTO_SHA1_HMAC:
  16110. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
  16111. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
  16112. + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
  16113. + break;
  16114. + }
  16115. +
  16116. + if (maccrd->crd_alg == CRYPTO_SHA1_HMAC ||
  16117. + maccrd->crd_alg == CRYPTO_MD5_HMAC) {
  16118. + cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY;
  16119. + bcopy(maccrd->crd_key, cmd->mac, maccrd->crd_klen >> 3);
  16120. + bzero(cmd->mac + (maccrd->crd_klen >> 3),
  16121. + HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3));
  16122. + }
  16123. + }
  16124. +
  16125. + cmd->crp = crp;
  16126. + cmd->session_num = session;
  16127. + cmd->softc = sc;
  16128. +
  16129. + err = hifn_crypto(sc, cmd, crp, hint);
  16130. + if (!err) {
  16131. + return 0;
  16132. + } else if (err == ERESTART) {
  16133. + /*
  16134. + * There weren't enough resources to dispatch the request
  16135. + * to the part. Notify the caller so they'll requeue this
  16136. + * request and resubmit it again soon.
  16137. + */
  16138. +#ifdef HIFN_DEBUG
  16139. + if (hifn_debug)
  16140. + device_printf(sc->sc_dev, "requeue request\n");
  16141. +#endif
  16142. + kfree(cmd);
  16143. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  16144. + return (err);
  16145. + }
  16146. +
  16147. +errout:
  16148. + if (cmd != NULL)
  16149. + kfree(cmd);
  16150. + if (err == EINVAL)
  16151. + hifnstats.hst_invalid++;
  16152. + else
  16153. + hifnstats.hst_nomem++;
  16154. + crp->crp_etype = err;
  16155. + crypto_done(crp);
  16156. + return (err);
  16157. +}
  16158. +
  16159. +static void
  16160. +hifn_abort(struct hifn_softc *sc)
  16161. +{
  16162. + struct hifn_dma *dma = sc->sc_dma;
  16163. + struct hifn_command *cmd;
  16164. + struct cryptop *crp;
  16165. + int i, u;
  16166. +
  16167. + DPRINTF("%s()\n", __FUNCTION__);
  16168. +
  16169. + i = dma->resk; u = dma->resu;
  16170. + while (u != 0) {
  16171. + cmd = dma->hifn_commands[i];
  16172. + KASSERT(cmd != NULL, ("hifn_abort: null command slot %u", i));
  16173. + dma->hifn_commands[i] = NULL;
  16174. + crp = cmd->crp;
  16175. +
  16176. + if ((dma->resr[i].l & htole32(HIFN_D_VALID)) == 0) {
  16177. + /* Salvage what we can. */
  16178. + u_int8_t *macbuf;
  16179. +
  16180. + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
  16181. + macbuf = dma->result_bufs[i];
  16182. + macbuf += 12;
  16183. + } else
  16184. + macbuf = NULL;
  16185. + hifnstats.hst_opackets++;
  16186. + hifn_callback(sc, cmd, macbuf);
  16187. + } else {
  16188. +#if 0
  16189. + if (cmd->src_map == cmd->dst_map) {
  16190. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  16191. + BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  16192. + } else {
  16193. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  16194. + BUS_DMASYNC_POSTWRITE);
  16195. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  16196. + BUS_DMASYNC_POSTREAD);
  16197. + }
  16198. +#endif
  16199. +
  16200. + if (cmd->src_skb != cmd->dst_skb) {
  16201. +#ifdef NOTYET
  16202. + m_freem(cmd->src_m);
  16203. + crp->crp_buf = (caddr_t)cmd->dst_m;
  16204. +#else
  16205. + device_printf(sc->sc_dev,
  16206. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  16207. + __FILE__, __LINE__);
  16208. +#endif
  16209. + }
  16210. +
  16211. + /* non-shared buffers cannot be restarted */
  16212. + if (cmd->src_map != cmd->dst_map) {
  16213. + /*
  16214. + * XXX should be EAGAIN, delayed until
  16215. + * after the reset.
  16216. + */
  16217. + crp->crp_etype = ENOMEM;
  16218. + pci_unmap_buf(sc, &cmd->dst);
  16219. + } else
  16220. + crp->crp_etype = ENOMEM;
  16221. +
  16222. + pci_unmap_buf(sc, &cmd->src);
  16223. +
  16224. + kfree(cmd);
  16225. + if (crp->crp_etype != EAGAIN)
  16226. + crypto_done(crp);
  16227. + }
  16228. +
  16229. + if (++i == HIFN_D_RES_RSIZE)
  16230. + i = 0;
  16231. + u--;
  16232. + }
  16233. + dma->resk = i; dma->resu = u;
  16234. +
  16235. + hifn_reset_board(sc, 1);
  16236. + hifn_init_dma(sc);
  16237. + hifn_init_pci_registers(sc);
  16238. +}
  16239. +
  16240. +static void
  16241. +hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)
  16242. +{
  16243. + struct hifn_dma *dma = sc->sc_dma;
  16244. + struct cryptop *crp = cmd->crp;
  16245. + struct cryptodesc *crd;
  16246. + int i, u, ivlen;
  16247. +
  16248. + DPRINTF("%s()\n", __FUNCTION__);
  16249. +
  16250. +#if 0
  16251. + if (cmd->src_map == cmd->dst_map) {
  16252. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  16253. + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
  16254. + } else {
  16255. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  16256. + BUS_DMASYNC_POSTWRITE);
  16257. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  16258. + BUS_DMASYNC_POSTREAD);
  16259. + }
  16260. +#endif
  16261. +
  16262. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  16263. + if (cmd->src_skb != cmd->dst_skb) {
  16264. +#ifdef NOTYET
  16265. + crp->crp_buf = (caddr_t)cmd->dst_m;
  16266. + totlen = cmd->src_mapsize;
  16267. + for (m = cmd->dst_m; m != NULL; m = m->m_next) {
  16268. + if (totlen < m->m_len) {
  16269. + m->m_len = totlen;
  16270. + totlen = 0;
  16271. + } else
  16272. + totlen -= m->m_len;
  16273. + }
  16274. + cmd->dst_m->m_pkthdr.len = cmd->src_m->m_pkthdr.len;
  16275. + m_freem(cmd->src_m);
  16276. +#else
  16277. + device_printf(sc->sc_dev,
  16278. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  16279. + __FILE__, __LINE__);
  16280. +#endif
  16281. + }
  16282. + }
  16283. +
  16284. + if (cmd->sloplen != 0) {
  16285. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  16286. + cmd->src_mapsize - cmd->sloplen, cmd->sloplen,
  16287. + (caddr_t)&dma->slop[cmd->slopidx]);
  16288. + }
  16289. +
  16290. + i = dma->dstk; u = dma->dstu;
  16291. + while (u != 0) {
  16292. + if (i == HIFN_D_DST_RSIZE)
  16293. + i = 0;
  16294. +#if 0
  16295. + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
  16296. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  16297. +#endif
  16298. + if (dma->dstr[i].l & htole32(HIFN_D_VALID)) {
  16299. +#if 0
  16300. + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
  16301. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  16302. +#endif
  16303. + break;
  16304. + }
  16305. + i++, u--;
  16306. + }
  16307. + dma->dstk = i; dma->dstu = u;
  16308. +
  16309. + hifnstats.hst_obytes += cmd->dst_mapsize;
  16310. +
  16311. + if ((cmd->base_masks & (HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE)) ==
  16312. + HIFN_BASE_CMD_CRYPT) {
  16313. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  16314. + if (crd->crd_alg != CRYPTO_DES_CBC &&
  16315. + crd->crd_alg != CRYPTO_3DES_CBC &&
  16316. + crd->crd_alg != CRYPTO_AES_CBC)
  16317. + continue;
  16318. + ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?
  16319. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  16320. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  16321. + crd->crd_skip + crd->crd_len - ivlen, ivlen,
  16322. + cmd->softc->sc_sessions[cmd->session_num].hs_iv);
  16323. + break;
  16324. + }
  16325. + }
  16326. +
  16327. + if (macbuf != NULL) {
  16328. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  16329. + int len;
  16330. +
  16331. + if (crd->crd_alg != CRYPTO_MD5 &&
  16332. + crd->crd_alg != CRYPTO_SHA1 &&
  16333. + crd->crd_alg != CRYPTO_MD5_HMAC &&
  16334. + crd->crd_alg != CRYPTO_SHA1_HMAC) {
  16335. + continue;
  16336. + }
  16337. + len = cmd->softc->sc_sessions[cmd->session_num].hs_mlen;
  16338. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  16339. + crd->crd_inject, len, macbuf);
  16340. + break;
  16341. + }
  16342. + }
  16343. +
  16344. + if (cmd->src_map != cmd->dst_map)
  16345. + pci_unmap_buf(sc, &cmd->dst);
  16346. + pci_unmap_buf(sc, &cmd->src);
  16347. + kfree(cmd);
  16348. + crypto_done(crp);
  16349. +}
  16350. +
  16351. +/*
  16352. + * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0
  16353. + * and Group 1 registers; avoid conditions that could create
  16354. + * burst writes by doing a read in between the writes.
  16355. + *
  16356. + * NB: The read we interpose is always to the same register;
  16357. + * we do this because reading from an arbitrary (e.g. last)
  16358. + * register may not always work.
  16359. + */
  16360. +static void
  16361. +hifn_write_reg_0(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
  16362. +{
  16363. + if (sc->sc_flags & HIFN_IS_7811) {
  16364. + if (sc->sc_bar0_lastreg == reg - 4)
  16365. + readl(sc->sc_bar0 + HIFN_0_PUCNFG);
  16366. + sc->sc_bar0_lastreg = reg;
  16367. + }
  16368. + writel(val, sc->sc_bar0 + reg);
  16369. +}
  16370. +
  16371. +static void
  16372. +hifn_write_reg_1(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
  16373. +{
  16374. + if (sc->sc_flags & HIFN_IS_7811) {
  16375. + if (sc->sc_bar1_lastreg == reg - 4)
  16376. + readl(sc->sc_bar1 + HIFN_1_REVID);
  16377. + sc->sc_bar1_lastreg = reg;
  16378. + }
  16379. + writel(val, sc->sc_bar1 + reg);
  16380. +}
  16381. +
  16382. +
  16383. +static struct pci_device_id hifn_pci_tbl[] = {
  16384. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7951,
  16385. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16386. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955,
  16387. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16388. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956,
  16389. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16390. + { PCI_VENDOR_NETSEC, PCI_PRODUCT_NETSEC_7751,
  16391. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16392. + { PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON,
  16393. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16394. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7811,
  16395. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16396. + /*
  16397. + * Other vendors share this PCI ID as well, such as
  16398. + * http://www.powercrypt.com, and obviously they also
  16399. + * use the same key.
  16400. + */
  16401. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7751,
  16402. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16403. + { 0, 0, 0, 0, 0, 0, }
  16404. +};
  16405. +MODULE_DEVICE_TABLE(pci, hifn_pci_tbl);
  16406. +
  16407. +static struct pci_driver hifn_driver = {
  16408. + .name = "hifn",
  16409. + .id_table = hifn_pci_tbl,
  16410. + .probe = hifn_probe,
  16411. + .remove = hifn_remove,
  16412. + /* add PM stuff here one day */
  16413. +};
  16414. +
  16415. +static int __init hifn_init (void)
  16416. +{
  16417. + struct hifn_softc *sc = NULL;
  16418. + int rc;
  16419. +
  16420. + DPRINTF("%s(%p)\n", __FUNCTION__, hifn_init);
  16421. +
  16422. + rc = pci_register_driver(&hifn_driver);
  16423. + pci_register_driver_compat(&hifn_driver, rc);
  16424. +
  16425. + return rc;
  16426. +}
  16427. +
  16428. +static void __exit hifn_exit (void)
  16429. +{
  16430. + pci_unregister_driver(&hifn_driver);
  16431. +}
  16432. +
  16433. +module_init(hifn_init);
  16434. +module_exit(hifn_exit);
  16435. +
  16436. +MODULE_LICENSE("BSD");
  16437. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  16438. +MODULE_DESCRIPTION("OCF driver for hifn PCI crypto devices");
  16439. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/hifn7751reg.h linux-2.6.39/crypto/ocf/hifn/hifn7751reg.h
  16440. --- linux-2.6.39.orig/crypto/ocf/hifn/hifn7751reg.h 1970-01-01 01:00:00.000000000 +0100
  16441. +++ linux-2.6.39/crypto/ocf/hifn/hifn7751reg.h 2011-07-31 11:31:54.163424609 +0200
  16442. @@ -0,0 +1,540 @@
  16443. +/* $FreeBSD: src/sys/dev/hifn/hifn7751reg.h,v 1.7 2007/03/21 03:42:49 sam Exp $ */
  16444. +/* $OpenBSD: hifn7751reg.h,v 1.35 2002/04/08 17:49:42 jason Exp $ */
  16445. +
  16446. +/*-
  16447. + * Invertex AEON / Hifn 7751 driver
  16448. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  16449. + * Copyright (c) 1999 Theo de Raadt
  16450. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  16451. + * http://www.netsec.net
  16452. + *
  16453. + * Please send any comments, feedback, bug-fixes, or feature requests to
  16454. + * software@invertex.com.
  16455. + *
  16456. + * Redistribution and use in source and binary forms, with or without
  16457. + * modification, are permitted provided that the following conditions
  16458. + * are met:
  16459. + *
  16460. + * 1. Redistributions of source code must retain the above copyright
  16461. + * notice, this list of conditions and the following disclaimer.
  16462. + * 2. Redistributions in binary form must reproduce the above copyright
  16463. + * notice, this list of conditions and the following disclaimer in the
  16464. + * documentation and/or other materials provided with the distribution.
  16465. + * 3. The name of the author may not be used to endorse or promote products
  16466. + * derived from this software without specific prior written permission.
  16467. + *
  16468. + *
  16469. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16470. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16471. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16472. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  16473. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  16474. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  16475. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  16476. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  16477. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  16478. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16479. + *
  16480. + * Effort sponsored in part by the Defense Advanced Research Projects
  16481. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  16482. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  16483. + *
  16484. + */
  16485. +#ifndef __HIFN_H__
  16486. +#define __HIFN_H__
  16487. +
  16488. +/*
  16489. + * Some PCI configuration space offset defines. The names were made
  16490. + * identical to the names used by the Linux kernel.
  16491. + */
  16492. +#define HIFN_BAR0 PCIR_BAR(0) /* PUC register map */
  16493. +#define HIFN_BAR1 PCIR_BAR(1) /* DMA register map */
  16494. +#define HIFN_TRDY_TIMEOUT 0x40
  16495. +#define HIFN_RETRY_TIMEOUT 0x41
  16496. +
  16497. +/*
  16498. + * PCI vendor and device identifiers
  16499. + * (the names are preserved from their OpenBSD source).
  16500. + */
  16501. +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
  16502. +#define PCI_PRODUCT_HIFN_7751 0x0005 /* 7751 */
  16503. +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
  16504. +#define PCI_PRODUCT_HIFN_7811 0x0007 /* 7811 */
  16505. +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
  16506. +#define PCI_PRODUCT_HIFN_7951 0x0012 /* 7951 */
  16507. +#define PCI_PRODUCT_HIFN_7955 0x0020 /* 7954/7955 */
  16508. +#define PCI_PRODUCT_HIFN_7956 0x001d /* 7956 */
  16509. +
  16510. +#define PCI_VENDOR_INVERTEX 0x14e1 /* Invertex */
  16511. +#define PCI_PRODUCT_INVERTEX_AEON 0x0005 /* AEON */
  16512. +
  16513. +#define PCI_VENDOR_NETSEC 0x1660 /* NetSec */
  16514. +#define PCI_PRODUCT_NETSEC_7751 0x7751 /* 7751 */
  16515. +
  16516. +/*
  16517. + * The values below should multiple of 4 -- and be large enough to handle
  16518. + * any command the driver implements.
  16519. + *
  16520. + * MAX_COMMAND = base command + mac command + encrypt command +
  16521. + * mac-key + rc4-key
  16522. + * MAX_RESULT = base result + mac result + mac + encrypt result
  16523. + *
  16524. + *
  16525. + */
  16526. +#define HIFN_MAX_COMMAND (8 + 8 + 8 + 64 + 260)
  16527. +#define HIFN_MAX_RESULT (8 + 4 + 20 + 4)
  16528. +
  16529. +/*
  16530. + * hifn_desc_t
  16531. + *
  16532. + * Holds an individual descriptor for any of the rings.
  16533. + */
  16534. +typedef struct hifn_desc {
  16535. + volatile u_int32_t l; /* length and status bits */
  16536. + volatile u_int32_t p;
  16537. +} hifn_desc_t;
  16538. +
  16539. +/*
  16540. + * Masks for the "length" field of struct hifn_desc.
  16541. + */
  16542. +#define HIFN_D_LENGTH 0x0000ffff /* length bit mask */
  16543. +#define HIFN_D_MASKDONEIRQ 0x02000000 /* mask the done interrupt */
  16544. +#define HIFN_D_DESTOVER 0x04000000 /* destination overflow */
  16545. +#define HIFN_D_OVER 0x08000000 /* overflow */
  16546. +#define HIFN_D_LAST 0x20000000 /* last descriptor in chain */
  16547. +#define HIFN_D_JUMP 0x40000000 /* jump descriptor */
  16548. +#define HIFN_D_VALID 0x80000000 /* valid bit */
  16549. +
  16550. +
  16551. +/*
  16552. + * Processing Unit Registers (offset from BASEREG0)
  16553. + */
  16554. +#define HIFN_0_PUDATA 0x00 /* Processing Unit Data */
  16555. +#define HIFN_0_PUCTRL 0x04 /* Processing Unit Control */
  16556. +#define HIFN_0_PUISR 0x08 /* Processing Unit Interrupt Status */
  16557. +#define HIFN_0_PUCNFG 0x0c /* Processing Unit Configuration */
  16558. +#define HIFN_0_PUIER 0x10 /* Processing Unit Interrupt Enable */
  16559. +#define HIFN_0_PUSTAT 0x14 /* Processing Unit Status/Chip ID */
  16560. +#define HIFN_0_FIFOSTAT 0x18 /* FIFO Status */
  16561. +#define HIFN_0_FIFOCNFG 0x1c /* FIFO Configuration */
  16562. +#define HIFN_0_PUCTRL2 0x28 /* Processing Unit Control (2nd map) */
  16563. +#define HIFN_0_MUTE1 0x80
  16564. +#define HIFN_0_MUTE2 0x90
  16565. +#define HIFN_0_SPACESIZE 0x100 /* Register space size */
  16566. +
  16567. +/* Processing Unit Control Register (HIFN_0_PUCTRL) */
  16568. +#define HIFN_PUCTRL_CLRSRCFIFO 0x0010 /* clear source fifo */
  16569. +#define HIFN_PUCTRL_STOP 0x0008 /* stop pu */
  16570. +#define HIFN_PUCTRL_LOCKRAM 0x0004 /* lock ram */
  16571. +#define HIFN_PUCTRL_DMAENA 0x0002 /* enable dma */
  16572. +#define HIFN_PUCTRL_RESET 0x0001 /* Reset processing unit */
  16573. +
  16574. +/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */
  16575. +#define HIFN_PUISR_CMDINVAL 0x8000 /* Invalid command interrupt */
  16576. +#define HIFN_PUISR_DATAERR 0x4000 /* Data error interrupt */
  16577. +#define HIFN_PUISR_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  16578. +#define HIFN_PUISR_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  16579. +#define HIFN_PUISR_DSTOVER 0x0200 /* Destination overrun interrupt */
  16580. +#define HIFN_PUISR_SRCCMD 0x0080 /* Source command interrupt */
  16581. +#define HIFN_PUISR_SRCCTX 0x0040 /* Source context interrupt */
  16582. +#define HIFN_PUISR_SRCDATA 0x0020 /* Source data interrupt */
  16583. +#define HIFN_PUISR_DSTDATA 0x0010 /* Destination data interrupt */
  16584. +#define HIFN_PUISR_DSTRESULT 0x0004 /* Destination result interrupt */
  16585. +
  16586. +/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */
  16587. +#define HIFN_PUCNFG_DRAMMASK 0xe000 /* DRAM size mask */
  16588. +#define HIFN_PUCNFG_DSZ_256K 0x0000 /* 256k dram */
  16589. +#define HIFN_PUCNFG_DSZ_512K 0x2000 /* 512k dram */
  16590. +#define HIFN_PUCNFG_DSZ_1M 0x4000 /* 1m dram */
  16591. +#define HIFN_PUCNFG_DSZ_2M 0x6000 /* 2m dram */
  16592. +#define HIFN_PUCNFG_DSZ_4M 0x8000 /* 4m dram */
  16593. +#define HIFN_PUCNFG_DSZ_8M 0xa000 /* 8m dram */
  16594. +#define HIFN_PUNCFG_DSZ_16M 0xc000 /* 16m dram */
  16595. +#define HIFN_PUCNFG_DSZ_32M 0xe000 /* 32m dram */
  16596. +#define HIFN_PUCNFG_DRAMREFRESH 0x1800 /* DRAM refresh rate mask */
  16597. +#define HIFN_PUCNFG_DRFR_512 0x0000 /* 512 divisor of ECLK */
  16598. +#define HIFN_PUCNFG_DRFR_256 0x0800 /* 256 divisor of ECLK */
  16599. +#define HIFN_PUCNFG_DRFR_128 0x1000 /* 128 divisor of ECLK */
  16600. +#define HIFN_PUCNFG_TCALLPHASES 0x0200 /* your guess is as good as mine... */
  16601. +#define HIFN_PUCNFG_TCDRVTOTEM 0x0100 /* your guess is as good as mine... */
  16602. +#define HIFN_PUCNFG_BIGENDIAN 0x0080 /* DMA big endian mode */
  16603. +#define HIFN_PUCNFG_BUS32 0x0040 /* Bus width 32bits */
  16604. +#define HIFN_PUCNFG_BUS16 0x0000 /* Bus width 16 bits */
  16605. +#define HIFN_PUCNFG_CHIPID 0x0020 /* Allow chipid from PUSTAT */
  16606. +#define HIFN_PUCNFG_DRAM 0x0010 /* Context RAM is DRAM */
  16607. +#define HIFN_PUCNFG_SRAM 0x0000 /* Context RAM is SRAM */
  16608. +#define HIFN_PUCNFG_COMPSING 0x0004 /* Enable single compression context */
  16609. +#define HIFN_PUCNFG_ENCCNFG 0x0002 /* Encryption configuration */
  16610. +
  16611. +/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */
  16612. +#define HIFN_PUIER_CMDINVAL 0x8000 /* Invalid command interrupt */
  16613. +#define HIFN_PUIER_DATAERR 0x4000 /* Data error interrupt */
  16614. +#define HIFN_PUIER_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  16615. +#define HIFN_PUIER_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  16616. +#define HIFN_PUIER_DSTOVER 0x0200 /* Destination overrun interrupt */
  16617. +#define HIFN_PUIER_SRCCMD 0x0080 /* Source command interrupt */
  16618. +#define HIFN_PUIER_SRCCTX 0x0040 /* Source context interrupt */
  16619. +#define HIFN_PUIER_SRCDATA 0x0020 /* Source data interrupt */
  16620. +#define HIFN_PUIER_DSTDATA 0x0010 /* Destination data interrupt */
  16621. +#define HIFN_PUIER_DSTRESULT 0x0004 /* Destination result interrupt */
  16622. +
  16623. +/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */
  16624. +#define HIFN_PUSTAT_CMDINVAL 0x8000 /* Invalid command interrupt */
  16625. +#define HIFN_PUSTAT_DATAERR 0x4000 /* Data error interrupt */
  16626. +#define HIFN_PUSTAT_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  16627. +#define HIFN_PUSTAT_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  16628. +#define HIFN_PUSTAT_DSTOVER 0x0200 /* Destination overrun interrupt */
  16629. +#define HIFN_PUSTAT_SRCCMD 0x0080 /* Source command interrupt */
  16630. +#define HIFN_PUSTAT_SRCCTX 0x0040 /* Source context interrupt */
  16631. +#define HIFN_PUSTAT_SRCDATA 0x0020 /* Source data interrupt */
  16632. +#define HIFN_PUSTAT_DSTDATA 0x0010 /* Destination data interrupt */
  16633. +#define HIFN_PUSTAT_DSTRESULT 0x0004 /* Destination result interrupt */
  16634. +#define HIFN_PUSTAT_CHIPREV 0x00ff /* Chip revision mask */
  16635. +#define HIFN_PUSTAT_CHIPENA 0xff00 /* Chip enabled mask */
  16636. +#define HIFN_PUSTAT_ENA_2 0x1100 /* Level 2 enabled */
  16637. +#define HIFN_PUSTAT_ENA_1 0x1000 /* Level 1 enabled */
  16638. +#define HIFN_PUSTAT_ENA_0 0x3000 /* Level 0 enabled */
  16639. +#define HIFN_PUSTAT_REV_2 0x0020 /* 7751 PT6/2 */
  16640. +#define HIFN_PUSTAT_REV_3 0x0030 /* 7751 PT6/3 */
  16641. +
  16642. +/* FIFO Status Register (HIFN_0_FIFOSTAT) */
  16643. +#define HIFN_FIFOSTAT_SRC 0x7f00 /* Source FIFO available */
  16644. +#define HIFN_FIFOSTAT_DST 0x007f /* Destination FIFO available */
  16645. +
  16646. +/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */
  16647. +#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as this value */
  16648. +
  16649. +/*
  16650. + * DMA Interface Registers (offset from BASEREG1)
  16651. + */
  16652. +#define HIFN_1_DMA_CRAR 0x0c /* DMA Command Ring Address */
  16653. +#define HIFN_1_DMA_SRAR 0x1c /* DMA Source Ring Address */
  16654. +#define HIFN_1_DMA_RRAR 0x2c /* DMA Result Ring Address */
  16655. +#define HIFN_1_DMA_DRAR 0x3c /* DMA Destination Ring Address */
  16656. +#define HIFN_1_DMA_CSR 0x40 /* DMA Status and Control */
  16657. +#define HIFN_1_DMA_IER 0x44 /* DMA Interrupt Enable */
  16658. +#define HIFN_1_DMA_CNFG 0x48 /* DMA Configuration */
  16659. +#define HIFN_1_PLL 0x4c /* 7955/7956: PLL config */
  16660. +#define HIFN_1_7811_RNGENA 0x60 /* 7811: rng enable */
  16661. +#define HIFN_1_7811_RNGCFG 0x64 /* 7811: rng config */
  16662. +#define HIFN_1_7811_RNGDAT 0x68 /* 7811: rng data */
  16663. +#define HIFN_1_7811_RNGSTS 0x6c /* 7811: rng status */
  16664. +#define HIFN_1_DMA_CNFG2 0x6c /* 7955/7956: dma config #2 */
  16665. +#define HIFN_1_7811_MIPSRST 0x94 /* 7811: MIPS reset */
  16666. +#define HIFN_1_REVID 0x98 /* Revision ID */
  16667. +
  16668. +#define HIFN_1_PUB_RESET 0x204 /* Public/RNG Reset */
  16669. +#define HIFN_1_PUB_BASE 0x300 /* Public Base Address */
  16670. +#define HIFN_1_PUB_OPLEN 0x304 /* 7951-compat Public Operand Length */
  16671. +#define HIFN_1_PUB_OP 0x308 /* 7951-compat Public Operand */
  16672. +#define HIFN_1_PUB_STATUS 0x30c /* 7951-compat Public Status */
  16673. +#define HIFN_1_PUB_IEN 0x310 /* Public Interrupt enable */
  16674. +#define HIFN_1_RNG_CONFIG 0x314 /* RNG config */
  16675. +#define HIFN_1_RNG_DATA 0x318 /* RNG data */
  16676. +#define HIFN_1_PUB_MODE 0x320 /* PK mode */
  16677. +#define HIFN_1_PUB_FIFO_OPLEN 0x380 /* first element of oplen fifo */
  16678. +#define HIFN_1_PUB_FIFO_OP 0x384 /* first element of op fifo */
  16679. +#define HIFN_1_PUB_MEM 0x400 /* start of Public key memory */
  16680. +#define HIFN_1_PUB_MEMEND 0xbff /* end of Public key memory */
  16681. +
  16682. +/* DMA Status and Control Register (HIFN_1_DMA_CSR) */
  16683. +#define HIFN_DMACSR_D_CTRLMASK 0xc0000000 /* Destinition Ring Control */
  16684. +#define HIFN_DMACSR_D_CTRL_NOP 0x00000000 /* Dest. Control: no-op */
  16685. +#define HIFN_DMACSR_D_CTRL_DIS 0x40000000 /* Dest. Control: disable */
  16686. +#define HIFN_DMACSR_D_CTRL_ENA 0x80000000 /* Dest. Control: enable */
  16687. +#define HIFN_DMACSR_D_ABORT 0x20000000 /* Destinition Ring PCIAbort */
  16688. +#define HIFN_DMACSR_D_DONE 0x10000000 /* Destinition Ring Done */
  16689. +#define HIFN_DMACSR_D_LAST 0x08000000 /* Destinition Ring Last */
  16690. +#define HIFN_DMACSR_D_WAIT 0x04000000 /* Destinition Ring Waiting */
  16691. +#define HIFN_DMACSR_D_OVER 0x02000000 /* Destinition Ring Overflow */
  16692. +#define HIFN_DMACSR_R_CTRL 0x00c00000 /* Result Ring Control */
  16693. +#define HIFN_DMACSR_R_CTRL_NOP 0x00000000 /* Result Control: no-op */
  16694. +#define HIFN_DMACSR_R_CTRL_DIS 0x00400000 /* Result Control: disable */
  16695. +#define HIFN_DMACSR_R_CTRL_ENA 0x00800000 /* Result Control: enable */
  16696. +#define HIFN_DMACSR_R_ABORT 0x00200000 /* Result Ring PCI Abort */
  16697. +#define HIFN_DMACSR_R_DONE 0x00100000 /* Result Ring Done */
  16698. +#define HIFN_DMACSR_R_LAST 0x00080000 /* Result Ring Last */
  16699. +#define HIFN_DMACSR_R_WAIT 0x00040000 /* Result Ring Waiting */
  16700. +#define HIFN_DMACSR_R_OVER 0x00020000 /* Result Ring Overflow */
  16701. +#define HIFN_DMACSR_S_CTRL 0x0000c000 /* Source Ring Control */
  16702. +#define HIFN_DMACSR_S_CTRL_NOP 0x00000000 /* Source Control: no-op */
  16703. +#define HIFN_DMACSR_S_CTRL_DIS 0x00004000 /* Source Control: disable */
  16704. +#define HIFN_DMACSR_S_CTRL_ENA 0x00008000 /* Source Control: enable */
  16705. +#define HIFN_DMACSR_S_ABORT 0x00002000 /* Source Ring PCI Abort */
  16706. +#define HIFN_DMACSR_S_DONE 0x00001000 /* Source Ring Done */
  16707. +#define HIFN_DMACSR_S_LAST 0x00000800 /* Source Ring Last */
  16708. +#define HIFN_DMACSR_S_WAIT 0x00000400 /* Source Ring Waiting */
  16709. +#define HIFN_DMACSR_ILLW 0x00000200 /* Illegal write (7811 only) */
  16710. +#define HIFN_DMACSR_ILLR 0x00000100 /* Illegal read (7811 only) */
  16711. +#define HIFN_DMACSR_C_CTRL 0x000000c0 /* Command Ring Control */
  16712. +#define HIFN_DMACSR_C_CTRL_NOP 0x00000000 /* Command Control: no-op */
  16713. +#define HIFN_DMACSR_C_CTRL_DIS 0x00000040 /* Command Control: disable */
  16714. +#define HIFN_DMACSR_C_CTRL_ENA 0x00000080 /* Command Control: enable */
  16715. +#define HIFN_DMACSR_C_ABORT 0x00000020 /* Command Ring PCI Abort */
  16716. +#define HIFN_DMACSR_C_DONE 0x00000010 /* Command Ring Done */
  16717. +#define HIFN_DMACSR_C_LAST 0x00000008 /* Command Ring Last */
  16718. +#define HIFN_DMACSR_C_WAIT 0x00000004 /* Command Ring Waiting */
  16719. +#define HIFN_DMACSR_PUBDONE 0x00000002 /* Public op done (7951 only) */
  16720. +#define HIFN_DMACSR_ENGINE 0x00000001 /* Command Ring Engine IRQ */
  16721. +
  16722. +/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */
  16723. +#define HIFN_DMAIER_D_ABORT 0x20000000 /* Destination Ring PCIAbort */
  16724. +#define HIFN_DMAIER_D_DONE 0x10000000 /* Destination Ring Done */
  16725. +#define HIFN_DMAIER_D_LAST 0x08000000 /* Destination Ring Last */
  16726. +#define HIFN_DMAIER_D_WAIT 0x04000000 /* Destination Ring Waiting */
  16727. +#define HIFN_DMAIER_D_OVER 0x02000000 /* Destination Ring Overflow */
  16728. +#define HIFN_DMAIER_R_ABORT 0x00200000 /* Result Ring PCI Abort */
  16729. +#define HIFN_DMAIER_R_DONE 0x00100000 /* Result Ring Done */
  16730. +#define HIFN_DMAIER_R_LAST 0x00080000 /* Result Ring Last */
  16731. +#define HIFN_DMAIER_R_WAIT 0x00040000 /* Result Ring Waiting */
  16732. +#define HIFN_DMAIER_R_OVER 0x00020000 /* Result Ring Overflow */
  16733. +#define HIFN_DMAIER_S_ABORT 0x00002000 /* Source Ring PCI Abort */
  16734. +#define HIFN_DMAIER_S_DONE 0x00001000 /* Source Ring Done */
  16735. +#define HIFN_DMAIER_S_LAST 0x00000800 /* Source Ring Last */
  16736. +#define HIFN_DMAIER_S_WAIT 0x00000400 /* Source Ring Waiting */
  16737. +#define HIFN_DMAIER_ILLW 0x00000200 /* Illegal write (7811 only) */
  16738. +#define HIFN_DMAIER_ILLR 0x00000100 /* Illegal read (7811 only) */
  16739. +#define HIFN_DMAIER_C_ABORT 0x00000020 /* Command Ring PCI Abort */
  16740. +#define HIFN_DMAIER_C_DONE 0x00000010 /* Command Ring Done */
  16741. +#define HIFN_DMAIER_C_LAST 0x00000008 /* Command Ring Last */
  16742. +#define HIFN_DMAIER_C_WAIT 0x00000004 /* Command Ring Waiting */
  16743. +#define HIFN_DMAIER_PUBDONE 0x00000002 /* public op done (7951 only) */
  16744. +#define HIFN_DMAIER_ENGINE 0x00000001 /* Engine IRQ */
  16745. +
  16746. +/* DMA Configuration Register (HIFN_1_DMA_CNFG) */
  16747. +#define HIFN_DMACNFG_BIGENDIAN 0x10000000 /* big endian mode */
  16748. +#define HIFN_DMACNFG_POLLFREQ 0x00ff0000 /* Poll frequency mask */
  16749. +#define HIFN_DMACNFG_UNLOCK 0x00000800
  16750. +#define HIFN_DMACNFG_POLLINVAL 0x00000700 /* Invalid Poll Scalar */
  16751. +#define HIFN_DMACNFG_LAST 0x00000010 /* Host control LAST bit */
  16752. +#define HIFN_DMACNFG_MODE 0x00000004 /* DMA mode */
  16753. +#define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */
  16754. +#define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */
  16755. +
  16756. +/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */
  16757. +#define HIFN_DMACNFG2_PKSWAP32 (1 << 19) /* swap the OPLEN/OP reg */
  16758. +#define HIFN_DMACNFG2_PKSWAP8 (1 << 18) /* swap the bits of OPLEN/OP */
  16759. +#define HIFN_DMACNFG2_BAR0_SWAP32 (1<<17) /* swap the bytes of BAR0 */
  16760. +#define HIFN_DMACNFG2_BAR1_SWAP8 (1<<16) /* swap the bits of BAR0 */
  16761. +#define HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12
  16762. +#define HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8
  16763. +#define HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4
  16764. +#define HIFN_DMACNFG2_TGT_READ_BURST_SHIFT 0
  16765. +
  16766. +/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */
  16767. +#define HIFN_7811_RNGENA_ENA 0x00000001 /* enable RNG */
  16768. +
  16769. +/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */
  16770. +#define HIFN_7811_RNGCFG_PRE1 0x00000f00 /* first prescalar */
  16771. +#define HIFN_7811_RNGCFG_OPRE 0x00000080 /* output prescalar */
  16772. +#define HIFN_7811_RNGCFG_DEFL 0x00000f80 /* 2 words/ 1/100 sec */
  16773. +
  16774. +/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */
  16775. +#define HIFN_7811_RNGSTS_RDY 0x00004000 /* two numbers in FIFO */
  16776. +#define HIFN_7811_RNGSTS_UFL 0x00001000 /* rng underflow */
  16777. +
  16778. +/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */
  16779. +#define HIFN_MIPSRST_BAR2SIZE 0xffff0000 /* sdram size */
  16780. +#define HIFN_MIPSRST_GPRAMINIT 0x00008000 /* gpram can be accessed */
  16781. +#define HIFN_MIPSRST_CRAMINIT 0x00004000 /* ctxram can be accessed */
  16782. +#define HIFN_MIPSRST_LED2 0x00000400 /* external LED2 */
  16783. +#define HIFN_MIPSRST_LED1 0x00000200 /* external LED1 */
  16784. +#define HIFN_MIPSRST_LED0 0x00000100 /* external LED0 */
  16785. +#define HIFN_MIPSRST_MIPSDIS 0x00000004 /* disable MIPS */
  16786. +#define HIFN_MIPSRST_MIPSRST 0x00000002 /* warm reset MIPS */
  16787. +#define HIFN_MIPSRST_MIPSCOLD 0x00000001 /* cold reset MIPS */
  16788. +
  16789. +/* Public key reset register (HIFN_1_PUB_RESET) */
  16790. +#define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */
  16791. +
  16792. +/* Public operation register (HIFN_1_PUB_OP) */
  16793. +#define HIFN_PUBOP_AOFFSET 0x0000003e /* A offset */
  16794. +#define HIFN_PUBOP_BOFFSET 0x00000fc0 /* B offset */
  16795. +#define HIFN_PUBOP_MOFFSET 0x0003f000 /* M offset */
  16796. +#define HIFN_PUBOP_OP_MASK 0x003c0000 /* Opcode: */
  16797. +#define HIFN_PUBOP_OP_NOP 0x00000000 /* NOP */
  16798. +#define HIFN_PUBOP_OP_ADD 0x00040000 /* ADD */
  16799. +#define HIFN_PUBOP_OP_ADDC 0x00080000 /* ADD w/carry */
  16800. +#define HIFN_PUBOP_OP_SUB 0x000c0000 /* SUB */
  16801. +#define HIFN_PUBOP_OP_SUBC 0x00100000 /* SUB w/carry */
  16802. +#define HIFN_PUBOP_OP_MODADD 0x00140000 /* Modular ADD */
  16803. +#define HIFN_PUBOP_OP_MODSUB 0x00180000 /* Modular SUB */
  16804. +#define HIFN_PUBOP_OP_INCA 0x001c0000 /* INC A */
  16805. +#define HIFN_PUBOP_OP_DECA 0x00200000 /* DEC A */
  16806. +#define HIFN_PUBOP_OP_MULT 0x00240000 /* MULT */
  16807. +#define HIFN_PUBOP_OP_MODMULT 0x00280000 /* Modular MULT */
  16808. +#define HIFN_PUBOP_OP_MODRED 0x002c0000 /* Modular Red */
  16809. +#define HIFN_PUBOP_OP_MODEXP 0x00300000 /* Modular Exp */
  16810. +
  16811. +/* Public operand length register (HIFN_1_PUB_OPLEN) */
  16812. +#define HIFN_PUBOPLEN_MODLEN 0x0000007f
  16813. +#define HIFN_PUBOPLEN_EXPLEN 0x0003ff80
  16814. +#define HIFN_PUBOPLEN_REDLEN 0x003c0000
  16815. +
  16816. +/* Public status register (HIFN_1_PUB_STATUS) */
  16817. +#define HIFN_PUBSTS_DONE 0x00000001 /* operation done */
  16818. +#define HIFN_PUBSTS_CARRY 0x00000002 /* carry */
  16819. +#define HIFN_PUBSTS_FIFO_EMPTY 0x00000100 /* fifo empty */
  16820. +#define HIFN_PUBSTS_FIFO_FULL 0x00000200 /* fifo full */
  16821. +#define HIFN_PUBSTS_FIFO_OVFL 0x00000400 /* fifo overflow */
  16822. +#define HIFN_PUBSTS_FIFO_WRITE 0x000f0000 /* fifo write */
  16823. +#define HIFN_PUBSTS_FIFO_READ 0x0f000000 /* fifo read */
  16824. +
  16825. +/* Public interrupt enable register (HIFN_1_PUB_IEN) */
  16826. +#define HIFN_PUBIEN_DONE 0x00000001 /* operation done interrupt */
  16827. +
  16828. +/* Random number generator config register (HIFN_1_RNG_CONFIG) */
  16829. +#define HIFN_RNGCFG_ENA 0x00000001 /* enable rng */
  16830. +
  16831. +/*
  16832. + * Register offsets in register set 1
  16833. + */
  16834. +
  16835. +#define HIFN_UNLOCK_SECRET1 0xf4
  16836. +#define HIFN_UNLOCK_SECRET2 0xfc
  16837. +
  16838. +/*
  16839. + * PLL config register
  16840. + *
  16841. + * This register is present only on 7954/7955/7956 parts. It must be
  16842. + * programmed according to the bus interface method used by the h/w.
  16843. + * Note that the parts require a stable clock. Since the PCI clock
  16844. + * may vary the reference clock must usually be used. To avoid
  16845. + * overclocking the core logic, setup must be done carefully, refer
  16846. + * to the driver for details. The exact multiplier required varies
  16847. + * by part and system configuration; refer to the Hifn documentation.
  16848. + */
  16849. +#define HIFN_PLL_REF_SEL 0x00000001 /* REF/HBI clk selection */
  16850. +#define HIFN_PLL_BP 0x00000002 /* bypass (used during setup) */
  16851. +/* bit 2 reserved */
  16852. +#define HIFN_PLL_PK_CLK_SEL 0x00000008 /* public key clk select */
  16853. +#define HIFN_PLL_PE_CLK_SEL 0x00000010 /* packet engine clk select */
  16854. +/* bits 5-9 reserved */
  16855. +#define HIFN_PLL_MBSET 0x00000400 /* must be set to 1 */
  16856. +#define HIFN_PLL_ND 0x00003800 /* Fpll_ref multiplier select */
  16857. +#define HIFN_PLL_ND_SHIFT 11
  16858. +#define HIFN_PLL_ND_2 0x00000000 /* 2x */
  16859. +#define HIFN_PLL_ND_4 0x00000800 /* 4x */
  16860. +#define HIFN_PLL_ND_6 0x00001000 /* 6x */
  16861. +#define HIFN_PLL_ND_8 0x00001800 /* 8x */
  16862. +#define HIFN_PLL_ND_10 0x00002000 /* 10x */
  16863. +#define HIFN_PLL_ND_12 0x00002800 /* 12x */
  16864. +/* bits 14-15 reserved */
  16865. +#define HIFN_PLL_IS 0x00010000 /* charge pump current select */
  16866. +/* bits 17-31 reserved */
  16867. +
  16868. +/*
  16869. + * Board configuration specifies only these bits.
  16870. + */
  16871. +#define HIFN_PLL_CONFIG (HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL)
  16872. +
  16873. +/*
  16874. + * Public Key Engine Mode Register
  16875. + */
  16876. +#define HIFN_PKMODE_HOSTINVERT (1 << 0) /* HOST INVERT */
  16877. +#define HIFN_PKMODE_ENHANCED (1 << 1) /* Enable enhanced mode */
  16878. +
  16879. +
  16880. +/*********************************************************************
  16881. + * Structs for board commands
  16882. + *
  16883. + *********************************************************************/
  16884. +
  16885. +/*
  16886. + * Structure to help build up the command data structure.
  16887. + */
  16888. +typedef struct hifn_base_command {
  16889. + volatile u_int16_t masks;
  16890. + volatile u_int16_t session_num;
  16891. + volatile u_int16_t total_source_count;
  16892. + volatile u_int16_t total_dest_count;
  16893. +} hifn_base_command_t;
  16894. +
  16895. +#define HIFN_BASE_CMD_MAC 0x0400
  16896. +#define HIFN_BASE_CMD_CRYPT 0x0800
  16897. +#define HIFN_BASE_CMD_DECODE 0x2000
  16898. +#define HIFN_BASE_CMD_SRCLEN_M 0xc000
  16899. +#define HIFN_BASE_CMD_SRCLEN_S 14
  16900. +#define HIFN_BASE_CMD_DSTLEN_M 0x3000
  16901. +#define HIFN_BASE_CMD_DSTLEN_S 12
  16902. +#define HIFN_BASE_CMD_LENMASK_HI 0x30000
  16903. +#define HIFN_BASE_CMD_LENMASK_LO 0x0ffff
  16904. +
  16905. +/*
  16906. + * Structure to help build up the command data structure.
  16907. + */
  16908. +typedef struct hifn_crypt_command {
  16909. + volatile u_int16_t masks;
  16910. + volatile u_int16_t header_skip;
  16911. + volatile u_int16_t source_count;
  16912. + volatile u_int16_t reserved;
  16913. +} hifn_crypt_command_t;
  16914. +
  16915. +#define HIFN_CRYPT_CMD_ALG_MASK 0x0003 /* algorithm: */
  16916. +#define HIFN_CRYPT_CMD_ALG_DES 0x0000 /* DES */
  16917. +#define HIFN_CRYPT_CMD_ALG_3DES 0x0001 /* 3DES */
  16918. +#define HIFN_CRYPT_CMD_ALG_RC4 0x0002 /* RC4 */
  16919. +#define HIFN_CRYPT_CMD_ALG_AES 0x0003 /* AES */
  16920. +#define HIFN_CRYPT_CMD_MODE_MASK 0x0018 /* Encrypt mode: */
  16921. +#define HIFN_CRYPT_CMD_MODE_ECB 0x0000 /* ECB */
  16922. +#define HIFN_CRYPT_CMD_MODE_CBC 0x0008 /* CBC */
  16923. +#define HIFN_CRYPT_CMD_MODE_CFB 0x0010 /* CFB */
  16924. +#define HIFN_CRYPT_CMD_MODE_OFB 0x0018 /* OFB */
  16925. +#define HIFN_CRYPT_CMD_CLR_CTX 0x0040 /* clear context */
  16926. +#define HIFN_CRYPT_CMD_NEW_KEY 0x0800 /* expect new key */
  16927. +#define HIFN_CRYPT_CMD_NEW_IV 0x1000 /* expect new iv */
  16928. +
  16929. +#define HIFN_CRYPT_CMD_SRCLEN_M 0xc000
  16930. +#define HIFN_CRYPT_CMD_SRCLEN_S 14
  16931. +
  16932. +#define HIFN_CRYPT_CMD_KSZ_MASK 0x0600 /* AES key size: */
  16933. +#define HIFN_CRYPT_CMD_KSZ_128 0x0000 /* 128 bit */
  16934. +#define HIFN_CRYPT_CMD_KSZ_192 0x0200 /* 192 bit */
  16935. +#define HIFN_CRYPT_CMD_KSZ_256 0x0400 /* 256 bit */
  16936. +
  16937. +/*
  16938. + * Structure to help build up the command data structure.
  16939. + */
  16940. +typedef struct hifn_mac_command {
  16941. + volatile u_int16_t masks;
  16942. + volatile u_int16_t header_skip;
  16943. + volatile u_int16_t source_count;
  16944. + volatile u_int16_t reserved;
  16945. +} hifn_mac_command_t;
  16946. +
  16947. +#define HIFN_MAC_CMD_ALG_MASK 0x0001
  16948. +#define HIFN_MAC_CMD_ALG_SHA1 0x0000
  16949. +#define HIFN_MAC_CMD_ALG_MD5 0x0001
  16950. +#define HIFN_MAC_CMD_MODE_MASK 0x000c
  16951. +#define HIFN_MAC_CMD_MODE_HMAC 0x0000
  16952. +#define HIFN_MAC_CMD_MODE_SSL_MAC 0x0004
  16953. +#define HIFN_MAC_CMD_MODE_HASH 0x0008
  16954. +#define HIFN_MAC_CMD_MODE_FULL 0x0004
  16955. +#define HIFN_MAC_CMD_TRUNC 0x0010
  16956. +#define HIFN_MAC_CMD_RESULT 0x0020
  16957. +#define HIFN_MAC_CMD_APPEND 0x0040
  16958. +#define HIFN_MAC_CMD_SRCLEN_M 0xc000
  16959. +#define HIFN_MAC_CMD_SRCLEN_S 14
  16960. +
  16961. +/*
  16962. + * MAC POS IPsec initiates authentication after encryption on encodes
  16963. + * and before decryption on decodes.
  16964. + */
  16965. +#define HIFN_MAC_CMD_POS_IPSEC 0x0200
  16966. +#define HIFN_MAC_CMD_NEW_KEY 0x0800
  16967. +
  16968. +/*
  16969. + * The poll frequency and poll scalar defines are unshifted values used
  16970. + * to set fields in the DMA Configuration Register.
  16971. + */
  16972. +#ifndef HIFN_POLL_FREQUENCY
  16973. +#define HIFN_POLL_FREQUENCY 0x1
  16974. +#endif
  16975. +
  16976. +#ifndef HIFN_POLL_SCALAR
  16977. +#define HIFN_POLL_SCALAR 0x0
  16978. +#endif
  16979. +
  16980. +#define HIFN_MAX_SEGLEN 0xffff /* maximum dma segment len */
  16981. +#define HIFN_MAX_DMALEN 0x3ffff /* maximum dma length */
  16982. +#endif /* __HIFN_H__ */
  16983. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/hifn7751var.h linux-2.6.39/crypto/ocf/hifn/hifn7751var.h
  16984. --- linux-2.6.39.orig/crypto/ocf/hifn/hifn7751var.h 1970-01-01 01:00:00.000000000 +0100
  16985. +++ linux-2.6.39/crypto/ocf/hifn/hifn7751var.h 2011-07-31 11:31:54.233424983 +0200
  16986. @@ -0,0 +1,369 @@
  16987. +/* $FreeBSD: src/sys/dev/hifn/hifn7751var.h,v 1.9 2007/03/21 03:42:49 sam Exp $ */
  16988. +/* $OpenBSD: hifn7751var.h,v 1.42 2002/04/08 17:49:42 jason Exp $ */
  16989. +
  16990. +/*-
  16991. + * Invertex AEON / Hifn 7751 driver
  16992. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  16993. + * Copyright (c) 1999 Theo de Raadt
  16994. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  16995. + * http://www.netsec.net
  16996. + *
  16997. + * Please send any comments, feedback, bug-fixes, or feature requests to
  16998. + * software@invertex.com.
  16999. + *
  17000. + * Redistribution and use in source and binary forms, with or without
  17001. + * modification, are permitted provided that the following conditions
  17002. + * are met:
  17003. + *
  17004. + * 1. Redistributions of source code must retain the above copyright
  17005. + * notice, this list of conditions and the following disclaimer.
  17006. + * 2. Redistributions in binary form must reproduce the above copyright
  17007. + * notice, this list of conditions and the following disclaimer in the
  17008. + * documentation and/or other materials provided with the distribution.
  17009. + * 3. The name of the author may not be used to endorse or promote products
  17010. + * derived from this software without specific prior written permission.
  17011. + *
  17012. + *
  17013. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17014. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17015. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17016. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  17017. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  17018. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  17019. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  17020. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  17021. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  17022. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17023. + *
  17024. + * Effort sponsored in part by the Defense Advanced Research Projects
  17025. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  17026. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  17027. + *
  17028. + */
  17029. +
  17030. +#ifndef __HIFN7751VAR_H__
  17031. +#define __HIFN7751VAR_H__
  17032. +
  17033. +#ifdef __KERNEL__
  17034. +
  17035. +/*
  17036. + * Some configurable values for the driver. By default command+result
  17037. + * descriptor rings are the same size. The src+dst descriptor rings
  17038. + * are sized at 3.5x the number of potential commands. Slower parts
  17039. + * (e.g. 7951) tend to run out of src descriptors; faster parts (7811)
  17040. + * src+cmd/result descriptors. It's not clear that increasing the size
  17041. + * of the descriptor rings helps performance significantly as other
  17042. + * factors tend to come into play (e.g. copying misaligned packets).
  17043. + */
  17044. +#define HIFN_D_CMD_RSIZE 24 /* command descriptors */
  17045. +#define HIFN_D_SRC_RSIZE ((HIFN_D_CMD_RSIZE * 7) / 2) /* source descriptors */
  17046. +#define HIFN_D_RES_RSIZE HIFN_D_CMD_RSIZE /* result descriptors */
  17047. +#define HIFN_D_DST_RSIZE HIFN_D_SRC_RSIZE /* destination descriptors */
  17048. +
  17049. +/*
  17050. + * Length values for cryptography
  17051. + */
  17052. +#define HIFN_DES_KEY_LENGTH 8
  17053. +#define HIFN_3DES_KEY_LENGTH 24
  17054. +#define HIFN_MAX_CRYPT_KEY_LENGTH HIFN_3DES_KEY_LENGTH
  17055. +#define HIFN_IV_LENGTH 8
  17056. +#define HIFN_AES_IV_LENGTH 16
  17057. +#define HIFN_MAX_IV_LENGTH HIFN_AES_IV_LENGTH
  17058. +
  17059. +/*
  17060. + * Length values for authentication
  17061. + */
  17062. +#define HIFN_MAC_KEY_LENGTH 64
  17063. +#define HIFN_MD5_LENGTH 16
  17064. +#define HIFN_SHA1_LENGTH 20
  17065. +#define HIFN_MAC_TRUNC_LENGTH 12
  17066. +
  17067. +#define MAX_SCATTER 64
  17068. +
  17069. +/*
  17070. + * Data structure to hold all 4 rings and any other ring related data.
  17071. + */
  17072. +struct hifn_dma {
  17073. + /*
  17074. + * Descriptor rings. We add +1 to the size to accomidate the
  17075. + * jump descriptor.
  17076. + */
  17077. + struct hifn_desc cmdr[HIFN_D_CMD_RSIZE+1];
  17078. + struct hifn_desc srcr[HIFN_D_SRC_RSIZE+1];
  17079. + struct hifn_desc dstr[HIFN_D_DST_RSIZE+1];
  17080. + struct hifn_desc resr[HIFN_D_RES_RSIZE+1];
  17081. +
  17082. + struct hifn_command *hifn_commands[HIFN_D_RES_RSIZE];
  17083. +
  17084. + u_char command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];
  17085. + u_char result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];
  17086. + u_int32_t slop[HIFN_D_CMD_RSIZE];
  17087. +
  17088. + u_int64_t test_src, test_dst;
  17089. +
  17090. + /*
  17091. + * Our current positions for insertion and removal from the desriptor
  17092. + * rings.
  17093. + */
  17094. + int cmdi, srci, dsti, resi;
  17095. + volatile int cmdu, srcu, dstu, resu;
  17096. + int cmdk, srck, dstk, resk;
  17097. +};
  17098. +
  17099. +struct hifn_session {
  17100. + int hs_used;
  17101. + int hs_mlen;
  17102. + u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
  17103. +};
  17104. +
  17105. +#define HIFN_RING_SYNC(sc, r, i, f) \
  17106. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  17107. +
  17108. +#define HIFN_CMDR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), cmdr, (i), (f))
  17109. +#define HIFN_RESR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), resr, (i), (f))
  17110. +#define HIFN_SRCR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), srcr, (i), (f))
  17111. +#define HIFN_DSTR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), dstr, (i), (f))
  17112. +
  17113. +#define HIFN_CMD_SYNC(sc, i, f) \
  17114. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  17115. +
  17116. +#define HIFN_RES_SYNC(sc, i, f) \
  17117. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  17118. +
  17119. +typedef int bus_size_t;
  17120. +
  17121. +/*
  17122. + * Holds data specific to a single HIFN board.
  17123. + */
  17124. +struct hifn_softc {
  17125. + softc_device_decl sc_dev;
  17126. +
  17127. + struct pci_dev *sc_pcidev; /* PCI device pointer */
  17128. + spinlock_t sc_mtx; /* per-instance lock */
  17129. +
  17130. + int sc_num; /* for multiple devs */
  17131. +
  17132. + ocf_iomem_t sc_bar0;
  17133. + bus_size_t sc_bar0_lastreg;/* bar0 last reg written */
  17134. + ocf_iomem_t sc_bar1;
  17135. + bus_size_t sc_bar1_lastreg;/* bar1 last reg written */
  17136. +
  17137. + int sc_irq;
  17138. +
  17139. + u_int32_t sc_dmaier;
  17140. + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
  17141. + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
  17142. +
  17143. + struct hifn_dma *sc_dma;
  17144. + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
  17145. +
  17146. + int sc_dmansegs;
  17147. + int32_t sc_cid;
  17148. + int sc_maxses;
  17149. + int sc_nsessions;
  17150. + struct hifn_session *sc_sessions;
  17151. + int sc_ramsize;
  17152. + int sc_flags;
  17153. +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
  17154. +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
  17155. +#define HIFN_HAS_AES 0x4 /* includes AES support */
  17156. +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
  17157. +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
  17158. +
  17159. + struct timer_list sc_tickto; /* for managing DMA */
  17160. +
  17161. + int sc_rngfirst;
  17162. + int sc_rnghz; /* RNG polling frequency */
  17163. +
  17164. + int sc_c_busy; /* command ring busy */
  17165. + int sc_s_busy; /* source data ring busy */
  17166. + int sc_d_busy; /* destination data ring busy */
  17167. + int sc_r_busy; /* result ring busy */
  17168. + int sc_active; /* for initial countdown */
  17169. + int sc_needwakeup; /* ops q'd wating on resources */
  17170. + int sc_curbatch; /* # ops submitted w/o int */
  17171. + int sc_suspended;
  17172. +#ifdef HIFN_VULCANDEV
  17173. + struct cdev *sc_pkdev;
  17174. +#endif
  17175. +};
  17176. +
  17177. +#define HIFN_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
  17178. +#define HIFN_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
  17179. +
  17180. +/*
  17181. + * hifn_command_t
  17182. + *
  17183. + * This is the control structure used to pass commands to hifn_encrypt().
  17184. + *
  17185. + * flags
  17186. + * -----
  17187. + * Flags is the bitwise "or" values for command configuration. A single
  17188. + * encrypt direction needs to be set:
  17189. + *
  17190. + * HIFN_ENCODE or HIFN_DECODE
  17191. + *
  17192. + * To use cryptography, a single crypto algorithm must be included:
  17193. + *
  17194. + * HIFN_CRYPT_3DES or HIFN_CRYPT_DES
  17195. + *
  17196. + * To use authentication is used, a single MAC algorithm must be included:
  17197. + *
  17198. + * HIFN_MAC_MD5 or HIFN_MAC_SHA1
  17199. + *
  17200. + * By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash.
  17201. + * If the value below is set, hash values are truncated or assumed
  17202. + * truncated to 12 bytes:
  17203. + *
  17204. + * HIFN_MAC_TRUNC
  17205. + *
  17206. + * Keys for encryption and authentication can be sent as part of a command,
  17207. + * or the last key value used with a particular session can be retrieved
  17208. + * and used again if either of these flags are not specified.
  17209. + *
  17210. + * HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY
  17211. + *
  17212. + * session_num
  17213. + * -----------
  17214. + * A number between 0 and 2048 (for DRAM models) or a number between
  17215. + * 0 and 768 (for SRAM models). Those who don't want to use session
  17216. + * numbers should leave value at zero and send a new crypt key and/or
  17217. + * new MAC key on every command. If you use session numbers and
  17218. + * don't send a key with a command, the last key sent for that same
  17219. + * session number will be used.
  17220. + *
  17221. + * Warning: Using session numbers and multiboard at the same time
  17222. + * is currently broken.
  17223. + *
  17224. + * mbuf
  17225. + * ----
  17226. + * Either fill in the mbuf pointer and npa=0 or
  17227. + * fill packp[] and packl[] and set npa to > 0
  17228. + *
  17229. + * mac_header_skip
  17230. + * ---------------
  17231. + * The number of bytes of the source_buf that are skipped over before
  17232. + * authentication begins. This must be a number between 0 and 2^16-1
  17233. + * and can be used by IPsec implementers to skip over IP headers.
  17234. + * *** Value ignored if authentication not used ***
  17235. + *
  17236. + * crypt_header_skip
  17237. + * -----------------
  17238. + * The number of bytes of the source_buf that are skipped over before
  17239. + * the cryptographic operation begins. This must be a number between 0
  17240. + * and 2^16-1. For IPsec, this number will always be 8 bytes larger
  17241. + * than the auth_header_skip (to skip over the ESP header).
  17242. + * *** Value ignored if cryptography not used ***
  17243. + *
  17244. + */
  17245. +struct hifn_operand {
  17246. + union {
  17247. + struct sk_buff *skb;
  17248. + struct uio *io;
  17249. + unsigned char *buf;
  17250. + } u;
  17251. + void *map;
  17252. + bus_size_t mapsize;
  17253. + int nsegs;
  17254. + struct {
  17255. + dma_addr_t ds_addr;
  17256. + int ds_len;
  17257. + } segs[MAX_SCATTER];
  17258. +};
  17259. +
  17260. +struct hifn_command {
  17261. + u_int16_t session_num;
  17262. + u_int16_t base_masks, cry_masks, mac_masks;
  17263. + u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];
  17264. + int cklen;
  17265. + int sloplen, slopidx;
  17266. +
  17267. + struct hifn_operand src;
  17268. + struct hifn_operand dst;
  17269. +
  17270. + struct hifn_softc *softc;
  17271. + struct cryptop *crp;
  17272. + struct cryptodesc *enccrd, *maccrd;
  17273. +};
  17274. +
  17275. +#define src_skb src.u.skb
  17276. +#define src_io src.u.io
  17277. +#define src_map src.map
  17278. +#define src_mapsize src.mapsize
  17279. +#define src_segs src.segs
  17280. +#define src_nsegs src.nsegs
  17281. +#define src_buf src.u.buf
  17282. +
  17283. +#define dst_skb dst.u.skb
  17284. +#define dst_io dst.u.io
  17285. +#define dst_map dst.map
  17286. +#define dst_mapsize dst.mapsize
  17287. +#define dst_segs dst.segs
  17288. +#define dst_nsegs dst.nsegs
  17289. +#define dst_buf dst.u.buf
  17290. +
  17291. +/*
  17292. + * Return values for hifn_crypto()
  17293. + */
  17294. +#define HIFN_CRYPTO_SUCCESS 0
  17295. +#define HIFN_CRYPTO_BAD_INPUT (-1)
  17296. +#define HIFN_CRYPTO_RINGS_FULL (-2)
  17297. +
  17298. +/**************************************************************************
  17299. + *
  17300. + * Function: hifn_crypto
  17301. + *
  17302. + * Purpose: Called by external drivers to begin an encryption on the
  17303. + * HIFN board.
  17304. + *
  17305. + * Blocking/Non-blocking Issues
  17306. + * ============================
  17307. + * The driver cannot block in hifn_crypto (no calls to tsleep) currently.
  17308. + * hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough
  17309. + * room in any of the rings for the request to proceed.
  17310. + *
  17311. + * Return Values
  17312. + * =============
  17313. + * 0 for success, negative values on error
  17314. + *
  17315. + * Defines for negative error codes are:
  17316. + *
  17317. + * HIFN_CRYPTO_BAD_INPUT : The passed in command had invalid settings.
  17318. + * HIFN_CRYPTO_RINGS_FULL : All DMA rings were full and non-blocking
  17319. + * behaviour was requested.
  17320. + *
  17321. + *************************************************************************/
  17322. +
  17323. +/*
  17324. + * Convert back and forth from 'sid' to 'card' and 'session'
  17325. + */
  17326. +#define HIFN_CARD(sid) (((sid) & 0xf0000000) >> 28)
  17327. +#define HIFN_SESSION(sid) ((sid) & 0x000007ff)
  17328. +#define HIFN_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
  17329. +
  17330. +#endif /* _KERNEL */
  17331. +
  17332. +struct hifn_stats {
  17333. + u_int64_t hst_ibytes;
  17334. + u_int64_t hst_obytes;
  17335. + u_int32_t hst_ipackets;
  17336. + u_int32_t hst_opackets;
  17337. + u_int32_t hst_invalid;
  17338. + u_int32_t hst_nomem; /* malloc or one of hst_nomem_* */
  17339. + u_int32_t hst_abort;
  17340. + u_int32_t hst_noirq; /* IRQ for no reason */
  17341. + u_int32_t hst_totbatch; /* ops submitted w/o interrupt */
  17342. + u_int32_t hst_maxbatch; /* max ops submitted together */
  17343. + u_int32_t hst_unaligned; /* unaligned src caused copy */
  17344. + /*
  17345. + * The following divides hst_nomem into more specific buckets.
  17346. + */
  17347. + u_int32_t hst_nomem_map; /* bus_dmamap_create failed */
  17348. + u_int32_t hst_nomem_load; /* bus_dmamap_load_* failed */
  17349. + u_int32_t hst_nomem_mbuf; /* MGET* failed */
  17350. + u_int32_t hst_nomem_mcl; /* MCLGET* failed */
  17351. + u_int32_t hst_nomem_cr; /* out of command/result descriptor */
  17352. + u_int32_t hst_nomem_sd; /* out of src/dst descriptors */
  17353. +};
  17354. +
  17355. +#endif /* __HIFN7751VAR_H__ */
  17356. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/hifnHIPP.c linux-2.6.39/crypto/ocf/hifn/hifnHIPP.c
  17357. --- linux-2.6.39.orig/crypto/ocf/hifn/hifnHIPP.c 1970-01-01 01:00:00.000000000 +0100
  17358. +++ linux-2.6.39/crypto/ocf/hifn/hifnHIPP.c 2011-07-31 11:31:54.313421813 +0200
  17359. @@ -0,0 +1,420 @@
  17360. +/*-
  17361. + * Driver for Hifn HIPP-I/II chipset
  17362. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
  17363. + *
  17364. + * Redistribution and use in source and binary forms, with or without
  17365. + * modification, are permitted provided that the following conditions
  17366. + * are met:
  17367. + *
  17368. + * 1. Redistributions of source code must retain the above copyright
  17369. + * notice, this list of conditions and the following disclaimer.
  17370. + * 2. Redistributions in binary form must reproduce the above copyright
  17371. + * notice, this list of conditions and the following disclaimer in the
  17372. + * documentation and/or other materials provided with the distribution.
  17373. + * 3. The name of the author may not be used to endorse or promote products
  17374. + * derived from this software without specific prior written permission.
  17375. + *
  17376. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17377. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17378. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17379. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  17380. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  17381. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  17382. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  17383. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  17384. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  17385. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17386. + *
  17387. + * Effort sponsored by Hifn Inc.
  17388. + *
  17389. + */
  17390. +
  17391. +/*
  17392. + * Driver for various Hifn encryption processors.
  17393. + */
  17394. +#ifndef AUTOCONF_INCLUDED
  17395. +#include <linux/config.h>
  17396. +#endif
  17397. +#include <linux/module.h>
  17398. +#include <linux/init.h>
  17399. +#include <linux/list.h>
  17400. +#include <linux/slab.h>
  17401. +#include <linux/wait.h>
  17402. +#include <linux/sched.h>
  17403. +#include <linux/pci.h>
  17404. +#include <linux/delay.h>
  17405. +#include <linux/interrupt.h>
  17406. +#include <linux/spinlock.h>
  17407. +#include <linux/random.h>
  17408. +#include <linux/version.h>
  17409. +#include <linux/skbuff.h>
  17410. +#include <linux/uio.h>
  17411. +#include <linux/sysfs.h>
  17412. +#include <linux/miscdevice.h>
  17413. +#include <asm/io.h>
  17414. +
  17415. +#include <cryptodev.h>
  17416. +
  17417. +#include "hifnHIPPreg.h"
  17418. +#include "hifnHIPPvar.h"
  17419. +
  17420. +#if 1
  17421. +#define DPRINTF(a...) if (hipp_debug) { \
  17422. + printk("%s: ", sc ? \
  17423. + device_get_nameunit(sc->sc_dev) : "hifn"); \
  17424. + printk(a); \
  17425. + } else
  17426. +#else
  17427. +#define DPRINTF(a...)
  17428. +#endif
  17429. +
  17430. +typedef int bus_size_t;
  17431. +
  17432. +static inline int
  17433. +pci_get_revid(struct pci_dev *dev)
  17434. +{
  17435. + u8 rid = 0;
  17436. + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
  17437. + return rid;
  17438. +}
  17439. +
  17440. +#define debug hipp_debug
  17441. +int hipp_debug = 0;
  17442. +module_param(hipp_debug, int, 0644);
  17443. +MODULE_PARM_DESC(hipp_debug, "Enable debug");
  17444. +
  17445. +int hipp_maxbatch = 1;
  17446. +module_param(hipp_maxbatch, int, 0644);
  17447. +MODULE_PARM_DESC(hipp_maxbatch, "max ops to batch w/o interrupt");
  17448. +
  17449. +static int hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent);
  17450. +static void hipp_remove(struct pci_dev *dev);
  17451. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  17452. +static irqreturn_t hipp_intr(int irq, void *arg);
  17453. +#else
  17454. +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs);
  17455. +#endif
  17456. +
  17457. +static int hipp_num_chips = 0;
  17458. +static struct hipp_softc *hipp_chip_idx[HIPP_MAX_CHIPS];
  17459. +
  17460. +static int hipp_newsession(device_t, u_int32_t *, struct cryptoini *);
  17461. +static int hipp_freesession(device_t, u_int64_t);
  17462. +static int hipp_process(device_t, struct cryptop *, int);
  17463. +
  17464. +static device_method_t hipp_methods = {
  17465. + /* crypto device methods */
  17466. + DEVMETHOD(cryptodev_newsession, hipp_newsession),
  17467. + DEVMETHOD(cryptodev_freesession,hipp_freesession),
  17468. + DEVMETHOD(cryptodev_process, hipp_process),
  17469. +};
  17470. +
  17471. +static __inline u_int32_t
  17472. +READ_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg)
  17473. +{
  17474. + u_int32_t v = readl(sc->sc_bar[barno] + reg);
  17475. + //sc->sc_bar0_lastreg = (bus_size_t) -1;
  17476. + return (v);
  17477. +}
  17478. +static __inline void
  17479. +WRITE_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg, u_int32_t val)
  17480. +{
  17481. + writel(val, sc->sc_bar[barno] + reg);
  17482. +}
  17483. +
  17484. +#define READ_REG_0(sc, reg) READ_REG(sc, 0, reg)
  17485. +#define WRITE_REG_0(sc, reg, val) WRITE_REG(sc,0, reg, val)
  17486. +#define READ_REG_1(sc, reg) READ_REG(sc, 1, reg)
  17487. +#define WRITE_REG_1(sc, reg, val) WRITE_REG(sc,1, reg, val)
  17488. +
  17489. +static int
  17490. +hipp_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  17491. +{
  17492. + return EINVAL;
  17493. +}
  17494. +
  17495. +static int
  17496. +hipp_freesession(device_t dev, u_int64_t tid)
  17497. +{
  17498. + return EINVAL;
  17499. +}
  17500. +
  17501. +static int
  17502. +hipp_process(device_t dev, struct cryptop *crp, int hint)
  17503. +{
  17504. + return EINVAL;
  17505. +}
  17506. +
  17507. +static const char*
  17508. +hipp_partname(struct hipp_softc *sc, char buf[128], size_t blen)
  17509. +{
  17510. + char *n = NULL;
  17511. +
  17512. + switch (pci_get_vendor(sc->sc_pcidev)) {
  17513. + case PCI_VENDOR_HIFN:
  17514. + switch (pci_get_device(sc->sc_pcidev)) {
  17515. + case PCI_PRODUCT_HIFN_7855: n = "Hifn 7855";
  17516. + case PCI_PRODUCT_HIFN_8155: n = "Hifn 8155";
  17517. + case PCI_PRODUCT_HIFN_6500: n = "Hifn 6500";
  17518. + }
  17519. + }
  17520. +
  17521. + if(n==NULL) {
  17522. + snprintf(buf, blen, "VID=%02x,PID=%02x",
  17523. + pci_get_vendor(sc->sc_pcidev),
  17524. + pci_get_device(sc->sc_pcidev));
  17525. + } else {
  17526. + buf[0]='\0';
  17527. + strncat(buf, n, blen);
  17528. + }
  17529. + return buf;
  17530. +}
  17531. +
  17532. +struct hipp_fs_entry {
  17533. + struct attribute attr;
  17534. + /* other stuff */
  17535. +};
  17536. +
  17537. +
  17538. +static ssize_t
  17539. +cryptoid_show(struct device *dev,
  17540. + struct device_attribute *attr,
  17541. + char *buf)
  17542. +{
  17543. + struct hipp_softc *sc;
  17544. +
  17545. + sc = pci_get_drvdata(to_pci_dev (dev));
  17546. + return sprintf (buf, "%d\n", sc->sc_cid);
  17547. +}
  17548. +
  17549. +struct device_attribute hipp_dev_cryptoid = __ATTR_RO(cryptoid);
  17550. +
  17551. +/*
  17552. + * Attach an interface that successfully probed.
  17553. + */
  17554. +static int
  17555. +hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  17556. +{
  17557. + struct hipp_softc *sc = NULL;
  17558. + int i;
  17559. + //char rbase;
  17560. + //u_int16_t ena;
  17561. + int rev;
  17562. + //int rseg;
  17563. + int rc;
  17564. +
  17565. + DPRINTF("%s()\n", __FUNCTION__);
  17566. +
  17567. + if (pci_enable_device(dev) < 0)
  17568. + return(-ENODEV);
  17569. +
  17570. + if (pci_set_mwi(dev))
  17571. + return(-ENODEV);
  17572. +
  17573. + if (!dev->irq) {
  17574. + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
  17575. + pci_disable_device(dev);
  17576. + return(-ENODEV);
  17577. + }
  17578. +
  17579. + sc = (struct hipp_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  17580. + if (!sc)
  17581. + return(-ENOMEM);
  17582. + memset(sc, 0, sizeof(*sc));
  17583. +
  17584. + softc_device_init(sc, "hifn-hipp", hipp_num_chips, hipp_methods);
  17585. +
  17586. + sc->sc_pcidev = dev;
  17587. + sc->sc_irq = -1;
  17588. + sc->sc_cid = -1;
  17589. + sc->sc_num = hipp_num_chips++;
  17590. +
  17591. + if (sc->sc_num < HIPP_MAX_CHIPS)
  17592. + hipp_chip_idx[sc->sc_num] = sc;
  17593. +
  17594. + pci_set_drvdata(sc->sc_pcidev, sc);
  17595. +
  17596. + spin_lock_init(&sc->sc_mtx);
  17597. +
  17598. + /*
  17599. + * Setup PCI resources.
  17600. + * The READ_REG_0, WRITE_REG_0, READ_REG_1,
  17601. + * and WRITE_REG_1 macros throughout the driver are used
  17602. + * to permit better debugging.
  17603. + */
  17604. + for(i=0; i<4; i++) {
  17605. + unsigned long mem_start, mem_len;
  17606. + mem_start = pci_resource_start(sc->sc_pcidev, i);
  17607. + mem_len = pci_resource_len(sc->sc_pcidev, i);
  17608. + sc->sc_barphy[i] = (caddr_t)mem_start;
  17609. + sc->sc_bar[i] = (ocf_iomem_t) ioremap(mem_start, mem_len);
  17610. + if (!sc->sc_bar[i]) {
  17611. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", i);
  17612. + goto fail;
  17613. + }
  17614. + }
  17615. +
  17616. + //hipp_reset_board(sc, 0);
  17617. + pci_set_master(sc->sc_pcidev);
  17618. +
  17619. + /*
  17620. + * Arrange the interrupt line.
  17621. + */
  17622. + rc = request_irq(dev->irq, hipp_intr, IRQF_SHARED, "hifn", sc);
  17623. + if (rc) {
  17624. + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
  17625. + goto fail;
  17626. + }
  17627. + sc->sc_irq = dev->irq;
  17628. +
  17629. + rev = READ_REG_1(sc, HIPP_1_REVID) & 0xffff;
  17630. +
  17631. + {
  17632. + char b[32];
  17633. + device_printf(sc->sc_dev, "%s, rev %u",
  17634. + hipp_partname(sc, b, sizeof(b)), rev);
  17635. + }
  17636. +
  17637. +#if 0
  17638. + if (sc->sc_flags & HIFN_IS_7956)
  17639. + printf(", pll=0x%x<%s clk, %ux mult>",
  17640. + sc->sc_pllconfig,
  17641. + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
  17642. + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
  17643. +#endif
  17644. + printf("\n");
  17645. +
  17646. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  17647. + if (sc->sc_cid < 0) {
  17648. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  17649. + goto fail;
  17650. + }
  17651. +
  17652. +#if 0 /* cannot work with a non-GPL module */
  17653. + /* make a sysfs entry to let the world know what entry we got */
  17654. + sysfs_create_file(&sc->sc_pcidev->dev.kobj, &hipp_dev_cryptoid.attr);
  17655. +#endif
  17656. +
  17657. +#if 0
  17658. + init_timer(&sc->sc_tickto);
  17659. + sc->sc_tickto.function = hifn_tick;
  17660. + sc->sc_tickto.data = (unsigned long) sc->sc_num;
  17661. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  17662. +#endif
  17663. +
  17664. +#if 0 /* no code here yet ?? */
  17665. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  17666. +#endif
  17667. +
  17668. + return (0);
  17669. +
  17670. +fail:
  17671. + if (sc->sc_cid >= 0)
  17672. + crypto_unregister_all(sc->sc_cid);
  17673. + if (sc->sc_irq != -1)
  17674. + free_irq(sc->sc_irq, sc);
  17675. +
  17676. +#if 0
  17677. + if (sc->sc_dma) {
  17678. + /* Turn off DMA polling */
  17679. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  17680. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  17681. +
  17682. + pci_free_consistent(sc->sc_pcidev,
  17683. + sizeof(*sc->sc_dma),
  17684. + sc->sc_dma, sc->sc_dma_physaddr);
  17685. + }
  17686. +#endif
  17687. + kfree(sc);
  17688. + return (-ENXIO);
  17689. +}
  17690. +
  17691. +/*
  17692. + * Detach an interface that successfully probed.
  17693. + */
  17694. +static void
  17695. +hipp_remove(struct pci_dev *dev)
  17696. +{
  17697. + struct hipp_softc *sc = pci_get_drvdata(dev);
  17698. + unsigned long l_flags;
  17699. +
  17700. + DPRINTF("%s()\n", __FUNCTION__);
  17701. +
  17702. + /* disable interrupts */
  17703. + HIPP_LOCK(sc);
  17704. +
  17705. +#if 0
  17706. + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
  17707. + HIFN_UNLOCK(sc);
  17708. +
  17709. + /*XXX other resources */
  17710. + del_timer_sync(&sc->sc_tickto);
  17711. +
  17712. + /* Turn off DMA polling */
  17713. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  17714. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  17715. +#endif
  17716. +
  17717. + crypto_unregister_all(sc->sc_cid);
  17718. +
  17719. + free_irq(sc->sc_irq, sc);
  17720. +
  17721. +#if 0
  17722. + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
  17723. + sc->sc_dma, sc->sc_dma_physaddr);
  17724. +#endif
  17725. +}
  17726. +
  17727. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  17728. +static irqreturn_t hipp_intr(int irq, void *arg)
  17729. +#else
  17730. +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs)
  17731. +#endif
  17732. +{
  17733. + struct hipp_softc *sc = arg;
  17734. +
  17735. + sc = sc; /* shut up compiler */
  17736. +
  17737. + return IRQ_HANDLED;
  17738. +}
  17739. +
  17740. +static struct pci_device_id hipp_pci_tbl[] = {
  17741. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7855,
  17742. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  17743. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_8155,
  17744. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  17745. +};
  17746. +MODULE_DEVICE_TABLE(pci, hipp_pci_tbl);
  17747. +
  17748. +static struct pci_driver hipp_driver = {
  17749. + .name = "hipp",
  17750. + .id_table = hipp_pci_tbl,
  17751. + .probe = hipp_probe,
  17752. + .remove = hipp_remove,
  17753. + /* add PM stuff here one day */
  17754. +};
  17755. +
  17756. +static int __init hipp_init (void)
  17757. +{
  17758. + struct hipp_softc *sc = NULL;
  17759. + int rc;
  17760. +
  17761. + DPRINTF("%s(%p)\n", __FUNCTION__, hipp_init);
  17762. +
  17763. + rc = pci_register_driver(&hipp_driver);
  17764. + pci_register_driver_compat(&hipp_driver, rc);
  17765. +
  17766. + return rc;
  17767. +}
  17768. +
  17769. +static void __exit hipp_exit (void)
  17770. +{
  17771. + pci_unregister_driver(&hipp_driver);
  17772. +}
  17773. +
  17774. +module_init(hipp_init);
  17775. +module_exit(hipp_exit);
  17776. +
  17777. +MODULE_LICENSE("BSD");
  17778. +MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
  17779. +MODULE_DESCRIPTION("OCF driver for hifn HIPP-I/II PCI crypto devices");
  17780. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/hifnHIPPreg.h linux-2.6.39/crypto/ocf/hifn/hifnHIPPreg.h
  17781. --- linux-2.6.39.orig/crypto/ocf/hifn/hifnHIPPreg.h 1970-01-01 01:00:00.000000000 +0100
  17782. +++ linux-2.6.39/crypto/ocf/hifn/hifnHIPPreg.h 2011-07-31 11:31:54.373909392 +0200
  17783. @@ -0,0 +1,46 @@
  17784. +/*-
  17785. + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
  17786. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
  17787. + *
  17788. + * Redistribution and use in source and binary forms, with or without
  17789. + * modification, are permitted provided that the following conditions
  17790. + * are met:
  17791. + *
  17792. + * 1. Redistributions of source code must retain the above copyright
  17793. + * notice, this list of conditions and the following disclaimer.
  17794. + * 2. Redistributions in binary form must reproduce the above copyright
  17795. + * notice, this list of conditions and the following disclaimer in the
  17796. + * documentation and/or other materials provided with the distribution.
  17797. + * 3. The name of the author may not be used to endorse or promote products
  17798. + * derived from this software without specific prior written permission.
  17799. + *
  17800. + *
  17801. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17802. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17803. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17804. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  17805. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  17806. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  17807. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  17808. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  17809. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  17810. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17811. + *
  17812. + * Effort sponsored by Hifn inc.
  17813. + *
  17814. + */
  17815. +
  17816. +#ifndef __HIFNHIPP_H__
  17817. +#define __HIFNHIPP_H__
  17818. +
  17819. +/*
  17820. + * PCI vendor and device identifiers
  17821. + */
  17822. +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
  17823. +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
  17824. +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
  17825. +#define PCI_PRODUCT_HIFN_8155 0x999 /* XXX 8155 */
  17826. +
  17827. +#define HIPP_1_REVID 0x01 /* BOGUS */
  17828. +
  17829. +#endif /* __HIPP_H__ */
  17830. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/hifnHIPPvar.h linux-2.6.39/crypto/ocf/hifn/hifnHIPPvar.h
  17831. --- linux-2.6.39.orig/crypto/ocf/hifn/hifnHIPPvar.h 1970-01-01 01:00:00.000000000 +0100
  17832. +++ linux-2.6.39/crypto/ocf/hifn/hifnHIPPvar.h 2011-07-31 11:31:54.423425112 +0200
  17833. @@ -0,0 +1,93 @@
  17834. +/*
  17835. + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
  17836. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com> *
  17837. + *
  17838. + * Redistribution and use in source and binary forms, with or without
  17839. + * modification, are permitted provided that the following conditions
  17840. + * are met:
  17841. + *
  17842. + * 1. Redistributions of source code must retain the above copyright
  17843. + * notice, this list of conditions and the following disclaimer.
  17844. + * 2. Redistributions in binary form must reproduce the above copyright
  17845. + * notice, this list of conditions and the following disclaimer in the
  17846. + * documentation and/or other materials provided with the distribution.
  17847. + * 3. The name of the author may not be used to endorse or promote products
  17848. + * derived from this software without specific prior written permission.
  17849. + *
  17850. + *
  17851. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17852. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17853. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17854. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  17855. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  17856. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  17857. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  17858. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  17859. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  17860. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17861. + *
  17862. + * Effort sponsored by Hifn inc.
  17863. + *
  17864. + */
  17865. +
  17866. +#ifndef __HIFNHIPPVAR_H__
  17867. +#define __HIFNHIPPVAR_H__
  17868. +
  17869. +#define HIPP_MAX_CHIPS 8
  17870. +
  17871. +/*
  17872. + * Holds data specific to a single Hifn HIPP-I board.
  17873. + */
  17874. +struct hipp_softc {
  17875. + softc_device_decl sc_dev;
  17876. +
  17877. + struct pci_dev *sc_pcidev; /* device backpointer */
  17878. + ocf_iomem_t sc_bar[5];
  17879. + caddr_t sc_barphy[5]; /* physical address */
  17880. + int sc_num; /* for multiple devs */
  17881. + spinlock_t sc_mtx; /* per-instance lock */
  17882. + int32_t sc_cid;
  17883. + int sc_irq;
  17884. +
  17885. +#if 0
  17886. +
  17887. + u_int32_t sc_dmaier;
  17888. + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
  17889. + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
  17890. +
  17891. + struct hifn_dma *sc_dma;
  17892. + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
  17893. +
  17894. + int sc_dmansegs;
  17895. + int sc_maxses;
  17896. + int sc_nsessions;
  17897. + struct hifn_session *sc_sessions;
  17898. + int sc_ramsize;
  17899. + int sc_flags;
  17900. +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
  17901. +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
  17902. +#define HIFN_HAS_AES 0x4 /* includes AES support */
  17903. +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
  17904. +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
  17905. +
  17906. + struct timer_list sc_tickto; /* for managing DMA */
  17907. +
  17908. + int sc_rngfirst;
  17909. + int sc_rnghz; /* RNG polling frequency */
  17910. +
  17911. + int sc_c_busy; /* command ring busy */
  17912. + int sc_s_busy; /* source data ring busy */
  17913. + int sc_d_busy; /* destination data ring busy */
  17914. + int sc_r_busy; /* result ring busy */
  17915. + int sc_active; /* for initial countdown */
  17916. + int sc_needwakeup; /* ops q'd wating on resources */
  17917. + int sc_curbatch; /* # ops submitted w/o int */
  17918. + int sc_suspended;
  17919. + struct miscdevice sc_miscdev;
  17920. +#endif
  17921. +};
  17922. +
  17923. +#define HIPP_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
  17924. +#define HIPP_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
  17925. +
  17926. +#endif /* __HIFNHIPPVAR_H__ */
  17927. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/Makefile linux-2.6.39/crypto/ocf/hifn/Makefile
  17928. --- linux-2.6.39.orig/crypto/ocf/hifn/Makefile 1970-01-01 01:00:00.000000000 +0100
  17929. +++ linux-2.6.39/crypto/ocf/hifn/Makefile 2011-07-31 11:31:54.483424794 +0200
  17930. @@ -0,0 +1,13 @@
  17931. +# for SGlinux builds
  17932. +-include $(ROOTDIR)/modules/.config
  17933. +
  17934. +obj-$(CONFIG_OCF_HIFN) += hifn7751.o
  17935. +obj-$(CONFIG_OCF_HIFNHIPP) += hifnHIPP.o
  17936. +
  17937. +obj ?= .
  17938. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  17939. +
  17940. +ifdef TOPDIR
  17941. +-include $(TOPDIR)/Rules.make
  17942. +endif
  17943. +
  17944. diff -Nur linux-2.6.39.orig/crypto/ocf/ixp4xx/ixp4xx.c linux-2.6.39/crypto/ocf/ixp4xx/ixp4xx.c
  17945. --- linux-2.6.39.orig/crypto/ocf/ixp4xx/ixp4xx.c 1970-01-01 01:00:00.000000000 +0100
  17946. +++ linux-2.6.39/crypto/ocf/ixp4xx/ixp4xx.c 2011-07-31 11:31:54.543519301 +0200
  17947. @@ -0,0 +1,1324 @@
  17948. +/*
  17949. + * An OCF module that uses Intels IXP CryptACC API to do the crypto.
  17950. + * This driver requires the IXP400 Access Library that is available
  17951. + * from Intel in order to operate (or compile).
  17952. + *
  17953. + * Written by David McCullough <david_mccullough@mcafee.com>
  17954. + * Copyright (C) 2006-2010 David McCullough
  17955. + * Copyright (C) 2004-2005 Intel Corporation.
  17956. + *
  17957. + * LICENSE TERMS
  17958. + *
  17959. + * The free distribution and use of this software in both source and binary
  17960. + * form is allowed (with or without changes) provided that:
  17961. + *
  17962. + * 1. distributions of this source code include the above copyright
  17963. + * notice, this list of conditions and the following disclaimer;
  17964. + *
  17965. + * 2. distributions in binary form include the above copyright
  17966. + * notice, this list of conditions and the following disclaimer
  17967. + * in the documentation and/or other associated materials;
  17968. + *
  17969. + * 3. the copyright holder's name is not used to endorse products
  17970. + * built using this software without specific written permission.
  17971. + *
  17972. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  17973. + * may be distributed under the terms of the GNU General Public License (GPL),
  17974. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  17975. + *
  17976. + * DISCLAIMER
  17977. + *
  17978. + * This software is provided 'as is' with no explicit or implied warranties
  17979. + * in respect of its properties, including, but not limited to, correctness
  17980. + * and/or fitness for purpose.
  17981. + */
  17982. +
  17983. +#ifndef AUTOCONF_INCLUDED
  17984. +#include <linux/config.h>
  17985. +#endif
  17986. +#include <linux/module.h>
  17987. +#include <linux/init.h>
  17988. +#include <linux/list.h>
  17989. +#include <linux/slab.h>
  17990. +#include <linux/sched.h>
  17991. +#include <linux/wait.h>
  17992. +#include <linux/crypto.h>
  17993. +#include <linux/interrupt.h>
  17994. +#include <asm/scatterlist.h>
  17995. +
  17996. +#include <IxTypes.h>
  17997. +#include <IxOsBuffMgt.h>
  17998. +#include <IxNpeDl.h>
  17999. +#include <IxCryptoAcc.h>
  18000. +#include <IxQMgr.h>
  18001. +#include <IxOsServices.h>
  18002. +#include <IxOsCacheMMU.h>
  18003. +
  18004. +#include <cryptodev.h>
  18005. +#include <uio.h>
  18006. +
  18007. +#ifndef IX_MBUF_PRIV
  18008. +#define IX_MBUF_PRIV(x) ((x)->priv)
  18009. +#endif
  18010. +
  18011. +struct ixp_data;
  18012. +
  18013. +struct ixp_q {
  18014. + struct list_head ixp_q_list;
  18015. + struct ixp_data *ixp_q_data;
  18016. + struct cryptop *ixp_q_crp;
  18017. + struct cryptodesc *ixp_q_ccrd;
  18018. + struct cryptodesc *ixp_q_acrd;
  18019. + IX_MBUF ixp_q_mbuf;
  18020. + UINT8 *ixp_hash_dest; /* Location for hash in client buffer */
  18021. + UINT8 *ixp_hash_src; /* Location of hash in internal buffer */
  18022. + unsigned char ixp_q_iv_data[IX_CRYPTO_ACC_MAX_CIPHER_IV_LENGTH];
  18023. + unsigned char *ixp_q_iv;
  18024. +};
  18025. +
  18026. +struct ixp_data {
  18027. + int ixp_registered; /* is the context registered */
  18028. + int ixp_crd_flags; /* detect direction changes */
  18029. +
  18030. + int ixp_cipher_alg;
  18031. + int ixp_auth_alg;
  18032. +
  18033. + UINT32 ixp_ctx_id;
  18034. + UINT32 ixp_hash_key_id; /* used when hashing */
  18035. + IxCryptoAccCtx ixp_ctx;
  18036. + IX_MBUF ixp_pri_mbuf;
  18037. + IX_MBUF ixp_sec_mbuf;
  18038. +
  18039. + struct work_struct ixp_pending_work;
  18040. + struct work_struct ixp_registration_work;
  18041. + struct list_head ixp_q; /* unprocessed requests */
  18042. +};
  18043. +
  18044. +#ifdef __ixp46X
  18045. +
  18046. +#define MAX_IOP_SIZE 64 /* words */
  18047. +#define MAX_OOP_SIZE 128
  18048. +
  18049. +#define MAX_PARAMS 3
  18050. +
  18051. +struct ixp_pkq {
  18052. + struct list_head pkq_list;
  18053. + struct cryptkop *pkq_krp;
  18054. +
  18055. + IxCryptoAccPkeEauInOperands pkq_op;
  18056. + IxCryptoAccPkeEauOpResult pkq_result;
  18057. +
  18058. + UINT32 pkq_ibuf0[MAX_IOP_SIZE];
  18059. + UINT32 pkq_ibuf1[MAX_IOP_SIZE];
  18060. + UINT32 pkq_ibuf2[MAX_IOP_SIZE];
  18061. + UINT32 pkq_obuf[MAX_OOP_SIZE];
  18062. +};
  18063. +
  18064. +static LIST_HEAD(ixp_pkq); /* current PK wait list */
  18065. +static struct ixp_pkq *ixp_pk_cur;
  18066. +static spinlock_t ixp_pkq_lock;
  18067. +
  18068. +#endif /* __ixp46X */
  18069. +
  18070. +static int ixp_blocked = 0;
  18071. +
  18072. +static int32_t ixp_id = -1;
  18073. +static struct ixp_data **ixp_sessions = NULL;
  18074. +static u_int32_t ixp_sesnum = 0;
  18075. +
  18076. +static int ixp_process(device_t, struct cryptop *, int);
  18077. +static int ixp_newsession(device_t, u_int32_t *, struct cryptoini *);
  18078. +static int ixp_freesession(device_t, u_int64_t);
  18079. +#ifdef __ixp46X
  18080. +static int ixp_kprocess(device_t, struct cryptkop *krp, int hint);
  18081. +#endif
  18082. +
  18083. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  18084. +static kmem_cache_t *qcache;
  18085. +#else
  18086. +static struct kmem_cache *qcache;
  18087. +#endif
  18088. +
  18089. +#define debug ixp_debug
  18090. +static int ixp_debug = 0;
  18091. +module_param(ixp_debug, int, 0644);
  18092. +MODULE_PARM_DESC(ixp_debug, "Enable debug");
  18093. +
  18094. +static int ixp_init_crypto = 1;
  18095. +module_param(ixp_init_crypto, int, 0444); /* RO after load/boot */
  18096. +MODULE_PARM_DESC(ixp_init_crypto, "Call ixCryptoAccInit (default is 1)");
  18097. +
  18098. +static void ixp_process_pending(void *arg);
  18099. +static void ixp_registration(void *arg);
  18100. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  18101. +static void ixp_process_pending_wq(struct work_struct *work);
  18102. +static void ixp_registration_wq(struct work_struct *work);
  18103. +#endif
  18104. +
  18105. +/*
  18106. + * dummy device structure
  18107. + */
  18108. +
  18109. +static struct {
  18110. + softc_device_decl sc_dev;
  18111. +} ixpdev;
  18112. +
  18113. +static device_method_t ixp_methods = {
  18114. + /* crypto device methods */
  18115. + DEVMETHOD(cryptodev_newsession, ixp_newsession),
  18116. + DEVMETHOD(cryptodev_freesession,ixp_freesession),
  18117. + DEVMETHOD(cryptodev_process, ixp_process),
  18118. +#ifdef __ixp46X
  18119. + DEVMETHOD(cryptodev_kprocess, ixp_kprocess),
  18120. +#endif
  18121. +};
  18122. +
  18123. +/*
  18124. + * Generate a new software session.
  18125. + */
  18126. +static int
  18127. +ixp_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  18128. +{
  18129. + struct ixp_data *ixp;
  18130. + u_int32_t i;
  18131. +#define AUTH_LEN(cri, def) \
  18132. + (cri->cri_mlen ? cri->cri_mlen : (def))
  18133. +
  18134. + dprintk("%s():alg %d\n", __FUNCTION__,cri->cri_alg);
  18135. + if (sid == NULL || cri == NULL) {
  18136. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  18137. + return EINVAL;
  18138. + }
  18139. +
  18140. + if (ixp_sessions) {
  18141. + for (i = 1; i < ixp_sesnum; i++)
  18142. + if (ixp_sessions[i] == NULL)
  18143. + break;
  18144. + } else
  18145. + i = 1; /* NB: to silence compiler warning */
  18146. +
  18147. + if (ixp_sessions == NULL || i == ixp_sesnum) {
  18148. + struct ixp_data **ixpd;
  18149. +
  18150. + if (ixp_sessions == NULL) {
  18151. + i = 1; /* We leave ixp_sessions[0] empty */
  18152. + ixp_sesnum = CRYPTO_SW_SESSIONS;
  18153. + } else
  18154. + ixp_sesnum *= 2;
  18155. +
  18156. + ixpd = kmalloc(ixp_sesnum * sizeof(struct ixp_data *), SLAB_ATOMIC);
  18157. + if (ixpd == NULL) {
  18158. + /* Reset session number */
  18159. + if (ixp_sesnum == CRYPTO_SW_SESSIONS)
  18160. + ixp_sesnum = 0;
  18161. + else
  18162. + ixp_sesnum /= 2;
  18163. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  18164. + return ENOBUFS;
  18165. + }
  18166. + memset(ixpd, 0, ixp_sesnum * sizeof(struct ixp_data *));
  18167. +
  18168. + /* Copy existing sessions */
  18169. + if (ixp_sessions) {
  18170. + memcpy(ixpd, ixp_sessions,
  18171. + (ixp_sesnum / 2) * sizeof(struct ixp_data *));
  18172. + kfree(ixp_sessions);
  18173. + }
  18174. +
  18175. + ixp_sessions = ixpd;
  18176. + }
  18177. +
  18178. + ixp_sessions[i] = (struct ixp_data *) kmalloc(sizeof(struct ixp_data),
  18179. + SLAB_ATOMIC);
  18180. + if (ixp_sessions[i] == NULL) {
  18181. + ixp_freesession(NULL, i);
  18182. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  18183. + return ENOBUFS;
  18184. + }
  18185. +
  18186. + *sid = i;
  18187. +
  18188. + ixp = ixp_sessions[i];
  18189. + memset(ixp, 0, sizeof(*ixp));
  18190. +
  18191. + ixp->ixp_cipher_alg = -1;
  18192. + ixp->ixp_auth_alg = -1;
  18193. + ixp->ixp_ctx_id = -1;
  18194. + INIT_LIST_HEAD(&ixp->ixp_q);
  18195. +
  18196. + ixp->ixp_ctx.useDifferentSrcAndDestMbufs = 0;
  18197. +
  18198. + while (cri) {
  18199. + switch (cri->cri_alg) {
  18200. + case CRYPTO_DES_CBC:
  18201. + ixp->ixp_cipher_alg = cri->cri_alg;
  18202. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_DES;
  18203. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  18204. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  18205. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  18206. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
  18207. + IX_CRYPTO_ACC_DES_IV_64;
  18208. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  18209. + cri->cri_key, (cri->cri_klen + 7) / 8);
  18210. + break;
  18211. +
  18212. + case CRYPTO_3DES_CBC:
  18213. + ixp->ixp_cipher_alg = cri->cri_alg;
  18214. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
  18215. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  18216. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  18217. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  18218. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
  18219. + IX_CRYPTO_ACC_DES_IV_64;
  18220. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  18221. + cri->cri_key, (cri->cri_klen + 7) / 8);
  18222. + break;
  18223. +
  18224. + case CRYPTO_RIJNDAEL128_CBC:
  18225. + ixp->ixp_cipher_alg = cri->cri_alg;
  18226. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_AES;
  18227. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  18228. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  18229. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = 16;
  18230. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen = 16;
  18231. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  18232. + cri->cri_key, (cri->cri_klen + 7) / 8);
  18233. + break;
  18234. +
  18235. + case CRYPTO_MD5:
  18236. + case CRYPTO_MD5_HMAC:
  18237. + ixp->ixp_auth_alg = cri->cri_alg;
  18238. + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_MD5;
  18239. + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, MD5_HASH_LEN);
  18240. + ixp->ixp_ctx.authCtx.aadLen = 0;
  18241. + /* Only MD5_HMAC needs a key */
  18242. + if (cri->cri_alg == CRYPTO_MD5_HMAC) {
  18243. + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
  18244. + if (ixp->ixp_ctx.authCtx.authKeyLen >
  18245. + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
  18246. + printk(
  18247. + "ixp4xx: Invalid key length for MD5_HMAC - %d bits\n",
  18248. + cri->cri_klen);
  18249. + ixp_freesession(NULL, i);
  18250. + return EINVAL;
  18251. + }
  18252. + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
  18253. + cri->cri_key, (cri->cri_klen + 7) / 8);
  18254. + }
  18255. + break;
  18256. +
  18257. + case CRYPTO_SHA1:
  18258. + case CRYPTO_SHA1_HMAC:
  18259. + ixp->ixp_auth_alg = cri->cri_alg;
  18260. + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
  18261. + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, SHA1_HASH_LEN);
  18262. + ixp->ixp_ctx.authCtx.aadLen = 0;
  18263. + /* Only SHA1_HMAC needs a key */
  18264. + if (cri->cri_alg == CRYPTO_SHA1_HMAC) {
  18265. + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
  18266. + if (ixp->ixp_ctx.authCtx.authKeyLen >
  18267. + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
  18268. + printk(
  18269. + "ixp4xx: Invalid key length for SHA1_HMAC - %d bits\n",
  18270. + cri->cri_klen);
  18271. + ixp_freesession(NULL, i);
  18272. + return EINVAL;
  18273. + }
  18274. + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
  18275. + cri->cri_key, (cri->cri_klen + 7) / 8);
  18276. + }
  18277. + break;
  18278. +
  18279. + default:
  18280. + printk("ixp: unknown algo 0x%x\n", cri->cri_alg);
  18281. + ixp_freesession(NULL, i);
  18282. + return EINVAL;
  18283. + }
  18284. + cri = cri->cri_next;
  18285. + }
  18286. +
  18287. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  18288. + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending_wq);
  18289. + INIT_WORK(&ixp->ixp_registration_work, ixp_registration_wq);
  18290. +#else
  18291. + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending, ixp);
  18292. + INIT_WORK(&ixp->ixp_registration_work, ixp_registration, ixp);
  18293. +#endif
  18294. +
  18295. + return 0;
  18296. +}
  18297. +
  18298. +
  18299. +/*
  18300. + * Free a session.
  18301. + */
  18302. +static int
  18303. +ixp_freesession(device_t dev, u_int64_t tid)
  18304. +{
  18305. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  18306. +
  18307. + dprintk("%s()\n", __FUNCTION__);
  18308. + if (sid > ixp_sesnum || ixp_sessions == NULL ||
  18309. + ixp_sessions[sid] == NULL) {
  18310. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  18311. + return EINVAL;
  18312. + }
  18313. +
  18314. + /* Silently accept and return */
  18315. + if (sid == 0)
  18316. + return 0;
  18317. +
  18318. + if (ixp_sessions[sid]) {
  18319. + if (ixp_sessions[sid]->ixp_ctx_id != -1) {
  18320. + ixCryptoAccCtxUnregister(ixp_sessions[sid]->ixp_ctx_id);
  18321. + ixp_sessions[sid]->ixp_ctx_id = -1;
  18322. + }
  18323. + kfree(ixp_sessions[sid]);
  18324. + }
  18325. + ixp_sessions[sid] = NULL;
  18326. + if (ixp_blocked) {
  18327. + ixp_blocked = 0;
  18328. + crypto_unblock(ixp_id, CRYPTO_SYMQ);
  18329. + }
  18330. + return 0;
  18331. +}
  18332. +
  18333. +
  18334. +/*
  18335. + * callback for when hash processing is complete
  18336. + */
  18337. +
  18338. +static void
  18339. +ixp_hash_perform_cb(
  18340. + UINT32 hash_key_id,
  18341. + IX_MBUF *bufp,
  18342. + IxCryptoAccStatus status)
  18343. +{
  18344. + struct ixp_q *q;
  18345. +
  18346. + dprintk("%s(%u, %p, 0x%x)\n", __FUNCTION__, hash_key_id, bufp, status);
  18347. +
  18348. + if (bufp == NULL) {
  18349. + printk("ixp: NULL buf in %s\n", __FUNCTION__);
  18350. + return;
  18351. + }
  18352. +
  18353. + q = IX_MBUF_PRIV(bufp);
  18354. + if (q == NULL) {
  18355. + printk("ixp: NULL priv in %s\n", __FUNCTION__);
  18356. + return;
  18357. + }
  18358. +
  18359. + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
  18360. + /* On success, need to copy hash back into original client buffer */
  18361. + memcpy(q->ixp_hash_dest, q->ixp_hash_src,
  18362. + (q->ixp_q_data->ixp_auth_alg == CRYPTO_SHA1) ?
  18363. + SHA1_HASH_LEN : MD5_HASH_LEN);
  18364. + }
  18365. + else {
  18366. + printk("ixp: hash perform failed status=%d\n", status);
  18367. + q->ixp_q_crp->crp_etype = EINVAL;
  18368. + }
  18369. +
  18370. + /* Free internal buffer used for hashing */
  18371. + kfree(IX_MBUF_MDATA(&q->ixp_q_mbuf));
  18372. +
  18373. + crypto_done(q->ixp_q_crp);
  18374. + kmem_cache_free(qcache, q);
  18375. +}
  18376. +
  18377. +/*
  18378. + * setup a request and perform it
  18379. + */
  18380. +static void
  18381. +ixp_q_process(struct ixp_q *q)
  18382. +{
  18383. + IxCryptoAccStatus status;
  18384. + struct ixp_data *ixp = q->ixp_q_data;
  18385. + int auth_off = 0;
  18386. + int auth_len = 0;
  18387. + int crypt_off = 0;
  18388. + int crypt_len = 0;
  18389. + int icv_off = 0;
  18390. + char *crypt_func;
  18391. +
  18392. + dprintk("%s(%p)\n", __FUNCTION__, q);
  18393. +
  18394. + if (q->ixp_q_ccrd) {
  18395. + if (q->ixp_q_ccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  18396. + q->ixp_q_iv = q->ixp_q_ccrd->crd_iv;
  18397. + } else {
  18398. + q->ixp_q_iv = q->ixp_q_iv_data;
  18399. + crypto_copydata(q->ixp_q_crp->crp_flags, q->ixp_q_crp->crp_buf,
  18400. + q->ixp_q_ccrd->crd_inject,
  18401. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen,
  18402. + (caddr_t) q->ixp_q_iv);
  18403. + }
  18404. +
  18405. + if (q->ixp_q_acrd) {
  18406. + auth_off = q->ixp_q_acrd->crd_skip;
  18407. + auth_len = q->ixp_q_acrd->crd_len;
  18408. + icv_off = q->ixp_q_acrd->crd_inject;
  18409. + }
  18410. +
  18411. + crypt_off = q->ixp_q_ccrd->crd_skip;
  18412. + crypt_len = q->ixp_q_ccrd->crd_len;
  18413. + } else { /* if (q->ixp_q_acrd) */
  18414. + auth_off = q->ixp_q_acrd->crd_skip;
  18415. + auth_len = q->ixp_q_acrd->crd_len;
  18416. + icv_off = q->ixp_q_acrd->crd_inject;
  18417. + }
  18418. +
  18419. + if (q->ixp_q_crp->crp_flags & CRYPTO_F_SKBUF) {
  18420. + struct sk_buff *skb = (struct sk_buff *) q->ixp_q_crp->crp_buf;
  18421. + if (skb_shinfo(skb)->nr_frags) {
  18422. + /*
  18423. + * DAVIDM fix this limitation one day by using
  18424. + * a buffer pool and chaining, it is not currently
  18425. + * needed for current user/kernel space acceleration
  18426. + */
  18427. + printk("ixp: Cannot handle fragmented skb's yet !\n");
  18428. + q->ixp_q_crp->crp_etype = ENOENT;
  18429. + goto done;
  18430. + }
  18431. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  18432. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = skb->len;
  18433. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = skb->data;
  18434. + } else if (q->ixp_q_crp->crp_flags & CRYPTO_F_IOV) {
  18435. + struct uio *uiop = (struct uio *) q->ixp_q_crp->crp_buf;
  18436. + if (uiop->uio_iovcnt != 1) {
  18437. + /*
  18438. + * DAVIDM fix this limitation one day by using
  18439. + * a buffer pool and chaining, it is not currently
  18440. + * needed for current user/kernel space acceleration
  18441. + */
  18442. + printk("ixp: Cannot handle more than 1 iovec yet !\n");
  18443. + q->ixp_q_crp->crp_etype = ENOENT;
  18444. + goto done;
  18445. + }
  18446. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  18447. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_len;
  18448. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_base;
  18449. + } else /* contig buffer */ {
  18450. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  18451. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_ilen;
  18452. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_buf;
  18453. + }
  18454. +
  18455. + IX_MBUF_PRIV(&q->ixp_q_mbuf) = q;
  18456. +
  18457. + if (ixp->ixp_auth_alg == CRYPTO_SHA1 || ixp->ixp_auth_alg == CRYPTO_MD5) {
  18458. + /*
  18459. + * For SHA1 and MD5 hash, need to create an internal buffer that is big
  18460. + * enough to hold the original data + the appropriate padding for the
  18461. + * hash algorithm.
  18462. + */
  18463. + UINT8 *tbuf = NULL;
  18464. +
  18465. + IX_MBUF_MLEN(&q->ixp_q_mbuf) = IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) =
  18466. + ((IX_MBUF_MLEN(&q->ixp_q_mbuf) * 8) + 72 + 511) / 8;
  18467. + tbuf = kmalloc(IX_MBUF_MLEN(&q->ixp_q_mbuf), SLAB_ATOMIC);
  18468. +
  18469. + if (IX_MBUF_MDATA(&q->ixp_q_mbuf) == NULL) {
  18470. + printk("ixp: kmalloc(%u, SLAB_ATOMIC) failed\n",
  18471. + IX_MBUF_MLEN(&q->ixp_q_mbuf));
  18472. + q->ixp_q_crp->crp_etype = ENOMEM;
  18473. + goto done;
  18474. + }
  18475. + memcpy(tbuf, &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off], auth_len);
  18476. +
  18477. + /* Set location in client buffer to copy hash into */
  18478. + q->ixp_hash_dest =
  18479. + &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off + auth_len];
  18480. +
  18481. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = tbuf;
  18482. +
  18483. + /* Set location in internal buffer for where hash starts */
  18484. + q->ixp_hash_src = &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_len];
  18485. +
  18486. + crypt_func = "ixCryptoAccHashPerform";
  18487. + status = ixCryptoAccHashPerform(ixp->ixp_ctx.authCtx.authAlgo,
  18488. + &q->ixp_q_mbuf, ixp_hash_perform_cb, 0, auth_len, auth_len,
  18489. + &ixp->ixp_hash_key_id);
  18490. + }
  18491. + else {
  18492. + crypt_func = "ixCryptoAccAuthCryptPerform";
  18493. + status = ixCryptoAccAuthCryptPerform(ixp->ixp_ctx_id, &q->ixp_q_mbuf,
  18494. + NULL, auth_off, auth_len, crypt_off, crypt_len, icv_off,
  18495. + q->ixp_q_iv);
  18496. + }
  18497. +
  18498. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  18499. + return;
  18500. +
  18501. + if (IX_CRYPTO_ACC_STATUS_QUEUE_FULL == status) {
  18502. + q->ixp_q_crp->crp_etype = ENOMEM;
  18503. + goto done;
  18504. + }
  18505. +
  18506. + printk("ixp: %s failed %u\n", crypt_func, status);
  18507. + q->ixp_q_crp->crp_etype = EINVAL;
  18508. +
  18509. +done:
  18510. + crypto_done(q->ixp_q_crp);
  18511. + kmem_cache_free(qcache, q);
  18512. +}
  18513. +
  18514. +
  18515. +/*
  18516. + * because we cannot process the Q from the Register callback
  18517. + * we do it here on a task Q.
  18518. + */
  18519. +
  18520. +static void
  18521. +ixp_process_pending(void *arg)
  18522. +{
  18523. + struct ixp_data *ixp = arg;
  18524. + struct ixp_q *q = NULL;
  18525. +
  18526. + dprintk("%s(%p)\n", __FUNCTION__, arg);
  18527. +
  18528. + if (!ixp)
  18529. + return;
  18530. +
  18531. + while (!list_empty(&ixp->ixp_q)) {
  18532. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  18533. + list_del(&q->ixp_q_list);
  18534. + ixp_q_process(q);
  18535. + }
  18536. +}
  18537. +
  18538. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  18539. +static void
  18540. +ixp_process_pending_wq(struct work_struct *work)
  18541. +{
  18542. + struct ixp_data *ixp = container_of(work, struct ixp_data, ixp_pending_work);
  18543. + ixp_process_pending(ixp);
  18544. +}
  18545. +#endif
  18546. +
  18547. +/*
  18548. + * callback for when context registration is complete
  18549. + */
  18550. +
  18551. +static void
  18552. +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
  18553. +{
  18554. + int i;
  18555. + struct ixp_data *ixp;
  18556. + struct ixp_q *q;
  18557. +
  18558. + dprintk("%s(%d, %p, %d)\n", __FUNCTION__, ctx_id, bufp, status);
  18559. +
  18560. + /*
  18561. + * free any buffer passed in to this routine
  18562. + */
  18563. + if (bufp) {
  18564. + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
  18565. + kfree(IX_MBUF_MDATA(bufp));
  18566. + IX_MBUF_MDATA(bufp) = NULL;
  18567. + }
  18568. +
  18569. + for (i = 0; i < ixp_sesnum; i++) {
  18570. + ixp = ixp_sessions[i];
  18571. + if (ixp && ixp->ixp_ctx_id == ctx_id)
  18572. + break;
  18573. + }
  18574. + if (i >= ixp_sesnum) {
  18575. + printk("ixp: invalid context id %d\n", ctx_id);
  18576. + return;
  18577. + }
  18578. +
  18579. + if (IX_CRYPTO_ACC_STATUS_WAIT == status) {
  18580. + /* this is normal to free the first of two buffers */
  18581. + dprintk("ixp: register not finished yet.\n");
  18582. + return;
  18583. + }
  18584. +
  18585. + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
  18586. + printk("ixp: register failed 0x%x\n", status);
  18587. + while (!list_empty(&ixp->ixp_q)) {
  18588. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  18589. + list_del(&q->ixp_q_list);
  18590. + q->ixp_q_crp->crp_etype = EINVAL;
  18591. + crypto_done(q->ixp_q_crp);
  18592. + kmem_cache_free(qcache, q);
  18593. + }
  18594. + return;
  18595. + }
  18596. +
  18597. + /*
  18598. + * we are now registered, we cannot start processing the Q here
  18599. + * or we get strange errors with AES (DES/3DES seem to be ok).
  18600. + */
  18601. + ixp->ixp_registered = 1;
  18602. + schedule_work(&ixp->ixp_pending_work);
  18603. +}
  18604. +
  18605. +
  18606. +/*
  18607. + * callback for when data processing is complete
  18608. + */
  18609. +
  18610. +static void
  18611. +ixp_perform_cb(
  18612. + UINT32 ctx_id,
  18613. + IX_MBUF *sbufp,
  18614. + IX_MBUF *dbufp,
  18615. + IxCryptoAccStatus status)
  18616. +{
  18617. + struct ixp_q *q;
  18618. +
  18619. + dprintk("%s(%d, %p, %p, 0x%x)\n", __FUNCTION__, ctx_id, sbufp,
  18620. + dbufp, status);
  18621. +
  18622. + if (sbufp == NULL) {
  18623. + printk("ixp: NULL sbuf in ixp_perform_cb\n");
  18624. + return;
  18625. + }
  18626. +
  18627. + q = IX_MBUF_PRIV(sbufp);
  18628. + if (q == NULL) {
  18629. + printk("ixp: NULL priv in ixp_perform_cb\n");
  18630. + return;
  18631. + }
  18632. +
  18633. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  18634. + printk("ixp: perform failed status=%d\n", status);
  18635. + q->ixp_q_crp->crp_etype = EINVAL;
  18636. + }
  18637. +
  18638. + crypto_done(q->ixp_q_crp);
  18639. + kmem_cache_free(qcache, q);
  18640. +}
  18641. +
  18642. +
  18643. +/*
  18644. + * registration is not callable at IRQ time, so we defer
  18645. + * to a task queue, this routines completes the registration for us
  18646. + * when the task queue runs
  18647. + *
  18648. + * Unfortunately this means we cannot tell OCF that the driver is blocked,
  18649. + * we do that on the next request.
  18650. + */
  18651. +
  18652. +static void
  18653. +ixp_registration(void *arg)
  18654. +{
  18655. + struct ixp_data *ixp = arg;
  18656. + struct ixp_q *q = NULL;
  18657. + IX_MBUF *pri = NULL, *sec = NULL;
  18658. + int status = IX_CRYPTO_ACC_STATUS_SUCCESS;
  18659. +
  18660. + if (!ixp) {
  18661. + printk("ixp: ixp_registration with no arg\n");
  18662. + return;
  18663. + }
  18664. +
  18665. + if (ixp->ixp_ctx_id != -1) {
  18666. + ixCryptoAccCtxUnregister(ixp->ixp_ctx_id);
  18667. + ixp->ixp_ctx_id = -1;
  18668. + }
  18669. +
  18670. + if (list_empty(&ixp->ixp_q)) {
  18671. + printk("ixp: ixp_registration with no Q\n");
  18672. + return;
  18673. + }
  18674. +
  18675. + /*
  18676. + * setup the primary and secondary buffers
  18677. + */
  18678. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  18679. + if (q->ixp_q_acrd) {
  18680. + pri = &ixp->ixp_pri_mbuf;
  18681. + sec = &ixp->ixp_sec_mbuf;
  18682. + IX_MBUF_MLEN(pri) = IX_MBUF_PKT_LEN(pri) = 128;
  18683. + IX_MBUF_MDATA(pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  18684. + IX_MBUF_MLEN(sec) = IX_MBUF_PKT_LEN(sec) = 128;
  18685. + IX_MBUF_MDATA(sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  18686. + }
  18687. +
  18688. + /* Only need to register if a crypt op or HMAC op */
  18689. + if (!(ixp->ixp_auth_alg == CRYPTO_SHA1 ||
  18690. + ixp->ixp_auth_alg == CRYPTO_MD5)) {
  18691. + status = ixCryptoAccCtxRegister(
  18692. + &ixp->ixp_ctx,
  18693. + pri, sec,
  18694. + ixp_register_cb,
  18695. + ixp_perform_cb,
  18696. + &ixp->ixp_ctx_id);
  18697. + }
  18698. + else {
  18699. + /* Otherwise we start processing pending q */
  18700. + schedule_work(&ixp->ixp_pending_work);
  18701. + }
  18702. +
  18703. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  18704. + return;
  18705. +
  18706. + if (IX_CRYPTO_ACC_STATUS_EXCEED_MAX_TUNNELS == status) {
  18707. + printk("ixp: ixCryptoAccCtxRegister failed (out of tunnels)\n");
  18708. + ixp_blocked = 1;
  18709. + /* perhaps we should return EGAIN on queued ops ? */
  18710. + return;
  18711. + }
  18712. +
  18713. + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
  18714. + ixp->ixp_ctx_id = -1;
  18715. +
  18716. + /*
  18717. + * everything waiting is toasted
  18718. + */
  18719. + while (!list_empty(&ixp->ixp_q)) {
  18720. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  18721. + list_del(&q->ixp_q_list);
  18722. + q->ixp_q_crp->crp_etype = ENOENT;
  18723. + crypto_done(q->ixp_q_crp);
  18724. + kmem_cache_free(qcache, q);
  18725. + }
  18726. +}
  18727. +
  18728. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  18729. +static void
  18730. +ixp_registration_wq(struct work_struct *work)
  18731. +{
  18732. + struct ixp_data *ixp = container_of(work, struct ixp_data,
  18733. + ixp_registration_work);
  18734. + ixp_registration(ixp);
  18735. +}
  18736. +#endif
  18737. +
  18738. +/*
  18739. + * Process a request.
  18740. + */
  18741. +static int
  18742. +ixp_process(device_t dev, struct cryptop *crp, int hint)
  18743. +{
  18744. + struct ixp_data *ixp;
  18745. + unsigned int lid;
  18746. + struct ixp_q *q = NULL;
  18747. + int status;
  18748. +
  18749. + dprintk("%s()\n", __FUNCTION__);
  18750. +
  18751. + /* Sanity check */
  18752. + if (crp == NULL) {
  18753. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  18754. + return EINVAL;
  18755. + }
  18756. +
  18757. + crp->crp_etype = 0;
  18758. +
  18759. + if (ixp_blocked)
  18760. + return ERESTART;
  18761. +
  18762. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  18763. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  18764. + crp->crp_etype = EINVAL;
  18765. + goto done;
  18766. + }
  18767. +
  18768. + /*
  18769. + * find the session we are using
  18770. + */
  18771. +
  18772. + lid = crp->crp_sid & 0xffffffff;
  18773. + if (lid >= ixp_sesnum || lid == 0 || ixp_sessions == NULL ||
  18774. + ixp_sessions[lid] == NULL) {
  18775. + crp->crp_etype = ENOENT;
  18776. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  18777. + goto done;
  18778. + }
  18779. + ixp = ixp_sessions[lid];
  18780. +
  18781. + /*
  18782. + * setup a new request ready for queuing
  18783. + */
  18784. + q = kmem_cache_alloc(qcache, SLAB_ATOMIC);
  18785. + if (q == NULL) {
  18786. + dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
  18787. + crp->crp_etype = ENOMEM;
  18788. + goto done;
  18789. + }
  18790. + /*
  18791. + * save some cycles by only zeroing the important bits
  18792. + */
  18793. + memset(&q->ixp_q_mbuf, 0, sizeof(q->ixp_q_mbuf));
  18794. + q->ixp_q_ccrd = NULL;
  18795. + q->ixp_q_acrd = NULL;
  18796. + q->ixp_q_crp = crp;
  18797. + q->ixp_q_data = ixp;
  18798. +
  18799. + /*
  18800. + * point the cipher and auth descriptors appropriately
  18801. + * check that we have something to do
  18802. + */
  18803. + if (crp->crp_desc->crd_alg == ixp->ixp_cipher_alg)
  18804. + q->ixp_q_ccrd = crp->crp_desc;
  18805. + else if (crp->crp_desc->crd_alg == ixp->ixp_auth_alg)
  18806. + q->ixp_q_acrd = crp->crp_desc;
  18807. + else {
  18808. + crp->crp_etype = ENOENT;
  18809. + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
  18810. + goto done;
  18811. + }
  18812. + if (crp->crp_desc->crd_next) {
  18813. + if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_cipher_alg)
  18814. + q->ixp_q_ccrd = crp->crp_desc->crd_next;
  18815. + else if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_auth_alg)
  18816. + q->ixp_q_acrd = crp->crp_desc->crd_next;
  18817. + else {
  18818. + crp->crp_etype = ENOENT;
  18819. + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
  18820. + goto done;
  18821. + }
  18822. + }
  18823. +
  18824. + /*
  18825. + * If there is a direction change for this context then we mark it as
  18826. + * unregistered and re-register is for the new direction. This is not
  18827. + * a very expensive operation and currently only tends to happen when
  18828. + * user-space application are doing benchmarks
  18829. + *
  18830. + * DM - we should be checking for pending requests before unregistering.
  18831. + */
  18832. + if (q->ixp_q_ccrd && ixp->ixp_registered &&
  18833. + ixp->ixp_crd_flags != (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT)) {
  18834. + dprintk("%s - detected direction change on session\n", __FUNCTION__);
  18835. + ixp->ixp_registered = 0;
  18836. + }
  18837. +
  18838. + /*
  18839. + * if we are registered, call straight into the perform code
  18840. + */
  18841. + if (ixp->ixp_registered) {
  18842. + ixp_q_process(q);
  18843. + return 0;
  18844. + }
  18845. +
  18846. + /*
  18847. + * the only part of the context not set in newsession is the direction
  18848. + * dependent parts
  18849. + */
  18850. + if (q->ixp_q_ccrd) {
  18851. + ixp->ixp_crd_flags = (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT);
  18852. + if (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT) {
  18853. + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
  18854. + IX_CRYPTO_ACC_OP_ENCRYPT_AUTH : IX_CRYPTO_ACC_OP_ENCRYPT;
  18855. + } else {
  18856. + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
  18857. + IX_CRYPTO_ACC_OP_AUTH_DECRYPT : IX_CRYPTO_ACC_OP_DECRYPT;
  18858. + }
  18859. + } else {
  18860. + /* q->ixp_q_acrd must be set if we are here */
  18861. + ixp->ixp_ctx.operation = IX_CRYPTO_ACC_OP_AUTH_CALC;
  18862. + }
  18863. +
  18864. + status = list_empty(&ixp->ixp_q);
  18865. + list_add_tail(&q->ixp_q_list, &ixp->ixp_q);
  18866. + if (status)
  18867. + schedule_work(&ixp->ixp_registration_work);
  18868. + return 0;
  18869. +
  18870. +done:
  18871. + if (q)
  18872. + kmem_cache_free(qcache, q);
  18873. + crypto_done(crp);
  18874. + return 0;
  18875. +}
  18876. +
  18877. +
  18878. +#ifdef __ixp46X
  18879. +/*
  18880. + * key processing support for the ixp465
  18881. + */
  18882. +
  18883. +
  18884. +/*
  18885. + * copy a BN (LE) into a buffer (BE) an fill out the op appropriately
  18886. + * assume zeroed and only copy bits that are significant
  18887. + */
  18888. +
  18889. +static int
  18890. +ixp_copy_ibuf(struct crparam *p, IxCryptoAccPkeEauOperand *op, UINT32 *buf)
  18891. +{
  18892. + unsigned char *src = (unsigned char *) p->crp_p;
  18893. + unsigned char *dst;
  18894. + int len, bits = p->crp_nbits;
  18895. +
  18896. + dprintk("%s()\n", __FUNCTION__);
  18897. +
  18898. + if (bits > MAX_IOP_SIZE * sizeof(UINT32) * 8) {
  18899. + dprintk("%s - ibuf too big (%d > %d)\n", __FUNCTION__,
  18900. + bits, MAX_IOP_SIZE * sizeof(UINT32) * 8);
  18901. + return -1;
  18902. + }
  18903. +
  18904. + len = (bits + 31) / 32; /* the number UINT32's needed */
  18905. +
  18906. + dst = (unsigned char *) &buf[len];
  18907. + dst--;
  18908. +
  18909. + while (bits > 0) {
  18910. + *dst-- = *src++;
  18911. + bits -= 8;
  18912. + }
  18913. +
  18914. +#if 0 /* no need to zero remaining bits as it is done during request alloc */
  18915. + while (dst > (unsigned char *) buf)
  18916. + *dst-- = '\0';
  18917. +#endif
  18918. +
  18919. + op->pData = buf;
  18920. + op->dataLen = len;
  18921. + return 0;
  18922. +}
  18923. +
  18924. +/*
  18925. + * copy out the result, be as forgiving as we can about small output buffers
  18926. + */
  18927. +
  18928. +static int
  18929. +ixp_copy_obuf(struct crparam *p, IxCryptoAccPkeEauOpResult *op, UINT32 *buf)
  18930. +{
  18931. + unsigned char *dst = (unsigned char *) p->crp_p;
  18932. + unsigned char *src = (unsigned char *) buf;
  18933. + int len, z, bits = p->crp_nbits;
  18934. +
  18935. + dprintk("%s()\n", __FUNCTION__);
  18936. +
  18937. + len = op->dataLen * sizeof(UINT32);
  18938. +
  18939. + /* skip leading zeroes to be small buffer friendly */
  18940. + z = 0;
  18941. + while (z < len && src[z] == '\0')
  18942. + z++;
  18943. +
  18944. + src += len;
  18945. + src--;
  18946. + len -= z;
  18947. +
  18948. + while (len > 0 && bits > 0) {
  18949. + *dst++ = *src--;
  18950. + len--;
  18951. + bits -= 8;
  18952. + }
  18953. +
  18954. + while (bits > 0) {
  18955. + *dst++ = '\0';
  18956. + bits -= 8;
  18957. + }
  18958. +
  18959. + if (len > 0) {
  18960. + dprintk("%s - obuf is %d (z=%d, ob=%d) bytes too small\n",
  18961. + __FUNCTION__, len, z, p->crp_nbits / 8);
  18962. + return -1;
  18963. + }
  18964. +
  18965. + return 0;
  18966. +}
  18967. +
  18968. +
  18969. +/*
  18970. + * the parameter offsets for exp_mod
  18971. + */
  18972. +
  18973. +#define IXP_PARAM_BASE 0
  18974. +#define IXP_PARAM_EXP 1
  18975. +#define IXP_PARAM_MOD 2
  18976. +#define IXP_PARAM_RES 3
  18977. +
  18978. +/*
  18979. + * key processing complete callback, is also used to start processing
  18980. + * by passing a NULL for pResult
  18981. + */
  18982. +
  18983. +static void
  18984. +ixp_kperform_cb(
  18985. + IxCryptoAccPkeEauOperation operation,
  18986. + IxCryptoAccPkeEauOpResult *pResult,
  18987. + BOOL carryOrBorrow,
  18988. + IxCryptoAccStatus status)
  18989. +{
  18990. + struct ixp_pkq *q, *tmp;
  18991. + unsigned long flags;
  18992. +
  18993. + dprintk("%s(0x%x, %p, %d, 0x%x)\n", __FUNCTION__, operation, pResult,
  18994. + carryOrBorrow, status);
  18995. +
  18996. + /* handle a completed request */
  18997. + if (pResult) {
  18998. + if (ixp_pk_cur && &ixp_pk_cur->pkq_result == pResult) {
  18999. + q = ixp_pk_cur;
  19000. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  19001. + dprintk("%s() - op failed 0x%x\n", __FUNCTION__, status);
  19002. + q->pkq_krp->krp_status = ERANGE; /* could do better */
  19003. + } else {
  19004. + /* copy out the result */
  19005. + if (ixp_copy_obuf(&q->pkq_krp->krp_param[IXP_PARAM_RES],
  19006. + &q->pkq_result, q->pkq_obuf))
  19007. + q->pkq_krp->krp_status = ERANGE;
  19008. + }
  19009. + crypto_kdone(q->pkq_krp);
  19010. + kfree(q);
  19011. + ixp_pk_cur = NULL;
  19012. + } else
  19013. + printk("%s - callback with invalid result pointer\n", __FUNCTION__);
  19014. + }
  19015. +
  19016. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  19017. + if (ixp_pk_cur || list_empty(&ixp_pkq)) {
  19018. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  19019. + return;
  19020. + }
  19021. +
  19022. + list_for_each_entry_safe(q, tmp, &ixp_pkq, pkq_list) {
  19023. +
  19024. + list_del(&q->pkq_list);
  19025. + ixp_pk_cur = q;
  19026. +
  19027. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  19028. +
  19029. + status = ixCryptoAccPkeEauPerform(
  19030. + IX_CRYPTO_ACC_OP_EAU_MOD_EXP,
  19031. + &q->pkq_op,
  19032. + ixp_kperform_cb,
  19033. + &q->pkq_result);
  19034. +
  19035. + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
  19036. + dprintk("%s() - ixCryptoAccPkeEauPerform SUCCESS\n", __FUNCTION__);
  19037. + return; /* callback will return here for callback */
  19038. + } else if (status == IX_CRYPTO_ACC_STATUS_RETRY) {
  19039. + printk("%s() - ixCryptoAccPkeEauPerform RETRY\n", __FUNCTION__);
  19040. + } else {
  19041. + printk("%s() - ixCryptoAccPkeEauPerform failed %d\n",
  19042. + __FUNCTION__, status);
  19043. + }
  19044. + q->pkq_krp->krp_status = ERANGE; /* could do better */
  19045. + crypto_kdone(q->pkq_krp);
  19046. + kfree(q);
  19047. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  19048. + }
  19049. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  19050. +}
  19051. +
  19052. +
  19053. +static int
  19054. +ixp_kprocess(device_t dev, struct cryptkop *krp, int hint)
  19055. +{
  19056. + struct ixp_pkq *q;
  19057. + int rc = 0;
  19058. + unsigned long flags;
  19059. +
  19060. + dprintk("%s l1=%d l2=%d l3=%d l4=%d\n", __FUNCTION__,
  19061. + krp->krp_param[IXP_PARAM_BASE].crp_nbits,
  19062. + krp->krp_param[IXP_PARAM_EXP].crp_nbits,
  19063. + krp->krp_param[IXP_PARAM_MOD].crp_nbits,
  19064. + krp->krp_param[IXP_PARAM_RES].crp_nbits);
  19065. +
  19066. +
  19067. + if (krp->krp_op != CRK_MOD_EXP) {
  19068. + krp->krp_status = EOPNOTSUPP;
  19069. + goto err;
  19070. + }
  19071. +
  19072. + q = (struct ixp_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
  19073. + if (q == NULL) {
  19074. + krp->krp_status = ENOMEM;
  19075. + goto err;
  19076. + }
  19077. +
  19078. + /*
  19079. + * The PKE engine does not appear to zero the output buffer
  19080. + * appropriately, so we need to do it all here.
  19081. + */
  19082. + memset(q, 0, sizeof(*q));
  19083. +
  19084. + q->pkq_krp = krp;
  19085. + INIT_LIST_HEAD(&q->pkq_list);
  19086. +
  19087. + if (ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_BASE], &q->pkq_op.modExpOpr.M,
  19088. + q->pkq_ibuf0))
  19089. + rc = 1;
  19090. + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_EXP],
  19091. + &q->pkq_op.modExpOpr.e, q->pkq_ibuf1))
  19092. + rc = 2;
  19093. + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_MOD],
  19094. + &q->pkq_op.modExpOpr.N, q->pkq_ibuf2))
  19095. + rc = 3;
  19096. +
  19097. + if (rc) {
  19098. + kfree(q);
  19099. + krp->krp_status = ERANGE;
  19100. + goto err;
  19101. + }
  19102. +
  19103. + q->pkq_result.pData = q->pkq_obuf;
  19104. + q->pkq_result.dataLen =
  19105. + (krp->krp_param[IXP_PARAM_RES].crp_nbits + 31) / 32;
  19106. +
  19107. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  19108. + list_add_tail(&q->pkq_list, &ixp_pkq);
  19109. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  19110. +
  19111. + if (!ixp_pk_cur)
  19112. + ixp_kperform_cb(0, NULL, 0, 0);
  19113. + return (0);
  19114. +
  19115. +err:
  19116. + crypto_kdone(krp);
  19117. + return (0);
  19118. +}
  19119. +
  19120. +
  19121. +
  19122. +#ifdef CONFIG_OCF_RANDOMHARVEST
  19123. +/*
  19124. + * We run the random number generator output through SHA so that it
  19125. + * is FIPS compliant.
  19126. + */
  19127. +
  19128. +static volatile int sha_done = 0;
  19129. +static unsigned char sha_digest[20];
  19130. +
  19131. +static void
  19132. +ixp_hash_cb(UINT8 *digest, IxCryptoAccStatus status)
  19133. +{
  19134. + dprintk("%s(%p, %d)\n", __FUNCTION__, digest, status);
  19135. + if (sha_digest != digest)
  19136. + printk("digest error\n");
  19137. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  19138. + sha_done = 1;
  19139. + else
  19140. + sha_done = -status;
  19141. +}
  19142. +
  19143. +static int
  19144. +ixp_read_random(void *arg, u_int32_t *buf, int maxwords)
  19145. +{
  19146. + IxCryptoAccStatus status;
  19147. + int i, n, rc;
  19148. +
  19149. + dprintk("%s(%p, %d)\n", __FUNCTION__, buf, maxwords);
  19150. + memset(buf, 0, maxwords * sizeof(*buf));
  19151. + status = ixCryptoAccPkePseudoRandomNumberGet(maxwords, buf);
  19152. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  19153. + dprintk("%s: ixCryptoAccPkePseudoRandomNumberGet failed %d\n",
  19154. + __FUNCTION__, status);
  19155. + return 0;
  19156. + }
  19157. +
  19158. + /*
  19159. + * run the random data through SHA to make it look more random
  19160. + */
  19161. +
  19162. + n = sizeof(sha_digest); /* process digest bytes at a time */
  19163. +
  19164. + rc = 0;
  19165. + for (i = 0; i < maxwords; i += n / sizeof(*buf)) {
  19166. + if ((maxwords - i) * sizeof(*buf) < n)
  19167. + n = (maxwords - i) * sizeof(*buf);
  19168. + sha_done = 0;
  19169. + status = ixCryptoAccPkeHashPerform(IX_CRYPTO_ACC_AUTH_SHA1,
  19170. + (UINT8 *) &buf[i], n, ixp_hash_cb, sha_digest);
  19171. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  19172. + dprintk("ixCryptoAccPkeHashPerform failed %d\n", status);
  19173. + return -EIO;
  19174. + }
  19175. + while (!sha_done)
  19176. + schedule();
  19177. + if (sha_done < 0) {
  19178. + dprintk("ixCryptoAccPkeHashPerform failed CB %d\n", -sha_done);
  19179. + return 0;
  19180. + }
  19181. + memcpy(&buf[i], sha_digest, n);
  19182. + rc += n / sizeof(*buf);;
  19183. + }
  19184. +
  19185. + return rc;
  19186. +}
  19187. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  19188. +
  19189. +#endif /* __ixp46X */
  19190. +
  19191. +
  19192. +
  19193. +/*
  19194. + * our driver startup and shutdown routines
  19195. + */
  19196. +
  19197. +static int
  19198. +ixp_init(void)
  19199. +{
  19200. + dprintk("%s(%p)\n", __FUNCTION__, ixp_init);
  19201. +
  19202. + if (ixp_init_crypto && ixCryptoAccInit() != IX_CRYPTO_ACC_STATUS_SUCCESS)
  19203. + printk("ixCryptoAccInit failed, assuming already initialised!\n");
  19204. +
  19205. + qcache = kmem_cache_create("ixp4xx_q", sizeof(struct ixp_q), 0,
  19206. + SLAB_HWCACHE_ALIGN, NULL
  19207. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  19208. + , NULL
  19209. +#endif
  19210. + );
  19211. + if (!qcache) {
  19212. + printk("failed to create Qcache\n");
  19213. + return -ENOENT;
  19214. + }
  19215. +
  19216. + memset(&ixpdev, 0, sizeof(ixpdev));
  19217. + softc_device_init(&ixpdev, "ixp4xx", 0, ixp_methods);
  19218. +
  19219. + ixp_id = crypto_get_driverid(softc_get_device(&ixpdev),
  19220. + CRYPTOCAP_F_HARDWARE);
  19221. + if (ixp_id < 0)
  19222. + panic("IXP/OCF crypto device cannot initialize!");
  19223. +
  19224. +#define REGISTER(alg) \
  19225. + crypto_register(ixp_id,alg,0,0)
  19226. +
  19227. + REGISTER(CRYPTO_DES_CBC);
  19228. + REGISTER(CRYPTO_3DES_CBC);
  19229. + REGISTER(CRYPTO_RIJNDAEL128_CBC);
  19230. +#ifdef CONFIG_OCF_IXP4XX_SHA1_MD5
  19231. + REGISTER(CRYPTO_MD5);
  19232. + REGISTER(CRYPTO_SHA1);
  19233. +#endif
  19234. + REGISTER(CRYPTO_MD5_HMAC);
  19235. + REGISTER(CRYPTO_SHA1_HMAC);
  19236. +#undef REGISTER
  19237. +
  19238. +#ifdef __ixp46X
  19239. + spin_lock_init(&ixp_pkq_lock);
  19240. + /*
  19241. + * we do not enable the go fast options here as they can potentially
  19242. + * allow timing based attacks
  19243. + *
  19244. + * http://www.openssl.org/news/secadv_20030219.txt
  19245. + */
  19246. + ixCryptoAccPkeEauExpConfig(0, 0);
  19247. + crypto_kregister(ixp_id, CRK_MOD_EXP, 0);
  19248. +#ifdef CONFIG_OCF_RANDOMHARVEST
  19249. + crypto_rregister(ixp_id, ixp_read_random, NULL);
  19250. +#endif
  19251. +#endif
  19252. +
  19253. + return 0;
  19254. +}
  19255. +
  19256. +static void
  19257. +ixp_exit(void)
  19258. +{
  19259. + dprintk("%s()\n", __FUNCTION__);
  19260. + crypto_unregister_all(ixp_id);
  19261. + ixp_id = -1;
  19262. + kmem_cache_destroy(qcache);
  19263. + qcache = NULL;
  19264. +}
  19265. +
  19266. +module_init(ixp_init);
  19267. +module_exit(ixp_exit);
  19268. +
  19269. +MODULE_LICENSE("Dual BSD/GPL");
  19270. +MODULE_AUTHOR("David McCullough <dmccullough@cyberguard.com>");
  19271. +MODULE_DESCRIPTION("ixp (OCF module for IXP4xx crypto)");
  19272. diff -Nur linux-2.6.39.orig/crypto/ocf/ixp4xx/Makefile linux-2.6.39/crypto/ocf/ixp4xx/Makefile
  19273. --- linux-2.6.39.orig/crypto/ocf/ixp4xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  19274. +++ linux-2.6.39/crypto/ocf/ixp4xx/Makefile 2011-07-31 11:31:54.573910448 +0200
  19275. @@ -0,0 +1,104 @@
  19276. +# for SGlinux builds
  19277. +-include $(ROOTDIR)/modules/.config
  19278. +
  19279. +#
  19280. +# You will need to point this at your Intel ixp425 includes, this portion
  19281. +# of the Makefile only really works under SGLinux with the appropriate libs
  19282. +# installed. They can be downloaded from http://www.snapgear.org/
  19283. +#
  19284. +ifeq ($(CONFIG_CPU_IXP46X),y)
  19285. +IXPLATFORM = ixp46X
  19286. +else
  19287. +ifeq ($(CONFIG_CPU_IXP43X),y)
  19288. +IXPLATFORM = ixp43X
  19289. +else
  19290. +IXPLATFORM = ixp42X
  19291. +endif
  19292. +endif
  19293. +
  19294. +ifdef CONFIG_IXP400_LIB_2_4
  19295. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp400_xscale_sw
  19296. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp_osal
  19297. +endif
  19298. +ifdef CONFIG_IXP400_LIB_2_1
  19299. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp400_xscale_sw
  19300. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp_osal
  19301. +endif
  19302. +ifdef CONFIG_IXP400_LIB_2_0
  19303. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp400_xscale_sw
  19304. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp_osal
  19305. +endif
  19306. +ifdef IX_XSCALE_SW
  19307. +ifdef CONFIG_IXP400_LIB_2_4
  19308. +IXP_CFLAGS = \
  19309. + -I$(ROOTDIR)/. \
  19310. + -I$(IX_XSCALE_SW)/src/include \
  19311. + -I$(OSAL_DIR)/common/include/ \
  19312. + -I$(OSAL_DIR)/common/include/modules/ \
  19313. + -I$(OSAL_DIR)/common/include/modules/ddk/ \
  19314. + -I$(OSAL_DIR)/common/include/modules/bufferMgt/ \
  19315. + -I$(OSAL_DIR)/common/include/modules/ioMem/ \
  19316. + -I$(OSAL_DIR)/common/os/linux/include/ \
  19317. + -I$(OSAL_DIR)/common/os/linux/include/core/ \
  19318. + -I$(OSAL_DIR)/common/os/linux/include/modules/ \
  19319. + -I$(OSAL_DIR)/common/os/linux/include/modules/ddk/ \
  19320. + -I$(OSAL_DIR)/common/os/linux/include/modules/bufferMgt/ \
  19321. + -I$(OSAL_DIR)/common/os/linux/include/modules/ioMem/ \
  19322. + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/include/ \
  19323. + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/os/linux/include/ \
  19324. + -DENABLE_IOMEM -DENABLE_BUFFERMGT -DENABLE_DDK \
  19325. + -DUSE_IXP4XX_CRYPTO
  19326. +else
  19327. +IXP_CFLAGS = \
  19328. + -I$(ROOTDIR)/. \
  19329. + -I$(IX_XSCALE_SW)/src/include \
  19330. + -I$(OSAL_DIR)/ \
  19331. + -I$(OSAL_DIR)/os/linux/include/ \
  19332. + -I$(OSAL_DIR)/os/linux/include/modules/ \
  19333. + -I$(OSAL_DIR)/os/linux/include/modules/ioMem/ \
  19334. + -I$(OSAL_DIR)/os/linux/include/modules/bufferMgt/ \
  19335. + -I$(OSAL_DIR)/os/linux/include/core/ \
  19336. + -I$(OSAL_DIR)/os/linux/include/platforms/ \
  19337. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ \
  19338. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp425 \
  19339. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp465 \
  19340. + -I$(OSAL_DIR)/os/linux/include/core/ \
  19341. + -I$(OSAL_DIR)/include/ \
  19342. + -I$(OSAL_DIR)/include/modules/ \
  19343. + -I$(OSAL_DIR)/include/modules/bufferMgt/ \
  19344. + -I$(OSAL_DIR)/include/modules/ioMem/ \
  19345. + -I$(OSAL_DIR)/include/platforms/ \
  19346. + -I$(OSAL_DIR)/include/platforms/ixp400/ \
  19347. + -DUSE_IXP4XX_CRYPTO
  19348. +endif
  19349. +endif
  19350. +ifdef CONFIG_IXP400_LIB_1_4
  19351. +IXP_CFLAGS = \
  19352. + -I$(ROOTDIR)/. \
  19353. + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/include \
  19354. + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/linux \
  19355. + -DUSE_IXP4XX_CRYPTO
  19356. +endif
  19357. +ifndef IXPDIR
  19358. +IXPDIR = ixp-version-is-not-supported
  19359. +endif
  19360. +
  19361. +ifeq ($(CONFIG_CPU_IXP46X),y)
  19362. +IXP_CFLAGS += -D__ixp46X
  19363. +else
  19364. +ifeq ($(CONFIG_CPU_IXP43X),y)
  19365. +IXP_CFLAGS += -D__ixp43X
  19366. +else
  19367. +IXP_CFLAGS += -D__ixp42X
  19368. +endif
  19369. +endif
  19370. +
  19371. +obj-$(CONFIG_OCF_IXP4XX) += ixp4xx.o
  19372. +
  19373. +obj ?= .
  19374. +EXTRA_CFLAGS += $(IXP_CFLAGS) -I$(obj)/.. -I$(obj)/.
  19375. +
  19376. +ifdef TOPDIR
  19377. +-include $(TOPDIR)/Rules.make
  19378. +endif
  19379. +
  19380. diff -Nur linux-2.6.39.orig/crypto/ocf/Kconfig linux-2.6.39/crypto/ocf/Kconfig
  19381. --- linux-2.6.39.orig/crypto/ocf/Kconfig 1970-01-01 01:00:00.000000000 +0100
  19382. +++ linux-2.6.39/crypto/ocf/Kconfig 2011-07-31 11:31:54.634586634 +0200
  19383. @@ -0,0 +1,119 @@
  19384. +menu "OCF Configuration"
  19385. +
  19386. +config OCF_OCF
  19387. + tristate "OCF (Open Cryptograhic Framework)"
  19388. + help
  19389. + A linux port of the OpenBSD/FreeBSD crypto framework.
  19390. +
  19391. +config OCF_RANDOMHARVEST
  19392. + bool "crypto random --- harvest entropy for /dev/random"
  19393. + depends on OCF_OCF
  19394. + help
  19395. + Includes code to harvest random numbers from devices that support it.
  19396. +
  19397. +config OCF_FIPS
  19398. + bool "enable fips RNG checks"
  19399. + depends on OCF_OCF && OCF_RANDOMHARVEST
  19400. + help
  19401. + Run all RNG provided data through a fips check before
  19402. + adding it /dev/random's entropy pool.
  19403. +
  19404. +config OCF_CRYPTODEV
  19405. + tristate "cryptodev (user space support)"
  19406. + depends on OCF_OCF
  19407. + help
  19408. + The user space API to access crypto hardware.
  19409. +
  19410. +config OCF_CRYPTOSOFT
  19411. + tristate "cryptosoft (software crypto engine)"
  19412. + depends on OCF_OCF
  19413. + help
  19414. + A software driver for the OCF framework that uses
  19415. + the kernel CryptoAPI.
  19416. +
  19417. +config OCF_SAFE
  19418. + tristate "safenet (HW crypto engine)"
  19419. + depends on OCF_OCF
  19420. + help
  19421. + A driver for a number of the safenet Excel crypto accelerators.
  19422. + Currently tested and working on the 1141 and 1741.
  19423. +
  19424. +config OCF_IXP4XX
  19425. + tristate "IXP4xx (HW crypto engine)"
  19426. + depends on OCF_OCF
  19427. + help
  19428. + XScale IXP4xx crypto accelerator driver. Requires the
  19429. + Intel Access library.
  19430. +
  19431. +config OCF_IXP4XX_SHA1_MD5
  19432. + bool "IXP4xx SHA1 and MD5 Hashing"
  19433. + depends on OCF_IXP4XX
  19434. + help
  19435. + Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.
  19436. + Note: this is MUCH slower than using cryptosoft (software crypto engine).
  19437. +
  19438. +config OCF_HIFN
  19439. + tristate "hifn (HW crypto engine)"
  19440. + depends on OCF_OCF
  19441. + help
  19442. + OCF driver for various HIFN based crypto accelerators.
  19443. + (7951, 7955, 7956, 7751, 7811)
  19444. +
  19445. +config OCF_HIFNHIPP
  19446. + tristate "Hifn HIPP (HW packet crypto engine)"
  19447. + depends on OCF_OCF
  19448. + help
  19449. + OCF driver for various HIFN (HIPP) based crypto accelerators
  19450. + (7855)
  19451. +
  19452. +config OCF_TALITOS
  19453. + tristate "talitos (HW crypto engine)"
  19454. + depends on OCF_OCF
  19455. + help
  19456. + OCF driver for Freescale's security engine (SEC/talitos).
  19457. +
  19458. +config OCF_PASEMI
  19459. + tristate "pasemi (HW crypto engine)"
  19460. + depends on OCF_OCF && PPC_PASEMI
  19461. + help
  19462. + OCF driver for the PA Semi PWRficient DMA Engine
  19463. +
  19464. +config OCF_EP80579
  19465. + tristate "ep80579 (HW crypto engine)"
  19466. + depends on OCF_OCF
  19467. + help
  19468. + OCF driver for the Intel EP80579 Integrated Processor Product Line.
  19469. +
  19470. +config OCF_CRYPTOCTEON
  19471. + tristate "cryptocteon (HW crypto engine)"
  19472. + depends on OCF_OCF
  19473. + help
  19474. + OCF driver for the Cavium OCTEON Processors.
  19475. +
  19476. +config OCF_KIRKWOOD
  19477. + tristate "kirkwood (HW crypto engine)"
  19478. + depends on OCF_OCF
  19479. + help
  19480. + OCF driver for the Marvell Kirkwood (88F6xxx) Processors.
  19481. +
  19482. +config OCF_C7108
  19483. + tristate "Micronas 7108 (HW crypto engine)"
  19484. + depends on OCF_OCF
  19485. + help
  19486. + OCF driver for the Microna 7108 Cipher processors.
  19487. +
  19488. +config OCF_OCFNULL
  19489. + tristate "ocfnull (fake crypto engine)"
  19490. + depends on OCF_OCF
  19491. + help
  19492. + OCF driver for measuring ipsec overheads (does no crypto)
  19493. +
  19494. +config OCF_BENCH
  19495. + tristate "ocf-bench (HW crypto in-kernel benchmark)"
  19496. + depends on OCF_OCF
  19497. + help
  19498. + A very simple encryption test for the in-kernel interface
  19499. + of OCF. Also includes code to benchmark the IXP Access library
  19500. + for comparison.
  19501. +
  19502. +endmenu
  19503. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c
  19504. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c 1970-01-01 01:00:00.000000000 +0100
  19505. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c 2011-07-31 11:31:54.683425043 +0200
  19506. @@ -0,0 +1,317 @@
  19507. +/* rijndael-alg-ref.c v2.0 August '99
  19508. + * Reference ANSI C code
  19509. + * authors: Paulo Barreto
  19510. + * Vincent Rijmen, K.U.Leuven
  19511. + *
  19512. + * This code is placed in the public domain.
  19513. + */
  19514. +
  19515. +#include "mvOs.h"
  19516. +
  19517. +#include "mvAesAlg.h"
  19518. +
  19519. +#include "mvAesBoxes.dat"
  19520. +
  19521. +
  19522. +MV_U8 mul1(MV_U8 aa, MV_U8 bb);
  19523. +void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC);
  19524. +void ShiftRow128Enc(MV_U8 a[4][MAXBC]);
  19525. +void ShiftRow128Dec(MV_U8 a[4][MAXBC]);
  19526. +void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]);
  19527. +void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]);
  19528. +void InvMixColumn(MV_U8 a[4][MAXBC]);
  19529. +
  19530. +
  19531. +#define mul(aa, bb) (mask[bb] & Alogtable[aa + Logtable[bb]])
  19532. +
  19533. +MV_U8 mul1(MV_U8 aa, MV_U8 bb)
  19534. +{
  19535. + return mask[bb] & Alogtable[aa + Logtable[bb]];
  19536. +}
  19537. +
  19538. +
  19539. +void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC)
  19540. +{
  19541. + /* Exor corresponding text input and round key input bytes
  19542. + */
  19543. + ((MV_U32*)(&(a[0][0])))[0] ^= ((MV_U32*)(&(rk[0][0])))[0];
  19544. + ((MV_U32*)(&(a[1][0])))[0] ^= ((MV_U32*)(&(rk[1][0])))[0];
  19545. + ((MV_U32*)(&(a[2][0])))[0] ^= ((MV_U32*)(&(rk[2][0])))[0];
  19546. + ((MV_U32*)(&(a[3][0])))[0] ^= ((MV_U32*)(&(rk[3][0])))[0];
  19547. +
  19548. +}
  19549. +
  19550. +void ShiftRow128Enc(MV_U8 a[4][MAXBC]) {
  19551. + /* Row 0 remains unchanged
  19552. + * The other three rows are shifted a variable amount
  19553. + */
  19554. + MV_U8 tmp[MAXBC];
  19555. +
  19556. + tmp[0] = a[1][1];
  19557. + tmp[1] = a[1][2];
  19558. + tmp[2] = a[1][3];
  19559. + tmp[3] = a[1][0];
  19560. +
  19561. + ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  19562. + /*
  19563. + a[1][0] = tmp[0];
  19564. + a[1][1] = tmp[1];
  19565. + a[1][2] = tmp[2];
  19566. + a[1][3] = tmp[3];
  19567. + */
  19568. + tmp[0] = a[2][2];
  19569. + tmp[1] = a[2][3];
  19570. + tmp[2] = a[2][0];
  19571. + tmp[3] = a[2][1];
  19572. +
  19573. + ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  19574. + /*
  19575. + a[2][0] = tmp[0];
  19576. + a[2][1] = tmp[1];
  19577. + a[2][2] = tmp[2];
  19578. + a[2][3] = tmp[3];
  19579. + */
  19580. + tmp[0] = a[3][3];
  19581. + tmp[1] = a[3][0];
  19582. + tmp[2] = a[3][1];
  19583. + tmp[3] = a[3][2];
  19584. +
  19585. + ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  19586. + /*
  19587. + a[3][0] = tmp[0];
  19588. + a[3][1] = tmp[1];
  19589. + a[3][2] = tmp[2];
  19590. + a[3][3] = tmp[3];
  19591. + */
  19592. +}
  19593. +
  19594. +void ShiftRow128Dec(MV_U8 a[4][MAXBC]) {
  19595. + /* Row 0 remains unchanged
  19596. + * The other three rows are shifted a variable amount
  19597. + */
  19598. + MV_U8 tmp[MAXBC];
  19599. +
  19600. + tmp[0] = a[1][3];
  19601. + tmp[1] = a[1][0];
  19602. + tmp[2] = a[1][1];
  19603. + tmp[3] = a[1][2];
  19604. +
  19605. + ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  19606. + /*
  19607. + a[1][0] = tmp[0];
  19608. + a[1][1] = tmp[1];
  19609. + a[1][2] = tmp[2];
  19610. + a[1][3] = tmp[3];
  19611. + */
  19612. +
  19613. + tmp[0] = a[2][2];
  19614. + tmp[1] = a[2][3];
  19615. + tmp[2] = a[2][0];
  19616. + tmp[3] = a[2][1];
  19617. +
  19618. + ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  19619. + /*
  19620. + a[2][0] = tmp[0];
  19621. + a[2][1] = tmp[1];
  19622. + a[2][2] = tmp[2];
  19623. + a[2][3] = tmp[3];
  19624. + */
  19625. +
  19626. + tmp[0] = a[3][1];
  19627. + tmp[1] = a[3][2];
  19628. + tmp[2] = a[3][3];
  19629. + tmp[3] = a[3][0];
  19630. +
  19631. + ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  19632. + /*
  19633. + a[3][0] = tmp[0];
  19634. + a[3][1] = tmp[1];
  19635. + a[3][2] = tmp[2];
  19636. + a[3][3] = tmp[3];
  19637. + */
  19638. +}
  19639. +
  19640. +void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]) {
  19641. + /* Replace every byte of the input by the byte at that place
  19642. + * in the nonlinear S-box
  19643. + */
  19644. + int i, j;
  19645. +
  19646. + for(i = 0; i < 4; i++)
  19647. + for(j = 0; j < 4; j++) a[i][j] = box[a[i][j]] ;
  19648. +}
  19649. +
  19650. +void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]) {
  19651. + /* Mix the four bytes of every column in a linear way
  19652. + */
  19653. + MV_U8 b[4][MAXBC];
  19654. + int i, j;
  19655. +
  19656. + for(j = 0; j < 4; j++){
  19657. + b[0][j] = mul(25,a[0][j]) ^ mul(1,a[1][j]) ^ a[2][j] ^ a[3][j];
  19658. + b[1][j] = mul(25,a[1][j]) ^ mul(1,a[2][j]) ^ a[3][j] ^ a[0][j];
  19659. + b[2][j] = mul(25,a[2][j]) ^ mul(1,a[3][j]) ^ a[0][j] ^ a[1][j];
  19660. + b[3][j] = mul(25,a[3][j]) ^ mul(1,a[0][j]) ^ a[1][j] ^ a[2][j];
  19661. + }
  19662. + for(i = 0; i < 4; i++)
  19663. + /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
  19664. + ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0] ^ ((MV_U32*)(&(rk[i][0])))[0];;
  19665. +}
  19666. +
  19667. +void InvMixColumn(MV_U8 a[4][MAXBC]) {
  19668. + /* Mix the four bytes of every column in a linear way
  19669. + * This is the opposite operation of Mixcolumn
  19670. + */
  19671. + MV_U8 b[4][MAXBC];
  19672. + int i, j;
  19673. +
  19674. + for(j = 0; j < 4; j++){
  19675. + b[0][j] = mul(223,a[0][j]) ^ mul(104,a[1][j]) ^ mul(238,a[2][j]) ^ mul(199,a[3][j]);
  19676. + b[1][j] = mul(223,a[1][j]) ^ mul(104,a[2][j]) ^ mul(238,a[3][j]) ^ mul(199,a[0][j]);
  19677. + b[2][j] = mul(223,a[2][j]) ^ mul(104,a[3][j]) ^ mul(238,a[0][j]) ^ mul(199,a[1][j]);
  19678. + b[3][j] = mul(223,a[3][j]) ^ mul(104,a[0][j]) ^ mul(238,a[1][j]) ^ mul(199,a[2][j]);
  19679. + }
  19680. + for(i = 0; i < 4; i++)
  19681. + /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
  19682. + ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0];
  19683. +}
  19684. +
  19685. +int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 W[MAXROUNDS+1][4][MAXBC])
  19686. +{
  19687. + /* Calculate the necessary round keys
  19688. + * The number of calculations depends on keyBits and blockBits
  19689. + */
  19690. + int KC, BC, ROUNDS;
  19691. + int i, j, t, rconpointer = 0;
  19692. + MV_U8 tk[4][MAXKC];
  19693. +
  19694. + switch (keyBits) {
  19695. + case 128: KC = 4; break;
  19696. + case 192: KC = 6; break;
  19697. + case 256: KC = 8; break;
  19698. + default : return (-1);
  19699. + }
  19700. +
  19701. + switch (blockBits) {
  19702. + case 128: BC = 4; break;
  19703. + case 192: BC = 6; break;
  19704. + case 256: BC = 8; break;
  19705. + default : return (-2);
  19706. + }
  19707. +
  19708. + switch (keyBits >= blockBits ? keyBits : blockBits) {
  19709. + case 128: ROUNDS = 10; break;
  19710. + case 192: ROUNDS = 12; break;
  19711. + case 256: ROUNDS = 14; break;
  19712. + default : return (-3); /* this cannot happen */
  19713. + }
  19714. +
  19715. +
  19716. + for(j = 0; j < KC; j++)
  19717. + for(i = 0; i < 4; i++)
  19718. + tk[i][j] = k[i][j];
  19719. + t = 0;
  19720. + /* copy values into round key array */
  19721. + for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
  19722. + for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
  19723. +
  19724. + while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
  19725. + /* calculate new values */
  19726. + for(i = 0; i < 4; i++)
  19727. + tk[i][0] ^= S[tk[(i+1)%4][KC-1]];
  19728. + tk[0][0] ^= rcon[rconpointer++];
  19729. +
  19730. + if (KC != 8)
  19731. + for(j = 1; j < KC; j++)
  19732. + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  19733. + else {
  19734. + for(j = 1; j < KC/2; j++)
  19735. + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  19736. + for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]];
  19737. + for(j = KC/2 + 1; j < KC; j++)
  19738. + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  19739. + }
  19740. + /* copy values into round key array */
  19741. + for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
  19742. + for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
  19743. + }
  19744. +
  19745. + return 0;
  19746. +}
  19747. +
  19748. +
  19749. +
  19750. +int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
  19751. +{
  19752. + /* Encryption of one block.
  19753. + */
  19754. + int r, BC, ROUNDS;
  19755. +
  19756. + BC = 4;
  19757. + ROUNDS = rounds;
  19758. +
  19759. + /* begin with a key addition
  19760. + */
  19761. +
  19762. + KeyAddition(a,rk[0],BC);
  19763. +
  19764. + /* ROUNDS-1 ordinary rounds
  19765. + */
  19766. + for(r = 1; r < ROUNDS; r++) {
  19767. + Substitution(a,S);
  19768. + ShiftRow128Enc(a);
  19769. + MixColumn(a, rk[r]);
  19770. + /*KeyAddition(a,rk[r],BC);*/
  19771. + }
  19772. +
  19773. + /* Last round is special: there is no MixColumn
  19774. + */
  19775. + Substitution(a,S);
  19776. + ShiftRow128Enc(a);
  19777. + KeyAddition(a,rk[ROUNDS],BC);
  19778. +
  19779. + return 0;
  19780. +}
  19781. +
  19782. +
  19783. +int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
  19784. +{
  19785. + int r, BC, ROUNDS;
  19786. +
  19787. + BC = 4;
  19788. + ROUNDS = rounds;
  19789. +
  19790. + /* To decrypt: apply the inverse operations of the encrypt routine,
  19791. + * in opposite order
  19792. + *
  19793. + * (KeyAddition is an involution: it 's equal to its inverse)
  19794. + * (the inverse of Substitution with table S is Substitution with the inverse table of S)
  19795. + * (the inverse of Shiftrow is Shiftrow over a suitable distance)
  19796. + */
  19797. +
  19798. + /* First the special round:
  19799. + * without InvMixColumn
  19800. + * with extra KeyAddition
  19801. + */
  19802. + KeyAddition(a,rk[ROUNDS],BC);
  19803. + ShiftRow128Dec(a);
  19804. + Substitution(a,Si);
  19805. +
  19806. + /* ROUNDS-1 ordinary rounds
  19807. + */
  19808. + for(r = ROUNDS-1; r > 0; r--) {
  19809. + KeyAddition(a,rk[r],BC);
  19810. + InvMixColumn(a);
  19811. + ShiftRow128Dec(a);
  19812. + Substitution(a,Si);
  19813. +
  19814. + }
  19815. +
  19816. + /* End with the extra key addition
  19817. + */
  19818. +
  19819. + KeyAddition(a,rk[0],BC);
  19820. +
  19821. + return 0;
  19822. +}
  19823. +
  19824. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h
  19825. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h 1970-01-01 01:00:00.000000000 +0100
  19826. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h 2011-07-31 11:31:54.743635409 +0200
  19827. @@ -0,0 +1,19 @@
  19828. +/* rijndael-alg-ref.h v2.0 August '99
  19829. + * Reference ANSI C code
  19830. + * authors: Paulo Barreto
  19831. + * Vincent Rijmen, K.U.Leuven
  19832. + */
  19833. +#ifndef __RIJNDAEL_ALG_H
  19834. +#define __RIJNDAEL_ALG_H
  19835. +
  19836. +#define MAXBC (128/32)
  19837. +#define MAXKC (256/32)
  19838. +#define MAXROUNDS 14
  19839. +
  19840. +
  19841. +int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 rk[MAXROUNDS+1][4][MAXBC]);
  19842. +
  19843. +int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
  19844. +int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
  19845. +
  19846. +#endif /* __RIJNDAEL_ALG_H */
  19847. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c
  19848. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c 1970-01-01 01:00:00.000000000 +0100
  19849. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c 2011-07-31 11:31:54.783912104 +0200
  19850. @@ -0,0 +1,312 @@
  19851. +/* rijndael-api-ref.c v2.1 April 2000
  19852. + * Reference ANSI C code
  19853. + * authors: v2.0 Paulo Barreto
  19854. + * Vincent Rijmen, K.U.Leuven
  19855. + * v2.1 Vincent Rijmen, K.U.Leuven
  19856. + *
  19857. + * This code is placed in the public domain.
  19858. + */
  19859. +#include "mvOs.h"
  19860. +
  19861. +#include "mvAes.h"
  19862. +#include "mvAesAlg.h"
  19863. +
  19864. +
  19865. +/* Defines:
  19866. + Add any additional defines you need
  19867. +*/
  19868. +
  19869. +#define MODE_ECB 1 /* Are we ciphering in ECB mode? */
  19870. +#define MODE_CBC 2 /* Are we ciphering in CBC mode? */
  19871. +#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
  19872. +
  19873. +
  19874. +int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen)
  19875. +{
  19876. + MV_U8 W[MAXROUNDS+1][4][MAXBC];
  19877. + MV_U8 k[4][MAXKC];
  19878. + MV_U8 j;
  19879. + int i, rounds, KC;
  19880. +
  19881. + if (expandedKey == NULL)
  19882. + {
  19883. + return AES_BAD_KEY_INSTANCE;
  19884. + }
  19885. +
  19886. + if (!((keyLen == 128) || (keyLen == 192) || (keyLen == 256)))
  19887. + {
  19888. + return AES_BAD_KEY_MAT;
  19889. + }
  19890. +
  19891. + if (keyMaterial == NULL)
  19892. + {
  19893. + return AES_BAD_KEY_MAT;
  19894. + }
  19895. +
  19896. + /* initialize key schedule: */
  19897. + for(i=0; i<keyLen/8; i++)
  19898. + {
  19899. + j = keyMaterial[i];
  19900. + k[i % 4][i / 4] = j;
  19901. + }
  19902. +
  19903. + rijndaelKeySched (k, keyLen, blockLen, W);
  19904. +#ifdef MV_AES_DEBUG
  19905. + {
  19906. + MV_U8* pW = &W[0][0][0];
  19907. + int x;
  19908. +
  19909. + mvOsPrintf("Expended Key: size = %d\n", sizeof(W));
  19910. + for(i=0; i<sizeof(W); i++)
  19911. + {
  19912. + mvOsPrintf("%02x ", pW[i]);
  19913. + }
  19914. + for(i=0; i<MAXROUNDS+1; i++)
  19915. + {
  19916. + mvOsPrintf("\n Round #%02d: ", i);
  19917. + for(x=0; x<MAXBC; x++)
  19918. + {
  19919. + mvOsPrintf("%02x%02x%02x%02x ",
  19920. + W[i][0][x], W[i][1][x], W[i][2][x], W[i][3][x]);
  19921. + }
  19922. + mvOsPrintf("\n");
  19923. + }
  19924. + }
  19925. +#endif /* MV_AES_DEBUG */
  19926. + switch (keyLen)
  19927. + {
  19928. + case 128:
  19929. + rounds = 10;
  19930. + KC = 4;
  19931. + break;
  19932. + case 192:
  19933. + rounds = 12;
  19934. + KC = 6;
  19935. + break;
  19936. + case 256:
  19937. + rounds = 14;
  19938. + KC = 8;
  19939. + break;
  19940. + default :
  19941. + return (-1);
  19942. + }
  19943. +
  19944. + for(i=0; i<MAXBC; i++)
  19945. + {
  19946. + for(j=0; j<4; j++)
  19947. + {
  19948. + expandedKey[i*4+j] = W[rounds][j][i];
  19949. + }
  19950. + }
  19951. + for(; i<KC; i++)
  19952. + {
  19953. + for(j=0; j<4; j++)
  19954. + {
  19955. + expandedKey[i*4+j] = W[rounds-1][j][i+MAXBC-KC];
  19956. + }
  19957. + }
  19958. +
  19959. +
  19960. + return 0;
  19961. +}
  19962. +
  19963. +int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  19964. + MV_U32 *plain, int numBlocks, MV_U32 *cipher)
  19965. +{
  19966. + int i, j, t;
  19967. + MV_U8 block[4][MAXBC];
  19968. + int rounds;
  19969. + char *input, *outBuffer;
  19970. +
  19971. + input = (char*)plain;
  19972. + outBuffer = (char*)cipher;
  19973. +
  19974. + /* check parameter consistency: */
  19975. + if( (expandedKey == NULL) || ((keyLen != 128) && (keyLen != 192) && (keyLen != 256)))
  19976. + {
  19977. + return AES_BAD_KEY_MAT;
  19978. + }
  19979. + if ((mode != MODE_ECB && mode != MODE_CBC))
  19980. + {
  19981. + return AES_BAD_CIPHER_STATE;
  19982. + }
  19983. +
  19984. + switch (keyLen)
  19985. + {
  19986. + case 128: rounds = 10; break;
  19987. + case 192: rounds = 12; break;
  19988. + case 256: rounds = 14; break;
  19989. + default : return (-3); /* this cannot happen */
  19990. + }
  19991. +
  19992. +
  19993. + switch (mode)
  19994. + {
  19995. + case MODE_ECB:
  19996. + for (i = 0; i < numBlocks; i++)
  19997. + {
  19998. + for (j = 0; j < 4; j++)
  19999. + {
  20000. + for(t = 0; t < 4; t++)
  20001. + /* parse input stream into rectangular array */
  20002. + block[t][j] = input[16*i+4*j+t] & 0xFF;
  20003. + }
  20004. + rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  20005. + for (j = 0; j < 4; j++)
  20006. + {
  20007. + /* parse rectangular array into output ciphertext bytes */
  20008. + for(t = 0; t < 4; t++)
  20009. + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
  20010. +
  20011. + }
  20012. + }
  20013. + break;
  20014. +
  20015. + case MODE_CBC:
  20016. + for (j = 0; j < 4; j++)
  20017. + {
  20018. + for(t = 0; t < 4; t++)
  20019. + /* parse initial value into rectangular array */
  20020. + block[t][j] = IV[t+4*j] & 0xFF;
  20021. + }
  20022. + for (i = 0; i < numBlocks; i++)
  20023. + {
  20024. + for (j = 0; j < 4; j++)
  20025. + {
  20026. + for(t = 0; t < 4; t++)
  20027. + /* parse input stream into rectangular array and exor with
  20028. + IV or the previous ciphertext */
  20029. + block[t][j] ^= input[16*i+4*j+t] & 0xFF;
  20030. + }
  20031. + rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  20032. + for (j = 0; j < 4; j++)
  20033. + {
  20034. + /* parse rectangular array into output ciphertext bytes */
  20035. + for(t = 0; t < 4; t++)
  20036. + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
  20037. + }
  20038. + }
  20039. + break;
  20040. +
  20041. + default: return AES_BAD_CIPHER_STATE;
  20042. + }
  20043. +
  20044. + return 0;
  20045. +}
  20046. +
  20047. +int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  20048. + MV_U32 *srcData, int numBlocks, MV_U32 *dstData)
  20049. +{
  20050. + int i, j, t;
  20051. + MV_U8 block[4][MAXBC];
  20052. + MV_U8 iv[4][MAXBC];
  20053. + int rounds;
  20054. + char *input, *outBuffer;
  20055. +
  20056. + input = (char*)srcData;
  20057. + outBuffer = (char*)dstData;
  20058. +
  20059. + if (expandedKey == NULL)
  20060. + {
  20061. + return AES_BAD_KEY_MAT;
  20062. + }
  20063. +
  20064. + /* check parameter consistency: */
  20065. + if (keyLen != 128 && keyLen != 192 && keyLen != 256)
  20066. + {
  20067. + return AES_BAD_KEY_MAT;
  20068. + }
  20069. + if ((mode != MODE_ECB && mode != MODE_CBC))
  20070. + {
  20071. + return AES_BAD_CIPHER_STATE;
  20072. + }
  20073. +
  20074. + switch (keyLen)
  20075. + {
  20076. + case 128: rounds = 10; break;
  20077. + case 192: rounds = 12; break;
  20078. + case 256: rounds = 14; break;
  20079. + default : return (-3); /* this cannot happen */
  20080. + }
  20081. +
  20082. +
  20083. + switch (mode)
  20084. + {
  20085. + case MODE_ECB:
  20086. + for (i = 0; i < numBlocks; i++)
  20087. + {
  20088. + for (j = 0; j < 4; j++)
  20089. + {
  20090. + for(t = 0; t < 4; t++)
  20091. + {
  20092. + /* parse input stream into rectangular array */
  20093. + block[t][j] = input[16*i+4*j+t] & 0xFF;
  20094. + }
  20095. + }
  20096. + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  20097. + for (j = 0; j < 4; j++)
  20098. + {
  20099. + /* parse rectangular array into output ciphertext bytes */
  20100. + for(t = 0; t < 4; t++)
  20101. + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
  20102. + }
  20103. + }
  20104. + break;
  20105. +
  20106. + case MODE_CBC:
  20107. + /* first block */
  20108. + for (j = 0; j < 4; j++)
  20109. + {
  20110. + for(t = 0; t < 4; t++)
  20111. + {
  20112. + /* parse input stream into rectangular array */
  20113. + block[t][j] = input[4*j+t] & 0xFF;
  20114. + iv[t][j] = block[t][j];
  20115. + }
  20116. + }
  20117. + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  20118. +
  20119. + for (j = 0; j < 4; j++)
  20120. + {
  20121. + /* exor the IV and parse rectangular array into output ciphertext bytes */
  20122. + for(t = 0; t < 4; t++)
  20123. + {
  20124. + outBuffer[4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);
  20125. + IV[t+4*j] = iv[t][j];
  20126. + }
  20127. + }
  20128. +
  20129. + /* next blocks */
  20130. + for (i = 1; i < numBlocks; i++)
  20131. + {
  20132. + for (j = 0; j < 4; j++)
  20133. + {
  20134. + for(t = 0; t < 4; t++)
  20135. + {
  20136. + /* parse input stream into rectangular array */
  20137. + iv[t][j] = input[16*i+4*j+t] & 0xFF;
  20138. + block[t][j] = iv[t][j];
  20139. + }
  20140. + }
  20141. + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  20142. +
  20143. + for (j = 0; j < 4; j++)
  20144. + {
  20145. + /* exor previous ciphertext block and parse rectangular array
  20146. + into output ciphertext bytes */
  20147. + for(t = 0; t < 4; t++)
  20148. + {
  20149. + outBuffer[16*i+4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);
  20150. + IV[t+4*j] = iv[t][j];
  20151. + }
  20152. + }
  20153. + }
  20154. + break;
  20155. +
  20156. + default: return AES_BAD_CIPHER_STATE;
  20157. + }
  20158. +
  20159. + return 0;
  20160. +}
  20161. +
  20162. +
  20163. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAes.h linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAes.h
  20164. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAes.h 1970-01-01 01:00:00.000000000 +0100
  20165. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAes.h 2011-07-31 11:31:54.835924463 +0200
  20166. @@ -0,0 +1,62 @@
  20167. +/* mvAes.h v2.0 August '99
  20168. + * Reference ANSI C code
  20169. + */
  20170. +
  20171. +/* AES Cipher header file for ANSI C Submissions
  20172. + Lawrence E. Bassham III
  20173. + Computer Security Division
  20174. + National Institute of Standards and Technology
  20175. +
  20176. + April 15, 1998
  20177. +
  20178. + This sample is to assist implementers developing to the Cryptographic
  20179. +API Profile for AES Candidate Algorithm Submissions. Please consult this
  20180. +document as a cross-reference.
  20181. +
  20182. + ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE
  20183. +MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH
  20184. +THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS CANNOT
  20185. +BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO INCLUDE
  20186. +IMPLEMENTATION SPECIFIC INFORMATION.
  20187. +*/
  20188. +
  20189. +/* Includes:
  20190. + Standard include files
  20191. +*/
  20192. +
  20193. +#include "mvOs.h"
  20194. +
  20195. +
  20196. +/* Error Codes - CHANGE POSSIBLE: inclusion of additional error codes */
  20197. +
  20198. +/* Key direction is invalid, e.g., unknown value */
  20199. +#define AES_BAD_KEY_DIR -1
  20200. +
  20201. +/* Key material not of correct length */
  20202. +#define AES_BAD_KEY_MAT -2
  20203. +
  20204. +/* Key passed is not valid */
  20205. +#define AES_BAD_KEY_INSTANCE -3
  20206. +
  20207. +/* Params struct passed to cipherInit invalid */
  20208. +#define AES_BAD_CIPHER_MODE -4
  20209. +
  20210. +/* Cipher in wrong state (e.g., not initialized) */
  20211. +#define AES_BAD_CIPHER_STATE -5
  20212. +
  20213. +#define AES_BAD_CIPHER_INSTANCE -7
  20214. +
  20215. +
  20216. +/* Function protoypes */
  20217. +/* CHANGED: makeKey(): parameter blockLen added
  20218. + this parameter is absolutely necessary if you want to
  20219. + setup the round keys in a variable block length setting
  20220. + cipherInit(): parameter blockLen added (for obvious reasons)
  20221. + */
  20222. +int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen);
  20223. +int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  20224. + MV_U32 *plain, int numBlocks, MV_U32 *cipher);
  20225. +int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  20226. + MV_U32 *plain, int numBlocks, MV_U32 *cipher);
  20227. +
  20228. +
  20229. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesa.c linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesa.c
  20230. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesa.c 1970-01-01 01:00:00.000000000 +0100
  20231. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesa.c 2011-07-31 11:31:54.853425894 +0200
  20232. @@ -0,0 +1,3126 @@
  20233. +/*******************************************************************************
  20234. +Copyright (C) Marvell International Ltd. and its affiliates
  20235. +
  20236. +This software file (the "File") is owned and distributed by Marvell
  20237. +International Ltd. and/or its affiliates ("Marvell") under the following
  20238. +alternative licensing terms. Once you have made an election to distribute the
  20239. +File under one of the following license alternatives, please (i) delete this
  20240. +introductory statement regarding license alternatives, (ii) delete the two
  20241. +license alternatives that you have not elected to use and (iii) preserve the
  20242. +Marvell copyright notice above.
  20243. +
  20244. +********************************************************************************
  20245. +Marvell Commercial License Option
  20246. +
  20247. +If you received this File from Marvell and you have entered into a commercial
  20248. +license agreement (a "Commercial License") with Marvell, the File is licensed
  20249. +to you under the terms of the applicable Commercial License.
  20250. +
  20251. +********************************************************************************
  20252. +Marvell GPL License Option
  20253. +
  20254. +If you received this File from Marvell, you may opt to use, redistribute and/or
  20255. +modify this File in accordance with the terms and conditions of the General
  20256. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  20257. +available along with the File in the license.txt file or by writing to the Free
  20258. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  20259. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  20260. +
  20261. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  20262. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  20263. +DISCLAIMED. The GPL License provides additional details about this warranty
  20264. +disclaimer.
  20265. +********************************************************************************
  20266. +Marvell BSD License Option
  20267. +
  20268. +If you received this File from Marvell, you may opt to use, redistribute and/or
  20269. +modify this File under the following licensing terms.
  20270. +Redistribution and use in source and binary forms, with or without modification,
  20271. +are permitted provided that the following conditions are met:
  20272. +
  20273. + * Redistributions of source code must retain the above copyright notice,
  20274. + this list of conditions and the following disclaimer.
  20275. +
  20276. + * Redistributions in binary form must reproduce the above copyright
  20277. + notice, this list of conditions and the following disclaimer in the
  20278. + documentation and/or other materials provided with the distribution.
  20279. +
  20280. + * Neither the name of Marvell nor the names of its contributors may be
  20281. + used to endorse or promote products derived from this software without
  20282. + specific prior written permission.
  20283. +
  20284. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20285. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20286. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20287. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  20288. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20289. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20290. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  20291. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  20292. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  20293. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  20294. +
  20295. +*******************************************************************************/
  20296. +
  20297. +#include "cesa/mvCesa.h"
  20298. +
  20299. +#include "ctrlEnv/mvCtrlEnvLib.h"
  20300. +#undef CESA_DEBUG
  20301. +
  20302. +
  20303. +/********** Global variables **********/
  20304. +
  20305. +/* If request size is more than MV_CESA_MAX_BUF_SIZE the
  20306. + * request is processed as fragmented request.
  20307. + */
  20308. +
  20309. +MV_CESA_STATS cesaStats;
  20310. +
  20311. +MV_BUF_INFO cesaSramSaBuf;
  20312. +short cesaLastSid = -1;
  20313. +MV_CESA_SA* pCesaSAD = NULL;
  20314. +MV_U16 cesaMaxSA = 0;
  20315. +
  20316. +MV_CESA_REQ* pCesaReqFirst = NULL;
  20317. +MV_CESA_REQ* pCesaReqLast = NULL;
  20318. +MV_CESA_REQ* pCesaReqEmpty = NULL;
  20319. +MV_CESA_REQ* pCesaReqProcess = NULL;
  20320. +int cesaQueueDepth = 0;
  20321. +int cesaReqResources = 0;
  20322. +
  20323. +MV_CESA_SRAM_MAP* cesaSramVirtPtr = NULL;
  20324. +MV_U32 cesaCryptEngBase = 0;
  20325. +void *cesaOsHandle = NULL;
  20326. +#if (MV_CESA_VERSION >= 3)
  20327. +MV_U32 cesaChainLength = 0;
  20328. +int chainReqNum = 0;
  20329. +MV_U32 chainIndex = 0;
  20330. +MV_CESA_REQ* pNextActiveChain = 0;
  20331. +MV_CESA_REQ* pEndCurrChain = 0;
  20332. +MV_BOOL isFirstReq = MV_TRUE;
  20333. +#endif
  20334. +
  20335. +static INLINE MV_U8* mvCesaSramAddrGet(void)
  20336. +{
  20337. +#ifdef MV_CESA_NO_SRAM
  20338. + return (MV_U8*)cesaSramVirtPtr;
  20339. +#else
  20340. + return (MV_U8*)cesaCryptEngBase;
  20341. +#endif /* MV_CESA_NO_SRAM */
  20342. +}
  20343. +
  20344. +static INLINE MV_ULONG mvCesaSramVirtToPhys(void* pDev, MV_U8* pSramVirt)
  20345. +{
  20346. +#ifdef MV_CESA_NO_SRAM
  20347. + return (MV_ULONG)mvOsIoVirtToPhy(NULL, pSramVirt);
  20348. +#else
  20349. + return (MV_ULONG)pSramVirt;
  20350. +#endif /* MV_CESA_NO_SRAM */
  20351. +}
  20352. +
  20353. +/* Internal Function prototypes */
  20354. +
  20355. +static INLINE void mvCesaSramDescrBuild(MV_U32 config, int frag,
  20356. + int cryptoOffset, int ivOffset, int cryptoLength,
  20357. + int macOffset, int digestOffset, int macLength, int macTotalLen,
  20358. + MV_CESA_REQ *pCesaReq, MV_DMA_DESC* pDmaDesc);
  20359. +
  20360. +static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc);
  20361. +
  20362. +static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
  20363. + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
  20364. + int offset, int copySize, MV_BOOL skipFlush);
  20365. +
  20366. +static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,
  20367. + unsigned char innerIV[], unsigned char outerIV[]);
  20368. +
  20369. +static MV_STATUS mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,
  20370. + int macDataSize);
  20371. +
  20372. +static MV_CESA_COMMAND* mvCesaCtrModeInit(void);
  20373. +
  20374. +static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd);
  20375. +static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd);
  20376. +static void mvCesaCtrModeFinish(MV_CESA_COMMAND *pCmd);
  20377. +
  20378. +static INLINE MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq);
  20379. +static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag);
  20380. +
  20381. +static INLINE MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset);
  20382. +static INLINE MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd);
  20383. +
  20384. +static INLINE void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq,
  20385. + int cryptoOffset, int macOffset,
  20386. + int* pCopySize, int* pCryptoDataSize, int* pMacDataSize);
  20387. +static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size);
  20388. +
  20389. +
  20390. +/* Go to the next request in the request queue */
  20391. +static INLINE MV_CESA_REQ* MV_CESA_REQ_NEXT_PTR(MV_CESA_REQ* pReq)
  20392. +{
  20393. + if(pReq == pCesaReqLast)
  20394. + return pCesaReqFirst;
  20395. +
  20396. + return pReq+1;
  20397. +}
  20398. +
  20399. +#if (MV_CESA_VERSION >= 3)
  20400. +/* Go to the previous request in the request queue */
  20401. +static INLINE MV_CESA_REQ* MV_CESA_REQ_PREV_PTR(MV_CESA_REQ* pReq)
  20402. +{
  20403. + if(pReq == pCesaReqFirst)
  20404. + return pCesaReqLast;
  20405. +
  20406. + return pReq-1;
  20407. +}
  20408. +
  20409. +#endif
  20410. +
  20411. +
  20412. +static INLINE void mvCesaReqProcessStart(MV_CESA_REQ* pReq)
  20413. +{
  20414. + int frag;
  20415. +
  20416. +#if (MV_CESA_VERSION >= 3)
  20417. + pReq->state = MV_CESA_CHAIN;
  20418. +#else
  20419. + pReq->state = MV_CESA_PROCESS;
  20420. +#endif
  20421. + cesaStats.startCount++;
  20422. +
  20423. + if(pReq->fragMode == MV_CESA_FRAG_NONE)
  20424. + {
  20425. + frag = 0;
  20426. + }
  20427. + else
  20428. + {
  20429. + frag = pReq->frags.nextFrag;
  20430. + pReq->frags.nextFrag++;
  20431. + }
  20432. +#if (MV_CESA_VERSION >= 2)
  20433. + /* Enable TDMA engine */
  20434. + MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);
  20435. + MV_REG_WRITE(MV_CESA_TDMA_NEXT_DESC_PTR_REG,
  20436. + (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
  20437. +#else
  20438. + /* Enable IDMA engine */
  20439. + MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
  20440. + MV_REG_WRITE(IDMA_NEXT_DESC_PTR_REG(0),
  20441. + (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
  20442. +#endif /* MV_CESA_VERSION >= 2 */
  20443. +
  20444. +#if defined(MV_BRIDGE_SYNC_REORDER)
  20445. + mvOsBridgeReorderWA();
  20446. +#endif
  20447. +
  20448. + /* Start Accelerator */
  20449. + MV_REG_WRITE(MV_CESA_CMD_REG, MV_CESA_CMD_CHAN_ENABLE_MASK);
  20450. +}
  20451. +
  20452. +
  20453. +/*******************************************************************************
  20454. +* mvCesaHalInit - Initialize the CESA driver
  20455. +*
  20456. +* DESCRIPTION:
  20457. +* This function initialize the CESA driver.
  20458. +* 1) Session database
  20459. +* 2) Request queue
  20460. +* 4) DMA descriptor lists - one list per request. Each list
  20461. +* has MV_CESA_MAX_DMA_DESC descriptors.
  20462. +*
  20463. +* INPUT:
  20464. +* numOfSession - maximum number of supported sessions
  20465. +* queueDepth - number of elements in the request queue.
  20466. +* pSramBase - virtual address of Sram
  20467. +* osHandle - A handle used by the OS to allocate memory for the
  20468. +* module (Passed to the OS Services layer)
  20469. +*
  20470. +* RETURN:
  20471. +* MV_OK - Success
  20472. +* MV_NO_RESOURCE - Fail, can't allocate resources:
  20473. +* Session database, request queue,
  20474. +* DMA descriptors list, LRU cache database.
  20475. +* MV_NOT_ALIGNED - Sram base address is not 8 byte aligned.
  20476. +*
  20477. +*******************************************************************************/
  20478. +MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase,
  20479. + void *osHandle)
  20480. +{
  20481. + int i, req;
  20482. + MV_U32 descOffsetReg, configReg;
  20483. + MV_CESA_SRAM_SA *pSramSA;
  20484. +
  20485. +
  20486. + mvOsPrintf("mvCesaInit: sessions=%d, queue=%d, pSram=%p\n",
  20487. + numOfSession, queueDepth, pSramBase);
  20488. +
  20489. + cesaOsHandle = osHandle;
  20490. + /* Create Session database */
  20491. + pCesaSAD = mvOsMalloc(sizeof(MV_CESA_SA)*numOfSession);
  20492. + if(pCesaSAD == NULL)
  20493. + {
  20494. + mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d SAs\n",
  20495. + sizeof(MV_CESA_SA)*numOfSession, numOfSession);
  20496. + mvCesaFinish();
  20497. + return MV_NO_RESOURCE;
  20498. + }
  20499. + memset(pCesaSAD, 0, sizeof(MV_CESA_SA)*numOfSession);
  20500. + cesaMaxSA = numOfSession;
  20501. +
  20502. + /* Allocate imag of sramSA in the DRAM */
  20503. + cesaSramSaBuf.bufSize = sizeof(MV_CESA_SRAM_SA)*numOfSession +
  20504. + CPU_D_CACHE_LINE_SIZE;
  20505. +
  20506. + cesaSramSaBuf.bufVirtPtr = mvOsIoCachedMalloc(osHandle,cesaSramSaBuf.bufSize,
  20507. + &cesaSramSaBuf.bufPhysAddr,
  20508. + &cesaSramSaBuf.memHandle);
  20509. +
  20510. + if(cesaSramSaBuf.bufVirtPtr == NULL)
  20511. + {
  20512. + mvOsPrintf("mvCesaInit: Can't allocate %d bytes for sramSA structures\n",
  20513. + cesaSramSaBuf.bufSize);
  20514. + mvCesaFinish();
  20515. + return MV_NO_RESOURCE;
  20516. + }
  20517. + memset(cesaSramSaBuf.bufVirtPtr, 0, cesaSramSaBuf.bufSize);
  20518. + pSramSA = (MV_CESA_SRAM_SA*)MV_ALIGN_UP((MV_ULONG)cesaSramSaBuf.bufVirtPtr,
  20519. + CPU_D_CACHE_LINE_SIZE);
  20520. + for(i=0; i<numOfSession; i++)
  20521. + {
  20522. + pCesaSAD[i].pSramSA = &pSramSA[i];
  20523. + }
  20524. +
  20525. + /* Create request queue */
  20526. + pCesaReqFirst = mvOsMalloc(sizeof(MV_CESA_REQ)*queueDepth);
  20527. + if(pCesaReqFirst == NULL)
  20528. + {
  20529. + mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d requests\n",
  20530. + sizeof(MV_CESA_REQ)*queueDepth, queueDepth);
  20531. + mvCesaFinish();
  20532. + return MV_NO_RESOURCE;
  20533. + }
  20534. + memset(pCesaReqFirst, 0, sizeof(MV_CESA_REQ)*queueDepth);
  20535. + pCesaReqEmpty = pCesaReqFirst;
  20536. + pCesaReqLast = pCesaReqFirst + (queueDepth-1);
  20537. + pCesaReqProcess = pCesaReqEmpty;
  20538. + cesaQueueDepth = queueDepth;
  20539. + cesaReqResources = queueDepth;
  20540. +#if (MV_CESA_VERSION >= 3)
  20541. + cesaChainLength = MAX_CESA_CHAIN_LENGTH;
  20542. +#endif
  20543. + /* pSramBase must be 8 byte aligned */
  20544. + if( MV_IS_NOT_ALIGN((MV_ULONG)pSramBase, 8) )
  20545. + {
  20546. + mvOsPrintf("mvCesaInit: pSramBase (%p) must be 8 byte aligned\n",
  20547. + pSramBase);
  20548. + mvCesaFinish();
  20549. + return MV_NOT_ALIGNED;
  20550. + }
  20551. + cesaSramVirtPtr = (MV_CESA_SRAM_MAP*)pSramBase;
  20552. +
  20553. + cesaCryptEngBase = cryptEngBase;
  20554. +
  20555. + /*memset(cesaSramVirtPtr, 0, sizeof(MV_CESA_SRAM_MAP));*/
  20556. +
  20557. + /* Clear registers */
  20558. + MV_REG_WRITE( MV_CESA_CFG_REG, 0);
  20559. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  20560. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
  20561. +
  20562. + /* Initialize DMA descriptor lists for all requests in Request queue */
  20563. + descOffsetReg = configReg = 0;
  20564. + for(req=0; req<queueDepth; req++)
  20565. + {
  20566. + int frag;
  20567. + MV_CESA_REQ* pReq;
  20568. + MV_DMA_DESC* pDmaDesc;
  20569. +
  20570. + pReq = &pCesaReqFirst[req];
  20571. +
  20572. + pReq->cesaDescBuf.bufSize = sizeof(MV_CESA_DESC)*MV_CESA_MAX_REQ_FRAGS +
  20573. + CPU_D_CACHE_LINE_SIZE;
  20574. +
  20575. + pReq->cesaDescBuf.bufVirtPtr =
  20576. + mvOsIoCachedMalloc(osHandle,pReq->cesaDescBuf.bufSize,
  20577. + &pReq->cesaDescBuf.bufPhysAddr,
  20578. + &pReq->cesaDescBuf.memHandle);
  20579. +
  20580. + if(pReq->cesaDescBuf.bufVirtPtr == NULL)
  20581. + {
  20582. + mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for CESA descriptors\n",
  20583. + req, pReq->cesaDescBuf.bufSize);
  20584. + mvCesaFinish();
  20585. + return MV_NO_RESOURCE;
  20586. + }
  20587. + memset(pReq->cesaDescBuf.bufVirtPtr, 0, pReq->cesaDescBuf.bufSize);
  20588. + pReq->pCesaDesc = (MV_CESA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->cesaDescBuf.bufVirtPtr,
  20589. + CPU_D_CACHE_LINE_SIZE);
  20590. +
  20591. + pReq->dmaDescBuf.bufSize = sizeof(MV_DMA_DESC)*MV_CESA_MAX_DMA_DESC*MV_CESA_MAX_REQ_FRAGS +
  20592. + CPU_D_CACHE_LINE_SIZE;
  20593. +
  20594. + pReq->dmaDescBuf.bufVirtPtr =
  20595. + mvOsIoCachedMalloc(osHandle,pReq->dmaDescBuf.bufSize,
  20596. + &pReq->dmaDescBuf.bufPhysAddr,
  20597. + &pReq->dmaDescBuf.memHandle);
  20598. +
  20599. + if(pReq->dmaDescBuf.bufVirtPtr == NULL)
  20600. + {
  20601. + mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for DMA descriptor list\n",
  20602. + req, pReq->dmaDescBuf.bufSize);
  20603. + mvCesaFinish();
  20604. + return MV_NO_RESOURCE;
  20605. + }
  20606. + memset(pReq->dmaDescBuf.bufVirtPtr, 0, pReq->dmaDescBuf.bufSize);
  20607. + pDmaDesc = (MV_DMA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->dmaDescBuf.bufVirtPtr,
  20608. + CPU_D_CACHE_LINE_SIZE);
  20609. +
  20610. + for(frag=0; frag<MV_CESA_MAX_REQ_FRAGS; frag++)
  20611. + {
  20612. + MV_CESA_DMA* pDma = &pReq->dma[frag];
  20613. +
  20614. + pDma->pDmaFirst = pDmaDesc;
  20615. + pDma->pDmaLast = NULL;
  20616. +
  20617. + for(i=0; i<MV_CESA_MAX_DMA_DESC-1; i++)
  20618. + {
  20619. + /* link all DMA descriptors together */
  20620. + pDma->pDmaFirst[i].phyNextDescPtr =
  20621. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pDmaDesc[i+1]));
  20622. + }
  20623. + pDma->pDmaFirst[i].phyNextDescPtr = 0;
  20624. + mvOsCacheFlush(NULL, &pDma->pDmaFirst[0], MV_CESA_MAX_DMA_DESC*sizeof(MV_DMA_DESC));
  20625. +
  20626. + pDmaDesc += MV_CESA_MAX_DMA_DESC;
  20627. + }
  20628. + }
  20629. + /*mvCesaCryptoIvSet(NULL, MV_CESA_MAX_IV_LENGTH);*/
  20630. + descOffsetReg = (MV_U16)((MV_U8*)&cesaSramVirtPtr->desc - mvCesaSramAddrGet());
  20631. + MV_REG_WRITE(MV_CESA_CHAN_DESC_OFFSET_REG, descOffsetReg);
  20632. +
  20633. + configReg |= (MV_CESA_CFG_WAIT_DMA_MASK | MV_CESA_CFG_ACT_DMA_MASK);
  20634. +#if (MV_CESA_VERSION >= 3)
  20635. + configReg |= MV_CESA_CFG_CHAIN_MODE_MASK;
  20636. +#endif
  20637. +
  20638. +#if (MV_CESA_VERSION >= 2)
  20639. + /* Initialize TDMA engine */
  20640. + MV_REG_WRITE(MV_CESA_TDMA_CTRL_REG, MV_CESA_TDMA_CTRL_VALUE);
  20641. + MV_REG_WRITE(MV_CESA_TDMA_BYTE_COUNT_REG, 0);
  20642. + MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);
  20643. +#else
  20644. + /* Initialize IDMA #0 engine */
  20645. + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
  20646. + MV_REG_WRITE(IDMA_BYTE_COUNT_REG(0), 0);
  20647. + MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
  20648. + MV_REG_WRITE(IDMA_CTRL_HIGH_REG(0), ICCHR_ENDIAN_LITTLE
  20649. +#ifdef MV_CPU_LE
  20650. + | ICCHR_DESC_BYTE_SWAP_EN
  20651. +#endif
  20652. + );
  20653. + /* Clear Cause Byte of IDMA channel to be used */
  20654. + MV_REG_WRITE( IDMA_CAUSE_REG, ~ICICR_CAUSE_MASK_ALL(0));
  20655. + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), MV_CESA_IDMA_CTRL_LOW_VALUE);
  20656. +#endif /* (MV_CESA_VERSION >= 2) */
  20657. +
  20658. + /* Set CESA configuration registers */
  20659. + MV_REG_WRITE( MV_CESA_CFG_REG, configReg);
  20660. + mvCesaDebugStatsClear();
  20661. +
  20662. + return MV_OK;
  20663. +}
  20664. +
  20665. +/*******************************************************************************
  20666. +* mvCesaFinish - Shutdown the CESA driver
  20667. +*
  20668. +* DESCRIPTION:
  20669. +* This function shutdown the CESA driver and free all allocted resources.
  20670. +*
  20671. +* INPUT: None
  20672. +*
  20673. +* RETURN:
  20674. +* MV_OK - Success
  20675. +* Other - Fail
  20676. +*
  20677. +*******************************************************************************/
  20678. +MV_STATUS mvCesaFinish (void)
  20679. +{
  20680. + int req;
  20681. + MV_CESA_REQ* pReq;
  20682. +
  20683. + mvOsPrintf("mvCesaFinish: \n");
  20684. +
  20685. + cesaSramVirtPtr = NULL;
  20686. +
  20687. + /* Free all resources: DMA list, etc. */
  20688. + for(req=0; req<cesaQueueDepth; req++)
  20689. + {
  20690. + pReq = &pCesaReqFirst[req];
  20691. + if(pReq->dmaDescBuf.bufVirtPtr != NULL)
  20692. + {
  20693. + mvOsIoCachedFree(cesaOsHandle,pReq->dmaDescBuf.bufSize,
  20694. + pReq->dmaDescBuf.bufPhysAddr,
  20695. + pReq->dmaDescBuf.bufVirtPtr,
  20696. + pReq->dmaDescBuf.memHandle);
  20697. + }
  20698. + if(pReq->cesaDescBuf.bufVirtPtr != NULL)
  20699. + {
  20700. + mvOsIoCachedFree(cesaOsHandle,pReq->cesaDescBuf.bufSize,
  20701. + pReq->cesaDescBuf.bufPhysAddr,
  20702. + pReq->cesaDescBuf.bufVirtPtr,
  20703. + pReq->cesaDescBuf.memHandle);
  20704. + }
  20705. + }
  20706. +#if (MV_CESA_VERSION < 2)
  20707. + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
  20708. +#endif /* (MV_CESA_VERSION < 2) */
  20709. +
  20710. + /* Free request queue */
  20711. + if(pCesaReqFirst != NULL)
  20712. + {
  20713. + mvOsFree(pCesaReqFirst);
  20714. + pCesaReqFirst = pCesaReqLast = NULL;
  20715. + pCesaReqEmpty = pCesaReqProcess = NULL;
  20716. + cesaQueueDepth = cesaReqResources = 0;
  20717. + }
  20718. + /* Free SA database */
  20719. + if(pCesaSAD != NULL)
  20720. + {
  20721. + mvOsFree(pCesaSAD);
  20722. + pCesaSAD = NULL;
  20723. + cesaMaxSA = 0;
  20724. + }
  20725. + MV_REG_WRITE( MV_CESA_CFG_REG, 0);
  20726. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  20727. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
  20728. +
  20729. + return MV_OK;
  20730. +}
  20731. +
  20732. +/*******************************************************************************
  20733. +* mvCesaCryptoIvSet - Set IV value for Crypto algorithm working in CBC mode
  20734. +*
  20735. +* DESCRIPTION:
  20736. +* This function set IV value using by Crypto algorithms in CBC mode.
  20737. +* Each channel has its own IV value.
  20738. +* This function gets IV value from the caller. If no IV value passed from
  20739. +* the caller or only part of IV passed, the function will init the rest part
  20740. +* of IV value (or the whole IV) by random value.
  20741. +*
  20742. +* INPUT:
  20743. +* MV_U8* pIV - Pointer to IV value supplied by user. If pIV==NULL
  20744. +* the function will generate random IV value.
  20745. +* int ivSize - size (in bytes) of IV provided by user. If ivSize is
  20746. +* smaller than maximum IV size, the function will complete
  20747. +* IV by random value.
  20748. +*
  20749. +* RETURN:
  20750. +* MV_OK - Success
  20751. +* Other - Fail
  20752. +*
  20753. +*******************************************************************************/
  20754. +MV_STATUS mvCesaCryptoIvSet(MV_U8* pIV, int ivSize)
  20755. +{
  20756. + MV_U8* pSramIV;
  20757. +#if defined(MV646xx)
  20758. + mvOsPrintf("mvCesaCryptoIvSet: ERR. shouldn't use this call on MV64660\n");
  20759. +#endif
  20760. + pSramIV = cesaSramVirtPtr->cryptoIV;
  20761. + if(ivSize > MV_CESA_MAX_IV_LENGTH)
  20762. + {
  20763. + mvOsPrintf("mvCesaCryptoIvSet: ivSize (%d) is too large\n", ivSize);
  20764. + ivSize = MV_CESA_MAX_IV_LENGTH;
  20765. + }
  20766. + if(pIV != NULL)
  20767. + {
  20768. + memcpy(pSramIV, pIV, ivSize);
  20769. + ivSize = MV_CESA_MAX_IV_LENGTH - ivSize;
  20770. + pSramIV += ivSize;
  20771. + }
  20772. +
  20773. + while(ivSize > 0)
  20774. + {
  20775. + int size, mv_random = mvOsRand();
  20776. +
  20777. + size = MV_MIN(ivSize, sizeof(mv_random));
  20778. + memcpy(pSramIV, (void*)&mv_random, size);
  20779. +
  20780. + pSramIV += size;
  20781. + ivSize -= size;
  20782. + }
  20783. +/*
  20784. + mvOsCacheFlush(NULL, cesaSramVirtPtr->cryptoIV,
  20785. + MV_CESA_MAX_IV_LENGTH);
  20786. + mvOsCacheInvalidate(NULL, cesaSramVirtPtr->cryptoIV,
  20787. + MV_CESA_MAX_IV_LENGTH);
  20788. +*/
  20789. + return MV_OK;
  20790. +}
  20791. +
  20792. +/*******************************************************************************
  20793. +* mvCesaSessionOpen - Open new uni-directional crypto session
  20794. +*
  20795. +* DESCRIPTION:
  20796. +* This function open new session.
  20797. +*
  20798. +* INPUT:
  20799. +* MV_CESA_OPEN_SESSION *pSession - pointer to new session input parameters
  20800. +*
  20801. +* OUTPUT:
  20802. +* short *pSid - session ID, should be used for all future
  20803. +* requests over this session.
  20804. +*
  20805. +* RETURN:
  20806. +* MV_OK - Session opend successfully.
  20807. +* MV_FULL - All sessions are in use, no free place in
  20808. +* SA database.
  20809. +* MV_BAD_PARAM - One of session input parameters is invalid.
  20810. +*
  20811. +*******************************************************************************/
  20812. +MV_STATUS mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid)
  20813. +{
  20814. + short sid;
  20815. + MV_U32 config = 0;
  20816. + int digestSize;
  20817. +
  20818. + cesaStats.openedCount++;
  20819. +
  20820. + /* Find free entry in SAD */
  20821. + for(sid=0; sid<cesaMaxSA; sid++)
  20822. + {
  20823. + if(pCesaSAD[sid].valid == 0)
  20824. + {
  20825. + break;
  20826. + }
  20827. + }
  20828. + if(sid == cesaMaxSA)
  20829. + {
  20830. + mvOsPrintf("mvCesaSessionOpen: SA Database is FULL\n");
  20831. + return MV_FULL;
  20832. + }
  20833. +
  20834. + /* Check Input parameters for Open session */
  20835. + if (pSession->operation >= MV_CESA_MAX_OPERATION)
  20836. + {
  20837. + mvOsPrintf("mvCesaSessionOpen: Unexpected operation %d\n",
  20838. + pSession->operation);
  20839. + return MV_BAD_PARAM;
  20840. + }
  20841. + config |= (pSession->operation << MV_CESA_OPERATION_OFFSET);
  20842. +
  20843. + if( (pSession->direction != MV_CESA_DIR_ENCODE) &&
  20844. + (pSession->direction != MV_CESA_DIR_DECODE) )
  20845. + {
  20846. + mvOsPrintf("mvCesaSessionOpen: Unexpected direction %d\n",
  20847. + pSession->direction);
  20848. + return MV_BAD_PARAM;
  20849. + }
  20850. + config |= (pSession->direction << MV_CESA_DIRECTION_BIT);
  20851. + /* Clear SA entry */
  20852. + /* memset(&pCesaSAD[sid], 0, sizeof(pCesaSAD[sid])); */
  20853. +
  20854. + /* Check AUTH parameters and update SA entry */
  20855. + if(pSession->operation != MV_CESA_CRYPTO_ONLY)
  20856. + {
  20857. + /* For HMAC (MD5 and SHA1) - Maximum Key size is 64 bytes */
  20858. + if( (pSession->macMode == MV_CESA_MAC_HMAC_MD5) ||
  20859. + (pSession->macMode == MV_CESA_MAC_HMAC_SHA1) )
  20860. + {
  20861. + if(pSession->macKeyLength > MV_CESA_MAX_MAC_KEY_LENGTH)
  20862. + {
  20863. + mvOsPrintf("mvCesaSessionOpen: macKeyLength %d is too large\n",
  20864. + pSession->macKeyLength);
  20865. + return MV_BAD_PARAM;
  20866. + }
  20867. + mvCesaHmacIvGet(pSession->macMode, pSession->macKey, pSession->macKeyLength,
  20868. + pCesaSAD[sid].pSramSA->macInnerIV,
  20869. + pCesaSAD[sid].pSramSA->macOuterIV);
  20870. + pCesaSAD[sid].macKeyLength = pSession->macKeyLength;
  20871. + }
  20872. + switch(pSession->macMode)
  20873. + {
  20874. + case MV_CESA_MAC_MD5:
  20875. + case MV_CESA_MAC_HMAC_MD5:
  20876. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  20877. + break;
  20878. +
  20879. + case MV_CESA_MAC_SHA1:
  20880. + case MV_CESA_MAC_HMAC_SHA1:
  20881. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  20882. + break;
  20883. +
  20884. + default:
  20885. + mvOsPrintf("mvCesaSessionOpen: Unexpected macMode %d\n",
  20886. + pSession->macMode);
  20887. + return MV_BAD_PARAM;
  20888. + }
  20889. + config |= (pSession->macMode << MV_CESA_MAC_MODE_OFFSET);
  20890. +
  20891. + /* Supported digest sizes: MD5 - 16 bytes (128 bits), */
  20892. + /* SHA1 - 20 bytes (160 bits) or 12 bytes (96 bits) for both */
  20893. + if( (pSession->digestSize != digestSize) && (pSession->digestSize != 12))
  20894. + {
  20895. + mvOsPrintf("mvCesaSessionOpen: Unexpected digest size %d\n",
  20896. + pSession->digestSize);
  20897. + mvOsPrintf("\t Valid values [bytes]: MD5-16, SHA1-20, Both-12\n");
  20898. + return MV_BAD_PARAM;
  20899. + }
  20900. + pCesaSAD[sid].digestSize = pSession->digestSize;
  20901. +
  20902. + if(pCesaSAD[sid].digestSize == 12)
  20903. + {
  20904. + /* Set MV_CESA_MAC_DIGEST_SIZE_BIT if digest size is 96 bits */
  20905. + config |= (MV_CESA_MAC_DIGEST_96B << MV_CESA_MAC_DIGEST_SIZE_BIT);
  20906. + }
  20907. + }
  20908. +
  20909. + /* Check CRYPTO parameters and update SA entry */
  20910. + if(pSession->operation != MV_CESA_MAC_ONLY)
  20911. + {
  20912. + switch(pSession->cryptoAlgorithm)
  20913. + {
  20914. + case MV_CESA_CRYPTO_DES:
  20915. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_DES_KEY_LENGTH;
  20916. + pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;
  20917. + break;
  20918. +
  20919. + case MV_CESA_CRYPTO_3DES:
  20920. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_3DES_KEY_LENGTH;
  20921. + pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;
  20922. + /* Only EDE mode is supported */
  20923. + config |= (MV_CESA_CRYPTO_3DES_EDE <<
  20924. + MV_CESA_CRYPTO_3DES_MODE_BIT);
  20925. + break;
  20926. +
  20927. + case MV_CESA_CRYPTO_AES:
  20928. + switch(pSession->cryptoKeyLength)
  20929. + {
  20930. + case 16:
  20931. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_128_KEY_LENGTH;
  20932. + config |= (MV_CESA_CRYPTO_AES_KEY_128 <<
  20933. + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
  20934. + break;
  20935. +
  20936. + case 24:
  20937. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_192_KEY_LENGTH;
  20938. + config |= (MV_CESA_CRYPTO_AES_KEY_192 <<
  20939. + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
  20940. + break;
  20941. +
  20942. + case 32:
  20943. + default:
  20944. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_256_KEY_LENGTH;
  20945. + config |= (MV_CESA_CRYPTO_AES_KEY_256 <<
  20946. + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
  20947. + break;
  20948. + }
  20949. + pCesaSAD[sid].cryptoBlockSize = MV_CESA_AES_BLOCK_SIZE;
  20950. + break;
  20951. +
  20952. + default:
  20953. + mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoAlgorithm %d\n",
  20954. + pSession->cryptoAlgorithm);
  20955. + return MV_BAD_PARAM;
  20956. + }
  20957. + config |= (pSession->cryptoAlgorithm << MV_CESA_CRYPTO_ALG_OFFSET);
  20958. +
  20959. + if(pSession->cryptoKeyLength != pCesaSAD[sid].cryptoKeyLength)
  20960. + {
  20961. + mvOsPrintf("cesaSessionOpen: Wrong CryptoKeySize %d != %d\n",
  20962. + pSession->cryptoKeyLength, pCesaSAD[sid].cryptoKeyLength);
  20963. + return MV_BAD_PARAM;
  20964. + }
  20965. +
  20966. + /* Copy Crypto key */
  20967. + if( (pSession->cryptoAlgorithm == MV_CESA_CRYPTO_AES) &&
  20968. + (pSession->direction == MV_CESA_DIR_DECODE))
  20969. + {
  20970. + /* Crypto Key for AES decode is computed from original key material */
  20971. + /* and depend on cryptoKeyLength (128/192/256 bits) */
  20972. + aesMakeKey(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey,
  20973. + pSession->cryptoKeyLength*8, MV_CESA_AES_BLOCK_SIZE*8);
  20974. + }
  20975. + else
  20976. + {
  20977. + /*panic("mvCesaSessionOpen2");*/
  20978. + memcpy(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey,
  20979. + pCesaSAD[sid].cryptoKeyLength);
  20980. +
  20981. + }
  20982. +
  20983. + switch(pSession->cryptoMode)
  20984. + {
  20985. + case MV_CESA_CRYPTO_ECB:
  20986. + pCesaSAD[sid].cryptoIvSize = 0;
  20987. + break;
  20988. +
  20989. + case MV_CESA_CRYPTO_CBC:
  20990. + pCesaSAD[sid].cryptoIvSize = pCesaSAD[sid].cryptoBlockSize;
  20991. + break;
  20992. +
  20993. + case MV_CESA_CRYPTO_CTR:
  20994. + /* Supported only for AES algorithm */
  20995. + if(pSession->cryptoAlgorithm != MV_CESA_CRYPTO_AES)
  20996. + {
  20997. + mvOsPrintf("mvCesaSessionOpen: CRYPTO CTR mode supported for AES only\n");
  20998. + return MV_BAD_PARAM;
  20999. + }
  21000. + pCesaSAD[sid].cryptoIvSize = 0;
  21001. + pCesaSAD[sid].ctrMode = 1;
  21002. + /* Replace to ECB mode for HW */
  21003. + pSession->cryptoMode = MV_CESA_CRYPTO_ECB;
  21004. + break;
  21005. +
  21006. + default:
  21007. + mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoMode %d\n",
  21008. + pSession->cryptoMode);
  21009. + return MV_BAD_PARAM;
  21010. + }
  21011. +
  21012. + config |= (pSession->cryptoMode << MV_CESA_CRYPTO_MODE_BIT);
  21013. + }
  21014. + pCesaSAD[sid].config = config;
  21015. +
  21016. + mvOsCacheFlush(NULL, pCesaSAD[sid].pSramSA, sizeof(MV_CESA_SRAM_SA));
  21017. + if(pSid != NULL)
  21018. + *pSid = sid;
  21019. +
  21020. + pCesaSAD[sid].valid = 1;
  21021. + return MV_OK;
  21022. +}
  21023. +
  21024. +/*******************************************************************************
  21025. +* mvCesaSessionClose - Close active crypto session
  21026. +*
  21027. +* DESCRIPTION:
  21028. +* This function closes existing session
  21029. +*
  21030. +* INPUT:
  21031. +* short sid - Unique identifier of the session to be closed
  21032. +*
  21033. +* RETURN:
  21034. +* MV_OK - Session closed successfully.
  21035. +* MV_BAD_PARAM - Session identifier is out of valid range.
  21036. +* MV_NOT_FOUND - There is no active session with such ID.
  21037. +*
  21038. +*******************************************************************************/
  21039. +MV_STATUS mvCesaSessionClose(short sid)
  21040. +{
  21041. + cesaStats.closedCount++;
  21042. +
  21043. + if(sid >= cesaMaxSA)
  21044. + {
  21045. + mvOsPrintf("CESA Error: sid (%d) is too big\n", sid);
  21046. + return MV_BAD_PARAM;
  21047. + }
  21048. + if(pCesaSAD[sid].valid == 0)
  21049. + {
  21050. + mvOsPrintf("CESA Warning: Session (sid=%d) is invalid\n", sid);
  21051. + return MV_NOT_FOUND;
  21052. + }
  21053. + if(cesaLastSid == sid)
  21054. + cesaLastSid = -1;
  21055. +
  21056. + pCesaSAD[sid].valid = 0;
  21057. + return MV_OK;
  21058. +}
  21059. +
  21060. +/*******************************************************************************
  21061. +* mvCesaAction - Perform crypto operation
  21062. +*
  21063. +* DESCRIPTION:
  21064. +* This function set new CESA request FIFO queue for further HW processing.
  21065. +* The function checks request parameters before set new request to the queue.
  21066. +* If one of the CESA channels is ready for processing the request will be
  21067. +* passed to HW. When request processing is finished the CESA interrupt will
  21068. +* be generated by HW. The caller should call mvCesaReadyGet() function to
  21069. +* complete request processing and get result.
  21070. +*
  21071. +* INPUT:
  21072. +* MV_CESA_COMMAND *pCmd - pointer to new CESA request.
  21073. +* It includes pointers to Source and Destination
  21074. +* buffers, session identifier get from
  21075. +* mvCesaSessionOpen() function, pointer to caller
  21076. +* private data and all needed crypto parameters.
  21077. +*
  21078. +* RETURN:
  21079. +* MV_OK - request successfully added to request queue
  21080. +* and will be processed.
  21081. +* MV_NO_MORE - request successfully added to request queue and will
  21082. +* be processed, but request queue became Full and next
  21083. +* request will not be accepted.
  21084. +* MV_NO_RESOURCE - request queue is FULL and the request can not
  21085. +* be processed.
  21086. +* MV_OUT_OF_CPU_MEM - memory allocation needed for request processing is
  21087. +* failed. Request can not be processed.
  21088. +* MV_NOT_ALLOWED - This mixed request (CRYPTO+MAC) can not be processed
  21089. +* as one request and should be splitted for two requests:
  21090. +* CRYPTO_ONLY and MAC_ONLY.
  21091. +* MV_BAD_PARAM - One of the request parameters is out of valid range.
  21092. +* The request can not be processed.
  21093. +*
  21094. +*******************************************************************************/
  21095. +MV_STATUS mvCesaAction (MV_CESA_COMMAND *pCmd)
  21096. +{
  21097. + MV_STATUS status;
  21098. + MV_CESA_REQ* pReq = pCesaReqEmpty;
  21099. + int sid = pCmd->sessionId;
  21100. + MV_CESA_SA* pSA = &pCesaSAD[sid];
  21101. +#if (MV_CESA_VERSION >= 3)
  21102. + MV_CESA_REQ* pFromReq;
  21103. + MV_CESA_REQ* pToReq;
  21104. +#endif
  21105. + cesaStats.reqCount++;
  21106. +
  21107. + /* Check that the request queue is not FULL */
  21108. + if(cesaReqResources == 0)
  21109. + return MV_NO_RESOURCE;
  21110. +
  21111. + if( (sid >= cesaMaxSA) || (!pSA->valid) )
  21112. + {
  21113. + mvOsPrintf("CESA Action Error: Session sid=%d is INVALID\n", sid);
  21114. + return MV_BAD_PARAM;
  21115. + }
  21116. + pSA->count++;
  21117. +
  21118. + if(pSA->ctrMode)
  21119. + {
  21120. + /* AES in CTR mode can't be mixed with Authentication */
  21121. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  21122. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  21123. + {
  21124. + mvOsPrintf("mvCesaAction : CRYPTO CTR mode can't be mixed with AUTH\n");
  21125. + return MV_NOT_ALLOWED;
  21126. + }
  21127. + /* All other request parameters should not be checked because key stream */
  21128. + /* (not user data) processed by AES HW engine */
  21129. + pReq->pOrgCmd = pCmd;
  21130. + /* Allocate temporary pCmd structure for Key stream */
  21131. + pCmd = mvCesaCtrModeInit();
  21132. + if(pCmd == NULL)
  21133. + return MV_OUT_OF_CPU_MEM;
  21134. +
  21135. + /* Prepare Key stream */
  21136. + mvCesaCtrModePrepare(pCmd, pReq->pOrgCmd);
  21137. + pReq->fixOffset = 0;
  21138. + }
  21139. + else
  21140. + {
  21141. + /* Check request parameters and calculae fixOffset */
  21142. + status = mvCesaParamCheck(pSA, pCmd, &pReq->fixOffset);
  21143. + if(status != MV_OK)
  21144. + {
  21145. + return status;
  21146. + }
  21147. + }
  21148. + pReq->pCmd = pCmd;
  21149. +
  21150. + /* Check if the packet need fragmentation */
  21151. + if(pCmd->pSrc->mbufSize <= sizeof(cesaSramVirtPtr->buf) )
  21152. + {
  21153. + /* request size is smaller than single buffer size */
  21154. + pReq->fragMode = MV_CESA_FRAG_NONE;
  21155. +
  21156. + /* Prepare NOT fragmented packets */
  21157. + status = mvCesaReqProcess(pReq);
  21158. + if(status != MV_OK)
  21159. + {
  21160. + mvOsPrintf("CesaReady: ReqProcess error: pReq=%p, status=0x%x\n",
  21161. + pReq, status);
  21162. + }
  21163. +#if (MV_CESA_VERSION >= 3)
  21164. + pReq->frags.numFrag = 1;
  21165. +#endif
  21166. + }
  21167. + else
  21168. + {
  21169. + MV_U8 frag = 0;
  21170. +
  21171. + /* request size is larger than buffer size - needs fragmentation */
  21172. +
  21173. + /* Check restrictions for processing fragmented packets */
  21174. + status = mvCesaFragParamCheck(pSA, pCmd);
  21175. + if(status != MV_OK)
  21176. + return status;
  21177. +
  21178. + pReq->fragMode = MV_CESA_FRAG_FIRST;
  21179. + pReq->frags.nextFrag = 0;
  21180. +
  21181. + /* Prepare Process Fragmented packets */
  21182. + while(pReq->fragMode != MV_CESA_FRAG_LAST)
  21183. + {
  21184. + if(frag >= MV_CESA_MAX_REQ_FRAGS)
  21185. + {
  21186. + mvOsPrintf("mvCesaAction Error: Too large request frag=%d\n", frag);
  21187. + return MV_OUT_OF_CPU_MEM;
  21188. + }
  21189. + status = mvCesaFragReqProcess(pReq, frag);
  21190. + if(status == MV_OK) {
  21191. +#if (MV_CESA_VERSION >= 3)
  21192. + if(frag) {
  21193. + pReq->dma[frag-1].pDmaLast->phyNextDescPtr =
  21194. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
  21195. + mvOsCacheFlush(NULL, pReq->dma[frag-1].pDmaLast, sizeof(MV_DMA_DESC));
  21196. + }
  21197. +#endif
  21198. + frag++;
  21199. + }
  21200. + }
  21201. + pReq->frags.numFrag = frag;
  21202. +#if (MV_CESA_VERSION >= 3)
  21203. + if(chainReqNum) {
  21204. + chainReqNum += pReq->frags.numFrag;
  21205. + if(chainReqNum >= MAX_CESA_CHAIN_LENGTH)
  21206. + chainReqNum = MAX_CESA_CHAIN_LENGTH;
  21207. + }
  21208. +#endif
  21209. + }
  21210. +
  21211. + pReq->state = MV_CESA_PENDING;
  21212. +
  21213. + pCesaReqEmpty = MV_CESA_REQ_NEXT_PTR(pReq);
  21214. + cesaReqResources -= 1;
  21215. +
  21216. +/* #ifdef CESA_DEBUG */
  21217. + if( (cesaQueueDepth - cesaReqResources) > cesaStats.maxReqCount)
  21218. + cesaStats.maxReqCount = (cesaQueueDepth - cesaReqResources);
  21219. +/* #endif CESA_DEBUG */
  21220. +
  21221. + cesaLastSid = sid;
  21222. +
  21223. +#if (MV_CESA_VERSION >= 3)
  21224. + /* Are we within chain bounderies and follows the first request ? */
  21225. + if((chainReqNum > 0) && (chainReqNum < MAX_CESA_CHAIN_LENGTH)) {
  21226. + if(chainIndex) {
  21227. + pFromReq = MV_CESA_REQ_PREV_PTR(pReq);
  21228. + pToReq = pReq;
  21229. + pReq->state = MV_CESA_CHAIN;
  21230. + /* assume concatenating is possible */
  21231. + pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast->phyNextDescPtr =
  21232. + MV_32BIT_LE(mvCesaVirtToPhys(&pToReq->dmaDescBuf, pToReq->dma[0].pDmaFirst));
  21233. + mvOsCacheFlush(NULL, pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast, sizeof(MV_DMA_DESC));
  21234. +
  21235. + /* align active & next pointers */
  21236. + if(pNextActiveChain->state != MV_CESA_PENDING)
  21237. + pEndCurrChain = pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pReq);
  21238. + }
  21239. + else { /* we have only one chain, start new one */
  21240. + chainReqNum = 0;
  21241. + chainIndex++;
  21242. + /* align active & next pointers */
  21243. + if(pNextActiveChain->state != MV_CESA_PENDING)
  21244. + pEndCurrChain = pNextActiveChain = pReq;
  21245. + }
  21246. + }
  21247. + else {
  21248. + /* In case we concatenate full chain */
  21249. + if(chainReqNum == MAX_CESA_CHAIN_LENGTH) {
  21250. + chainIndex++;
  21251. + if(pNextActiveChain->state != MV_CESA_PENDING)
  21252. + pEndCurrChain = pNextActiveChain = pReq;
  21253. + chainReqNum = 0;
  21254. + }
  21255. +
  21256. + pReq = pCesaReqProcess;
  21257. + if(pReq->state == MV_CESA_PENDING) {
  21258. + pNextActiveChain = pReq;
  21259. + pEndCurrChain = MV_CESA_REQ_NEXT_PTR(pReq);
  21260. + /* Start Process new request */
  21261. + mvCesaReqProcessStart(pReq);
  21262. + }
  21263. + }
  21264. +
  21265. + chainReqNum++;
  21266. +
  21267. + if((chainIndex < MAX_CESA_CHAIN_LENGTH) && (chainReqNum > cesaStats.maxChainUsage))
  21268. + cesaStats.maxChainUsage = chainReqNum;
  21269. +
  21270. +#else
  21271. +
  21272. + /* Check status of CESA channels and process requests if possible */
  21273. + pReq = pCesaReqProcess;
  21274. + if(pReq->state == MV_CESA_PENDING)
  21275. + {
  21276. + /* Start Process new request */
  21277. + mvCesaReqProcessStart(pReq);
  21278. + }
  21279. +#endif
  21280. + /* If request queue became FULL - return MV_NO_MORE */
  21281. + if(cesaReqResources == 0)
  21282. + return MV_NO_MORE;
  21283. +
  21284. + return MV_OK;
  21285. +
  21286. +}
  21287. +
  21288. +/*******************************************************************************
  21289. +* mvCesaReadyGet - Get crypto request that processing is finished
  21290. +*
  21291. +* DESCRIPTION:
  21292. +* This function complete request processing and return ready request to
  21293. +* caller. To don't miss interrupts the caller must call this function
  21294. +* while MV_OK or MV_TERMINATE values returned.
  21295. +*
  21296. +* INPUT:
  21297. +* MV_U32 chanMap - map of CESA channels finished thier job
  21298. +* accordingly with CESA Cause register.
  21299. +* MV_CESA_RESULT* pResult - pointer to structure contains information
  21300. +* about ready request. It includes pointer to
  21301. +* user private structure "pReqPrv", session identifier
  21302. +* for this request "sessionId" and return code.
  21303. +* Return code set to MV_FAIL if calculated digest value
  21304. +* on decode direction is different than digest value
  21305. +* in the packet.
  21306. +*
  21307. +* RETURN:
  21308. +* MV_OK - Success, ready request is returned.
  21309. +* MV_NOT_READY - Next request is not ready yet. New interrupt will
  21310. +* be generated for futher request processing.
  21311. +* MV_EMPTY - There is no more request for processing.
  21312. +* MV_BUSY - Fragmented request is not ready yet.
  21313. +* MV_TERMINATE - Call this function once more to complete processing
  21314. +* of fragmented request.
  21315. +*
  21316. +*******************************************************************************/
  21317. +MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult)
  21318. +{
  21319. + MV_STATUS status, readyStatus = MV_NOT_READY;
  21320. + MV_U32 statusReg;
  21321. + MV_CESA_REQ* pReq;
  21322. + MV_CESA_SA* pSA;
  21323. +
  21324. +#if (MV_CESA_VERSION >= 3)
  21325. + if(isFirstReq == MV_TRUE) {
  21326. + if(chainIndex == 0)
  21327. + chainReqNum = 0;
  21328. +
  21329. + isFirstReq = MV_FALSE;
  21330. +
  21331. + if(pNextActiveChain->state == MV_CESA_PENDING) {
  21332. + /* Start request Process */
  21333. + mvCesaReqProcessStart(pNextActiveChain);
  21334. + pEndCurrChain = pNextActiveChain;
  21335. + if(chainIndex > 0)
  21336. + chainIndex--;
  21337. + /* Update pNextActiveChain to next chain head */
  21338. + while(pNextActiveChain->state == MV_CESA_CHAIN)
  21339. + pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pNextActiveChain);
  21340. + }
  21341. + }
  21342. +
  21343. + /* Check if there are more processed requests - can we remove pEndCurrChain ??? */
  21344. + if(pCesaReqProcess == pEndCurrChain) {
  21345. + isFirstReq = MV_TRUE;
  21346. + pEndCurrChain = pNextActiveChain;
  21347. +#else
  21348. + if(pCesaReqProcess->state != MV_CESA_PROCESS) {
  21349. +#endif
  21350. + return MV_EMPTY;
  21351. + }
  21352. +
  21353. +#ifdef CESA_DEBUG
  21354. + statusReg = MV_REG_READ(MV_CESA_STATUS_REG);
  21355. + if( statusReg & MV_CESA_STATUS_ACTIVE_MASK )
  21356. + {
  21357. + mvOsPrintf("mvCesaReadyGet: Not Ready, Status = 0x%x\n", statusReg);
  21358. + cesaStats.notReadyCount++;
  21359. + return MV_NOT_READY;
  21360. + }
  21361. +#endif /* CESA_DEBUG */
  21362. +
  21363. + cesaStats.readyCount++;
  21364. +
  21365. + pReq = pCesaReqProcess;
  21366. + pSA = &pCesaSAD[pReq->pCmd->sessionId];
  21367. +
  21368. + pResult->retCode = MV_OK;
  21369. + if(pReq->fragMode != MV_CESA_FRAG_NONE)
  21370. + {
  21371. + MV_U8* pNewDigest;
  21372. + int frag;
  21373. +#if (MV_CESA_VERSION >= 3)
  21374. + pReq->frags.nextFrag = 1;
  21375. + while(pReq->frags.nextFrag <= pReq->frags.numFrag) {
  21376. +#endif
  21377. + frag = (pReq->frags.nextFrag - 1);
  21378. +
  21379. + /* Restore DMA descriptor list */
  21380. + pReq->dma[frag].pDmaLast->phyNextDescPtr =
  21381. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[frag].pDmaLast[1]));
  21382. + pReq->dma[frag].pDmaLast = NULL;
  21383. +
  21384. + /* Special processing for finished fragmented request */
  21385. + if(pReq->frags.nextFrag >= pReq->frags.numFrag)
  21386. + {
  21387. + mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);
  21388. +
  21389. + /* Fragmented packet is ready */
  21390. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  21391. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  21392. + {
  21393. + int macDataSize = pReq->pCmd->macLength - pReq->frags.macSize;
  21394. +
  21395. + if(macDataSize != 0)
  21396. + {
  21397. + /* Calculate all other blocks by SW */
  21398. + mvCesaFragAuthComplete(pReq, pSA, macDataSize);
  21399. + }
  21400. +
  21401. + /* Copy new digest from SRAM to the Destination buffer */
  21402. + pNewDigest = cesaSramVirtPtr->buf + pReq->frags.newDigestOffset;
  21403. + status = mvCesaCopyToMbuf(pNewDigest, pReq->pCmd->pDst,
  21404. + pReq->pCmd->digestOffset, pSA->digestSize);
  21405. +
  21406. + /* For decryption: Compare new digest value with original one */
  21407. + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
  21408. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
  21409. + {
  21410. + if( memcmp(pNewDigest, pReq->frags.orgDigest, pSA->digestSize) != 0)
  21411. + {
  21412. +/*
  21413. + mvOsPrintf("Digest error: chan=%d, newDigest=%p, orgDigest=%p, status = 0x%x\n",
  21414. + chan, pNewDigest, pReq->frags.orgDigest, MV_REG_READ(MV_CESA_STATUS_REG));
  21415. +*/
  21416. + /* Signiture verification is failed */
  21417. + pResult->retCode = MV_FAIL;
  21418. + }
  21419. + }
  21420. + }
  21421. + readyStatus = MV_OK;
  21422. + }
  21423. +#if (MV_CESA_VERSION >= 3)
  21424. + pReq->frags.nextFrag++;
  21425. + }
  21426. +#endif
  21427. + }
  21428. + else
  21429. + {
  21430. + mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);
  21431. +
  21432. + /* Restore DMA descriptor list */
  21433. + pReq->dma[0].pDmaLast->phyNextDescPtr =
  21434. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[0].pDmaLast[1]));
  21435. + pReq->dma[0].pDmaLast = NULL;
  21436. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  21437. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) &&
  21438. + ((pSA->config & MV_CESA_DIRECTION_MASK) ==
  21439. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT)) )
  21440. + {
  21441. + /* For AUTH on decode : Check Digest result in Status register */
  21442. + statusReg = MV_REG_READ(MV_CESA_STATUS_REG);
  21443. + if(statusReg & MV_CESA_STATUS_DIGEST_ERR_MASK)
  21444. + {
  21445. +/*
  21446. + mvOsPrintf("Digest error: chan=%d, status = 0x%x\n",
  21447. + chan, statusReg);
  21448. +*/
  21449. + /* Signiture verification is failed */
  21450. + pResult->retCode = MV_FAIL;
  21451. + }
  21452. + }
  21453. + readyStatus = MV_OK;
  21454. + }
  21455. +
  21456. + if(readyStatus == MV_OK)
  21457. + {
  21458. + /* If Request is ready - Prepare pResult structure */
  21459. + pResult->pReqPrv = pReq->pCmd->pReqPrv;
  21460. + pResult->sessionId = pReq->pCmd->sessionId;
  21461. +
  21462. + pReq->state = MV_CESA_IDLE;
  21463. + pCesaReqProcess = MV_CESA_REQ_NEXT_PTR(pReq);
  21464. + cesaReqResources++;
  21465. +
  21466. + if(pSA->ctrMode)
  21467. + {
  21468. + /* For AES CTR mode - complete processing and free allocated resources */
  21469. + mvCesaCtrModeComplete(pReq->pOrgCmd, pReq->pCmd);
  21470. + mvCesaCtrModeFinish(pReq->pCmd);
  21471. + pReq->pOrgCmd = NULL;
  21472. + }
  21473. + }
  21474. +
  21475. +#if (MV_CESA_VERSION < 3)
  21476. + if(pCesaReqProcess->state == MV_CESA_PROCESS)
  21477. + {
  21478. + /* Start request Process */
  21479. + mvCesaReqProcessStart(pCesaReqProcess);
  21480. + if(readyStatus == MV_NOT_READY)
  21481. + readyStatus = MV_BUSY;
  21482. + }
  21483. + else if(pCesaReqProcess != pCesaReqEmpty)
  21484. + {
  21485. + /* Start process new request from the queue */
  21486. + mvCesaReqProcessStart(pCesaReqProcess);
  21487. + }
  21488. +#endif
  21489. + return readyStatus;
  21490. +}
  21491. +
  21492. +/***************** Functions to work with CESA_MBUF structure ******************/
  21493. +
  21494. +/*******************************************************************************
  21495. +* mvCesaMbufOffset - Locate offset in the Mbuf structure
  21496. +*
  21497. +* DESCRIPTION:
  21498. +* This function locates offset inside Multi-Bufeer structure.
  21499. +* It get fragment number and place in the fragment where the offset
  21500. +* is located.
  21501. +*
  21502. +*
  21503. +* INPUT:
  21504. +* MV_CESA_MBUF* pMbuf - Pointer to multi-buffer structure
  21505. +* int offset - Offset from the beginning of the data presented by
  21506. +* the Mbuf structure.
  21507. +*
  21508. +* OUTPUT:
  21509. +* int* pBufOffset - Offset from the beginning of the fragment where
  21510. +* the offset is located.
  21511. +*
  21512. +* RETURN:
  21513. +* int - Number of fragment, where the offset is located\
  21514. +*
  21515. +*******************************************************************************/
  21516. +int mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset)
  21517. +{
  21518. + int frag = 0;
  21519. +
  21520. + while(offset > 0)
  21521. + {
  21522. + if(frag >= pMbuf->numFrags)
  21523. + {
  21524. + mvOsPrintf("mvCesaMbufOffset: Error: frag (%d) > numFrags (%d)\n",
  21525. + frag, pMbuf->numFrags);
  21526. + return MV_INVALID;
  21527. + }
  21528. + if(offset < pMbuf->pFrags[frag].bufSize)
  21529. + {
  21530. + break;
  21531. + }
  21532. + offset -= pMbuf->pFrags[frag].bufSize;
  21533. + frag++;
  21534. + }
  21535. + if(pBufOffset != NULL)
  21536. + *pBufOffset = offset;
  21537. +
  21538. + return frag;
  21539. +}
  21540. +
  21541. +/*******************************************************************************
  21542. +* mvCesaCopyFromMbuf - Copy data from the Mbuf structure to continuous buffer
  21543. +*
  21544. +* DESCRIPTION:
  21545. +*
  21546. +*
  21547. +* INPUT:
  21548. +* MV_U8* pDstBuf - Pointer to continuous buffer, where data is
  21549. +* copied to.
  21550. +* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
  21551. +* copied from.
  21552. +* int offset - Offset in the Mbuf structure where located first
  21553. +* byte of data should be copied.
  21554. +* int size - Size of data should be copied
  21555. +*
  21556. +* RETURN:
  21557. +* MV_OK - Success, all data is copied successfully.
  21558. +* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
  21559. +* No data is copied.
  21560. +* MV_EMPTY - Multi-buffer structure has not enough data to copy
  21561. +* Data from the offset to end of Mbuf data is copied.
  21562. +*
  21563. +*******************************************************************************/
  21564. +MV_STATUS mvCesaCopyFromMbuf(MV_U8* pDstBuf, MV_CESA_MBUF* pSrcMbuf,
  21565. + int offset, int size)
  21566. +{
  21567. + int frag, fragOffset, bufSize;
  21568. + MV_U8* pBuf;
  21569. +
  21570. + if(size == 0)
  21571. + return MV_OK;
  21572. +
  21573. + frag = mvCesaMbufOffset(pSrcMbuf, offset, &fragOffset);
  21574. + if(frag == MV_INVALID)
  21575. + {
  21576. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  21577. + return MV_OUT_OF_RANGE;
  21578. + }
  21579. +
  21580. + bufSize = pSrcMbuf->pFrags[frag].bufSize - fragOffset;
  21581. + pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  21582. + while(MV_TRUE)
  21583. + {
  21584. + if(size <= bufSize)
  21585. + {
  21586. + memcpy(pDstBuf, pBuf, size);
  21587. + return MV_OK;
  21588. + }
  21589. + memcpy(pDstBuf, pBuf, bufSize);
  21590. + size -= bufSize;
  21591. + frag++;
  21592. + pDstBuf += bufSize;
  21593. + if(frag >= pSrcMbuf->numFrags)
  21594. + break;
  21595. +
  21596. + bufSize = pSrcMbuf->pFrags[frag].bufSize;
  21597. + pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr;
  21598. + }
  21599. + mvOsPrintf("mvCesaCopyFromMbuf: Mbuf is EMPTY - %d bytes isn't copied\n",
  21600. + size);
  21601. + return MV_EMPTY;
  21602. +}
  21603. +
  21604. +/*******************************************************************************
  21605. +* mvCesaCopyToMbuf - Copy data from continuous buffer to the Mbuf structure
  21606. +*
  21607. +* DESCRIPTION:
  21608. +*
  21609. +*
  21610. +* INPUT:
  21611. +* MV_U8* pSrcBuf - Pointer to continuous buffer, where data is
  21612. +* copied from.
  21613. +* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
  21614. +* copied to.
  21615. +* int offset - Offset in the Mbuf structure where located first
  21616. +* byte of data should be copied.
  21617. +* int size - Size of data should be copied
  21618. +*
  21619. +* RETURN:
  21620. +* MV_OK - Success, all data is copied successfully.
  21621. +* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
  21622. +* No data is copied.
  21623. +* MV_FULL - Multi-buffer structure has not enough place to copy
  21624. +* all data. Data from the offset to end of Mbuf data
  21625. +* is copied.
  21626. +*
  21627. +*******************************************************************************/
  21628. +MV_STATUS mvCesaCopyToMbuf(MV_U8* pSrcBuf, MV_CESA_MBUF* pDstMbuf,
  21629. + int offset, int size)
  21630. +{
  21631. + int frag, fragOffset, bufSize;
  21632. + MV_U8* pBuf;
  21633. +
  21634. + if(size == 0)
  21635. + return MV_OK;
  21636. +
  21637. + frag = mvCesaMbufOffset(pDstMbuf, offset, &fragOffset);
  21638. + if(frag == MV_INVALID)
  21639. + {
  21640. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  21641. + return MV_OUT_OF_RANGE;
  21642. + }
  21643. +
  21644. + bufSize = pDstMbuf->pFrags[frag].bufSize - fragOffset;
  21645. + pBuf = pDstMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  21646. + while(MV_TRUE)
  21647. + {
  21648. + if(size <= bufSize)
  21649. + {
  21650. + memcpy(pBuf, pSrcBuf, size);
  21651. + return MV_OK;
  21652. + }
  21653. + memcpy(pBuf, pSrcBuf, bufSize);
  21654. + size -= bufSize;
  21655. + frag++;
  21656. + pSrcBuf += bufSize;
  21657. + if(frag >= pDstMbuf->numFrags)
  21658. + break;
  21659. +
  21660. + bufSize = pDstMbuf->pFrags[frag].bufSize;
  21661. + pBuf = pDstMbuf->pFrags[frag].bufVirtPtr;
  21662. + }
  21663. + mvOsPrintf("mvCesaCopyToMbuf: Mbuf is FULL - %d bytes isn't copied\n",
  21664. + size);
  21665. + return MV_FULL;
  21666. +}
  21667. +
  21668. +/*******************************************************************************
  21669. +* mvCesaMbufCopy - Copy data from one Mbuf structure to the other Mbuf structure
  21670. +*
  21671. +* DESCRIPTION:
  21672. +*
  21673. +*
  21674. +* INPUT:
  21675. +*
  21676. +* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
  21677. +* copied to.
  21678. +* int dstMbufOffset - Offset in the dstMbuf structure where first byte
  21679. +* of data should be copied to.
  21680. +* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
  21681. +* copied from.
  21682. +* int srcMbufOffset - Offset in the srcMbuf structure where first byte
  21683. +* of data should be copied from.
  21684. +* int size - Size of data should be copied
  21685. +*
  21686. +* RETURN:
  21687. +* MV_OK - Success, all data is copied successfully.
  21688. +* MV_OUT_OF_RANGE - Failed, srcMbufOffset or dstMbufOffset is out of
  21689. +* srcMbuf or dstMbuf structure correspondently.
  21690. +* No data is copied.
  21691. +* MV_BAD_SIZE - srcMbuf or dstMbuf structure is too small to copy
  21692. +* all data. Partial data is copied
  21693. +*
  21694. +*******************************************************************************/
  21695. +MV_STATUS mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,
  21696. + MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size)
  21697. +{
  21698. + int srcFrag, dstFrag, srcSize, dstSize, srcOffset, dstOffset;
  21699. + int copySize;
  21700. + MV_U8 *pSrc, *pDst;
  21701. +
  21702. + if(size == 0)
  21703. + return MV_OK;
  21704. +
  21705. + srcFrag = mvCesaMbufOffset(pMbufSrc, srcMbufOffset, &srcOffset);
  21706. + if(srcFrag == MV_INVALID)
  21707. + {
  21708. + mvOsPrintf("CESA srcMbuf Error: offset (%d) out of range\n", srcMbufOffset);
  21709. + return MV_OUT_OF_RANGE;
  21710. + }
  21711. + pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr + srcOffset;
  21712. + srcSize = pMbufSrc->pFrags[srcFrag].bufSize - srcOffset;
  21713. +
  21714. + dstFrag = mvCesaMbufOffset(pMbufDst, dstMbufOffset, &dstOffset);
  21715. + if(dstFrag == MV_INVALID)
  21716. + {
  21717. + mvOsPrintf("CESA dstMbuf Error: offset (%d) out of range\n", dstMbufOffset);
  21718. + return MV_OUT_OF_RANGE;
  21719. + }
  21720. + pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr + dstOffset;
  21721. + dstSize = pMbufDst->pFrags[dstFrag].bufSize - dstOffset;
  21722. +
  21723. + while(size > 0)
  21724. + {
  21725. + copySize = MV_MIN(srcSize, dstSize);
  21726. + if(size <= copySize)
  21727. + {
  21728. + memcpy(pDst, pSrc, size);
  21729. + return MV_OK;
  21730. + }
  21731. + memcpy(pDst, pSrc, copySize);
  21732. + size -= copySize;
  21733. + srcSize -= copySize;
  21734. + dstSize -= copySize;
  21735. +
  21736. + if(srcSize == 0)
  21737. + {
  21738. + srcFrag++;
  21739. + if(srcFrag >= pMbufSrc->numFrags)
  21740. + break;
  21741. +
  21742. + pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr;
  21743. + srcSize = pMbufSrc->pFrags[srcFrag].bufSize;
  21744. + }
  21745. +
  21746. + if(dstSize == 0)
  21747. + {
  21748. + dstFrag++;
  21749. + if(dstFrag >= pMbufDst->numFrags)
  21750. + break;
  21751. +
  21752. + pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr;
  21753. + dstSize = pMbufDst->pFrags[dstFrag].bufSize;
  21754. + }
  21755. + }
  21756. + mvOsPrintf("mvCesaMbufCopy: BAD size - %d bytes isn't copied\n",
  21757. + size);
  21758. +
  21759. + return MV_BAD_SIZE;
  21760. +}
  21761. +
  21762. +static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size)
  21763. +{
  21764. + int frag, fragOffset, bufSize;
  21765. + MV_U8* pBuf;
  21766. +
  21767. + if(size == 0)
  21768. + return MV_OK;
  21769. +
  21770. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  21771. + if(frag == MV_INVALID)
  21772. + {
  21773. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  21774. + return MV_OUT_OF_RANGE;
  21775. + }
  21776. +
  21777. + bufSize = pMbuf->pFrags[frag].bufSize - fragOffset;
  21778. + pBuf = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  21779. + while(MV_TRUE)
  21780. + {
  21781. + if(size <= bufSize)
  21782. + {
  21783. + mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), size);
  21784. + return MV_OK;
  21785. + }
  21786. +
  21787. + mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), bufSize);
  21788. + size -= bufSize;
  21789. + frag++;
  21790. + if(frag >= pMbuf->numFrags)
  21791. + break;
  21792. +
  21793. + bufSize = pMbuf->pFrags[frag].bufSize;
  21794. + pBuf = pMbuf->pFrags[frag].bufVirtPtr;
  21795. + }
  21796. + mvOsPrintf("%s: Mbuf is FULL - %d bytes isn't Unmapped\n",
  21797. + __FUNCTION__, size);
  21798. + return MV_FULL;
  21799. +}
  21800. +
  21801. +
  21802. +/*************************************** Local Functions ******************************/
  21803. +
  21804. +/*******************************************************************************
  21805. +* mvCesaFragReqProcess - Process fragmented request
  21806. +*
  21807. +* DESCRIPTION:
  21808. +* This function processes a fragment of fragmented request (First, Middle or Last)
  21809. +*
  21810. +*
  21811. +* INPUT:
  21812. +* MV_CESA_REQ* pReq - Pointer to the request in the request queue.
  21813. +*
  21814. +* RETURN:
  21815. +* MV_OK - The fragment is successfully passed to HW for processing.
  21816. +* MV_TERMINATE - Means, that HW finished its work on this packet and no more
  21817. +* interrupts will be generated for this request.
  21818. +* Function mvCesaReadyGet() must be called to complete request
  21819. +* processing and get request result.
  21820. +*
  21821. +*******************************************************************************/
  21822. +static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag)
  21823. +{
  21824. + int i, copySize, cryptoDataSize, macDataSize, sid;
  21825. + int cryptoIvOffset, digestOffset;
  21826. + MV_U32 config;
  21827. + MV_CESA_COMMAND* pCmd = pReq->pCmd;
  21828. + MV_CESA_SA* pSA;
  21829. + MV_CESA_MBUF* pMbuf;
  21830. + MV_DMA_DESC* pDmaDesc = pReq->dma[frag].pDmaFirst;
  21831. + MV_U8* pSramBuf = cesaSramVirtPtr->buf;
  21832. + int macTotalLen = 0;
  21833. + int fixOffset, cryptoOffset, macOffset;
  21834. +
  21835. + cesaStats.fragCount++;
  21836. +
  21837. + sid = pReq->pCmd->sessionId;
  21838. +
  21839. + pSA = &pCesaSAD[sid];
  21840. +
  21841. + cryptoIvOffset = digestOffset = 0;
  21842. + i = macDataSize = 0;
  21843. + cryptoDataSize = 0;
  21844. +
  21845. + /* First fragment processing */
  21846. + if(pReq->fragMode == MV_CESA_FRAG_FIRST)
  21847. + {
  21848. + /* pReq->frags monitors processing of fragmented request between fragments */
  21849. + pReq->frags.bufOffset = 0;
  21850. + pReq->frags.cryptoSize = 0;
  21851. + pReq->frags.macSize = 0;
  21852. +
  21853. + config = pSA->config | (MV_CESA_FRAG_FIRST << MV_CESA_FRAG_MODE_OFFSET);
  21854. +
  21855. + /* fixOffset can be not equal to zero only for FIRST fragment */
  21856. + fixOffset = pReq->fixOffset;
  21857. + /* For FIRST fragment crypto and mac offsets are taken from pCmd */
  21858. + cryptoOffset = pCmd->cryptoOffset;
  21859. + macOffset = pCmd->macOffset;
  21860. +
  21861. + copySize = sizeof(cesaSramVirtPtr->buf) - pReq->fixOffset;
  21862. +
  21863. + /* Find fragment size: Must meet all requirements for CRYPTO and MAC
  21864. + * cryptoDataSize - size of data will be encrypted/decrypted in this fragment
  21865. + * macDataSize - size of data will be signed/verified in this fragment
  21866. + * copySize - size of data will be copied from srcMbuf to SRAM and
  21867. + * back to dstMbuf for this fragment
  21868. + */
  21869. + mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,
  21870. + &copySize, &cryptoDataSize, &macDataSize);
  21871. +
  21872. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  21873. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET))
  21874. + {
  21875. + /* CryptoIV special processing */
  21876. + if( (pSA->config & MV_CESA_CRYPTO_MODE_MASK) ==
  21877. + (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT) )
  21878. + {
  21879. + /* In CBC mode for encode direction when IV from user */
  21880. + if( (pCmd->ivFromUser) &&
  21881. + ((pSA->config & MV_CESA_DIRECTION_MASK) ==
  21882. + (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) )
  21883. + {
  21884. +
  21885. + /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
  21886. + * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
  21887. + * in the buffer to SRAM IVPointer
  21888. + */
  21889. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
  21890. + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  21891. + }
  21892. +
  21893. + /* Special processing when IV is not located in the first fragment */
  21894. + if(pCmd->ivOffset > (copySize - pSA->cryptoIvSize))
  21895. + {
  21896. + /* Prepare dummy place for cryptoIV in SRAM */
  21897. + cryptoIvOffset = cesaSramVirtPtr->tempCryptoIV - mvCesaSramAddrGet();
  21898. +
  21899. + /* For Decryption: Copy IV value from pCmd->ivOffset to Special SRAM place */
  21900. + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
  21901. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
  21902. + {
  21903. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->tempCryptoIV, &pDmaDesc[i],
  21904. + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  21905. + }
  21906. + else
  21907. + {
  21908. + /* For Encryption when IV is NOT from User: */
  21909. + /* Copy IV from SRAM to buffer (pCmd->ivOffset) */
  21910. + if(pCmd->ivFromUser == 0)
  21911. + {
  21912. + /* copy IV value from cryptoIV to Buffer (pCmd->ivOffset) */
  21913. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
  21914. + MV_TRUE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  21915. + }
  21916. + }
  21917. + }
  21918. + else
  21919. + {
  21920. + cryptoIvOffset = pCmd->ivOffset;
  21921. + }
  21922. + }
  21923. + }
  21924. +
  21925. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  21926. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  21927. + {
  21928. + /* MAC digest special processing on Decode direction */
  21929. + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
  21930. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
  21931. + {
  21932. + /* Save digest from pCmd->digestOffset */
  21933. + mvCesaCopyFromMbuf(pReq->frags.orgDigest,
  21934. + pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);
  21935. +
  21936. + /* If pCmd->digestOffset is not located on the first */
  21937. + if(pCmd->digestOffset > (copySize - pSA->digestSize))
  21938. + {
  21939. + MV_U8 digestZero[MV_CESA_MAX_DIGEST_SIZE];
  21940. +
  21941. + /* Set zeros to pCmd->digestOffset (DRAM) */
  21942. + memset(digestZero, 0, MV_CESA_MAX_DIGEST_SIZE);
  21943. + mvCesaCopyToMbuf(digestZero, pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);
  21944. +
  21945. + /* Prepare dummy place for digest in SRAM */
  21946. + digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
  21947. + }
  21948. + else
  21949. + {
  21950. + digestOffset = pCmd->digestOffset;
  21951. + }
  21952. + }
  21953. + }
  21954. + /* Update SA in SRAM */
  21955. + if(cesaLastSid != sid)
  21956. + {
  21957. + mvCesaSramSaUpdate(sid, &pDmaDesc[i]);
  21958. + i++;
  21959. + }
  21960. +
  21961. + pReq->fragMode = MV_CESA_FRAG_MIDDLE;
  21962. + }
  21963. + else
  21964. + {
  21965. + /* Continue fragment */
  21966. + fixOffset = 0;
  21967. + cryptoOffset = 0;
  21968. + macOffset = 0;
  21969. + if( (pCmd->pSrc->mbufSize - pReq->frags.bufOffset) <= sizeof(cesaSramVirtPtr->buf))
  21970. + {
  21971. + /* Last fragment */
  21972. + config = pSA->config | (MV_CESA_FRAG_LAST << MV_CESA_FRAG_MODE_OFFSET);
  21973. + pReq->fragMode = MV_CESA_FRAG_LAST;
  21974. + copySize = pCmd->pSrc->mbufSize - pReq->frags.bufOffset;
  21975. +
  21976. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  21977. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  21978. + {
  21979. + macDataSize = pCmd->macLength - pReq->frags.macSize;
  21980. +
  21981. + /* If pCmd->digestOffset is not located on last fragment */
  21982. + if(pCmd->digestOffset < pReq->frags.bufOffset)
  21983. + {
  21984. + /* Prepare dummy place for digest in SRAM */
  21985. + digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
  21986. + }
  21987. + else
  21988. + {
  21989. + digestOffset = pCmd->digestOffset - pReq->frags.bufOffset;
  21990. + }
  21991. + pReq->frags.newDigestOffset = digestOffset;
  21992. + macTotalLen = pCmd->macLength;
  21993. +
  21994. + /* HW can't calculate the Digest correctly for fragmented packets
  21995. + * in the following cases:
  21996. + * - MV88F5182 ||
  21997. + * - MV88F5181L when total macLength more that 16 Kbytes ||
  21998. + * - total macLength more that 64 Kbytes
  21999. + */
  22000. + if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||
  22001. + ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&
  22002. + (mvCtrlRevGet() >= MV_5181L_A0_REV) &&
  22003. + (pCmd->macLength >= (1 << 14)) ) )
  22004. + {
  22005. + return MV_TERMINATE;
  22006. + }
  22007. + }
  22008. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  22009. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
  22010. + {
  22011. + cryptoDataSize = pCmd->cryptoLength - pReq->frags.cryptoSize;
  22012. + }
  22013. +
  22014. + /* cryptoIvOffset - don't care */
  22015. + }
  22016. + else
  22017. + {
  22018. + /* WA for MV88F5182 SHA1 and MD5 fragmentation mode */
  22019. + if( (mvCtrlModelGet() == MV_5182_DEV_ID) &&
  22020. + (((pSA->config & MV_CESA_MAC_MODE_MASK) ==
  22021. + (MV_CESA_MAC_MD5 << MV_CESA_MAC_MODE_OFFSET)) ||
  22022. + ((pSA->config & MV_CESA_MAC_MODE_MASK) ==
  22023. + (MV_CESA_MAC_SHA1 << MV_CESA_MAC_MODE_OFFSET))) )
  22024. + {
  22025. + pReq->frags.newDigestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
  22026. + pReq->fragMode = MV_CESA_FRAG_LAST;
  22027. +
  22028. + return MV_TERMINATE;
  22029. + }
  22030. + /* Middle fragment */
  22031. + config = pSA->config | (MV_CESA_FRAG_MIDDLE << MV_CESA_FRAG_MODE_OFFSET);
  22032. + copySize = sizeof(cesaSramVirtPtr->buf);
  22033. + /* digestOffset and cryptoIvOffset - don't care */
  22034. +
  22035. + /* Find fragment size */
  22036. + mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,
  22037. + &copySize, &cryptoDataSize, &macDataSize);
  22038. + }
  22039. + }
  22040. + /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
  22041. + pMbuf = pCmd->pSrc;
  22042. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  22043. + MV_FALSE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);
  22044. +
  22045. + /* Prepare CESA descriptor to copy from DRAM to SRAM by DMA */
  22046. + mvCesaSramDescrBuild(config, frag,
  22047. + cryptoOffset + fixOffset, cryptoIvOffset + fixOffset,
  22048. + cryptoDataSize, macOffset + fixOffset,
  22049. + digestOffset + fixOffset, macDataSize, macTotalLen,
  22050. + pReq, &pDmaDesc[i]);
  22051. + i++;
  22052. +
  22053. + /* Add special descriptor Ownership for CPU */
  22054. + pDmaDesc[i].byteCnt = 0;
  22055. + pDmaDesc[i].phySrcAdd = 0;
  22056. + pDmaDesc[i].phyDestAdd = 0;
  22057. + i++;
  22058. +
  22059. + /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
  22060. + pMbuf = pCmd->pDst;
  22061. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  22062. + MV_TRUE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);
  22063. +
  22064. + /* Next field of Last DMA descriptor must be NULL */
  22065. + pDmaDesc[i-1].phyNextDescPtr = 0;
  22066. + pReq->dma[frag].pDmaLast = &pDmaDesc[i-1];
  22067. + mvOsCacheFlush(NULL, pReq->dma[frag].pDmaFirst,
  22068. + i*sizeof(MV_DMA_DESC));
  22069. +
  22070. + /*mvCesaDebugDescriptor(&cesaSramVirtPtr->desc[frag]);*/
  22071. +
  22072. + pReq->frags.bufOffset += copySize;
  22073. + pReq->frags.cryptoSize += cryptoDataSize;
  22074. + pReq->frags.macSize += macDataSize;
  22075. +
  22076. + return MV_OK;
  22077. +}
  22078. +
  22079. +
  22080. +/*******************************************************************************
  22081. +* mvCesaReqProcess - Process regular (Non-fragmented) request
  22082. +*
  22083. +* DESCRIPTION:
  22084. +* This function processes the whole (not fragmented) request
  22085. +*
  22086. +* INPUT:
  22087. +* MV_CESA_REQ* pReq - Pointer to the request in the request queue.
  22088. +*
  22089. +* RETURN:
  22090. +* MV_OK - The request is successfully passed to HW for processing.
  22091. +* Other - Failure. The request will not be processed
  22092. +*
  22093. +*******************************************************************************/
  22094. +static MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq)
  22095. +{
  22096. + MV_CESA_MBUF *pMbuf;
  22097. + MV_DMA_DESC *pDmaDesc;
  22098. + MV_U8 *pSramBuf;
  22099. + int sid, i, fixOffset;
  22100. + MV_CESA_SA *pSA;
  22101. + MV_CESA_COMMAND *pCmd = pReq->pCmd;
  22102. +
  22103. + cesaStats.procCount++;
  22104. +
  22105. + sid = pCmd->sessionId;
  22106. + pSA = &pCesaSAD[sid];
  22107. + pDmaDesc = pReq->dma[0].pDmaFirst;
  22108. + pSramBuf = cesaSramVirtPtr->buf;
  22109. + fixOffset = pReq->fixOffset;
  22110. +
  22111. +/*
  22112. + mvOsPrintf("mvCesaReqProcess: sid=%d, pSA=%p, pDmaDesc=%p, pSramBuf=%p\n",
  22113. + sid, pSA, pDmaDesc, pSramBuf);
  22114. +*/
  22115. + i = 0;
  22116. +
  22117. + /* Crypto IV Special processing in CBC mode for Encryption direction */
  22118. + if( ((pSA->config & MV_CESA_OPERATION_MASK) != (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) &&
  22119. + ((pSA->config & MV_CESA_CRYPTO_MODE_MASK) == (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT)) &&
  22120. + ((pSA->config & MV_CESA_DIRECTION_MASK) == (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) &&
  22121. + (pCmd->ivFromUser) )
  22122. + {
  22123. + /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
  22124. + * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
  22125. + * in the buffer to SRAM IVPointer
  22126. + */
  22127. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
  22128. + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  22129. + }
  22130. +
  22131. + /* Update SA in SRAM */
  22132. + if(cesaLastSid != sid)
  22133. + {
  22134. + mvCesaSramSaUpdate(sid, &pDmaDesc[i]);
  22135. + i++;
  22136. + }
  22137. +
  22138. + /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
  22139. + pMbuf = pCmd->pSrc;
  22140. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  22141. + MV_FALSE, 0, pMbuf->mbufSize, pCmd->skipFlush);
  22142. +
  22143. + /* Prepare Security Accelerator descriptor to SRAM words 0 - 7 */
  22144. + mvCesaSramDescrBuild(pSA->config, 0, pCmd->cryptoOffset + fixOffset,
  22145. + pCmd->ivOffset + fixOffset, pCmd->cryptoLength,
  22146. + pCmd->macOffset + fixOffset, pCmd->digestOffset + fixOffset,
  22147. + pCmd->macLength, pCmd->macLength, pReq, &pDmaDesc[i]);
  22148. + i++;
  22149. +
  22150. + /* Add special descriptor Ownership for CPU */
  22151. + pDmaDesc[i].byteCnt = 0;
  22152. + pDmaDesc[i].phySrcAdd = 0;
  22153. + pDmaDesc[i].phyDestAdd = 0;
  22154. + i++;
  22155. +
  22156. + /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
  22157. + pMbuf = pCmd->pDst;
  22158. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  22159. + MV_TRUE, 0, pMbuf->mbufSize, pCmd->skipFlush);
  22160. +
  22161. + /* Next field of Last DMA descriptor must be NULL */
  22162. + pDmaDesc[i-1].phyNextDescPtr = 0;
  22163. + pReq->dma[0].pDmaLast = &pDmaDesc[i-1];
  22164. + mvOsCacheFlush(NULL, pReq->dma[0].pDmaFirst, i*sizeof(MV_DMA_DESC));
  22165. +
  22166. + return MV_OK;
  22167. +}
  22168. +
  22169. +
  22170. +/*******************************************************************************
  22171. +* mvCesaSramDescrBuild - Set CESA descriptor in SRAM
  22172. +*
  22173. +* DESCRIPTION:
  22174. +* This function builds CESA descriptor in SRAM from all Command parameters
  22175. +*
  22176. +*
  22177. +* INPUT:
  22178. +* int chan - CESA channel uses the descriptor
  22179. +* MV_U32 config - 32 bits of WORD_0 in CESA descriptor structure
  22180. +* int cryptoOffset - Offset from the beginning of SRAM buffer where
  22181. +* data for encryption/decription is started.
  22182. +* int ivOffset - Offset of crypto IV from the SRAM base. Valid only
  22183. +* for first fragment.
  22184. +* int cryptoLength - Size (in bytes) of data for encryption/descryption
  22185. +* operation on this fragment.
  22186. +* int macOffset - Offset from the beginning of SRAM buffer where
  22187. +* data for Authentication is started
  22188. +* int digestOffset - Offset from the beginning of SRAM buffer where
  22189. +* digest is located. Valid for first and last fragments.
  22190. +* int macLength - Size (in bytes) of data for Authentication
  22191. +* operation on this fragment.
  22192. +* int macTotalLen - Toatl size (in bytes) of data for Authentication
  22193. +* operation on the whole request (packet). Valid for
  22194. +* last fragment only.
  22195. +*
  22196. +* RETURN: None
  22197. +*
  22198. +*******************************************************************************/
  22199. +static void mvCesaSramDescrBuild(MV_U32 config, int frag,
  22200. + int cryptoOffset, int ivOffset, int cryptoLength,
  22201. + int macOffset, int digestOffset, int macLength,
  22202. + int macTotalLen, MV_CESA_REQ* pReq, MV_DMA_DESC* pDmaDesc)
  22203. +{
  22204. + MV_CESA_DESC* pCesaDesc = &pReq->pCesaDesc[frag];
  22205. + MV_CESA_DESC* pSramDesc = pSramDesc = &cesaSramVirtPtr->desc;
  22206. + MV_U16 sramBufOffset = (MV_U16)((MV_U8*)cesaSramVirtPtr->buf - mvCesaSramAddrGet());
  22207. +
  22208. + pCesaDesc->config = MV_32BIT_LE(config);
  22209. +
  22210. + if( (config & MV_CESA_OPERATION_MASK) !=
  22211. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
  22212. + {
  22213. + /* word 1 */
  22214. + pCesaDesc->cryptoSrcOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);
  22215. + pCesaDesc->cryptoDstOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);
  22216. + /* word 2 */
  22217. + pCesaDesc->cryptoDataLen = MV_16BIT_LE(cryptoLength);
  22218. + /* word 3 */
  22219. + pCesaDesc->cryptoKeyOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.cryptoKey -
  22220. + mvCesaSramAddrGet()));
  22221. + /* word 4 */
  22222. + pCesaDesc->cryptoIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->cryptoIV -
  22223. + mvCesaSramAddrGet()));
  22224. + pCesaDesc->cryptoIvBufOffset = MV_16BIT_LE(sramBufOffset + ivOffset);
  22225. + }
  22226. +
  22227. + if( (config & MV_CESA_OPERATION_MASK) !=
  22228. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  22229. + {
  22230. + /* word 5 */
  22231. + pCesaDesc->macSrcOffset = MV_16BIT_LE(sramBufOffset + macOffset);
  22232. + pCesaDesc->macTotalLen = MV_16BIT_LE(macTotalLen);
  22233. +
  22234. + /* word 6 */
  22235. + pCesaDesc->macDigestOffset = MV_16BIT_LE(sramBufOffset + digestOffset);
  22236. + pCesaDesc->macDataLen = MV_16BIT_LE(macLength);
  22237. +
  22238. + /* word 7 */
  22239. + pCesaDesc->macInnerIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macInnerIV -
  22240. + mvCesaSramAddrGet()));
  22241. + pCesaDesc->macOuterIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macOuterIV -
  22242. + mvCesaSramAddrGet()));
  22243. + }
  22244. + /* Prepare DMA descriptor to CESA descriptor from DRAM to SRAM */
  22245. + pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&pReq->cesaDescBuf, pCesaDesc));
  22246. + pDmaDesc->phyDestAdd = MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)pSramDesc));
  22247. + pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_DESC) | BIT31);
  22248. +
  22249. + /* flush Source buffer */
  22250. + mvOsCacheFlush(NULL, pCesaDesc, sizeof(MV_CESA_DESC));
  22251. +}
  22252. +
  22253. +/*******************************************************************************
  22254. +* mvCesaSramSaUpdate - Move required SA information to SRAM if needed.
  22255. +*
  22256. +* DESCRIPTION:
  22257. +* Copy to SRAM values of the required SA.
  22258. +*
  22259. +*
  22260. +* INPUT:
  22261. +* short sid - Session ID needs SRAM Cache update
  22262. +* MV_DMA_DESC *pDmaDesc - Pointer to DMA descriptor used to
  22263. +* copy SA values from DRAM to SRAM.
  22264. +*
  22265. +* RETURN:
  22266. +* MV_OK - Cache entry for this SA copied to SRAM.
  22267. +* MV_NO_CHANGE - Cache entry for this SA already exist in SRAM
  22268. +*
  22269. +*******************************************************************************/
  22270. +static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc)
  22271. +{
  22272. + MV_CESA_SA *pSA = &pCesaSAD[sid];
  22273. +
  22274. + /* Prepare DMA descriptor to Copy CACHE_SA from SA database in DRAM to SRAM */
  22275. + pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_SRAM_SA) | BIT31);
  22276. + pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&cesaSramSaBuf, pSA->pSramSA));
  22277. + pDmaDesc->phyDestAdd =
  22278. + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)&cesaSramVirtPtr->sramSA));
  22279. +
  22280. + /* Source buffer is already flushed during OpenSession*/
  22281. + /*mvOsCacheFlush(NULL, &pSA->sramSA, sizeof(MV_CESA_SRAM_SA));*/
  22282. +}
  22283. +
  22284. +/*******************************************************************************
  22285. +* mvCesaDmaCopyPrepare - prepare DMA descriptor list to copy data presented by
  22286. +* Mbuf structure from DRAM to SRAM
  22287. +*
  22288. +* DESCRIPTION:
  22289. +*
  22290. +*
  22291. +* INPUT:
  22292. +* MV_CESA_MBUF* pMbuf - pointer to Mbuf structure contains request
  22293. +* data in DRAM
  22294. +* MV_U8* pSramBuf - pointer to buffer in SRAM where data should
  22295. +* be copied to.
  22296. +* MV_DMA_DESC* pDmaDesc - pointer to first DMA descriptor for this copy.
  22297. +* The function set number of DMA descriptors needed
  22298. +* to copy the copySize bytes from Mbuf.
  22299. +* MV_BOOL isToMbuf - Copy direction.
  22300. +* MV_TRUE means copy from SRAM buffer to Mbuf in DRAM.
  22301. +* MV_FALSE means copy from Mbuf in DRAM to SRAM buffer.
  22302. +* int offset - Offset in the Mbuf structure that copy should be
  22303. +* started from.
  22304. +* int copySize - Size of data should be copied.
  22305. +*
  22306. +* RETURN:
  22307. +* int - number of DMA descriptors used for the copy.
  22308. +*
  22309. +*******************************************************************************/
  22310. +#ifndef MV_NETBSD
  22311. +static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
  22312. + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
  22313. + int offset, int copySize, MV_BOOL skipFlush)
  22314. +{
  22315. + int bufOffset, bufSize, size, frag, i;
  22316. + MV_U8* pBuf;
  22317. +
  22318. + i = 0;
  22319. +
  22320. + /* Calculate start place for copy: fragment number and offset in the fragment */
  22321. + frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);
  22322. + bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;
  22323. + pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;
  22324. +
  22325. + /* Size accumulate total copy size */
  22326. + size = 0;
  22327. +
  22328. + /* Create DMA lists to copy mBuf from pSrc to SRAM */
  22329. + while(size < copySize)
  22330. + {
  22331. + /* Find copy size for each DMA descriptor */
  22332. + bufSize = MV_MIN(bufSize, (copySize - size));
  22333. + pDmaDesc[i].byteCnt = MV_32BIT_LE(bufSize | BIT31);
  22334. + if(isToMbuf)
  22335. + {
  22336. + pDmaDesc[i].phyDestAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
  22337. + pDmaDesc[i].phySrcAdd =
  22338. + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));
  22339. + /* invalidate the buffer */
  22340. + if(skipFlush == MV_FALSE)
  22341. + mvOsCacheInvalidate(NULL, pBuf, bufSize);
  22342. + }
  22343. + else
  22344. + {
  22345. + pDmaDesc[i].phySrcAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
  22346. + pDmaDesc[i].phyDestAdd =
  22347. + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));
  22348. + /* flush the buffer */
  22349. + if(skipFlush == MV_FALSE)
  22350. + mvOsCacheFlush(NULL, pBuf, bufSize);
  22351. + }
  22352. +
  22353. + /* Count number of used DMA descriptors */
  22354. + i++;
  22355. + size += bufSize;
  22356. +
  22357. + /* go to next fragment in the Mbuf */
  22358. + frag++;
  22359. + pBuf = pMbuf->pFrags[frag].bufVirtPtr;
  22360. + bufSize = pMbuf->pFrags[frag].bufSize;
  22361. + }
  22362. + return i;
  22363. +}
  22364. +#else /* MV_NETBSD */
  22365. +static int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
  22366. + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
  22367. + int offset, int copySize, MV_BOOL skipFlush)
  22368. +{
  22369. + int bufOffset, bufSize, thisSize, size, frag, i;
  22370. + MV_ULONG bufPhys, sramPhys;
  22371. + MV_U8* pBuf;
  22372. +
  22373. + /*
  22374. + * Calculate start place for copy: fragment number and offset in
  22375. + * the fragment
  22376. + */
  22377. + frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);
  22378. +
  22379. + /*
  22380. + * Get SRAM physical address only once. We can update it in-place
  22381. + * as we build the descriptor chain.
  22382. + */
  22383. + sramPhys = mvCesaSramVirtToPhys(NULL, pSramBuf);
  22384. +
  22385. + /*
  22386. + * 'size' accumulates total copy size, 'i' counts desccriptors.
  22387. + */
  22388. + size = i = 0;
  22389. +
  22390. + /* Create DMA lists to copy mBuf from pSrc to SRAM */
  22391. + while (size < copySize) {
  22392. + /*
  22393. + * Calculate # of bytes to copy from the current fragment,
  22394. + * and the pointer to the start of data
  22395. + */
  22396. + bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;
  22397. + pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;
  22398. + bufOffset = 0; /* First frag may be non-zero */
  22399. + frag++;
  22400. +
  22401. + /*
  22402. + * As long as there is data in the current fragment...
  22403. + */
  22404. + while (bufSize > 0) {
  22405. + /*
  22406. + * Ensure we don't cross an MMU page boundary.
  22407. + * XXX: This is NetBSD-specific, but it is a
  22408. + * quick and dirty way to fix the problem.
  22409. + * A true HAL would rely on the OS-specific
  22410. + * driver to do this...
  22411. + */
  22412. + thisSize = PAGE_SIZE -
  22413. + (((MV_ULONG)pBuf) & (PAGE_SIZE - 1));
  22414. + thisSize = MV_MIN(bufSize, thisSize);
  22415. + /*
  22416. + * Make sure we don't copy more than requested
  22417. + */
  22418. + if (thisSize > (copySize - size)) {
  22419. + thisSize = copySize - size;
  22420. + bufSize = 0;
  22421. + }
  22422. +
  22423. + /*
  22424. + * Physicall address of this fragment
  22425. + */
  22426. + bufPhys = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
  22427. +
  22428. + /*
  22429. + * Set up the descriptor
  22430. + */
  22431. + pDmaDesc[i].byteCnt = MV_32BIT_LE(thisSize | BIT31);
  22432. + if(isToMbuf) {
  22433. + pDmaDesc[i].phyDestAdd = bufPhys;
  22434. + pDmaDesc[i].phySrcAdd = MV_32BIT_LE(sramPhys);
  22435. + /* invalidate the buffer */
  22436. + if(skipFlush == MV_FALSE)
  22437. + mvOsCacheInvalidate(NULL, pBuf, thisSize);
  22438. + } else {
  22439. + pDmaDesc[i].phySrcAdd = bufPhys;
  22440. + pDmaDesc[i].phyDestAdd = MV_32BIT_LE(sramPhys);
  22441. + /* flush the buffer */
  22442. + if(skipFlush == MV_FALSE)
  22443. + mvOsCacheFlush(NULL, pBuf, thisSize);
  22444. + }
  22445. +
  22446. + pDmaDesc[i].phyNextDescPtr =
  22447. + MV_32BIT_LE(mvOsIoVirtToPhy(NULL,(&pDmaDesc[i+1])));
  22448. +
  22449. + /* flush the DMA desc */
  22450. + mvOsCacheFlush(NULL, &pDmaDesc[i], sizeof(MV_DMA_DESC));
  22451. +
  22452. + /* Update state */
  22453. + bufSize -= thisSize;
  22454. + sramPhys += thisSize;
  22455. + pBuf += thisSize;
  22456. + size += thisSize;
  22457. + i++;
  22458. + }
  22459. + }
  22460. +
  22461. + return i;
  22462. +}
  22463. +#endif /* MV_NETBSD */
  22464. +/*******************************************************************************
  22465. +* mvCesaHmacIvGet - Calculate Inner and Outter values from HMAC key
  22466. +*
  22467. +* DESCRIPTION:
  22468. +* This function calculate Inner and Outer values used for HMAC algorithm.
  22469. +* This operation allows improve performance fro the whole HMAC processing.
  22470. +*
  22471. +* INPUT:
  22472. +* MV_CESA_MAC_MODE macMode - Authentication mode: HMAC_MD5 or HMAC_SHA1.
  22473. +* unsigned char key[] - Pointer to HMAC key.
  22474. +* int keyLength - Size of HMAC key (maximum 64 bytes)
  22475. +*
  22476. +* OUTPUT:
  22477. +* unsigned char innerIV[] - HASH(key^inner)
  22478. +* unsigned char outerIV[] - HASH(key^outter)
  22479. +*
  22480. +* RETURN: None
  22481. +*
  22482. +*******************************************************************************/
  22483. +static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,
  22484. + unsigned char innerIV[], unsigned char outerIV[])
  22485. +{
  22486. + unsigned char inner[MV_CESA_MAX_MAC_KEY_LENGTH];
  22487. + unsigned char outer[MV_CESA_MAX_MAC_KEY_LENGTH];
  22488. + int i, digestSize = 0;
  22489. +#if defined(MV_CPU_LE) || defined(MV_PPC)
  22490. + MV_U32 swapped32, val32, *pVal32;
  22491. +#endif
  22492. + for(i=0; i<keyLength; i++)
  22493. + {
  22494. + inner[i] = 0x36 ^ key[i];
  22495. + outer[i] = 0x5c ^ key[i];
  22496. + }
  22497. +
  22498. + for(i=keyLength; i<MV_CESA_MAX_MAC_KEY_LENGTH; i++)
  22499. + {
  22500. + inner[i] = 0x36;
  22501. + outer[i] = 0x5c;
  22502. + }
  22503. + if(macMode == MV_CESA_MAC_HMAC_MD5)
  22504. + {
  22505. + MV_MD5_CONTEXT ctx;
  22506. +
  22507. + mvMD5Init(&ctx);
  22508. + mvMD5Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);
  22509. +
  22510. + memcpy(innerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);
  22511. + memset(&ctx, 0, sizeof(ctx));
  22512. +
  22513. + mvMD5Init(&ctx);
  22514. + mvMD5Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);
  22515. + memcpy(outerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);
  22516. + memset(&ctx, 0, sizeof(ctx));
  22517. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  22518. + }
  22519. + else if(macMode == MV_CESA_MAC_HMAC_SHA1)
  22520. + {
  22521. + MV_SHA1_CTX ctx;
  22522. +
  22523. + mvSHA1Init(&ctx);
  22524. + mvSHA1Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);
  22525. + memcpy(innerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);
  22526. + memset(&ctx, 0, sizeof(ctx));
  22527. +
  22528. + mvSHA1Init(&ctx);
  22529. + mvSHA1Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);
  22530. + memcpy(outerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);
  22531. + memset(&ctx, 0, sizeof(ctx));
  22532. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  22533. + }
  22534. + else
  22535. + {
  22536. + mvOsPrintf("hmacGetIV: Unexpected macMode %d\n", macMode);
  22537. + }
  22538. +#if defined(MV_CPU_LE) || defined(MV_PPC)
  22539. + /* 32 bits Swap of Inner and Outer values */
  22540. + pVal32 = (MV_U32*)innerIV;
  22541. + for(i=0; i<digestSize/4; i++)
  22542. + {
  22543. + val32 = *pVal32;
  22544. + swapped32 = MV_BYTE_SWAP_32BIT(val32);
  22545. + *pVal32 = swapped32;
  22546. + pVal32++;
  22547. + }
  22548. + pVal32 = (MV_U32*)outerIV;
  22549. + for(i=0; i<digestSize/4; i++)
  22550. + {
  22551. + val32 = *pVal32;
  22552. + swapped32 = MV_BYTE_SWAP_32BIT(val32);
  22553. + *pVal32 = swapped32;
  22554. + pVal32++;
  22555. + }
  22556. +#endif /* defined(MV_CPU_LE) || defined(MV_PPC) */
  22557. +}
  22558. +
  22559. +
  22560. +/*******************************************************************************
  22561. +* mvCesaFragSha1Complete - Complete SHA1 authentication started by HW using SW
  22562. +*
  22563. +* DESCRIPTION:
  22564. +*
  22565. +*
  22566. +* INPUT:
  22567. +* MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
  22568. +* for SHA1 is placed.
  22569. +* int offset - Offset in the Mbuf structure where
  22570. +* unprocessed data for SHA1 is started.
  22571. +* MV_U8* pOuterIV - Pointer to OUTER for this session.
  22572. +* If pOuterIV==NULL - MAC mode is HASH_SHA1
  22573. +* If pOuterIV!=NULL - MAC mode is HMAC_SHA1
  22574. +* int macLeftSize - Size of unprocessed data for SHA1.
  22575. +* int macTotalSize - Total size of data for SHA1 in the
  22576. +* request (processed + unprocessed)
  22577. +*
  22578. +* OUTPUT:
  22579. +* MV_U8* pDigest - Pointer to place where calculated Digest will
  22580. +* be stored.
  22581. +*
  22582. +* RETURN: None
  22583. +*
  22584. +*******************************************************************************/
  22585. +static void mvCesaFragSha1Complete(MV_CESA_MBUF* pMbuf, int offset,
  22586. + MV_U8* pOuterIV, int macLeftSize,
  22587. + int macTotalSize, MV_U8* pDigest)
  22588. +{
  22589. + MV_SHA1_CTX ctx;
  22590. + MV_U8 *pData;
  22591. + int i, frag, fragOffset, size;
  22592. +
  22593. + /* Read temporary Digest from HW */
  22594. + for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)
  22595. + {
  22596. + ctx.state[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));
  22597. + }
  22598. + /* Initialize MV_SHA1_CTX structure */
  22599. + memset(ctx.buffer, 0, 64);
  22600. + /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
  22601. + /* so count[1] is always 0 */
  22602. + ctx.count[0] = ((macTotalSize - macLeftSize) * 8);
  22603. + ctx.count[1] = 0;
  22604. +
  22605. + /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
  22606. + if(pOuterIV != NULL)
  22607. + ctx.count[0] += (64 * 8);
  22608. +
  22609. + /* Get place of unprocessed data in the Mbuf structure */
  22610. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  22611. + if(frag == MV_INVALID)
  22612. + {
  22613. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  22614. + return;
  22615. + }
  22616. +
  22617. + pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  22618. + size = pMbuf->pFrags[frag].bufSize - fragOffset;
  22619. +
  22620. + /* Complete Inner part */
  22621. + while(macLeftSize > 0)
  22622. + {
  22623. + if(macLeftSize <= size)
  22624. + {
  22625. + mvSHA1Update(&ctx, pData, macLeftSize);
  22626. + break;
  22627. + }
  22628. + mvSHA1Update(&ctx, pData, size);
  22629. + macLeftSize -= size;
  22630. + frag++;
  22631. + pData = pMbuf->pFrags[frag].bufVirtPtr;
  22632. + size = pMbuf->pFrags[frag].bufSize;
  22633. + }
  22634. + mvSHA1Final(pDigest, &ctx);
  22635. +/*
  22636. + mvOsPrintf("mvCesaFragSha1Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
  22637. + pOuterIV, macLeftSize, macTotalSize);
  22638. + mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);
  22639. +*/
  22640. +
  22641. + if(pOuterIV != NULL)
  22642. + {
  22643. + /* If HMAC - Complete Outer part */
  22644. + for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)
  22645. + {
  22646. +#if defined(MV_CPU_LE) || defined(MV_ARM)
  22647. + ctx.state[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);
  22648. +#else
  22649. + ctx.state[i] = ((MV_U32*)pOuterIV)[i];
  22650. +#endif
  22651. + }
  22652. + memset(ctx.buffer, 0, 64);
  22653. +
  22654. + ctx.count[0] = 64*8;
  22655. + ctx.count[1] = 0;
  22656. + mvSHA1Update(&ctx, pDigest, MV_CESA_SHA1_DIGEST_SIZE);
  22657. + mvSHA1Final(pDigest, &ctx);
  22658. + }
  22659. +}
  22660. +
  22661. +/*******************************************************************************
  22662. +* mvCesaFragMd5Complete - Complete MD5 authentication started by HW using SW
  22663. +*
  22664. +* DESCRIPTION:
  22665. +*
  22666. +*
  22667. +* INPUT:
  22668. +* MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
  22669. +* for SHA1 is placed.
  22670. +* int offset - Offset in the Mbuf structure where
  22671. +* unprocessed data for MD5 is started.
  22672. +* MV_U8* pOuterIV - Pointer to OUTER for this session.
  22673. +* If pOuterIV==NULL - MAC mode is HASH_MD5
  22674. +* If pOuterIV!=NULL - MAC mode is HMAC_MD5
  22675. +* int macLeftSize - Size of unprocessed data for MD5.
  22676. +* int macTotalSize - Total size of data for MD5 in the
  22677. +* request (processed + unprocessed)
  22678. +*
  22679. +* OUTPUT:
  22680. +* MV_U8* pDigest - Pointer to place where calculated Digest will
  22681. +* be stored.
  22682. +*
  22683. +* RETURN: None
  22684. +*
  22685. +*******************************************************************************/
  22686. +static void mvCesaFragMd5Complete(MV_CESA_MBUF* pMbuf, int offset,
  22687. + MV_U8* pOuterIV, int macLeftSize,
  22688. + int macTotalSize, MV_U8* pDigest)
  22689. +{
  22690. + MV_MD5_CONTEXT ctx;
  22691. + MV_U8 *pData;
  22692. + int i, frag, fragOffset, size;
  22693. +
  22694. + /* Read temporary Digest from HW */
  22695. + for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)
  22696. + {
  22697. + ctx.buf[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));
  22698. + }
  22699. + memset(ctx.in, 0, 64);
  22700. +
  22701. + /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
  22702. + /* so count[1] is always 0 */
  22703. + ctx.bits[0] = ((macTotalSize - macLeftSize) * 8);
  22704. + ctx.bits[1] = 0;
  22705. +
  22706. + /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
  22707. + if(pOuterIV != NULL)
  22708. + ctx.bits[0] += (64 * 8);
  22709. +
  22710. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  22711. + if(frag == MV_INVALID)
  22712. + {
  22713. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  22714. + return;
  22715. + }
  22716. +
  22717. + pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  22718. + size = pMbuf->pFrags[frag].bufSize - fragOffset;
  22719. +
  22720. + /* Complete Inner part */
  22721. + while(macLeftSize > 0)
  22722. + {
  22723. + if(macLeftSize <= size)
  22724. + {
  22725. + mvMD5Update(&ctx, pData, macLeftSize);
  22726. + break;
  22727. + }
  22728. + mvMD5Update(&ctx, pData, size);
  22729. + macLeftSize -= size;
  22730. + frag++;
  22731. + pData = pMbuf->pFrags[frag].bufVirtPtr;
  22732. + size = pMbuf->pFrags[frag].bufSize;
  22733. + }
  22734. + mvMD5Final(pDigest, &ctx);
  22735. +
  22736. +/*
  22737. + mvOsPrintf("mvCesaFragMd5Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
  22738. + pOuterIV, macLeftSize, macTotalSize);
  22739. + mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);
  22740. +*/
  22741. + if(pOuterIV != NULL)
  22742. + {
  22743. + /* Complete Outer part */
  22744. + for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)
  22745. + {
  22746. +#if defined(MV_CPU_LE) || defined(MV_ARM)
  22747. + ctx.buf[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);
  22748. +#else
  22749. + ctx.buf[i] = ((MV_U32*)pOuterIV)[i];
  22750. +#endif
  22751. + }
  22752. + memset(ctx.in, 0, 64);
  22753. +
  22754. + ctx.bits[0] = 64*8;
  22755. + ctx.bits[1] = 0;
  22756. + mvMD5Update(&ctx, pDigest, MV_CESA_MD5_DIGEST_SIZE);
  22757. + mvMD5Final(pDigest, &ctx);
  22758. + }
  22759. +}
  22760. +
  22761. +/*******************************************************************************
  22762. +* mvCesaFragAuthComplete -
  22763. +*
  22764. +* DESCRIPTION:
  22765. +*
  22766. +*
  22767. +* INPUT:
  22768. +* MV_CESA_REQ* pReq,
  22769. +* MV_CESA_SA* pSA,
  22770. +* int macDataSize
  22771. +*
  22772. +* RETURN:
  22773. +* MV_STATUS
  22774. +*
  22775. +*******************************************************************************/
  22776. +static MV_STATUS mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,
  22777. + int macDataSize)
  22778. +{
  22779. + MV_CESA_COMMAND* pCmd = pReq->pCmd;
  22780. + MV_U8* pDigest;
  22781. + MV_CESA_MAC_MODE macMode;
  22782. + MV_U8* pOuterIV = NULL;
  22783. +
  22784. + /* Copy data from Source fragment to Destination */
  22785. + if(pCmd->pSrc != pCmd->pDst)
  22786. + {
  22787. + mvCesaMbufCopy(pCmd->pDst, pReq->frags.bufOffset,
  22788. + pCmd->pSrc, pReq->frags.bufOffset, macDataSize);
  22789. + }
  22790. +
  22791. +/*
  22792. + mvCesaCopyFromMbuf(cesaSramVirtPtr->buf[0], pCmd->pSrc, pReq->frags.bufOffset, macDataSize);
  22793. + mvCesaCopyToMbuf(cesaSramVirtPtr->buf[0], pCmd->pDst, pReq->frags.bufOffset, macDataSize);
  22794. +*/
  22795. + pDigest = (mvCesaSramAddrGet() + pReq->frags.newDigestOffset);
  22796. +
  22797. + macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;
  22798. +/*
  22799. + mvOsPrintf("macDataSize=%d, macLength=%d, digestOffset=%d, macMode=%d\n",
  22800. + macDataSize, pCmd->macLength, pCmd->digestOffset, macMode);
  22801. +*/
  22802. + switch(macMode)
  22803. + {
  22804. + case MV_CESA_MAC_HMAC_MD5:
  22805. + pOuterIV = pSA->pSramSA->macOuterIV;
  22806. +
  22807. + case MV_CESA_MAC_MD5:
  22808. + mvCesaFragMd5Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,
  22809. + macDataSize, pCmd->macLength, pDigest);
  22810. + break;
  22811. +
  22812. + case MV_CESA_MAC_HMAC_SHA1:
  22813. + pOuterIV = pSA->pSramSA->macOuterIV;
  22814. +
  22815. + case MV_CESA_MAC_SHA1:
  22816. + mvCesaFragSha1Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,
  22817. + macDataSize, pCmd->macLength, pDigest);
  22818. + break;
  22819. +
  22820. + default:
  22821. + mvOsPrintf("mvCesaFragAuthComplete: Unexpected macMode %d\n", macMode);
  22822. + return MV_BAD_PARAM;
  22823. + }
  22824. + return MV_OK;
  22825. +}
  22826. +
  22827. +/*******************************************************************************
  22828. +* mvCesaCtrModeInit -
  22829. +*
  22830. +* DESCRIPTION:
  22831. +*
  22832. +*
  22833. +* INPUT: NONE
  22834. +*
  22835. +*
  22836. +* RETURN:
  22837. +* MV_CESA_COMMAND*
  22838. +*
  22839. +*******************************************************************************/
  22840. +static MV_CESA_COMMAND* mvCesaCtrModeInit(void)
  22841. +{
  22842. + MV_CESA_MBUF *pMbuf;
  22843. + MV_U8 *pBuf;
  22844. + MV_CESA_COMMAND *pCmd;
  22845. +
  22846. + pBuf = mvOsMalloc(sizeof(MV_CESA_COMMAND) +
  22847. + sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) + 100);
  22848. + if(pBuf == NULL)
  22849. + {
  22850. + mvOsPrintf("mvCesaSessionOpen: Can't allocate %u bytes for CTR Mode\n",
  22851. + sizeof(MV_CESA_COMMAND) + sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) );
  22852. + return NULL;
  22853. + }
  22854. + pCmd = (MV_CESA_COMMAND*)pBuf;
  22855. + pBuf += sizeof(MV_CESA_COMMAND);
  22856. +
  22857. + pMbuf = (MV_CESA_MBUF*)pBuf;
  22858. + pBuf += sizeof(MV_CESA_MBUF);
  22859. +
  22860. + pMbuf->pFrags = (MV_BUF_INFO*)pBuf;
  22861. +
  22862. + pMbuf->numFrags = 1;
  22863. + pCmd->pSrc = pMbuf;
  22864. + pCmd->pDst = pMbuf;
  22865. +/*
  22866. + mvOsPrintf("CtrModeInit: pCmd=%p, pSrc=%p, pDst=%p, pFrags=%p\n",
  22867. + pCmd, pCmd->pSrc, pCmd->pDst,
  22868. + pMbuf->pFrags);
  22869. +*/
  22870. + return pCmd;
  22871. +}
  22872. +
  22873. +/*******************************************************************************
  22874. +* mvCesaCtrModePrepare -
  22875. +*
  22876. +* DESCRIPTION:
  22877. +*
  22878. +*
  22879. +* INPUT:
  22880. +* MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd
  22881. +*
  22882. +* RETURN:
  22883. +* MV_STATUS
  22884. +*
  22885. +*******************************************************************************/
  22886. +static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd)
  22887. +{
  22888. + MV_CESA_MBUF *pMbuf;
  22889. + MV_U8 *pBuf, *pIV;
  22890. + MV_U32 counter, *pCounter;
  22891. + int cryptoSize = MV_ALIGN_UP(pCmd->cryptoLength, MV_CESA_AES_BLOCK_SIZE);
  22892. +/*
  22893. + mvOsPrintf("CtrModePrepare: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
  22894. + pCmd, pCmd->pSrc, pCmd->pDst,
  22895. + pCtrModeCmd, pCtrModeCmd->pSrc, pCtrModeCmd->pDst);
  22896. +*/
  22897. + pMbuf = pCtrModeCmd->pSrc;
  22898. +
  22899. + /* Allocate buffer for Key stream */
  22900. + pBuf = mvOsIoCachedMalloc(cesaOsHandle,cryptoSize,
  22901. + &pMbuf->pFrags[0].bufPhysAddr,
  22902. + &pMbuf->pFrags[0].memHandle);
  22903. + if(pBuf == NULL)
  22904. + {
  22905. + mvOsPrintf("mvCesaCtrModePrepare: Can't allocate %d bytes\n", cryptoSize);
  22906. + return MV_OUT_OF_CPU_MEM;
  22907. + }
  22908. + memset(pBuf, 0, cryptoSize);
  22909. + mvOsCacheFlush(NULL, pBuf, cryptoSize);
  22910. +
  22911. + pMbuf->pFrags[0].bufVirtPtr = pBuf;
  22912. + pMbuf->mbufSize = cryptoSize;
  22913. + pMbuf->pFrags[0].bufSize = cryptoSize;
  22914. +
  22915. + pCtrModeCmd->pReqPrv = pCmd->pReqPrv;
  22916. + pCtrModeCmd->sessionId = pCmd->sessionId;
  22917. +
  22918. + /* ivFromUser and ivOffset are don't care */
  22919. + pCtrModeCmd->cryptoOffset = 0;
  22920. + pCtrModeCmd->cryptoLength = cryptoSize;
  22921. +
  22922. + /* digestOffset, macOffset and macLength are don't care */
  22923. +
  22924. + mvCesaCopyFromMbuf(pBuf, pCmd->pSrc, pCmd->ivOffset, MV_CESA_AES_BLOCK_SIZE);
  22925. + pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));
  22926. + counter = *pCounter;
  22927. + counter = MV_32BIT_BE(counter);
  22928. + pIV = pBuf;
  22929. + cryptoSize -= MV_CESA_AES_BLOCK_SIZE;
  22930. +
  22931. + /* fill key stream */
  22932. + while(cryptoSize > 0)
  22933. + {
  22934. + pBuf += MV_CESA_AES_BLOCK_SIZE;
  22935. + memcpy(pBuf, pIV, MV_CESA_AES_BLOCK_SIZE - sizeof(counter));
  22936. + pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));
  22937. + counter++;
  22938. + *pCounter = MV_32BIT_BE(counter);
  22939. + cryptoSize -= MV_CESA_AES_BLOCK_SIZE;
  22940. + }
  22941. +
  22942. + return MV_OK;
  22943. +}
  22944. +
  22945. +/*******************************************************************************
  22946. +* mvCesaCtrModeComplete -
  22947. +*
  22948. +* DESCRIPTION:
  22949. +*
  22950. +*
  22951. +* INPUT:
  22952. +* MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd
  22953. +*
  22954. +* RETURN:
  22955. +* MV_STATUS
  22956. +*
  22957. +*******************************************************************************/
  22958. +static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd)
  22959. +{
  22960. + int srcFrag, dstFrag, srcOffset, dstOffset, keyOffset, srcSize, dstSize;
  22961. + int cryptoSize = pCmd->cryptoLength;
  22962. + MV_U8 *pSrc, *pDst, *pKey;
  22963. + MV_STATUS status = MV_OK;
  22964. +/*
  22965. + mvOsPrintf("CtrModeComplete: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
  22966. + pCmd, pCmd->pSrc, pCmd->pDst,
  22967. + pOrgCmd, pOrgCmd->pSrc, pOrgCmd->pDst);
  22968. +*/
  22969. + /* XOR source data with key stream to destination data */
  22970. + pKey = pCmd->pDst->pFrags[0].bufVirtPtr;
  22971. + keyOffset = 0;
  22972. +
  22973. + if( (pOrgCmd->pSrc != pOrgCmd->pDst) &&
  22974. + (pOrgCmd->cryptoOffset > 0) )
  22975. + {
  22976. + /* Copy Prefix from source buffer to destination buffer */
  22977. +
  22978. + status = mvCesaMbufCopy(pOrgCmd->pDst, 0,
  22979. + pOrgCmd->pSrc, 0, pOrgCmd->cryptoOffset);
  22980. +/*
  22981. + status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
  22982. + 0, pOrgCmd->cryptoOffset);
  22983. + status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
  22984. + 0, pOrgCmd->cryptoOffset);
  22985. +*/
  22986. + }
  22987. +
  22988. + srcFrag = mvCesaMbufOffset(pOrgCmd->pSrc, pOrgCmd->cryptoOffset, &srcOffset);
  22989. + pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;
  22990. + srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;
  22991. +
  22992. + dstFrag = mvCesaMbufOffset(pOrgCmd->pDst, pOrgCmd->cryptoOffset, &dstOffset);
  22993. + pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;
  22994. + dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;
  22995. +
  22996. + while(cryptoSize > 0)
  22997. + {
  22998. + pDst[dstOffset] = (pSrc[srcOffset] ^ pKey[keyOffset]);
  22999. +
  23000. + cryptoSize--;
  23001. + dstOffset++;
  23002. + srcOffset++;
  23003. + keyOffset++;
  23004. +
  23005. + if(srcOffset >= srcSize)
  23006. + {
  23007. + srcFrag++;
  23008. + srcOffset = 0;
  23009. + pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;
  23010. + srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;
  23011. + }
  23012. +
  23013. + if(dstOffset >= dstSize)
  23014. + {
  23015. + dstFrag++;
  23016. + dstOffset = 0;
  23017. + pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;
  23018. + dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;
  23019. + }
  23020. + }
  23021. +
  23022. + if(pOrgCmd->pSrc != pOrgCmd->pDst)
  23023. + {
  23024. + /* Copy Suffix from source buffer to destination buffer */
  23025. + srcOffset = pOrgCmd->cryptoOffset + pOrgCmd->cryptoLength;
  23026. +
  23027. + if( (pOrgCmd->pDst->mbufSize - srcOffset) > 0)
  23028. + {
  23029. + status = mvCesaMbufCopy(pOrgCmd->pDst, srcOffset,
  23030. + pOrgCmd->pSrc, srcOffset,
  23031. + pOrgCmd->pDst->mbufSize - srcOffset);
  23032. + }
  23033. +
  23034. +/*
  23035. + status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
  23036. + srcOffset, pOrgCmd->pSrc->mbufSize - srcOffset);
  23037. + status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
  23038. + srcOffset, pOrgCmd->pDst->mbufSize - srcOffset);
  23039. +*/
  23040. + }
  23041. +
  23042. + /* Free buffer used for Key stream */
  23043. + mvOsIoCachedFree(cesaOsHandle,pCmd->pDst->pFrags[0].bufSize,
  23044. + pCmd->pDst->pFrags[0].bufPhysAddr,
  23045. + pCmd->pDst->pFrags[0].bufVirtPtr,
  23046. + pCmd->pDst->pFrags[0].memHandle);
  23047. +
  23048. + return MV_OK;
  23049. +}
  23050. +
  23051. +/*******************************************************************************
  23052. +* mvCesaCtrModeFinish -
  23053. +*
  23054. +* DESCRIPTION:
  23055. +*
  23056. +*
  23057. +* INPUT:
  23058. +* MV_CESA_COMMAND* pCmd
  23059. +*
  23060. +* RETURN:
  23061. +* MV_STATUS
  23062. +*
  23063. +*******************************************************************************/
  23064. +static void mvCesaCtrModeFinish(MV_CESA_COMMAND* pCmd)
  23065. +{
  23066. + mvOsFree(pCmd);
  23067. +}
  23068. +
  23069. +/*******************************************************************************
  23070. +* mvCesaParamCheck -
  23071. +*
  23072. +* DESCRIPTION:
  23073. +*
  23074. +*
  23075. +* INPUT:
  23076. +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset
  23077. +*
  23078. +* RETURN:
  23079. +* MV_STATUS
  23080. +*
  23081. +*******************************************************************************/
  23082. +static MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,
  23083. + MV_U8* pFixOffset)
  23084. +{
  23085. + MV_U8 fixOffset = 0xFF;
  23086. +
  23087. + /* Check AUTH operation parameters */
  23088. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  23089. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )
  23090. + {
  23091. + /* MAC offset should be at least 4 byte aligned */
  23092. + if( MV_IS_NOT_ALIGN(pCmd->macOffset, 4) )
  23093. + {
  23094. + mvOsPrintf("mvCesaAction: macOffset %d must be 4 byte aligned\n",
  23095. + pCmd->macOffset);
  23096. + return MV_BAD_PARAM;
  23097. + }
  23098. + /* Digest offset must be 4 byte aligned */
  23099. + if( MV_IS_NOT_ALIGN(pCmd->digestOffset, 4) )
  23100. + {
  23101. + mvOsPrintf("mvCesaAction: digestOffset %d must be 4 byte aligned\n",
  23102. + pCmd->digestOffset);
  23103. + return MV_BAD_PARAM;
  23104. + }
  23105. + /* In addition all offsets should be the same alignment: 8 or 4 */
  23106. + if(fixOffset == 0xFF)
  23107. + {
  23108. + fixOffset = (pCmd->macOffset % 8);
  23109. + }
  23110. + else
  23111. + {
  23112. + if( (pCmd->macOffset % 8) != fixOffset)
  23113. + {
  23114. + mvOsPrintf("mvCesaAction: macOffset %d mod 8 must be equal %d\n",
  23115. + pCmd->macOffset, fixOffset);
  23116. + return MV_BAD_PARAM;
  23117. + }
  23118. + }
  23119. + if( (pCmd->digestOffset % 8) != fixOffset)
  23120. + {
  23121. + mvOsPrintf("mvCesaAction: digestOffset %d mod 8 must be equal %d\n",
  23122. + pCmd->digestOffset, fixOffset);
  23123. + return MV_BAD_PARAM;
  23124. + }
  23125. + }
  23126. + /* Check CRYPTO operation parameters */
  23127. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  23128. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )
  23129. + {
  23130. + /* CryptoOffset should be at least 4 byte aligned */
  23131. + if( MV_IS_NOT_ALIGN(pCmd->cryptoOffset, 4) )
  23132. + {
  23133. + mvOsPrintf("CesaAction: cryptoOffset=%d must be 4 byte aligned\n",
  23134. + pCmd->cryptoOffset);
  23135. + return MV_BAD_PARAM;
  23136. + }
  23137. + /* cryptoLength should be the whole number of blocks */
  23138. + if( MV_IS_NOT_ALIGN(pCmd->cryptoLength, pSA->cryptoBlockSize) )
  23139. + {
  23140. + mvOsPrintf("mvCesaAction: cryptoLength=%d must be %d byte aligned\n",
  23141. + pCmd->cryptoLength, pSA->cryptoBlockSize);
  23142. + return MV_BAD_PARAM;
  23143. + }
  23144. + if(fixOffset == 0xFF)
  23145. + {
  23146. + fixOffset = (pCmd->cryptoOffset % 8);
  23147. + }
  23148. + else
  23149. + {
  23150. + /* In addition all offsets should be the same alignment: 8 or 4 */
  23151. + if( (pCmd->cryptoOffset % 8) != fixOffset)
  23152. + {
  23153. + mvOsPrintf("mvCesaAction: cryptoOffset %d mod 8 must be equal %d \n",
  23154. + pCmd->cryptoOffset, fixOffset);
  23155. + return MV_BAD_PARAM;
  23156. + }
  23157. + }
  23158. +
  23159. + /* check for CBC mode */
  23160. + if(pSA->cryptoIvSize > 0)
  23161. + {
  23162. + /* cryptoIV must not be part of CryptoLength */
  23163. + if( ((pCmd->ivOffset + pSA->cryptoIvSize) > pCmd->cryptoOffset) &&
  23164. + (pCmd->ivOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )
  23165. + {
  23166. + mvOsPrintf("mvCesaFragParamCheck: cryptoIvOffset (%d) is part of cryptoLength (%d+%d)\n",
  23167. + pCmd->ivOffset, pCmd->macOffset, pCmd->macLength);
  23168. + return MV_BAD_PARAM;
  23169. + }
  23170. +
  23171. + /* ivOffset must be 4 byte aligned */
  23172. + if( MV_IS_NOT_ALIGN(pCmd->ivOffset, 4) )
  23173. + {
  23174. + mvOsPrintf("CesaAction: ivOffset=%d must be 4 byte aligned\n",
  23175. + pCmd->ivOffset);
  23176. + return MV_BAD_PARAM;
  23177. + }
  23178. + /* In addition all offsets should be the same alignment: 8 or 4 */
  23179. + if( (pCmd->ivOffset % 8) != fixOffset)
  23180. + {
  23181. + mvOsPrintf("mvCesaAction: ivOffset %d mod 8 must be %d\n",
  23182. + pCmd->ivOffset, fixOffset);
  23183. + return MV_BAD_PARAM;
  23184. + }
  23185. + }
  23186. + }
  23187. + return MV_OK;
  23188. +}
  23189. +
  23190. +/*******************************************************************************
  23191. +* mvCesaFragParamCheck -
  23192. +*
  23193. +* DESCRIPTION:
  23194. +*
  23195. +*
  23196. +* INPUT:
  23197. +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd
  23198. +*
  23199. +* RETURN:
  23200. +* MV_STATUS
  23201. +*
  23202. +*******************************************************************************/
  23203. +static MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd)
  23204. +{
  23205. + int offset;
  23206. +
  23207. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  23208. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )
  23209. + {
  23210. + /* macOffset must be less that SRAM buffer size */
  23211. + if(pCmd->macOffset > (sizeof(cesaSramVirtPtr->buf) - MV_CESA_AUTH_BLOCK_SIZE))
  23212. + {
  23213. + mvOsPrintf("mvCesaFragParamCheck: macOffset is too large (%d)\n",
  23214. + pCmd->macOffset);
  23215. + return MV_BAD_PARAM;
  23216. + }
  23217. + /* macOffset+macSize must be more than mbufSize - SRAM buffer size */
  23218. + if( ((pCmd->macOffset + pCmd->macLength) > pCmd->pSrc->mbufSize) ||
  23219. + ((pCmd->pSrc->mbufSize - (pCmd->macOffset + pCmd->macLength)) >=
  23220. + sizeof(cesaSramVirtPtr->buf)) )
  23221. + {
  23222. + mvOsPrintf("mvCesaFragParamCheck: macLength is too large (%d), mbufSize=%d\n",
  23223. + pCmd->macLength, pCmd->pSrc->mbufSize);
  23224. + return MV_BAD_PARAM;
  23225. + }
  23226. + }
  23227. +
  23228. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  23229. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )
  23230. + {
  23231. + /* cryptoOffset must be less that SRAM buffer size */
  23232. + /* 4 for possible fixOffset */
  23233. + if( (pCmd->cryptoOffset + 4) > (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize))
  23234. + {
  23235. + mvOsPrintf("mvCesaFragParamCheck: cryptoOffset is too large (%d)\n",
  23236. + pCmd->cryptoOffset);
  23237. + return MV_BAD_PARAM;
  23238. + }
  23239. +
  23240. + /* cryptoOffset+cryptoSize must be more than mbufSize - SRAM buffer size */
  23241. + if( ((pCmd->cryptoOffset + pCmd->cryptoLength) > pCmd->pSrc->mbufSize) ||
  23242. + ((pCmd->pSrc->mbufSize - (pCmd->cryptoOffset + pCmd->cryptoLength)) >=
  23243. + (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize)) )
  23244. + {
  23245. + mvOsPrintf("mvCesaFragParamCheck: cryptoLength is too large (%d), mbufSize=%d\n",
  23246. + pCmd->cryptoLength, pCmd->pSrc->mbufSize);
  23247. + return MV_BAD_PARAM;
  23248. + }
  23249. + }
  23250. +
  23251. + /* When MAC_THEN_CRYPTO or CRYPTO_THEN_MAC */
  23252. + if( ((pSA->config & MV_CESA_OPERATION_MASK) ==
  23253. + (MV_CESA_MAC_THEN_CRYPTO << MV_CESA_OPERATION_OFFSET)) ||
  23254. + ((pSA->config & MV_CESA_OPERATION_MASK) ==
  23255. + (MV_CESA_CRYPTO_THEN_MAC << MV_CESA_OPERATION_OFFSET)) )
  23256. + {
  23257. + if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||
  23258. + ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&
  23259. + (mvCtrlRevGet() >= MV_5181L_A0_REV) &&
  23260. + (pCmd->macLength >= (1 << 14)) ) )
  23261. + {
  23262. + return MV_NOT_ALLOWED;
  23263. + }
  23264. +
  23265. + /* abs(cryptoOffset-macOffset) must be aligned cryptoBlockSize */
  23266. + if(pCmd->cryptoOffset > pCmd->macOffset)
  23267. + {
  23268. + offset = pCmd->cryptoOffset - pCmd->macOffset;
  23269. + }
  23270. + else
  23271. + {
  23272. + offset = pCmd->macOffset - pCmd->cryptoOffset;
  23273. + }
  23274. +
  23275. + if( MV_IS_NOT_ALIGN(offset, pSA->cryptoBlockSize) )
  23276. + {
  23277. +/*
  23278. + mvOsPrintf("mvCesaFragParamCheck: (cryptoOffset - macOffset) must be %d byte aligned\n",
  23279. + pSA->cryptoBlockSize);
  23280. +*/
  23281. + return MV_NOT_ALLOWED;
  23282. + }
  23283. + /* Digest must not be part of CryptoLength */
  23284. + if( ((pCmd->digestOffset + pSA->digestSize) > pCmd->cryptoOffset) &&
  23285. + (pCmd->digestOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )
  23286. + {
  23287. +/*
  23288. + mvOsPrintf("mvCesaFragParamCheck: digestOffset (%d) is part of cryptoLength (%d+%d)\n",
  23289. + pCmd->digestOffset, pCmd->cryptoOffset, pCmd->cryptoLength);
  23290. +*/
  23291. + return MV_NOT_ALLOWED;
  23292. + }
  23293. + }
  23294. + return MV_OK;
  23295. +}
  23296. +
  23297. +/*******************************************************************************
  23298. +* mvCesaFragSizeFind -
  23299. +*
  23300. +* DESCRIPTION:
  23301. +*
  23302. +*
  23303. +* INPUT:
  23304. +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,
  23305. +* int cryptoOffset, int macOffset,
  23306. +*
  23307. +* OUTPUT:
  23308. +* int* pCopySize, int* pCryptoDataSize, int* pMacDataSize
  23309. +*
  23310. +* RETURN:
  23311. +* MV_STATUS
  23312. +*
  23313. +*******************************************************************************/
  23314. +static void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq,
  23315. + int cryptoOffset, int macOffset,
  23316. + int* pCopySize, int* pCryptoDataSize, int* pMacDataSize)
  23317. +{
  23318. + MV_CESA_COMMAND *pCmd = pReq->pCmd;
  23319. + int cryptoDataSize, macDataSize, copySize;
  23320. +
  23321. + cryptoDataSize = macDataSize = 0;
  23322. + copySize = *pCopySize;
  23323. +
  23324. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  23325. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
  23326. + {
  23327. + cryptoDataSize = MV_MIN( (copySize - cryptoOffset),
  23328. + (pCmd->cryptoLength - (pReq->frags.cryptoSize + 1)) );
  23329. +
  23330. + /* cryptoSize for each fragment must be the whole number of blocksSize */
  23331. + if( MV_IS_NOT_ALIGN(cryptoDataSize, pSA->cryptoBlockSize) )
  23332. + {
  23333. + cryptoDataSize = MV_ALIGN_DOWN(cryptoDataSize, pSA->cryptoBlockSize);
  23334. + copySize = cryptoOffset + cryptoDataSize;
  23335. + }
  23336. + }
  23337. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  23338. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  23339. + {
  23340. + macDataSize = MV_MIN( (copySize - macOffset),
  23341. + (pCmd->macLength - (pReq->frags.macSize + 1)));
  23342. +
  23343. + /* macSize for each fragment (except last) must be the whole number of blocksSize */
  23344. + if( MV_IS_NOT_ALIGN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE) )
  23345. + {
  23346. + macDataSize = MV_ALIGN_DOWN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE);
  23347. + copySize = macOffset + macDataSize;
  23348. + }
  23349. + cryptoDataSize = copySize - cryptoOffset;
  23350. + }
  23351. + *pCopySize = copySize;
  23352. +
  23353. + if(pCryptoDataSize != NULL)
  23354. + *pCryptoDataSize = cryptoDataSize;
  23355. +
  23356. + if(pMacDataSize != NULL)
  23357. + *pMacDataSize = macDataSize;
  23358. +}
  23359. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesaDebug.c linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesaDebug.c
  23360. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesaDebug.c 1970-01-01 01:00:00.000000000 +0100
  23361. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesaDebug.c 2011-07-31 11:31:54.923415148 +0200
  23362. @@ -0,0 +1,484 @@
  23363. +/*******************************************************************************
  23364. +Copyright (C) Marvell International Ltd. and its affiliates
  23365. +
  23366. +This software file (the "File") is owned and distributed by Marvell
  23367. +International Ltd. and/or its affiliates ("Marvell") under the following
  23368. +alternative licensing terms. Once you have made an election to distribute the
  23369. +File under one of the following license alternatives, please (i) delete this
  23370. +introductory statement regarding license alternatives, (ii) delete the two
  23371. +license alternatives that you have not elected to use and (iii) preserve the
  23372. +Marvell copyright notice above.
  23373. +
  23374. +********************************************************************************
  23375. +Marvell Commercial License Option
  23376. +
  23377. +If you received this File from Marvell and you have entered into a commercial
  23378. +license agreement (a "Commercial License") with Marvell, the File is licensed
  23379. +to you under the terms of the applicable Commercial License.
  23380. +
  23381. +********************************************************************************
  23382. +Marvell GPL License Option
  23383. +
  23384. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23385. +modify this File in accordance with the terms and conditions of the General
  23386. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  23387. +available along with the File in the license.txt file or by writing to the Free
  23388. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  23389. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  23390. +
  23391. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  23392. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  23393. +DISCLAIMED. The GPL License provides additional details about this warranty
  23394. +disclaimer.
  23395. +********************************************************************************
  23396. +Marvell BSD License Option
  23397. +
  23398. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23399. +modify this File under the following licensing terms.
  23400. +Redistribution and use in source and binary forms, with or without modification,
  23401. +are permitted provided that the following conditions are met:
  23402. +
  23403. + * Redistributions of source code must retain the above copyright notice,
  23404. + this list of conditions and the following disclaimer.
  23405. +
  23406. + * Redistributions in binary form must reproduce the above copyright
  23407. + notice, this list of conditions and the following disclaimer in the
  23408. + documentation and/or other materials provided with the distribution.
  23409. +
  23410. + * Neither the name of Marvell nor the names of its contributors may be
  23411. + used to endorse or promote products derived from this software without
  23412. + specific prior written permission.
  23413. +
  23414. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  23415. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23416. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23417. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  23418. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23419. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23420. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  23421. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23422. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23423. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23424. +
  23425. +*******************************************************************************/
  23426. +
  23427. +#include "mvOs.h"
  23428. +#include "mvDebug.h"
  23429. +
  23430. +#include "cesa/mvMD5.h"
  23431. +#include "cesa/mvSHA1.h"
  23432. +
  23433. +#include "cesa/mvCesa.h"
  23434. +#include "cesa/mvCesaRegs.h"
  23435. +#include "cesa/AES/mvAes.h"
  23436. +
  23437. +static const char* mvCesaDebugStateStr(MV_CESA_STATE state)
  23438. +{
  23439. + switch(state)
  23440. + {
  23441. + case MV_CESA_IDLE:
  23442. + return "Idle";
  23443. +
  23444. + case MV_CESA_PENDING:
  23445. + return "Pend";
  23446. +
  23447. + case MV_CESA_PROCESS:
  23448. + return "Proc";
  23449. +
  23450. + case MV_CESA_READY:
  23451. + return "Ready";
  23452. +
  23453. + default:
  23454. + break;
  23455. + }
  23456. + return "Unknown";
  23457. +}
  23458. +
  23459. +static const char* mvCesaDebugOperStr(MV_CESA_OPERATION oper)
  23460. +{
  23461. + switch(oper)
  23462. + {
  23463. + case MV_CESA_MAC_ONLY:
  23464. + return "MacOnly";
  23465. +
  23466. + case MV_CESA_CRYPTO_ONLY:
  23467. + return "CryptoOnly";
  23468. +
  23469. + case MV_CESA_MAC_THEN_CRYPTO:
  23470. + return "MacCrypto";
  23471. +
  23472. + case MV_CESA_CRYPTO_THEN_MAC:
  23473. + return "CryptoMac";
  23474. +
  23475. + default:
  23476. + break;
  23477. + }
  23478. + return "Null";
  23479. +}
  23480. +
  23481. +static const char* mvCesaDebugCryptoAlgStr(MV_CESA_CRYPTO_ALG cryptoAlg)
  23482. +{
  23483. + switch(cryptoAlg)
  23484. + {
  23485. + case MV_CESA_CRYPTO_DES:
  23486. + return "DES";
  23487. +
  23488. + case MV_CESA_CRYPTO_3DES:
  23489. + return "3DES";
  23490. +
  23491. + case MV_CESA_CRYPTO_AES:
  23492. + return "AES";
  23493. +
  23494. + default:
  23495. + break;
  23496. + }
  23497. + return "Null";
  23498. +}
  23499. +
  23500. +static const char* mvCesaDebugMacModeStr(MV_CESA_MAC_MODE macMode)
  23501. +{
  23502. + switch(macMode)
  23503. + {
  23504. + case MV_CESA_MAC_MD5:
  23505. + return "MD5";
  23506. +
  23507. + case MV_CESA_MAC_SHA1:
  23508. + return "SHA1";
  23509. +
  23510. + case MV_CESA_MAC_HMAC_MD5:
  23511. + return "HMAC-MD5";
  23512. +
  23513. + case MV_CESA_MAC_HMAC_SHA1:
  23514. + return "HMAC_SHA1";
  23515. +
  23516. + default:
  23517. + break;
  23518. + }
  23519. + return "Null";
  23520. +}
  23521. +
  23522. +void mvCesaDebugCmd(MV_CESA_COMMAND* pCmd, int mode)
  23523. +{
  23524. + mvOsPrintf("pCmd=%p, pReqPrv=%p, pSrc=%p, pDst=%p, pCB=%p, sid=%d\n",
  23525. + pCmd, pCmd->pReqPrv, pCmd->pSrc, pCmd->pDst,
  23526. + pCmd->pFuncCB, pCmd->sessionId);
  23527. + mvOsPrintf("isUser=%d, ivOffs=%d, crOffs=%d, crLen=%d, digest=%d, macOffs=%d, macLen=%d\n",
  23528. + pCmd->ivFromUser, pCmd->ivOffset, pCmd->cryptoOffset, pCmd->cryptoLength,
  23529. + pCmd->digestOffset, pCmd->macOffset, pCmd->macLength);
  23530. +}
  23531. +
  23532. +/* no need to use in tool */
  23533. +void mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size)
  23534. +{
  23535. + int frag, len, fragOffset;
  23536. +
  23537. + if(str != NULL)
  23538. + mvOsPrintf("%s: pMbuf=%p, numFrags=%d, mbufSize=%d\n",
  23539. + str, pMbuf, pMbuf->numFrags, pMbuf->mbufSize);
  23540. +
  23541. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  23542. + if(frag == MV_INVALID)
  23543. + {
  23544. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  23545. + return;
  23546. + }
  23547. +
  23548. + for(; frag<pMbuf->numFrags; frag++)
  23549. + {
  23550. + mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n",
  23551. + frag, pMbuf->pFrags[frag].bufVirtPtr,
  23552. + pMbuf->pFrags[frag].bufSize);
  23553. + if(size > 0)
  23554. + {
  23555. + len = MV_MIN(pMbuf->pFrags[frag].bufSize, size);
  23556. + mvDebugMemDump(pMbuf->pFrags[frag].bufVirtPtr+fragOffset, len, 1);
  23557. + size -= len;
  23558. + fragOffset = 0;
  23559. + }
  23560. + }
  23561. +}
  23562. +
  23563. +void mvCesaDebugRegs(void)
  23564. +{
  23565. + mvOsPrintf("\t CESA Registers:\n");
  23566. +
  23567. + mvOsPrintf("MV_CESA_CMD_REG : 0x%X = 0x%08x\n",
  23568. + MV_CESA_CMD_REG,
  23569. + MV_REG_READ( MV_CESA_CMD_REG ) );
  23570. +
  23571. + mvOsPrintf("MV_CESA_CHAN_DESC_OFFSET_REG : 0x%X = 0x%08x\n",
  23572. + MV_CESA_CHAN_DESC_OFFSET_REG,
  23573. + MV_REG_READ(MV_CESA_CHAN_DESC_OFFSET_REG) );
  23574. +
  23575. + mvOsPrintf("MV_CESA_CFG_REG : 0x%X = 0x%08x\n",
  23576. + MV_CESA_CFG_REG,
  23577. + MV_REG_READ( MV_CESA_CFG_REG ) );
  23578. +
  23579. + mvOsPrintf("MV_CESA_STATUS_REG : 0x%X = 0x%08x\n",
  23580. + MV_CESA_STATUS_REG,
  23581. + MV_REG_READ( MV_CESA_STATUS_REG ) );
  23582. +
  23583. + mvOsPrintf("MV_CESA_ISR_CAUSE_REG : 0x%X = 0x%08x\n",
  23584. + MV_CESA_ISR_CAUSE_REG,
  23585. + MV_REG_READ( MV_CESA_ISR_CAUSE_REG ) );
  23586. +
  23587. + mvOsPrintf("MV_CESA_ISR_MASK_REG : 0x%X = 0x%08x\n",
  23588. + MV_CESA_ISR_MASK_REG,
  23589. + MV_REG_READ( MV_CESA_ISR_MASK_REG ) );
  23590. +#if (MV_CESA_VERSION >= 2)
  23591. + mvOsPrintf("MV_CESA_TDMA_CTRL_REG : 0x%X = 0x%08x\n",
  23592. + MV_CESA_TDMA_CTRL_REG,
  23593. + MV_REG_READ( MV_CESA_TDMA_CTRL_REG ) );
  23594. +
  23595. + mvOsPrintf("MV_CESA_TDMA_BYTE_COUNT_REG : 0x%X = 0x%08x\n",
  23596. + MV_CESA_TDMA_BYTE_COUNT_REG,
  23597. + MV_REG_READ( MV_CESA_TDMA_BYTE_COUNT_REG ) );
  23598. +
  23599. + mvOsPrintf("MV_CESA_TDMA_SRC_ADDR_REG : 0x%X = 0x%08x\n",
  23600. + MV_CESA_TDMA_SRC_ADDR_REG,
  23601. + MV_REG_READ( MV_CESA_TDMA_SRC_ADDR_REG ) );
  23602. +
  23603. + mvOsPrintf("MV_CESA_TDMA_DST_ADDR_REG : 0x%X = 0x%08x\n",
  23604. + MV_CESA_TDMA_DST_ADDR_REG,
  23605. + MV_REG_READ( MV_CESA_TDMA_DST_ADDR_REG ) );
  23606. +
  23607. + mvOsPrintf("MV_CESA_TDMA_NEXT_DESC_PTR_REG : 0x%X = 0x%08x\n",
  23608. + MV_CESA_TDMA_NEXT_DESC_PTR_REG,
  23609. + MV_REG_READ( MV_CESA_TDMA_NEXT_DESC_PTR_REG ) );
  23610. +
  23611. + mvOsPrintf("MV_CESA_TDMA_CURR_DESC_PTR_REG : 0x%X = 0x%08x\n",
  23612. + MV_CESA_TDMA_CURR_DESC_PTR_REG,
  23613. + MV_REG_READ( MV_CESA_TDMA_CURR_DESC_PTR_REG ) );
  23614. +
  23615. + mvOsPrintf("MV_CESA_TDMA_ERROR_CAUSE_REG : 0x%X = 0x%08x\n",
  23616. + MV_CESA_TDMA_ERROR_CAUSE_REG,
  23617. + MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );
  23618. +
  23619. + mvOsPrintf("MV_CESA_TDMA_ERROR_MASK_REG : 0x%X = 0x%08x\n",
  23620. + MV_CESA_TDMA_ERROR_MASK_REG,
  23621. + MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );
  23622. +
  23623. +#endif
  23624. +}
  23625. +
  23626. +void mvCesaDebugStatus(void)
  23627. +{
  23628. + mvOsPrintf("\n\t CESA Status\n\n");
  23629. +
  23630. + mvOsPrintf("pReqQ=%p, qDepth=%d, reqSize=%ld bytes, qRes=%d, ",
  23631. + pCesaReqFirst, cesaQueueDepth, sizeof(MV_CESA_REQ),
  23632. + cesaReqResources);
  23633. +#if (MV_CESA_VERSION >= 3)
  23634. + mvOsPrintf("chainLength=%u\n",cesaChainLength);
  23635. +#else
  23636. + mvOsPrintf("\n");
  23637. +#endif
  23638. +
  23639. + mvOsPrintf("pSAD=%p, maxSA=%d, sizeSA=%ld bytes\n",
  23640. + pCesaSAD, cesaMaxSA, sizeof(MV_CESA_SA));
  23641. +
  23642. + mvOsPrintf("\n");
  23643. +
  23644. + mvCesaDebugRegs();
  23645. + mvCesaDebugStats();
  23646. + mvCesaDebugStatsClear();
  23647. +}
  23648. +
  23649. +void mvCesaDebugDescriptor(MV_CESA_DESC* pDesc)
  23650. +{
  23651. + mvOsPrintf("config=0x%08x, crSrcOffs=0x%04x, crDstOffs=0x%04x\n",
  23652. + pDesc->config, pDesc->cryptoSrcOffset, pDesc->cryptoDstOffset);
  23653. +
  23654. + mvOsPrintf("crLen=0x%04x, crKeyOffs=0x%04x, ivOffs=0x%04x, ivBufOffs=0x%04x\n",
  23655. + pDesc->cryptoDataLen, pDesc->cryptoKeyOffset,
  23656. + pDesc->cryptoIvOffset, pDesc->cryptoIvBufOffset);
  23657. +
  23658. + mvOsPrintf("macSrc=0x%04x, digest=0x%04x, macLen=0x%04x, inIv=0x%04x, outIv=0x%04x\n",
  23659. + pDesc->macSrcOffset, pDesc->macDigestOffset, pDesc->macDataLen,
  23660. + pDesc->macInnerIvOffset, pDesc->macOuterIvOffset);
  23661. +}
  23662. +
  23663. +void mvCesaDebugQueue(int mode)
  23664. +{
  23665. + mvOsPrintf("\n\t CESA Request Queue:\n\n");
  23666. +
  23667. + mvOsPrintf("pFirstReq=%p, pLastReq=%p, qDepth=%d, reqSize=%ld bytes\n",
  23668. + pCesaReqFirst, pCesaReqLast, cesaQueueDepth, sizeof(MV_CESA_REQ));
  23669. +
  23670. + mvOsPrintf("pEmpty=%p, pProcess=%p, qResources=%d\n",
  23671. + pCesaReqEmpty, pCesaReqProcess,
  23672. + cesaReqResources);
  23673. +
  23674. + if(mode != 0)
  23675. + {
  23676. + int count = 0;
  23677. + MV_CESA_REQ* pReq = pCesaReqFirst;
  23678. +
  23679. + for(count=0; count<cesaQueueDepth; count++)
  23680. + {
  23681. + /* Print out requsts */
  23682. + mvOsPrintf("%02d. pReq=%p, state=%s, frag=0x%x, pCmd=%p, pDma=%p, pDesc=%p\n",
  23683. + count, pReq, mvCesaDebugStateStr(pReq->state),
  23684. + pReq->fragMode, pReq->pCmd, pReq->dma[0].pDmaFirst, &pReq->pCesaDesc[0]);
  23685. + if(pReq->fragMode != MV_CESA_FRAG_NONE)
  23686. + {
  23687. + int frag;
  23688. +
  23689. + mvOsPrintf("pFrags=%p, num=%d, next=%d, bufOffset=%d, cryptoSize=%d, macSize=%d\n",
  23690. + &pReq->frags, pReq->frags.numFrag, pReq->frags.nextFrag,
  23691. + pReq->frags.bufOffset, pReq->frags.cryptoSize, pReq->frags.macSize);
  23692. + for(frag=0; frag<pReq->frags.numFrag; frag++)
  23693. + {
  23694. + mvOsPrintf("#%d: pDmaFirst=%p, pDesc=%p\n", frag,
  23695. + pReq->dma[frag].pDmaFirst, &pReq->pCesaDesc[frag]);
  23696. + }
  23697. + }
  23698. + if(mode > 1)
  23699. + {
  23700. + /* Print out Command */
  23701. + mvCesaDebugCmd(pReq->pCmd, mode);
  23702. +
  23703. + /* Print out Descriptor */
  23704. + mvCesaDebugDescriptor(&pReq->pCesaDesc[0]);
  23705. + }
  23706. + pReq++;
  23707. + }
  23708. + }
  23709. +}
  23710. +
  23711. +
  23712. +void mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode)
  23713. +{
  23714. + if(pSramSA == NULL)
  23715. + {
  23716. + mvOsPrintf("cesaSramSA: Unexpected pSramSA=%p\n", pSramSA);
  23717. + return;
  23718. + }
  23719. + mvOsPrintf("pSramSA=%p, sizeSramSA=%ld bytes\n",
  23720. + pSramSA, sizeof(MV_CESA_SRAM_SA));
  23721. +
  23722. + if(mode != 0)
  23723. + {
  23724. + mvOsPrintf("cryptoKey=%p, maxCryptoKey=%d bytes\n",
  23725. + pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH);
  23726. + mvDebugMemDump(pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH, 1);
  23727. +
  23728. + mvOsPrintf("macInnerIV=%p, maxInnerIV=%d bytes\n",
  23729. + pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE);
  23730. + mvDebugMemDump(pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE, 1);
  23731. +
  23732. + mvOsPrintf("macOuterIV=%p, maxOuterIV=%d bytes\n",
  23733. + pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE);
  23734. + mvDebugMemDump(pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE, 1);
  23735. + }
  23736. +}
  23737. +
  23738. +void mvCesaDebugSA(short sid, int mode)
  23739. +{
  23740. + MV_CESA_OPERATION oper;
  23741. + MV_CESA_DIRECTION dir;
  23742. + MV_CESA_CRYPTO_ALG cryptoAlg;
  23743. + MV_CESA_CRYPTO_MODE cryptoMode;
  23744. + MV_CESA_MAC_MODE macMode;
  23745. + MV_CESA_SA* pSA = &pCesaSAD[sid];
  23746. +
  23747. + if( (pSA->valid) || ((pSA->count != 0) && (mode > 0)) || (mode >= 2) )
  23748. + {
  23749. + mvOsPrintf("\n\nCESA SA Entry #%d (%p) - %s (count=%d)\n",
  23750. + sid, pSA,
  23751. + pSA->valid ? "Valid" : "Invalid", pSA->count);
  23752. +
  23753. + oper = (pSA->config & MV_CESA_OPERATION_MASK) >> MV_CESA_OPERATION_OFFSET;
  23754. + dir = (pSA->config & MV_CESA_DIRECTION_MASK) >> MV_CESA_DIRECTION_BIT;
  23755. + mvOsPrintf("%s - %s ", mvCesaDebugOperStr(oper),
  23756. + (dir == MV_CESA_DIR_ENCODE) ? "Encode" : "Decode");
  23757. + if(oper != MV_CESA_MAC_ONLY)
  23758. + {
  23759. + cryptoAlg = (pSA->config & MV_CESA_CRYPTO_ALG_MASK) >> MV_CESA_CRYPTO_ALG_OFFSET;
  23760. + cryptoMode = (pSA->config & MV_CESA_CRYPTO_MODE_MASK) >> MV_CESA_CRYPTO_MODE_BIT;
  23761. + mvOsPrintf("- %s - %s ", mvCesaDebugCryptoAlgStr(cryptoAlg),
  23762. + (cryptoMode == MV_CESA_CRYPTO_ECB) ? "ECB" : "CBC");
  23763. + }
  23764. + if(oper != MV_CESA_CRYPTO_ONLY)
  23765. + {
  23766. + macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;
  23767. + mvOsPrintf("- %s ", mvCesaDebugMacModeStr(macMode));
  23768. + }
  23769. + mvOsPrintf("\n");
  23770. +
  23771. + if(mode > 0)
  23772. + {
  23773. + mvOsPrintf("config=0x%08x, cryptoKeySize=%d, digestSize=%d\n",
  23774. + pCesaSAD[sid].config, pCesaSAD[sid].cryptoKeyLength,
  23775. + pCesaSAD[sid].digestSize);
  23776. +
  23777. + mvCesaDebugSramSA(pCesaSAD[sid].pSramSA, mode);
  23778. + }
  23779. + }
  23780. +}
  23781. +
  23782. +
  23783. +/**/
  23784. +void mvCesaDebugSram(int mode)
  23785. +{
  23786. + mvOsPrintf("\n\t SRAM contents: size=%ld, pVirt=%p\n\n",
  23787. + sizeof(MV_CESA_SRAM_MAP), cesaSramVirtPtr);
  23788. +
  23789. + mvOsPrintf("\n\t Sram buffer: size=%d, pVirt=%p\n",
  23790. + MV_CESA_MAX_BUF_SIZE, cesaSramVirtPtr->buf);
  23791. + if(mode != 0)
  23792. + mvDebugMemDump(cesaSramVirtPtr->buf, 64, 1);
  23793. +
  23794. + mvOsPrintf("\n");
  23795. + mvOsPrintf("\n\t Sram descriptor: size=%ld, pVirt=%p\n",
  23796. + sizeof(MV_CESA_DESC), &cesaSramVirtPtr->desc);
  23797. + if(mode != 0)
  23798. + {
  23799. + mvOsPrintf("\n");
  23800. + mvCesaDebugDescriptor(&cesaSramVirtPtr->desc);
  23801. + }
  23802. + mvOsPrintf("\n\t Sram IV: size=%d, pVirt=%p\n",
  23803. + MV_CESA_MAX_IV_LENGTH, &cesaSramVirtPtr->cryptoIV);
  23804. + if(mode != 0)
  23805. + {
  23806. + mvOsPrintf("\n");
  23807. + mvDebugMemDump(cesaSramVirtPtr->cryptoIV, MV_CESA_MAX_IV_LENGTH, 1);
  23808. + }
  23809. + mvOsPrintf("\n");
  23810. + mvCesaDebugSramSA(&cesaSramVirtPtr->sramSA, 0);
  23811. +}
  23812. +
  23813. +void mvCesaDebugSAD(int mode)
  23814. +{
  23815. + int sid;
  23816. +
  23817. + mvOsPrintf("\n\t Cesa SAD status: pSAD=%p, maxSA=%d\n",
  23818. + pCesaSAD, cesaMaxSA);
  23819. +
  23820. + for(sid=0; sid<cesaMaxSA; sid++)
  23821. + {
  23822. + mvCesaDebugSA(sid, mode);
  23823. + }
  23824. +}
  23825. +
  23826. +void mvCesaDebugStats(void)
  23827. +{
  23828. + mvOsPrintf("\n\t Cesa Statistics\n");
  23829. +
  23830. + mvOsPrintf("Opened=%u, Closed=%u\n",
  23831. + cesaStats.openedCount, cesaStats.closedCount);
  23832. + mvOsPrintf("Req=%u, maxReq=%u, frags=%u, start=%u\n",
  23833. + cesaStats.reqCount, cesaStats.maxReqCount,
  23834. + cesaStats.fragCount, cesaStats.startCount);
  23835. +#if (MV_CESA_VERSION >= 3)
  23836. + mvOsPrintf("maxChainUsage=%u\n",cesaStats.maxChainUsage);
  23837. +#endif
  23838. + mvOsPrintf("\n");
  23839. + mvOsPrintf("proc=%u, ready=%u, notReady=%u\n",
  23840. + cesaStats.procCount, cesaStats.readyCount, cesaStats.notReadyCount);
  23841. +}
  23842. +
  23843. +void mvCesaDebugStatsClear(void)
  23844. +{
  23845. + memset(&cesaStats, 0, sizeof(cesaStats));
  23846. +}
  23847. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesa.h linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesa.h
  23848. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesa.h 1970-01-01 01:00:00.000000000 +0100
  23849. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesa.h 2011-07-31 11:31:54.973417428 +0200
  23850. @@ -0,0 +1,412 @@
  23851. +/*******************************************************************************
  23852. +Copyright (C) Marvell International Ltd. and its affiliates
  23853. +
  23854. +This software file (the "File") is owned and distributed by Marvell
  23855. +International Ltd. and/or its affiliates ("Marvell") under the following
  23856. +alternative licensing terms. Once you have made an election to distribute the
  23857. +File under one of the following license alternatives, please (i) delete this
  23858. +introductory statement regarding license alternatives, (ii) delete the two
  23859. +license alternatives that you have not elected to use and (iii) preserve the
  23860. +Marvell copyright notice above.
  23861. +
  23862. +********************************************************************************
  23863. +Marvell Commercial License Option
  23864. +
  23865. +If you received this File from Marvell and you have entered into a commercial
  23866. +license agreement (a "Commercial License") with Marvell, the File is licensed
  23867. +to you under the terms of the applicable Commercial License.
  23868. +
  23869. +********************************************************************************
  23870. +Marvell GPL License Option
  23871. +
  23872. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23873. +modify this File in accordance with the terms and conditions of the General
  23874. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  23875. +available along with the File in the license.txt file or by writing to the Free
  23876. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  23877. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  23878. +
  23879. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  23880. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  23881. +DISCLAIMED. The GPL License provides additional details about this warranty
  23882. +disclaimer.
  23883. +********************************************************************************
  23884. +Marvell BSD License Option
  23885. +
  23886. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23887. +modify this File under the following licensing terms.
  23888. +Redistribution and use in source and binary forms, with or without modification,
  23889. +are permitted provided that the following conditions are met:
  23890. +
  23891. + * Redistributions of source code must retain the above copyright notice,
  23892. + this list of conditions and the following disclaimer.
  23893. +
  23894. + * Redistributions in binary form must reproduce the above copyright
  23895. + notice, this list of conditions and the following disclaimer in the
  23896. + documentation and/or other materials provided with the distribution.
  23897. +
  23898. + * Neither the name of Marvell nor the names of its contributors may be
  23899. + used to endorse or promote products derived from this software without
  23900. + specific prior written permission.
  23901. +
  23902. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  23903. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23904. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23905. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  23906. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23907. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23908. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  23909. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23910. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23911. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23912. +
  23913. +*******************************************************************************/
  23914. +
  23915. +/*******************************************************************************
  23916. +* mvCesa.h - Header File for Cryptographic Engines and Security Accelerator
  23917. +*
  23918. +* DESCRIPTION:
  23919. +* This header file contains macros typedefs and function declaration for
  23920. +* the Marvell Cryptographic Engines and Security Accelerator.
  23921. +*
  23922. +*******************************************************************************/
  23923. +
  23924. +#ifndef __mvCesa_h__
  23925. +#define __mvCesa_h__
  23926. +
  23927. +#include "mvOs.h"
  23928. +#include "mvCommon.h"
  23929. +#include "mvDebug.h"
  23930. +
  23931. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  23932. +
  23933. +#include "cesa/mvMD5.h"
  23934. +#include "cesa/mvSHA1.h"
  23935. +
  23936. +#include "cesa/mvCesa.h"
  23937. +#include "cesa/AES/mvAes.h"
  23938. +#include "mvSysHwConfig.h"
  23939. +
  23940. +#ifdef MV_INCLUDE_IDMA
  23941. +#include "idma/mvIdma.h"
  23942. +#include "idma/mvIdmaRegs.h"
  23943. +#else
  23944. +/* Redefine MV_DMA_DESC structure */
  23945. +typedef struct _mvDmaDesc
  23946. +{
  23947. + MV_U32 byteCnt; /* The total number of bytes to transfer */
  23948. + MV_U32 phySrcAdd; /* The physical source address */
  23949. + MV_U32 phyDestAdd; /* The physical destination address */
  23950. + MV_U32 phyNextDescPtr; /* If we are using chain mode DMA transfer, */
  23951. + /* then this pointer should point to the */
  23952. + /* physical address of the next descriptor, */
  23953. + /* otherwise it should be NULL. */
  23954. +}MV_DMA_DESC;
  23955. +#endif /* MV_INCLUDE_IDMA */
  23956. +
  23957. +#include "cesa/mvCesaRegs.h"
  23958. +
  23959. +#define MV_CESA_AUTH_BLOCK_SIZE 64 /* bytes */
  23960. +
  23961. +#define MV_CESA_MD5_DIGEST_SIZE 16 /* bytes */
  23962. +#define MV_CESA_SHA1_DIGEST_SIZE 20 /* bytes */
  23963. +
  23964. +#define MV_CESA_MAX_DIGEST_SIZE MV_CESA_SHA1_DIGEST_SIZE
  23965. +
  23966. +#define MV_CESA_DES_KEY_LENGTH 8 /* bytes = 64 bits */
  23967. +#define MV_CESA_3DES_KEY_LENGTH 24 /* bytes = 192 bits */
  23968. +#define MV_CESA_AES_128_KEY_LENGTH 16 /* bytes = 128 bits */
  23969. +#define MV_CESA_AES_192_KEY_LENGTH 24 /* bytes = 192 bits */
  23970. +#define MV_CESA_AES_256_KEY_LENGTH 32 /* bytes = 256 bits */
  23971. +
  23972. +#define MV_CESA_MAX_CRYPTO_KEY_LENGTH MV_CESA_AES_256_KEY_LENGTH
  23973. +
  23974. +#define MV_CESA_DES_BLOCK_SIZE 8 /* bytes = 64 bits */
  23975. +#define MV_CESA_3DES_BLOCK_SIZE 8 /* bytes = 64 bits */
  23976. +
  23977. +#define MV_CESA_AES_BLOCK_SIZE 16 /* bytes = 128 bits */
  23978. +
  23979. +#define MV_CESA_MAX_IV_LENGTH MV_CESA_AES_BLOCK_SIZE
  23980. +
  23981. +#define MV_CESA_MAX_MAC_KEY_LENGTH 64 /* bytes */
  23982. +
  23983. +typedef struct
  23984. +{
  23985. + MV_U8 cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];
  23986. + MV_U8 macKey[MV_CESA_MAX_MAC_KEY_LENGTH];
  23987. + MV_CESA_OPERATION operation;
  23988. + MV_CESA_DIRECTION direction;
  23989. + MV_CESA_CRYPTO_ALG cryptoAlgorithm;
  23990. + MV_CESA_CRYPTO_MODE cryptoMode;
  23991. + MV_U8 cryptoKeyLength;
  23992. + MV_CESA_MAC_MODE macMode;
  23993. + MV_U8 macKeyLength;
  23994. + MV_U8 digestSize;
  23995. +
  23996. +} MV_CESA_OPEN_SESSION;
  23997. +
  23998. +typedef struct
  23999. +{
  24000. + MV_BUF_INFO *pFrags;
  24001. + MV_U16 numFrags;
  24002. + MV_U16 mbufSize;
  24003. +
  24004. +} MV_CESA_MBUF;
  24005. +
  24006. +typedef struct
  24007. +{
  24008. + void* pReqPrv; /* instead of reqId */
  24009. + MV_U32 retCode;
  24010. + MV_16 sessionId;
  24011. +
  24012. +} MV_CESA_RESULT;
  24013. +
  24014. +typedef void (*MV_CESA_CALLBACK) (MV_CESA_RESULT* pResult);
  24015. +
  24016. +
  24017. +typedef struct
  24018. +{
  24019. + void* pReqPrv; /* instead of reqId */
  24020. + MV_CESA_MBUF* pSrc;
  24021. + MV_CESA_MBUF* pDst;
  24022. + MV_CESA_CALLBACK* pFuncCB;
  24023. + MV_16 sessionId;
  24024. + MV_U16 ivFromUser;
  24025. + MV_U16 ivOffset;
  24026. + MV_U16 cryptoOffset;
  24027. + MV_U16 cryptoLength;
  24028. + MV_U16 digestOffset;
  24029. + MV_U16 macOffset;
  24030. + MV_U16 macLength;
  24031. + MV_BOOL skipFlush;
  24032. +} MV_CESA_COMMAND;
  24033. +
  24034. +
  24035. +
  24036. +MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase, void *osHandle);
  24037. +MV_STATUS mvCesaFinish (void);
  24038. +MV_STATUS mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid);
  24039. +MV_STATUS mvCesaSessionClose(short sid);
  24040. +MV_STATUS mvCesaCryptoIvSet(MV_U8* pIV, int ivSize);
  24041. +
  24042. +MV_STATUS mvCesaAction (MV_CESA_COMMAND* pCmd);
  24043. +
  24044. +MV_U32 mvCesaInProcessGet(void);
  24045. +MV_STATUS mvCesaReadyDispatch(void);
  24046. +MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult);
  24047. +MV_BOOL mvCesaIsReady(void);
  24048. +
  24049. +int mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset);
  24050. +MV_STATUS mvCesaCopyFromMbuf(MV_U8* pDst, MV_CESA_MBUF* pSrcMbuf,
  24051. + int offset, int size);
  24052. +MV_STATUS mvCesaCopyToMbuf(MV_U8* pSrc, MV_CESA_MBUF* pDstMbuf,
  24053. + int offset, int size);
  24054. +MV_STATUS mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,
  24055. + MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size);
  24056. +
  24057. +/********** Debug functions ********/
  24058. +
  24059. +void mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size);
  24060. +void mvCesaDebugSA(short sid, int mode);
  24061. +void mvCesaDebugStats(void);
  24062. +void mvCesaDebugStatsClear(void);
  24063. +void mvCesaDebugRegs(void);
  24064. +void mvCesaDebugStatus(void);
  24065. +void mvCesaDebugQueue(int mode);
  24066. +void mvCesaDebugSram(int mode);
  24067. +void mvCesaDebugSAD(int mode);
  24068. +
  24069. +
  24070. +/******** CESA Private definitions ********/
  24071. +#if (MV_CESA_VERSION >= 2)
  24072. +#if (MV_CACHE_COHERENCY == MV_CACHE_COHER_SW)
  24073. +#define MV_CESA_TDMA_CTRL_VALUE MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
  24074. + | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
  24075. + | MV_CESA_TDMA_OUTSTAND_READ_EN_MASK \
  24076. + | MV_CESA_TDMA_NO_BYTE_SWAP_MASK \
  24077. + | MV_CESA_TDMA_ENABLE_MASK
  24078. +#else
  24079. +#define MV_CESA_TDMA_CTRL_VALUE MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_32B) \
  24080. + | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
  24081. + /*| MV_CESA_TDMA_OUTSTAND_READ_EN_MASK */\
  24082. + | MV_CESA_TDMA_ENABLE_MASK
  24083. +
  24084. +#endif
  24085. +#else
  24086. +#define MV_CESA_IDMA_CTRL_LOW_VALUE ICCLR_DST_BURST_LIM_128BYTE \
  24087. + | ICCLR_SRC_BURST_LIM_128BYTE \
  24088. + | ICCLR_INT_MODE_MASK \
  24089. + | ICCLR_BLOCK_MODE \
  24090. + | ICCLR_CHAN_ENABLE \
  24091. + | ICCLR_DESC_MODE_16M
  24092. +#endif /* MV_CESA_VERSION >= 2 */
  24093. +
  24094. +#define MV_CESA_MAX_PKT_SIZE (64 * 1024)
  24095. +#define MV_CESA_MAX_MBUF_FRAGS 20
  24096. +
  24097. +#define MV_CESA_MAX_REQ_FRAGS ( (MV_CESA_MAX_PKT_SIZE / MV_CESA_MAX_BUF_SIZE) + 1)
  24098. +
  24099. +#define MV_CESA_MAX_DMA_DESC (MV_CESA_MAX_MBUF_FRAGS*2 + 5)
  24100. +
  24101. +#define MAX_CESA_CHAIN_LENGTH 20
  24102. +
  24103. +typedef enum
  24104. +{
  24105. + MV_CESA_IDLE = 0,
  24106. + MV_CESA_PENDING,
  24107. + MV_CESA_PROCESS,
  24108. + MV_CESA_READY,
  24109. +#if (MV_CESA_VERSION >= 3)
  24110. + MV_CESA_CHAIN,
  24111. +#endif
  24112. +} MV_CESA_STATE;
  24113. +
  24114. +
  24115. +/* Session database */
  24116. +
  24117. +/* Map of Key materials of the session in SRAM.
  24118. + * Each field must be 8 byte aligned
  24119. + * Total size: 32 + 24 + 24 = 80 bytes
  24120. + */
  24121. +typedef struct
  24122. +{
  24123. + MV_U8 cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];
  24124. + MV_U8 macInnerIV[MV_CESA_MAX_DIGEST_SIZE];
  24125. + MV_U8 reservedInner[4];
  24126. + MV_U8 macOuterIV[MV_CESA_MAX_DIGEST_SIZE];
  24127. + MV_U8 reservedOuter[4];
  24128. +
  24129. +} MV_CESA_SRAM_SA;
  24130. +
  24131. +typedef struct
  24132. +{
  24133. + MV_CESA_SRAM_SA* pSramSA;
  24134. + MV_U32 config;
  24135. + MV_U8 cryptoKeyLength;
  24136. + MV_U8 cryptoIvSize;
  24137. + MV_U8 cryptoBlockSize;
  24138. + MV_U8 digestSize;
  24139. + MV_U8 macKeyLength;
  24140. + MV_U8 valid;
  24141. + MV_U8 ctrMode;
  24142. + MV_U32 count;
  24143. +
  24144. +} MV_CESA_SA;
  24145. +
  24146. +/* DMA list management */
  24147. +typedef struct
  24148. +{
  24149. + MV_DMA_DESC* pDmaFirst;
  24150. + MV_DMA_DESC* pDmaLast;
  24151. +
  24152. +} MV_CESA_DMA;
  24153. +
  24154. +
  24155. +typedef struct
  24156. +{
  24157. + MV_U8 numFrag;
  24158. + MV_U8 nextFrag;
  24159. + int bufOffset;
  24160. + int cryptoSize;
  24161. + int macSize;
  24162. + int newDigestOffset;
  24163. + MV_U8 orgDigest[MV_CESA_MAX_DIGEST_SIZE];
  24164. +
  24165. +} MV_CESA_FRAGS;
  24166. +
  24167. +/* Request queue */
  24168. +typedef struct
  24169. +{
  24170. + MV_U8 state;
  24171. + MV_U8 fragMode;
  24172. + MV_U8 fixOffset;
  24173. + MV_CESA_COMMAND* pCmd;
  24174. + MV_CESA_COMMAND* pOrgCmd;
  24175. + MV_BUF_INFO dmaDescBuf;
  24176. + MV_CESA_DMA dma[MV_CESA_MAX_REQ_FRAGS];
  24177. + MV_BUF_INFO cesaDescBuf;
  24178. + MV_CESA_DESC* pCesaDesc;
  24179. + MV_CESA_FRAGS frags;
  24180. +
  24181. +
  24182. +} MV_CESA_REQ;
  24183. +
  24184. +
  24185. +/* SRAM map */
  24186. +/* Total SRAM size calculation */
  24187. +/* SRAM size =
  24188. + * MV_CESA_MAX_BUF_SIZE +
  24189. + * sizeof(MV_CESA_DESC) +
  24190. + * MV_CESA_MAX_IV_LENGTH +
  24191. + * MV_CESA_MAX_IV_LENGTH +
  24192. + * MV_CESA_MAX_DIGEST_SIZE +
  24193. + * sizeof(MV_CESA_SRAM_SA)
  24194. + * = 1600 + 32 + 16 + 16 + 24 + 80 + 280 (reserved) = 2048 bytes
  24195. + * = 3200 + 32 + 16 + 16 + 24 + 80 + 728 (reserved) = 4096 bytes
  24196. + */
  24197. +typedef struct
  24198. +{
  24199. + MV_U8 buf[MV_CESA_MAX_BUF_SIZE];
  24200. + MV_CESA_DESC desc;
  24201. + MV_U8 cryptoIV[MV_CESA_MAX_IV_LENGTH];
  24202. + MV_U8 tempCryptoIV[MV_CESA_MAX_IV_LENGTH];
  24203. + MV_U8 tempDigest[MV_CESA_MAX_DIGEST_SIZE+4];
  24204. + MV_CESA_SRAM_SA sramSA;
  24205. +
  24206. +} MV_CESA_SRAM_MAP;
  24207. +
  24208. +
  24209. +typedef struct
  24210. +{
  24211. + MV_U32 openedCount;
  24212. + MV_U32 closedCount;
  24213. + MV_U32 fragCount;
  24214. + MV_U32 reqCount;
  24215. + MV_U32 maxReqCount;
  24216. + MV_U32 procCount;
  24217. + MV_U32 readyCount;
  24218. + MV_U32 notReadyCount;
  24219. + MV_U32 startCount;
  24220. +#if (MV_CESA_VERSION >= 3)
  24221. + MV_U32 maxChainUsage;
  24222. +#endif
  24223. +
  24224. +} MV_CESA_STATS;
  24225. +
  24226. +
  24227. +/* External variables */
  24228. +
  24229. +extern MV_CESA_STATS cesaStats;
  24230. +extern MV_CESA_FRAGS cesaFrags;
  24231. +
  24232. +extern MV_BUF_INFO cesaSramSaBuf;
  24233. +
  24234. +extern MV_CESA_SA* pCesaSAD;
  24235. +extern MV_U16 cesaMaxSA;
  24236. +
  24237. +extern MV_CESA_REQ* pCesaReqFirst;
  24238. +extern MV_CESA_REQ* pCesaReqLast;
  24239. +extern MV_CESA_REQ* pCesaReqEmpty;
  24240. +extern MV_CESA_REQ* pCesaReqProcess;
  24241. +extern int cesaQueueDepth;
  24242. +extern int cesaReqResources;
  24243. +#if (MV_CESA_VERSION>= 3)
  24244. +extern MV_U32 cesaChainLength;
  24245. +#endif
  24246. +
  24247. +extern MV_CESA_SRAM_MAP* cesaSramVirtPtr;
  24248. +extern MV_U32 cesaSramPhysAddr;
  24249. +
  24250. +static INLINE MV_ULONG mvCesaVirtToPhys(MV_BUF_INFO* pBufInfo, void* pVirt)
  24251. +{
  24252. + return (pBufInfo->bufPhysAddr + ((MV_U8*)pVirt - pBufInfo->bufVirtPtr));
  24253. +}
  24254. +
  24255. +/* Additional DEBUG functions */
  24256. +void mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode);
  24257. +void mvCesaDebugCmd(MV_CESA_COMMAND* pCmd, int mode);
  24258. +void mvCesaDebugDescriptor(MV_CESA_DESC* pDesc);
  24259. +
  24260. +
  24261. +
  24262. +#endif /* __mvCesa_h__ */
  24263. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesaRegs.h linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesaRegs.h
  24264. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesaRegs.h 1970-01-01 01:00:00.000000000 +0100
  24265. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesaRegs.h 2011-07-31 11:31:55.033424351 +0200
  24266. @@ -0,0 +1,357 @@
  24267. +/*******************************************************************************
  24268. +Copyright (C) Marvell International Ltd. and its affiliates
  24269. +
  24270. +This software file (the "File") is owned and distributed by Marvell
  24271. +International Ltd. and/or its affiliates ("Marvell") under the following
  24272. +alternative licensing terms. Once you have made an election to distribute the
  24273. +File under one of the following license alternatives, please (i) delete this
  24274. +introductory statement regarding license alternatives, (ii) delete the two
  24275. +license alternatives that you have not elected to use and (iii) preserve the
  24276. +Marvell copyright notice above.
  24277. +
  24278. +********************************************************************************
  24279. +Marvell Commercial License Option
  24280. +
  24281. +If you received this File from Marvell and you have entered into a commercial
  24282. +license agreement (a "Commercial License") with Marvell, the File is licensed
  24283. +to you under the terms of the applicable Commercial License.
  24284. +
  24285. +********************************************************************************
  24286. +Marvell GPL License Option
  24287. +
  24288. +If you received this File from Marvell, you may opt to use, redistribute and/or
  24289. +modify this File in accordance with the terms and conditions of the General
  24290. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  24291. +available along with the File in the license.txt file or by writing to the Free
  24292. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  24293. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  24294. +
  24295. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  24296. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  24297. +DISCLAIMED. The GPL License provides additional details about this warranty
  24298. +disclaimer.
  24299. +********************************************************************************
  24300. +Marvell BSD License Option
  24301. +
  24302. +If you received this File from Marvell, you may opt to use, redistribute and/or
  24303. +modify this File under the following licensing terms.
  24304. +Redistribution and use in source and binary forms, with or without modification,
  24305. +are permitted provided that the following conditions are met:
  24306. +
  24307. + * Redistributions of source code must retain the above copyright notice,
  24308. + this list of conditions and the following disclaimer.
  24309. +
  24310. + * Redistributions in binary form must reproduce the above copyright
  24311. + notice, this list of conditions and the following disclaimer in the
  24312. + documentation and/or other materials provided with the distribution.
  24313. +
  24314. + * Neither the name of Marvell nor the names of its contributors may be
  24315. + used to endorse or promote products derived from this software without
  24316. + specific prior written permission.
  24317. +
  24318. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24319. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24320. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  24321. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  24322. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24323. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24324. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  24325. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24326. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24327. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24328. +
  24329. +*******************************************************************************/
  24330. +
  24331. +#ifndef __mvCesaRegs_h__
  24332. +#define __mvCesaRegs_h__
  24333. +
  24334. +#include "mvTypes.h"
  24335. +
  24336. +typedef struct
  24337. +{
  24338. + /* word 0 */
  24339. + MV_U32 config;
  24340. + /* word 1 */
  24341. + MV_U16 cryptoSrcOffset;
  24342. + MV_U16 cryptoDstOffset;
  24343. + /* word 2 */
  24344. + MV_U16 cryptoDataLen;
  24345. + MV_U16 reserved1;
  24346. + /* word 3 */
  24347. + MV_U16 cryptoKeyOffset;
  24348. + MV_U16 reserved2;
  24349. + /* word 4 */
  24350. + MV_U16 cryptoIvOffset;
  24351. + MV_U16 cryptoIvBufOffset;
  24352. + /* word 5 */
  24353. + MV_U16 macSrcOffset;
  24354. + MV_U16 macTotalLen;
  24355. + /* word 6 */
  24356. + MV_U16 macDigestOffset;
  24357. + MV_U16 macDataLen;
  24358. + /* word 7 */
  24359. + MV_U16 macInnerIvOffset;
  24360. + MV_U16 macOuterIvOffset;
  24361. +
  24362. +} MV_CESA_DESC;
  24363. +
  24364. +/* operation */
  24365. +typedef enum
  24366. +{
  24367. + MV_CESA_MAC_ONLY = 0,
  24368. + MV_CESA_CRYPTO_ONLY = 1,
  24369. + MV_CESA_MAC_THEN_CRYPTO = 2,
  24370. + MV_CESA_CRYPTO_THEN_MAC = 3,
  24371. +
  24372. + MV_CESA_MAX_OPERATION
  24373. +
  24374. +} MV_CESA_OPERATION;
  24375. +
  24376. +#define MV_CESA_OPERATION_OFFSET 0
  24377. +#define MV_CESA_OPERATION_MASK (0x3 << MV_CESA_OPERATION_OFFSET)
  24378. +
  24379. +/* mac algorithm */
  24380. +typedef enum
  24381. +{
  24382. + MV_CESA_MAC_NULL = 0,
  24383. + MV_CESA_MAC_MD5 = 4,
  24384. + MV_CESA_MAC_SHA1 = 5,
  24385. + MV_CESA_MAC_HMAC_MD5 = 6,
  24386. + MV_CESA_MAC_HMAC_SHA1 = 7,
  24387. +
  24388. +} MV_CESA_MAC_MODE;
  24389. +
  24390. +#define MV_CESA_MAC_MODE_OFFSET 4
  24391. +#define MV_CESA_MAC_MODE_MASK (0x7 << MV_CESA_MAC_MODE_OFFSET)
  24392. +
  24393. +typedef enum
  24394. +{
  24395. + MV_CESA_MAC_DIGEST_FULL = 0,
  24396. + MV_CESA_MAC_DIGEST_96B = 1,
  24397. +
  24398. +} MV_CESA_MAC_DIGEST_SIZE;
  24399. +
  24400. +#define MV_CESA_MAC_DIGEST_SIZE_BIT 7
  24401. +#define MV_CESA_MAC_DIGEST_SIZE_MASK (1 << MV_CESA_MAC_DIGEST_SIZE_BIT)
  24402. +
  24403. +
  24404. +typedef enum
  24405. +{
  24406. + MV_CESA_CRYPTO_NULL = 0,
  24407. + MV_CESA_CRYPTO_DES = 1,
  24408. + MV_CESA_CRYPTO_3DES = 2,
  24409. + MV_CESA_CRYPTO_AES = 3,
  24410. +
  24411. +} MV_CESA_CRYPTO_ALG;
  24412. +
  24413. +#define MV_CESA_CRYPTO_ALG_OFFSET 8
  24414. +#define MV_CESA_CRYPTO_ALG_MASK (0x3 << MV_CESA_CRYPTO_ALG_OFFSET)
  24415. +
  24416. +
  24417. +/* direction */
  24418. +typedef enum
  24419. +{
  24420. + MV_CESA_DIR_ENCODE = 0,
  24421. + MV_CESA_DIR_DECODE = 1,
  24422. +
  24423. +} MV_CESA_DIRECTION;
  24424. +
  24425. +#define MV_CESA_DIRECTION_BIT 12
  24426. +#define MV_CESA_DIRECTION_MASK (1 << MV_CESA_DIRECTION_BIT)
  24427. +
  24428. +/* crypto IV mode */
  24429. +typedef enum
  24430. +{
  24431. + MV_CESA_CRYPTO_ECB = 0,
  24432. + MV_CESA_CRYPTO_CBC = 1,
  24433. +
  24434. + /* NO HW Support */
  24435. + MV_CESA_CRYPTO_CTR = 10,
  24436. +
  24437. +} MV_CESA_CRYPTO_MODE;
  24438. +
  24439. +#define MV_CESA_CRYPTO_MODE_BIT 16
  24440. +#define MV_CESA_CRYPTO_MODE_MASK (1 << MV_CESA_CRYPTO_MODE_BIT)
  24441. +
  24442. +/* 3DES mode */
  24443. +typedef enum
  24444. +{
  24445. + MV_CESA_CRYPTO_3DES_EEE = 0,
  24446. + MV_CESA_CRYPTO_3DES_EDE = 1,
  24447. +
  24448. +} MV_CESA_CRYPTO_3DES_MODE;
  24449. +
  24450. +#define MV_CESA_CRYPTO_3DES_MODE_BIT 20
  24451. +#define MV_CESA_CRYPTO_3DES_MODE_MASK (1 << MV_CESA_CRYPTO_3DES_MODE_BIT)
  24452. +
  24453. +
  24454. +/* AES Key Length */
  24455. +typedef enum
  24456. +{
  24457. + MV_CESA_CRYPTO_AES_KEY_128 = 0,
  24458. + MV_CESA_CRYPTO_AES_KEY_192 = 1,
  24459. + MV_CESA_CRYPTO_AES_KEY_256 = 2,
  24460. +
  24461. +} MV_CESA_CRYPTO_AES_KEY_LEN;
  24462. +
  24463. +#define MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET 24
  24464. +#define MV_CESA_CRYPTO_AES_KEY_LEN_MASK (0x3 << MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET)
  24465. +
  24466. +/* Fragmentation mode */
  24467. +typedef enum
  24468. +{
  24469. + MV_CESA_FRAG_NONE = 0,
  24470. + MV_CESA_FRAG_FIRST = 1,
  24471. + MV_CESA_FRAG_LAST = 2,
  24472. + MV_CESA_FRAG_MIDDLE = 3,
  24473. +
  24474. +} MV_CESA_FRAG_MODE;
  24475. +
  24476. +#define MV_CESA_FRAG_MODE_OFFSET 30
  24477. +#define MV_CESA_FRAG_MODE_MASK (0x3 << MV_CESA_FRAG_MODE_OFFSET)
  24478. +/*---------------------------------------------------------------------------*/
  24479. +
  24480. +/********** Security Accelerator Command Register **************/
  24481. +#define MV_CESA_CMD_REG (MV_CESA_REG_BASE + 0xE00)
  24482. +
  24483. +#define MV_CESA_CMD_CHAN_ENABLE_BIT 0
  24484. +#define MV_CESA_CMD_CHAN_ENABLE_MASK (1 << MV_CESA_CMD_CHAN_ENABLE_BIT)
  24485. +
  24486. +#define MV_CESA_CMD_CHAN_DISABLE_BIT 2
  24487. +#define MV_CESA_CMD_CHAN_DISABLE_MASK (1 << MV_CESA_CMD_CHAN_DISABLE_BIT)
  24488. +
  24489. +/********** Security Accelerator Descriptor Pointers Register **********/
  24490. +#define MV_CESA_CHAN_DESC_OFFSET_REG (MV_CESA_REG_BASE + 0xE04)
  24491. +
  24492. +/********** Security Accelerator Configuration Register **********/
  24493. +#define MV_CESA_CFG_REG (MV_CESA_REG_BASE + 0xE08)
  24494. +
  24495. +#define MV_CESA_CFG_STOP_DIGEST_ERR_BIT 0
  24496. +#define MV_CESA_CFG_STOP_DIGEST_ERR_MASK (1 << MV_CESA_CFG_STOP_DIGEST_ERR_BIT)
  24497. +
  24498. +#define MV_CESA_CFG_WAIT_DMA_BIT 7
  24499. +#define MV_CESA_CFG_WAIT_DMA_MASK (1 << MV_CESA_CFG_WAIT_DMA_BIT)
  24500. +
  24501. +#define MV_CESA_CFG_ACT_DMA_BIT 9
  24502. +#define MV_CESA_CFG_ACT_DMA_MASK (1 << MV_CESA_CFG_ACT_DMA_BIT)
  24503. +
  24504. +#define MV_CESA_CFG_CHAIN_MODE_BIT 11
  24505. +#define MV_CESA_CFG_CHAIN_MODE_MASK (1 << MV_CESA_CFG_CHAIN_MODE_BIT)
  24506. +
  24507. +/********** Security Accelerator Status Register ***********/
  24508. +#define MV_CESA_STATUS_REG (MV_CESA_REG_BASE + 0xE0C)
  24509. +
  24510. +#define MV_CESA_STATUS_ACTIVE_BIT 0
  24511. +#define MV_CESA_STATUS_ACTIVE_MASK (1 << MV_CESA_STATUS_ACTIVE_BIT)
  24512. +
  24513. +#define MV_CESA_STATUS_DIGEST_ERR_BIT 8
  24514. +#define MV_CESA_STATUS_DIGEST_ERR_MASK (1 << MV_CESA_STATUS_DIGEST_ERR_BIT)
  24515. +
  24516. +
  24517. +/* Cryptographic Engines and Security Accelerator Interrupt Cause Register */
  24518. +#define MV_CESA_ISR_CAUSE_REG (MV_CESA_REG_BASE + 0xE20)
  24519. +
  24520. +/* Cryptographic Engines and Security Accelerator Interrupt Mask Register */
  24521. +#define MV_CESA_ISR_MASK_REG (MV_CESA_REG_BASE + 0xE24)
  24522. +
  24523. +#define MV_CESA_CAUSE_AUTH_MASK (1 << 0)
  24524. +#define MV_CESA_CAUSE_DES_MASK (1 << 1)
  24525. +#define MV_CESA_CAUSE_AES_ENCR_MASK (1 << 2)
  24526. +#define MV_CESA_CAUSE_AES_DECR_MASK (1 << 3)
  24527. +#define MV_CESA_CAUSE_DES_ALL_MASK (1 << 4)
  24528. +
  24529. +#define MV_CESA_CAUSE_ACC_BIT 5
  24530. +#define MV_CESA_CAUSE_ACC_MASK (1 << MV_CESA_CAUSE_ACC_BIT)
  24531. +
  24532. +#define MV_CESA_CAUSE_ACC_DMA_BIT 7
  24533. +#define MV_CESA_CAUSE_ACC_DMA_MASK (1 << MV_CESA_CAUSE_ACC_DMA_BIT)
  24534. +#define MV_CESA_CAUSE_ACC_DMA_ALL_MASK (3 << MV_CESA_CAUSE_ACC_DMA_BIT)
  24535. +
  24536. +#define MV_CESA_CAUSE_DMA_COMPL_BIT 9
  24537. +#define MV_CESA_CAUSE_DMA_COMPL_MASK (1 << MV_CESA_CAUSE_DMA_COMPL_BIT)
  24538. +
  24539. +#define MV_CESA_CAUSE_DMA_OWN_ERR_BIT 10
  24540. +#define MV_CESA_CAUSE_DMA_OWN_ERR_MASK (1 < MV_CESA_CAUSE_DMA_OWN_ERR_BIT)
  24541. +
  24542. +#define MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT 11
  24543. +#define MV_CESA_CAUSE_DMA_CHAIN_PKT_MASK (1 < MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT)
  24544. +
  24545. +
  24546. +#define MV_CESA_AUTH_DATA_IN_REG (MV_CESA_REG_BASE + 0xd38)
  24547. +#define MV_CESA_AUTH_BIT_COUNT_LOW_REG (MV_CESA_REG_BASE + 0xd20)
  24548. +#define MV_CESA_AUTH_BIT_COUNT_HIGH_REG (MV_CESA_REG_BASE + 0xd24)
  24549. +
  24550. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i) (MV_CESA_REG_BASE + 0xd00 + (i<<2))
  24551. +
  24552. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_A_REG (MV_CESA_REG_BASE + 0xd00)
  24553. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_B_REG (MV_CESA_REG_BASE + 0xd04)
  24554. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_C_REG (MV_CESA_REG_BASE + 0xd08)
  24555. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_D_REG (MV_CESA_REG_BASE + 0xd0c)
  24556. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_E_REG (MV_CESA_REG_BASE + 0xd10)
  24557. +#define MV_CESA_AUTH_COMMAND_REG (MV_CESA_REG_BASE + 0xd18)
  24558. +
  24559. +#define MV_CESA_AUTH_ALGORITHM_BIT 0
  24560. +#define MV_CESA_AUTH_ALGORITHM_MD5 (0<<AUTH_ALGORITHM_BIT)
  24561. +#define MV_CESA_AUTH_ALGORITHM_SHA1 (1<<AUTH_ALGORITHM_BIT)
  24562. +
  24563. +#define MV_CESA_AUTH_IV_MODE_BIT 1
  24564. +#define MV_CESA_AUTH_IV_MODE_INIT (0<<AUTH_IV_MODE_BIT)
  24565. +#define MV_CESA_AUTH_IV_MODE_CONTINUE (1<<AUTH_IV_MODE_BIT)
  24566. +
  24567. +#define MV_CESA_AUTH_DATA_BYTE_SWAP_BIT 2
  24568. +#define MV_CESA_AUTH_DATA_BYTE_SWAP_MASK (1<<AUTH_DATA_BYTE_SWAP_BIT)
  24569. +
  24570. +
  24571. +#define MV_CESA_AUTH_IV_BYTE_SWAP_BIT 4
  24572. +#define MV_CESA_AUTH_IV_BYTE_SWAP_MASK (1<<AUTH_IV_BYTE_SWAP_BIT)
  24573. +
  24574. +#define MV_CESA_AUTH_TERMINATION_BIT 31
  24575. +#define MV_CESA_AUTH_TERMINATION_MASK (1<<AUTH_TERMINATION_BIT)
  24576. +
  24577. +
  24578. +/*************** TDMA Control Register ************************************************/
  24579. +#define MV_CESA_TDMA_CTRL_REG (MV_CESA_TDMA_REG_BASE + 0x840)
  24580. +
  24581. +#define MV_CESA_TDMA_BURST_32B 3
  24582. +#define MV_CESA_TDMA_BURST_128B 4
  24583. +
  24584. +#define MV_CESA_TDMA_DST_BURST_OFFSET 0
  24585. +#define MV_CESA_TDMA_DST_BURST_ALL_MASK (0x7<<MV_CESA_TDMA_DST_BURST_OFFSET)
  24586. +#define MV_CESA_TDMA_DST_BURST_MASK(burst) ((burst)<<MV_CESA_TDMA_DST_BURST_OFFSET)
  24587. +
  24588. +#define MV_CESA_TDMA_OUTSTAND_READ_EN_BIT 4
  24589. +#define MV_CESA_TDMA_OUTSTAND_READ_EN_MASK (1<<MV_CESA_TDMA_OUTSTAND_READ_EN_BIT)
  24590. +
  24591. +#define MV_CESA_TDMA_SRC_BURST_OFFSET 6
  24592. +#define MV_CESA_TDMA_SRC_BURST_ALL_MASK (0x7<<MV_CESA_TDMA_SRC_BURST_OFFSET)
  24593. +#define MV_CESA_TDMA_SRC_BURST_MASK(burst) ((burst)<<MV_CESA_TDMA_SRC_BURST_OFFSET)
  24594. +
  24595. +#define MV_CESA_TDMA_CHAIN_MODE_BIT 9
  24596. +#define MV_CESA_TDMA_NON_CHAIN_MODE_MASK (1<<MV_CESA_TDMA_CHAIN_MODE_BIT)
  24597. +
  24598. +#define MV_CESA_TDMA_BYTE_SWAP_BIT 11
  24599. +#define MV_CESA_TDMA_BYTE_SWAP_MASK (0 << MV_CESA_TDMA_BYTE_SWAP_BIT)
  24600. +#define MV_CESA_TDMA_NO_BYTE_SWAP_MASK (1 << MV_CESA_TDMA_BYTE_SWAP_BIT)
  24601. +
  24602. +#define MV_CESA_TDMA_ENABLE_BIT 12
  24603. +#define MV_CESA_TDMA_ENABLE_MASK (1<<MV_CESA_TDMA_ENABLE_BIT)
  24604. +
  24605. +#define MV_CESA_TDMA_FETCH_NEXT_DESC_BIT 13
  24606. +#define MV_CESA_TDMA_FETCH_NEXT_DESC_MASK (1<<MV_CESA_TDMA_FETCH_NEXT_DESC_BIT)
  24607. +
  24608. +#define MV_CESA_TDMA_CHAN_ACTIVE_BIT 14
  24609. +#define MV_CESA_TDMA_CHAN_ACTIVE_MASK (1<<MV_CESA_TDMA_CHAN_ACTIVE_BIT)
  24610. +/*------------------------------------------------------------------------------------*/
  24611. +
  24612. +#define MV_CESA_TDMA_BYTE_COUNT_REG (MV_CESA_TDMA_REG_BASE + 0x800)
  24613. +#define MV_CESA_TDMA_SRC_ADDR_REG (MV_CESA_TDMA_REG_BASE + 0x810)
  24614. +#define MV_CESA_TDMA_DST_ADDR_REG (MV_CESA_TDMA_REG_BASE + 0x820)
  24615. +#define MV_CESA_TDMA_NEXT_DESC_PTR_REG (MV_CESA_TDMA_REG_BASE + 0x830)
  24616. +#define MV_CESA_TDMA_CURR_DESC_PTR_REG (MV_CESA_TDMA_REG_BASE + 0x870)
  24617. +
  24618. +#define MV_CESA_TDMA_ERROR_CAUSE_REG (MV_CESA_TDMA_REG_BASE + 0x8C0)
  24619. +#define MV_CESA_TDMA_ERROR_MASK_REG (MV_CESA_TDMA_REG_BASE + 0x8C4)
  24620. +
  24621. +
  24622. +#endif /* __mvCesaRegs_h__ */
  24623. +
  24624. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesaTest.c linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesaTest.c
  24625. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesaTest.c 1970-01-01 01:00:00.000000000 +0100
  24626. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesaTest.c 2011-07-31 11:31:55.053418421 +0200
  24627. @@ -0,0 +1,3096 @@
  24628. +/*******************************************************************************
  24629. +Copyright (C) Marvell International Ltd. and its affiliates
  24630. +
  24631. +This software file (the "File") is owned and distributed by Marvell
  24632. +International Ltd. and/or its affiliates ("Marvell") under the following
  24633. +alternative licensing terms. Once you have made an election to distribute the
  24634. +File under one of the following license alternatives, please (i) delete this
  24635. +introductory statement regarding license alternatives, (ii) delete the two
  24636. +license alternatives that you have not elected to use and (iii) preserve the
  24637. +Marvell copyright notice above.
  24638. +
  24639. +********************************************************************************
  24640. +Marvell Commercial License Option
  24641. +
  24642. +If you received this File from Marvell and you have entered into a commercial
  24643. +license agreement (a "Commercial License") with Marvell, the File is licensed
  24644. +to you under the terms of the applicable Commercial License.
  24645. +
  24646. +********************************************************************************
  24647. +Marvell GPL License Option
  24648. +
  24649. +If you received this File from Marvell, you may opt to use, redistribute and/or
  24650. +modify this File in accordance with the terms and conditions of the General
  24651. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  24652. +available along with the File in the license.txt file or by writing to the Free
  24653. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  24654. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  24655. +
  24656. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  24657. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  24658. +DISCLAIMED. The GPL License provides additional details about this warranty
  24659. +disclaimer.
  24660. +********************************************************************************
  24661. +Marvell BSD License Option
  24662. +
  24663. +If you received this File from Marvell, you may opt to use, redistribute and/or
  24664. +modify this File under the following licensing terms.
  24665. +Redistribution and use in source and binary forms, with or without modification,
  24666. +are permitted provided that the following conditions are met:
  24667. +
  24668. + * Redistributions of source code must retain the above copyright notice,
  24669. + this list of conditions and the following disclaimer.
  24670. +
  24671. + * Redistributions in binary form must reproduce the above copyright
  24672. + notice, this list of conditions and the following disclaimer in the
  24673. + documentation and/or other materials provided with the distribution.
  24674. +
  24675. + * Neither the name of Marvell nor the names of its contributors may be
  24676. + used to endorse or promote products derived from this software without
  24677. + specific prior written permission.
  24678. +
  24679. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24680. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24681. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  24682. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  24683. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24684. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24685. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  24686. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24687. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24688. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24689. +
  24690. +*******************************************************************************/
  24691. +
  24692. +#include "mvOs.h"
  24693. +
  24694. +#if defined(MV_VXWORKS)
  24695. +
  24696. +#include "sysLib.h"
  24697. +#include "logLib.h"
  24698. +#include "tickLib.h"
  24699. +#include "intLib.h"
  24700. +#include "config.h"
  24701. +
  24702. +
  24703. +SEM_ID cesaSemId = NULL;
  24704. +SEM_ID cesaWaitSemId = NULL;
  24705. +
  24706. +#define CESA_TEST_LOCK(flags) flags = intLock()
  24707. +#define CESA_TEST_UNLOCK(flags) intUnlock(flags)
  24708. +
  24709. +#define CESA_TEST_WAIT_INIT() cesaWaitSemId = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)
  24710. +#define CESA_TEST_WAKE_UP() semGive(cesaWaitSemId)
  24711. +#define CESA_TEST_WAIT(cond, ms) semTake(cesaWaitSemId, (sysClkRateGet()*ms)/1000)
  24712. +
  24713. +#define CESA_TEST_TICK_GET() tickGet()
  24714. +#define CESA_TEST_TICK_TO_MS(tick) (((tick)*1000)/sysClkRateGet())
  24715. +
  24716. +#elif defined(MV_LINUX)
  24717. +
  24718. +#include <linux/wait.h>
  24719. +wait_queue_head_t cesaTest_waitq;
  24720. +spinlock_t cesaLock;
  24721. +
  24722. +#define CESA_TEST_LOCK(flags) spin_lock_irqsave( &cesaLock, flags)
  24723. +#define CESA_TEST_UNLOCK(flags) spin_unlock_irqrestore( &cesaLock, flags);
  24724. +
  24725. +#define CESA_TEST_WAIT_INIT() init_waitqueue_head(&cesaTest_waitq)
  24726. +#define CESA_TEST_WAKE_UP() wake_up(&cesaTest_waitq)
  24727. +#define CESA_TEST_WAIT(cond, ms) wait_event_timeout(cesaTest_waitq, (cond), msecs_to_jiffies(ms))
  24728. +
  24729. +#define CESA_TEST_TICK_GET() jiffies
  24730. +#define CESA_TEST_TICK_TO_MS(tick) jiffies_to_msecs(tick)
  24731. +
  24732. +#elif defined(MV_NETBSD)
  24733. +
  24734. +#include <sys/param.h>
  24735. +#include <sys/kernel.h>
  24736. +static int cesaLock;
  24737. +
  24738. +#define CESA_TEST_LOCK(flags) flags = splnet()
  24739. +#define CESA_TEST_UNLOCK(flags) splx(flags)
  24740. +
  24741. +#define CESA_TEST_WAIT_INIT() /* nothing */
  24742. +#define CESA_TEST_WAKE_UP() wakeup(&cesaLock)
  24743. +#define CESA_TEST_WAIT(cond, ms) \
  24744. +do { \
  24745. + while (!(cond)) \
  24746. + tsleep(&cesaLock, PWAIT, "cesatest",mstohz(ms)); \
  24747. +} while (/*CONSTCOND*/0)
  24748. +
  24749. +#define CESA_TEST_TICK_GET() hardclock_ticks
  24750. +#define CESA_TEST_TICK_TO_MS(tick) ((1000/hz)*(tick))
  24751. +
  24752. +#define request_irq(i,h,t,n,a) \
  24753. + !mv_intr_establish((i),IPL_NET,(int(*)(void *))(h),(a))
  24754. +
  24755. +#else
  24756. +#error "Only Linux, VxWorks, or NetBSD OS are supported"
  24757. +#endif
  24758. +
  24759. +#include "mvDebug.h"
  24760. +
  24761. +#include "mvSysHwConfig.h"
  24762. +#include "boardEnv/mvBoardEnvLib.h"
  24763. +#include "ctrlEnv/sys/mvCpuIf.h"
  24764. +#include "cntmr/mvCntmr.h"
  24765. +#include "cesa/mvCesa.h"
  24766. +#include "cesa/mvCesaRegs.h"
  24767. +#include "cesa/mvMD5.h"
  24768. +#include "cesa/mvSHA1.h"
  24769. +
  24770. +#if defined(CONFIG_MV646xx)
  24771. +#include "marvell_pic.h"
  24772. +#endif
  24773. +
  24774. +#define MV_CESA_USE_TIMER_ID 0
  24775. +#define CESA_DEF_BUF_SIZE 1500
  24776. +#define CESA_DEF_BUF_NUM 1
  24777. +#define CESA_DEF_SESSION_NUM 32
  24778. +
  24779. +#define CESA_DEF_ITER_NUM 100
  24780. +
  24781. +#define CESA_DEF_REQ_SIZE 256
  24782. +
  24783. +
  24784. +/* CESA Tests Debug */
  24785. +#undef CESA_TEST_DEBUG
  24786. +
  24787. +#ifdef CESA_TEST_DEBUG
  24788. +
  24789. +# define CESA_TEST_DEBUG_PRINT(msg) mvOsPrintf msg
  24790. +# define CESA_TEST_DEBUG_CODE(code) code
  24791. +
  24792. +typedef struct
  24793. +{
  24794. + int type; /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */
  24795. + MV_U32 timeStamp;
  24796. + MV_U32 cause;
  24797. + MV_U32 realCause;
  24798. + MV_U32 dmaCause;
  24799. + int resources;
  24800. + MV_CESA_REQ* pReqReady;
  24801. + MV_CESA_REQ* pReqEmpty;
  24802. + MV_CESA_REQ* pReqProcess;
  24803. +} MV_CESA_TEST_TRACE;
  24804. +
  24805. +#define MV_CESA_TEST_TRACE_SIZE 25
  24806. +
  24807. +static int cesaTestTraceIdx = 0;
  24808. +static MV_CESA_TEST_TRACE cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];
  24809. +
  24810. +static void cesaTestTraceAdd(int type, MV_U32 cause)
  24811. +{
  24812. + cesaTestTrace[cesaTestTraceIdx].type = type;
  24813. + cesaTestTrace[cesaTestTraceIdx].cause = cause;
  24814. + cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  24815. + cesaTestTrace[cesaTestTraceIdx].dmaCause = MV_REG_READ(IDMA_CAUSE_REG);
  24816. + cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;
  24817. + cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;
  24818. + cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;
  24819. + cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;
  24820. + cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);
  24821. + cesaTestTraceIdx++;
  24822. + if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)
  24823. + cesaTestTraceIdx = 0;
  24824. +}
  24825. +
  24826. +#else
  24827. +
  24828. +# define CESA_TEST_DEBUG_PRINT(msg)
  24829. +# define CESA_TEST_DEBUG_CODE(code)
  24830. +
  24831. +#endif /* CESA_TEST_DEBUG */
  24832. +
  24833. +int cesaExpReqId=0;
  24834. +int cesaCbIter=0;
  24835. +
  24836. +int cesaIdx;
  24837. +int cesaIteration;
  24838. +int cesaRateSize;
  24839. +int cesaReqSize;
  24840. +unsigned long cesaTaskId;
  24841. +int cesaBufNum;
  24842. +int cesaBufSize;
  24843. +int cesaCheckOffset;
  24844. +int cesaCheckSize;
  24845. +int cesaCheckMode;
  24846. +int cesaTestIdx;
  24847. +int cesaCaseIdx;
  24848. +
  24849. +
  24850. +MV_U32 cesaTestIsrCount = 0;
  24851. +MV_U32 cesaTestIsrMissCount = 0;
  24852. +
  24853. +MV_U32 cesaCryptoError = 0;
  24854. +MV_U32 cesaReqIdError = 0;
  24855. +MV_U32 cesaError = 0;
  24856. +
  24857. +char* cesaHexBuffer = NULL;
  24858. +
  24859. +char* cesaBinBuffer = NULL;
  24860. +char* cesaExpBinBuffer = NULL;
  24861. +
  24862. +char* cesaInputHexStr = NULL;
  24863. +char* cesaOutputHexStr = NULL;
  24864. +
  24865. +MV_BUF_INFO cesaReqBufs[CESA_DEF_REQ_SIZE];
  24866. +
  24867. +MV_CESA_COMMAND* cesaCmdRing;
  24868. +MV_CESA_RESULT cesaResult;
  24869. +
  24870. +int cesaTestFull = 0;
  24871. +
  24872. +MV_BOOL cesaIsReady = MV_FALSE;
  24873. +MV_U32 cesaCycles = 0;
  24874. +MV_U32 cesaBeginTicks = 0;
  24875. +MV_U32 cesaEndTicks = 0;
  24876. +MV_U32 cesaRate = 0;
  24877. +MV_U32 cesaRateAfterDot = 0;
  24878. +
  24879. +void *cesaTestOSHandle = NULL;
  24880. +
  24881. +enum
  24882. +{
  24883. + CESA_FAST_CHECK_MODE = 0,
  24884. + CESA_FULL_CHECK_MODE,
  24885. + CESA_NULL_CHECK_MODE,
  24886. + CESA_SHOW_CHECK_MODE,
  24887. + CESA_SW_SHOW_CHECK_MODE,
  24888. + CESA_SW_NULL_CHECK_MODE,
  24889. +
  24890. + CESA_MAX_CHECK_MODE
  24891. +};
  24892. +
  24893. +enum
  24894. +{
  24895. + DES_TEST_TYPE = 0,
  24896. + TRIPLE_DES_TEST_TYPE = 1,
  24897. + AES_TEST_TYPE = 2,
  24898. + MD5_TEST_TYPE = 3,
  24899. + SHA_TEST_TYPE = 4,
  24900. + COMBINED_TEST_TYPE = 5,
  24901. +
  24902. + MAX_TEST_TYPE
  24903. +};
  24904. +
  24905. +/* Tests data base */
  24906. +typedef struct
  24907. +{
  24908. + short sid;
  24909. + char cryptoAlgorithm; /* DES/3DES/AES */
  24910. + char cryptoMode; /* ECB or CBC */
  24911. + char macAlgorithm; /* MD5 / SHA1 */
  24912. + char operation; /* CRYPTO/HMAC/CRYPTO+HMAC/HMAC+CRYPTO */
  24913. + char direction; /* ENCODE(SIGN)/DECODE(VERIFY) */
  24914. + unsigned char* pCryptoKey;
  24915. + int cryptoKeySize;
  24916. + unsigned char* pMacKey;
  24917. + int macKeySize;
  24918. + const char* name;
  24919. +
  24920. +} MV_CESA_TEST_SESSION;
  24921. +
  24922. +typedef struct
  24923. +{
  24924. + MV_CESA_TEST_SESSION* pSessions;
  24925. + int numSessions;
  24926. +
  24927. +} MV_CESA_TEST_DB_ENTRY;
  24928. +
  24929. +typedef struct
  24930. +{
  24931. + char* plainHexStr;
  24932. + char* cipherHexStr;
  24933. + unsigned char* pCryptoIV;
  24934. + int cryptoLength;
  24935. + int macLength;
  24936. + int digestOffset;
  24937. +
  24938. +} MV_CESA_TEST_CASE;
  24939. +
  24940. +typedef struct
  24941. +{
  24942. + int size;
  24943. + const char* outputHexStr;
  24944. +
  24945. +} MV_CESA_SIZE_TEST;
  24946. +
  24947. +static unsigned char cryptoKey1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
  24948. + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
  24949. + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  24950. +
  24951. +static unsigned char cryptoKey7[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  24952. +static unsigned char iv1[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef};
  24953. +
  24954. +
  24955. +static unsigned char cryptoKey2[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  24956. + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
  24957. +
  24958. +static unsigned char cryptoKey3[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  24959. + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  24960. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
  24961. +
  24962. +static unsigned char cryptoKey4[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  24963. + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  24964. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  24965. + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
  24966. +
  24967. +static unsigned char cryptoKey5[] = {0x56, 0xe4, 0x7a, 0x38, 0xc5, 0x59, 0x89, 0x74,
  24968. + 0xbc, 0x46, 0x90, 0x3d, 0xba, 0x29, 0x03, 0x49};
  24969. +
  24970. +
  24971. +static unsigned char key3des1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
  24972. + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
  24973. + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23};
  24974. +
  24975. +/* Input ASCII string: The quick brown fox jump */
  24976. +static char plain3des1[] = "54686520717566636B2062726F776E20666F78206A756D70";
  24977. +static char cipher3des1[] = "A826FD8CE53B855FCCE21C8112256FE668D5C05DD9B6B900";
  24978. +
  24979. +static unsigned char key3des2[] = {0x62, 0x7f, 0x46, 0x0e, 0x08, 0x10, 0x4a, 0x10,
  24980. + 0x43, 0xcd, 0x26, 0x5d, 0x58, 0x40, 0xea, 0xf1,
  24981. + 0x31, 0x3e, 0xdf, 0x97, 0xdf, 0x2a, 0x8a, 0x8c};
  24982. +
  24983. +static unsigned char iv3des2[] = {0x8e, 0x29, 0xf7, 0x5e, 0xa7, 0x7e, 0x54, 0x75};
  24984. +
  24985. +static char plain3des2[] = "326a494cd33fe756";
  24986. +
  24987. +static char cipher3desCbc2[] = "8e29f75ea77e5475"
  24988. + "b22b8d66de970692";
  24989. +
  24990. +static unsigned char key3des3[] = {0x37, 0xae, 0x5e, 0xbf, 0x46, 0xdf, 0xf2, 0xdc,
  24991. + 0x07, 0x54, 0xb9, 0x4f, 0x31, 0xcb, 0xb3, 0x85,
  24992. + 0x5e, 0x7f, 0xd3, 0x6d, 0xc8, 0x70, 0xbf, 0xae};
  24993. +
  24994. +static unsigned char iv3des3[] = {0x3d, 0x1d, 0xe3, 0xcc, 0x13, 0x2e, 0x3b, 0x65};
  24995. +
  24996. +static char plain3des3[] = "84401f78fe6c10876d8ea23094ea5309";
  24997. +
  24998. +static char cipher3desCbc3[] = "3d1de3cc132e3b65"
  24999. + "7b1f7c7e3b1c948ebd04a75ffba7d2f5";
  25000. +
  25001. +static unsigned char iv5[] = {0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c,
  25002. + 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9};
  25003. +
  25004. +static unsigned char aesCtrKey[] = {0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
  25005. + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC};
  25006. +
  25007. +static unsigned char mdKey1[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  25008. + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
  25009. +
  25010. +static unsigned char mdKey2[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  25011. + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
  25012. +
  25013. +static unsigned char shaKey1[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  25014. + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  25015. + 0x0b, 0x0b, 0x0b, 0x0b};
  25016. +
  25017. +static unsigned char shaKey2[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  25018. + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  25019. + 0xaa, 0xaa, 0xaa, 0xaa};
  25020. +
  25021. +static unsigned char mdKey4[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25022. + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
  25023. +
  25024. +static unsigned char shaKey4[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25025. + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
  25026. + 0x11, 0x12, 0x13, 0x14};
  25027. +
  25028. +
  25029. +static MV_CESA_TEST_SESSION desTestSessions[] =
  25030. +{
  25031. +/*000*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  25032. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25033. + MV_CESA_DIR_ENCODE,
  25034. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  25035. + NULL, 0,
  25036. + "DES ECB encode",
  25037. + },
  25038. +/*001*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  25039. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25040. + MV_CESA_DIR_DECODE,
  25041. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  25042. + NULL, 0,
  25043. + "DES ECB decode",
  25044. + },
  25045. +/*002*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,
  25046. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25047. + MV_CESA_DIR_ENCODE,
  25048. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  25049. + NULL, 0,
  25050. + "DES CBC encode"
  25051. + },
  25052. +/*003*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,
  25053. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25054. + MV_CESA_DIR_DECODE,
  25055. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  25056. + NULL, 0,
  25057. + "DES CBC decode"
  25058. + },
  25059. +/*004*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25060. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25061. + MV_CESA_DIR_ENCODE,
  25062. + NULL, 0, NULL, 0,
  25063. + "NULL Crypto Algorithm encode"
  25064. + },
  25065. +};
  25066. +
  25067. +
  25068. +static MV_CESA_TEST_SESSION tripleDesTestSessions[] =
  25069. +{
  25070. +/*100*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  25071. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25072. + MV_CESA_DIR_ENCODE,
  25073. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25074. + NULL, 0,
  25075. + "3DES ECB encode",
  25076. + },
  25077. +/*101*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  25078. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25079. + MV_CESA_DIR_DECODE,
  25080. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25081. + NULL, 0,
  25082. + "3DES ECB decode",
  25083. + },
  25084. +/*102*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  25085. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25086. + MV_CESA_DIR_ENCODE,
  25087. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25088. + NULL, 0,
  25089. + "3DES CBC encode"
  25090. + },
  25091. +/*103*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  25092. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25093. + MV_CESA_DIR_DECODE,
  25094. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25095. + NULL, 0,
  25096. + "3DES CBC decode"
  25097. + },
  25098. +/*104*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  25099. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25100. + MV_CESA_DIR_ENCODE,
  25101. + key3des1, sizeof(key3des1),
  25102. + NULL, 0,
  25103. + "3DES ECB encode"
  25104. + },
  25105. +/*105*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  25106. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25107. + MV_CESA_DIR_ENCODE,
  25108. + key3des2, sizeof(key3des2),
  25109. + NULL, 0,
  25110. + "3DES ECB encode"
  25111. + },
  25112. +/*106*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  25113. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25114. + MV_CESA_DIR_ENCODE,
  25115. + key3des3, sizeof(key3des3),
  25116. + NULL, 0,
  25117. + "3DES ECB encode"
  25118. + },
  25119. +};
  25120. +
  25121. +
  25122. +static MV_CESA_TEST_SESSION aesTestSessions[] =
  25123. +{
  25124. +/*200*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  25125. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25126. + MV_CESA_DIR_ENCODE,
  25127. + cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),
  25128. + NULL, 0,
  25129. + "AES-128 ECB encode"
  25130. + },
  25131. +/*201*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  25132. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25133. + MV_CESA_DIR_DECODE,
  25134. + cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),
  25135. + NULL, 0,
  25136. + "AES-128 ECB decode"
  25137. + },
  25138. +/*202*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  25139. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25140. + MV_CESA_DIR_ENCODE,
  25141. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  25142. + NULL, 0,
  25143. + "AES-128 CBC encode"
  25144. + },
  25145. +/*203*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  25146. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25147. + MV_CESA_DIR_DECODE,
  25148. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  25149. + NULL, 0,
  25150. + "AES-128 CBC decode"
  25151. + },
  25152. +/*204*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  25153. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25154. + MV_CESA_DIR_ENCODE,
  25155. + cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),
  25156. + NULL, 0,
  25157. + "AES-192 ECB encode"
  25158. + },
  25159. +/*205*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  25160. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25161. + MV_CESA_DIR_DECODE,
  25162. + cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),
  25163. + NULL, 0,
  25164. + "AES-192 ECB decode"
  25165. + },
  25166. +/*206*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  25167. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25168. + MV_CESA_DIR_ENCODE,
  25169. + cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),
  25170. + NULL, 0,
  25171. + "AES-256 ECB encode"
  25172. + },
  25173. +/*207*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  25174. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25175. + MV_CESA_DIR_DECODE,
  25176. + cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),
  25177. + NULL, 0,
  25178. + "AES-256 ECB decode"
  25179. + },
  25180. +/*208*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CTR,
  25181. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25182. + MV_CESA_DIR_ENCODE,
  25183. + aesCtrKey, sizeof(aesCtrKey)/sizeof(aesCtrKey[0]),
  25184. + NULL, 0,
  25185. + "AES-128 CTR encode"
  25186. + },
  25187. +};
  25188. +
  25189. +
  25190. +static MV_CESA_TEST_SESSION md5TestSessions[] =
  25191. +{
  25192. +/*300*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25193. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  25194. + MV_CESA_DIR_ENCODE,
  25195. + NULL, 0,
  25196. + mdKey1, sizeof(mdKey1),
  25197. + "HMAC-MD5 Generate Signature"
  25198. + },
  25199. +/*301*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25200. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  25201. + MV_CESA_DIR_DECODE,
  25202. + NULL, 0,
  25203. + mdKey1, sizeof(mdKey1),
  25204. + "HMAC-MD5 Verify Signature"
  25205. + },
  25206. +/*302*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25207. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  25208. + MV_CESA_DIR_ENCODE,
  25209. + NULL, 0,
  25210. + mdKey2, sizeof(mdKey2),
  25211. + "HMAC-MD5 Generate Signature"
  25212. + },
  25213. +/*303*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25214. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  25215. + MV_CESA_DIR_DECODE,
  25216. + NULL, 0,
  25217. + mdKey2, sizeof(mdKey2),
  25218. + "HMAC-MD5 Verify Signature"
  25219. + },
  25220. +/*304*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25221. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  25222. + MV_CESA_DIR_ENCODE,
  25223. + NULL, 0,
  25224. + mdKey4, sizeof(mdKey4),
  25225. + "HMAC-MD5 Generate Signature"
  25226. + },
  25227. +/*305*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25228. + MV_CESA_MAC_MD5, MV_CESA_MAC_ONLY,
  25229. + MV_CESA_DIR_ENCODE,
  25230. + NULL, 0,
  25231. + NULL, 0,
  25232. + "HASH-MD5 Generate Signature"
  25233. + },
  25234. +};
  25235. +
  25236. +
  25237. +static MV_CESA_TEST_SESSION shaTestSessions[] =
  25238. +{
  25239. +/*400*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25240. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  25241. + MV_CESA_DIR_ENCODE,
  25242. + NULL, 0,
  25243. + shaKey1, sizeof(shaKey1),
  25244. + "HMAC-SHA1 Generate Signature"
  25245. + },
  25246. +/*401*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25247. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  25248. + MV_CESA_DIR_DECODE,
  25249. + NULL, 0,
  25250. + shaKey1, sizeof(shaKey1),
  25251. + "HMAC-SHA1 Verify Signature"
  25252. + },
  25253. +/*402*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25254. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  25255. + MV_CESA_DIR_ENCODE,
  25256. + NULL, 0,
  25257. + shaKey2, sizeof(shaKey2),
  25258. + "HMAC-SHA1 Generate Signature"
  25259. + },
  25260. +/*403*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25261. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  25262. + MV_CESA_DIR_DECODE,
  25263. + NULL, 0,
  25264. + shaKey2, sizeof(shaKey2),
  25265. + "HMAC-SHA1 Verify Signature"
  25266. + },
  25267. +/*404*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25268. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  25269. + MV_CESA_DIR_ENCODE,
  25270. + NULL, 0,
  25271. + shaKey4, sizeof(shaKey4),
  25272. + "HMAC-SHA1 Generate Signature"
  25273. + },
  25274. +/*405*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25275. + MV_CESA_MAC_SHA1, MV_CESA_MAC_ONLY,
  25276. + MV_CESA_DIR_ENCODE,
  25277. + NULL, 0,
  25278. + NULL, 0,
  25279. + "HASH-SHA1 Generate Signature"
  25280. + },
  25281. +};
  25282. +
  25283. +static MV_CESA_TEST_SESSION combinedTestSessions[] =
  25284. +{
  25285. +/*500*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  25286. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  25287. + MV_CESA_DIR_ENCODE,
  25288. + cryptoKey1, MV_CESA_DES_KEY_LENGTH,
  25289. + mdKey4, sizeof(mdKey4),
  25290. + "DES + MD5 encode"
  25291. + },
  25292. +/*501*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  25293. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  25294. + MV_CESA_DIR_ENCODE,
  25295. + cryptoKey1, MV_CESA_DES_KEY_LENGTH,
  25296. + shaKey4, sizeof(shaKey4),
  25297. + "DES + SHA1 encode"
  25298. + },
  25299. +/*502*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  25300. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  25301. + MV_CESA_DIR_ENCODE,
  25302. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25303. + mdKey4, sizeof(mdKey4),
  25304. + "3DES + MD5 encode"
  25305. + },
  25306. +/*503*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  25307. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  25308. + MV_CESA_DIR_ENCODE,
  25309. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25310. + shaKey4, sizeof(shaKey4),
  25311. + "3DES + SHA1 encode"
  25312. + },
  25313. +/*504*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  25314. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  25315. + MV_CESA_DIR_ENCODE,
  25316. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25317. + mdKey4, sizeof(mdKey4),
  25318. + "3DES CBC + MD5 encode"
  25319. + },
  25320. +/*505*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  25321. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  25322. + MV_CESA_DIR_ENCODE,
  25323. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25324. + shaKey4, sizeof(shaKey4),
  25325. + "3DES CBC + SHA1 encode"
  25326. + },
  25327. +/*506*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  25328. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  25329. + MV_CESA_DIR_ENCODE,
  25330. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  25331. + mdKey4, sizeof(mdKey4),
  25332. + "AES-128 CBC + MD5 encode"
  25333. + },
  25334. +/*507*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  25335. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  25336. + MV_CESA_DIR_ENCODE,
  25337. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  25338. + shaKey4, sizeof(shaKey4),
  25339. + "AES-128 CBC + SHA1 encode"
  25340. + },
  25341. +/*508*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  25342. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_THEN_CRYPTO,
  25343. + MV_CESA_DIR_DECODE,
  25344. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25345. + mdKey4, sizeof(mdKey4),
  25346. + "HMAC-MD5 + 3DES decode"
  25347. + },
  25348. +};
  25349. +
  25350. +
  25351. +static MV_CESA_TEST_DB_ENTRY cesaTestsDB[MAX_TEST_TYPE+1] =
  25352. +{
  25353. + { desTestSessions, sizeof(desTestSessions)/sizeof(desTestSessions[0]) },
  25354. + { tripleDesTestSessions, sizeof(tripleDesTestSessions)/sizeof(tripleDesTestSessions[0]) },
  25355. + { aesTestSessions, sizeof(aesTestSessions)/sizeof(aesTestSessions[0]) },
  25356. + { md5TestSessions, sizeof(md5TestSessions)/sizeof(md5TestSessions[0]) },
  25357. + { shaTestSessions, sizeof(shaTestSessions)/sizeof(shaTestSessions[0]) },
  25358. + { combinedTestSessions, sizeof(combinedTestSessions)/sizeof(combinedTestSessions[0]) },
  25359. + { NULL, 0 }
  25360. +};
  25361. +
  25362. +
  25363. +char cesaNullPlainHexText[] = "000000000000000000000000000000000000000000000000";
  25364. +
  25365. +char cesaPlainAsciiText[] = "Now is the time for all ";
  25366. +char cesaPlainHexEbc[] = "4e6f77206973207468652074696d6520666f7220616c6c20";
  25367. +char cesaCipherHexEcb[] = "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53";
  25368. +char cesaPlainHexCbc[] = "1234567890abcdef4e6f77206973207468652074696d6520666f7220616c6c20";
  25369. +char cesaCipherHexCbc[] = "1234567890abcdefe5c7cdde872bf27c43e934008c389c0f683788499a7c05f6";
  25370. +
  25371. +char cesaAesPlainHexEcb[] = "000102030405060708090a0b0c0d0e0f";
  25372. +char cesaAes128cipherHexEcb[] = "0a940bb5416ef045f1c39458c653ea5a";
  25373. +char cesaAes192cipherHexEcb[] = "0060bffe46834bb8da5cf9a61ff220ae";
  25374. +char cesaAes256cipherHexEcb[] = "5a6e045708fb7196f02e553d02c3a692";
  25375. +
  25376. +char cesaAsciiStr1[] = "Hi There";
  25377. +char cesaDataHexStr1[] = "4869205468657265";
  25378. +char cesaHmacMd5digestHex1[] = "9294727a3638bb1c13f48ef8158bfc9d";
  25379. +char cesaHmacSha1digestHex1[] = "b617318655057264e28bc0b6fb378c8ef146be00";
  25380. +char cesaDataAndMd5digest1[] = "48692054686572659294727a3638bb1c13f48ef8158bfc9d";
  25381. +char cesaDataAndSha1digest1[] = "4869205468657265b617318655057264e28bc0b6fb378c8ef146be00";
  25382. +
  25383. +char cesaAesPlainText[] = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
  25384. + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
  25385. + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
  25386. + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
  25387. +
  25388. +char cesaAes128CipherCbc[] = "c30e32ffedc0774e6aff6af0869f71aa"
  25389. + "0f3af07a9a31a9c684db207eb0ef8e4e"
  25390. + "35907aa632c3ffdf868bb7b29d3d46ad"
  25391. + "83ce9f9a102ee99d49a53e87f4c3da55";
  25392. +
  25393. +char cesaAesIvPlainText[] = "8ce82eefbea0da3c44699ed7db51b7d9"
  25394. + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
  25395. + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
  25396. + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
  25397. + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
  25398. +
  25399. +char cesaAes128IvCipherCbc[] = "8ce82eefbea0da3c44699ed7db51b7d9"
  25400. + "c30e32ffedc0774e6aff6af0869f71aa"
  25401. + "0f3af07a9a31a9c684db207eb0ef8e4e"
  25402. + "35907aa632c3ffdf868bb7b29d3d46ad"
  25403. + "83ce9f9a102ee99d49a53e87f4c3da55";
  25404. +
  25405. +char cesaAesCtrPlain[] = "00E0017B27777F3F4A1786F000000001"
  25406. + "000102030405060708090A0B0C0D0E0F"
  25407. + "101112131415161718191A1B1C1D1E1F"
  25408. + "20212223";
  25409. +
  25410. +char cesaAesCtrCipher[] = "00E0017B27777F3F4A1786F000000001"
  25411. + "C1CF48A89F2FFDD9CF4652E9EFDB72D7"
  25412. + "4540A42BDE6D7836D59A5CEAAEF31053"
  25413. + "25B2072F";
  25414. +
  25415. +
  25416. +
  25417. +/* Input cesaHmacHex3 is '0xdd' repeated 50 times */
  25418. +char cesaHmacMd5digestHex3[] = "56be34521d144c88dbb8c733f0e8b3f6";
  25419. +char cesaHmacSha1digestHex3[] = "125d7342b9ac11cd91a39af48aa17b4f63f175d3";
  25420. +char cesaDataHexStr3[50*2+1] = "";
  25421. +char cesaDataAndMd5digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacMd5digestHex3)+8*2+1] = "";
  25422. +char cesaDataAndSha1digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacSha1digestHex3)+8*2+1] = "";
  25423. +
  25424. +/* Ascii string is "abc" */
  25425. +char hashHexStr3[] = "616263";
  25426. +char hashMd5digest3[] = "900150983cd24fb0d6963f7d28e17f72";
  25427. +char hashSha1digest3[] = "a9993e364706816aba3e25717850c26c9cd0d89d";
  25428. +
  25429. +char hashHexStr80[] = "31323334353637383930"
  25430. + "31323334353637383930"
  25431. + "31323334353637383930"
  25432. + "31323334353637383930"
  25433. + "31323334353637383930"
  25434. + "31323334353637383930"
  25435. + "31323334353637383930"
  25436. + "31323334353637383930";
  25437. +
  25438. +char hashMd5digest80[] = "57edf4a22be3c955ac49da2e2107b67a";
  25439. +
  25440. +char tripleDesThenMd5digest80[] = "b7726a03aad490bd6c5a452a89a1b271";
  25441. +char tripleDesThenSha1digest80[] = "b2ddeaca91030eab5b95a234ef2c0f6e738ff883";
  25442. +
  25443. +char cbc3desThenMd5digest80[] = "6f463057e1a90e0e91ae505b527bcec0";
  25444. +char cbc3desThenSha1digest80[] = "1b002ed050be743aa98860cf35659646bb8efcc0";
  25445. +
  25446. +char cbcAes128ThenMd5digest80[] = "6b6e863ac5a71d15e3e9b1c86c9ba05f";
  25447. +char cbcAes128ThenSha1digest80[] = "13558472d1fc1c90dffec6e5136c7203452d509b";
  25448. +
  25449. +
  25450. +static MV_CESA_TEST_CASE cesaTestCases[] =
  25451. +{
  25452. + /* plainHexStr cipherHexStr IV crypto mac digest */
  25453. + /* Length Length Offset */
  25454. + /*0*/ { NULL, NULL, NULL, 0, 0, -1 },
  25455. + /*1*/ { cesaPlainHexEbc, cesaCipherHexEcb, NULL, 24, 0, -1 },
  25456. + /*2*/ { cesaPlainHexCbc, cesaCipherHexCbc, NULL, 24, 0, -1 },
  25457. + /*3*/ { cesaAesPlainHexEcb, cesaAes128cipherHexEcb, NULL, 16, 0, -1 },
  25458. + /*4*/ { cesaAesPlainHexEcb, cesaAes192cipherHexEcb, NULL, 16, 0, -1 },
  25459. + /*5*/ { cesaAesPlainHexEcb, cesaAes256cipherHexEcb, NULL, 16, 0, -1 },
  25460. + /*6*/ { cesaDataHexStr1, cesaHmacMd5digestHex1, NULL, 0, 8, -1 },
  25461. + /*7*/ { NULL, cesaDataAndMd5digest1, NULL, 0, 8, -1 },
  25462. + /*8*/ { cesaDataHexStr3, cesaHmacMd5digestHex3, NULL, 0, 50, -1 },
  25463. + /*9*/ { NULL, cesaDataAndMd5digest3, NULL, 0, 50, -1 },
  25464. +/*10*/ { cesaAesPlainText, cesaAes128IvCipherCbc, iv5, 64, 0, -1 },
  25465. +/*11*/ { cesaDataHexStr1, cesaHmacSha1digestHex1, NULL, 0, 8, -1 },
  25466. +/*12*/ { NULL, cesaDataAndSha1digest1, NULL, 0, 8, -1 },
  25467. +/*13*/ { cesaDataHexStr3, cesaHmacSha1digestHex3, NULL, 0, 50, -1 },
  25468. +/*14*/ { NULL, cesaDataAndSha1digest3, NULL, 0, 50, -1 },
  25469. +/*15*/ { hashHexStr3, hashMd5digest3, NULL, 0, 3, -1 },
  25470. +/*16*/ { hashHexStr3, hashSha1digest3, NULL, 0, 3, -1 },
  25471. +/*17*/ { hashHexStr80, tripleDesThenMd5digest80, NULL, 80, 80, -1 },
  25472. +/*18*/ { hashHexStr80, tripleDesThenSha1digest80, NULL, 80, 80, -1 },
  25473. +/*19*/ { hashHexStr80, cbc3desThenMd5digest80, iv1, 80, 80, -1 },
  25474. +/*20*/ { hashHexStr80, cbc3desThenSha1digest80, iv1, 80, 80, -1 },
  25475. +/*21*/ { hashHexStr80, cbcAes128ThenMd5digest80, iv5, 80, 80, -1 },
  25476. +/*22*/ { hashHexStr80, cbcAes128ThenSha1digest80, iv5, 80, 80, -1 },
  25477. +/*23*/ { cesaAesCtrPlain, cesaAesCtrCipher, NULL, 36, 0, -1 },
  25478. +/*24*/ { cesaAesIvPlainText, cesaAes128IvCipherCbc, NULL, 64, 0, -1 },
  25479. +/*25*/ { plain3des1, cipher3des1, NULL, 0, 0, -1 },
  25480. +/*26*/ { plain3des2, cipher3desCbc2, iv3des2,0, 0, -1 },
  25481. +/*27*/ { plain3des3, cipher3desCbc3, iv3des3,0, 0, -1 },
  25482. +};
  25483. +
  25484. +
  25485. +/* Key = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  25486. + * 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
  25487. + * Input 0xdd repeated "size" times
  25488. + */
  25489. +static MV_CESA_SIZE_TEST mdMultiSizeTest302[] =
  25490. +{
  25491. + { 80, "7a031a640c14a4872814930b1ef3a5b2" },
  25492. + { 512, "5488e6c5a14dc72a79f28312ca5b939b" },
  25493. + { 1000, "d00814f586a8b78a05724239d2531821" },
  25494. + { 1001, "bf07df7b7f49d3f5b5ecacd4e9e63281" },
  25495. + { 1002, "1ed4a1a802e87817a819d4e37bb4d0f7" },
  25496. + { 1003, "5972ab64a4f265ee371dac2f2f137f90" },
  25497. + { 1004, "71f95e7ec3aa7df2548e90898abdb28e" },
  25498. + { 1005, "e082790b4857fcfc266e92e59e608814" },
  25499. + { 1006, "9500f02fd8ac7fde8b10e4fece9a920d" },
  25500. + { 1336, "e42edcce57d0b75b01aa09d71427948b" },
  25501. + { 1344, "bb5454ada0deb49ba0a97ffd60f57071" },
  25502. + { 1399, "0f44d793e744b24d53f44f295082ee8c" },
  25503. + { 1400, "359de8a03a9b707928c6c60e0e8d79f1" },
  25504. + { 1401, "e913858b484cbe2b384099ea88d8855b" },
  25505. + { 1402, "d9848a164af53620e0540c1d7d87629e" },
  25506. + { 1403, "0c9ee1c2c9ef45e9b625c26cbaf3e822" },
  25507. + { 1404, "12edd4f609416e3c936170360561b064" },
  25508. + { 1405, "7fc912718a05446395345009132bf562" },
  25509. + { 1406, "882f17425e579ff0d85a91a59f308aa0" },
  25510. + { 1407, "005cae408630a2fb5db82ad9db7e59da" },
  25511. + { 1408, "64655f8b404b3fea7a3e3e609bc5088f" },
  25512. + { 1409, "4a145284a7f74e01b6bb1a0ec6a0dd80" },
  25513. + { 2048, "67caf64475650732def374ebb8bde3fd" },
  25514. + { 2049, "6c84f11f472825f7e6cd125c2981884b" },
  25515. + { 2050, "8999586754a73a99efbe4dbad2816d41" },
  25516. + { 2051, "ba6946b610e098d286bc81091659dfff" },
  25517. + { 2052, "d0afa01c92d4d13def2b024f36faed83" },
  25518. + { 3072, "61d8beac61806afa2585d74a9a0e6974" },
  25519. + { 3074, "f6501a28dcc24d1e4770505c51a87ed3" },
  25520. + { 3075, "ea4a6929be67e33e61ff475369248b73" },
  25521. + { 4048, "aa8c4d68f282a07e7385acdfa69f4bed" },
  25522. + { 4052, "afb5ed2c0e1d430ea59e59ed5ed6b18a" },
  25523. + { 4058, "9e8553f9bdd43aebe0bd729f0e600c99" },
  25524. + { 6144, "f628f3e5d183fe5cdd3a5abee39cf872" },
  25525. + { 6150, "89a3efcea9a2f25f919168ad4a1fd292" },
  25526. + { 6400, "cdd176b7fb747873efa4da5e32bdf88f" },
  25527. + { 6528, "b1d707b027354aca152c45ee559ccd3f" },
  25528. + { 8192, "c600ea4429ac47f9941f09182166e51a" },
  25529. + {16384, "16e8754bfbeb4c649218422792267a37" },
  25530. + {18432, "0fd0607521b0aa8b52219cfbe215f63e" },
  25531. + { 0, NULL },
  25532. +};
  25533. +
  25534. +/* Key = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25535. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  25536. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25537. + */
  25538. +static MV_CESA_SIZE_TEST mdMultiSizeTest304[] =
  25539. +{
  25540. + { 80, "a456c4723fee6068530af5a2afa71627" },
  25541. + { 512, "f85c2a2344f5de68b432208ad13e5794" },
  25542. + { 1000, "35464d6821fd4a293a41eb84e274c8c5" },
  25543. + { 1001, "c08eedbdce60cceb54bc2d732bb32c8b" },
  25544. + { 1002, "5664f71800c011cc311cb6943339c1b8" },
  25545. + { 1003, "779c723b044c585dc7802b13e8501bdc" },
  25546. + { 1004, "55e500766a2c307bc5c5fdd15e4cacd4" },
  25547. + { 1005, "d5f978954f5c38529d1679d2b714f068" },
  25548. + { 1006, "cd3efc827ce628b7281b72172693abf9" },
  25549. + { 1336, "6f04479910785878ae6335b8d1e87edf" },
  25550. + { 1344, "b6d27b50c2bce1ba2a8e1b5cc4324368" },
  25551. + { 1399, "65f70a1d4c86e5eaeb0704c8a7816795" },
  25552. + { 1400, "3394b5adc4cb3ff98843ca260a44a88a" },
  25553. + { 1401, "3a06f3582033a66a4e57e0603ce94e74" },
  25554. + { 1402, "e4d97f5ed51edc48abfa46eeb5c31752" },
  25555. + { 1403, "3d05e40b080ee3bedf293cb87b7140e7" },
  25556. + { 1404, "8cf294fc3cd153ab18dccb2a52cbf244" },
  25557. + { 1405, "d1487bd42f6edd9b4dab316631159221" },
  25558. + { 1406, "0527123b6bf6936cf5d369dc18c6c70f" },
  25559. + { 1407, "3224a06639db70212a0cd1ae1fcc570a" },
  25560. + { 1408, "a9e13335612c0356f5e2c27086e86c43" },
  25561. + { 1409, "a86d1f37d1ed8a3552e9a4f04dceea98" },
  25562. + { 2048, "396905c9b961cd0f6152abfb69c4449c" },
  25563. + { 2049, "49f39bff85d9dcf059fadb89efc4a70f" },
  25564. + { 2050, "3a2b4823bc4d0415656550226a63e34a" },
  25565. + { 2051, "dec60580d406c782540f398ad0bcc7e0" },
  25566. + { 2052, "32f76610a14310309eb748fe025081bf" },
  25567. + { 3072, "45edc1a42bf9d708a621076b63b774da" },
  25568. + { 3074, "9be1b333fe7c0c9f835fb369dc45f778" },
  25569. + { 3075, "8c06fcac7bd0e7b7a17fd6508c09a549" },
  25570. + { 4048, "0ddaef848184bf0ad98507a10f1e90e4" },
  25571. + { 4052, "81976bcaeb274223983996c137875cb8" },
  25572. + { 4058, "0b0a7a1c82bc7cbc64d8b7cd2dc2bb22" },
  25573. + { 6144, "1c24056f52725ede2dff0d7f9fc9855f" },
  25574. + { 6150, "b7f4b65681c4e43ee68ca466ca9ca4ec" },
  25575. + { 6400, "443bbaab9f7331ddd4bf11b659cd43c8" },
  25576. + { 6528, "216f44f23047cfee03a7a64f88f9a995" },
  25577. + { 8192, "ac7a993b2cad54879dba1bde63e39097" },
  25578. + { 8320, "55ed7be9682d6c0025b3221a62088d08" },
  25579. + {16384, "c6c722087653b62007aea668277175e5" },
  25580. + {18432, "f1faca8e907872c809e14ffbd85792d6" },
  25581. + { 0, NULL },
  25582. +};
  25583. +
  25584. +/* HASH-MD5
  25585. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25586. + * repeated "size" times
  25587. + */
  25588. +static MV_CESA_SIZE_TEST mdMultiSizeTest305[] =
  25589. +{
  25590. + { 80, "57edf4a22be3c955ac49da2e2107b67a" },
  25591. + { 512, "c729ae8f0736cc377a9767a660eaa04e" },
  25592. + { 1000, "f1257a8659eb92d36fe14c6bf3852a6a" },
  25593. + { 1001, "f8a46fe8ea04fdc8c7de0e84042d3878" },
  25594. + { 1002, "da188dd67bff87d58aa3c02af2d0cc0f" },
  25595. + { 1003, "961753017feee04c9b93a8e51658a829" },
  25596. + { 1004, "dd68c4338608dcc87807a711636bf2af" },
  25597. + { 1005, "e338d567d3ce66bf69ada29658a8759b" },
  25598. + { 1006, "443c9811e8b92599b0b149e8d7ec700a" },
  25599. + { 1336, "89a98511706008ba4cbd0b4a24fa5646" },
  25600. + { 1344, "335a919805f370b9e402a62c6fe01739" },
  25601. + { 1399, "5d18d0eddcd84212fe28d812b5e80e3b" },
  25602. + { 1400, "6b695c240d2dffd0dffc99459ca76db6" },
  25603. + { 1401, "49590f61298a76719bc93a57a30136f5" },
  25604. + { 1402, "94c2999fa3ef1910a683d69b2b8476f2" },
  25605. + { 1403, "37073a02ab00ecba2645c57c228860db" },
  25606. + { 1404, "1bcd06994fce28b624f0c5fdc2dcdd2b" },
  25607. + { 1405, "11b93671a64c95079e8cf9e7cddc8b3d" },
  25608. + { 1406, "4b6695772a4c66313fa4871017d05f36" },
  25609. + { 1407, "d1539b97fbfda1c075624e958de19c5b" },
  25610. + { 1408, "b801b9b69920907cd018e8063092ede9" },
  25611. + { 1409, "b765f1406cfe78e238273ed01bbcaf7e" },
  25612. + { 2048, "1d7e2c64ac29e2b3fb4c272844ed31f5" },
  25613. + { 2049, "71d38fac49c6b1f4478d8d88447bcdd0" },
  25614. + { 2050, "141c34a5592b1bebfa731e0b23d0cdba" },
  25615. + { 2051, "c5e1853f21c59f5d6039bd13d4b380d8" },
  25616. + { 2052, "dd44a0d128b63d4b5cccd967906472d7" },
  25617. + { 3072, "37d158e33b21390822739d13db7b87fe" },
  25618. + { 3074, "aef3b209d01d39d0597fe03634bbf441" },
  25619. + { 3075, "335ffb428eabf210bada96d74d5a4012" },
  25620. + { 4048, "2434c2b43d798d2819487a886261fc64" },
  25621. + { 4052, "ac2fa84a8a33065b2e92e36432e861f8" },
  25622. + { 4058, "856781f85616c341c3533d090c1e1e84" },
  25623. + { 6144, "e5d134c652c18bf19833e115f7a82e9b" },
  25624. + { 6150, "a09a353be7795fac2401dac5601872e6" },
  25625. + { 6400, "08b9033ac6a1821398f50af75a2dbc83" },
  25626. + { 6528, "3d47aa193a8540c091e7e02f779e6751" },
  25627. + { 8192, "d3164e710c0626f6f395b38f20141cb7" },
  25628. + { 8320, "b727589d9183ff4e8491dd24466974a3" },
  25629. + {16384, "3f54d970793d2274d5b20d10a69938ac" },
  25630. + {18432, "f558511dcf81985b7a1bb57fad970531" },
  25631. + { 0, NULL },
  25632. +};
  25633. +
  25634. +
  25635. +/* Key = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  25636. + * 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
  25637. + * 0xaa, 0xaa, 0xaa, 0xaa
  25638. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25639. + */
  25640. +static MV_CESA_SIZE_TEST shaMultiSizeTest402[] =
  25641. +{
  25642. + { 80, "e812f370e659705a1649940d1f78cd7af18affd3" },
  25643. + { 512, "e547f886b2c15d995ed76a8a924cb408c8080f66" },
  25644. + { 1000, "239443194409f1a5342ecde1a092c8f3a3ed790a" },
  25645. + { 1001, "f278ab9a102850a9f48dc4e9e6822afe2d0c52b5" },
  25646. + { 1002, "8bcc667df5ab6ece988b3af361d09747c77f4e72" },
  25647. + { 1003, "0fae6046c7dc1d3e356b25af836f6077a363f338" },
  25648. + { 1004, "0ea48401cc92ae6bc92ae76685269cb0167fbe1a" },
  25649. + { 1005, "ecbcd7c879b295bafcd8766cbeac58cc371e31d1" },
  25650. + { 1006, "eb4a4a3d07d1e9a15e6f1ab8a9c47f243e27324c" },
  25651. + { 1336, "f5950ee1d77c10e9011d2149699c9366fe52529c" },
  25652. + { 1344, "b04263604a63c351b0b3b9cf1785b4bdba6c8838" },
  25653. + { 1399, "8cb1cff61d5b784045974a2fc69386e3b8d24218" },
  25654. + { 1400, "9bb2f3fcbeddb2b90f0be797cd647334a2816d51" },
  25655. + { 1401, "23ae462a7a0cb440f7445791079a5d75a535dd33" },
  25656. + { 1402, "832974b524a4d3f9cc2f45a3cabf5ccef65cd2aa" },
  25657. + { 1403, "d1c683742fe404c3c20d5704a5430e7832a7ec95" },
  25658. + { 1404, "867c79042e64f310628e219d8b85594cd0c7adc3" },
  25659. + { 1405, "c9d81d49d13d94358f56ccfd61af02b36c69f7c3" },
  25660. + { 1406, "0df43daab2786172f9b8d07d61f14a070cf1287a" },
  25661. + { 1407, "0fd8f3ad7f169534b274d4c66bbddd89f759e391" },
  25662. + { 1408, "3987511182b18473a564436003139b808fa46343" },
  25663. + { 1409, "ef667e063c9e9f539a8987a8d0bd3066ee85d901" },
  25664. + { 2048, "921109c99f3fedaca21727156d5f2b4460175327" },
  25665. + { 2049, "47188600dd165eb45f27c27196d3c46f4f042c1b" },
  25666. + { 2050, "8831939904009338de10e7fa670847041387807d" },
  25667. + { 2051, "2f8ebb5db2997d614e767be1050366f3641e7520" },
  25668. + { 2052, "669e51cd730dae158d3bef8adba075bd95a0d011" },
  25669. + { 3072, "cfee66cfd83abc8451af3c96c6b35a41cc6c55f5" },
  25670. + { 3074, "216ea26f02976a261b7d21a4dd3085157bedfabd" },
  25671. + { 3075, "bd612ebba021fd8e012b14c3bd60c8c5161fabc0" },
  25672. + { 4048, "c2564c1fdf2d5e9d7dde7aace2643428e90662e8" },
  25673. + { 4052, "91ce61fe924b445dfe7b5a1dcd10a27caec16df6" },
  25674. + { 4058, "db2a9be5ee8124f091c7ebd699266c5de223c164" },
  25675. + { 6144, "855109903feae2ba3a7a05a326b8a171116eb368" },
  25676. + { 6150, "37520bb3a668294d9c7b073e7e3daf8fee248a78" },
  25677. + { 6400, "60a353c841b6d2b1a05890349dad2fa33c7536b7" },
  25678. + { 6528, "9e53a43a69bb42d7c8522ca8bd632e421d5edb36" },
  25679. + { 8192, "a918cb0da862eaea0a33ee0efea50243e6b4927c" },
  25680. + { 8320, "29a5dcf55d1db29cd113fcf0572ae414f1c71329" },
  25681. + {16384, "6fb27966138e0c8d5a0d65ace817ebd53633cee1" },
  25682. + {18432, "ca09900d891c7c9ae2a559b10f63a217003341c1" },
  25683. + { 0, NULL },
  25684. +};
  25685. +
  25686. +/* Key = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25687. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  25688. + * 0x11, 0x12, 0x13, 0x14
  25689. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25690. + */
  25691. +static MV_CESA_SIZE_TEST shaMultiSizeTest404[] =
  25692. +{
  25693. + { 80, "beaf20a34b06a87558d156c0949bc3957d40222e" },
  25694. + { 512, "3353955358d886bc2940a3c7f337ff7dafb59c7b" },
  25695. + { 1000, "8737a542c5e9b2b6244b757ebb69d5bd602a829f" },
  25696. + { 1001, "fd9e7582d8a5d3c9fe3b923e4e6a41b07a1eb4d4" },
  25697. + { 1002, "a146d14a6fc3c274ff600568f4d75b977989e00d" },
  25698. + { 1003, "be22601bbc027ddef2dec97d30b3dc424fd803c5" },
  25699. + { 1004, "3e71fe99b2fe2b7bfdf4dbf0c7f3da25d7ea35e7" },
  25700. + { 1005, "2c422735d7295408fddd76f5e8a83a2a8da13df3" },
  25701. + { 1006, "6d875319049314b61855101a647b9ba3313428e6" },
  25702. + { 1336, "c1631ea80bad9dc43a180712461b65a0598c711c" },
  25703. + { 1344, "816069bf91d34581005746e2e0283d0f9c7b7605" },
  25704. + { 1399, "4e139866dc61cfcb8b67ca2ebd637b3a538593af" },
  25705. + { 1400, "ff2a0f8dd2b02c5417910f6f55d33a78e081a723" },
  25706. + { 1401, "ab00c12be62336964cbce31ae97fe2a0002984d5" },
  25707. + { 1402, "61349e7f999f3a1acc56c3e9a5060a9c4a7b05b6" },
  25708. + { 1403, "3edbc0f61e435bc1317fa27d840076093fb79353" },
  25709. + { 1404, "d052c6dfdbe63d45dab23ef9893e2aa4636aca1e" },
  25710. + { 1405, "0cc16b7388d67bf0add15a31e6e6c753cfae4987" },
  25711. + { 1406, "c96ba7eaad74253c38c22101b558d2850b1d1b90" },
  25712. + { 1407, "3445428a40d2c6556e7c55797ad8d323b61a48d9" },
  25713. + { 1408, "8d6444f937a09317c89834187b8ea9b8d3a8c56b" },
  25714. + { 1409, "c700acd3ecd19014ea2bdb4d42510c467e088475" },
  25715. + { 2048, "ee27d2a0cb77470c2f496212dfd68b5bb7b04e4b" },
  25716. + { 2049, "683762d7a02983b26a6d046e6451d9cd82c25932" },
  25717. + { 2050, "0fd20f1d55a9ee18363c2a6fd54aa13aee69992f" },
  25718. + { 2051, "86c267d8cc4bc8d59090e4f8b303da960fd228b7" },
  25719. + { 2052, "452395ae05b3ec503eea34f86fc0832485ad97c1" },
  25720. + { 3072, "75198e3cfd0b9bcff2dabdf8e38e6fdaa33ca49a" },
  25721. + { 3074, "4e24785ef080141ce4aab4675986d9acea624d7c" },
  25722. + { 3075, "3a20c5978dd637ec0e809bf84f0d9ccf30bc65bf" },
  25723. + { 4048, "3c32da256be7a7554922bf5fed51b0d2d09e59ad" },
  25724. + { 4052, "fff898426ea16e54325ae391a32c6c9bce4c23c0" },
  25725. + { 4058, "c800b9e562e1c91e1310116341a3c91d37f848ec" },
  25726. + { 6144, "d91d509d0cc4376c2d05bf9a5097717a373530e6" },
  25727. + { 6150, "d957030e0f13c5df07d9eec298542d8f94a07f12" },
  25728. + { 6400, "bb745313c3d7dc17b3f955e5534ad500a1082613" },
  25729. + { 6528, "77905f80d9ca82080bbb3e5654896dabfcfd1bdb" },
  25730. + { 8192, "5237fd9a81830c974396f99f32047586612ff3c0" },
  25731. + { 8320, "57668e28d5f2dba0839518a11db0f6af3d7e08bf" },
  25732. + {16384, "62e093fde467f0748087beea32e9af97d5c61241" },
  25733. + {18432, "845fb33130c7d6ea554fd5aacb9c50cf7ccb5929" },
  25734. + { 0, NULL },
  25735. +};
  25736. +
  25737. +/* HASH-SHA1
  25738. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25739. + * repeated "size" times
  25740. + */
  25741. +static MV_CESA_SIZE_TEST shaMultiSizeTest405[] =
  25742. +{
  25743. + { 80, "50abf5706a150990a08b2c5ea40fa0e585554732" },
  25744. + { 512, "f14516a08948fa27917a974d219741a697ba0087" },
  25745. + { 1000, "0bd18c378d5788817eb4f1e5dc07d867efa5cbf4" },
  25746. + { 1001, "ca29b85c35db1b8aef83c977893a11159d1b7aa2" },
  25747. + { 1002, "d83bc973eaaedb8a31437994dabbb3304b0be086" },
  25748. + { 1003, "2cf7bbef0acd6c00536b5c58ca470df9a3a90b6c" },
  25749. + { 1004, "e4375d09b1223385a8a393066f8209acfd936a80" },
  25750. + { 1005, "1029b38043e027745d019ce1d2d68e3d8b9d8f99" },
  25751. + { 1006, "deea16dcebbd8ac137e2b984deb639b9fb5e9680" },
  25752. + { 1336, "ea031b065fff63dcfb6a41956e4777520cdbc55d" },
  25753. + { 1344, "b52096c6445e6c0a8355995c70dc36ae186c863c" },
  25754. + { 1399, "cde2f6f8379870db4b32cf17471dc828a8dbff2b" },
  25755. + { 1400, "e53ff664064bc09fe5054c650806bd42d8179518" },
  25756. + { 1401, "d1156db5ddafcace64cdb510ff0d4af9b9a8ad64" },
  25757. + { 1402, "34ede0e9a909dd84a2ae291539105c0507b958e1" },
  25758. + { 1403, "a772ca3536da77e6ad3251e4f9e1234a4d7b87c0" },
  25759. + { 1404, "29740fd2b04e7a8bfd32242db6233156ad699948" },
  25760. + { 1405, "65b17397495b70ce4865dad93bf991b74c97cce1" },
  25761. + { 1406, "a7ee89cd0754061fdb91af7ea6abad2c69d542e3" },
  25762. + { 1407, "3eebf82f7420188e23d328b7ce93580b279a5715" },
  25763. + { 1408, "e08d3363a8b9a490dfb3a4c453452b8f114deeec" },
  25764. + { 1409, "95d74df739181a4ff30b8c39e28793a36598e924" },
  25765. + { 2048, "aa40262509c2abf84aab0197f83187fc90056d91" },
  25766. + { 2049, "7dec28ef105bc313bade8d9a7cdeac58b99de5ea" },
  25767. + { 2050, "d2e30f77ec81197de20f56588a156094ecb88450" },
  25768. + { 2051, "6b22ccc874833e96551a39da0c0edcaa0d969d92" },
  25769. + { 2052, "f843141e57875cd669af58744bc60aa9ea59549c" },
  25770. + { 3072, "09c5fedeaa62c132e673cc3c608a00142273d086" },
  25771. + { 3074, "b09e95eea9c7b1b007a58accec488301901a7f3d" },
  25772. + { 3075, "e6226b77b4ada287a8c9bbcf4ed71eec5ce632dc" },
  25773. + { 4048, "e99394894f855821951ddddf5bfc628547435f5c" },
  25774. + { 4052, "32d2f1af38be9cfba6cd03d55a254d0b3e1eb382" },
  25775. + { 4058, "d906552a4f2aca3a22e1fecccbcd183d7289d0ef" },
  25776. + { 6144, "2e7f62d35a860988e1224dc0543204af19316041" },
  25777. + { 6150, "d6b89698ee133df46fec9d552fadc328aa5a1b51" },
  25778. + { 6400, "dff50e90c46853988fa3a4b4ce5dda6945aae976" },
  25779. + { 6528, "9e63ec0430b96db02d38bc78357a2f63de2ab7f8" },
  25780. + { 8192, "971eb71ed60394d5ab5abb12e88420bdd41b5992" },
  25781. + { 8320, "91606a31b46afeaac965cecf87297e791b211013" },
  25782. + {16384, "547f830a5ec1f5f170ce818f156b1002cabc7569" },
  25783. + {18432, "f16f272787f3b8d539652e4dc315af6ab4fda0ef" },
  25784. + { 0, NULL },
  25785. +};
  25786. +
  25787. +/* CryptoKey = 0x01234567, 0x89abcdef,
  25788. + * 0x01234567, 0x89abcdef,
  25789. + * 0x01234567, 0x89abcdef;
  25790. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25791. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  25792. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25793. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  25794. + */
  25795. +static MV_CESA_SIZE_TEST tripleDesMdMultiSizeTest502[] =
  25796. +{
  25797. + { 64, "9586962a2aaaef28803dec2e17807a7f" },
  25798. + { 80, "b7726a03aad490bd6c5a452a89a1b271" },
  25799. + { 352, "f1ed9563aecc3c0d2766eb2bed3b4e4c" },
  25800. + { 512, "0f9decb11ab40fe86f4d4d9397bc020e" },
  25801. + { 1000, "3ba69deac12cab8ff9dff7dbd9669927" },
  25802. + { 1336, "6cf47bf1e80e03e2c1d0945bc50d37d2" },
  25803. + { 1344, "4be388dab21ceb3fa1b8d302e9b821f7" },
  25804. + { 1400, "a58b79fb21dd9bfc6ec93e3b99fb0ef1" },
  25805. + { 1408, "8bc97379fc2ac3237effcdd4f7a86528" },
  25806. + { 2048, "1339f03ab3076f25a20bc4cba16eb5bf" },
  25807. + { 3072, "731204d2d90c4b36ae41f5e1fb874288" },
  25808. + { 4048, "c028d998cfda5642547b7e1ed5ea16e4" },
  25809. + { 6144, "b1b19cd910cc51bd22992f1e59f1e068" },
  25810. + { 6400, "44e4613496ba622deb0e7cb768135a2f" },
  25811. + { 6528, "3b06b0a86f8db9cd67f9448dfcf10549" },
  25812. + { 8192, "d581780b7163138a0f412be681457d82" },
  25813. + {16384, "03b8ac05527faaf1bed03df149c65ccf" },
  25814. + {18432, "677c8a86a41dab6c5d81b85b8fb10ff6" },
  25815. + { 0, NULL },
  25816. +};
  25817. +
  25818. +
  25819. +/* CryptoKey = 0x01234567, 0x89abcdef,
  25820. + * 0x01234567, 0x89abcdef,
  25821. + * 0x01234567, 0x89abcdef;
  25822. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25823. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  25824. + * 0x11, 0x12, 0x13, 0x14
  25825. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25826. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  25827. + */
  25828. +static MV_CESA_SIZE_TEST tripleDesShaMultiSizeTest503[] =
  25829. +{
  25830. + { 64, "44a1e9bcbfc1429630d9ea68b7a48b0427a684f2" },
  25831. + { 80, "b2ddeaca91030eab5b95a234ef2c0f6e738ff883" },
  25832. + { 352, "4b91864c7ff629bdff75d9726421f76705452aaf" },
  25833. + { 512, "6dd37faceeb2aa98ba74f4242ed6734a4d546af5" },
  25834. + { 1000, "463661c30300be512a9df40904f0757cde5f1141" },
  25835. + { 1336, "b931f831d9034fe59c65176400b039fe9c1f44a5" },
  25836. + { 1344, "af8866b1cd4a4887d6185bfe72470ffdfb3648e1" },
  25837. + { 1400, "49c6caf07296d5e31d2504d088bc5b20c3ee7cdb" },
  25838. + { 1408, "fcae8deedbc6ebf0763575dc7e9de075b448a0f4" },
  25839. + { 2048, "edece5012146c1faa0dd10f50b183ba5d2af58ac" },
  25840. + { 3072, "5b83625adb43a488b8d64fecf39bb766818547b7" },
  25841. + { 4048, "d2c533678d26c970293af60f14c8279dc708bfc9" },
  25842. + { 6144, "b8f67af4f991b08b725f969b049ebf813bfacc5c" },
  25843. + { 6400, "d9a6c7f746ac7a60ef2edbed2841cf851c25cfb0" },
  25844. + { 6528, "376792b8c8d18161d15579fb7829e6e3a27e9946" },
  25845. + { 8192, "d890eabdca195b34ef8724b28360cffa92ae5655" },
  25846. + {16384, "a167ee52639ec7bf19aee9c6e8f76667c14134b9" },
  25847. + {18432, "e4396ab56f67296b220985a12078f4a0e365d2cc" },
  25848. + { 0, NULL },
  25849. +};
  25850. +
  25851. +/* CryptoKey = 0x01234567, 0x89abcdef,
  25852. + * 0x01234567, 0x89abcdef,
  25853. + * 0x01234567, 0x89abcdef
  25854. + * IV = 0x12345678, 0x90abcdef
  25855. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25856. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  25857. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25858. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  25859. + */
  25860. +static MV_CESA_SIZE_TEST cbc3desMdMultiSizeTest504[] =
  25861. +{
  25862. + { 64, "8d10e00802460ede0058c139ba48bd2d" },
  25863. + { 80, "6f463057e1a90e0e91ae505b527bcec0" },
  25864. + { 352, "4938d48bdf86aece2c6851e7c6079788" },
  25865. + { 512, "516705d59f3cf810ebf2a13a23a7d42e" },
  25866. + { 1000, "a5a000ee5c830e67ddc6a2d2e5644b31" },
  25867. + { 1336, "44af60087b74ed07950088efbe3b126a" },
  25868. + { 1344, "1f5b39e0577920af731dabbfcf6dfc2a" },
  25869. + { 1400, "6804ea640e29b9cd39e08bc37dbce734" },
  25870. + { 1408, "4fb436624b02516fc9d1535466574bf9" },
  25871. + { 2048, "c909b0985c423d8d86719f701e9e83db" },
  25872. + { 3072, "cfe0bc34ef97213ee3d3f8b10122db21" },
  25873. + { 4048, "03ea10b5ae4ddeb20aed6af373082ed1" },
  25874. + { 6144, "b9a0ff4f87fc14b3c2dc6f0ed0998fdf" },
  25875. + { 6400, "6995f85d9d4985dd99e974ec7dda9dd6" },
  25876. + { 6528, "bbbb548ce2fa3d58467f6a6a5168a0e6" },
  25877. + { 8192, "afe101fbe745bb449ae4f50d10801456" },
  25878. + {16384, "9741706d0b1c923340c4660ff97cacdf" },
  25879. + {18432, "b0217becb73cb8f61fd79c7ce9d023fb" },
  25880. + { 0, NULL },
  25881. +};
  25882. +
  25883. +
  25884. +/* CryptoKey = 0x01234567, 0x89abcdef,
  25885. + * 0x01234567, 0x89abcdef,
  25886. + * 0x01234567, 0x89abcdef;
  25887. + * IV = 0x12345678, 0x90abcdef
  25888. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25889. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  25890. + * 0x11, 0x12, 0x13, 0x14
  25891. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25892. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  25893. + */
  25894. +static MV_CESA_SIZE_TEST cbc3desShaMultiSizeTest505[] =
  25895. +{
  25896. + { 64, "409187e5bdb0be4a7754ca3747f7433dc4f01b98" },
  25897. + { 80, "1b002ed050be743aa98860cf35659646bb8efcc0" },
  25898. + { 352, "6cbf7ebe50fa4fa6eecc19eca23f9eae553ccfff" },
  25899. + { 512, "cfb5253fb4bf72b743320c30c7e48c54965853b0" },
  25900. + { 1000, "95e04e1ca2937e7c5a9aba9e42d2bcdb8a7af21f" },
  25901. + { 1336, "3b5c1f5eee5837ebf67b83ae01405542d77a6627" },
  25902. + { 1344, "2b3d42ab25615437f98a1ee310b81d07a02badc2" },
  25903. + { 1400, "7f8687df7c1af44e4baf3c934b6cca5ab6bc993e" },
  25904. + { 1408, "473a581c5f04f7527d50793c845471ac87e86430" },
  25905. + { 2048, "e41d20cae7ebe34e6e828ed62b1e5734019037bb" },
  25906. + { 3072, "275664afd7a561d804e6b0d204e53939cde653ae" },
  25907. + { 4048, "0d220cc5b34aeeb46bbbd637dde6290b5a8285a3" },
  25908. + { 6144, "cb393ddcc8b1c206060625b7d822ef9839e67bc5" },
  25909. + { 6400, "dd3317e2a627fc04800f74a4b05bfda00fab0347" },
  25910. + { 6528, "8a74c3b2441ab3f5a7e08895cc432566219a7c41" },
  25911. + { 8192, "b8e6ef3a549ed0e005bd5b8b1a5fe6689e9711a7" },
  25912. + {16384, "55f59404008276cdac0e2ba0d193af2d40eac5ce" },
  25913. + {18432, "86ae6c4fc72369a54cce39938e2d0296cd9c6ec5" },
  25914. + { 0, NULL },
  25915. +};
  25916. +
  25917. +
  25918. +/* CryptoKey = 0x01234567, 0x89abcdef,
  25919. + * 0x01234567, 0x89abcdef,
  25920. + * 0x01234567, 0x89abcdef
  25921. + * IV = 0x12345678, 0x90abcdef
  25922. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25923. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  25924. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25925. + * Note: only sizes aligned to AES block size (16 bytes) allowed
  25926. + */
  25927. +static MV_CESA_SIZE_TEST cbcAes128md5multiSizeTest506[] =
  25928. +{
  25929. + { 16, "7ca4c2ba866751598720c5c4aa0d6786" },
  25930. + { 64, "7dba7fb988e80da609b1fea7254bced8" },
  25931. + { 80, "6b6e863ac5a71d15e3e9b1c86c9ba05f" },
  25932. + { 352, "a1ceb9c2e3021002400d525187a9f38c" },
  25933. + { 512, "596c055c1c55db748379223164075641" },
  25934. + { 1008, "f920989c02f3b3603f53c99d89492377" },
  25935. + { 1344, "2e496b73759d77ed32ea222dbd2e7b41" },
  25936. + { 1408, "7178c046b3a8d772efdb6a71c4991ea4" },
  25937. + { 2048, "a917f0099c69eb94079a8421714b6aad" },
  25938. + { 3072, "693cd5033d7f5391d3c958519fa9e934" },
  25939. + { 4048, "139dca91bcff65b3c40771749052906b" },
  25940. + { 6144, "428d9cef6df4fb70a6e9b6bbe4819e55" },
  25941. + { 6400, "9c0b909e76daa811e12b1fc17000a0c4" },
  25942. + { 6528, "ad876f6297186a7be1f1b907ed860eda" },
  25943. + { 8192, "479cbbaca37dd3191ea1f3e8134a0ef4" },
  25944. + {16384, "60fda559c74f91df538100c9842f2f15" },
  25945. + {18432, "4a3eb1cba1fa45f3981270953f720c42" },
  25946. + { 0, NULL },
  25947. +};
  25948. +
  25949. +
  25950. +/* CryptoKey = 0x01234567, 0x89abcdef,
  25951. + * 0x01234567, 0x89abcdef,
  25952. + * 0x01234567, 0x89abcdef;
  25953. + * IV = 0x12345678, 0x90abcdef
  25954. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25955. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  25956. + * 0x11, 0x12, 0x13, 0x14
  25957. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25958. + * Note: only sizes aligned to AES block size (16 bytes) allowed
  25959. + */
  25960. +static MV_CESA_SIZE_TEST cbcAes128sha1multiSizeTest507[] =
  25961. +{
  25962. + { 16, "9aa8dc1c45f0946daf78057fa978759c625c1fee" },
  25963. + { 64, "9f588fc1ede851e5f8b20256abc9979465ae2189" },
  25964. + { 80, "13558472d1fc1c90dffec6e5136c7203452d509b" },
  25965. + { 352, "6b93518e006cfaa1f7adb24615e7291fb0a27e06" },
  25966. + { 512, "096874951a77fbbf333e49d80c096ee2016e09bd" },
  25967. + { 1008, "696fc203c2e4b5ae0ec5d1db3f623c490bc6dbac" },
  25968. + { 1344, "79bf77509935ccd3528caaac6a5eb6481f74029b" },
  25969. + { 1408, "627f9462b95fc188e8cfa7eec15119bdc5d4fcf1" },
  25970. + { 2048, "3d50d0c005feba92fe41502d609fced9c882b4d1" },
  25971. + { 3072, "758807e5b983e3a91c06fb218fe0f73f77111e94" },
  25972. + { 4048, "ca90e85242e33f005da3504416a52098d0d31fb2" },
  25973. + { 6144, "8044c1d4fd06642dfc46990b4f18b61ef1e972cf" },
  25974. + { 6400, "166f1f4ea57409f04feba9fb1e39af0e00bd6f43" },
  25975. + { 6528, "0389016a39485d6e330f8b4215ddf718b404f7e9" },
  25976. + { 8192, "6df7ee2a8b61d6f7f860ce8dbf778f0c2a5b508b" },
  25977. + {16384, "a70a6d8dfa1f91ded621c3dbaed34162bc48783f" },
  25978. + {18432, "8dfad627922ce15df1eed10bdbed49244efa57db" },
  25979. + { 0, NULL },
  25980. +};
  25981. +
  25982. +
  25983. +void cesaTestPrintStatus(void);
  25984. +
  25985. +
  25986. +/*------------------------- LOCAL FUNCTIONs ---------------------------------*/
  25987. +MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,
  25988. + MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize);
  25989. +MV_STATUS testClose(int idx);
  25990. +MV_STATUS testOpen(int idx);
  25991. +void close_session(int sid);
  25992. +void cesaTestCheckReady(const MV_CESA_RESULT *r);
  25993. +void cesaCheckReady(MV_CESA_RESULT* r);
  25994. +void printTestResults(int idx, MV_STATUS status, int checkMode);
  25995. +void cesaLastResult(void);
  25996. +void cesaTestPrintReq(int req, int offset, int size);
  25997. +
  25998. +void cesaTestPrintStatus(void);
  25999. +void cesaTestPrintSession(int idx);
  26000. +void sizeTest(int testIdx, int iter, int checkMode);
  26001. +void multiTest(int iter, int reqSize, int checkMode);
  26002. +void oneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);
  26003. +void multiSizeTest(int idx, int iter, int checkMode, char* inputData);
  26004. +void cesaTest(int iter, int reqSize, int checkMode);
  26005. +void cesaOneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);
  26006. +void combiTest(int iter, int reqSize, int checkMode);
  26007. +void shaTest(int iter, int reqSize, int checkMode);
  26008. +void mdTest(int iter, int reqSize, int checkMode);
  26009. +void aesTest(int iter, int reqSize, int checkMode);
  26010. +void tripleDesTest(int iter, int reqSize, int checkMode);
  26011. +void desTest(int iter, int reqSize, int checkMode);
  26012. +void cesaTestStop(void);
  26013. +MV_STATUS testRun(int idx, int caseIdx, int iter,int reqSize, int checkMode);
  26014. +void cesaTestStart(int bufNum, int bufSize);
  26015. +
  26016. +
  26017. +static MV_U32 getRate(MV_U32* remainder)
  26018. +{
  26019. + MV_U32 kBits, milliSec, rate;
  26020. +
  26021. + milliSec = 0;
  26022. + if( (cesaEndTicks - cesaBeginTicks) > 0)
  26023. + {
  26024. + milliSec = CESA_TEST_TICK_TO_MS(cesaEndTicks - cesaBeginTicks);
  26025. + }
  26026. + if(milliSec == 0)
  26027. + {
  26028. + if(remainder != NULL)
  26029. + *remainder = 0;
  26030. + return 0;
  26031. + }
  26032. +
  26033. + kBits = (cesaIteration*cesaRateSize*8)/1000;
  26034. + rate = kBits/milliSec;
  26035. + if(remainder != NULL)
  26036. + *remainder = ((kBits % milliSec)*10)/milliSec;
  26037. +
  26038. + return rate;
  26039. +}
  26040. +
  26041. +static char* extractMbuf(MV_CESA_MBUF *pMbuf,
  26042. + int offset, int size, char* hexStr)
  26043. +{
  26044. + mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, size);
  26045. + mvBinToHex((const MV_U8*)cesaBinBuffer, hexStr, size);
  26046. +
  26047. + return hexStr;
  26048. +}
  26049. +
  26050. +static MV_BOOL cesaCheckMbuf(MV_CESA_MBUF *pMbuf,
  26051. + const char* hexString, int offset,
  26052. + int checkSize)
  26053. +{
  26054. + MV_BOOL isFailed = MV_FALSE;
  26055. + MV_STATUS status;
  26056. + int size = strlen(hexString)/2;
  26057. + int checkedSize = 0;
  26058. +/*
  26059. + mvOsPrintf("cesaCheckMbuf: pMbuf=%p, offset=%d, checkSize=%d, mBufSize=%d\n",
  26060. + pMbuf, offset, checkSize, pMbuf->mbufSize);
  26061. +*/
  26062. + if(pMbuf->mbufSize < (checkSize + offset))
  26063. + {
  26064. + mvOsPrintf("checkSize (%d) is too large: offset=%d, mbufSize=%d\n",
  26065. + checkSize, offset, pMbuf->mbufSize);
  26066. + return MV_TRUE;
  26067. + }
  26068. + status = mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, checkSize);
  26069. + if(status != MV_OK)
  26070. + {
  26071. + mvOsPrintf("CesaTest: Can't copy %d bytes from Mbuf=%p to checkBuf=%p\n",
  26072. + checkSize, pMbuf, cesaBinBuffer);
  26073. + return MV_TRUE;
  26074. + }
  26075. +/*
  26076. + mvDebugMemDump(cesaBinBuffer, size, 1);
  26077. +*/
  26078. + mvHexToBin(hexString, (MV_U8*)cesaExpBinBuffer, size);
  26079. +
  26080. + /* Compare buffers */
  26081. + while(checkSize > checkedSize)
  26082. + {
  26083. + size = MV_MIN(size, (checkSize - checkedSize));
  26084. + if(memcmp(cesaExpBinBuffer, &cesaBinBuffer[checkedSize], size) != 0)
  26085. + {
  26086. + mvOsPrintf("CheckMbuf failed: checkSize=%d, size=%d, checkedSize=%d\n",
  26087. + checkSize, size, checkedSize);
  26088. + mvDebugMemDump(&cesaBinBuffer[checkedSize], size, 1);
  26089. + mvDebugMemDump(cesaExpBinBuffer, size, 1);
  26090. +
  26091. + isFailed = MV_TRUE;
  26092. + break;
  26093. + }
  26094. + checkedSize += size;
  26095. + }
  26096. +
  26097. + return isFailed;
  26098. +}
  26099. +
  26100. +static MV_STATUS cesaSetMbuf(MV_CESA_MBUF *pMbuf,
  26101. + const char* hexString,
  26102. + int offset, int reqSize)
  26103. +{
  26104. + MV_STATUS status = MV_OK;
  26105. + int copySize, size = strlen(hexString)/2;
  26106. +
  26107. + mvHexToBin(hexString, (MV_U8*)cesaBinBuffer, size);
  26108. +
  26109. + copySize = 0;
  26110. + while(reqSize > copySize)
  26111. + {
  26112. + size = MV_MIN(size, (reqSize - copySize));
  26113. +
  26114. + status = mvCesaCopyToMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset+copySize, size);
  26115. + if(status != MV_OK)
  26116. + {
  26117. + mvOsPrintf("cesaSetMbuf Error: Copy %d of %d bytes to MBuf\n",
  26118. + copySize, reqSize);
  26119. + break;
  26120. + }
  26121. + copySize += size;
  26122. + }
  26123. + pMbuf->mbufSize = offset+copySize;
  26124. + return status;
  26125. +}
  26126. +
  26127. +static MV_CESA_TEST_SESSION* getTestSessionDb(int idx, int* pTestIdx)
  26128. +{
  26129. + int testIdx, dbIdx = idx/100;
  26130. +
  26131. + if(dbIdx > MAX_TEST_TYPE)
  26132. + {
  26133. + mvOsPrintf("Wrong index %d - No such test type\n", idx);
  26134. + return NULL;
  26135. + }
  26136. + testIdx = idx % 100;
  26137. +
  26138. + if(testIdx >= cesaTestsDB[dbIdx].numSessions)
  26139. + {
  26140. + mvOsPrintf("Wrong index %d - No such test\n", idx);
  26141. + return NULL;
  26142. + }
  26143. + if(pTestIdx != NULL)
  26144. + *pTestIdx = testIdx;
  26145. +
  26146. + return cesaTestsDB[dbIdx].pSessions;
  26147. +}
  26148. +
  26149. +/* Debug */
  26150. +void cesaTestPrintReq(int req, int offset, int size)
  26151. +{
  26152. + MV_CESA_MBUF* pMbuf;
  26153. +
  26154. + mvOsPrintf("cesaTestPrintReq: req=%d, offset=%d, size=%d\n",
  26155. + req, offset, size);
  26156. + mvDebugMemDump(cesaCmdRing, 128, 4);
  26157. +
  26158. + pMbuf = cesaCmdRing[req].pSrc;
  26159. + mvCesaDebugMbuf("src", pMbuf, offset,size);
  26160. + pMbuf = cesaCmdRing[req].pDst;
  26161. + mvCesaDebugMbuf("dst", pMbuf, offset, size);
  26162. +
  26163. + cesaTestPrintStatus();
  26164. +}
  26165. +
  26166. +void cesaLastResult(void)
  26167. +{
  26168. + mvOsPrintf("Last Result: ReqId = %d, SessionId = %d, rc = (%d)\n",
  26169. + (MV_U32)cesaResult.pReqPrv, cesaResult.sessionId,
  26170. + cesaResult.retCode);
  26171. +}
  26172. +
  26173. +void printTestResults(int idx, MV_STATUS status, int checkMode)
  26174. +{
  26175. + int testIdx;
  26176. + MV_CESA_TEST_SESSION* pTestSessions = getTestSessionDb(idx, &testIdx);
  26177. +
  26178. + if(pTestSessions == NULL)
  26179. + return;
  26180. +
  26181. + mvOsPrintf("%-35s %4dx%-4d : ", pTestSessions[testIdx].name,
  26182. + cesaIteration, cesaReqSize);
  26183. + if( (status == MV_OK) &&
  26184. + (cesaCryptoError == 0) &&
  26185. + (cesaError == 0) &&
  26186. + (cesaReqIdError == 0) )
  26187. + {
  26188. + mvOsPrintf("Passed, Rate=%3u.%u Mbps (%5u cpp)\n",
  26189. + cesaRate, cesaRateAfterDot, cesaEndTicks - cesaBeginTicks);
  26190. + }
  26191. + else
  26192. + {
  26193. + mvOsPrintf("Failed, Status = 0x%x\n", status);
  26194. + if(cesaCryptoError > 0)
  26195. + mvOsPrintf("cryptoError : %d\n", cesaCryptoError);
  26196. + if(cesaReqIdError > 0)
  26197. + mvOsPrintf("reqIdError : %d\n", cesaReqIdError);
  26198. + if(cesaError > 0)
  26199. + mvOsPrintf("cesaError : %d\n", cesaError);
  26200. + }
  26201. + if(cesaTestIsrMissCount > 0)
  26202. + mvOsPrintf("cesaIsrMissed : %d\n", cesaTestIsrMissCount);
  26203. +}
  26204. +
  26205. +void cesaCheckReady(MV_CESA_RESULT* r)
  26206. +{
  26207. + int reqId;
  26208. + MV_CESA_MBUF *pMbuf;
  26209. + MV_BOOL isFailed;
  26210. +
  26211. + cesaResult = *r;
  26212. + reqId = (int)cesaResult.pReqPrv;
  26213. + pMbuf = cesaCmdRing[reqId].pDst;
  26214. +
  26215. +/*
  26216. + mvOsPrintf("cesaCheckReady: reqId=%d, checkOffset=%d, checkSize=%d\n",
  26217. + reqId, cesaCheckOffset, cesaCheckSize);
  26218. +*/
  26219. + /* Check expected reqId */
  26220. + if(reqId != cesaExpReqId)
  26221. + {
  26222. + cesaReqIdError++;
  26223. +/*
  26224. + mvOsPrintf("CESA reqId Error: cbIter=%d (%d), reqId=%d, expReqId=%d\n",
  26225. + cesaCbIter, cesaIteration, reqId, cesaExpReqId);
  26226. +*/
  26227. + }
  26228. + else
  26229. + {
  26230. + if( (cesaCheckMode == CESA_FULL_CHECK_MODE) ||
  26231. + (cesaCheckMode == CESA_FAST_CHECK_MODE) )
  26232. + {
  26233. + if(cesaResult.retCode != MV_OK)
  26234. + {
  26235. + cesaError++;
  26236. +
  26237. + mvOsPrintf("CESA Error: cbIter=%d (%d), reqId=%d, rc=%d\n",
  26238. + cesaCbIter, cesaIteration, reqId, cesaResult.retCode);
  26239. + }
  26240. + else
  26241. + {
  26242. + if( (cesaCheckSize > 0) && (cesaOutputHexStr != NULL) )
  26243. + {
  26244. + /* Check expected output */
  26245. +
  26246. + isFailed = cesaCheckMbuf(pMbuf, cesaOutputHexStr, cesaCheckOffset, cesaCheckSize);
  26247. + if(isFailed)
  26248. + {
  26249. + mvOsPrintf("CESA Crypto Error: cbIter=%d (%d), reqId=%d\n",
  26250. + cesaCbIter, cesaIteration, reqId);
  26251. +
  26252. + CESA_TEST_DEBUG_PRINT(("Error: reqId=%d, reqSize=%d, checkOffset=%d, checkSize=%d\n",
  26253. + reqId, cesaReqSize, cesaCheckOffset, cesaCheckSize));
  26254. +
  26255. + CESA_TEST_DEBUG_PRINT(("Output str: %s\n", cesaOutputHexStr));
  26256. +
  26257. + CESA_TEST_DEBUG_CODE( mvCesaDebugMbuf("error", pMbuf, 0, cesaCheckOffset+cesaCheckSize) );
  26258. +
  26259. + cesaCryptoError++;
  26260. + }
  26261. + }
  26262. + }
  26263. + }
  26264. + }
  26265. + if(cesaCheckMode == CESA_SHOW_CHECK_MODE)
  26266. + {
  26267. + extractMbuf(pMbuf, cesaCheckOffset, cesaCheckSize, cesaHexBuffer);
  26268. + mvOsPrintf("%4d, %s\n", cesaCheckOffset, cesaHexBuffer);
  26269. + }
  26270. +
  26271. + cesaCbIter++;
  26272. + if(cesaCbIter >= cesaIteration)
  26273. + {
  26274. + cesaCbIter = 0;
  26275. + cesaExpReqId = 0;
  26276. + cesaIsReady = MV_TRUE;
  26277. +
  26278. + cesaEndTicks = CESA_TEST_TICK_GET();
  26279. + cesaRate = getRate(&cesaRateAfterDot);
  26280. + }
  26281. + else
  26282. + {
  26283. + cesaExpReqId = reqId + 1;
  26284. + if(cesaExpReqId == CESA_DEF_REQ_SIZE)
  26285. + cesaExpReqId = 0;
  26286. + }
  26287. +}
  26288. +
  26289. +
  26290. +#ifdef MV_NETBSD
  26291. +static int cesaTestReadyIsr(void *arg)
  26292. +#else
  26293. +#ifdef __KERNEL__
  26294. +static irqreturn_t cesaTestReadyIsr( int irq , void *dev_id)
  26295. +#endif
  26296. +#ifdef MV_VXWORKS
  26297. +void cesaTestReadyIsr(void)
  26298. +#endif
  26299. +#endif
  26300. +{
  26301. + MV_U32 cause;
  26302. + MV_STATUS status;
  26303. + MV_CESA_RESULT result;
  26304. +
  26305. + cesaTestIsrCount++;
  26306. + /* Clear cause register */
  26307. + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  26308. + if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)
  26309. + {
  26310. + mvOsPrintf("cesaTestReadyIsr: cause=0x%x\n", cause);
  26311. +#ifdef MV_NETBSD
  26312. + return 0;
  26313. +#else
  26314. +#ifdef __KERNEL__
  26315. + return 1;
  26316. +#else
  26317. + return;
  26318. +#endif
  26319. +#endif
  26320. + }
  26321. +
  26322. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  26323. +
  26324. + while(MV_TRUE)
  26325. + {
  26326. + /* Get Ready requests */
  26327. + status = mvCesaReadyGet(&result);
  26328. + if(status == MV_OK)
  26329. + cesaCheckReady(&result);
  26330. +
  26331. + break;
  26332. + }
  26333. + if( (cesaTestFull == 1) && (status != MV_BUSY) )
  26334. + {
  26335. + cesaTestFull = 0;
  26336. + CESA_TEST_WAKE_UP();
  26337. + }
  26338. +
  26339. +#ifdef __KERNEL__
  26340. + return 1;
  26341. +#endif
  26342. +}
  26343. +
  26344. +void
  26345. +cesaTestCheckReady(const MV_CESA_RESULT *r)
  26346. +{
  26347. + MV_CESA_RESULT result = *r;
  26348. +
  26349. + cesaCheckReady(&result);
  26350. +
  26351. + if (cesaTestFull == 1) {
  26352. + cesaTestFull = 0;
  26353. + CESA_TEST_WAKE_UP();
  26354. + }
  26355. +}
  26356. +
  26357. +static INLINE int open_session(MV_CESA_OPEN_SESSION* pOs)
  26358. +{
  26359. + MV_U16 sid;
  26360. + MV_STATUS status;
  26361. +
  26362. + status = mvCesaSessionOpen(pOs, (short*)&sid);
  26363. + if(status != MV_OK)
  26364. + {
  26365. + mvOsPrintf("CesaTest: Can't open new session - status = 0x%x\n",
  26366. + status);
  26367. + return -1;
  26368. + }
  26369. +
  26370. + return (int)sid;
  26371. +}
  26372. +
  26373. +void close_session(int sid)
  26374. +{
  26375. + MV_STATUS status;
  26376. +
  26377. + status = mvCesaSessionClose(sid);
  26378. + if(status != MV_OK)
  26379. + {
  26380. + mvOsPrintf("CesaTest: Can't close session %d - status = 0x%x\n",
  26381. + sid, status);
  26382. + }
  26383. +}
  26384. +
  26385. +MV_STATUS testOpen(int idx)
  26386. +{
  26387. + MV_CESA_OPEN_SESSION os;
  26388. + int sid, i, testIdx;
  26389. + MV_CESA_TEST_SESSION* pTestSession;
  26390. + MV_U16 digestSize = 0;
  26391. +
  26392. + pTestSession = getTestSessionDb(idx, &testIdx);
  26393. + if(pTestSession == NULL)
  26394. + {
  26395. + mvOsPrintf("Test %d is not exist\n", idx);
  26396. + return MV_BAD_PARAM;
  26397. + }
  26398. + pTestSession = &pTestSession[testIdx];
  26399. +
  26400. + if(pTestSession->sid != -1)
  26401. + {
  26402. + mvOsPrintf("Session for test %d already created: sid=%d\n",
  26403. + idx, pTestSession->sid);
  26404. + return MV_OK;
  26405. + }
  26406. +
  26407. + os.cryptoAlgorithm = pTestSession->cryptoAlgorithm;
  26408. + os.macMode = pTestSession->macAlgorithm;
  26409. + switch(os.macMode)
  26410. + {
  26411. + case MV_CESA_MAC_MD5:
  26412. + case MV_CESA_MAC_HMAC_MD5:
  26413. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  26414. + break;
  26415. +
  26416. + case MV_CESA_MAC_SHA1:
  26417. + case MV_CESA_MAC_HMAC_SHA1:
  26418. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  26419. + break;
  26420. +
  26421. + case MV_CESA_MAC_NULL:
  26422. + digestSize = 0;
  26423. + }
  26424. + os.cryptoMode = pTestSession->cryptoMode;
  26425. + os.direction = pTestSession->direction;
  26426. + os.operation = pTestSession->operation;
  26427. +
  26428. + for(i=0; i<pTestSession->cryptoKeySize; i++)
  26429. + os.cryptoKey[i] = pTestSession->pCryptoKey[i];
  26430. +
  26431. + os.cryptoKeyLength = pTestSession->cryptoKeySize;
  26432. +
  26433. + for(i=0; i<pTestSession->macKeySize; i++)
  26434. + os.macKey[i] = pTestSession->pMacKey[i];
  26435. +
  26436. + os.macKeyLength = pTestSession->macKeySize;
  26437. + os.digestSize = digestSize;
  26438. +
  26439. + sid = open_session(&os);
  26440. + if(sid == -1)
  26441. + {
  26442. + mvOsPrintf("Can't open session for test %d: rc=0x%x\n",
  26443. + idx, cesaResult.retCode);
  26444. + return cesaResult.retCode;
  26445. + }
  26446. + CESA_TEST_DEBUG_PRINT(("Opened session: sid = %d\n", sid));
  26447. + pTestSession->sid = sid;
  26448. + return MV_OK;
  26449. +}
  26450. +
  26451. +MV_STATUS testClose(int idx)
  26452. +{
  26453. + int testIdx;
  26454. + MV_CESA_TEST_SESSION* pTestSession;
  26455. +
  26456. + pTestSession = getTestSessionDb(idx, &testIdx);
  26457. + if(pTestSession == NULL)
  26458. + {
  26459. + mvOsPrintf("Test %d is not exist\n", idx);
  26460. + return MV_BAD_PARAM;
  26461. + }
  26462. + pTestSession = &pTestSession[testIdx];
  26463. +
  26464. + if(pTestSession->sid == -1)
  26465. + {
  26466. + mvOsPrintf("Test session %d is not opened\n", idx);
  26467. + return MV_NO_SUCH;
  26468. + }
  26469. +
  26470. + close_session(pTestSession->sid);
  26471. + pTestSession->sid = -1;
  26472. +
  26473. + return MV_OK;
  26474. +}
  26475. +
  26476. +MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,
  26477. + MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize)
  26478. +{
  26479. + int cmdReqId = 0;
  26480. + int i;
  26481. + MV_STATUS rc = MV_OK;
  26482. + char ivZeroHex[] = "0000";
  26483. +
  26484. + if(iter == 0)
  26485. + iter = CESA_DEF_ITER_NUM;
  26486. +
  26487. + if(pCmd == NULL)
  26488. + {
  26489. + mvOsPrintf("testCmd failed: pCmd=NULL\n");
  26490. + return MV_BAD_PARAM;
  26491. + }
  26492. + pCmd->sessionId = sid;
  26493. +
  26494. + cesaCryptoError = 0;
  26495. + cesaReqIdError = 0;
  26496. + cesaError = 0;
  26497. + cesaTestIsrMissCount = 0;
  26498. + cesaIsReady = MV_FALSE;
  26499. + cesaIteration = iter;
  26500. +
  26501. + if(cesaInputHexStr == NULL)
  26502. + cesaInputHexStr = cesaPlainHexEbc;
  26503. +
  26504. + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
  26505. + {
  26506. + pCmd->pSrc = (MV_CESA_MBUF*)(cesaCmdRing[i].pSrc);
  26507. + if(pIV != NULL)
  26508. + {
  26509. + /* If IV from SA - set IV in Source buffer to zeros */
  26510. + cesaSetMbuf(pCmd->pSrc, ivZeroHex, 0, pCmd->cryptoOffset);
  26511. + cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, pCmd->cryptoOffset,
  26512. + (cesaReqSize - pCmd->cryptoOffset));
  26513. + }
  26514. + else
  26515. + {
  26516. + cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, 0, cesaReqSize);
  26517. + }
  26518. + pCmd->pDst = (MV_CESA_MBUF*)(cesaCmdRing[i].pDst);
  26519. + cesaSetMbuf(pCmd->pDst, cesaNullPlainHexText, 0, cesaReqSize);
  26520. +
  26521. + memcpy(&cesaCmdRing[i], pCmd, sizeof(*pCmd));
  26522. + }
  26523. +
  26524. + if(cesaCheckMode == CESA_SW_SHOW_CHECK_MODE)
  26525. + {
  26526. + MV_U8 pDigest[MV_CESA_MAX_DIGEST_SIZE];
  26527. +
  26528. + if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)
  26529. + {
  26530. + mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);
  26531. + mvOsPrintf("SW HASH_MD5: reqSize=%d, macLength=%d\n",
  26532. + cesaReqSize, pCmd->macLength);
  26533. + mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);
  26534. + return MV_OK;
  26535. + }
  26536. + if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)
  26537. + {
  26538. + mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);
  26539. + mvOsPrintf("SW HASH_SHA1: reqSize=%d, macLength=%d\n",
  26540. + cesaReqSize, pCmd->macLength);
  26541. + mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);
  26542. + return MV_OK;
  26543. + }
  26544. + }
  26545. +
  26546. + cesaBeginTicks = CESA_TEST_TICK_GET();
  26547. + CESA_TEST_DEBUG_CODE( memset(cesaTestTrace, 0, sizeof(cesaTestTrace));
  26548. + cesaTestTraceIdx = 0;
  26549. + );
  26550. +
  26551. + if(cesaCheckMode == CESA_SW_NULL_CHECK_MODE)
  26552. + {
  26553. + volatile MV_U8 pDigest[MV_CESA_MAX_DIGEST_SIZE];
  26554. +
  26555. + for(i=0; i<iter; i++)
  26556. + {
  26557. + if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)
  26558. + {
  26559. + mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (unsigned char*)pDigest);
  26560. + }
  26561. + if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)
  26562. + {
  26563. + mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (MV_U8 *)pDigest);
  26564. + }
  26565. + }
  26566. + cesaEndTicks = CESA_TEST_TICK_GET();
  26567. + cesaRate = getRate(&cesaRateAfterDot);
  26568. + cesaIsReady = MV_TRUE;
  26569. +
  26570. + return MV_OK;
  26571. + }
  26572. +
  26573. + /*cesaTestIsrCount = 0;*/
  26574. + /*mvCesaDebugStatsClear();*/
  26575. +
  26576. +#ifndef MV_NETBSD
  26577. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  26578. +#endif
  26579. +
  26580. + for(i=0; i<iter; i++)
  26581. + {
  26582. + unsigned long flags;
  26583. +
  26584. + pCmd = &cesaCmdRing[cmdReqId];
  26585. + pCmd->pReqPrv = (void*)cmdReqId;
  26586. +
  26587. + CESA_TEST_LOCK(flags);
  26588. +
  26589. + rc = mvCesaAction(pCmd);
  26590. + if(rc == MV_NO_RESOURCE)
  26591. + cesaTestFull = 1;
  26592. +
  26593. + CESA_TEST_UNLOCK(flags);
  26594. +
  26595. + if(rc == MV_NO_RESOURCE)
  26596. + {
  26597. + CESA_TEST_LOCK(flags);
  26598. + CESA_TEST_WAIT( (cesaTestFull == 0), 100);
  26599. + CESA_TEST_UNLOCK(flags);
  26600. + if(cesaTestFull == 1)
  26601. + {
  26602. + mvOsPrintf("CESA Test timeout: i=%d, iter=%d, cesaTestFull=%d\n",
  26603. + i, iter, cesaTestFull);
  26604. + cesaTestFull = 0;
  26605. + return MV_TIMEOUT;
  26606. + }
  26607. +
  26608. + CESA_TEST_LOCK(flags);
  26609. +
  26610. + rc = mvCesaAction(pCmd);
  26611. +
  26612. + CESA_TEST_UNLOCK(flags);
  26613. + }
  26614. + if( (rc != MV_OK) && (rc != MV_NO_MORE) )
  26615. + {
  26616. + mvOsPrintf("mvCesaAction failed: rc=%d\n", rc);
  26617. + return rc;
  26618. + }
  26619. +
  26620. + cmdReqId++;
  26621. + if(cmdReqId >= CESA_DEF_REQ_SIZE)
  26622. + cmdReqId = 0;
  26623. +
  26624. +#ifdef MV_LINUX
  26625. + /* Reschedule each 16 requests */
  26626. + if( (i & 0xF) == 0)
  26627. + schedule();
  26628. +#endif
  26629. + }
  26630. + return MV_OK;
  26631. +}
  26632. +
  26633. +void cesaTestStart(int bufNum, int bufSize)
  26634. +{
  26635. + int i, j, idx;
  26636. + MV_CESA_MBUF *pMbufSrc, *pMbufDst;
  26637. + MV_BUF_INFO *pFragsSrc, *pFragsDst;
  26638. + char *pBuf;
  26639. +#ifndef MV_NETBSD
  26640. + int numOfSessions, queueDepth;
  26641. + char *pSram;
  26642. + MV_STATUS status;
  26643. + MV_CPU_DEC_WIN addrDecWin;
  26644. +#endif
  26645. +
  26646. + cesaCmdRing = mvOsMalloc(sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
  26647. + if(cesaCmdRing == NULL)
  26648. + {
  26649. + mvOsPrintf("testStart: Can't allocate %ld bytes of memory\n",
  26650. + sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
  26651. + return;
  26652. + }
  26653. + memset(cesaCmdRing, 0, sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
  26654. +
  26655. + if(bufNum == 0)
  26656. + bufNum = CESA_DEF_BUF_NUM;
  26657. +
  26658. + if(bufSize == 0)
  26659. + bufSize = CESA_DEF_BUF_SIZE;
  26660. +
  26661. + cesaBufNum = bufNum;
  26662. + cesaBufSize = bufSize;
  26663. + mvOsPrintf("CESA test started: bufNum = %d, bufSize = %d\n",
  26664. + bufNum, bufSize);
  26665. +
  26666. + cesaHexBuffer = mvOsMalloc(2*bufNum*bufSize);
  26667. + if(cesaHexBuffer == NULL)
  26668. + {
  26669. + mvOsPrintf("testStart: Can't malloc %d bytes for cesaHexBuffer.\n",
  26670. + 2*bufNum*bufSize);
  26671. + return;
  26672. + }
  26673. + memset(cesaHexBuffer, 0, (2*bufNum*bufSize));
  26674. +
  26675. + cesaBinBuffer = mvOsMalloc(bufNum*bufSize);
  26676. + if(cesaBinBuffer == NULL)
  26677. + {
  26678. + mvOsPrintf("testStart: Can't malloc %d bytes for cesaBinBuffer\n",
  26679. + bufNum*bufSize);
  26680. + return;
  26681. + }
  26682. + memset(cesaBinBuffer, 0, (bufNum*bufSize));
  26683. +
  26684. + cesaExpBinBuffer = mvOsMalloc(bufNum*bufSize);
  26685. + if(cesaExpBinBuffer == NULL)
  26686. + {
  26687. + mvOsPrintf("testStart: Can't malloc %d bytes for cesaExpBinBuffer\n",
  26688. + bufNum*bufSize);
  26689. + return;
  26690. + }
  26691. + memset(cesaExpBinBuffer, 0, (bufNum*bufSize));
  26692. +
  26693. + CESA_TEST_WAIT_INIT();
  26694. +
  26695. + pMbufSrc = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  26696. + pFragsSrc = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  26697. +
  26698. + pMbufDst = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  26699. + pFragsDst = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  26700. +
  26701. + if( (pMbufSrc == NULL) || (pFragsSrc == NULL) ||
  26702. + (pMbufDst == NULL) || (pFragsDst == NULL) )
  26703. + {
  26704. + mvOsPrintf("testStart: Can't malloc Src and Dst pMbuf and pFrags structures.\n");
  26705. + /* !!!! Dima cesaTestCleanup();*/
  26706. + return;
  26707. + }
  26708. +
  26709. + memset(pMbufSrc, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  26710. + memset(pFragsSrc, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  26711. +
  26712. + memset(pMbufDst, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  26713. + memset(pFragsDst, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  26714. +
  26715. + mvOsPrintf("Cesa Test Start: pMbufSrc=%p, pFragsSrc=%p, pMbufDst=%p, pFragsDst=%p\n",
  26716. + pMbufSrc, pFragsSrc, pMbufDst, pFragsDst);
  26717. +
  26718. + idx = 0;
  26719. + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
  26720. + {
  26721. + pBuf = mvOsIoCachedMalloc(cesaTestOSHandle,bufSize * bufNum * 2,
  26722. + &cesaReqBufs[i].bufPhysAddr,
  26723. + &cesaReqBufs[i].memHandle);
  26724. + if(pBuf == NULL)
  26725. + {
  26726. + mvOsPrintf("testStart: Can't malloc %d bytes for pBuf\n",
  26727. + bufSize * bufNum * 2);
  26728. + return;
  26729. + }
  26730. +
  26731. + memset(pBuf, 0, bufSize * bufNum * 2);
  26732. + mvOsCacheFlush(cesaTestOSHandle,pBuf, bufSize * bufNum * 2);
  26733. + if(pBuf == NULL)
  26734. + {
  26735. + mvOsPrintf("cesaTestStart: Can't allocate %d bytes for req_%d buffers\n",
  26736. + bufSize * bufNum * 2, i);
  26737. + return;
  26738. + }
  26739. +
  26740. + cesaReqBufs[i].bufVirtPtr = (MV_U8*)pBuf;
  26741. + cesaReqBufs[i].bufSize = bufSize * bufNum * 2;
  26742. +
  26743. + cesaCmdRing[i].pSrc = &pMbufSrc[i];
  26744. + cesaCmdRing[i].pSrc->pFrags = &pFragsSrc[idx];
  26745. + cesaCmdRing[i].pSrc->numFrags = bufNum;
  26746. + cesaCmdRing[i].pSrc->mbufSize = 0;
  26747. +
  26748. + cesaCmdRing[i].pDst = &pMbufDst[i];
  26749. + cesaCmdRing[i].pDst->pFrags = &pFragsDst[idx];
  26750. + cesaCmdRing[i].pDst->numFrags = bufNum;
  26751. + cesaCmdRing[i].pDst->mbufSize = 0;
  26752. +
  26753. + for(j=0; j<bufNum; j++)
  26754. + {
  26755. + cesaCmdRing[i].pSrc->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;
  26756. + cesaCmdRing[i].pSrc->pFrags[j].bufSize = bufSize;
  26757. + pBuf += bufSize;
  26758. + cesaCmdRing[i].pDst->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;
  26759. + cesaCmdRing[i].pDst->pFrags[j].bufSize = bufSize;
  26760. + pBuf += bufSize;
  26761. + }
  26762. + idx += bufNum;
  26763. + }
  26764. +
  26765. +#ifndef MV_NETBSD
  26766. + if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)
  26767. + pSram = (char*)addrDecWin.addrWin.baseLow;
  26768. + else
  26769. + {
  26770. + mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");
  26771. + return;
  26772. + }
  26773. +
  26774. +#ifdef MV_CESA_NO_SRAM
  26775. + pSram = mvOsMalloc(4*1024+8);
  26776. + if(pSram == NULL)
  26777. + {
  26778. + mvOsPrintf("CesaTest: can't allocate %d bytes for SRAM simulation\n",
  26779. + 4*1024+8);
  26780. + /* !!!! Dima cesaTestCleanup();*/
  26781. + return;
  26782. + }
  26783. + pSram = (MV_U8*)MV_ALIGN_UP((MV_U32)pSram, 8);
  26784. +#endif /* MV_CESA_NO_SRAM */
  26785. +
  26786. + numOfSessions = CESA_DEF_SESSION_NUM;
  26787. + queueDepth = CESA_DEF_REQ_SIZE - MV_CESA_MAX_CHAN;
  26788. +
  26789. + status = mvCesaInit(numOfSessions, queueDepth, pSram, NULL);
  26790. + if(status != MV_OK)
  26791. + {
  26792. + mvOsPrintf("mvCesaInit is Failed: status = 0x%x\n", status);
  26793. + /* !!!! Dima cesaTestCleanup();*/
  26794. + return;
  26795. + }
  26796. +#endif /* !MV_NETBSD */
  26797. +
  26798. + /* Prepare data for tests */
  26799. + for(i=0; i<50; i++)
  26800. + strcat((char*)cesaDataHexStr3, "dd");
  26801. +
  26802. + strcpy((char*)cesaDataAndMd5digest3, cesaDataHexStr3);
  26803. + strcpy((char*)cesaDataAndSha1digest3, cesaDataHexStr3);
  26804. +
  26805. + /* Digest must be 8 byte aligned */
  26806. + for(; i<56; i++)
  26807. + {
  26808. + strcat((char*)cesaDataAndMd5digest3, "00");
  26809. + strcat((char*)cesaDataAndSha1digest3, "00");
  26810. + }
  26811. + strcat((char*)cesaDataAndMd5digest3, cesaHmacMd5digestHex3);
  26812. + strcat((char*)cesaDataAndSha1digest3, cesaHmacSha1digestHex3);
  26813. +
  26814. +#ifndef MV_NETBSD
  26815. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  26816. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);
  26817. +#endif
  26818. +
  26819. +#ifdef MV_VXWORKS
  26820. + {
  26821. + MV_STATUS status;
  26822. +
  26823. + status = intConnect((VOIDFUNCPTR *)INT_LVL_CESA, cesaTestReadyIsr, (int)NULL);
  26824. + if (status != OK)
  26825. + {
  26826. + mvOsPrintf("CESA: Can't connect CESA (%d) interrupt, status=0x%x \n",
  26827. + INT_LVL_CESA, status);
  26828. + /* !!!! Dima cesaTestCleanup();*/
  26829. + return;
  26830. + }
  26831. + cesaSemId = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
  26832. + if(cesaSemId == NULL)
  26833. + {
  26834. + mvOsPrintf("cesaTestStart: Can't create semaphore\n");
  26835. + return;
  26836. + }
  26837. + intEnable(INT_LVL_CESA);
  26838. + }
  26839. +#endif /* MV_VXWORKS */
  26840. +
  26841. +#if !defined(MV_NETBSD) && defined(__KERNEL__)
  26842. + if( request_irq(CESA_IRQ, cesaTestReadyIsr, (SA_INTERRUPT) , "cesa_test", NULL ) )
  26843. + {
  26844. + mvOsPrintf( "cannot assign irq\n" );
  26845. + /* !!!! Dima cesaTestCleanup();*/
  26846. + return;
  26847. + }
  26848. + spin_lock_init( &cesaLock );
  26849. +#endif
  26850. +}
  26851. +
  26852. +MV_STATUS testRun(int idx, int caseIdx, int iter,
  26853. + int reqSize, int checkMode)
  26854. +{
  26855. + int testIdx, count, sid, digestSize;
  26856. + int blockSize;
  26857. + MV_CESA_TEST_SESSION* pTestSession;
  26858. + MV_CESA_COMMAND cmd;
  26859. + MV_STATUS status;
  26860. +
  26861. + memset(&cmd, 0, sizeof(cmd));
  26862. +
  26863. + pTestSession = getTestSessionDb(idx, &testIdx);
  26864. + if(pTestSession == NULL)
  26865. + {
  26866. + mvOsPrintf("Test %d is not exist\n", idx);
  26867. + return MV_BAD_PARAM;
  26868. + }
  26869. + pTestSession = &pTestSession[testIdx];
  26870. +
  26871. + sid = pTestSession->sid;
  26872. + if(sid == -1)
  26873. + {
  26874. + mvOsPrintf("Test %d is not opened\n", idx);
  26875. + return MV_BAD_STATE;
  26876. + }
  26877. + switch(pTestSession->cryptoAlgorithm)
  26878. + {
  26879. + case MV_CESA_CRYPTO_DES:
  26880. + case MV_CESA_CRYPTO_3DES:
  26881. + blockSize = MV_CESA_DES_BLOCK_SIZE;
  26882. + break;
  26883. +
  26884. + case MV_CESA_CRYPTO_AES:
  26885. + blockSize = MV_CESA_AES_BLOCK_SIZE;
  26886. + break;
  26887. +
  26888. + case MV_CESA_CRYPTO_NULL:
  26889. + blockSize = 0;
  26890. + break;
  26891. +
  26892. + default:
  26893. + mvOsPrintf("cesaTestRun: Bad CryptoAlgorithm=%d\n",
  26894. + pTestSession->cryptoAlgorithm);
  26895. + return MV_BAD_PARAM;
  26896. + }
  26897. + switch(pTestSession->macAlgorithm)
  26898. + {
  26899. + case MV_CESA_MAC_MD5:
  26900. + case MV_CESA_MAC_HMAC_MD5:
  26901. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  26902. + break;
  26903. +
  26904. + case MV_CESA_MAC_SHA1:
  26905. + case MV_CESA_MAC_HMAC_SHA1:
  26906. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  26907. + break;
  26908. + default:
  26909. + digestSize = 0;
  26910. + }
  26911. +
  26912. + if(iter == 0)
  26913. + iter = CESA_DEF_ITER_NUM;
  26914. +
  26915. + if(pTestSession->direction == MV_CESA_DIR_ENCODE)
  26916. + {
  26917. + cesaOutputHexStr = cesaTestCases[caseIdx].cipherHexStr;
  26918. + cesaInputHexStr = cesaTestCases[caseIdx].plainHexStr;
  26919. + }
  26920. + else
  26921. + {
  26922. + cesaOutputHexStr = cesaTestCases[caseIdx].plainHexStr;
  26923. + cesaInputHexStr = cesaTestCases[caseIdx].cipherHexStr;
  26924. + }
  26925. +
  26926. + cmd.sessionId = sid;
  26927. + if(checkMode == CESA_FAST_CHECK_MODE)
  26928. + {
  26929. + cmd.cryptoLength = cesaTestCases[caseIdx].cryptoLength;
  26930. + cmd.macLength = cesaTestCases[caseIdx].macLength;
  26931. + }
  26932. + else
  26933. + {
  26934. + cmd.cryptoLength = reqSize;
  26935. + cmd.macLength = reqSize;
  26936. + }
  26937. + cesaRateSize = cmd.cryptoLength;
  26938. + cesaReqSize = cmd.cryptoLength;
  26939. + cmd.cryptoOffset = 0;
  26940. + if(pTestSession->operation != MV_CESA_MAC_ONLY)
  26941. + {
  26942. + if( (pTestSession->cryptoMode == MV_CESA_CRYPTO_CBC) ||
  26943. + (pTestSession->cryptoMode == MV_CESA_CRYPTO_CTR) )
  26944. + {
  26945. + cmd.ivOffset = 0;
  26946. + cmd.cryptoOffset = blockSize;
  26947. + if(cesaTestCases[caseIdx].pCryptoIV == NULL)
  26948. + {
  26949. + cmd.ivFromUser = 1;
  26950. + }
  26951. + else
  26952. + {
  26953. + cmd.ivFromUser = 0;
  26954. + mvCesaCryptoIvSet(cesaTestCases[caseIdx].pCryptoIV, blockSize);
  26955. + }
  26956. + cesaReqSize = cmd.cryptoOffset + cmd.cryptoLength;
  26957. + }
  26958. + }
  26959. +
  26960. +/*
  26961. + mvOsPrintf("ivFromUser=%d, cryptoLength=%d, cesaReqSize=%d, cryptoOffset=%d\n",
  26962. + cmd.ivFromUser, cmd.cryptoLength, cesaReqSize, cmd.cryptoOffset);
  26963. +*/
  26964. + if(pTestSession->operation != MV_CESA_CRYPTO_ONLY)
  26965. + {
  26966. + cmd.macOffset = cmd.cryptoOffset;
  26967. +
  26968. + if(cesaTestCases[caseIdx].digestOffset == -1)
  26969. + {
  26970. + cmd.digestOffset = cmd.macOffset + cmd.macLength;
  26971. + cmd.digestOffset = MV_ALIGN_UP(cmd.digestOffset, 8);
  26972. + }
  26973. + else
  26974. + {
  26975. + cmd.digestOffset = cesaTestCases[caseIdx].digestOffset;
  26976. + }
  26977. + if( (cmd.digestOffset + digestSize) > cesaReqSize)
  26978. + cesaReqSize = cmd.digestOffset + digestSize;
  26979. + }
  26980. +
  26981. + cesaCheckMode = checkMode;
  26982. +
  26983. + if(checkMode == CESA_NULL_CHECK_MODE)
  26984. + {
  26985. + cesaCheckSize = 0;
  26986. + cesaCheckOffset = 0;
  26987. + }
  26988. + else
  26989. + {
  26990. + if(pTestSession->operation == MV_CESA_CRYPTO_ONLY)
  26991. + {
  26992. + cesaCheckOffset = 0;
  26993. + cesaCheckSize = cmd.cryptoLength;
  26994. + }
  26995. + else
  26996. + {
  26997. + cesaCheckSize = digestSize;
  26998. + cesaCheckOffset = cmd.digestOffset;
  26999. + }
  27000. + }
  27001. +/*
  27002. + mvOsPrintf("reqSize=%d, checkSize=%d, checkOffset=%d, checkMode=%d\n",
  27003. + cesaReqSize, cesaCheckSize, cesaCheckOffset, cesaCheckMode);
  27004. +
  27005. + mvOsPrintf("blockSize=%d, ivOffset=%d, ivFromUser=%d, crOffset=%d, crLength=%d\n",
  27006. + blockSize, cmd.ivOffset, cmd.ivFromUser,
  27007. + cmd.cryptoOffset, cmd.cryptoLength);
  27008. +
  27009. + mvOsPrintf("macOffset=%d, digestOffset=%d, macLength=%d\n",
  27010. + cmd.macOffset, cmd.digestOffset, cmd.macLength);
  27011. +*/
  27012. + status = testCmd(sid, iter, &cmd, pTestSession,
  27013. + cesaTestCases[caseIdx].pCryptoIV, blockSize);
  27014. +
  27015. + if(status != MV_OK)
  27016. + return status;
  27017. +
  27018. + /* Wait when all callbacks is received */
  27019. + count = 0;
  27020. + while(cesaIsReady == MV_FALSE)
  27021. + {
  27022. + mvOsSleep(10);
  27023. + count++;
  27024. + if(count > 100)
  27025. + {
  27026. + mvOsPrintf("testRun: Timeout occured\n");
  27027. + return MV_TIMEOUT;
  27028. + }
  27029. + }
  27030. +
  27031. + return MV_OK;
  27032. +}
  27033. +
  27034. +
  27035. +void cesaTestStop(void)
  27036. +{
  27037. + MV_CESA_MBUF *pMbufSrc, *pMbufDst;
  27038. + MV_BUF_INFO *pFragsSrc, *pFragsDst;
  27039. + int i;
  27040. +
  27041. + /* Release all allocated memories */
  27042. + pMbufSrc = (MV_CESA_MBUF*)(cesaCmdRing[0].pSrc);
  27043. + pFragsSrc = cesaCmdRing[0].pSrc->pFrags;
  27044. +
  27045. + pMbufDst = (MV_CESA_MBUF*)(cesaCmdRing[0].pDst);
  27046. + pFragsDst = cesaCmdRing[0].pDst->pFrags;
  27047. +
  27048. + mvOsFree(pMbufSrc);
  27049. + mvOsFree(pMbufDst);
  27050. + mvOsFree(pFragsSrc);
  27051. + mvOsFree(pFragsDst);
  27052. +
  27053. + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
  27054. + {
  27055. + mvOsIoCachedFree(cesaTestOSHandle,cesaReqBufs[i].bufSize,
  27056. + cesaReqBufs[i].bufPhysAddr,cesaReqBufs[i].bufVirtPtr,
  27057. + cesaReqBufs[i].memHandle);
  27058. + }
  27059. + cesaDataHexStr3[0] = '\0';
  27060. +}
  27061. +
  27062. +void desTest(int iter, int reqSize, int checkMode)
  27063. +{
  27064. + int mode, i;
  27065. + MV_STATUS status;
  27066. +
  27067. + mode = checkMode;
  27068. + if(checkMode == CESA_FULL_CHECK_MODE)
  27069. + mode = CESA_FAST_CHECK_MODE;
  27070. + i = iter;
  27071. + if(mode != CESA_NULL_CHECK_MODE)
  27072. + i = 1;
  27073. +
  27074. + testOpen(0);
  27075. + testOpen(1);
  27076. + testOpen(2);
  27077. + testOpen(3);
  27078. +
  27079. +/* DES / ECB mode / Encrypt only */
  27080. + status = testRun(0, 1, iter, reqSize, checkMode);
  27081. + printTestResults(0, status, checkMode);
  27082. +
  27083. +/* DES / ECB mode / Decrypt only */
  27084. + status = testRun(1, 1, iter, reqSize, checkMode);
  27085. + printTestResults(1, status, checkMode);
  27086. +
  27087. +/* DES / CBC mode / Encrypt only */
  27088. + status = testRun(2, 2, i, reqSize, mode);
  27089. + printTestResults(2, status, mode);
  27090. +
  27091. +/* DES / CBC mode / Decrypt only */
  27092. + status = testRun(3, 2, iter, reqSize, mode);
  27093. + printTestResults(3, status, mode);
  27094. +
  27095. + testClose(0);
  27096. + testClose(1);
  27097. + testClose(2);
  27098. + testClose(3);
  27099. +}
  27100. +
  27101. +void tripleDesTest(int iter, int reqSize, int checkMode)
  27102. +{
  27103. + int mode, i;
  27104. + MV_STATUS status;
  27105. +
  27106. + mode = checkMode;
  27107. + if(checkMode == CESA_FULL_CHECK_MODE)
  27108. + mode = CESA_FAST_CHECK_MODE;
  27109. + i = iter;
  27110. + if(mode != CESA_NULL_CHECK_MODE)
  27111. + i = 1;
  27112. +
  27113. + testOpen(100);
  27114. + testOpen(101);
  27115. + testOpen(102);
  27116. + testOpen(103);
  27117. +
  27118. +/* 3DES / ECB mode / Encrypt only */
  27119. + status = testRun(100, 1, iter, reqSize, checkMode);
  27120. + printTestResults(100, status, checkMode);
  27121. +
  27122. +/* 3DES / ECB mode / Decrypt only */
  27123. + status = testRun(101, 1, iter, reqSize, checkMode);
  27124. + printTestResults(101, status, checkMode);
  27125. +
  27126. +/* 3DES / CBC mode / Encrypt only */
  27127. + status = testRun(102, 2, i, reqSize, mode);
  27128. + printTestResults(102, status, mode);
  27129. +
  27130. +/* 3DES / CBC mode / Decrypt only */
  27131. + status = testRun(103, 2, iter, reqSize, mode);
  27132. + printTestResults(103, status, mode);
  27133. +
  27134. + testClose(100);
  27135. + testClose(101);
  27136. + testClose(102);
  27137. + testClose(103);
  27138. +}
  27139. +
  27140. +void aesTest(int iter, int reqSize, int checkMode)
  27141. +{
  27142. + MV_STATUS status;
  27143. + int mode, i;
  27144. +
  27145. + mode = checkMode;
  27146. + if(checkMode == CESA_FULL_CHECK_MODE)
  27147. + mode = CESA_FAST_CHECK_MODE;
  27148. +
  27149. + i = iter;
  27150. + if(mode != CESA_NULL_CHECK_MODE)
  27151. + i = 1;
  27152. +
  27153. + testOpen(200);
  27154. + testOpen(201);
  27155. + testOpen(202);
  27156. + testOpen(203);
  27157. + testOpen(204);
  27158. + testOpen(205);
  27159. + testOpen(206);
  27160. + testOpen(207);
  27161. + testOpen(208);
  27162. +
  27163. +/* AES-128 Encode ECB mode */
  27164. + status = testRun(200, 3, iter, reqSize, checkMode);
  27165. + printTestResults(200, status, checkMode);
  27166. +
  27167. +/* AES-128 Decode ECB mode */
  27168. + status = testRun(201, 3, iter, reqSize, checkMode);
  27169. + printTestResults(201, status, checkMode);
  27170. +
  27171. +/* AES-128 Encode CBC mode (IV from SA) */
  27172. + status = testRun(202, 10, i, reqSize, mode);
  27173. + printTestResults(202, status, mode);
  27174. +
  27175. +/* AES-128 Encode CBC mode (IV from User) */
  27176. + status = testRun(202, 24, i, reqSize, mode);
  27177. + printTestResults(202, status, mode);
  27178. +
  27179. +/* AES-128 Decode CBC mode */
  27180. + status = testRun(203, 24, iter, reqSize, mode);
  27181. + printTestResults(203, status, checkMode);
  27182. +
  27183. +/* AES-192 Encode ECB mode */
  27184. + status = testRun(204, 4, iter, reqSize, checkMode);
  27185. + printTestResults(204, status, checkMode);
  27186. +
  27187. +/* AES-192 Decode ECB mode */
  27188. + status = testRun(205, 4, iter, reqSize, checkMode);
  27189. + printTestResults(205, status, checkMode);
  27190. +
  27191. +/* AES-256 Encode ECB mode */
  27192. + status = testRun(206, 5, iter, reqSize, checkMode);
  27193. + printTestResults(206, status, checkMode);
  27194. +
  27195. +/* AES-256 Decode ECB mode */
  27196. + status = testRun(207, 5, iter, reqSize, checkMode);
  27197. + printTestResults(207, status, checkMode);
  27198. +
  27199. +#if defined(MV_LINUX)
  27200. +/* AES-128 Encode CTR mode */
  27201. + status = testRun(208, 23, iter, reqSize, mode);
  27202. + printTestResults(208, status, checkMode);
  27203. +#endif
  27204. + testClose(200);
  27205. + testClose(201);
  27206. + testClose(202);
  27207. + testClose(203);
  27208. + testClose(204);
  27209. + testClose(205);
  27210. + testClose(206);
  27211. + testClose(207);
  27212. + testClose(208);
  27213. +}
  27214. +
  27215. +
  27216. +void mdTest(int iter, int reqSize, int checkMode)
  27217. +{
  27218. + int mode;
  27219. + MV_STATUS status;
  27220. +
  27221. + if(iter == 0)
  27222. + iter = CESA_DEF_ITER_NUM;
  27223. +
  27224. + mode = checkMode;
  27225. + if(checkMode == CESA_FULL_CHECK_MODE)
  27226. + mode = CESA_FAST_CHECK_MODE;
  27227. +
  27228. + testOpen(300);
  27229. + testOpen(301);
  27230. + testOpen(302);
  27231. + testOpen(303);
  27232. + testOpen(305);
  27233. +
  27234. +/* HMAC-MD5 Generate signature test */
  27235. + status = testRun(300, 6, iter, reqSize, mode);
  27236. + printTestResults(300, status, checkMode);
  27237. +
  27238. +/* HMAC-MD5 Verify Signature test */
  27239. + status = testRun(301, 7, iter, reqSize, mode);
  27240. + printTestResults(301, status, checkMode);
  27241. +
  27242. +/* HMAC-MD5 Generate signature test */
  27243. + status = testRun(302, 8, iter, reqSize, mode);
  27244. + printTestResults(302, status, checkMode);
  27245. +
  27246. +/* HMAC-MD5 Verify Signature test */
  27247. + status = testRun(303, 9, iter, reqSize, mode);
  27248. + printTestResults(303, status, checkMode);
  27249. +
  27250. +/* HASH-MD5 Generate signature test */
  27251. + status = testRun(305, 15, iter, reqSize, mode);
  27252. + printTestResults(305, status, checkMode);
  27253. +
  27254. + testClose(300);
  27255. + testClose(301);
  27256. + testClose(302);
  27257. + testClose(303);
  27258. + testClose(305);
  27259. +}
  27260. +
  27261. +void shaTest(int iter, int reqSize, int checkMode)
  27262. +{
  27263. + int mode;
  27264. + MV_STATUS status;
  27265. +
  27266. + if(iter == 0)
  27267. + iter = CESA_DEF_ITER_NUM;
  27268. +
  27269. + mode = checkMode;
  27270. + if(checkMode == CESA_FULL_CHECK_MODE)
  27271. + mode = CESA_FAST_CHECK_MODE;
  27272. +
  27273. + testOpen(400);
  27274. + testOpen(401);
  27275. + testOpen(402);
  27276. + testOpen(403);
  27277. + testOpen(405);
  27278. +
  27279. +/* HMAC-SHA1 Generate signature test */
  27280. + status = testRun(400, 11, iter, reqSize, mode);
  27281. + printTestResults(400, status, checkMode);
  27282. +
  27283. +/* HMAC-SHA1 Verify Signature test */
  27284. + status = testRun(401, 12, iter, reqSize, mode);
  27285. + printTestResults(401, status, checkMode);
  27286. +
  27287. +/* HMAC-SHA1 Generate signature test */
  27288. + status = testRun(402, 13, iter, reqSize, mode);
  27289. + printTestResults(402, status, checkMode);
  27290. +
  27291. +/* HMAC-SHA1 Verify Signature test */
  27292. + status = testRun(403, 14, iter, reqSize, mode);
  27293. + printTestResults(403, status, checkMode);
  27294. +
  27295. +/* HMAC-SHA1 Generate signature test */
  27296. + status = testRun(405, 16, iter, reqSize, mode);
  27297. + printTestResults(405, status, checkMode);
  27298. +
  27299. + testClose(400);
  27300. + testClose(401);
  27301. + testClose(402);
  27302. + testClose(403);
  27303. + testClose(405);
  27304. +}
  27305. +
  27306. +void combiTest(int iter, int reqSize, int checkMode)
  27307. +{
  27308. + MV_STATUS status;
  27309. + int mode, i;
  27310. +
  27311. + mode = checkMode;
  27312. + if(checkMode == CESA_FULL_CHECK_MODE)
  27313. + mode = CESA_FAST_CHECK_MODE;
  27314. +
  27315. + if(iter == 0)
  27316. + iter = CESA_DEF_ITER_NUM;
  27317. +
  27318. + i = iter;
  27319. + if(mode != CESA_NULL_CHECK_MODE)
  27320. + i = 1;
  27321. +
  27322. + testOpen(500);
  27323. + testOpen(501);
  27324. + testOpen(502);
  27325. + testOpen(503);
  27326. + testOpen(504);
  27327. + testOpen(505);
  27328. + testOpen(506);
  27329. + testOpen(507);
  27330. +
  27331. +/* DES ECB + MD5 encode test */
  27332. + status = testRun(500, 17, iter, reqSize, mode);
  27333. + printTestResults(500, status, mode);
  27334. +
  27335. +/* DES ECB + SHA1 encode test */
  27336. + status = testRun(501, 18, iter, reqSize, mode);
  27337. + printTestResults(501, status, mode);
  27338. +
  27339. +/* 3DES ECB + MD5 encode test */
  27340. + status = testRun(502, 17, iter, reqSize, mode);
  27341. + printTestResults(502, status, mode);
  27342. +
  27343. +/* 3DES ECB + SHA1 encode test */
  27344. + status = testRun(503, 18, iter, reqSize, mode);
  27345. + printTestResults(503, status, mode);
  27346. +
  27347. +/* 3DES CBC + MD5 encode test */
  27348. + status = testRun(504, 19, i, reqSize, mode);
  27349. + printTestResults(504, status, mode);
  27350. +
  27351. +/* 3DES CBC + SHA1 encode test */
  27352. + status = testRun(505, 20, i, reqSize, mode);
  27353. + printTestResults(505, status, mode);
  27354. +
  27355. +/* AES-128 CBC + MD5 encode test */
  27356. + status = testRun(506, 21, i, reqSize, mode);
  27357. + printTestResults(506, status, mode);
  27358. +
  27359. +/* AES-128 CBC + SHA1 encode test */
  27360. + status = testRun(507, 22, i, reqSize, mode);
  27361. + printTestResults(507, status, mode);
  27362. +
  27363. + testClose(500);
  27364. + testClose(501);
  27365. + testClose(502);
  27366. + testClose(503);
  27367. + testClose(504);
  27368. + testClose(505);
  27369. + testClose(506);
  27370. + testClose(507);
  27371. +}
  27372. +
  27373. +void cesaOneTest(int testIdx, int caseIdx,
  27374. + int iter, int reqSize, int checkMode)
  27375. +{
  27376. + MV_STATUS status;
  27377. +
  27378. + if(iter == 0)
  27379. + iter = CESA_DEF_ITER_NUM;
  27380. +
  27381. + mvOsPrintf("test=%d, case=%d, size=%d, iter=%d\n",
  27382. + testIdx, caseIdx, reqSize, iter);
  27383. +
  27384. + status = testOpen(testIdx);
  27385. +
  27386. + status = testRun(testIdx, caseIdx, iter, reqSize, checkMode);
  27387. + printTestResults(testIdx, status, checkMode);
  27388. + status = testClose(testIdx);
  27389. +
  27390. +}
  27391. +
  27392. +void cesaTest(int iter, int reqSize, int checkMode)
  27393. +{
  27394. + if(iter == 0)
  27395. + iter = CESA_DEF_ITER_NUM;
  27396. +
  27397. + mvOsPrintf("%d iteration\n", iter);
  27398. + mvOsPrintf("%d size\n\n", reqSize);
  27399. +
  27400. +/* DES tests */
  27401. + desTest(iter, reqSize, checkMode);
  27402. +
  27403. +/* 3DES tests */
  27404. + tripleDesTest(iter, reqSize, checkMode);
  27405. +
  27406. +/* AES tests */
  27407. + aesTest(iter, reqSize, checkMode);
  27408. +
  27409. +/* MD5 tests */
  27410. + mdTest(iter, reqSize, checkMode);
  27411. +
  27412. +/* SHA-1 tests */
  27413. + shaTest(iter, reqSize, checkMode);
  27414. +}
  27415. +
  27416. +void multiSizeTest(int idx, int iter, int checkMode, char* inputData)
  27417. +{
  27418. + MV_STATUS status;
  27419. + int i;
  27420. + MV_CESA_SIZE_TEST* pMultiTest;
  27421. +
  27422. + if( testOpen(idx) != MV_OK)
  27423. + return;
  27424. +
  27425. + if(iter == 0)
  27426. + iter = CESA_DEF_ITER_NUM;
  27427. +
  27428. + if(checkMode == CESA_SHOW_CHECK_MODE)
  27429. + {
  27430. + iter = 1;
  27431. + }
  27432. + else
  27433. + checkMode = CESA_FULL_CHECK_MODE;
  27434. +
  27435. + cesaTestCases[0].plainHexStr = inputData;
  27436. + cesaTestCases[0].pCryptoIV = NULL;
  27437. +
  27438. + switch(idx)
  27439. + {
  27440. + case 302:
  27441. + pMultiTest = mdMultiSizeTest302;
  27442. + if(inputData == NULL)
  27443. + cesaTestCases[0].plainHexStr = cesaDataHexStr3;
  27444. + break;
  27445. +
  27446. + case 304:
  27447. + pMultiTest = mdMultiSizeTest304;
  27448. + if(inputData == NULL)
  27449. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27450. + break;
  27451. +
  27452. + case 305:
  27453. + pMultiTest = mdMultiSizeTest305;
  27454. + if(inputData == NULL)
  27455. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27456. + break;
  27457. +
  27458. + case 402:
  27459. + pMultiTest = shaMultiSizeTest402;
  27460. + if(inputData == NULL)
  27461. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27462. + break;
  27463. +
  27464. + case 404:
  27465. + pMultiTest = shaMultiSizeTest404;
  27466. + if(inputData == NULL)
  27467. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27468. + break;
  27469. +
  27470. + case 405:
  27471. + pMultiTest = shaMultiSizeTest405;
  27472. + if(inputData == NULL)
  27473. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27474. + break;
  27475. +
  27476. + case 502:
  27477. + pMultiTest = tripleDesMdMultiSizeTest502;
  27478. + if(inputData == NULL)
  27479. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27480. + break;
  27481. +
  27482. + case 503:
  27483. + pMultiTest = tripleDesShaMultiSizeTest503;
  27484. + if(inputData == NULL)
  27485. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27486. + break;
  27487. +
  27488. + case 504:
  27489. + iter = 1;
  27490. + pMultiTest = cbc3desMdMultiSizeTest504;
  27491. + cesaTestCases[0].pCryptoIV = iv1;
  27492. + if(inputData == NULL)
  27493. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27494. + break;
  27495. +
  27496. + case 505:
  27497. + iter = 1;
  27498. + pMultiTest = cbc3desShaMultiSizeTest505;
  27499. + cesaTestCases[0].pCryptoIV = iv1;
  27500. + if(inputData == NULL)
  27501. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27502. + break;
  27503. +
  27504. + case 506:
  27505. + iter = 1;
  27506. + pMultiTest = cbcAes128md5multiSizeTest506;
  27507. + cesaTestCases[0].pCryptoIV = iv5;
  27508. + if(inputData == NULL)
  27509. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27510. + break;
  27511. +
  27512. + case 507:
  27513. + iter = 1;
  27514. + pMultiTest = cbcAes128sha1multiSizeTest507;
  27515. + cesaTestCases[0].pCryptoIV = iv5;
  27516. + if(inputData == NULL)
  27517. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27518. + break;
  27519. +
  27520. + default:
  27521. + iter = 1;
  27522. + checkMode = CESA_SHOW_CHECK_MODE;
  27523. + pMultiTest = mdMultiSizeTest302;
  27524. + if(inputData == NULL)
  27525. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27526. + }
  27527. + i = 0;
  27528. + while(pMultiTest[i].outputHexStr != NULL)
  27529. + {
  27530. + cesaTestCases[0].cipherHexStr = (char *)pMultiTest[i].outputHexStr;
  27531. + status = testRun(idx, 0, iter, pMultiTest[i].size,
  27532. + checkMode);
  27533. + if(checkMode != CESA_SHOW_CHECK_MODE)
  27534. + {
  27535. + cesaReqSize = pMultiTest[i].size;
  27536. + printTestResults(idx, status, checkMode);
  27537. + }
  27538. + if(status != MV_OK)
  27539. + break;
  27540. + i++;
  27541. + }
  27542. + testClose(idx);
  27543. +/*
  27544. + mvCesaDebugStatus();
  27545. + cesaTestPrintStatus();
  27546. +*/
  27547. +}
  27548. +
  27549. +void open_session_test(int idx, int caseIdx, int iter)
  27550. +{
  27551. + int reqIdError, cryptoError, openErrors, i;
  27552. + int openErrDisp[100];
  27553. + MV_STATUS status;
  27554. +
  27555. + memset(openErrDisp, 0, sizeof(openErrDisp));
  27556. + openErrors = 0;
  27557. + reqIdError = 0;
  27558. + cryptoError = 0;
  27559. + for(i=0; i<iter; i++)
  27560. + {
  27561. + status = testOpen(idx);
  27562. + if(status != MV_OK)
  27563. + {
  27564. + openErrors++;
  27565. + openErrDisp[status]++;
  27566. + }
  27567. + else
  27568. + {
  27569. + testRun(idx, caseIdx, 1, 0, CESA_FAST_CHECK_MODE);
  27570. + if(cesaCryptoError > 0)
  27571. + cryptoError++;
  27572. + if(cesaReqIdError > 0)
  27573. + reqIdError++;
  27574. +
  27575. + testClose(idx);
  27576. + }
  27577. + }
  27578. + if(cryptoError > 0)
  27579. + mvOsPrintf("cryptoError : %d\n", cryptoError);
  27580. + if(reqIdError > 0)
  27581. + mvOsPrintf("reqIdError : %d\n", reqIdError);
  27582. +
  27583. + if(openErrors > 0)
  27584. + {
  27585. + mvOsPrintf("Open Errors = %d\n", openErrors);
  27586. + for(i=0; i<100; i++)
  27587. + {
  27588. + if(openErrDisp[i] != 0)
  27589. + mvOsPrintf("Error %d - occurs %d times\n", i, openErrDisp[i]);
  27590. + }
  27591. + }
  27592. +}
  27593. +
  27594. +
  27595. +void loopback_test(int idx, int iter, int size, char* pPlainData)
  27596. +{
  27597. +}
  27598. +
  27599. +
  27600. +#if defined(MV_VXWORKS)
  27601. +int testMode = 0;
  27602. +unsigned __TASKCONV cesaTask(void* args)
  27603. +{
  27604. + int reqSize = cesaReqSize;
  27605. +
  27606. + if(testMode == 0)
  27607. + {
  27608. + cesaOneTest(cesaTestIdx, cesaCaseIdx, cesaIteration,
  27609. + reqSize, cesaCheckMode);
  27610. + }
  27611. + else
  27612. + {
  27613. + if(testMode == 1)
  27614. + {
  27615. + cesaTest(cesaIteration, reqSize, cesaCheckMode);
  27616. + combiTest(cesaIteration, reqSize, cesaCheckMode);
  27617. + }
  27618. + else
  27619. + {
  27620. + multiSizeTest(cesaIdx, cesaIteration, cesaCheckMode, NULL);
  27621. + }
  27622. + }
  27623. + return 0;
  27624. +}
  27625. +
  27626. +void oneTest(int testIdx, int caseIdx,
  27627. + int iter, int reqSize, int checkMode)
  27628. +{
  27629. + long rc;
  27630. +
  27631. + cesaIteration = iter;
  27632. + cesaReqSize = cesaRateSize = reqSize;
  27633. + cesaCheckMode = checkMode;
  27634. + testMode = 0;
  27635. + cesaTestIdx = testIdx;
  27636. + cesaCaseIdx = caseIdx;
  27637. + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
  27638. + if (rc != MV_OK)
  27639. + {
  27640. + mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);
  27641. + }
  27642. +}
  27643. +
  27644. +void multiTest(int iter, int reqSize, int checkMode)
  27645. +{
  27646. + long rc;
  27647. +
  27648. + cesaIteration = iter;
  27649. + cesaCheckMode = checkMode;
  27650. + cesaReqSize = reqSize;
  27651. + testMode = 1;
  27652. + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
  27653. + if (rc != MV_OK)
  27654. + {
  27655. + mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);
  27656. + }
  27657. +}
  27658. +
  27659. +void sizeTest(int testIdx, int iter, int checkMode)
  27660. +{
  27661. + long rc;
  27662. +
  27663. + cesaIteration = iter;
  27664. + cesaCheckMode = checkMode;
  27665. + testMode = 2;
  27666. + cesaIdx = testIdx;
  27667. + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
  27668. + if (rc != MV_OK)
  27669. + {
  27670. + mvOsPrintf("hMW: Can't create CESA test task, rc = %ld\n", rc);
  27671. + }
  27672. +}
  27673. +
  27674. +#endif /* MV_VXWORKS */
  27675. +
  27676. +extern void mvCesaDebugSA(short sid, int mode);
  27677. +void cesaTestPrintSession(int idx)
  27678. +{
  27679. + int testIdx;
  27680. + MV_CESA_TEST_SESSION* pTestSession;
  27681. +
  27682. + pTestSession = getTestSessionDb(idx, &testIdx);
  27683. + if(pTestSession == NULL)
  27684. + {
  27685. + mvOsPrintf("Test %d is not exist\n", idx);
  27686. + return;
  27687. + }
  27688. + pTestSession = &pTestSession[testIdx];
  27689. +
  27690. + if(pTestSession->sid == -1)
  27691. + {
  27692. + mvOsPrintf("Test session %d is not opened\n", idx);
  27693. + return;
  27694. + }
  27695. +
  27696. + mvCesaDebugSA(pTestSession->sid, 1);
  27697. +}
  27698. +
  27699. +void cesaTestPrintStatus(void)
  27700. +{
  27701. + mvOsPrintf("\n\t Cesa Test Status\n\n");
  27702. +
  27703. + mvOsPrintf("isrCount=%d\n",
  27704. + cesaTestIsrCount);
  27705. +
  27706. +#ifdef CESA_TEST_DEBUG
  27707. + {
  27708. + int i, j;
  27709. + j = cesaTestTraceIdx;
  27710. + mvOsPrintf("No Type Cause rCause iCause Res Time pReady pProc pEmpty\n");
  27711. + for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)
  27712. + {
  27713. + mvOsPrintf("%02d. %d 0x%04x 0x%04x 0x%04x 0x%02x 0x%02x %02d 0x%06x %p %p %p\n",
  27714. + j, cesaTestTrace[j].type, cesaTestTrace[j].cause, cesaTestTrace[j].realCause,
  27715. + cesaTestTrace[j].dmaCause, cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,
  27716. + cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);
  27717. + j++;
  27718. + if(j == MV_CESA_TEST_TRACE_SIZE)
  27719. + j = 0;
  27720. + }
  27721. + }
  27722. +#endif /* CESA_TEST_DEBUG */
  27723. +}
  27724. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvLru.c linux-2.6.39/crypto/ocf/kirkwood/cesa/mvLru.c
  27725. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvLru.c 1970-01-01 01:00:00.000000000 +0100
  27726. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvLru.c 2011-07-31 11:31:55.133650609 +0200
  27727. @@ -0,0 +1,158 @@
  27728. +/*******************************************************************************
  27729. +Copyright (C) Marvell International Ltd. and its affiliates
  27730. +
  27731. +This software file (the "File") is owned and distributed by Marvell
  27732. +International Ltd. and/or its affiliates ("Marvell") under the following
  27733. +alternative licensing terms. Once you have made an election to distribute the
  27734. +File under one of the following license alternatives, please (i) delete this
  27735. +introductory statement regarding license alternatives, (ii) delete the two
  27736. +license alternatives that you have not elected to use and (iii) preserve the
  27737. +Marvell copyright notice above.
  27738. +
  27739. +********************************************************************************
  27740. +Marvell Commercial License Option
  27741. +
  27742. +If you received this File from Marvell and you have entered into a commercial
  27743. +license agreement (a "Commercial License") with Marvell, the File is licensed
  27744. +to you under the terms of the applicable Commercial License.
  27745. +
  27746. +********************************************************************************
  27747. +Marvell GPL License Option
  27748. +
  27749. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27750. +modify this File in accordance with the terms and conditions of the General
  27751. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  27752. +available along with the File in the license.txt file or by writing to the Free
  27753. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  27754. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  27755. +
  27756. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  27757. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  27758. +DISCLAIMED. The GPL License provides additional details about this warranty
  27759. +disclaimer.
  27760. +********************************************************************************
  27761. +Marvell BSD License Option
  27762. +
  27763. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27764. +modify this File under the following licensing terms.
  27765. +Redistribution and use in source and binary forms, with or without modification,
  27766. +are permitted provided that the following conditions are met:
  27767. +
  27768. + * Redistributions of source code must retain the above copyright notice,
  27769. + this list of conditions and the following disclaimer.
  27770. +
  27771. + * Redistributions in binary form must reproduce the above copyright
  27772. + notice, this list of conditions and the following disclaimer in the
  27773. + documentation and/or other materials provided with the distribution.
  27774. +
  27775. + * Neither the name of Marvell nor the names of its contributors may be
  27776. + used to endorse or promote products derived from this software without
  27777. + specific prior written permission.
  27778. +
  27779. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  27780. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  27781. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27782. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  27783. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27784. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27785. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  27786. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27787. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27788. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27789. +
  27790. +*******************************************************************************/
  27791. +
  27792. +#include "mvOs.h"
  27793. +#include "mvLru.h"
  27794. +/* LRU Cache support */
  27795. +
  27796. +
  27797. +/* Init LRU cache database */
  27798. +MV_LRU_CACHE* mvLruCacheInit(int numOfEntries)
  27799. +{
  27800. + int i;
  27801. + MV_LRU_CACHE* pLruCache;
  27802. +
  27803. + pLruCache = mvOsMalloc(sizeof(MV_LRU_CACHE));
  27804. + if(pLruCache == NULL)
  27805. + {
  27806. + return NULL;
  27807. + }
  27808. + memset(pLruCache, 0, sizeof(MV_LRU_CACHE));
  27809. +
  27810. + pLruCache->table = mvOsMalloc(numOfEntries*sizeof(MV_LRU_ENTRY));
  27811. + if(pLruCache->table == NULL)
  27812. + {
  27813. + mvOsFree(pLruCache);
  27814. + return NULL;
  27815. + }
  27816. + memset(pLruCache->table, 0, numOfEntries*sizeof(MV_LRU_ENTRY));
  27817. + pLruCache->tableSize = numOfEntries;
  27818. +
  27819. + for(i=0; i<numOfEntries; i++)
  27820. + {
  27821. + pLruCache->table[i].next = i+1;
  27822. + pLruCache->table[i].prev = i-1;
  27823. + }
  27824. + pLruCache->least = 0;
  27825. + pLruCache->most = numOfEntries-1;
  27826. +
  27827. + return pLruCache;
  27828. +}
  27829. +
  27830. +void mvLruCacheFinish(MV_LRU_CACHE* pLruCache)
  27831. +{
  27832. + mvOsFree(pLruCache->table);
  27833. + mvOsFree(pLruCache);
  27834. +}
  27835. +
  27836. +/* Update LRU cache database after using cache Index */
  27837. +void mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx)
  27838. +{
  27839. + int prev, next;
  27840. +
  27841. + if(cacheIdx == pLruHndl->most)
  27842. + return;
  27843. +
  27844. + next = pLruHndl->table[cacheIdx].next;
  27845. + if(cacheIdx == pLruHndl->least)
  27846. + {
  27847. + pLruHndl->least = next;
  27848. + }
  27849. + else
  27850. + {
  27851. + prev = pLruHndl->table[cacheIdx].prev;
  27852. +
  27853. + pLruHndl->table[next].prev = prev;
  27854. + pLruHndl->table[prev].next = next;
  27855. + }
  27856. +
  27857. + pLruHndl->table[pLruHndl->most].next = cacheIdx;
  27858. + pLruHndl->table[cacheIdx].prev = pLruHndl->most;
  27859. + pLruHndl->most = cacheIdx;
  27860. +}
  27861. +
  27862. +/* Delete LRU cache entry */
  27863. +void mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx)
  27864. +{
  27865. + int prev, next;
  27866. +
  27867. + if(cacheIdx == pLruHndl->least)
  27868. + return;
  27869. +
  27870. + prev = pLruHndl->table[cacheIdx].prev;
  27871. + if(cacheIdx == pLruHndl->most)
  27872. + {
  27873. + pLruHndl->most = prev;
  27874. + }
  27875. + else
  27876. + {
  27877. + next = pLruHndl->table[cacheIdx].next;
  27878. +
  27879. + pLruHndl->table[next].prev = prev;
  27880. + pLruHndl->table[prev].next = next;
  27881. + }
  27882. + pLruHndl->table[pLruHndl->least].prev = cacheIdx;
  27883. + pLruHndl->table[cacheIdx].next = pLruHndl->least;
  27884. + pLruHndl->least = cacheIdx;
  27885. +}
  27886. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvLru.h linux-2.6.39/crypto/ocf/kirkwood/cesa/mvLru.h
  27887. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvLru.h 1970-01-01 01:00:00.000000000 +0100
  27888. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvLru.h 2011-07-31 11:31:55.193969642 +0200
  27889. @@ -0,0 +1,112 @@
  27890. +/*******************************************************************************
  27891. +Copyright (C) Marvell International Ltd. and its affiliates
  27892. +
  27893. +This software file (the "File") is owned and distributed by Marvell
  27894. +International Ltd. and/or its affiliates ("Marvell") under the following
  27895. +alternative licensing terms. Once you have made an election to distribute the
  27896. +File under one of the following license alternatives, please (i) delete this
  27897. +introductory statement regarding license alternatives, (ii) delete the two
  27898. +license alternatives that you have not elected to use and (iii) preserve the
  27899. +Marvell copyright notice above.
  27900. +
  27901. +********************************************************************************
  27902. +Marvell Commercial License Option
  27903. +
  27904. +If you received this File from Marvell and you have entered into a commercial
  27905. +license agreement (a "Commercial License") with Marvell, the File is licensed
  27906. +to you under the terms of the applicable Commercial License.
  27907. +
  27908. +********************************************************************************
  27909. +Marvell GPL License Option
  27910. +
  27911. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27912. +modify this File in accordance with the terms and conditions of the General
  27913. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  27914. +available along with the File in the license.txt file or by writing to the Free
  27915. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  27916. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  27917. +
  27918. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  27919. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  27920. +DISCLAIMED. The GPL License provides additional details about this warranty
  27921. +disclaimer.
  27922. +********************************************************************************
  27923. +Marvell BSD License Option
  27924. +
  27925. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27926. +modify this File under the following licensing terms.
  27927. +Redistribution and use in source and binary forms, with or without modification,
  27928. +are permitted provided that the following conditions are met:
  27929. +
  27930. + * Redistributions of source code must retain the above copyright notice,
  27931. + this list of conditions and the following disclaimer.
  27932. +
  27933. + * Redistributions in binary form must reproduce the above copyright
  27934. + notice, this list of conditions and the following disclaimer in the
  27935. + documentation and/or other materials provided with the distribution.
  27936. +
  27937. + * Neither the name of Marvell nor the names of its contributors may be
  27938. + used to endorse or promote products derived from this software without
  27939. + specific prior written permission.
  27940. +
  27941. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  27942. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  27943. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27944. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  27945. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27946. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27947. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  27948. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27949. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27950. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27951. +
  27952. +*******************************************************************************/
  27953. +/*******************************************************************************
  27954. +* mvLru.h - Header File for Least Recently Used Cache algorithm
  27955. +*
  27956. +* DESCRIPTION:
  27957. +* This header file contains macros typedefs and function declaration for
  27958. +* the Least Recently Used Cache algorithm.
  27959. +*
  27960. +*******************************************************************************/
  27961. +
  27962. +#ifndef __mvLru_h__
  27963. +#define __mvLru_h__
  27964. +
  27965. +
  27966. +typedef struct
  27967. +{
  27968. + int next;
  27969. + int prev;
  27970. +} MV_LRU_ENTRY;
  27971. +
  27972. +typedef struct
  27973. +{
  27974. + int least;
  27975. + int most;
  27976. + MV_LRU_ENTRY* table;
  27977. + int tableSize;
  27978. +
  27979. +}MV_LRU_CACHE;
  27980. +
  27981. +
  27982. +/* Find Cache index for replacement LRU */
  27983. +static INLINE int mvLruCacheIdxFind(MV_LRU_CACHE* pLruHndl)
  27984. +{
  27985. + return pLruHndl->least;
  27986. +}
  27987. +
  27988. +/* Init LRU cache module */
  27989. +MV_LRU_CACHE* mvLruCacheInit(int numOfEntries);
  27990. +
  27991. +/* Finish LRU cache module */
  27992. +void mvLruCacheFinish(MV_LRU_CACHE* pLruHndl);
  27993. +
  27994. +/* Update LRU cache database after using cache Index */
  27995. +void mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx);
  27996. +
  27997. +/* Delete LRU cache entry */
  27998. +void mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx);
  27999. +
  28000. +
  28001. +#endif /* __mvLru_h__ */
  28002. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvMD5.c linux-2.6.39/crypto/ocf/kirkwood/cesa/mvMD5.c
  28003. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvMD5.c 1970-01-01 01:00:00.000000000 +0100
  28004. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvMD5.c 2011-07-31 11:31:55.223415204 +0200
  28005. @@ -0,0 +1,349 @@
  28006. +/*******************************************************************************
  28007. +Copyright (C) Marvell International Ltd. and its affiliates
  28008. +
  28009. +This software file (the "File") is owned and distributed by Marvell
  28010. +International Ltd. and/or its affiliates ("Marvell") under the following
  28011. +alternative licensing terms. Once you have made an election to distribute the
  28012. +File under one of the following license alternatives, please (i) delete this
  28013. +introductory statement regarding license alternatives, (ii) delete the two
  28014. +license alternatives that you have not elected to use and (iii) preserve the
  28015. +Marvell copyright notice above.
  28016. +
  28017. +********************************************************************************
  28018. +Marvell Commercial License Option
  28019. +
  28020. +If you received this File from Marvell and you have entered into a commercial
  28021. +license agreement (a "Commercial License") with Marvell, the File is licensed
  28022. +to you under the terms of the applicable Commercial License.
  28023. +
  28024. +********************************************************************************
  28025. +Marvell GPL License Option
  28026. +
  28027. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28028. +modify this File in accordance with the terms and conditions of the General
  28029. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  28030. +available along with the File in the license.txt file or by writing to the Free
  28031. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  28032. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  28033. +
  28034. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  28035. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  28036. +DISCLAIMED. The GPL License provides additional details about this warranty
  28037. +disclaimer.
  28038. +********************************************************************************
  28039. +Marvell BSD License Option
  28040. +
  28041. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28042. +modify this File under the following licensing terms.
  28043. +Redistribution and use in source and binary forms, with or without modification,
  28044. +are permitted provided that the following conditions are met:
  28045. +
  28046. + * Redistributions of source code must retain the above copyright notice,
  28047. + this list of conditions and the following disclaimer.
  28048. +
  28049. + * Redistributions in binary form must reproduce the above copyright
  28050. + notice, this list of conditions and the following disclaimer in the
  28051. + documentation and/or other materials provided with the distribution.
  28052. +
  28053. + * Neither the name of Marvell nor the names of its contributors may be
  28054. + used to endorse or promote products derived from this software without
  28055. + specific prior written permission.
  28056. +
  28057. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  28058. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  28059. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  28060. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  28061. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28062. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28063. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  28064. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28065. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28066. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28067. +
  28068. +*******************************************************************************/
  28069. +
  28070. +#include "mvOs.h"
  28071. +#include "mvMD5.h"
  28072. +
  28073. +static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN]);
  28074. +
  28075. +#ifdef MV_CPU_LE
  28076. +#define mvByteReverse(buf, len) /* Nothing */
  28077. +#else
  28078. +static void mvByteReverse(unsigned char *buf, unsigned longs);
  28079. +
  28080. +/*
  28081. + * Note: this code is harmless on little-endian machines.
  28082. + */
  28083. +static void mvByteReverse(unsigned char *buf, unsigned longs)
  28084. +{
  28085. + MV_U32 t;
  28086. +
  28087. + do
  28088. + {
  28089. + t = (MV_U32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
  28090. + ((unsigned) buf[1] << 8 | buf[0]);
  28091. + *(MV_U32 *) buf = t;
  28092. + buf += 4;
  28093. + } while (--longs);
  28094. +}
  28095. +#endif
  28096. +
  28097. +/*
  28098. + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
  28099. + * initialization constants.
  28100. + */
  28101. +void mvMD5Init(MV_MD5_CONTEXT *ctx)
  28102. +{
  28103. + ctx->buf[0] = 0x67452301;
  28104. + ctx->buf[1] = 0xefcdab89;
  28105. + ctx->buf[2] = 0x98badcfe;
  28106. + ctx->buf[3] = 0x10325476;
  28107. +
  28108. + ctx->bits[0] = 0;
  28109. + ctx->bits[1] = 0;
  28110. +}
  28111. +
  28112. +/*
  28113. + * Update context to reflect the concatenation of another buffer full
  28114. + * of bytes.
  28115. + */
  28116. +void mvMD5Update(MV_MD5_CONTEXT *ctx, unsigned char const *buf, unsigned len)
  28117. +{
  28118. + MV_U32 t;
  28119. +
  28120. + /* Update bitcount */
  28121. +
  28122. + t = ctx->bits[0];
  28123. + if ((ctx->bits[0] = t + ((MV_U32) len << 3)) < t)
  28124. + ctx->bits[1]++; /* Carry from low to high */
  28125. + ctx->bits[1] += len >> 29;
  28126. +
  28127. + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
  28128. +
  28129. + /* Handle any leading odd-sized chunks */
  28130. +
  28131. + if (t)
  28132. + {
  28133. + unsigned char *p = (unsigned char *) ctx->in + t;
  28134. +
  28135. + t = 64 - t;
  28136. + if (len < t)
  28137. + {
  28138. + memcpy(p, buf, len);
  28139. + return;
  28140. + }
  28141. + memcpy(p, buf, t);
  28142. + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
  28143. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  28144. + buf += t;
  28145. + len -= t;
  28146. + }
  28147. + /* Process data in 64-byte chunks */
  28148. +
  28149. + while (len >= 64)
  28150. + {
  28151. + memcpy(ctx->in, buf, 64);
  28152. + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
  28153. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  28154. + buf += 64;
  28155. + len -= 64;
  28156. + }
  28157. +
  28158. + /* Handle any remaining bytes of data. */
  28159. +
  28160. + memcpy(ctx->in, buf, len);
  28161. +}
  28162. +
  28163. +/*
  28164. + * Final wrapup - pad to 64-byte boundary with the bit pattern
  28165. + * 1 0* (64-bit count of bits processed, MSB-first)
  28166. + */
  28167. +void mvMD5Final(unsigned char digest[MV_MD5_MAC_LEN], MV_MD5_CONTEXT *ctx)
  28168. +{
  28169. + unsigned count;
  28170. + unsigned char *p;
  28171. +
  28172. + /* Compute number of bytes mod 64 */
  28173. + count = (ctx->bits[0] >> 3) & 0x3F;
  28174. +
  28175. + /* Set the first char of padding to 0x80. This is safe since there is
  28176. + always at least one byte free */
  28177. + p = ctx->in + count;
  28178. + *p++ = 0x80;
  28179. +
  28180. + /* Bytes of padding needed to make 64 bytes */
  28181. + count = 64 - 1 - count;
  28182. +
  28183. + /* Pad out to 56 mod 64 */
  28184. + if (count < 8)
  28185. + {
  28186. + /* Two lots of padding: Pad the first block to 64 bytes */
  28187. + memset(p, 0, count);
  28188. + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
  28189. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  28190. +
  28191. + /* Now fill the next block with 56 bytes */
  28192. + memset(ctx->in, 0, 56);
  28193. + }
  28194. + else
  28195. + {
  28196. + /* Pad block to 56 bytes */
  28197. + memset(p, 0, count - 8);
  28198. + }
  28199. + mvByteReverse(ctx->in, 14);
  28200. +
  28201. + /* Append length in bits and transform */
  28202. + ((MV_U32 *) ctx->in)[14] = ctx->bits[0];
  28203. + ((MV_U32 *) ctx->in)[15] = ctx->bits[1];
  28204. +
  28205. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  28206. + mvByteReverse((unsigned char *) ctx->buf, 4);
  28207. + memcpy(digest, ctx->buf, MV_MD5_MAC_LEN);
  28208. + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
  28209. +}
  28210. +
  28211. +/* The four core functions - F1 is optimized somewhat */
  28212. +
  28213. +/* #define F1(x, y, z) (x & y | ~x & z) */
  28214. +#define F1(x, y, z) (z ^ (x & (y ^ z)))
  28215. +#define F2(x, y, z) F1(z, x, y)
  28216. +#define F3(x, y, z) (x ^ y ^ z)
  28217. +#define F4(x, y, z) (y ^ (x | ~z))
  28218. +
  28219. +/* This is the central step in the MD5 algorithm. */
  28220. +#define MD5STEP(f, w, x, y, z, data, s) \
  28221. + ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
  28222. +
  28223. +/*
  28224. + * The core of the MD5 algorithm, this alters an existing MD5 hash to
  28225. + * reflect the addition of 16 longwords of new data. MD5Update blocks
  28226. + * the data and converts bytes into longwords for this routine.
  28227. + */
  28228. +static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN])
  28229. +{
  28230. + register MV_U32 a, b, c, d;
  28231. +
  28232. + a = buf[0];
  28233. + b = buf[1];
  28234. + c = buf[2];
  28235. + d = buf[3];
  28236. +
  28237. + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
  28238. + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
  28239. + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
  28240. + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
  28241. + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
  28242. + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
  28243. + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
  28244. + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
  28245. + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
  28246. + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
  28247. + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
  28248. + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
  28249. + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
  28250. + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
  28251. + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
  28252. + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
  28253. +
  28254. + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
  28255. + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
  28256. + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
  28257. + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
  28258. + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
  28259. + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
  28260. + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
  28261. + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
  28262. + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
  28263. + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
  28264. + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
  28265. + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
  28266. + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
  28267. + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
  28268. + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
  28269. + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
  28270. +
  28271. + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
  28272. + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
  28273. + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
  28274. + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
  28275. + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
  28276. + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
  28277. + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
  28278. + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
  28279. + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
  28280. + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
  28281. + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
  28282. + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
  28283. + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
  28284. + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
  28285. + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
  28286. + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
  28287. +
  28288. + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
  28289. + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
  28290. + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
  28291. + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
  28292. + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
  28293. + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
  28294. + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
  28295. + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
  28296. + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
  28297. + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
  28298. + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
  28299. + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
  28300. + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
  28301. + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
  28302. + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
  28303. + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
  28304. +
  28305. + buf[0] += a;
  28306. + buf[1] += b;
  28307. + buf[2] += c;
  28308. + buf[3] += d;
  28309. +}
  28310. +
  28311. +void mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest)
  28312. +{
  28313. + MV_MD5_CONTEXT ctx;
  28314. +
  28315. + mvMD5Init(&ctx);
  28316. + mvMD5Update(&ctx, buf, len);
  28317. + mvMD5Final(digest, &ctx);
  28318. +}
  28319. +
  28320. +
  28321. +void mvHmacMd5(unsigned char const* text, int text_len,
  28322. + unsigned char const* key, int key_len,
  28323. + unsigned char* digest)
  28324. +{
  28325. + int i;
  28326. + MV_MD5_CONTEXT ctx;
  28327. + unsigned char k_ipad[64+1]; /* inner padding - key XORd with ipad */
  28328. + unsigned char k_opad[64+1]; /* outer padding - key XORd with opad */
  28329. +
  28330. + /* start out by storing key in pads */
  28331. + memset(k_ipad, 0, 64);
  28332. + memcpy(k_ipad, key, key_len);
  28333. + memset(k_opad, 0, 64);
  28334. + memcpy(k_opad, key, key_len);
  28335. +
  28336. + /* XOR key with ipad and opad values */
  28337. + for (i=0; i<64; i++)
  28338. + {
  28339. + k_ipad[i] ^= 0x36;
  28340. + k_opad[i] ^= 0x5c;
  28341. + }
  28342. +
  28343. + /* perform inner MD5 */
  28344. + mvMD5Init(&ctx); /* init ctx for 1st pass */
  28345. + mvMD5Update(&ctx, k_ipad, 64); /* start with inner pad */
  28346. + mvMD5Update(&ctx, text, text_len); /* then text of datagram */
  28347. + mvMD5Final(digest, &ctx); /* finish up 1st pass */
  28348. +
  28349. + /* perform outer MD5 */
  28350. + mvMD5Init(&ctx); /* init ctx for 2nd pass */
  28351. + mvMD5Update(&ctx, k_opad, 64); /* start with outer pad */
  28352. + mvMD5Update(&ctx, digest, 16); /* then results of 1st hash */
  28353. + mvMD5Final(digest, &ctx); /* finish up 2nd pass */
  28354. +}
  28355. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvMD5.h linux-2.6.39/crypto/ocf/kirkwood/cesa/mvMD5.h
  28356. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvMD5.h 1970-01-01 01:00:00.000000000 +0100
  28357. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvMD5.h 2011-07-31 11:31:55.263415027 +0200
  28358. @@ -0,0 +1,93 @@
  28359. +/*******************************************************************************
  28360. +Copyright (C) Marvell International Ltd. and its affiliates
  28361. +
  28362. +This software file (the "File") is owned and distributed by Marvell
  28363. +International Ltd. and/or its affiliates ("Marvell") under the following
  28364. +alternative licensing terms. Once you have made an election to distribute the
  28365. +File under one of the following license alternatives, please (i) delete this
  28366. +introductory statement regarding license alternatives, (ii) delete the two
  28367. +license alternatives that you have not elected to use and (iii) preserve the
  28368. +Marvell copyright notice above.
  28369. +
  28370. +********************************************************************************
  28371. +Marvell Commercial License Option
  28372. +
  28373. +If you received this File from Marvell and you have entered into a commercial
  28374. +license agreement (a "Commercial License") with Marvell, the File is licensed
  28375. +to you under the terms of the applicable Commercial License.
  28376. +
  28377. +********************************************************************************
  28378. +Marvell GPL License Option
  28379. +
  28380. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28381. +modify this File in accordance with the terms and conditions of the General
  28382. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  28383. +available along with the File in the license.txt file or by writing to the Free
  28384. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  28385. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  28386. +
  28387. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  28388. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  28389. +DISCLAIMED. The GPL License provides additional details about this warranty
  28390. +disclaimer.
  28391. +********************************************************************************
  28392. +Marvell BSD License Option
  28393. +
  28394. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28395. +modify this File under the following licensing terms.
  28396. +Redistribution and use in source and binary forms, with or without modification,
  28397. +are permitted provided that the following conditions are met:
  28398. +
  28399. + * Redistributions of source code must retain the above copyright notice,
  28400. + this list of conditions and the following disclaimer.
  28401. +
  28402. + * Redistributions in binary form must reproduce the above copyright
  28403. + notice, this list of conditions and the following disclaimer in the
  28404. + documentation and/or other materials provided with the distribution.
  28405. +
  28406. + * Neither the name of Marvell nor the names of its contributors may be
  28407. + used to endorse or promote products derived from this software without
  28408. + specific prior written permission.
  28409. +
  28410. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  28411. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  28412. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  28413. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  28414. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28415. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28416. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  28417. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28418. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28419. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28420. +
  28421. +*******************************************************************************/
  28422. +
  28423. +#ifndef __mvMD5_h__
  28424. +#define __mvMD5_h__
  28425. +
  28426. +#include "mvMD5.h"
  28427. +
  28428. +#define MV_MD5_MAC_LEN 16
  28429. +
  28430. +
  28431. +typedef struct
  28432. +{
  28433. + MV_U32 buf[4];
  28434. + MV_U32 bits[2];
  28435. + MV_U8 in[64];
  28436. +
  28437. +} MV_MD5_CONTEXT;
  28438. +
  28439. +void mvMD5Init(MV_MD5_CONTEXT *context);
  28440. +void mvMD5Update(MV_MD5_CONTEXT *context, unsigned char const *buf,
  28441. + unsigned len);
  28442. +void mvMD5Final(unsigned char digest[16], MV_MD5_CONTEXT *context);
  28443. +
  28444. +void mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest);
  28445. +
  28446. +void mvHmacMd5(unsigned char const* text, int text_len,
  28447. + unsigned char const* key, int key_len,
  28448. + unsigned char* digest);
  28449. +
  28450. +
  28451. +#endif /* __mvMD5_h__ */
  28452. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvSHA1.c linux-2.6.39/crypto/ocf/kirkwood/cesa/mvSHA1.c
  28453. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvSHA1.c 1970-01-01 01:00:00.000000000 +0100
  28454. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvSHA1.c 2011-07-31 11:31:55.323424785 +0200
  28455. @@ -0,0 +1,239 @@
  28456. +/*******************************************************************************
  28457. +Copyright (C) Marvell International Ltd. and its affiliates
  28458. +
  28459. +This software file (the "File") is owned and distributed by Marvell
  28460. +International Ltd. and/or its affiliates ("Marvell") under the following
  28461. +alternative licensing terms. Once you have made an election to distribute the
  28462. +File under one of the following license alternatives, please (i) delete this
  28463. +introductory statement regarding license alternatives, (ii) delete the two
  28464. +license alternatives that you have not elected to use and (iii) preserve the
  28465. +Marvell copyright notice above.
  28466. +
  28467. +********************************************************************************
  28468. +Marvell Commercial License Option
  28469. +
  28470. +If you received this File from Marvell and you have entered into a commercial
  28471. +license agreement (a "Commercial License") with Marvell, the File is licensed
  28472. +to you under the terms of the applicable Commercial License.
  28473. +
  28474. +********************************************************************************
  28475. +Marvell GPL License Option
  28476. +
  28477. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28478. +modify this File in accordance with the terms and conditions of the General
  28479. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  28480. +available along with the File in the license.txt file or by writing to the Free
  28481. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  28482. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  28483. +
  28484. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  28485. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  28486. +DISCLAIMED. The GPL License provides additional details about this warranty
  28487. +disclaimer.
  28488. +********************************************************************************
  28489. +Marvell BSD License Option
  28490. +
  28491. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28492. +modify this File under the following licensing terms.
  28493. +Redistribution and use in source and binary forms, with or without modification,
  28494. +are permitted provided that the following conditions are met:
  28495. +
  28496. + * Redistributions of source code must retain the above copyright notice,
  28497. + this list of conditions and the following disclaimer.
  28498. +
  28499. + * Redistributions in binary form must reproduce the above copyright
  28500. + notice, this list of conditions and the following disclaimer in the
  28501. + documentation and/or other materials provided with the distribution.
  28502. +
  28503. + * Neither the name of Marvell nor the names of its contributors may be
  28504. + used to endorse or promote products derived from this software without
  28505. + specific prior written permission.
  28506. +
  28507. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  28508. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  28509. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  28510. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  28511. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28512. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28513. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  28514. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28515. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28516. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28517. +
  28518. +*******************************************************************************/
  28519. +
  28520. +#include "mvOs.h"
  28521. +#include "mvSHA1.h"
  28522. +
  28523. +#define SHA1HANDSOFF
  28524. +
  28525. +typedef union
  28526. +{
  28527. + MV_U8 c[64];
  28528. + MV_U32 l[16];
  28529. +
  28530. +} CHAR64LONG16;
  28531. +
  28532. +static void mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer);
  28533. +
  28534. +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
  28535. +
  28536. +
  28537. +#ifdef MV_CPU_LE
  28538. +#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
  28539. + (rol(block->l[i], 8) & 0x00FF00FF))
  28540. +#else
  28541. +#define blk0(i) block->l[i]
  28542. +#endif
  28543. +#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
  28544. + block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
  28545. +
  28546. +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
  28547. +#define R0(v,w,x,y,z,i) \
  28548. + z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
  28549. + w = rol(w, 30);
  28550. +#define R1(v,w,x,y,z,i) \
  28551. + z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
  28552. + w = rol(w, 30);
  28553. +#define R2(v,w,x,y,z,i) \
  28554. + z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
  28555. +#define R3(v,w,x,y,z,i) \
  28556. + z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
  28557. + w = rol(w, 30);
  28558. +#define R4(v,w,x,y,z,i) \
  28559. + z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
  28560. + w=rol(w, 30);
  28561. +
  28562. +/* Hash a single 512-bit block. This is the core of the algorithm. */
  28563. +static void mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer)
  28564. +{
  28565. + MV_U32 a, b, c, d, e;
  28566. + CHAR64LONG16* block;
  28567. +
  28568. +#ifdef SHA1HANDSOFF
  28569. + static MV_U32 workspace[16];
  28570. +
  28571. + block = (CHAR64LONG16 *) workspace;
  28572. + memcpy(block, buffer, 64);
  28573. +#else
  28574. + block = (CHAR64LONG16 *) buffer;
  28575. +#endif
  28576. + /* Copy context->state[] to working vars */
  28577. + a = state[0];
  28578. + b = state[1];
  28579. + c = state[2];
  28580. + d = state[3];
  28581. + e = state[4];
  28582. + /* 4 rounds of 20 operations each. Loop unrolled. */
  28583. + 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);
  28584. + 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);
  28585. + 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);
  28586. + 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);
  28587. + 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);
  28588. + 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);
  28589. + 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);
  28590. + 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);
  28591. + 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);
  28592. + 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);
  28593. + 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);
  28594. + 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);
  28595. + 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);
  28596. + 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);
  28597. + 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);
  28598. + 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);
  28599. + 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);
  28600. + 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);
  28601. + 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);
  28602. + 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);
  28603. + /* Add the working vars back into context.state[] */
  28604. + state[0] += a;
  28605. + state[1] += b;
  28606. + state[2] += c;
  28607. + state[3] += d;
  28608. + state[4] += e;
  28609. + /* Wipe variables */
  28610. + a = b = c = d = e = 0;
  28611. +}
  28612. +
  28613. +void mvSHA1Init(MV_SHA1_CTX* context)
  28614. +{
  28615. + /* SHA1 initialization constants */
  28616. + context->state[0] = 0x67452301;
  28617. + context->state[1] = 0xEFCDAB89;
  28618. + context->state[2] = 0x98BADCFE;
  28619. + context->state[3] = 0x10325476;
  28620. + context->state[4] = 0xC3D2E1F0;
  28621. + context->count[0] = context->count[1] = 0;
  28622. +}
  28623. +
  28624. +
  28625. +/* Run your data through this. */
  28626. +void mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *data,
  28627. + unsigned int len)
  28628. +{
  28629. + MV_U32 i, j;
  28630. +
  28631. + j = (context->count[0] >> 3) & 63;
  28632. + if ((context->count[0] += len << 3) < (len << 3))
  28633. + context->count[1]++;
  28634. + context->count[1] += (len >> 29);
  28635. + if ((j + len) > 63)
  28636. + {
  28637. + memcpy(&context->buffer[j], data, (i = 64-j));
  28638. + mvSHA1Transform(context->state, context->buffer);
  28639. + for ( ; i + 63 < len; i += 64)
  28640. + {
  28641. + mvSHA1Transform(context->state, &data[i]);
  28642. + }
  28643. + j = 0;
  28644. + }
  28645. + else
  28646. + {
  28647. + i = 0;
  28648. + }
  28649. + memcpy(&context->buffer[j], &data[i], len - i);
  28650. +}
  28651. +
  28652. +void mvSHA1Final(MV_U8* digest, MV_SHA1_CTX* context)
  28653. +{
  28654. + MV_U32 i;
  28655. + MV_U8 finalcount[8];
  28656. +
  28657. + for (i = 0; i < 8; i++)
  28658. + {
  28659. + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >>
  28660. + ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
  28661. + }
  28662. + mvSHA1Update(context, (const unsigned char *) "\200", 1);
  28663. + while ((context->count[0] & 504) != 448)
  28664. + {
  28665. + mvSHA1Update(context, (const unsigned char *) "\0", 1);
  28666. + }
  28667. + mvSHA1Update(context, finalcount, 8); /* Should cause a mvSHA1Transform()
  28668. + */
  28669. + for (i = 0; i < 20; i++)
  28670. + {
  28671. + digest[i] = (unsigned char)
  28672. + ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
  28673. + }
  28674. + /* Wipe variables */
  28675. + i = 0;
  28676. + memset(context->buffer, 0, 64);
  28677. + memset(context->state, 0, 20);
  28678. + memset(context->count, 0, 8);
  28679. + memset(finalcount, 0, 8);
  28680. +
  28681. +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
  28682. + mvSHA1Transform(context->state, context->buffer);
  28683. +#endif
  28684. +}
  28685. +
  28686. +
  28687. +void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest)
  28688. +{
  28689. + MV_SHA1_CTX ctx;
  28690. +
  28691. + mvSHA1Init(&ctx);
  28692. + mvSHA1Update(&ctx, buf, len);
  28693. + mvSHA1Final(digest, &ctx);
  28694. +}
  28695. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvSHA1.h linux-2.6.39/crypto/ocf/kirkwood/cesa/mvSHA1.h
  28696. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvSHA1.h 1970-01-01 01:00:00.000000000 +0100
  28697. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvSHA1.h 2011-07-31 11:31:55.383926123 +0200
  28698. @@ -0,0 +1,88 @@
  28699. +/*******************************************************************************
  28700. +Copyright (C) Marvell International Ltd. and its affiliates
  28701. +
  28702. +This software file (the "File") is owned and distributed by Marvell
  28703. +International Ltd. and/or its affiliates ("Marvell") under the following
  28704. +alternative licensing terms. Once you have made an election to distribute the
  28705. +File under one of the following license alternatives, please (i) delete this
  28706. +introductory statement regarding license alternatives, (ii) delete the two
  28707. +license alternatives that you have not elected to use and (iii) preserve the
  28708. +Marvell copyright notice above.
  28709. +
  28710. +********************************************************************************
  28711. +Marvell Commercial License Option
  28712. +
  28713. +If you received this File from Marvell and you have entered into a commercial
  28714. +license agreement (a "Commercial License") with Marvell, the File is licensed
  28715. +to you under the terms of the applicable Commercial License.
  28716. +
  28717. +********************************************************************************
  28718. +Marvell GPL License Option
  28719. +
  28720. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28721. +modify this File in accordance with the terms and conditions of the General
  28722. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  28723. +available along with the File in the license.txt file or by writing to the Free
  28724. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  28725. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  28726. +
  28727. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  28728. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  28729. +DISCLAIMED. The GPL License provides additional details about this warranty
  28730. +disclaimer.
  28731. +********************************************************************************
  28732. +Marvell BSD License Option
  28733. +
  28734. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28735. +modify this File under the following licensing terms.
  28736. +Redistribution and use in source and binary forms, with or without modification,
  28737. +are permitted provided that the following conditions are met:
  28738. +
  28739. + * Redistributions of source code must retain the above copyright notice,
  28740. + this list of conditions and the following disclaimer.
  28741. +
  28742. + * Redistributions in binary form must reproduce the above copyright
  28743. + notice, this list of conditions and the following disclaimer in the
  28744. + documentation and/or other materials provided with the distribution.
  28745. +
  28746. + * Neither the name of Marvell nor the names of its contributors may be
  28747. + used to endorse or promote products derived from this software without
  28748. + specific prior written permission.
  28749. +
  28750. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  28751. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  28752. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  28753. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  28754. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28755. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28756. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  28757. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28758. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28759. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28760. +
  28761. +*******************************************************************************/
  28762. +
  28763. +#ifndef __mvSHA1_h__
  28764. +#define __mvSHA1_h__
  28765. +
  28766. +#include "mvSHA1.h"
  28767. +
  28768. +#define MV_SHA1_MAC_LEN 20
  28769. +
  28770. +
  28771. +typedef struct
  28772. +{
  28773. + MV_U32 state[5];
  28774. + MV_U32 count[2];
  28775. + MV_U8 buffer[64];
  28776. +
  28777. +} MV_SHA1_CTX;
  28778. +
  28779. +void mvSHA1Init(MV_SHA1_CTX *context);
  28780. +void mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *buf, unsigned int len);
  28781. +void mvSHA1Final(MV_U8* digest, MV_SHA1_CTX *context);
  28782. +
  28783. +void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest);
  28784. +
  28785. +
  28786. +#endif /* __mvSHA1_h__ */
  28787. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa_ocf_drv.c linux-2.6.39/crypto/ocf/kirkwood/cesa_ocf_drv.c
  28788. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa_ocf_drv.c 1970-01-01 01:00:00.000000000 +0100
  28789. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa_ocf_drv.c 2011-07-31 11:31:55.436832710 +0200
  28790. @@ -0,0 +1,1296 @@
  28791. +/*******************************************************************************
  28792. +Copyright (C) Marvell International Ltd. and its affiliates
  28793. +
  28794. +This software file (the "File") is owned and distributed by Marvell
  28795. +International Ltd. and/or its affiliates ("Marvell") under the following
  28796. +alternative licensing terms. Once you have made an election to distribute the
  28797. +File under one of the following license alternatives, please (i) delete this
  28798. +introductory statement regarding license alternatives, (ii) delete the two
  28799. +license alternatives that you have not elected to use and (iii) preserve the
  28800. +Marvell copyright notice above.
  28801. +
  28802. +
  28803. +********************************************************************************
  28804. +Marvell GPL License Option
  28805. +
  28806. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28807. +modify this File in accordance with the terms and conditions of the General
  28808. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  28809. +available along with the File in the license.txt file or by writing to the Free
  28810. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  28811. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  28812. +
  28813. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  28814. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  28815. +DISCLAIMED. The GPL License provides additional details about this warranty
  28816. +disclaimer.
  28817. +*******************************************************************************/
  28818. +
  28819. +#ifndef AUTOCONF_INCLUDED
  28820. +#include <linux/config.h>
  28821. +#endif
  28822. +#include <linux/module.h>
  28823. +#include <linux/init.h>
  28824. +#include <linux/list.h>
  28825. +#include <linux/slab.h>
  28826. +#include <linux/sched.h>
  28827. +#include <linux/wait.h>
  28828. +#include <linux/crypto.h>
  28829. +#include <linux/mm.h>
  28830. +#include <linux/skbuff.h>
  28831. +#include <linux/random.h>
  28832. +#include <linux/platform_device.h>
  28833. +#include <asm/scatterlist.h>
  28834. +#include <linux/spinlock.h>
  28835. +#include "ctrlEnv/sys/mvSysCesa.h"
  28836. +#include "cesa/mvCesa.h" /* moved here before cryptodev.h due to include dependencies */
  28837. +#include <cryptodev.h>
  28838. +#include <uio.h>
  28839. +#include <plat/mv_cesa.h>
  28840. +#include <linux/mbus.h>
  28841. +#include "mvDebug.h"
  28842. +
  28843. +#include "cesa/mvMD5.h"
  28844. +#include "cesa/mvSHA1.h"
  28845. +
  28846. +#include "cesa/mvCesaRegs.h"
  28847. +#include "cesa/AES/mvAes.h"
  28848. +#include "cesa/mvLru.h"
  28849. +
  28850. +#undef RT_DEBUG
  28851. +#ifdef RT_DEBUG
  28852. +static int debug = 1;
  28853. +module_param(debug, int, 1);
  28854. +MODULE_PARM_DESC(debug, "Enable debug");
  28855. +#undef dprintk
  28856. +#define dprintk(a...) if (debug) { printk(a); } else
  28857. +#else
  28858. +static int debug = 0;
  28859. +#undef dprintk
  28860. +#define dprintk(a...)
  28861. +#endif
  28862. +
  28863. +
  28864. +/* TDMA Regs */
  28865. +#define WINDOW_BASE(i) 0xA00 + (i << 3)
  28866. +#define WINDOW_CTRL(i) 0xA04 + (i << 3)
  28867. +
  28868. +/* interrupt handling */
  28869. +#undef CESA_OCF_POLLING
  28870. +#undef CESA_OCF_TASKLET
  28871. +
  28872. +#if defined(CESA_OCF_POLLING) && defined(CESA_OCF_TASKLET)
  28873. +#error "don't use both tasklet and polling mode"
  28874. +#endif
  28875. +
  28876. +extern int cesaReqResources;
  28877. +/* support for spliting action into 2 actions */
  28878. +#define CESA_OCF_SPLIT
  28879. +
  28880. +/* general defines */
  28881. +#define CESA_OCF_MAX_SES 128
  28882. +#define CESA_Q_SIZE 64
  28883. +
  28884. +
  28885. +/* data structures */
  28886. +struct cesa_ocf_data {
  28887. + int cipher_alg;
  28888. + int auth_alg;
  28889. + int encrypt_tn_auth;
  28890. +#define auth_tn_decrypt encrypt_tn_auth
  28891. + int ivlen;
  28892. + int digestlen;
  28893. + short sid_encrypt;
  28894. + short sid_decrypt;
  28895. + /* fragment workaround sessions */
  28896. + short frag_wa_encrypt;
  28897. + short frag_wa_decrypt;
  28898. + short frag_wa_auth;
  28899. +};
  28900. +
  28901. +/* CESA device data */
  28902. +struct cesa_dev {
  28903. + void __iomem *sram;
  28904. + void __iomem *reg;
  28905. + struct mv_cesa_platform_data *plat_data;
  28906. + int irq;
  28907. +};
  28908. +
  28909. +#define DIGEST_BUF_SIZE 32
  28910. +struct cesa_ocf_process {
  28911. + MV_CESA_COMMAND cesa_cmd;
  28912. + MV_CESA_MBUF cesa_mbuf;
  28913. + MV_BUF_INFO cesa_bufs[MV_CESA_MAX_MBUF_FRAGS];
  28914. + char digest[DIGEST_BUF_SIZE];
  28915. + int digest_len;
  28916. + struct cryptop *crp;
  28917. + int need_cb;
  28918. +};
  28919. +
  28920. +/* global variables */
  28921. +static int32_t cesa_ocf_id = -1;
  28922. +static struct cesa_ocf_data *cesa_ocf_sessions[CESA_OCF_MAX_SES];
  28923. +static spinlock_t cesa_lock;
  28924. +static struct cesa_dev cesa_device;
  28925. +
  28926. +/* static APIs */
  28927. +static int cesa_ocf_process (device_t, struct cryptop *, int);
  28928. +static int cesa_ocf_newsession (device_t, u_int32_t *, struct cryptoini *);
  28929. +static int cesa_ocf_freesession (device_t, u_int64_t);
  28930. +static void cesa_callback (unsigned long);
  28931. +static irqreturn_t cesa_interrupt_handler (int, void *);
  28932. +#ifdef CESA_OCF_POLLING
  28933. +static void cesa_interrupt_polling(void);
  28934. +#endif
  28935. +#ifdef CESA_OCF_TASKLET
  28936. +static struct tasklet_struct cesa_ocf_tasklet;
  28937. +#endif
  28938. +
  28939. +static struct timeval tt_start;
  28940. +static struct timeval tt_end;
  28941. +
  28942. +/*
  28943. + * dummy device structure
  28944. + */
  28945. +
  28946. +static struct {
  28947. + softc_device_decl sc_dev;
  28948. +} mv_cesa_dev;
  28949. +
  28950. +static device_method_t mv_cesa_methods = {
  28951. + /* crypto device methods */
  28952. + DEVMETHOD(cryptodev_newsession, cesa_ocf_newsession),
  28953. + DEVMETHOD(cryptodev_freesession,cesa_ocf_freesession),
  28954. + DEVMETHOD(cryptodev_process, cesa_ocf_process),
  28955. + DEVMETHOD(cryptodev_kprocess, NULL),
  28956. +};
  28957. +
  28958. +
  28959. +
  28960. +/* Add debug Trace */
  28961. +#undef CESA_OCF_TRACE_DEBUG
  28962. +#ifdef CESA_OCF_TRACE_DEBUG
  28963. +
  28964. +#define MV_CESA_USE_TIMER_ID 0
  28965. +
  28966. +typedef struct
  28967. +{
  28968. + int type; /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */
  28969. + MV_U32 timeStamp;
  28970. + MV_U32 cause;
  28971. + MV_U32 realCause;
  28972. + MV_U32 dmaCause;
  28973. + int resources;
  28974. + MV_CESA_REQ* pReqReady;
  28975. + MV_CESA_REQ* pReqEmpty;
  28976. + MV_CESA_REQ* pReqProcess;
  28977. +} MV_CESA_TEST_TRACE;
  28978. +
  28979. +#define MV_CESA_TEST_TRACE_SIZE 50
  28980. +
  28981. +static int cesaTestTraceIdx = 0;
  28982. +static MV_CESA_TEST_TRACE cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];
  28983. +
  28984. +static void cesaTestTraceAdd(int type)
  28985. +{
  28986. + cesaTestTrace[cesaTestTraceIdx].type = type;
  28987. + cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  28988. + //cesaTestTrace[cesaTestTraceIdx].idmaCause = MV_REG_READ(IDMA_CAUSE_REG);
  28989. + cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;
  28990. + cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;
  28991. + cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;
  28992. + cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;
  28993. + cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);
  28994. + cesaTestTraceIdx++;
  28995. + if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)
  28996. + cesaTestTraceIdx = 0;
  28997. +}
  28998. +
  28999. +#else /* CESA_OCF_TRACE_DEBUG */
  29000. +
  29001. +#define cesaTestTraceAdd(x)
  29002. +
  29003. +#endif /* CESA_OCF_TRACE_DEBUG */
  29004. +
  29005. +unsigned int
  29006. +get_usec(unsigned int start)
  29007. +{
  29008. + if(start) {
  29009. + do_gettimeofday (&tt_start);
  29010. + return 0;
  29011. + }
  29012. + else {
  29013. + do_gettimeofday (&tt_end);
  29014. + tt_end.tv_sec -= tt_start.tv_sec;
  29015. + tt_end.tv_usec -= tt_start.tv_usec;
  29016. + if (tt_end.tv_usec < 0) {
  29017. + tt_end.tv_usec += 1000 * 1000;
  29018. + tt_end.tv_sec -= 1;
  29019. + }
  29020. + }
  29021. + printk("time taken is %d\n", (unsigned int)(tt_end.tv_usec + tt_end.tv_sec * 1000000));
  29022. + return (tt_end.tv_usec + tt_end.tv_sec * 1000000);
  29023. +}
  29024. +
  29025. +#ifdef RT_DEBUG
  29026. +/*
  29027. + * check that the crp action match the current session
  29028. + */
  29029. +static int
  29030. +ocf_check_action(struct cryptop *crp, struct cesa_ocf_data *cesa_ocf_cur_ses) {
  29031. + int count = 0;
  29032. + int encrypt = 0, decrypt = 0, auth = 0;
  29033. + struct cryptodesc *crd;
  29034. +
  29035. + /* Go through crypto descriptors, processing as we go */
  29036. + for (crd = crp->crp_desc; crd; crd = crd->crd_next, count++) {
  29037. + if(count > 2) {
  29038. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  29039. + return 1;
  29040. + }
  29041. +
  29042. + /* Encryption /Decryption */
  29043. + if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
  29044. + /* check that the action is compatible with session */
  29045. + if(encrypt || decrypt) {
  29046. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  29047. + return 1;
  29048. + }
  29049. +
  29050. + if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  29051. + if( (count == 2) && (cesa_ocf_cur_ses->encrypt_tn_auth) ) {
  29052. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  29053. + return 1;
  29054. + }
  29055. + encrypt++;
  29056. + }
  29057. + else { /* decrypt */
  29058. + if( (count == 2) && !(cesa_ocf_cur_ses->auth_tn_decrypt) ) {
  29059. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  29060. + return 1;
  29061. + }
  29062. + decrypt++;
  29063. + }
  29064. +
  29065. + }
  29066. + /* Authentication */
  29067. + else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
  29068. + /* check that the action is compatible with session */
  29069. + if(auth) {
  29070. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  29071. + return 1;
  29072. + }
  29073. + if( (count == 2) && (decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
  29074. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  29075. + return 1;
  29076. + }
  29077. + if( (count == 2) && (encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)) {
  29078. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  29079. + return 1;
  29080. + }
  29081. + auth++;
  29082. + }
  29083. + else {
  29084. + printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
  29085. + return 1;
  29086. + }
  29087. + }
  29088. + return 0;
  29089. +
  29090. +}
  29091. +#endif
  29092. +
  29093. +/*
  29094. + * Process a request.
  29095. + */
  29096. +static int
  29097. +cesa_ocf_process(device_t dev, struct cryptop *crp, int hint)
  29098. +{
  29099. + struct cesa_ocf_process *cesa_ocf_cmd = NULL;
  29100. + struct cesa_ocf_process *cesa_ocf_cmd_wa = NULL;
  29101. + MV_CESA_COMMAND *cesa_cmd;
  29102. + struct cryptodesc *crd;
  29103. + struct cesa_ocf_data *cesa_ocf_cur_ses;
  29104. + int sid = 0, temp_len = 0, i;
  29105. + int encrypt = 0, decrypt = 0, auth = 0;
  29106. + int status;
  29107. + struct sk_buff *skb = NULL;
  29108. + struct uio *uiop = NULL;
  29109. + unsigned char *ivp;
  29110. + MV_BUF_INFO *p_buf_info;
  29111. + MV_CESA_MBUF *p_mbuf_info;
  29112. + unsigned long flags;
  29113. +
  29114. + dprintk("%s()\n", __FUNCTION__);
  29115. +
  29116. + if( cesaReqResources <= 1 ) {
  29117. + dprintk("%s,%d: ERESTART\n", __FILE__, __LINE__);
  29118. + return ERESTART;
  29119. + }
  29120. +
  29121. +#ifdef RT_DEBUG
  29122. + /* Sanity check */
  29123. + if (crp == NULL) {
  29124. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  29125. + return EINVAL;
  29126. + }
  29127. +
  29128. + if (crp->crp_desc == NULL || crp->crp_buf == NULL ) {
  29129. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  29130. + crp->crp_etype = EINVAL;
  29131. + return EINVAL;
  29132. + }
  29133. +
  29134. + sid = crp->crp_sid & 0xffffffff;
  29135. + if ((sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL)) {
  29136. + crp->crp_etype = ENOENT;
  29137. + printk("%s,%d: ENOENT session %d \n", __FILE__, __LINE__, sid);
  29138. + return EINVAL;
  29139. + }
  29140. +#endif
  29141. +
  29142. + sid = crp->crp_sid & 0xffffffff;
  29143. + crp->crp_etype = 0;
  29144. + cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
  29145. +
  29146. +#ifdef RT_DEBUG
  29147. + if(ocf_check_action(crp, cesa_ocf_cur_ses)){
  29148. + goto p_error;
  29149. + }
  29150. +#endif
  29151. +
  29152. + /* malloc a new cesa process */
  29153. + cesa_ocf_cmd = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
  29154. +
  29155. + if (cesa_ocf_cmd == NULL) {
  29156. + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
  29157. + goto p_error;
  29158. + }
  29159. + memset(cesa_ocf_cmd, 0, sizeof(struct cesa_ocf_process));
  29160. +
  29161. + /* init cesa_process */
  29162. + cesa_ocf_cmd->crp = crp;
  29163. + /* always call callback */
  29164. + cesa_ocf_cmd->need_cb = 1;
  29165. +
  29166. + /* init cesa_cmd for usage of the HALs */
  29167. + cesa_cmd = &cesa_ocf_cmd->cesa_cmd;
  29168. + cesa_cmd->pReqPrv = (void *)cesa_ocf_cmd;
  29169. + cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_encrypt; /* defualt use encrypt */
  29170. +
  29171. + /* prepare src buffer */
  29172. + /* we send the entire buffer to the HAL, even if only part of it should be encrypt/auth. */
  29173. + /* if not using seesions for both encrypt and auth, then it will be wiser to to copy only */
  29174. + /* from skip to crd_len. */
  29175. + p_buf_info = cesa_ocf_cmd->cesa_bufs;
  29176. + p_mbuf_info = &cesa_ocf_cmd->cesa_mbuf;
  29177. +
  29178. + p_buf_info += 2; /* save 2 first buffers for IV and digest -
  29179. + we won't append them to the end since, they
  29180. + might be places in an unaligned addresses. */
  29181. +
  29182. + p_mbuf_info->pFrags = p_buf_info;
  29183. + temp_len = 0;
  29184. +
  29185. + /* handle SKB */
  29186. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  29187. +
  29188. + dprintk("%s,%d: handle SKB.\n", __FILE__, __LINE__);
  29189. + skb = (struct sk_buff *) crp->crp_buf;
  29190. +
  29191. + if (skb_shinfo(skb)->nr_frags >= (MV_CESA_MAX_MBUF_FRAGS - 1)) {
  29192. + printk("%s,%d: %d nr_frags > MV_CESA_MAX_MBUF_FRAGS", __FILE__, __LINE__, skb_shinfo(skb)->nr_frags);
  29193. + goto p_error;
  29194. + }
  29195. +
  29196. + p_mbuf_info->mbufSize = skb->len;
  29197. + temp_len = skb->len;
  29198. + /* first skb fragment */
  29199. + p_buf_info->bufSize = skb_headlen(skb);
  29200. + p_buf_info->bufVirtPtr = skb->data;
  29201. + p_buf_info++;
  29202. +
  29203. + /* now handle all other skb fragments */
  29204. + for ( i = 0; i < skb_shinfo(skb)->nr_frags; i++ ) {
  29205. + skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
  29206. + p_buf_info->bufSize = frag->size;
  29207. + p_buf_info->bufVirtPtr = page_address(frag->page) + frag->page_offset;
  29208. + p_buf_info++;
  29209. + }
  29210. + p_mbuf_info->numFrags = skb_shinfo(skb)->nr_frags + 1;
  29211. + }
  29212. + /* handle UIO */
  29213. + else if(crp->crp_flags & CRYPTO_F_IOV) {
  29214. +
  29215. + dprintk("%s,%d: handle UIO.\n", __FILE__, __LINE__);
  29216. + uiop = (struct uio *) crp->crp_buf;
  29217. +
  29218. + if (uiop->uio_iovcnt > (MV_CESA_MAX_MBUF_FRAGS - 1)) {
  29219. + printk("%s,%d: %d uio_iovcnt > MV_CESA_MAX_MBUF_FRAGS \n", __FILE__, __LINE__, uiop->uio_iovcnt);
  29220. + goto p_error;
  29221. + }
  29222. +
  29223. + p_mbuf_info->mbufSize = crp->crp_ilen;
  29224. + p_mbuf_info->numFrags = uiop->uio_iovcnt;
  29225. + for(i = 0; i < uiop->uio_iovcnt; i++) {
  29226. + p_buf_info->bufVirtPtr = uiop->uio_iov[i].iov_base;
  29227. + p_buf_info->bufSize = uiop->uio_iov[i].iov_len;
  29228. + temp_len += p_buf_info->bufSize;
  29229. + dprintk("%s,%d: buf %x-> addr %x, size %x \n"
  29230. + , __FILE__, __LINE__, i, (unsigned int)p_buf_info->bufVirtPtr, p_buf_info->bufSize);
  29231. + p_buf_info++;
  29232. + }
  29233. +
  29234. + }
  29235. + /* handle CONTIG */
  29236. + else {
  29237. + dprintk("%s,%d: handle CONTIG.\n", __FILE__, __LINE__);
  29238. + p_mbuf_info->numFrags = 1;
  29239. + p_mbuf_info->mbufSize = crp->crp_ilen;
  29240. + p_buf_info->bufVirtPtr = crp->crp_buf;
  29241. + p_buf_info->bufSize = crp->crp_ilen;
  29242. + temp_len = crp->crp_ilen;
  29243. + p_buf_info++;
  29244. + }
  29245. +
  29246. + /* Support up to 64K why? cause! */
  29247. + if(crp->crp_ilen > 64*1024) {
  29248. + printk("%s,%d: buf too big %x \n", __FILE__, __LINE__, crp->crp_ilen);
  29249. + goto p_error;
  29250. + }
  29251. +
  29252. + if( temp_len != crp->crp_ilen ) {
  29253. + printk("%s,%d: warning size don't match.(%x %x) \n", __FILE__, __LINE__, temp_len, crp->crp_ilen);
  29254. + }
  29255. +
  29256. + cesa_cmd->pSrc = p_mbuf_info;
  29257. + cesa_cmd->pDst = p_mbuf_info;
  29258. +
  29259. + /* restore p_buf_info to point to first available buf */
  29260. + p_buf_info = cesa_ocf_cmd->cesa_bufs;
  29261. + p_buf_info += 1;
  29262. +
  29263. +
  29264. + /* Go through crypto descriptors, processing as we go */
  29265. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  29266. +
  29267. + /* Encryption /Decryption */
  29268. + if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
  29269. +
  29270. + dprintk("%s,%d: cipher", __FILE__, __LINE__);
  29271. +
  29272. + cesa_cmd->cryptoOffset = crd->crd_skip;
  29273. + cesa_cmd->cryptoLength = crd->crd_len;
  29274. +
  29275. + if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  29276. + dprintk(" encrypt \n");
  29277. + encrypt++;
  29278. +
  29279. + /* handle IV */
  29280. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) { /* IV from USER */
  29281. + dprintk("%s,%d: IV from USER (offset %x) \n", __FILE__, __LINE__, crd->crd_inject);
  29282. + cesa_cmd->ivFromUser = 1;
  29283. + ivp = crd->crd_iv;
  29284. +
  29285. + /*
  29286. + * do we have to copy the IV back to the buffer ?
  29287. + */
  29288. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  29289. + dprintk("%s,%d: copy the IV back to the buffer\n", __FILE__, __LINE__);
  29290. + cesa_cmd->ivOffset = crd->crd_inject;
  29291. + crypto_copy_bits_back(crp->crp_buf, crd->crd_inject, ivp, cesa_ocf_cur_ses->ivlen);
  29292. + }
  29293. + else {
  29294. + dprintk("%s,%d: don't copy the IV back to the buffer \n", __FILE__, __LINE__);
  29295. + p_mbuf_info->numFrags++;
  29296. + p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
  29297. + p_mbuf_info->pFrags = p_buf_info;
  29298. +
  29299. + p_buf_info->bufVirtPtr = ivp;
  29300. + p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
  29301. + p_buf_info--;
  29302. +
  29303. + /* offsets */
  29304. + cesa_cmd->ivOffset = 0;
  29305. + cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
  29306. + if(auth) {
  29307. + cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
  29308. + cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
  29309. + }
  29310. + }
  29311. + }
  29312. + else { /* random IV */
  29313. + dprintk("%s,%d: random IV \n", __FILE__, __LINE__);
  29314. + cesa_cmd->ivFromUser = 0;
  29315. +
  29316. + /*
  29317. + * do we have to copy the IV back to the buffer ?
  29318. + */
  29319. + /* in this mode the HAL will always copy the IV */
  29320. + /* given by the session to the ivOffset */
  29321. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  29322. + cesa_cmd->ivOffset = crd->crd_inject;
  29323. + }
  29324. + else {
  29325. + /* if IV isn't copy, then how will the user know which IV did we use??? */
  29326. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  29327. + goto p_error;
  29328. + }
  29329. + }
  29330. + }
  29331. + else { /* decrypt */
  29332. + dprintk(" decrypt \n");
  29333. + decrypt++;
  29334. + cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_decrypt;
  29335. +
  29336. + /* handle IV */
  29337. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  29338. + dprintk("%s,%d: IV from USER \n", __FILE__, __LINE__);
  29339. + /* append the IV buf to the mbuf */
  29340. + cesa_cmd->ivFromUser = 1;
  29341. + p_mbuf_info->numFrags++;
  29342. + p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
  29343. + p_mbuf_info->pFrags = p_buf_info;
  29344. +
  29345. + p_buf_info->bufVirtPtr = crd->crd_iv;
  29346. + p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
  29347. + p_buf_info--;
  29348. +
  29349. + /* offsets */
  29350. + cesa_cmd->ivOffset = 0;
  29351. + cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
  29352. + if(auth) {
  29353. + cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
  29354. + cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
  29355. + }
  29356. + }
  29357. + else {
  29358. + dprintk("%s,%d: IV inside the buffer \n", __FILE__, __LINE__);
  29359. + cesa_cmd->ivFromUser = 0;
  29360. + cesa_cmd->ivOffset = crd->crd_inject;
  29361. + }
  29362. + }
  29363. +
  29364. + }
  29365. + /* Authentication */
  29366. + else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
  29367. + dprintk("%s,%d: Authentication \n", __FILE__, __LINE__);
  29368. + auth++;
  29369. + cesa_cmd->macOffset = crd->crd_skip;
  29370. + cesa_cmd->macLength = crd->crd_len;
  29371. +
  29372. + /* digest + mac */
  29373. + cesa_cmd->digestOffset = crd->crd_inject;
  29374. + }
  29375. + else {
  29376. + printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
  29377. + goto p_error;
  29378. + }
  29379. + }
  29380. +
  29381. + dprintk("\n");
  29382. + dprintk("%s,%d: Sending Action: \n", __FILE__, __LINE__);
  29383. + dprintk("%s,%d: IV from user: %d. IV offset %x \n", __FILE__, __LINE__, cesa_cmd->ivFromUser, cesa_cmd->ivOffset);
  29384. + dprintk("%s,%d: crypt offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->cryptoOffset, cesa_cmd->cryptoLength);
  29385. + dprintk("%s,%d: Auth offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->macOffset, cesa_cmd->macLength);
  29386. + dprintk("%s,%d: set digest in offset %x . \n", __FILE__, __LINE__, cesa_cmd->digestOffset);
  29387. + if(debug) {
  29388. + mvCesaDebugMbuf("SRC BUFFER", cesa_cmd->pSrc, 0, cesa_cmd->pSrc->mbufSize);
  29389. + }
  29390. +
  29391. +
  29392. + /* send action to HAL */
  29393. + spin_lock_irqsave(&cesa_lock, flags);
  29394. + status = mvCesaAction(cesa_cmd);
  29395. + spin_unlock_irqrestore(&cesa_lock, flags);
  29396. +
  29397. + /* action not allowed */
  29398. + if(status == MV_NOT_ALLOWED) {
  29399. +#ifdef CESA_OCF_SPLIT
  29400. + /* if both encrypt and auth try to split */
  29401. + if(auth && (encrypt || decrypt)) {
  29402. + MV_CESA_COMMAND *cesa_cmd_wa;
  29403. +
  29404. + /* malloc a new cesa process and init it */
  29405. + cesa_ocf_cmd_wa = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
  29406. +
  29407. + if (cesa_ocf_cmd_wa == NULL) {
  29408. + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
  29409. + goto p_error;
  29410. + }
  29411. + memcpy(cesa_ocf_cmd_wa, cesa_ocf_cmd, sizeof(struct cesa_ocf_process));
  29412. + cesa_cmd_wa = &cesa_ocf_cmd_wa->cesa_cmd;
  29413. + cesa_cmd_wa->pReqPrv = (void *)cesa_ocf_cmd_wa;
  29414. + cesa_ocf_cmd_wa->need_cb = 0;
  29415. +
  29416. + /* break requests to two operation, first operation completion won't call callback */
  29417. + if((decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
  29418. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  29419. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
  29420. + }
  29421. + else if((decrypt) && !(cesa_ocf_cur_ses->auth_tn_decrypt)) {
  29422. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
  29423. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  29424. + }
  29425. + else if((encrypt) && (cesa_ocf_cur_ses->encrypt_tn_auth)) {
  29426. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
  29427. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  29428. + }
  29429. + else if((encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)){
  29430. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  29431. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
  29432. + }
  29433. + else {
  29434. + printk("%s,%d: Unsupporterd fragment wa mode \n", __FILE__, __LINE__);
  29435. + goto p_error;
  29436. + }
  29437. +
  29438. + /* send the 2 actions to the HAL */
  29439. + spin_lock_irqsave(&cesa_lock, flags);
  29440. + status = mvCesaAction(cesa_cmd_wa);
  29441. + spin_unlock_irqrestore(&cesa_lock, flags);
  29442. +
  29443. + if((status != MV_NO_MORE) && (status != MV_OK)) {
  29444. + printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
  29445. + goto p_error;
  29446. + }
  29447. + spin_lock_irqsave(&cesa_lock, flags);
  29448. + status = mvCesaAction(cesa_cmd);
  29449. + spin_unlock_irqrestore(&cesa_lock, flags);
  29450. +
  29451. + }
  29452. + /* action not allowed and can't split */
  29453. + else
  29454. +#endif
  29455. + {
  29456. + goto p_error;
  29457. + }
  29458. + }
  29459. +
  29460. + /* Hal Q is full, send again. This should never happen */
  29461. + if(status == MV_NO_RESOURCE) {
  29462. + printk("%s,%d: cesa no more resources \n", __FILE__, __LINE__);
  29463. + if(cesa_ocf_cmd)
  29464. + kfree(cesa_ocf_cmd);
  29465. + if(cesa_ocf_cmd_wa)
  29466. + kfree(cesa_ocf_cmd_wa);
  29467. + return ERESTART;
  29468. + }
  29469. + else if((status != MV_NO_MORE) && (status != MV_OK)) {
  29470. + printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
  29471. + goto p_error;
  29472. + }
  29473. +
  29474. +
  29475. +#ifdef CESA_OCF_POLLING
  29476. + cesa_interrupt_polling();
  29477. +#endif
  29478. + cesaTestTraceAdd(5);
  29479. +
  29480. + return 0;
  29481. +p_error:
  29482. + crp->crp_etype = EINVAL;
  29483. + if(cesa_ocf_cmd)
  29484. + kfree(cesa_ocf_cmd);
  29485. + if(cesa_ocf_cmd_wa)
  29486. + kfree(cesa_ocf_cmd_wa);
  29487. + return EINVAL;
  29488. +}
  29489. +
  29490. +/*
  29491. + * cesa callback.
  29492. + */
  29493. +static void
  29494. +cesa_callback(unsigned long dummy)
  29495. +{
  29496. + struct cesa_ocf_process *cesa_ocf_cmd = NULL;
  29497. + struct cryptop *crp = NULL;
  29498. + MV_CESA_RESULT result[MV_CESA_MAX_CHAN];
  29499. + int res_idx = 0,i;
  29500. + MV_STATUS status;
  29501. +
  29502. + dprintk("%s()\n", __FUNCTION__);
  29503. +
  29504. +#ifdef CESA_OCF_TASKLET
  29505. + disable_irq(cesa_device.irq);
  29506. +#endif
  29507. + while(MV_TRUE) {
  29508. +
  29509. + /* Get Ready requests */
  29510. + spin_lock(&cesa_lock);
  29511. + status = mvCesaReadyGet(&result[res_idx]);
  29512. + spin_unlock(&cesa_lock);
  29513. +
  29514. + cesaTestTraceAdd(2);
  29515. +
  29516. + if(status != MV_OK) {
  29517. +#ifdef CESA_OCF_POLLING
  29518. + if(status == MV_BUSY) { /* Fragment */
  29519. + cesa_interrupt_polling();
  29520. + return;
  29521. + }
  29522. +#endif
  29523. + break;
  29524. + }
  29525. + res_idx++;
  29526. + break;
  29527. + }
  29528. +
  29529. + for(i = 0; i < res_idx; i++) {
  29530. +
  29531. + if(!result[i].pReqPrv) {
  29532. + printk("%s,%d: warning private is NULL\n", __FILE__, __LINE__);
  29533. + break;
  29534. + }
  29535. +
  29536. + cesa_ocf_cmd = result[i].pReqPrv;
  29537. + crp = cesa_ocf_cmd->crp;
  29538. +
  29539. + // ignore HMAC error.
  29540. + //if(result->retCode)
  29541. + // crp->crp_etype = EIO;
  29542. +
  29543. +#if defined(CESA_OCF_POLLING)
  29544. + if(!cesa_ocf_cmd->need_cb){
  29545. + cesa_interrupt_polling();
  29546. + }
  29547. +#endif
  29548. + if(cesa_ocf_cmd->need_cb) {
  29549. + if(debug) {
  29550. + mvCesaDebugMbuf("DST BUFFER", cesa_ocf_cmd->cesa_cmd.pDst, 0, cesa_ocf_cmd->cesa_cmd.pDst->mbufSize);
  29551. + }
  29552. + crypto_done(crp);
  29553. + }
  29554. + kfree(cesa_ocf_cmd);
  29555. + }
  29556. +#ifdef CESA_OCF_TASKLET
  29557. + enable_irq(cesa_device.irq);
  29558. +#endif
  29559. +
  29560. + cesaTestTraceAdd(3);
  29561. +
  29562. + return;
  29563. +}
  29564. +
  29565. +#ifdef CESA_OCF_POLLING
  29566. +static void
  29567. +cesa_interrupt_polling(void)
  29568. +{
  29569. + u32 cause;
  29570. +
  29571. + dprintk("%s()\n", __FUNCTION__);
  29572. +
  29573. + /* Read cause register */
  29574. + do {
  29575. + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  29576. + cause &= MV_CESA_CAUSE_ACC_DMA_ALL_MASK;
  29577. +
  29578. + } while (cause == 0);
  29579. +
  29580. + /* clear interrupts */
  29581. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  29582. +
  29583. + cesa_callback(0);
  29584. +
  29585. + return;
  29586. +}
  29587. +
  29588. +#endif
  29589. +
  29590. +/*
  29591. + * cesa Interrupt polling routine.
  29592. + */
  29593. +static irqreturn_t
  29594. +cesa_interrupt_handler(int irq, void *arg)
  29595. +{
  29596. + u32 cause;
  29597. +
  29598. + dprintk("%s()\n", __FUNCTION__);
  29599. +
  29600. + cesaTestTraceAdd(0);
  29601. +
  29602. + /* Read cause register */
  29603. + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  29604. +
  29605. + if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)
  29606. + {
  29607. + /* Empty interrupt */
  29608. + dprintk("%s,%d: cesaTestReadyIsr: cause=0x%x\n", __FILE__, __LINE__, cause);
  29609. + return IRQ_HANDLED;
  29610. + }
  29611. +
  29612. + /* clear interrupts */
  29613. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  29614. +
  29615. + cesaTestTraceAdd(1);
  29616. +#ifdef CESA_OCF_TASKLET
  29617. + tasklet_hi_schedule(&cesa_ocf_tasklet);
  29618. +#else
  29619. + cesa_callback(0);
  29620. +#endif
  29621. + return IRQ_HANDLED;
  29622. +}
  29623. +
  29624. +/*
  29625. + * Open a session.
  29626. + */
  29627. +static int
  29628. +/*cesa_ocf_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)*/
  29629. +cesa_ocf_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  29630. +{
  29631. + u32 status = 0, i;
  29632. + u32 count = 0, auth = 0, encrypt =0;
  29633. + struct cesa_ocf_data *cesa_ocf_cur_ses;
  29634. + MV_CESA_OPEN_SESSION cesa_session;
  29635. + MV_CESA_OPEN_SESSION *cesa_ses = &cesa_session;
  29636. +
  29637. +
  29638. + dprintk("%s()\n", __FUNCTION__);
  29639. + if (sid == NULL || cri == NULL) {
  29640. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  29641. + return EINVAL;
  29642. + }
  29643. +
  29644. + /* leave first empty like in other implementations */
  29645. + for (i = 1; i < CESA_OCF_MAX_SES; i++) {
  29646. + if (cesa_ocf_sessions[i] == NULL)
  29647. + break;
  29648. + }
  29649. +
  29650. + if(i >= CESA_OCF_MAX_SES) {
  29651. + printk("%s,%d: no more sessions \n", __FILE__, __LINE__);
  29652. + return EINVAL;
  29653. + }
  29654. +
  29655. + cesa_ocf_sessions[i] = (struct cesa_ocf_data *) kmalloc(sizeof(struct cesa_ocf_data), GFP_ATOMIC);
  29656. + if (cesa_ocf_sessions[i] == NULL) {
  29657. + cesa_ocf_freesession(NULL, i);
  29658. + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
  29659. + return ENOBUFS;
  29660. + }
  29661. + dprintk("%s,%d: new session %d \n", __FILE__, __LINE__, i);
  29662. +
  29663. + *sid = i;
  29664. + cesa_ocf_cur_ses = cesa_ocf_sessions[i];
  29665. + memset(cesa_ocf_cur_ses, 0, sizeof(struct cesa_ocf_data));
  29666. + cesa_ocf_cur_ses->sid_encrypt = -1;
  29667. + cesa_ocf_cur_ses->sid_decrypt = -1;
  29668. + cesa_ocf_cur_ses->frag_wa_encrypt = -1;
  29669. + cesa_ocf_cur_ses->frag_wa_decrypt = -1;
  29670. + cesa_ocf_cur_ses->frag_wa_auth = -1;
  29671. +
  29672. + /* init the session */
  29673. + memset(cesa_ses, 0, sizeof(MV_CESA_OPEN_SESSION));
  29674. + count = 1;
  29675. + while (cri) {
  29676. + if(count > 2) {
  29677. + printk("%s,%d: don't support more then 2 operations\n", __FILE__, __LINE__);
  29678. + goto error;
  29679. + }
  29680. + switch (cri->cri_alg) {
  29681. + case CRYPTO_AES_CBC:
  29682. + dprintk("%s,%d: (%d) AES CBC \n", __FILE__, __LINE__, count);
  29683. + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
  29684. + cesa_ocf_cur_ses->ivlen = MV_CESA_AES_BLOCK_SIZE;
  29685. + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_AES;
  29686. + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
  29687. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  29688. + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
  29689. + goto error;
  29690. + }
  29691. + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
  29692. + dprintk("%s,%d: key length %d \n", __FILE__, __LINE__, cri->cri_klen/8);
  29693. + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
  29694. + encrypt += count;
  29695. + break;
  29696. + case CRYPTO_3DES_CBC:
  29697. + dprintk("%s,%d: (%d) 3DES CBC \n", __FILE__, __LINE__, count);
  29698. + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
  29699. + cesa_ocf_cur_ses->ivlen = MV_CESA_3DES_BLOCK_SIZE;
  29700. + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_3DES;
  29701. + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
  29702. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  29703. + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
  29704. + goto error;
  29705. + }
  29706. + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
  29707. + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
  29708. + encrypt += count;
  29709. + break;
  29710. + case CRYPTO_DES_CBC:
  29711. + dprintk("%s,%d: (%d) DES CBC \n", __FILE__, __LINE__, count);
  29712. + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
  29713. + cesa_ocf_cur_ses->ivlen = MV_CESA_DES_BLOCK_SIZE;
  29714. + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_DES;
  29715. + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
  29716. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  29717. + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
  29718. + goto error;
  29719. + }
  29720. + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
  29721. + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
  29722. + encrypt += count;
  29723. + break;
  29724. + case CRYPTO_MD5:
  29725. + case CRYPTO_MD5_HMAC:
  29726. + dprintk("%s,%d: (%d) %sMD5 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_MD5)? "H-":" ");
  29727. + cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
  29728. + cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MD5_DIGEST_SIZE : 12;
  29729. + cesa_ses->macMode = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MAC_MD5 : MV_CESA_MAC_HMAC_MD5;
  29730. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  29731. + printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
  29732. + goto error;
  29733. + }
  29734. + cesa_ses->macKeyLength = cri->cri_klen/8;
  29735. + memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
  29736. + cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
  29737. + auth += count;
  29738. + break;
  29739. + case CRYPTO_SHA1:
  29740. + case CRYPTO_SHA1_HMAC:
  29741. + dprintk("%s,%d: (%d) %sSHA1 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_SHA1)? "H-":" ");
  29742. + cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
  29743. + cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_SHA1_DIGEST_SIZE : 12;
  29744. + cesa_ses->macMode = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_MAC_SHA1 : MV_CESA_MAC_HMAC_SHA1;
  29745. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  29746. + printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
  29747. + goto error;
  29748. + }
  29749. + cesa_ses->macKeyLength = cri->cri_klen/8;
  29750. + memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
  29751. + cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
  29752. + auth += count;
  29753. + break;
  29754. + default:
  29755. + printk("%s,%d: unknown algo 0x%x\n", __FILE__, __LINE__, cri->cri_alg);
  29756. + goto error;
  29757. + }
  29758. + cri = cri->cri_next;
  29759. + count++;
  29760. + }
  29761. +
  29762. + if((encrypt > 2) || (auth > 2)) {
  29763. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  29764. + goto error;
  29765. + }
  29766. + /* create new sessions in HAL */
  29767. + if(encrypt) {
  29768. + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
  29769. + /* encrypt session */
  29770. + if(auth == 1) {
  29771. + cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
  29772. + }
  29773. + else if(auth == 2) {
  29774. + cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
  29775. + cesa_ocf_cur_ses->encrypt_tn_auth = 1;
  29776. + }
  29777. + else {
  29778. + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
  29779. + }
  29780. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  29781. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
  29782. + if(status != MV_OK) {
  29783. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  29784. + goto error;
  29785. + }
  29786. + /* decrypt session */
  29787. + if( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) {
  29788. + cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
  29789. + }
  29790. + else if( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC ) {
  29791. + cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
  29792. + }
  29793. + cesa_ses->direction = MV_CESA_DIR_DECODE;
  29794. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_decrypt);
  29795. + if(status != MV_OK) {
  29796. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  29797. + goto error;
  29798. + }
  29799. +
  29800. + /* preapre one action sessions for case we will need to split an action */
  29801. +#ifdef CESA_OCF_SPLIT
  29802. + if(( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) ||
  29803. + ( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC )) {
  29804. + /* open one session for encode and one for decode */
  29805. + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
  29806. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  29807. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_encrypt);
  29808. + if(status != MV_OK) {
  29809. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  29810. + goto error;
  29811. + }
  29812. +
  29813. + cesa_ses->direction = MV_CESA_DIR_DECODE;
  29814. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_decrypt);
  29815. + if(status != MV_OK) {
  29816. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  29817. + goto error;
  29818. + }
  29819. + /* open one session for auth */
  29820. + cesa_ses->operation = MV_CESA_MAC_ONLY;
  29821. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  29822. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_auth);
  29823. + if(status != MV_OK) {
  29824. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  29825. + goto error;
  29826. + }
  29827. + }
  29828. +#endif
  29829. + }
  29830. + else { /* only auth */
  29831. + cesa_ses->operation = MV_CESA_MAC_ONLY;
  29832. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  29833. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
  29834. + if(status != MV_OK) {
  29835. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  29836. + goto error;
  29837. + }
  29838. + }
  29839. +
  29840. + return 0;
  29841. +error:
  29842. + cesa_ocf_freesession(NULL, *sid);
  29843. + return EINVAL;
  29844. +
  29845. +}
  29846. +
  29847. +
  29848. +/*
  29849. + * Free a session.
  29850. + */
  29851. +static int
  29852. +cesa_ocf_freesession(device_t dev, u_int64_t tid)
  29853. +{
  29854. + struct cesa_ocf_data *cesa_ocf_cur_ses;
  29855. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  29856. + //unsigned long flags;
  29857. +
  29858. + dprintk("%s() %d \n", __FUNCTION__, sid);
  29859. + if ( (sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL) ) {
  29860. + printk("%s,%d: EINVAL can't free session %d \n", __FILE__, __LINE__, sid);
  29861. + return(EINVAL);
  29862. + }
  29863. +
  29864. + /* Silently accept and return */
  29865. + if (sid == 0)
  29866. + return(0);
  29867. +
  29868. + /* release session from HAL */
  29869. + cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
  29870. + if (cesa_ocf_cur_ses->sid_encrypt != -1) {
  29871. + mvCesaSessionClose(cesa_ocf_cur_ses->sid_encrypt);
  29872. + }
  29873. + if (cesa_ocf_cur_ses->sid_decrypt != -1) {
  29874. + mvCesaSessionClose(cesa_ocf_cur_ses->sid_decrypt);
  29875. + }
  29876. + if (cesa_ocf_cur_ses->frag_wa_encrypt != -1) {
  29877. + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_encrypt);
  29878. + }
  29879. + if (cesa_ocf_cur_ses->frag_wa_decrypt != -1) {
  29880. + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_decrypt);
  29881. + }
  29882. + if (cesa_ocf_cur_ses->frag_wa_auth != -1) {
  29883. + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_auth);
  29884. + }
  29885. +
  29886. + kfree(cesa_ocf_cur_ses);
  29887. + cesa_ocf_sessions[sid] = NULL;
  29888. +
  29889. + return 0;
  29890. +}
  29891. +
  29892. +
  29893. +/* TDMA Window setup */
  29894. +
  29895. +static void __init
  29896. +setup_tdma_mbus_windows(struct cesa_dev *dev)
  29897. +{
  29898. + int i;
  29899. +
  29900. + for (i = 0; i < 4; i++) {
  29901. + writel(0, dev->reg + WINDOW_BASE(i));
  29902. + writel(0, dev->reg + WINDOW_CTRL(i));
  29903. + }
  29904. +
  29905. + for (i = 0; i < dev->plat_data->dram->num_cs; i++) {
  29906. + struct mbus_dram_window *cs = dev->plat_data->dram->cs + i;
  29907. + writel(
  29908. + ((cs->size - 1) & 0xffff0000) |
  29909. + (cs->mbus_attr << 8) |
  29910. + (dev->plat_data->dram->mbus_dram_target_id << 4) | 1,
  29911. + dev->reg + WINDOW_CTRL(i)
  29912. + );
  29913. + writel(cs->base, dev->reg + WINDOW_BASE(i));
  29914. + }
  29915. +}
  29916. +
  29917. +/*
  29918. + * our driver startup and shutdown routines
  29919. + */
  29920. +static int
  29921. +mv_cesa_ocf_init(struct platform_device *pdev)
  29922. +{
  29923. +#if defined(CONFIG_MV78200) || defined(CONFIG_MV632X)
  29924. + if (MV_FALSE == mvSocUnitIsMappedToThisCpu(CESA))
  29925. + {
  29926. + dprintk("CESA is not mapped to this CPU\n");
  29927. + return -ENODEV;
  29928. + }
  29929. +#endif
  29930. +
  29931. + dprintk("%s\n", __FUNCTION__);
  29932. + memset(&mv_cesa_dev, 0, sizeof(mv_cesa_dev));
  29933. + softc_device_init(&mv_cesa_dev, "MV CESA", 0, mv_cesa_methods);
  29934. + cesa_ocf_id = crypto_get_driverid(softc_get_device(&mv_cesa_dev),CRYPTOCAP_F_HARDWARE);
  29935. +
  29936. + if (cesa_ocf_id < 0)
  29937. + panic("MV CESA crypto device cannot initialize!");
  29938. +
  29939. + dprintk("%s,%d: cesa ocf device id is %d \n", __FILE__, __LINE__, cesa_ocf_id);
  29940. +
  29941. + /* CESA unit is auto power on off */
  29942. +#if 0
  29943. + if (MV_FALSE == mvCtrlPwrClckGet(CESA_UNIT_ID,0))
  29944. + {
  29945. + printk("\nWarning CESA %d is Powered Off\n",0);
  29946. + return EINVAL;
  29947. + }
  29948. +#endif
  29949. +
  29950. + memset(&cesa_device, 0, sizeof(struct cesa_dev));
  29951. + /* Get the IRQ, and crypto memory regions */
  29952. + {
  29953. + struct resource *res;
  29954. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
  29955. +
  29956. + if (!res)
  29957. + return -ENXIO;
  29958. +
  29959. + cesa_device.sram = ioremap(res->start, res->end - res->start + 1);
  29960. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
  29961. +
  29962. + if (!res) {
  29963. + iounmap(cesa_device.sram);
  29964. + return -ENXIO;
  29965. + }
  29966. + cesa_device.reg = ioremap(res->start, res->end - res->start + 1);
  29967. + cesa_device.irq = platform_get_irq(pdev, 0);
  29968. + cesa_device.plat_data = pdev->dev.platform_data;
  29969. + setup_tdma_mbus_windows(&cesa_device);
  29970. +
  29971. + }
  29972. +
  29973. +
  29974. + if( MV_OK != mvCesaInit(CESA_OCF_MAX_SES*5, CESA_Q_SIZE, cesa_device.reg,
  29975. + NULL) ) {
  29976. + printk("%s,%d: mvCesaInit Failed. \n", __FILE__, __LINE__);
  29977. + return EINVAL;
  29978. + }
  29979. +
  29980. + /* clear and unmask Int */
  29981. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  29982. +#ifndef CESA_OCF_POLLING
  29983. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);
  29984. +#endif
  29985. +#ifdef CESA_OCF_TASKLET
  29986. + tasklet_init(&cesa_ocf_tasklet, cesa_callback, (unsigned int) 0);
  29987. +#endif
  29988. + /* register interrupt */
  29989. + if( request_irq( cesa_device.irq, cesa_interrupt_handler,
  29990. + (IRQF_DISABLED) , "cesa", &cesa_ocf_id) < 0) {
  29991. + printk("%s,%d: cannot assign irq %x\n", __FILE__, __LINE__, cesa_device.reg);
  29992. + return EINVAL;
  29993. + }
  29994. +
  29995. +
  29996. + memset(cesa_ocf_sessions, 0, sizeof(struct cesa_ocf_data *) * CESA_OCF_MAX_SES);
  29997. +
  29998. +#define REGISTER(alg) \
  29999. + crypto_register(cesa_ocf_id, alg, 0,0)
  30000. + REGISTER(CRYPTO_AES_CBC);
  30001. + REGISTER(CRYPTO_DES_CBC);
  30002. + REGISTER(CRYPTO_3DES_CBC);
  30003. + REGISTER(CRYPTO_MD5);
  30004. + REGISTER(CRYPTO_MD5_HMAC);
  30005. + REGISTER(CRYPTO_SHA1);
  30006. + REGISTER(CRYPTO_SHA1_HMAC);
  30007. +#undef REGISTER
  30008. +
  30009. + return 0;
  30010. +}
  30011. +
  30012. +static void
  30013. +mv_cesa_ocf_exit(struct platform_device *pdev)
  30014. +{
  30015. + dprintk("%s()\n", __FUNCTION__);
  30016. +
  30017. + crypto_unregister_all(cesa_ocf_id);
  30018. + cesa_ocf_id = -1;
  30019. + iounmap(cesa_device.reg);
  30020. + iounmap(cesa_device.sram);
  30021. + free_irq(cesa_device.irq, NULL);
  30022. +
  30023. + /* mask and clear Int */
  30024. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
  30025. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  30026. +
  30027. +
  30028. + if( MV_OK != mvCesaFinish() ) {
  30029. + printk("%s,%d: mvCesaFinish Failed. \n", __FILE__, __LINE__);
  30030. + return;
  30031. + }
  30032. +}
  30033. +
  30034. +
  30035. +void cesa_ocf_debug(void)
  30036. +{
  30037. +
  30038. +#ifdef CESA_OCF_TRACE_DEBUG
  30039. + {
  30040. + int i, j;
  30041. + j = cesaTestTraceIdx;
  30042. + mvOsPrintf("No Type rCause iCause Proc Isr Res Time pReady pProc pEmpty\n");
  30043. + for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)
  30044. + {
  30045. + mvOsPrintf("%02d. %d 0x%04x 0x%04x 0x%02x 0x%02x %02d 0x%06x %p %p %p\n",
  30046. + j, cesaTestTrace[j].type, cesaTestTrace[j].realCause,
  30047. + cesaTestTrace[j].idmaCause,
  30048. + cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,
  30049. + cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);
  30050. + j++;
  30051. + if(j == MV_CESA_TEST_TRACE_SIZE)
  30052. + j = 0;
  30053. + }
  30054. + }
  30055. +#endif
  30056. +
  30057. +}
  30058. +
  30059. +static struct platform_driver marvell_cesa = {
  30060. + .probe = mv_cesa_ocf_init,
  30061. + .remove = mv_cesa_ocf_exit,
  30062. + .driver = {
  30063. + .owner = THIS_MODULE,
  30064. + .name = "mv_crypto",
  30065. + },
  30066. +};
  30067. +
  30068. +MODULE_ALIAS("platform:mv_crypto");
  30069. +
  30070. +static int __init mv_cesa_init(void)
  30071. +{
  30072. + return platform_driver_register(&marvell_cesa);
  30073. +}
  30074. +
  30075. +module_init(mv_cesa_init);
  30076. +
  30077. +static void __exit mv_cesa_exit(void)
  30078. +{
  30079. + platform_driver_unregister(&marvell_cesa);
  30080. +}
  30081. +
  30082. +module_exit(mv_cesa_exit);
  30083. +
  30084. +MODULE_LICENSE("GPL");
  30085. +MODULE_AUTHOR("Ronen Shitrit");
  30086. +MODULE_DESCRIPTION("OCF module for Orion CESA crypto");
  30087. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/Makefile linux-2.6.39/crypto/ocf/kirkwood/Makefile
  30088. --- linux-2.6.39.orig/crypto/ocf/kirkwood/Makefile 1970-01-01 01:00:00.000000000 +0100
  30089. +++ linux-2.6.39/crypto/ocf/kirkwood/Makefile 2011-07-31 11:31:55.503426020 +0200
  30090. @@ -0,0 +1,19 @@
  30091. +# for SGlinux builds
  30092. +-include $(ROOTDIR)/modules/.config
  30093. +
  30094. +obj-$(CONFIG_OCF_KIRKWOOD) += mv_cesa.o
  30095. +
  30096. +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
  30097. +
  30098. +# Extra objects required by the CESA driver
  30099. +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
  30100. +
  30101. +ifdef src
  30102. +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)
  30103. +endif
  30104. +
  30105. +EXTRA_CFLAGS += -DMV_LINUX -DMV_CPU_LE -DMV_ARM -DMV_INCLUDE_CESA -DMV_INCLUDE_PEX -DMV_CACHE_COHERENCY=3
  30106. +ifdef TOPDIR
  30107. +-include $(TOPDIR)/Rules.make
  30108. +endif
  30109. +
  30110. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mv802_3.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mv802_3.h
  30111. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mv802_3.h 1970-01-01 01:00:00.000000000 +0100
  30112. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mv802_3.h 2011-07-31 11:31:55.563424805 +0200
  30113. @@ -0,0 +1,213 @@
  30114. +/*******************************************************************************
  30115. +Copyright (C) Marvell International Ltd. and its affiliates
  30116. +
  30117. +This software file (the "File") is owned and distributed by Marvell
  30118. +International Ltd. and/or its affiliates ("Marvell") under the following
  30119. +alternative licensing terms. Once you have made an election to distribute the
  30120. +File under one of the following license alternatives, please (i) delete this
  30121. +introductory statement regarding license alternatives, (ii) delete the two
  30122. +license alternatives that you have not elected to use and (iii) preserve the
  30123. +Marvell copyright notice above.
  30124. +
  30125. +********************************************************************************
  30126. +Marvell Commercial License Option
  30127. +
  30128. +If you received this File from Marvell and you have entered into a commercial
  30129. +license agreement (a "Commercial License") with Marvell, the File is licensed
  30130. +to you under the terms of the applicable Commercial License.
  30131. +
  30132. +********************************************************************************
  30133. +Marvell GPL License Option
  30134. +
  30135. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30136. +modify this File in accordance with the terms and conditions of the General
  30137. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  30138. +available along with the File in the license.txt file or by writing to the Free
  30139. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  30140. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  30141. +
  30142. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  30143. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  30144. +DISCLAIMED. The GPL License provides additional details about this warranty
  30145. +disclaimer.
  30146. +********************************************************************************
  30147. +Marvell BSD License Option
  30148. +
  30149. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30150. +modify this File under the following licensing terms.
  30151. +Redistribution and use in source and binary forms, with or without modification,
  30152. +are permitted provided that the following conditions are met:
  30153. +
  30154. + * Redistributions of source code must retain the above copyright notice,
  30155. + this list of conditions and the following disclaimer.
  30156. +
  30157. + * Redistributions in binary form must reproduce the above copyright
  30158. + notice, this list of conditions and the following disclaimer in the
  30159. + documentation and/or other materials provided with the distribution.
  30160. +
  30161. + * Neither the name of Marvell nor the names of its contributors may be
  30162. + used to endorse or promote products derived from this software without
  30163. + specific prior written permission.
  30164. +
  30165. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30166. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30167. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30168. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30169. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30170. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30171. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30172. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30173. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30174. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30175. +
  30176. +*******************************************************************************/
  30177. +
  30178. +
  30179. +#ifndef __INCmv802_3h
  30180. +#define __INCmv802_3h
  30181. +
  30182. +
  30183. +/* includes */
  30184. +#include "mvTypes.h"
  30185. +
  30186. +/* Defines */
  30187. +#define MV_MAX_ETH_DATA 1500
  30188. +
  30189. +/* 802.3 types */
  30190. +#define MV_IP_TYPE 0x0800
  30191. +#define MV_IP_ARP_TYPE 0x0806
  30192. +#define MV_APPLE_TALK_ARP_TYPE 0x80F3
  30193. +#define MV_NOVELL_IPX_TYPE 0x8137
  30194. +#define MV_EAPOL_TYPE 0x888e
  30195. +
  30196. +
  30197. +
  30198. +/* Encapsulation header for RFC1042 and Ethernet_tunnel */
  30199. +
  30200. +#define MV_RFC1042_SNAP_HEADER {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}
  30201. +
  30202. +#define MV_ETH_SNAP_LSB 0xF8
  30203. +
  30204. +
  30205. +#define MV_MAC_ADDR_SIZE (6)
  30206. +#define MV_MAC_STR_SIZE (20)
  30207. +#define MV_VLAN_HLEN (4)
  30208. +
  30209. +/* This macro checks for a multicast mac address */
  30210. +#define MV_IS_MULTICAST_MAC(mac) (((mac)[0] & 0x1) == 1)
  30211. +
  30212. +
  30213. +/* This macro checks for an broadcast mac address */
  30214. +#define MV_IS_BROADCAST_MAC(mac) \
  30215. + (((mac)[0] == 0xFF) && \
  30216. + ((mac)[1] == 0xFF) && \
  30217. + ((mac)[2] == 0xFF) && \
  30218. + ((mac)[3] == 0xFF) && \
  30219. + ((mac)[4] == 0xFF) && \
  30220. + ((mac)[5] == 0xFF))
  30221. +
  30222. +
  30223. +/* Typedefs */
  30224. +typedef struct
  30225. +{
  30226. + MV_U8 pDA[MV_MAC_ADDR_SIZE];
  30227. + MV_U8 pSA[MV_MAC_ADDR_SIZE];
  30228. + MV_U16 typeOrLen;
  30229. +
  30230. +} MV_802_3_HEADER;
  30231. +
  30232. +enum {
  30233. + MV_IP_PROTO_NULL = 0, /* Dummy protocol for TCP */
  30234. + MV_IP_PROTO_ICMP = 1, /* Internet Control Message Protocol */
  30235. + MV_IP_PROTO_IGMP = 2, /* Internet Group Management Protocol */
  30236. + MV_IP_PROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
  30237. + MV_IP_PROTO_TCP = 6, /* Transmission Control Protocol */
  30238. + MV_IP_PROTO_EGP = 8, /* Exterior Gateway Protocol */
  30239. + MV_IP_PROTO_PUP = 12, /* PUP protocol */
  30240. + MV_IP_PROTO_UDP = 17, /* User Datagram Protocol */
  30241. + MV_IP_PROTO_IDP = 22, /* XNS IDP protocol */
  30242. + MV_IP_PROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
  30243. + MV_IP_PROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
  30244. + MV_IP_PROTO_RSVP = 46, /* RSVP protocol */
  30245. + MV_IP_PROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
  30246. + MV_IP_PROTO_ESP = 50, /* Encapsulation Security Payload protocol */
  30247. + MV_IP_PROTO_AH = 51, /* Authentication Header protocol */
  30248. + MV_IP_PROTO_BEETPH = 94, /* IP option pseudo header for BEET */
  30249. + MV_IP_PROTO_PIM = 103,
  30250. + MV_IP_PROTO_COMP = 108, /* Compression Header protocol */
  30251. + MV_IP_PROTO_ZERO_HOP = 114, /* Any 0 hop protocol (IANA) */
  30252. + MV_IP_PROTO_SCTP = 132, /* Stream Control Transport Protocol */
  30253. + MV_IP_PROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
  30254. +
  30255. + MV_IP_PROTO_RAW = 255, /* Raw IP packets */
  30256. + MV_IP_PROTO_MAX
  30257. +};
  30258. +
  30259. +typedef struct
  30260. +{
  30261. + MV_U8 version;
  30262. + MV_U8 tos;
  30263. + MV_U16 totalLength;
  30264. + MV_U16 identifier;
  30265. + MV_U16 fragmentCtrl;
  30266. + MV_U8 ttl;
  30267. + MV_U8 protocol;
  30268. + MV_U16 checksum;
  30269. + MV_U32 srcIP;
  30270. + MV_U32 dstIP;
  30271. +
  30272. +} MV_IP_HEADER;
  30273. +
  30274. +typedef struct
  30275. +{
  30276. + MV_U32 spi;
  30277. + MV_U32 seqNum;
  30278. +} MV_ESP_HEADER;
  30279. +
  30280. +#define MV_ICMP_ECHOREPLY 0 /* Echo Reply */
  30281. +#define MV_ICMP_DEST_UNREACH 3 /* Destination Unreachable */
  30282. +#define MV_ICMP_SOURCE_QUENCH 4 /* Source Quench */
  30283. +#define MV_ICMP_REDIRECT 5 /* Redirect (change route) */
  30284. +#define MV_ICMP_ECHO 8 /* Echo Request */
  30285. +#define MV_ICMP_TIME_EXCEEDED 11 /* Time Exceeded */
  30286. +#define MV_ICMP_PARAMETERPROB 12 /* Parameter Problem */
  30287. +#define MV_ICMP_TIMESTAMP 13 /* Timestamp Request */
  30288. +#define MV_ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */
  30289. +#define MV_ICMP_INFO_REQUEST 15 /* Information Request */
  30290. +#define MV_ICMP_INFO_REPLY 16 /* Information Reply */
  30291. +#define MV_ICMP_ADDRESS 17 /* Address Mask Request */
  30292. +#define MV_ICMP_ADDRESSREPLY 18 /* Address Mask Reply */
  30293. +
  30294. +typedef struct
  30295. +{
  30296. + MV_U8 type;
  30297. + MV_U8 code;
  30298. + MV_U16 checksum;
  30299. + MV_U16 id;
  30300. + MV_U16 sequence;
  30301. +
  30302. +} MV_ICMP_ECHO_HEADER;
  30303. +
  30304. +typedef struct
  30305. +{
  30306. + MV_U16 source;
  30307. + MV_U16 dest;
  30308. + MV_U32 seq;
  30309. + MV_U32 ack_seq;
  30310. + MV_U16 flags;
  30311. + MV_U16 window;
  30312. + MV_U16 chksum;
  30313. + MV_U16 urg_offset;
  30314. +
  30315. +} MV_TCP_HEADER;
  30316. +
  30317. +typedef struct
  30318. +{
  30319. + MV_U16 source;
  30320. + MV_U16 dest;
  30321. + MV_U16 len;
  30322. + MV_U16 check;
  30323. +
  30324. +} MV_UDP_HEADER;
  30325. +
  30326. +#endif /* __INCmv802_3h */
  30327. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvCommon.c
  30328. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.c 1970-01-01 01:00:00.000000000 +0100
  30329. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvCommon.c 2011-07-31 11:31:55.623424464 +0200
  30330. @@ -0,0 +1,277 @@
  30331. +/*******************************************************************************
  30332. +Copyright (C) Marvell International Ltd. and its affiliates
  30333. +
  30334. +This software file (the "File") is owned and distributed by Marvell
  30335. +International Ltd. and/or its affiliates ("Marvell") under the following
  30336. +alternative licensing terms. Once you have made an election to distribute the
  30337. +File under one of the following license alternatives, please (i) delete this
  30338. +introductory statement regarding license alternatives, (ii) delete the two
  30339. +license alternatives that you have not elected to use and (iii) preserve the
  30340. +Marvell copyright notice above.
  30341. +
  30342. +********************************************************************************
  30343. +Marvell Commercial License Option
  30344. +
  30345. +If you received this File from Marvell and you have entered into a commercial
  30346. +license agreement (a "Commercial License") with Marvell, the File is licensed
  30347. +to you under the terms of the applicable Commercial License.
  30348. +
  30349. +********************************************************************************
  30350. +Marvell GPL License Option
  30351. +
  30352. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30353. +modify this File in accordance with the terms and conditions of the General
  30354. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  30355. +available along with the File in the license.txt file or by writing to the Free
  30356. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  30357. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  30358. +
  30359. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  30360. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  30361. +DISCLAIMED. The GPL License provides additional details about this warranty
  30362. +disclaimer.
  30363. +********************************************************************************
  30364. +Marvell BSD License Option
  30365. +
  30366. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30367. +modify this File under the following licensing terms.
  30368. +Redistribution and use in source and binary forms, with or without modification,
  30369. +are permitted provided that the following conditions are met:
  30370. +
  30371. + * Redistributions of source code must retain the above copyright notice,
  30372. + this list of conditions and the following disclaimer.
  30373. +
  30374. + * Redistributions in binary form must reproduce the above copyright
  30375. + notice, this list of conditions and the following disclaimer in the
  30376. + documentation and/or other materials provided with the distribution.
  30377. +
  30378. + * Neither the name of Marvell nor the names of its contributors may be
  30379. + used to endorse or promote products derived from this software without
  30380. + specific prior written permission.
  30381. +
  30382. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30383. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30384. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30385. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30386. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30387. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30388. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30389. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30390. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30391. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30392. +
  30393. +*******************************************************************************/
  30394. +
  30395. +#include "mvOs.h"
  30396. +#include "mv802_3.h"
  30397. +#include "mvCommon.h"
  30398. +
  30399. +
  30400. +/*******************************************************************************
  30401. +* mvMacStrToHex - Convert MAC format string to hex.
  30402. +*
  30403. +* DESCRIPTION:
  30404. +* This function convert MAC format string to hex.
  30405. +*
  30406. +* INPUT:
  30407. +* macStr - MAC address string. Fornat of address string is
  30408. +* uu:vv:ww:xx:yy:zz, where ":" can be any delimiter.
  30409. +*
  30410. +* OUTPUT:
  30411. +* macHex - MAC in hex format.
  30412. +*
  30413. +* RETURN:
  30414. +* None.
  30415. +*
  30416. +*******************************************************************************/
  30417. +MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex)
  30418. +{
  30419. + int i;
  30420. + char tmp[3];
  30421. +
  30422. + for(i = 0; i < MV_MAC_ADDR_SIZE; i++)
  30423. + {
  30424. + tmp[0] = macStr[(i * 3) + 0];
  30425. + tmp[1] = macStr[(i * 3) + 1];
  30426. + tmp[2] = '\0';
  30427. + macHex[i] = (MV_U8) (strtol(tmp, NULL, 16));
  30428. + }
  30429. + return MV_OK;
  30430. +}
  30431. +
  30432. +/*******************************************************************************
  30433. +* mvMacHexToStr - Convert MAC in hex format to string format.
  30434. +*
  30435. +* DESCRIPTION:
  30436. +* This function convert MAC in hex format to string format.
  30437. +*
  30438. +* INPUT:
  30439. +* macHex - MAC in hex format.
  30440. +*
  30441. +* OUTPUT:
  30442. +* macStr - MAC address string. String format is uu:vv:ww:xx:yy:zz.
  30443. +*
  30444. +* RETURN:
  30445. +* None.
  30446. +*
  30447. +*******************************************************************************/
  30448. +MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr)
  30449. +{
  30450. + int i;
  30451. +
  30452. + for(i = 0; i < MV_MAC_ADDR_SIZE; i++)
  30453. + {
  30454. + mvOsSPrintf(&macStr[i * 3], "%02x:", macHex[i]);
  30455. + }
  30456. + macStr[(i * 3) - 1] = '\0';
  30457. +
  30458. + return MV_OK;
  30459. +}
  30460. +
  30461. +/*******************************************************************************
  30462. +* mvSizePrint - Print the given size with size unit description.
  30463. +*
  30464. +* DESCRIPTION:
  30465. +* This function print the given size with size unit description.
  30466. +* FOr example when size paramter is 0x180000, the function prints:
  30467. +* "size 1MB+500KB"
  30468. +*
  30469. +* INPUT:
  30470. +* size - Size in bytes.
  30471. +*
  30472. +* OUTPUT:
  30473. +* None.
  30474. +*
  30475. +* RETURN:
  30476. +* None.
  30477. +*
  30478. +*******************************************************************************/
  30479. +MV_VOID mvSizePrint(MV_U32 size)
  30480. +{
  30481. + mvOsOutput("size ");
  30482. +
  30483. + if(size >= _1G)
  30484. + {
  30485. + mvOsOutput("%3dGB ", size / _1G);
  30486. + size %= _1G;
  30487. + if(size)
  30488. + mvOsOutput("+");
  30489. + }
  30490. + if(size >= _1M )
  30491. + {
  30492. + mvOsOutput("%3dMB ", size / _1M);
  30493. + size %= _1M;
  30494. + if(size)
  30495. + mvOsOutput("+");
  30496. + }
  30497. + if(size >= _1K)
  30498. + {
  30499. + mvOsOutput("%3dKB ", size / _1K);
  30500. + size %= _1K;
  30501. + if(size)
  30502. + mvOsOutput("+");
  30503. + }
  30504. + if(size > 0)
  30505. + {
  30506. + mvOsOutput("%3dB ", size);
  30507. + }
  30508. +}
  30509. +
  30510. +/*******************************************************************************
  30511. +* mvHexToBin - Convert hex to binary
  30512. +*
  30513. +* DESCRIPTION:
  30514. +* This function Convert hex to binary.
  30515. +*
  30516. +* INPUT:
  30517. +* pHexStr - hex buffer pointer.
  30518. +* size - Size to convert.
  30519. +*
  30520. +* OUTPUT:
  30521. +* pBin - Binary buffer pointer.
  30522. +*
  30523. +* RETURN:
  30524. +* None.
  30525. +*
  30526. +*******************************************************************************/
  30527. +MV_VOID mvHexToBin(const char* pHexStr, MV_U8* pBin, int size)
  30528. +{
  30529. + int j, i;
  30530. + char tmp[3];
  30531. + MV_U8 byte;
  30532. +
  30533. + for(j=0, i=0; j<size; j++, i+=2)
  30534. + {
  30535. + tmp[0] = pHexStr[i];
  30536. + tmp[1] = pHexStr[i+1];
  30537. + tmp[2] = '\0';
  30538. + byte = (MV_U8) (strtol(tmp, NULL, 16) & 0xFF);
  30539. + pBin[j] = byte;
  30540. + }
  30541. +}
  30542. +
  30543. +void mvAsciiToHex(const char* asciiStr, char* hexStr)
  30544. +{
  30545. + int i=0;
  30546. +
  30547. + while(asciiStr[i] != 0)
  30548. + {
  30549. + mvOsSPrintf(&hexStr[i*2], "%02x", asciiStr[i]);
  30550. + i++;
  30551. + }
  30552. + hexStr[i*2] = 0;
  30553. +}
  30554. +
  30555. +
  30556. +void mvBinToHex(const MV_U8* bin, char* hexStr, int size)
  30557. +{
  30558. + int i;
  30559. +
  30560. + for(i=0; i<size; i++)
  30561. + {
  30562. + mvOsSPrintf(&hexStr[i*2], "%02x", bin[i]);
  30563. + }
  30564. + hexStr[i*2] = '\0';
  30565. +}
  30566. +
  30567. +void mvBinToAscii(const MV_U8* bin, char* asciiStr, int size)
  30568. +{
  30569. + int i;
  30570. +
  30571. + for(i=0; i<size; i++)
  30572. + {
  30573. + mvOsSPrintf(&asciiStr[i*2], "%c", bin[i]);
  30574. + }
  30575. + asciiStr[i*2] = '\0';
  30576. +}
  30577. +
  30578. +/*******************************************************************************
  30579. +* mvLog2 -
  30580. +*
  30581. +* DESCRIPTION:
  30582. +* Calculate the Log2 of a given number.
  30583. +*
  30584. +* INPUT:
  30585. +* num - A number to calculate the Log2 for.
  30586. +*
  30587. +* OUTPUT:
  30588. +* None.
  30589. +*
  30590. +* RETURN:
  30591. +* Log 2 of the input number, or 0xFFFFFFFF if input is 0.
  30592. +*
  30593. +*******************************************************************************/
  30594. +MV_U32 mvLog2(MV_U32 num)
  30595. +{
  30596. + MV_U32 result = 0;
  30597. + if(num == 0)
  30598. + return 0xFFFFFFFF;
  30599. + while(num != 1)
  30600. + {
  30601. + num = num >> 1;
  30602. + result++;
  30603. + }
  30604. + return result;
  30605. +}
  30606. +
  30607. +
  30608. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvCommon.h
  30609. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.h 1970-01-01 01:00:00.000000000 +0100
  30610. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvCommon.h 2011-07-31 11:31:55.683414272 +0200
  30611. @@ -0,0 +1,308 @@
  30612. +/*******************************************************************************
  30613. +Copyright (C) Marvell International Ltd. and its affiliates
  30614. +
  30615. +This software file (the "File") is owned and distributed by Marvell
  30616. +International Ltd. and/or its affiliates ("Marvell") under the following
  30617. +alternative licensing terms. Once you have made an election to distribute the
  30618. +File under one of the following license alternatives, please (i) delete this
  30619. +introductory statement regarding license alternatives, (ii) delete the two
  30620. +license alternatives that you have not elected to use and (iii) preserve the
  30621. +Marvell copyright notice above.
  30622. +
  30623. +********************************************************************************
  30624. +Marvell Commercial License Option
  30625. +
  30626. +If you received this File from Marvell and you have entered into a commercial
  30627. +license agreement (a "Commercial License") with Marvell, the File is licensed
  30628. +to you under the terms of the applicable Commercial License.
  30629. +
  30630. +********************************************************************************
  30631. +Marvell GPL License Option
  30632. +
  30633. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30634. +modify this File in accordance with the terms and conditions of the General
  30635. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  30636. +available along with the File in the license.txt file or by writing to the Free
  30637. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  30638. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  30639. +
  30640. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  30641. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  30642. +DISCLAIMED. The GPL License provides additional details about this warranty
  30643. +disclaimer.
  30644. +********************************************************************************
  30645. +Marvell BSD License Option
  30646. +
  30647. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30648. +modify this File under the following licensing terms.
  30649. +Redistribution and use in source and binary forms, with or without modification,
  30650. +are permitted provided that the following conditions are met:
  30651. +
  30652. + * Redistributions of source code must retain the above copyright notice,
  30653. + this list of conditions and the following disclaimer.
  30654. +
  30655. + * Redistributions in binary form must reproduce the above copyright
  30656. + notice, this list of conditions and the following disclaimer in the
  30657. + documentation and/or other materials provided with the distribution.
  30658. +
  30659. + * Neither the name of Marvell nor the names of its contributors may be
  30660. + used to endorse or promote products derived from this software without
  30661. + specific prior written permission.
  30662. +
  30663. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30664. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30665. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30666. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30667. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30668. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30669. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30670. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30671. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30672. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30673. +
  30674. +*******************************************************************************/
  30675. +
  30676. +
  30677. +
  30678. +#ifndef __INCmvCommonh
  30679. +#define __INCmvCommonh
  30680. +
  30681. +#include "mvTypes.h"
  30682. +
  30683. +/* Swap tool */
  30684. +
  30685. +/* 16bit nibble swap. For example 0x1234 -> 0x2143 */
  30686. +#define MV_NIBBLE_SWAP_16BIT(X) (((X&0xf) << 4) | \
  30687. + ((X&0xf0) >> 4) | \
  30688. + ((X&0xf00) << 4) | \
  30689. + ((X&0xf000) >> 4))
  30690. +
  30691. +/* 32bit nibble swap. For example 0x12345678 -> 0x21436587 */
  30692. +#define MV_NIBBLE_SWAP_32BIT(X) (((X&0xf) << 4) | \
  30693. + ((X&0xf0) >> 4) | \
  30694. + ((X&0xf00) << 4) | \
  30695. + ((X&0xf000) >> 4) | \
  30696. + ((X&0xf0000) << 4) | \
  30697. + ((X&0xf00000) >> 4) | \
  30698. + ((X&0xf000000) << 4) | \
  30699. + ((X&0xf0000000) >> 4))
  30700. +
  30701. +/* 16bit byte swap. For example 0x1122 -> 0x2211 */
  30702. +#define MV_BYTE_SWAP_16BIT(X) ((((X)&0xff)<<8) | (((X)&0xff00)>>8))
  30703. +
  30704. +/* 32bit byte swap. For example 0x11223344 -> 0x44332211 */
  30705. +#define MV_BYTE_SWAP_32BIT(X) ((((X)&0xff)<<24) | \
  30706. + (((X)&0xff00)<<8) | \
  30707. + (((X)&0xff0000)>>8) | \
  30708. + (((X)&0xff000000)>>24))
  30709. +
  30710. +/* 64bit byte swap. For example 0x11223344.55667788 -> 0x88776655.44332211 */
  30711. +#define MV_BYTE_SWAP_64BIT(X) ((l64) ((((X)&0xffULL)<<56) | \
  30712. + (((X)&0xff00ULL)<<40) | \
  30713. + (((X)&0xff0000ULL)<<24) | \
  30714. + (((X)&0xff000000ULL)<<8) | \
  30715. + (((X)&0xff00000000ULL)>>8) | \
  30716. + (((X)&0xff0000000000ULL)>>24) | \
  30717. + (((X)&0xff000000000000ULL)>>40) | \
  30718. + (((X)&0xff00000000000000ULL)>>56)))
  30719. +
  30720. +/* Endianess macros. */
  30721. +#if defined(MV_CPU_LE)
  30722. + #define MV_16BIT_LE(X) (X)
  30723. + #define MV_32BIT_LE(X) (X)
  30724. + #define MV_64BIT_LE(X) (X)
  30725. + #define MV_16BIT_BE(X) MV_BYTE_SWAP_16BIT(X)
  30726. + #define MV_32BIT_BE(X) MV_BYTE_SWAP_32BIT(X)
  30727. + #define MV_64BIT_BE(X) MV_BYTE_SWAP_64BIT(X)
  30728. +#elif defined(MV_CPU_BE)
  30729. + #define MV_16BIT_LE(X) MV_BYTE_SWAP_16BIT(X)
  30730. + #define MV_32BIT_LE(X) MV_BYTE_SWAP_32BIT(X)
  30731. + #define MV_64BIT_LE(X) MV_BYTE_SWAP_64BIT(X)
  30732. + #define MV_16BIT_BE(X) (X)
  30733. + #define MV_32BIT_BE(X) (X)
  30734. + #define MV_64BIT_BE(X) (X)
  30735. +#else
  30736. + #error "CPU endianess isn't defined!\n"
  30737. +#endif
  30738. +
  30739. +
  30740. +/* Bit field definitions */
  30741. +#define NO_BIT 0x00000000
  30742. +#define BIT0 0x00000001
  30743. +#define BIT1 0x00000002
  30744. +#define BIT2 0x00000004
  30745. +#define BIT3 0x00000008
  30746. +#define BIT4 0x00000010
  30747. +#define BIT5 0x00000020
  30748. +#define BIT6 0x00000040
  30749. +#define BIT7 0x00000080
  30750. +#define BIT8 0x00000100
  30751. +#define BIT9 0x00000200
  30752. +#define BIT10 0x00000400
  30753. +#define BIT11 0x00000800
  30754. +#define BIT12 0x00001000
  30755. +#define BIT13 0x00002000
  30756. +#define BIT14 0x00004000
  30757. +#define BIT15 0x00008000
  30758. +#define BIT16 0x00010000
  30759. +#define BIT17 0x00020000
  30760. +#define BIT18 0x00040000
  30761. +#define BIT19 0x00080000
  30762. +#define BIT20 0x00100000
  30763. +#define BIT21 0x00200000
  30764. +#define BIT22 0x00400000
  30765. +#define BIT23 0x00800000
  30766. +#define BIT24 0x01000000
  30767. +#define BIT25 0x02000000
  30768. +#define BIT26 0x04000000
  30769. +#define BIT27 0x08000000
  30770. +#define BIT28 0x10000000
  30771. +#define BIT29 0x20000000
  30772. +#define BIT30 0x40000000
  30773. +#define BIT31 0x80000000
  30774. +
  30775. +/* Handy sizes */
  30776. +#define _1K 0x00000400
  30777. +#define _2K 0x00000800
  30778. +#define _4K 0x00001000
  30779. +#define _8K 0x00002000
  30780. +#define _16K 0x00004000
  30781. +#define _32K 0x00008000
  30782. +#define _64K 0x00010000
  30783. +#define _128K 0x00020000
  30784. +#define _256K 0x00040000
  30785. +#define _512K 0x00080000
  30786. +
  30787. +#define _1M 0x00100000
  30788. +#define _2M 0x00200000
  30789. +#define _4M 0x00400000
  30790. +#define _8M 0x00800000
  30791. +#define _16M 0x01000000
  30792. +#define _32M 0x02000000
  30793. +#define _64M 0x04000000
  30794. +#define _128M 0x08000000
  30795. +#define _256M 0x10000000
  30796. +#define _512M 0x20000000
  30797. +
  30798. +#define _1G 0x40000000
  30799. +#define _2G 0x80000000
  30800. +
  30801. +/* Tclock and Sys clock define */
  30802. +#define _100MHz 100000000
  30803. +#define _125MHz 125000000
  30804. +#define _133MHz 133333334
  30805. +#define _150MHz 150000000
  30806. +#define _160MHz 160000000
  30807. +#define _166MHz 166666667
  30808. +#define _175MHz 175000000
  30809. +#define _178MHz 178000000
  30810. +#define _183MHz 183333334
  30811. +#define _187MHz 187000000
  30812. +#define _192MHz 192000000
  30813. +#define _194MHz 194000000
  30814. +#define _200MHz 200000000
  30815. +#define _233MHz 233333334
  30816. +#define _250MHz 250000000
  30817. +#define _266MHz 266666667
  30818. +#define _300MHz 300000000
  30819. +
  30820. +/* For better address window table readability */
  30821. +#define EN MV_TRUE
  30822. +#define DIS MV_FALSE
  30823. +#define N_A -1 /* Not applicable */
  30824. +
  30825. +/* Cache configuration options for memory (DRAM, SRAM, ... ) */
  30826. +
  30827. +/* Memory uncached, HW or SW cache coherency is not needed */
  30828. +#define MV_UNCACHED 0
  30829. +/* Memory cached, HW cache coherency supported in WriteThrough mode */
  30830. +#define MV_CACHE_COHER_HW_WT 1
  30831. +/* Memory cached, HW cache coherency supported in WriteBack mode */
  30832. +#define MV_CACHE_COHER_HW_WB 2
  30833. +/* Memory cached, No HW cache coherency, Cache coherency must be in SW */
  30834. +#define MV_CACHE_COHER_SW 3
  30835. +
  30836. +
  30837. +/* Macro for testing aligment. Positive if number is NOT aligned */
  30838. +#define MV_IS_NOT_ALIGN(number, align) ((number) & ((align) - 1))
  30839. +
  30840. +/* Macro for alignment up. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0340 */
  30841. +#define MV_ALIGN_UP(number, align) \
  30842. +(((number) & ((align) - 1)) ? (((number) + (align)) & ~((align)-1)) : (number))
  30843. +
  30844. +/* Macro for alignment down. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0320 */
  30845. +#define MV_ALIGN_DOWN(number, align) ((number) & ~((align)-1))
  30846. +
  30847. +/* This macro returns absolute value */
  30848. +#define MV_ABS(number) (((int)(number) < 0) ? -(int)(number) : (int)(number))
  30849. +
  30850. +
  30851. +/* Bit fields manipulation macros */
  30852. +
  30853. +/* An integer word which its 'x' bit is set */
  30854. +#define MV_BIT_MASK(bitNum) (1 << (bitNum) )
  30855. +
  30856. +/* Checks wheter bit 'x' in integer word is set */
  30857. +#define MV_BIT_CHECK(word, bitNum) ( (word) & MV_BIT_MASK(bitNum) )
  30858. +
  30859. +/* Clear (reset) bit 'x' in integer word (RMW - Read-Modify-Write) */
  30860. +#define MV_BIT_CLEAR(word, bitNum) ( (word) &= ~(MV_BIT_MASK(bitNum)) )
  30861. +
  30862. +/* Set bit 'x' in integer word (RMW) */
  30863. +#define MV_BIT_SET(word, bitNum) ( (word) |= MV_BIT_MASK(bitNum) )
  30864. +
  30865. +/* Invert bit 'x' in integer word (RMW) */
  30866. +#define MV_BIT_INV(word, bitNum) ( (word) ^= MV_BIT_MASK(bitNum) )
  30867. +
  30868. +/* Get the min between 'a' or 'b' */
  30869. +#define MV_MIN(a,b) (((a) < (b)) ? (a) : (b))
  30870. +
  30871. +/* Get the max between 'a' or 'b' */
  30872. +#define MV_MAX(a,b) (((a) < (b)) ? (b) : (a))
  30873. +
  30874. +/* Temporary */
  30875. +#define mvOsDivide(num, div) \
  30876. +({ \
  30877. + int i=0, rem=(num); \
  30878. + \
  30879. + while(rem >= (div)) \
  30880. + { \
  30881. + rem -= (div); \
  30882. + i++; \
  30883. + } \
  30884. + (i); \
  30885. +})
  30886. +
  30887. +/* Temporary */
  30888. +#define mvOsReminder(num, div) \
  30889. +({ \
  30890. + int rem = (num); \
  30891. + \
  30892. + while(rem >= (div)) \
  30893. + rem -= (div); \
  30894. + (rem); \
  30895. +})
  30896. +
  30897. +#define MV_IP_QUAD(ipAddr) ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF), \
  30898. + ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF)
  30899. +
  30900. +#define MV_IS_POWER_OF_2(num) ((num != 0) && ((num & (num - 1)) == 0))
  30901. +
  30902. +#ifndef MV_ASMLANGUAGE
  30903. +/* mvCommon API list */
  30904. +
  30905. +MV_VOID mvHexToBin(const char* pHexStr, MV_U8* pBin, int size);
  30906. +void mvAsciiToHex(const char* asciiStr, char* hexStr);
  30907. +void mvBinToHex(const MV_U8* bin, char* hexStr, int size);
  30908. +void mvBinToAscii(const MV_U8* bin, char* asciiStr, int size);
  30909. +
  30910. +MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex);
  30911. +MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr);
  30912. +void mvSizePrint(MV_U32);
  30913. +
  30914. +MV_U32 mvLog2(MV_U32 num);
  30915. +
  30916. +#endif /* MV_ASMLANGUAGE */
  30917. +
  30918. +
  30919. +#endif /* __INCmvCommonh */
  30920. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvDebug.c
  30921. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.c 1970-01-01 01:00:00.000000000 +0100
  30922. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvDebug.c 2011-07-31 11:31:55.744001253 +0200
  30923. @@ -0,0 +1,326 @@
  30924. +/*******************************************************************************
  30925. +Copyright (C) Marvell International Ltd. and its affiliates
  30926. +
  30927. +This software file (the "File") is owned and distributed by Marvell
  30928. +International Ltd. and/or its affiliates ("Marvell") under the following
  30929. +alternative licensing terms. Once you have made an election to distribute the
  30930. +File under one of the following license alternatives, please (i) delete this
  30931. +introductory statement regarding license alternatives, (ii) delete the two
  30932. +license alternatives that you have not elected to use and (iii) preserve the
  30933. +Marvell copyright notice above.
  30934. +
  30935. +********************************************************************************
  30936. +Marvell Commercial License Option
  30937. +
  30938. +If you received this File from Marvell and you have entered into a commercial
  30939. +license agreement (a "Commercial License") with Marvell, the File is licensed
  30940. +to you under the terms of the applicable Commercial License.
  30941. +
  30942. +********************************************************************************
  30943. +Marvell GPL License Option
  30944. +
  30945. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30946. +modify this File in accordance with the terms and conditions of the General
  30947. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  30948. +available along with the File in the license.txt file or by writing to the Free
  30949. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  30950. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  30951. +
  30952. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  30953. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  30954. +DISCLAIMED. The GPL License provides additional details about this warranty
  30955. +disclaimer.
  30956. +********************************************************************************
  30957. +Marvell BSD License Option
  30958. +
  30959. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30960. +modify this File under the following licensing terms.
  30961. +Redistribution and use in source and binary forms, with or without modification,
  30962. +are permitted provided that the following conditions are met:
  30963. +
  30964. + * Redistributions of source code must retain the above copyright notice,
  30965. + this list of conditions and the following disclaimer.
  30966. +
  30967. + * Redistributions in binary form must reproduce the above copyright
  30968. + notice, this list of conditions and the following disclaimer in the
  30969. + documentation and/or other materials provided with the distribution.
  30970. +
  30971. + * Neither the name of Marvell nor the names of its contributors may be
  30972. + used to endorse or promote products derived from this software without
  30973. + specific prior written permission.
  30974. +
  30975. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30976. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30977. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30978. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30979. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30980. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30981. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30982. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30983. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30984. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30985. +
  30986. +*******************************************************************************/
  30987. +
  30988. +
  30989. +
  30990. +/* includes */
  30991. +#include "mvOs.h"
  30992. +#include "mv802_3.h"
  30993. +#include "mvCommon.h"
  30994. +#include "mvDebug.h"
  30995. +
  30996. +/* Global variables effect on behave MV_DEBUG_PRINT and MV_DEBUG_CODE macros
  30997. + * mvDebug - map of bits (one for each module) bit=1 means enable
  30998. + * debug code and messages for this module
  30999. + * mvModuleDebug - array of 32 bits varables one for each module
  31000. + */
  31001. +MV_U32 mvDebug = 0;
  31002. +MV_U32 mvDebugModules[MV_MODULE_MAX];
  31003. +
  31004. +/* Init mvModuleDebug array to default values */
  31005. +void mvDebugInit(void)
  31006. +{
  31007. + int bit;
  31008. +
  31009. + mvDebug = 0;
  31010. + for(bit=0; bit<MV_MODULE_MAX; bit++)
  31011. + {
  31012. + mvDebugModules[bit] = MV_DEBUG_FLAG_ERR | MV_DEBUG_FLAG_STATS;
  31013. + mvDebug |= MV_BIT_MASK(bit);
  31014. + }
  31015. +}
  31016. +
  31017. +void mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable)
  31018. +{
  31019. + if (isEnable)
  31020. + {
  31021. + MV_BIT_SET(mvDebug, module);
  31022. + }
  31023. + else
  31024. + MV_BIT_CLEAR(mvDebug, module);
  31025. +}
  31026. +
  31027. +void mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags)
  31028. +{
  31029. + mvDebugModules[module] |= flags;
  31030. +}
  31031. +
  31032. +void mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags)
  31033. +{
  31034. + mvDebugModules[module] &= ~flags;
  31035. +}
  31036. +
  31037. +/* Dump memory in specific format:
  31038. + * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8
  31039. + */
  31040. +void mvDebugMemDump(void* addr, int size, int access)
  31041. +{
  31042. + int i, j;
  31043. + MV_U32 memAddr = (MV_U32)addr;
  31044. +
  31045. + if(access == 0)
  31046. + access = 1;
  31047. +
  31048. + if( (access != 4) && (access != 2) && (access != 1) )
  31049. + {
  31050. + mvOsPrintf("%d wrong access size. Access must be 1 or 2 or 4\n",
  31051. + access);
  31052. + return;
  31053. + }
  31054. + memAddr = MV_ALIGN_DOWN( (unsigned int)addr, 4);
  31055. + size = MV_ALIGN_UP(size, 4);
  31056. + addr = (void*)MV_ALIGN_DOWN( (unsigned int)addr, access);
  31057. + while(size > 0)
  31058. + {
  31059. + mvOsPrintf("%08x: ", memAddr);
  31060. + i = 0;
  31061. + /* 32 bytes in the line */
  31062. + while(i < 32)
  31063. + {
  31064. + if(memAddr >= (MV_U32)addr)
  31065. + {
  31066. + switch(access)
  31067. + {
  31068. + case 1:
  31069. + if( memAddr == CPU_PHY_MEM(memAddr) )
  31070. + {
  31071. + mvOsPrintf("%02x ", MV_MEMIO8_READ(memAddr));
  31072. + }
  31073. + else
  31074. + {
  31075. + mvOsPrintf("%02x ", *((MV_U8*)memAddr));
  31076. + }
  31077. + break;
  31078. +
  31079. + case 2:
  31080. + if( memAddr == CPU_PHY_MEM(memAddr) )
  31081. + {
  31082. + mvOsPrintf("%04x ", MV_MEMIO16_READ(memAddr));
  31083. + }
  31084. + else
  31085. + {
  31086. + mvOsPrintf("%04x ", *((MV_U16*)memAddr));
  31087. + }
  31088. + break;
  31089. +
  31090. + case 4:
  31091. + if( memAddr == CPU_PHY_MEM(memAddr) )
  31092. + {
  31093. + mvOsPrintf("%08x ", MV_MEMIO32_READ(memAddr));
  31094. + }
  31095. + else
  31096. + {
  31097. + mvOsPrintf("%08x ", *((MV_U32*)memAddr));
  31098. + }
  31099. + break;
  31100. + }
  31101. + }
  31102. + else
  31103. + {
  31104. + for(j=0; j<(access*2+1); j++)
  31105. + mvOsPrintf(" ");
  31106. + }
  31107. + i += access;
  31108. + memAddr += access;
  31109. + size -= access;
  31110. + if(size <= 0)
  31111. + break;
  31112. + }
  31113. + mvOsPrintf("\n");
  31114. + }
  31115. +}
  31116. +
  31117. +void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access)
  31118. +{
  31119. + if(pBufInfo == NULL)
  31120. + {
  31121. + mvOsPrintf("\n!!! pBufInfo = NULL\n");
  31122. + return;
  31123. + }
  31124. + mvOsPrintf("\n*** pBufInfo=0x%x, cmdSts=0x%08x, pBuf=0x%x, bufSize=%d\n",
  31125. + (unsigned int)pBufInfo,
  31126. + (unsigned int)pBufInfo->cmdSts,
  31127. + (unsigned int)pBufInfo->pBuff,
  31128. + (unsigned int)pBufInfo->bufSize);
  31129. + mvOsPrintf("pData=0x%x, byteCnt=%d, pNext=0x%x, uInfo1=0x%x, uInfo2=0x%x\n",
  31130. + (unsigned int)pBufInfo->pData,
  31131. + (unsigned int)pBufInfo->byteCnt,
  31132. + (unsigned int)pBufInfo->pNextBufInfo,
  31133. + (unsigned int)pBufInfo->userInfo1,
  31134. + (unsigned int)pBufInfo->userInfo2);
  31135. + if(pBufInfo->pData != NULL)
  31136. + {
  31137. + if(size > pBufInfo->byteCnt)
  31138. + size = pBufInfo->byteCnt;
  31139. + mvDebugMemDump(pBufInfo->pData, size, access);
  31140. + }
  31141. +}
  31142. +
  31143. +void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access)
  31144. +{
  31145. + int frag, len;
  31146. +
  31147. + if(pPktInfo == NULL)
  31148. + {
  31149. + mvOsPrintf("\n!!! pPktInfo = NULL\n");
  31150. + return;
  31151. + }
  31152. + mvOsPrintf("\npPkt=%p, stat=0x%08x, numFr=%d, size=%d, pFr=%p, osInfo=0x%lx\n",
  31153. + pPktInfo, pPktInfo->status, pPktInfo->numFrags, pPktInfo->pktSize,
  31154. + pPktInfo->pFrags, pPktInfo->osInfo);
  31155. +
  31156. + for(frag=0; frag<pPktInfo->numFrags; frag++)
  31157. + {
  31158. + mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n",
  31159. + frag, pPktInfo->pFrags[frag].bufVirtPtr,
  31160. + pPktInfo->pFrags[frag].bufSize);
  31161. + if(size > 0)
  31162. + {
  31163. + len = MV_MIN((int)pPktInfo->pFrags[frag].bufSize, size);
  31164. + mvDebugMemDump(pPktInfo->pFrags[frag].bufVirtPtr, len, access);
  31165. + size -= len;
  31166. + }
  31167. + }
  31168. +
  31169. +}
  31170. +
  31171. +void mvDebugPrintIpAddr(MV_U32 ipAddr)
  31172. +{
  31173. + mvOsPrintf("%d.%d.%d.%d", ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF),
  31174. + ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF));
  31175. +}
  31176. +
  31177. +void mvDebugPrintMacAddr(const MV_U8* pMacAddr)
  31178. +{
  31179. + int i;
  31180. +
  31181. + mvOsPrintf("%02x", (unsigned int)pMacAddr[0]);
  31182. + for(i=1; i<MV_MAC_ADDR_SIZE; i++)
  31183. + {
  31184. + mvOsPrintf(":%02x", pMacAddr[i]);
  31185. + }
  31186. + /* mvOsPrintf("\n");*/
  31187. +}
  31188. +
  31189. +
  31190. +/******* There are three functions deals with MV_DEBUG_TIMES structure ********/
  31191. +
  31192. +/* Reset MV_DEBUG_TIMES entry */
  31193. +void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* pName)
  31194. +{
  31195. + pTimeEntry->begin = 0;
  31196. + pTimeEntry->count = count;
  31197. + pTimeEntry->end = 0;
  31198. + pTimeEntry->left = pTimeEntry->count;
  31199. + pTimeEntry->total = 0;
  31200. + pTimeEntry->min = 0xFFFFFFFF;
  31201. + pTimeEntry->max = 0x0;
  31202. + strncpy(pTimeEntry->name, pName, sizeof(pTimeEntry->name)-1);
  31203. + pTimeEntry->name[sizeof(pTimeEntry->name)-1] = '\0';
  31204. +}
  31205. +
  31206. +/* Print out MV_DEBUG_TIMES entry */
  31207. +void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle)
  31208. +{
  31209. + int num;
  31210. +
  31211. + if(isTitle == MV_TRUE)
  31212. + mvOsPrintf("Event NumOfEvents TotalTime Average Min Max\n");
  31213. +
  31214. + num = pTimeEntry->count-pTimeEntry->left;
  31215. + if(num > 0)
  31216. + {
  31217. + mvOsPrintf("%-11s %6u 0x%08lx %6lu %6lu %6lu\n",
  31218. + pTimeEntry->name, num, pTimeEntry->total, pTimeEntry->total/num,
  31219. + pTimeEntry->min, pTimeEntry->max);
  31220. + }
  31221. +}
  31222. +
  31223. +/* Update MV_DEBUG_TIMES entry */
  31224. +void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry)
  31225. +{
  31226. + MV_U32 delta;
  31227. +
  31228. + if(pTimeEntry->left > 0)
  31229. + {
  31230. + if(pTimeEntry->end <= pTimeEntry->begin)
  31231. + {
  31232. + delta = pTimeEntry->begin - pTimeEntry->end;
  31233. + }
  31234. + else
  31235. + {
  31236. + delta = ((MV_U32)0x10000 - pTimeEntry->end) + pTimeEntry->begin;
  31237. + }
  31238. + pTimeEntry->total += delta;
  31239. +
  31240. + if(delta < pTimeEntry->min)
  31241. + pTimeEntry->min = delta;
  31242. +
  31243. + if(delta > pTimeEntry->max)
  31244. + pTimeEntry->max = delta;
  31245. +
  31246. + pTimeEntry->left--;
  31247. + }
  31248. +}
  31249. +
  31250. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvDebug.h
  31251. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.h 1970-01-01 01:00:00.000000000 +0100
  31252. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvDebug.h 2011-07-31 11:31:55.803522408 +0200
  31253. @@ -0,0 +1,178 @@
  31254. +/*******************************************************************************
  31255. +Copyright (C) Marvell International Ltd. and its affiliates
  31256. +
  31257. +This software file (the "File") is owned and distributed by Marvell
  31258. +International Ltd. and/or its affiliates ("Marvell") under the following
  31259. +alternative licensing terms. Once you have made an election to distribute the
  31260. +File under one of the following license alternatives, please (i) delete this
  31261. +introductory statement regarding license alternatives, (ii) delete the two
  31262. +license alternatives that you have not elected to use and (iii) preserve the
  31263. +Marvell copyright notice above.
  31264. +
  31265. +********************************************************************************
  31266. +Marvell Commercial License Option
  31267. +
  31268. +If you received this File from Marvell and you have entered into a commercial
  31269. +license agreement (a "Commercial License") with Marvell, the File is licensed
  31270. +to you under the terms of the applicable Commercial License.
  31271. +
  31272. +********************************************************************************
  31273. +Marvell GPL License Option
  31274. +
  31275. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31276. +modify this File in accordance with the terms and conditions of the General
  31277. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  31278. +available along with the File in the license.txt file or by writing to the Free
  31279. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  31280. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  31281. +
  31282. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  31283. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  31284. +DISCLAIMED. The GPL License provides additional details about this warranty
  31285. +disclaimer.
  31286. +********************************************************************************
  31287. +Marvell BSD License Option
  31288. +
  31289. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31290. +modify this File under the following licensing terms.
  31291. +Redistribution and use in source and binary forms, with or without modification,
  31292. +are permitted provided that the following conditions are met:
  31293. +
  31294. + * Redistributions of source code must retain the above copyright notice,
  31295. + this list of conditions and the following disclaimer.
  31296. +
  31297. + * Redistributions in binary form must reproduce the above copyright
  31298. + notice, this list of conditions and the following disclaimer in the
  31299. + documentation and/or other materials provided with the distribution.
  31300. +
  31301. + * Neither the name of Marvell nor the names of its contributors may be
  31302. + used to endorse or promote products derived from this software without
  31303. + specific prior written permission.
  31304. +
  31305. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  31306. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  31307. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31308. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  31309. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  31310. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31311. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  31312. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31313. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31314. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31315. +
  31316. +*******************************************************************************/
  31317. +
  31318. +
  31319. +
  31320. +#ifndef __INCmvDebugh
  31321. +#define __INCmvDebugh
  31322. +
  31323. +/* includes */
  31324. +#include "mvTypes.h"
  31325. +
  31326. +typedef enum
  31327. +{
  31328. + MV_MODULE_INVALID = -1,
  31329. + MV_MODULE_ETH = 0,
  31330. + MV_MODULE_IDMA,
  31331. + MV_MODULE_XOR,
  31332. + MV_MODULE_TWASI,
  31333. + MV_MODULE_MGI,
  31334. + MV_MODULE_USB,
  31335. + MV_MODULE_CESA,
  31336. +
  31337. + MV_MODULE_MAX
  31338. +}MV_MODULE_ID;
  31339. +
  31340. +/* Define generic flags useful for most of modules */
  31341. +#define MV_DEBUG_FLAG_ALL (0)
  31342. +#define MV_DEBUG_FLAG_INIT (1 << 0)
  31343. +#define MV_DEBUG_FLAG_RX (1 << 1)
  31344. +#define MV_DEBUG_FLAG_TX (1 << 2)
  31345. +#define MV_DEBUG_FLAG_ERR (1 << 3)
  31346. +#define MV_DEBUG_FLAG_TRACE (1 << 4)
  31347. +#define MV_DEBUG_FLAG_DUMP (1 << 5)
  31348. +#define MV_DEBUG_FLAG_CACHE (1 << 6)
  31349. +#define MV_DEBUG_FLAG_IOCTL (1 << 7)
  31350. +#define MV_DEBUG_FLAG_STATS (1 << 8)
  31351. +
  31352. +extern MV_U32 mvDebug;
  31353. +extern MV_U32 mvDebugModules[MV_MODULE_MAX];
  31354. +
  31355. +#ifdef MV_DEBUG
  31356. +# define MV_DEBUG_PRINT(module, flags, msg) mvOsPrintf msg
  31357. +# define MV_DEBUG_CODE(module, flags, code) code
  31358. +#elif defined(MV_RT_DEBUG)
  31359. +# define MV_DEBUG_PRINT(module, flags, msg) \
  31360. + if( (mvDebug & (1<<(module))) && \
  31361. + ((mvDebugModules[(module)] & (flags)) == (flags)) ) \
  31362. + mvOsPrintf msg
  31363. +# define MV_DEBUG_CODE(module, flags, code) \
  31364. + if( (mvDebug & (1<<(module))) && \
  31365. + ((mvDebugModules[(module)] & (flags)) == (flags)) ) \
  31366. + code
  31367. +#else
  31368. +# define MV_DEBUG_PRINT(module, flags, msg)
  31369. +# define MV_DEBUG_CODE(module, flags, code)
  31370. +#endif
  31371. +
  31372. +
  31373. +
  31374. +/* typedefs */
  31375. +
  31376. +/* time measurement structure used to check how much time pass between
  31377. + * two points
  31378. + */
  31379. +typedef struct {
  31380. + char name[20]; /* name of the entry */
  31381. + unsigned long begin; /* time measured on begin point */
  31382. + unsigned long end; /* time measured on end point */
  31383. + unsigned long total; /* Accumulated time */
  31384. + unsigned long left; /* The rest measurement actions */
  31385. + unsigned long count; /* Maximum measurement actions */
  31386. + unsigned long min; /* Minimum time from begin to end */
  31387. + unsigned long max; /* Maximum time from begin to end */
  31388. +} MV_DEBUG_TIMES;
  31389. +
  31390. +
  31391. +/* mvDebug.h API list */
  31392. +
  31393. +/****** Error Recording ******/
  31394. +
  31395. +/* Dump memory in specific format:
  31396. + * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8
  31397. + */
  31398. +void mvDebugMemDump(void* addr, int size, int access);
  31399. +
  31400. +void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access);
  31401. +
  31402. +void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access);
  31403. +
  31404. +void mvDebugPrintIpAddr(MV_U32 ipAddr);
  31405. +
  31406. +void mvDebugPrintMacAddr(const MV_U8* pMacAddr);
  31407. +
  31408. +/**** There are three functions deals with MV_DEBUG_TIMES structure ****/
  31409. +
  31410. +/* Reset MV_DEBUG_TIMES entry */
  31411. +void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* name);
  31412. +
  31413. +/* Update MV_DEBUG_TIMES entry */
  31414. +void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry);
  31415. +
  31416. +/* Print out MV_DEBUG_TIMES entry */
  31417. +void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle);
  31418. +
  31419. +
  31420. +/******** General ***********/
  31421. +
  31422. +/* Change value of mvDebugPrint global variable */
  31423. +
  31424. +void mvDebugInit(void);
  31425. +void mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable);
  31426. +void mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags);
  31427. +void mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags);
  31428. +
  31429. +
  31430. +#endif /* __INCmvDebug.h */
  31431. +
  31432. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h
  31433. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h 1970-01-01 01:00:00.000000000 +0100
  31434. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h 2011-07-31 11:31:55.873417677 +0200
  31435. @@ -0,0 +1,225 @@
  31436. +/*******************************************************************************
  31437. +Copyright (C) Marvell International Ltd. and its affiliates
  31438. +
  31439. +This software file (the "File") is owned and distributed by Marvell
  31440. +International Ltd. and/or its affiliates ("Marvell") under the following
  31441. +alternative licensing terms. Once you have made an election to distribute the
  31442. +File under one of the following license alternatives, please (i) delete this
  31443. +introductory statement regarding license alternatives, (ii) delete the two
  31444. +license alternatives that you have not elected to use and (iii) preserve the
  31445. +Marvell copyright notice above.
  31446. +
  31447. +********************************************************************************
  31448. +Marvell Commercial License Option
  31449. +
  31450. +If you received this File from Marvell and you have entered into a commercial
  31451. +license agreement (a "Commercial License") with Marvell, the File is licensed
  31452. +to you under the terms of the applicable Commercial License.
  31453. +
  31454. +********************************************************************************
  31455. +Marvell GPL License Option
  31456. +
  31457. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31458. +modify this File in accordance with the terms and conditions of the General
  31459. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  31460. +available along with the File in the license.txt file or by writing to the Free
  31461. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  31462. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  31463. +
  31464. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  31465. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  31466. +DISCLAIMED. The GPL License provides additional details about this warranty
  31467. +disclaimer.
  31468. +********************************************************************************
  31469. +Marvell BSD License Option
  31470. +
  31471. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31472. +modify this File under the following licensing terms.
  31473. +Redistribution and use in source and binary forms, with or without modification,
  31474. +are permitted provided that the following conditions are met:
  31475. +
  31476. + * Redistributions of source code must retain the above copyright notice,
  31477. + this list of conditions and the following disclaimer.
  31478. +
  31479. + * Redistributions in binary form must reproduce the above copyright
  31480. + notice, this list of conditions and the following disclaimer in the
  31481. + documentation and/or other materials provided with the distribution.
  31482. +
  31483. + * Neither the name of Marvell nor the names of its contributors may be
  31484. + used to endorse or promote products derived from this software without
  31485. + specific prior written permission.
  31486. +
  31487. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  31488. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  31489. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31490. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  31491. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  31492. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31493. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  31494. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31495. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31496. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31497. +
  31498. +*******************************************************************************/
  31499. +
  31500. +#ifndef __INCmvDeviceIdh
  31501. +#define __INCmvDeviceIdh
  31502. +
  31503. +#ifdef __cplusplus
  31504. +extern "C" {
  31505. +#endif /* __cplusplus */
  31506. +
  31507. +/* defines */
  31508. +#define MARVELL_VEN_ID 0x11ab
  31509. +
  31510. +/* Disco-3 */
  31511. +#define MV64460_DEV_ID 0x6480
  31512. +#define MV64460B_DEV_ID 0x6485
  31513. +#define MV64430_DEV_ID 0x6420
  31514. +
  31515. +/* Disco-5 */
  31516. +#define MV64560_DEV_ID 0x6450
  31517. +
  31518. +/* Disco-6 */
  31519. +#define MV64660_DEV_ID 0x6460
  31520. +
  31521. +/* Orion */
  31522. +#define MV_1181_DEV_ID 0x1181
  31523. +#define MV_5181_DEV_ID 0x5181
  31524. +#define MV_5281_DEV_ID 0x5281
  31525. +#define MV_5182_DEV_ID 0x5182
  31526. +#define MV_8660_DEV_ID 0x8660
  31527. +#define MV_5180_DEV_ID 0x5180
  31528. +#define MV_5082_DEV_ID 0x5082
  31529. +#define MV_1281_DEV_ID 0x1281
  31530. +#define MV_6082_DEV_ID 0x6082
  31531. +#define MV_6183_DEV_ID 0x6183
  31532. +#define MV_6183L_DEV_ID 0x6083
  31533. +
  31534. +#define MV_5281_D0_REV 0x4
  31535. +#define MV_5281_D0_ID ((MV_5281_DEV_ID << 16) | MV_5281_D0_REV)
  31536. +#define MV_5281_D0_NAME "88F5281 D0"
  31537. +
  31538. +#define MV_5281_D1_REV 0x5
  31539. +#define MV_5281_D1_ID ((MV_5281_DEV_ID << 16) | MV_5281_D1_REV)
  31540. +#define MV_5281_D1_NAME "88F5281 D1"
  31541. +
  31542. +#define MV_5281_D2_REV 0x6
  31543. +#define MV_5281_D2_ID ((MV_5281_DEV_ID << 16) | MV_5281_D2_REV)
  31544. +#define MV_5281_D2_NAME "88F5281 D2"
  31545. +
  31546. +
  31547. +#define MV_5181L_A0_REV 0x8 /* need for PCIE Er */
  31548. +#define MV_5181_A1_REV 0x1 /* for USB Er ..*/
  31549. +#define MV_5181_B0_REV 0x2
  31550. +#define MV_5181_B1_REV 0x3
  31551. +#define MV_5182_A1_REV 0x1
  31552. +#define MV_5180N_B1_REV 0x3
  31553. +#define MV_5181L_A0_ID ((MV_5181_DEV_ID << 16) | MV_5181L_A0_REV)
  31554. +
  31555. +
  31556. +
  31557. +/* kw */
  31558. +#define MV_6281_DEV_ID 0x6281
  31559. +#define MV_6192_DEV_ID 0x6192
  31560. +#define MV_6190_DEV_ID 0x6190
  31561. +#define MV_6180_DEV_ID 0x6180
  31562. +
  31563. +#define MV_6281_A0_REV 0x2
  31564. +#define MV_6281_A0_ID ((MV_6281_DEV_ID << 16) | MV_6281_A0_REV)
  31565. +#define MV_6281_A0_NAME "88F6281 A0"
  31566. +
  31567. +#define MV_6192_A0_REV 0x2
  31568. +#define MV_6192_A0_ID ((MV_6192_DEV_ID << 16) | MV_6192_A0_REV)
  31569. +#define MV_6192_A0_NAME "88F6192 A0"
  31570. +
  31571. +#define MV_6190_A0_REV 0x2
  31572. +#define MV_6190_A0_ID ((MV_6190_DEV_ID << 16) | MV_6190_A0_REV)
  31573. +#define MV_6190_A0_NAME "88F6190 A0"
  31574. +
  31575. +#define MV_6180_A0_REV 0x2
  31576. +#define MV_6180_A0_ID ((MV_6180_DEV_ID << 16) | MV_6180_A0_REV)
  31577. +#define MV_6180_A0_NAME "88F6180 A0"
  31578. +
  31579. +#define MV_6281_A1_REV 0x3
  31580. +#define MV_6281_A1_ID ((MV_6281_DEV_ID << 16) | MV_6281_A1_REV)
  31581. +#define MV_6281_A1_NAME "88F6281 A1"
  31582. +
  31583. +#define MV_6192_A1_REV 0x3
  31584. +#define MV_6192_A1_ID ((MV_6192_DEV_ID << 16) | MV_6192_A1_REV)
  31585. +#define MV_6192_A1_NAME "88F6192 A1"
  31586. +
  31587. +#define MV_6190_A1_REV 0x3
  31588. +#define MV_6190_A1_ID ((MV_6190_DEV_ID << 16) | MV_6190_A1_REV)
  31589. +#define MV_6190_A1_NAME "88F6190 A1"
  31590. +
  31591. +#define MV_6180_A1_REV 0x3
  31592. +#define MV_6180_A1_ID ((MV_6180_DEV_ID << 16) | MV_6180_A1_REV)
  31593. +#define MV_6180_A1_NAME "88F6180 A1"
  31594. +
  31595. +#define MV_88F6XXX_A0_REV 0x2
  31596. +#define MV_88F6XXX_A1_REV 0x3
  31597. +/* Disco-Duo */
  31598. +#define MV_78XX0_ZY_DEV_ID 0x6381
  31599. +#define MV_78XX0_ZY_NAME "MV78X00"
  31600. +
  31601. +#define MV_78XX0_Z0_REV 0x1
  31602. +#define MV_78XX0_Z0_ID ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Z0_REV)
  31603. +#define MV_78XX0_Z0_NAME "78X00 Z0"
  31604. +
  31605. +#define MV_78XX0_Y0_REV 0x2
  31606. +#define MV_78XX0_Y0_ID ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Y0_REV)
  31607. +#define MV_78XX0_Y0_NAME "78X00 Y0"
  31608. +
  31609. +#define MV_78XX0_DEV_ID 0x7800
  31610. +#define MV_78XX0_NAME "MV78X00"
  31611. +
  31612. +#define MV_76100_DEV_ID 0x7610
  31613. +#define MV_78200_DEV_ID 0x7820
  31614. +#define MV_78100_DEV_ID 0x7810
  31615. +#define MV_78XX0_A0_REV 0x1
  31616. +#define MV_78XX0_A1_REV 0x2
  31617. +
  31618. +#define MV_76100_NAME "MV76100"
  31619. +#define MV_78100_NAME "MV78100"
  31620. +#define MV_78200_NAME "MV78200"
  31621. +
  31622. +#define MV_76100_A0_ID ((MV_76100_DEV_ID << 16) | MV_78XX0_A0_REV)
  31623. +#define MV_78100_A0_ID ((MV_78100_DEV_ID << 16) | MV_78XX0_A0_REV)
  31624. +#define MV_78200_A0_ID ((MV_78200_DEV_ID << 16) | MV_78XX0_A0_REV)
  31625. +
  31626. +#define MV_76100_A1_ID ((MV_76100_DEV_ID << 16) | MV_78XX0_A1_REV)
  31627. +#define MV_78100_A1_ID ((MV_78100_DEV_ID << 16) | MV_78XX0_A1_REV)
  31628. +#define MV_78200_A1_ID ((MV_78200_DEV_ID << 16) | MV_78XX0_A1_REV)
  31629. +
  31630. +#define MV_76100_A0_NAME "MV76100 A0"
  31631. +#define MV_78100_A0_NAME "MV78100 A0"
  31632. +#define MV_78200_A0_NAME "MV78200 A0"
  31633. +#define MV_78XX0_A0_NAME "MV78XX0 A0"
  31634. +
  31635. +#define MV_76100_A1_NAME "MV76100 A1"
  31636. +#define MV_78100_A1_NAME "MV78100 A1"
  31637. +#define MV_78200_A1_NAME "MV78200 A1"
  31638. +#define MV_78XX0_A1_NAME "MV78XX0 A1"
  31639. +
  31640. +/*MV88F632X family*/
  31641. +#define MV_6321_DEV_ID 0x6321
  31642. +#define MV_6322_DEV_ID 0x6322
  31643. +#define MV_6323_DEV_ID 0x6323
  31644. +
  31645. +#define MV_6321_NAME "88F6321"
  31646. +#define MV_6322_NAME "88F6322"
  31647. +#define MV_6323_NAME "88F6323"
  31648. +
  31649. +#define MV_632X_A1_REV 0x2
  31650. +
  31651. +#define MV_6321_A1_ID ((MV_6321_DEV_ID << 16) | MV_632X_A1_REV)
  31652. +#define MV_6322_A1_ID ((MV_6322_DEV_ID << 16) | MV_632X_A1_REV)
  31653. +#define MV_6323_A1_ID ((MV_6323_DEV_ID << 16) | MV_632X_A1_REV)
  31654. +
  31655. +#define MV_6321_A1_NAME "88F6321 A1"
  31656. +#define MV_6322_A1_NAME "88F6322 A1"
  31657. +#define MV_6323_A1_NAME "88F6323 A1"
  31658. +
  31659. +
  31660. +#endif /* __INCmvDeviceIdh */
  31661. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h
  31662. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h 1970-01-01 01:00:00.000000000 +0100
  31663. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h 2011-07-31 11:31:55.933421370 +0200
  31664. @@ -0,0 +1,73 @@
  31665. +/*******************************************************************************
  31666. +Copyright (C) Marvell International Ltd. and its affiliates
  31667. +
  31668. +This software file (the "File") is owned and distributed by Marvell
  31669. +International Ltd. and/or its affiliates ("Marvell") under the following
  31670. +alternative licensing terms. Once you have made an election to distribute the
  31671. +File under one of the following license alternatives, please (i) delete this
  31672. +introductory statement regarding license alternatives, (ii) delete the two
  31673. +license alternatives that you have not elected to use and (iii) preserve the
  31674. +Marvell copyright notice above.
  31675. +
  31676. +********************************************************************************
  31677. +Marvell Commercial License Option
  31678. +
  31679. +If you received this File from Marvell and you have entered into a commercial
  31680. +license agreement (a "Commercial License") with Marvell, the File is licensed
  31681. +to you under the terms of the applicable Commercial License.
  31682. +
  31683. +********************************************************************************
  31684. +Marvell GPL License Option
  31685. +
  31686. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31687. +modify this File in accordance with the terms and conditions of the General
  31688. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  31689. +available along with the File in the license.txt file or by writing to the Free
  31690. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  31691. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  31692. +
  31693. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  31694. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  31695. +DISCLAIMED. The GPL License provides additional details about this warranty
  31696. +disclaimer.
  31697. +********************************************************************************
  31698. +Marvell BSD License Option
  31699. +
  31700. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31701. +modify this File under the following licensing terms.
  31702. +Redistribution and use in source and binary forms, with or without modification,
  31703. +are permitted provided that the following conditions are met:
  31704. +
  31705. + * Redistributions of source code must retain the above copyright notice,
  31706. + this list of conditions and the following disclaimer.
  31707. +
  31708. + * Redistributions in binary form must reproduce the above copyright
  31709. + notice, this list of conditions and the following disclaimer in the
  31710. + documentation and/or other materials provided with the distribution.
  31711. +
  31712. + * Neither the name of Marvell nor the names of its contributors may be
  31713. + used to endorse or promote products derived from this software without
  31714. + specific prior written permission.
  31715. +
  31716. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  31717. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  31718. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31719. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  31720. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  31721. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31722. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  31723. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31724. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31725. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31726. +
  31727. +*******************************************************************************/
  31728. +
  31729. +
  31730. +#ifndef __INCmvHalVerh
  31731. +#define __INCmvHalVerh
  31732. +
  31733. +/* Defines */
  31734. +#define MV_HAL_VERSION "FEROCEON_HAL_3_1_7"
  31735. +#define MV_RELEASE_BASELINE "SoCandControllers_FEROCEON_RELEASE_7_9_2009_KW_4_3_4_DD_2_1_4_6183_1_1_4"
  31736. +
  31737. +#endif /* __INCmvHalVerh */
  31738. \ No newline at end of file
  31739. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvStack.c
  31740. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.c 1970-01-01 01:00:00.000000000 +0100
  31741. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvStack.c 2011-07-31 11:31:56.005913316 +0200
  31742. @@ -0,0 +1,100 @@
  31743. +/*******************************************************************************
  31744. +* Copyright 2003, Marvell Semiconductor Israel LTD. *
  31745. +* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL. *
  31746. +* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT *
  31747. +* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE *
  31748. +* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL. *
  31749. +* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED, *
  31750. +* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE. *
  31751. +* *
  31752. +* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, *
  31753. +* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL *
  31754. +* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K. *
  31755. +* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL). *
  31756. +********************************************************************************
  31757. +* mvQueue.c
  31758. +*
  31759. +* FILENAME: $Workfile: mvStack.c $
  31760. +* REVISION: $Revision: 1.1 $
  31761. +* LAST UPDATE: $Modtime: $
  31762. +*
  31763. +* DESCRIPTION:
  31764. +* This file implements simple Stack LIFO functionality.
  31765. +*******************************************************************************/
  31766. +
  31767. +/* includes */
  31768. +#include "mvOs.h"
  31769. +#include "mvTypes.h"
  31770. +#include "mvDebug.h"
  31771. +#include "mvStack.h"
  31772. +
  31773. +/* defines */
  31774. +
  31775. +
  31776. +/* Public functions */
  31777. +
  31778. +
  31779. +/* Purpose: Create new stack
  31780. + * Inputs:
  31781. + * - MV_U32 noOfElements - maximum number of elements in the stack.
  31782. + * Each element 4 bytes size
  31783. + * Return: void* - pointer to created stack.
  31784. + */
  31785. +void* mvStackCreate(int numOfElements)
  31786. +{
  31787. + MV_STACK* pStack;
  31788. + MV_U32* pStackElements;
  31789. +
  31790. + pStack = (MV_STACK*)mvOsMalloc(sizeof(MV_STACK));
  31791. + pStackElements = (MV_U32*)mvOsMalloc(numOfElements*sizeof(MV_U32));
  31792. + if( (pStack == NULL) || (pStackElements == NULL) )
  31793. + {
  31794. + mvOsPrintf("mvStack: Can't create new stack\n");
  31795. + return NULL;
  31796. + }
  31797. + memset(pStackElements, 0, numOfElements*sizeof(MV_U32));
  31798. + pStack->numOfElements = numOfElements;
  31799. + pStack->stackIdx = 0;
  31800. + pStack->stackElements = pStackElements;
  31801. +
  31802. + return pStack;
  31803. +}
  31804. +
  31805. +/* Purpose: Delete existing stack
  31806. + * Inputs:
  31807. + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function
  31808. + *
  31809. + * Return: MV_STATUS MV_NOT_FOUND - Failure. StackHandle is not valid.
  31810. + * MV_OK - Success.
  31811. + */
  31812. +MV_STATUS mvStackDelete(void* stackHndl)
  31813. +{
  31814. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  31815. +
  31816. + if( (pStack == NULL) || (pStack->stackElements == NULL) )
  31817. + return MV_NOT_FOUND;
  31818. +
  31819. + mvOsFree(pStack->stackElements);
  31820. + mvOsFree(pStack);
  31821. +
  31822. + return MV_OK;
  31823. +}
  31824. +
  31825. +
  31826. +/* PrintOut status of the stack */
  31827. +void mvStackStatus(void* stackHndl, MV_BOOL isPrintElements)
  31828. +{
  31829. + int i;
  31830. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  31831. +
  31832. + mvOsPrintf("StackHandle=%p, pElements=%p, numElements=%d, stackIdx=%d\n",
  31833. + stackHndl, pStack->stackElements, pStack->numOfElements,
  31834. + pStack->stackIdx);
  31835. + if(isPrintElements == MV_TRUE)
  31836. + {
  31837. + for(i=0; i<pStack->stackIdx; i++)
  31838. + {
  31839. + mvOsPrintf("%3d. Value=0x%x\n", i, pStack->stackElements[i]);
  31840. + }
  31841. + }
  31842. +}
  31843. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvStack.h
  31844. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.h 1970-01-01 01:00:00.000000000 +0100
  31845. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvStack.h 2011-07-31 11:31:56.063417654 +0200
  31846. @@ -0,0 +1,140 @@
  31847. +/*******************************************************************************
  31848. +* Copyright 2003, Marvell Semiconductor Israel LTD. *
  31849. +* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL. *
  31850. +* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT *
  31851. +* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE *
  31852. +* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL. *
  31853. +* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED, *
  31854. +* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE. *
  31855. +* *
  31856. +* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, *
  31857. +* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL *
  31858. +* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K. *
  31859. +* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL). *
  31860. +********************************************************************************
  31861. +* mvStack.h - Header File for :
  31862. +*
  31863. +* FILENAME: $Workfile: mvStack.h $
  31864. +* REVISION: $Revision: 1.1 $
  31865. +* LAST UPDATE: $Modtime: $
  31866. +*
  31867. +* DESCRIPTION:
  31868. +* This file defines simple Stack (LIFO) functionality.
  31869. +*
  31870. +*******************************************************************************/
  31871. +
  31872. +#ifndef __mvStack_h__
  31873. +#define __mvStack_h__
  31874. +
  31875. +
  31876. +/* includes */
  31877. +#include "mvTypes.h"
  31878. +
  31879. +
  31880. +/* defines */
  31881. +
  31882. +
  31883. +/* typedefs */
  31884. +/* Data structure describes general purpose Stack */
  31885. +typedef struct
  31886. +{
  31887. + int stackIdx;
  31888. + int numOfElements;
  31889. + MV_U32* stackElements;
  31890. +} MV_STACK;
  31891. +
  31892. +static INLINE MV_BOOL mvStackIsFull(void* stackHndl)
  31893. +{
  31894. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  31895. +
  31896. + if(pStack->stackIdx == pStack->numOfElements)
  31897. + return MV_TRUE;
  31898. +
  31899. + return MV_FALSE;
  31900. +}
  31901. +
  31902. +static INLINE MV_BOOL mvStackIsEmpty(void* stackHndl)
  31903. +{
  31904. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  31905. +
  31906. + if(pStack->stackIdx == 0)
  31907. + return MV_TRUE;
  31908. +
  31909. + return MV_FALSE;
  31910. +}
  31911. +/* Purpose: Push new element to stack
  31912. + * Inputs:
  31913. + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function.
  31914. + * - MV_U32 value - New element.
  31915. + *
  31916. + * Return: MV_STATUS MV_FULL - Failure. Stack is full.
  31917. + * MV_OK - Success. Element is put to stack.
  31918. + */
  31919. +static INLINE void mvStackPush(void* stackHndl, MV_U32 value)
  31920. +{
  31921. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  31922. +
  31923. +#ifdef MV_RT_DEBUG
  31924. + if(pStack->stackIdx == pStack->numOfElements)
  31925. + {
  31926. + mvOsPrintf("mvStackPush: Stack is FULL\n");
  31927. + return;
  31928. + }
  31929. +#endif /* MV_RT_DEBUG */
  31930. +
  31931. + pStack->stackElements[pStack->stackIdx] = value;
  31932. + pStack->stackIdx++;
  31933. +}
  31934. +
  31935. +/* Purpose: Pop element from the top of stack and copy it to "pValue"
  31936. + * Inputs:
  31937. + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function.
  31938. + * - MV_U32 value - Element in the top of stack.
  31939. + *
  31940. + * Return: MV_STATUS MV_EMPTY - Failure. Stack is empty.
  31941. + * MV_OK - Success. Element is removed from the stack and
  31942. + * copied to pValue argument
  31943. + */
  31944. +static INLINE MV_U32 mvStackPop(void* stackHndl)
  31945. +{
  31946. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  31947. +
  31948. +#ifdef MV_RT_DEBUG
  31949. + if(pStack->stackIdx == 0)
  31950. + {
  31951. + mvOsPrintf("mvStackPop: Stack is EMPTY\n");
  31952. + return 0;
  31953. + }
  31954. +#endif /* MV_RT_DEBUG */
  31955. +
  31956. + pStack->stackIdx--;
  31957. + return pStack->stackElements[pStack->stackIdx];
  31958. +}
  31959. +
  31960. +static INLINE int mvStackIndex(void* stackHndl)
  31961. +{
  31962. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  31963. +
  31964. + return pStack->stackIdx;
  31965. +}
  31966. +
  31967. +static INLINE int mvStackFreeElements(void* stackHndl)
  31968. +{
  31969. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  31970. +
  31971. + return (pStack->numOfElements - pStack->stackIdx);
  31972. +}
  31973. +
  31974. +/* mvStack.h API list */
  31975. +
  31976. +/* Create new Stack */
  31977. +void* mvStackCreate(int numOfElements);
  31978. +
  31979. +/* Delete existing stack */
  31980. +MV_STATUS mvStackDelete(void* stackHndl);
  31981. +
  31982. +/* Print status of the stack */
  31983. +void mvStackStatus(void* stackHndl, MV_BOOL isPrintElements);
  31984. +
  31985. +#endif /* __mvStack_h__ */
  31986. +
  31987. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvTypes.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvTypes.h
  31988. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvTypes.h 1970-01-01 01:00:00.000000000 +0100
  31989. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvTypes.h 2011-07-31 11:31:56.133428544 +0200
  31990. @@ -0,0 +1,245 @@
  31991. +/*******************************************************************************
  31992. +Copyright (C) Marvell International Ltd. and its affiliates
  31993. +
  31994. +This software file (the "File") is owned and distributed by Marvell
  31995. +International Ltd. and/or its affiliates ("Marvell") under the following
  31996. +alternative licensing terms. Once you have made an election to distribute the
  31997. +File under one of the following license alternatives, please (i) delete this
  31998. +introductory statement regarding license alternatives, (ii) delete the two
  31999. +license alternatives that you have not elected to use and (iii) preserve the
  32000. +Marvell copyright notice above.
  32001. +
  32002. +********************************************************************************
  32003. +Marvell Commercial License Option
  32004. +
  32005. +If you received this File from Marvell and you have entered into a commercial
  32006. +license agreement (a "Commercial License") with Marvell, the File is licensed
  32007. +to you under the terms of the applicable Commercial License.
  32008. +
  32009. +********************************************************************************
  32010. +Marvell GPL License Option
  32011. +
  32012. +If you received this File from Marvell, you may opt to use, redistribute and/or
  32013. +modify this File in accordance with the terms and conditions of the General
  32014. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  32015. +available along with the File in the license.txt file or by writing to the Free
  32016. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  32017. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  32018. +
  32019. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  32020. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  32021. +DISCLAIMED. The GPL License provides additional details about this warranty
  32022. +disclaimer.
  32023. +********************************************************************************
  32024. +Marvell BSD License Option
  32025. +
  32026. +If you received this File from Marvell, you may opt to use, redistribute and/or
  32027. +modify this File under the following licensing terms.
  32028. +Redistribution and use in source and binary forms, with or without modification,
  32029. +are permitted provided that the following conditions are met:
  32030. +
  32031. + * Redistributions of source code must retain the above copyright notice,
  32032. + this list of conditions and the following disclaimer.
  32033. +
  32034. + * Redistributions in binary form must reproduce the above copyright
  32035. + notice, this list of conditions and the following disclaimer in the
  32036. + documentation and/or other materials provided with the distribution.
  32037. +
  32038. + * Neither the name of Marvell nor the names of its contributors may be
  32039. + used to endorse or promote products derived from this software without
  32040. + specific prior written permission.
  32041. +
  32042. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  32043. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  32044. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  32045. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  32046. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  32047. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  32048. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  32049. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  32050. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32051. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32052. +
  32053. +*******************************************************************************/
  32054. +
  32055. +
  32056. +#ifndef __INCmvTypesh
  32057. +#define __INCmvTypesh
  32058. +
  32059. +/* Defines */
  32060. +
  32061. +/* The following is a list of Marvell status */
  32062. +#define MV_ERROR (-1)
  32063. +#define MV_OK (0x00) /* Operation succeeded */
  32064. +#define MV_FAIL (0x01) /* Operation failed */
  32065. +#define MV_BAD_VALUE (0x02) /* Illegal value (general) */
  32066. +#define MV_OUT_OF_RANGE (0x03) /* The value is out of range */
  32067. +#define MV_BAD_PARAM (0x04) /* Illegal parameter in function called */
  32068. +#define MV_BAD_PTR (0x05) /* Illegal pointer value */
  32069. +#define MV_BAD_SIZE (0x06) /* Illegal size */
  32070. +#define MV_BAD_STATE (0x07) /* Illegal state of state machine */
  32071. +#define MV_SET_ERROR (0x08) /* Set operation failed */
  32072. +#define MV_GET_ERROR (0x09) /* Get operation failed */
  32073. +#define MV_CREATE_ERROR (0x0A) /* Fail while creating an item */
  32074. +#define MV_NOT_FOUND (0x0B) /* Item not found */
  32075. +#define MV_NO_MORE (0x0C) /* No more items found */
  32076. +#define MV_NO_SUCH (0x0D) /* No such item */
  32077. +#define MV_TIMEOUT (0x0E) /* Time Out */
  32078. +#define MV_NO_CHANGE (0x0F) /* Parameter(s) is already in this value */
  32079. +#define MV_NOT_SUPPORTED (0x10) /* This request is not support */
  32080. +#define MV_NOT_IMPLEMENTED (0x11) /* Request supported but not implemented */
  32081. +#define MV_NOT_INITIALIZED (0x12) /* The item is not initialized */
  32082. +#define MV_NO_RESOURCE (0x13) /* Resource not available (memory ...) */
  32083. +#define MV_FULL (0x14) /* Item is full (Queue or table etc...) */
  32084. +#define MV_EMPTY (0x15) /* Item is empty (Queue or table etc...) */
  32085. +#define MV_INIT_ERROR (0x16) /* Error occured while INIT process */
  32086. +#define MV_HW_ERROR (0x17) /* Hardware error */
  32087. +#define MV_TX_ERROR (0x18) /* Transmit operation not succeeded */
  32088. +#define MV_RX_ERROR (0x19) /* Recieve operation not succeeded */
  32089. +#define MV_NOT_READY (0x1A) /* The other side is not ready yet */
  32090. +#define MV_ALREADY_EXIST (0x1B) /* Tried to create existing item */
  32091. +#define MV_OUT_OF_CPU_MEM (0x1C) /* Cpu memory allocation failed. */
  32092. +#define MV_NOT_STARTED (0x1D) /* Not started yet */
  32093. +#define MV_BUSY (0x1E) /* Item is busy. */
  32094. +#define MV_TERMINATE (0x1F) /* Item terminates it's work. */
  32095. +#define MV_NOT_ALIGNED (0x20) /* Wrong alignment */
  32096. +#define MV_NOT_ALLOWED (0x21) /* Operation NOT allowed */
  32097. +#define MV_WRITE_PROTECT (0x22) /* Write protected */
  32098. +
  32099. +
  32100. +#define MV_INVALID (int)(-1)
  32101. +
  32102. +#define MV_FALSE 0
  32103. +#define MV_TRUE (!(MV_FALSE))
  32104. +
  32105. +
  32106. +#ifndef NULL
  32107. +#define NULL ((void*)0)
  32108. +#endif
  32109. +
  32110. +
  32111. +#ifndef MV_ASMLANGUAGE
  32112. +/* typedefs */
  32113. +
  32114. +typedef char MV_8;
  32115. +typedef unsigned char MV_U8;
  32116. +
  32117. +typedef int MV_32;
  32118. +typedef unsigned int MV_U32;
  32119. +
  32120. +typedef short MV_16;
  32121. +typedef unsigned short MV_U16;
  32122. +
  32123. +#ifdef MV_PPC64
  32124. +typedef long MV_64;
  32125. +typedef unsigned long MV_U64;
  32126. +#else
  32127. +typedef long long MV_64;
  32128. +typedef unsigned long long MV_U64;
  32129. +#endif
  32130. +
  32131. +typedef long MV_LONG; /* 32/64 */
  32132. +typedef unsigned long MV_ULONG; /* 32/64 */
  32133. +
  32134. +typedef int MV_STATUS;
  32135. +typedef int MV_BOOL;
  32136. +typedef void MV_VOID;
  32137. +typedef float MV_FLOAT;
  32138. +
  32139. +typedef int (*MV_FUNCPTR) (void); /* ptr to function returning int */
  32140. +typedef void (*MV_VOIDFUNCPTR) (void); /* ptr to function returning void */
  32141. +typedef double (*MV_DBLFUNCPTR) (void); /* ptr to function returning double*/
  32142. +typedef float (*MV_FLTFUNCPTR) (void); /* ptr to function returning float */
  32143. +
  32144. +typedef MV_U32 MV_KHZ;
  32145. +typedef MV_U32 MV_MHZ;
  32146. +typedef MV_U32 MV_HZ;
  32147. +
  32148. +
  32149. +/* This enumerator describes the set of commands that can be applied on */
  32150. +/* an engine (e.g. IDMA, XOR). Appling a comman depends on the current */
  32151. +/* status (see MV_STATE enumerator) */
  32152. +/* Start can be applied only when status is IDLE */
  32153. +/* Stop can be applied only when status is IDLE, ACTIVE or PAUSED */
  32154. +/* Pause can be applied only when status is ACTIVE */
  32155. +/* Restart can be applied only when status is PAUSED */
  32156. +typedef enum _mvCommand
  32157. +{
  32158. + MV_START, /* Start */
  32159. + MV_STOP, /* Stop */
  32160. + MV_PAUSE, /* Pause */
  32161. + MV_RESTART /* Restart */
  32162. +} MV_COMMAND;
  32163. +
  32164. +/* This enumerator describes the set of state conditions. */
  32165. +/* Moving from one state to other is stricted. */
  32166. +typedef enum _mvState
  32167. +{
  32168. + MV_IDLE,
  32169. + MV_ACTIVE,
  32170. + MV_PAUSED,
  32171. + MV_UNDEFINED_STATE
  32172. +} MV_STATE;
  32173. +
  32174. +
  32175. +/* This structure describes address space window. Window base can be */
  32176. +/* 64 bit, window size up to 4GB */
  32177. +typedef struct _mvAddrWin
  32178. +{
  32179. + MV_U32 baseLow; /* 32bit base low */
  32180. + MV_U32 baseHigh; /* 32bit base high */
  32181. + MV_U32 size; /* 32bit size */
  32182. +}MV_ADDR_WIN;
  32183. +
  32184. +/* This binary enumerator describes protection attribute status */
  32185. +typedef enum _mvProtRight
  32186. +{
  32187. + ALLOWED, /* Protection attribute allowed */
  32188. + FORBIDDEN /* Protection attribute forbidden */
  32189. +}MV_PROT_RIGHT;
  32190. +
  32191. +/* Unified struct for Rx and Tx packet operations. The user is required to */
  32192. +/* be familier only with Tx/Rx descriptor command status. */
  32193. +typedef struct _bufInfo
  32194. +{
  32195. + MV_U32 cmdSts; /* Tx/Rx command status */
  32196. + MV_U16 byteCnt; /* Size of valid data in the buffer */
  32197. + MV_U16 bufSize; /* Total size of the buffer */
  32198. + MV_U8 *pBuff; /* Pointer to Buffer */
  32199. + MV_U8 *pData; /* Pointer to data in the Buffer */
  32200. + MV_U32 userInfo1; /* Tx/Rx attached user information 1 */
  32201. + MV_U32 userInfo2; /* Tx/Rx attached user information 2 */
  32202. + struct _bufInfo *pNextBufInfo; /* Next buffer in packet */
  32203. +} BUF_INFO;
  32204. +
  32205. +/* This structure contains information describing one of buffers
  32206. + * (fragments) they are built Ethernet packet.
  32207. + */
  32208. +typedef struct
  32209. +{
  32210. + MV_U8* bufVirtPtr;
  32211. + MV_ULONG bufPhysAddr;
  32212. + MV_U32 bufSize;
  32213. + MV_U32 dataSize;
  32214. + MV_U32 memHandle;
  32215. + MV_32 bufAddrShift;
  32216. +} MV_BUF_INFO;
  32217. +
  32218. +/* This structure contains information describing Ethernet packet.
  32219. + * The packet can be divided for few buffers (fragments)
  32220. + */
  32221. +typedef struct
  32222. +{
  32223. + MV_ULONG osInfo;
  32224. + MV_BUF_INFO *pFrags;
  32225. + MV_U32 status;
  32226. + MV_U16 pktSize;
  32227. + MV_U16 numFrags;
  32228. + MV_U32 ownerId;
  32229. + MV_U32 fragIP;
  32230. +} MV_PKT_INFO;
  32231. +
  32232. +#endif /* MV_ASMLANGUAGE */
  32233. +
  32234. +#endif /* __INCmvTypesh */
  32235. +
  32236. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/dbg-trace.c
  32237. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.c 1970-01-01 01:00:00.000000000 +0100
  32238. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/dbg-trace.c 2011-07-31 11:31:56.193415135 +0200
  32239. @@ -0,0 +1,110 @@
  32240. +#include <linux/kernel.h>
  32241. +#include <linux/slab.h>
  32242. +#include <linux/time.h>
  32243. +#include "dbg-trace.h"
  32244. +
  32245. +#define TRACE_ARR_LEN 800
  32246. +#define STR_LEN 128
  32247. +struct trace {
  32248. + struct timeval tv;
  32249. + char str[STR_LEN];
  32250. + unsigned int callback_val1;
  32251. + unsigned int callback_val2;
  32252. + char valid;
  32253. +};
  32254. +static unsigned int (*trc_callback1) (unsigned char) = NULL;
  32255. +static unsigned int (*trc_callback2) (unsigned char) = NULL;
  32256. +static unsigned char trc_param1 = 0;
  32257. +static unsigned char trc_param2 = 0;
  32258. +struct trace *trc_arr;
  32259. +static int trc_index;
  32260. +static int trc_active = 0;
  32261. +
  32262. +void TRC_START()
  32263. +{
  32264. + trc_active = 1;
  32265. +}
  32266. +
  32267. +void TRC_STOP()
  32268. +{
  32269. + trc_active = 0;
  32270. +}
  32271. +
  32272. +void TRC_INIT(void *callback1, void *callback2, unsigned char callback1_param, unsigned char callback2_param)
  32273. +{
  32274. + printk("Marvell debug tracing is on\n");
  32275. + trc_arr = (struct trace *)kmalloc(TRACE_ARR_LEN*sizeof(struct trace),GFP_KERNEL);
  32276. + if(trc_arr == NULL)
  32277. + {
  32278. + printk("Can't allocate Debug Trace buffer\n");
  32279. + return;
  32280. + }
  32281. + memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));
  32282. + trc_index = 0;
  32283. + trc_callback1 = callback1;
  32284. + trc_callback2 = callback2;
  32285. + trc_param1 = callback1_param;
  32286. + trc_param2 = callback2_param;
  32287. +}
  32288. +void TRC_REC(char *fmt,...)
  32289. +{
  32290. + va_list args;
  32291. + struct trace *trc = &trc_arr[trc_index];
  32292. +
  32293. + if(trc_active == 0)
  32294. + return;
  32295. +
  32296. + do_gettimeofday(&trc->tv);
  32297. + if(trc_callback1)
  32298. + trc->callback_val1 = trc_callback1(trc_param1);
  32299. + if(trc_callback2)
  32300. + trc->callback_val2 = trc_callback2(trc_param2);
  32301. + va_start(args, fmt);
  32302. + vsprintf(trc->str,fmt,args);
  32303. + va_end(args);
  32304. + trc->valid = 1;
  32305. + if((++trc_index) == TRACE_ARR_LEN) {
  32306. + trc_index = 0;
  32307. + }
  32308. +}
  32309. +void TRC_OUTPUT(void)
  32310. +{
  32311. + int i,j;
  32312. + struct trace *p;
  32313. + printk("\n\nTrace %d items\n",TRACE_ARR_LEN);
  32314. + for(i=0,j=trc_index; i<TRACE_ARR_LEN; i++,j++) {
  32315. + if(j == TRACE_ARR_LEN)
  32316. + j = 0;
  32317. + p = &trc_arr[j];
  32318. + if(p->valid) {
  32319. + unsigned long uoffs;
  32320. + struct trace *plast;
  32321. + if(p == &trc_arr[0])
  32322. + plast = &trc_arr[TRACE_ARR_LEN-1];
  32323. + else
  32324. + plast = p-1;
  32325. + if(p->tv.tv_sec == ((plast)->tv.tv_sec))
  32326. + uoffs = (p->tv.tv_usec - ((plast)->tv.tv_usec));
  32327. + else
  32328. + uoffs = (1000000 - ((plast)->tv.tv_usec)) +
  32329. + ((p->tv.tv_sec - ((plast)->tv.tv_sec) - 1) * 1000000) +
  32330. + p->tv.tv_usec;
  32331. + printk("%03d: [+%ld usec]", j, (unsigned long)uoffs);
  32332. + if(trc_callback1)
  32333. + printk("[%u]",p->callback_val1);
  32334. + if(trc_callback2)
  32335. + printk("[%u]",p->callback_val2);
  32336. + printk(": %s",p->str);
  32337. + }
  32338. + p->valid = 0;
  32339. + }
  32340. + memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));
  32341. + trc_index = 0;
  32342. +}
  32343. +void TRC_RELEASE(void)
  32344. +{
  32345. + kfree(trc_arr);
  32346. + trc_index = 0;
  32347. +}
  32348. +
  32349. +
  32350. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/dbg-trace.h
  32351. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.h 1970-01-01 01:00:00.000000000 +0100
  32352. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/dbg-trace.h 2011-07-31 11:31:56.263424881 +0200
  32353. @@ -0,0 +1,24 @@
  32354. +
  32355. +#ifndef _MV_DBG_TRCE_H_
  32356. +#define _MV_DBG_TRCE_H_
  32357. +
  32358. +#ifdef CONFIG_MV_DBG_TRACE
  32359. +void TRC_INIT(void *callback1, void *callback2,
  32360. + unsigned char callback1_param, unsigned char callback2_param);
  32361. +void TRC_REC(char *fmt,...);
  32362. +void TRC_OUTPUT(void);
  32363. +void TRC_RELEASE(void);
  32364. +void TRC_START(void);
  32365. +void TRC_STOP(void);
  32366. +
  32367. +#else
  32368. +#define TRC_INIT(x1,x2,x3,x4)
  32369. +#define TRC_REC(X...)
  32370. +#define TRC_OUTPUT()
  32371. +#define TRC_RELEASE()
  32372. +#define TRC_START()
  32373. +#define TRC_STOP()
  32374. +#endif
  32375. +
  32376. +
  32377. +#endif
  32378. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c
  32379. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c 1970-01-01 01:00:00.000000000 +0100
  32380. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c 2011-07-31 11:31:56.353421386 +0200
  32381. @@ -0,0 +1,2513 @@
  32382. +/*******************************************************************************
  32383. +Copyright (C) Marvell International Ltd. and its affiliates
  32384. +
  32385. +This software file (the "File") is owned and distributed by Marvell
  32386. +International Ltd. and/or its affiliates ("Marvell") under the following
  32387. +alternative licensing terms. Once you have made an election to distribute the
  32388. +File under one of the following license alternatives, please (i) delete this
  32389. +introductory statement regarding license alternatives, (ii) delete the two
  32390. +license alternatives that you have not elected to use and (iii) preserve the
  32391. +Marvell copyright notice above.
  32392. +
  32393. +********************************************************************************
  32394. +Marvell Commercial License Option
  32395. +
  32396. +If you received this File from Marvell and you have entered into a commercial
  32397. +license agreement (a "Commercial License") with Marvell, the File is licensed
  32398. +to you under the terms of the applicable Commercial License.
  32399. +
  32400. +********************************************************************************
  32401. +Marvell GPL License Option
  32402. +
  32403. +If you received this File from Marvell, you may opt to use, redistribute and/or
  32404. +modify this File in accordance with the terms and conditions of the General
  32405. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  32406. +available along with the File in the license.txt file or by writing to the Free
  32407. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  32408. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  32409. +
  32410. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  32411. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  32412. +DISCLAIMED. The GPL License provides additional details about this warranty
  32413. +disclaimer.
  32414. +********************************************************************************
  32415. +Marvell BSD License Option
  32416. +
  32417. +If you received this File from Marvell, you may opt to use, redistribute and/or
  32418. +modify this File under the following licensing terms.
  32419. +Redistribution and use in source and binary forms, with or without modification,
  32420. +are permitted provided that the following conditions are met:
  32421. +
  32422. + * Redistributions of source code must retain the above copyright notice,
  32423. + this list of conditions and the following disclaimer.
  32424. +
  32425. + * Redistributions in binary form must reproduce the above copyright
  32426. + notice, this list of conditions and the following disclaimer in the
  32427. + documentation and/or other materials provided with the distribution.
  32428. +
  32429. + * Neither the name of Marvell nor the names of its contributors may be
  32430. + used to endorse or promote products derived from this software without
  32431. + specific prior written permission.
  32432. +
  32433. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  32434. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  32435. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  32436. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  32437. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  32438. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  32439. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  32440. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  32441. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32442. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32443. +
  32444. +*******************************************************************************/
  32445. +
  32446. +#include "boardEnv/mvBoardEnvLib.h"
  32447. +#include "ctrlEnv/mvCtrlEnvLib.h"
  32448. +#include "ctrlEnv/sys/mvCpuIf.h"
  32449. +#include "cpu/mvCpu.h"
  32450. +#include "cntmr/mvCntmr.h"
  32451. +#include "gpp/mvGpp.h"
  32452. +#include "twsi/mvTwsi.h"
  32453. +#include "pex/mvPex.h"
  32454. +#include "device/mvDevice.h"
  32455. +#include "eth/gbe/mvEthRegs.h"
  32456. +
  32457. +/* defines */
  32458. +/* #define MV_DEBUG */
  32459. +#ifdef MV_DEBUG
  32460. + #define DB(x) x
  32461. +#else
  32462. + #define DB(x)
  32463. +#endif
  32464. +
  32465. +extern MV_CPU_ARM_CLK _cpuARMDDRCLK[];
  32466. +
  32467. +#define CODE_IN_ROM MV_FALSE
  32468. +#define CODE_IN_RAM MV_TRUE
  32469. +
  32470. +extern MV_BOARD_INFO* boardInfoTbl[];
  32471. +#define BOARD_INFO(boardId) boardInfoTbl[boardId - BOARD_ID_BASE]
  32472. +
  32473. +/* Locals */
  32474. +static MV_DEV_CS_INFO* boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  32475. +
  32476. +MV_U32 tClkRate = -1;
  32477. +
  32478. +
  32479. +/*******************************************************************************
  32480. +* mvBoardEnvInit - Init board
  32481. +*
  32482. +* DESCRIPTION:
  32483. +* In this function the board environment take care of device bank
  32484. +* initialization.
  32485. +*
  32486. +* INPUT:
  32487. +* None.
  32488. +*
  32489. +* OUTPUT:
  32490. +* None.
  32491. +*
  32492. +* RETURN:
  32493. +* None.
  32494. +*
  32495. +*******************************************************************************/
  32496. +MV_VOID mvBoardEnvInit(MV_VOID)
  32497. +{
  32498. + MV_U32 boardId= mvBoardIdGet();
  32499. +
  32500. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32501. + {
  32502. + mvOsPrintf("mvBoardEnvInit:Board unknown.\n");
  32503. + return;
  32504. +
  32505. + }
  32506. +
  32507. + /* Set GPP Out value */
  32508. + MV_REG_WRITE(GPP_DATA_OUT_REG(0), BOARD_INFO(boardId)->gppOutValLow);
  32509. + MV_REG_WRITE(GPP_DATA_OUT_REG(1), BOARD_INFO(boardId)->gppOutValHigh);
  32510. +
  32511. + /* set GPP polarity */
  32512. + mvGppPolaritySet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValLow);
  32513. + mvGppPolaritySet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValHigh);
  32514. +
  32515. + /* Workaround for Erratum FE-MISC-70*/
  32516. + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV)
  32517. + {
  32518. + BOARD_INFO(boardId)->gppOutEnValLow &= 0xfffffffd;
  32519. + BOARD_INFO(boardId)->gppOutEnValLow |= (BOARD_INFO(boardId)->gppOutEnValHigh) & 0x00000002;
  32520. + } /*End of WA*/
  32521. +
  32522. + /* Set GPP Out Enable*/
  32523. + mvGppTypeSet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValLow);
  32524. + mvGppTypeSet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValHigh);
  32525. +
  32526. + /* Nand CE */
  32527. + MV_REG_BIT_SET(NAND_CTRL_REG, NAND_ACTCEBOOT_BIT);
  32528. +}
  32529. +
  32530. +/*******************************************************************************
  32531. +* mvBoardModelGet - Get Board model
  32532. +*
  32533. +* DESCRIPTION:
  32534. +* This function returns 16bit describing board model.
  32535. +* Board model is constructed of one byte major and minor numbers in the
  32536. +* following manner:
  32537. +*
  32538. +* INPUT:
  32539. +* None.
  32540. +*
  32541. +* OUTPUT:
  32542. +* None.
  32543. +*
  32544. +* RETURN:
  32545. +* String describing board model.
  32546. +*
  32547. +*******************************************************************************/
  32548. +MV_U16 mvBoardModelGet(MV_VOID)
  32549. +{
  32550. + return (mvBoardIdGet() >> 16);
  32551. +}
  32552. +
  32553. +/*******************************************************************************
  32554. +* mbBoardRevlGet - Get Board revision
  32555. +*
  32556. +* DESCRIPTION:
  32557. +* This function returns a 32bit describing the board revision.
  32558. +* Board revision is constructed of 4bytes. 2bytes describes major number
  32559. +* and the other 2bytes describes minor munber.
  32560. +* For example for board revision 3.4 the function will return
  32561. +* 0x00030004.
  32562. +*
  32563. +* INPUT:
  32564. +* None.
  32565. +*
  32566. +* OUTPUT:
  32567. +* None.
  32568. +*
  32569. +* RETURN:
  32570. +* String describing board model.
  32571. +*
  32572. +*******************************************************************************/
  32573. +MV_U16 mvBoardRevGet(MV_VOID)
  32574. +{
  32575. + return (mvBoardIdGet() & 0xFFFF);
  32576. +}
  32577. +
  32578. +/*******************************************************************************
  32579. +* mvBoardNameGet - Get Board name
  32580. +*
  32581. +* DESCRIPTION:
  32582. +* This function returns a string describing the board model and revision.
  32583. +* String is extracted from board I2C EEPROM.
  32584. +*
  32585. +* INPUT:
  32586. +* None.
  32587. +*
  32588. +* OUTPUT:
  32589. +* pNameBuff - Buffer to contain board name string. Minimum size 32 chars.
  32590. +*
  32591. +* RETURN:
  32592. +*
  32593. +* MV_ERROR if informantion can not be read.
  32594. +*******************************************************************************/
  32595. +MV_STATUS mvBoardNameGet(char *pNameBuff)
  32596. +{
  32597. + MV_U32 boardId= mvBoardIdGet();
  32598. +
  32599. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32600. + {
  32601. + mvOsSPrintf (pNameBuff, "Board unknown.\n");
  32602. + return MV_ERROR;
  32603. +
  32604. + }
  32605. +
  32606. + mvOsSPrintf (pNameBuff, "%s",BOARD_INFO(boardId)->boardName);
  32607. +
  32608. + return MV_OK;
  32609. +}
  32610. +
  32611. +/*******************************************************************************
  32612. +* mvBoardIsPortInSgmii -
  32613. +*
  32614. +* DESCRIPTION:
  32615. +* This routine returns MV_TRUE for port number works in SGMII or MV_FALSE
  32616. +* For all other options.
  32617. +*
  32618. +* INPUT:
  32619. +* ethPortNum - Ethernet port number.
  32620. +*
  32621. +* OUTPUT:
  32622. +* None.
  32623. +*
  32624. +* RETURN:
  32625. +* MV_TRUE - port in SGMII.
  32626. +* MV_FALSE - other.
  32627. +*
  32628. +*******************************************************************************/
  32629. +MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum)
  32630. +{
  32631. + MV_BOOL ethPortSgmiiSupport[BOARD_ETH_PORT_NUM] = MV_ETH_PORT_SGMII;
  32632. +
  32633. + if(ethPortNum >= BOARD_ETH_PORT_NUM)
  32634. + {
  32635. + mvOsPrintf ("Invalid portNo=%d\n", ethPortNum);
  32636. + return MV_FALSE;
  32637. + }
  32638. + return ethPortSgmiiSupport[ethPortNum];
  32639. +}
  32640. +
  32641. +/*******************************************************************************
  32642. +* mvBoardIsPortInGmii -
  32643. +*
  32644. +* DESCRIPTION:
  32645. +* This routine returns MV_TRUE for port number works in GMII or MV_FALSE
  32646. +* For all other options.
  32647. +*
  32648. +* INPUT:
  32649. +*
  32650. +* OUTPUT:
  32651. +* None.
  32652. +*
  32653. +* RETURN:
  32654. +* MV_TRUE - port in GMII.
  32655. +* MV_FALSE - other.
  32656. +*
  32657. +*******************************************************************************/
  32658. +MV_BOOL mvBoardIsPortInGmii(MV_VOID)
  32659. +{
  32660. + MV_U32 devClassId, devClass = 0;
  32661. + if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)
  32662. + {
  32663. + /* Get MPP module ID */
  32664. + devClassId = mvBoarModuleTypeGet(devClass);
  32665. + if (MV_BOARD_MODULE_GMII_ID == devClassId)
  32666. + return MV_TRUE;
  32667. + }
  32668. + else if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII)
  32669. + return MV_TRUE;
  32670. +
  32671. + return MV_FALSE;
  32672. +}
  32673. +/*******************************************************************************
  32674. +* mvBoardPhyAddrGet - Get the phy address
  32675. +*
  32676. +* DESCRIPTION:
  32677. +* This routine returns the Phy address of a given ethernet port.
  32678. +*
  32679. +* INPUT:
  32680. +* ethPortNum - Ethernet port number.
  32681. +*
  32682. +* OUTPUT:
  32683. +* None.
  32684. +*
  32685. +* RETURN:
  32686. +* 32bit describing Phy address, -1 if the port number is wrong.
  32687. +*
  32688. +*******************************************************************************/
  32689. +MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum)
  32690. +{
  32691. + MV_U32 boardId= mvBoardIdGet();
  32692. +
  32693. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32694. + {
  32695. + mvOsPrintf("mvBoardPhyAddrGet: Board unknown.\n");
  32696. + return MV_ERROR;
  32697. + }
  32698. +
  32699. + return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardEthSmiAddr;
  32700. +}
  32701. +
  32702. +/*******************************************************************************
  32703. +* mvBoardMacSpeedGet - Get the Mac speed
  32704. +*
  32705. +* DESCRIPTION:
  32706. +* This routine returns the Mac speed if pre define of a given ethernet port.
  32707. +*
  32708. +* INPUT:
  32709. +* ethPortNum - Ethernet port number.
  32710. +*
  32711. +* OUTPUT:
  32712. +* None.
  32713. +*
  32714. +* RETURN:
  32715. +* MV_BOARD_MAC_SPEED, -1 if the port number is wrong.
  32716. +*
  32717. +*******************************************************************************/
  32718. +MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum)
  32719. +{
  32720. + MV_U32 boardId= mvBoardIdGet();
  32721. +
  32722. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32723. + {
  32724. + mvOsPrintf("mvBoardMacSpeedGet: Board unknown.\n");
  32725. + return MV_ERROR;
  32726. + }
  32727. +
  32728. + return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardMacSpeed;
  32729. +}
  32730. +
  32731. +/*******************************************************************************
  32732. +* mvBoardLinkStatusIrqGet - Get the IRQ number for the link status indication
  32733. +*
  32734. +* DESCRIPTION:
  32735. +* This routine returns the IRQ number for the link status indication.
  32736. +*
  32737. +* INPUT:
  32738. +* ethPortNum - Ethernet port number.
  32739. +*
  32740. +* OUTPUT:
  32741. +* None.
  32742. +*
  32743. +* RETURN:
  32744. +* the number of the IRQ for the link status indication, -1 if the port
  32745. +* number is wrong or if not relevant.
  32746. +*
  32747. +*******************************************************************************/
  32748. +MV_32 mvBoardLinkStatusIrqGet(MV_U32 ethPortNum)
  32749. +{
  32750. + MV_U32 boardId = mvBoardIdGet();
  32751. +
  32752. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32753. + {
  32754. + mvOsPrintf("mvBoardLinkStatusIrqGet: Board unknown.\n");
  32755. + return MV_ERROR;
  32756. + }
  32757. +
  32758. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].linkStatusIrq;
  32759. +}
  32760. +
  32761. +/*******************************************************************************
  32762. +* mvBoardSwitchPortGet - Get the mapping between the board connector and the
  32763. +* Ethernet Switch port
  32764. +*
  32765. +* DESCRIPTION:
  32766. +* This routine returns the matching Switch port.
  32767. +*
  32768. +* INPUT:
  32769. +* ethPortNum - Ethernet port number.
  32770. +* boardPortNum - logical number of the connector on the board
  32771. +*
  32772. +* OUTPUT:
  32773. +* None.
  32774. +*
  32775. +* RETURN:
  32776. +* the matching Switch port, -1 if the port number is wrong or if not relevant.
  32777. +*
  32778. +*******************************************************************************/
  32779. +MV_32 mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum)
  32780. +{
  32781. + MV_U32 boardId = mvBoardIdGet();
  32782. +
  32783. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32784. + {
  32785. + mvOsPrintf("mvBoardSwitchPortGet: Board unknown.\n");
  32786. + return MV_ERROR;
  32787. + }
  32788. + if (boardPortNum >= BOARD_ETH_SWITCH_PORT_NUM)
  32789. + {
  32790. + mvOsPrintf("mvBoardSwitchPortGet: Illegal board port number.\n");
  32791. + return MV_ERROR;
  32792. + }
  32793. +
  32794. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdPort[boardPortNum];
  32795. +}
  32796. +
  32797. +/*******************************************************************************
  32798. +* mvBoardSwitchCpuPortGet - Get the the Ethernet Switch CPU port
  32799. +*
  32800. +* DESCRIPTION:
  32801. +* This routine returns the Switch CPU port.
  32802. +*
  32803. +* INPUT:
  32804. +* ethPortNum - Ethernet port number.
  32805. +*
  32806. +* OUTPUT:
  32807. +* None.
  32808. +*
  32809. +* RETURN:
  32810. +* the Switch CPU port, -1 if the port number is wrong or if not relevant.
  32811. +*
  32812. +*******************************************************************************/
  32813. +MV_32 mvBoardSwitchCpuPortGet(MV_U32 ethPortNum)
  32814. +{
  32815. + MV_U32 boardId = mvBoardIdGet();
  32816. +
  32817. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32818. + {
  32819. + mvOsPrintf("mvBoardSwitchCpuPortGet: Board unknown.\n");
  32820. + return MV_ERROR;
  32821. + }
  32822. +
  32823. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdCpuPort;
  32824. +}
  32825. +
  32826. +/*******************************************************************************
  32827. +* mvBoardIsSwitchConnected - Get switch connection status
  32828. +* DESCRIPTION:
  32829. +* This routine returns port's connection status
  32830. +*
  32831. +* INPUT:
  32832. +* ethPortNum - Ethernet port number.
  32833. +*
  32834. +* OUTPUT:
  32835. +* None.
  32836. +*
  32837. +* RETURN:
  32838. +* 1 - if ethPortNum is connected to switch, 0 otherwise
  32839. +*
  32840. +*******************************************************************************/
  32841. +MV_32 mvBoardIsSwitchConnected(MV_U32 ethPortNum)
  32842. +{
  32843. + MV_U32 boardId = mvBoardIdGet();
  32844. +
  32845. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32846. + {
  32847. + mvOsPrintf("mvBoardIsSwitchConnected: Board unknown.\n");
  32848. + return MV_ERROR;
  32849. + }
  32850. +
  32851. + if(ethPortNum >= BOARD_INFO(boardId)->numBoardMacInfo)
  32852. + {
  32853. + mvOsPrintf("mvBoardIsSwitchConnected: Illegal port number(%u)\n", ethPortNum);
  32854. + return MV_ERROR;
  32855. + }
  32856. +
  32857. + if((MV_32)(BOARD_INFO(boardId)->pSwitchInfo))
  32858. + return (MV_32)(BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].switchOnPort == ethPortNum);
  32859. + else
  32860. + return 0;
  32861. +}
  32862. +/*******************************************************************************
  32863. +* mvBoardSmiScanModeGet - Get Switch SMI scan mode
  32864. +*
  32865. +* DESCRIPTION:
  32866. +* This routine returns Switch SMI scan mode.
  32867. +*
  32868. +* INPUT:
  32869. +* ethPortNum - Ethernet port number.
  32870. +*
  32871. +* OUTPUT:
  32872. +* None.
  32873. +*
  32874. +* RETURN:
  32875. +* 1 for SMI_MANUAL_MODE, -1 if the port number is wrong or if not relevant.
  32876. +*
  32877. +*******************************************************************************/
  32878. +MV_32 mvBoardSmiScanModeGet(MV_U32 ethPortNum)
  32879. +{
  32880. + MV_U32 boardId = mvBoardIdGet();
  32881. +
  32882. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32883. + {
  32884. + mvOsPrintf("mvBoardSmiScanModeGet: Board unknown.\n");
  32885. + return MV_ERROR;
  32886. + }
  32887. +
  32888. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].smiScanMode;
  32889. +}
  32890. +/*******************************************************************************
  32891. +* mvBoardSpecInitGet -
  32892. +*
  32893. +* DESCRIPTION:
  32894. +*
  32895. +* INPUT:
  32896. +*
  32897. +* OUTPUT:
  32898. +* None.
  32899. +*
  32900. +* RETURN: Return MV_TRUE and parameters in case board need spesific phy init,
  32901. +* otherwise return MV_FALSE.
  32902. +*
  32903. +*
  32904. +*******************************************************************************/
  32905. +
  32906. +MV_BOOL mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data)
  32907. +{
  32908. + return MV_FALSE;
  32909. +}
  32910. +
  32911. +/*******************************************************************************
  32912. +* mvBoardTclkGet - Get the board Tclk (Controller clock)
  32913. +*
  32914. +* DESCRIPTION:
  32915. +* This routine extract the controller core clock.
  32916. +* This function uses the controller counters to make identification.
  32917. +* Note: In order to avoid interference, make sure task context switch
  32918. +* and interrupts will not occure during this function operation
  32919. +*
  32920. +* INPUT:
  32921. +* countNum - Counter number.
  32922. +*
  32923. +* OUTPUT:
  32924. +* None.
  32925. +*
  32926. +* RETURN:
  32927. +* 32bit clock cycles in Hertz.
  32928. +*
  32929. +*******************************************************************************/
  32930. +MV_U32 mvBoardTclkGet(MV_VOID)
  32931. +{
  32932. + if(mvCtrlModelGet()==MV_6281_DEV_ID)
  32933. + {
  32934. +#if defined(TCLK_AUTO_DETECT)
  32935. + MV_U32 tmpTClkRate = MV_BOARD_TCLK_166MHZ;
  32936. +
  32937. + tmpTClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  32938. + tmpTClkRate &= MSAR_TCLCK_MASK;
  32939. +
  32940. + switch (tmpTClkRate)
  32941. + {
  32942. + case MSAR_TCLCK_166:
  32943. + return MV_BOARD_TCLK_166MHZ;
  32944. + break;
  32945. + case MSAR_TCLCK_200:
  32946. + return MV_BOARD_TCLK_200MHZ;
  32947. + break;
  32948. + }
  32949. +#else
  32950. + return MV_BOARD_TCLK_200MHZ;
  32951. +#endif
  32952. + }
  32953. +
  32954. + return MV_BOARD_TCLK_166MHZ;
  32955. +
  32956. +}
  32957. +/*******************************************************************************
  32958. +* mvBoardSysClkGet - Get the board SysClk (CPU bus clock)
  32959. +*
  32960. +* DESCRIPTION:
  32961. +* This routine extract the CPU bus clock.
  32962. +*
  32963. +* INPUT:
  32964. +* countNum - Counter number.
  32965. +*
  32966. +* OUTPUT:
  32967. +* None.
  32968. +*
  32969. +* RETURN:
  32970. +* 32bit clock cycles in Hertz.
  32971. +*
  32972. +*******************************************************************************/
  32973. +static MV_U32 mvBoard6180SysClkGet(MV_VOID)
  32974. +{
  32975. + MV_U32 sysClkRate=0;
  32976. + MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
  32977. +
  32978. + sysClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  32979. + sysClkRate = sysClkRate & MSAR_CPUCLCK_MASK_6180;
  32980. + sysClkRate = sysClkRate >> MSAR_CPUCLCK_OFFS_6180;
  32981. +
  32982. + sysClkRate = _cpu6180_ddr_l2_CLK[sysClkRate].ddrClk;
  32983. +
  32984. + return sysClkRate;
  32985. +
  32986. +}
  32987. +
  32988. +MV_U32 mvBoardSysClkGet(MV_VOID)
  32989. +{
  32990. +#ifdef SYSCLK_AUTO_DETECT
  32991. + MV_U32 sysClkRate, tmp, pClkRate, indexDdrRtio;
  32992. + MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;
  32993. + MV_U32 ddrRtio[][2] = MV_DDR_CLCK_RTIO_TBL;
  32994. +
  32995. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  32996. + return mvBoard6180SysClkGet();
  32997. +
  32998. + tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  32999. + pClkRate = MSAR_CPUCLCK_EXTRACT(tmp);
  33000. + pClkRate = cpuCLK[pClkRate];
  33001. +
  33002. + indexDdrRtio = tmp & MSAR_DDRCLCK_RTIO_MASK;
  33003. + indexDdrRtio = indexDdrRtio >> MSAR_DDRCLCK_RTIO_OFFS;
  33004. + if(ddrRtio[indexDdrRtio][0] != 0)
  33005. + sysClkRate = ((pClkRate * ddrRtio[indexDdrRtio][1]) / ddrRtio[indexDdrRtio][0]);
  33006. + else
  33007. + sysClkRate = 0;
  33008. + return sysClkRate;
  33009. +#else
  33010. + return MV_BOARD_DEFAULT_SYSCLK;
  33011. +#endif
  33012. +}
  33013. +
  33014. +
  33015. +/*******************************************************************************
  33016. +* mvBoardPexBridgeIntPinGet - Get PEX to PCI bridge interrupt pin number
  33017. +*
  33018. +* DESCRIPTION:
  33019. +* Multi-ported PCI Express bridges that is implemented on the board
  33020. +* collapse interrupts across multiple conventional PCI/PCI-X buses.
  33021. +* A dual-headed PCI Express bridge would map (or "swizzle") the
  33022. +* interrupts per the following table (in accordance with the respective
  33023. +* logical PCI/PCI-X bridge's Device Number), collapse the INTA#-INTD#
  33024. +* signals from its two logical PCI/PCI-X bridges, collapse the
  33025. +* INTA#-INTD# signals from any internal sources, and convert the
  33026. +* signals to in-band PCI Express messages. 10
  33027. +* This function returns the upstream interrupt as it was converted by
  33028. +* the bridge, according to board configuration and the following table:
  33029. +* PCI dev num
  33030. +* Interrupt pin 7, 8, 9
  33031. +* A -> A D C
  33032. +* B -> B A D
  33033. +* C -> C B A
  33034. +* D -> D C B
  33035. +*
  33036. +*
  33037. +* INPUT:
  33038. +* devNum - PCI/PCIX device number.
  33039. +* intPin - PCI Int pin
  33040. +*
  33041. +* OUTPUT:
  33042. +* None.
  33043. +*
  33044. +* RETURN:
  33045. +* Int pin connected to the Interrupt controller
  33046. +*
  33047. +*******************************************************************************/
  33048. +MV_U32 mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin)
  33049. +{
  33050. + MV_U32 realIntPin = ((intPin + (3 - (devNum % 4))) %4 );
  33051. +
  33052. + if (realIntPin == 0) return 4;
  33053. + else return realIntPin;
  33054. +
  33055. +}
  33056. +
  33057. +/*******************************************************************************
  33058. +* mvBoardDebugLedNumGet - Get number of debug Leds
  33059. +*
  33060. +* DESCRIPTION:
  33061. +* INPUT:
  33062. +* boardId
  33063. +*
  33064. +* OUTPUT:
  33065. +* None.
  33066. +*
  33067. +* RETURN:
  33068. +* None.
  33069. +*
  33070. +*******************************************************************************/
  33071. +MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId)
  33072. +{
  33073. + return BOARD_INFO(boardId)->activeLedsNumber;
  33074. +}
  33075. +
  33076. +/*******************************************************************************
  33077. +* mvBoardDebugLeg - Set the board debug Leds
  33078. +*
  33079. +* DESCRIPTION: turn on/off status leds.
  33080. +* Note: assume MPP leds are part of group 0 only.
  33081. +*
  33082. +* INPUT:
  33083. +* hexNum - Number to be displied in hex by Leds.
  33084. +*
  33085. +* OUTPUT:
  33086. +* None.
  33087. +*
  33088. +* RETURN:
  33089. +* None.
  33090. +*
  33091. +*******************************************************************************/
  33092. +MV_VOID mvBoardDebugLed(MV_U32 hexNum)
  33093. +{
  33094. + MV_U32 val = 0,totalMask, currentBitMask = 1,i;
  33095. + MV_U32 boardId= mvBoardIdGet();
  33096. +
  33097. + if (BOARD_INFO(boardId)->pLedGppPin == NULL)
  33098. + return;
  33099. +
  33100. + totalMask = (1 << BOARD_INFO(boardId)->activeLedsNumber) -1;
  33101. + hexNum &= totalMask;
  33102. + totalMask = 0;
  33103. +
  33104. + for (i = 0 ; i < BOARD_INFO(boardId)->activeLedsNumber ; i++)
  33105. + {
  33106. + if (hexNum & currentBitMask)
  33107. + {
  33108. + val |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);
  33109. + }
  33110. +
  33111. + totalMask |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);
  33112. +
  33113. + currentBitMask = (currentBitMask << 1);
  33114. + }
  33115. +
  33116. + if (BOARD_INFO(boardId)->ledsPolarity)
  33117. + {
  33118. + mvGppValueSet(0, totalMask, val);
  33119. + }
  33120. + else
  33121. + {
  33122. + mvGppValueSet(0, totalMask, ~val);
  33123. + }
  33124. +}
  33125. +
  33126. +
  33127. +/*******************************************************************************
  33128. +* mvBoarGpioPinGet - mvBoarGpioPinGet
  33129. +*
  33130. +* DESCRIPTION:
  33131. +*
  33132. +* INPUT:
  33133. +* class - MV_BOARD_GPP_CLASS enum.
  33134. +*
  33135. +* OUTPUT:
  33136. +* None.
  33137. +*
  33138. +* RETURN:
  33139. +* GPIO pin number. The function return -1 for bad parameters.
  33140. +*
  33141. +*******************************************************************************/
  33142. +MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index)
  33143. +{
  33144. + MV_U32 boardId, i;
  33145. + MV_U32 indexFound = 0;
  33146. +
  33147. + boardId = mvBoardIdGet();
  33148. +
  33149. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33150. + {
  33151. + mvOsPrintf("mvBoardRTCGpioPinGet:Board unknown.\n");
  33152. + return MV_ERROR;
  33153. +
  33154. + }
  33155. +
  33156. + for (i = 0; i < BOARD_INFO(boardId)->numBoardGppInfo; i++)
  33157. + if (BOARD_INFO(boardId)->pBoardGppInfo[i].devClass == class) {
  33158. + if (indexFound == index)
  33159. + return (MV_U32)BOARD_INFO(boardId)->pBoardGppInfo[i].gppPinNum;
  33160. + else
  33161. + indexFound++;
  33162. +
  33163. + }
  33164. +
  33165. + return MV_ERROR;
  33166. +}
  33167. +
  33168. +
  33169. +/*******************************************************************************
  33170. +* mvBoardRTCGpioPinGet - mvBoardRTCGpioPinGet
  33171. +*
  33172. +* DESCRIPTION:
  33173. +*
  33174. +* INPUT:
  33175. +* None.
  33176. +*
  33177. +* OUTPUT:
  33178. +* None.
  33179. +*
  33180. +* RETURN:
  33181. +* GPIO pin number. The function return -1 for bad parameters.
  33182. +*
  33183. +*******************************************************************************/
  33184. +MV_32 mvBoardRTCGpioPinGet(MV_VOID)
  33185. +{
  33186. + return mvBoarGpioPinNumGet(BOARD_GPP_RTC, 0);
  33187. +}
  33188. +
  33189. +
  33190. +/*******************************************************************************
  33191. +* mvBoardReset - mvBoardReset
  33192. +*
  33193. +* DESCRIPTION:
  33194. +* Reset the board
  33195. +* INPUT:
  33196. +* None.
  33197. +*
  33198. +* OUTPUT:
  33199. +* None.
  33200. +*
  33201. +* RETURN:
  33202. +* None
  33203. +*
  33204. +*******************************************************************************/
  33205. +MV_VOID mvBoardReset(MV_VOID)
  33206. +{
  33207. + MV_32 resetPin;
  33208. +
  33209. + /* Get gpp reset pin if define */
  33210. + resetPin = mvBoardResetGpioPinGet();
  33211. + if (resetPin != MV_ERROR)
  33212. + {
  33213. + MV_REG_BIT_RESET( GPP_DATA_OUT_REG(0) ,(1 << resetPin));
  33214. + MV_REG_BIT_RESET( GPP_DATA_OUT_EN_REG(0) ,(1 << resetPin));
  33215. +
  33216. + }
  33217. + else
  33218. + {
  33219. + /* No gpp reset pin was found, try to reset ussing
  33220. + system reset out */
  33221. + MV_REG_BIT_SET( CPU_RSTOUTN_MASK_REG , BIT2);
  33222. + MV_REG_BIT_SET( CPU_SYS_SOFT_RST_REG , BIT0);
  33223. + }
  33224. +}
  33225. +
  33226. +/*******************************************************************************
  33227. +* mvBoardResetGpioPinGet - mvBoardResetGpioPinGet
  33228. +*
  33229. +* DESCRIPTION:
  33230. +*
  33231. +* INPUT:
  33232. +* None.
  33233. +*
  33234. +* OUTPUT:
  33235. +* None.
  33236. +*
  33237. +* RETURN:
  33238. +* GPIO pin number. The function return -1 for bad parameters.
  33239. +*
  33240. +*******************************************************************************/
  33241. +MV_32 mvBoardResetGpioPinGet(MV_VOID)
  33242. +{
  33243. + return mvBoarGpioPinNumGet(BOARD_GPP_RESET, 0);
  33244. +}
  33245. +/*******************************************************************************
  33246. +* mvBoardSDIOGpioPinGet - mvBoardSDIOGpioPinGet
  33247. +*
  33248. +* DESCRIPTION:
  33249. +* used for hotswap detection
  33250. +* INPUT:
  33251. +* None.
  33252. +*
  33253. +* OUTPUT:
  33254. +* None.
  33255. +*
  33256. +* RETURN:
  33257. +* GPIO pin number. The function return -1 for bad parameters.
  33258. +*
  33259. +*******************************************************************************/
  33260. +MV_32 mvBoardSDIOGpioPinGet(MV_VOID)
  33261. +{
  33262. + return mvBoarGpioPinNumGet(BOARD_GPP_SDIO_DETECT, 0);
  33263. +}
  33264. +
  33265. +/*******************************************************************************
  33266. +* mvBoardUSBVbusGpioPinGet - return Vbus input GPP
  33267. +*
  33268. +* DESCRIPTION:
  33269. +*
  33270. +* INPUT:
  33271. +* int devNo.
  33272. +*
  33273. +* OUTPUT:
  33274. +* None.
  33275. +*
  33276. +* RETURN:
  33277. +* GPIO pin number. The function return -1 for bad parameters.
  33278. +*
  33279. +*******************************************************************************/
  33280. +MV_32 mvBoardUSBVbusGpioPinGet(MV_32 devId)
  33281. +{
  33282. + return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS, devId);
  33283. +}
  33284. +
  33285. +/*******************************************************************************
  33286. +* mvBoardUSBVbusEnGpioPinGet - return Vbus Enable output GPP
  33287. +*
  33288. +* DESCRIPTION:
  33289. +*
  33290. +* INPUT:
  33291. +* int devNo.
  33292. +*
  33293. +* OUTPUT:
  33294. +* None.
  33295. +*
  33296. +* RETURN:
  33297. +* GPIO pin number. The function return -1 for bad parameters.
  33298. +*
  33299. +*******************************************************************************/
  33300. +MV_32 mvBoardUSBVbusEnGpioPinGet(MV_32 devId)
  33301. +{
  33302. + return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS_EN, devId);
  33303. +}
  33304. +
  33305. +
  33306. +/*******************************************************************************
  33307. +* mvBoardGpioIntMaskGet - Get GPIO mask for interrupt pins
  33308. +*
  33309. +* DESCRIPTION:
  33310. +* This function returns a 32-bit mask of GPP pins that connected to
  33311. +* interrupt generating sources on board.
  33312. +* For example if UART channel A is hardwired to GPP pin 8 and
  33313. +* UART channel B is hardwired to GPP pin 4 the fuinction will return
  33314. +* the value 0x000000110
  33315. +*
  33316. +* INPUT:
  33317. +* None.
  33318. +*
  33319. +* OUTPUT:
  33320. +* None.
  33321. +*
  33322. +* RETURN:
  33323. +* See description. The function return -1 if board is not identified.
  33324. +*
  33325. +*******************************************************************************/
  33326. +MV_32 mvBoardGpioIntMaskLowGet(MV_VOID)
  33327. +{
  33328. + MV_U32 boardId;
  33329. +
  33330. + boardId = mvBoardIdGet();
  33331. +
  33332. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33333. + {
  33334. + mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");
  33335. + return MV_ERROR;
  33336. +
  33337. + }
  33338. +
  33339. + return BOARD_INFO(boardId)->intsGppMaskLow;
  33340. +}
  33341. +MV_32 mvBoardGpioIntMaskHighGet(MV_VOID)
  33342. +{
  33343. + MV_U32 boardId;
  33344. +
  33345. + boardId = mvBoardIdGet();
  33346. +
  33347. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33348. + {
  33349. + mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");
  33350. + return MV_ERROR;
  33351. +
  33352. + }
  33353. +
  33354. + return BOARD_INFO(boardId)->intsGppMaskHigh;
  33355. +}
  33356. +
  33357. +
  33358. +/*******************************************************************************
  33359. +* mvBoardMppGet - Get board dependent MPP register value
  33360. +*
  33361. +* DESCRIPTION:
  33362. +* MPP settings are derived from board design.
  33363. +* MPP group consist of 8 MPPs. An MPP group represent MPP
  33364. +* control register.
  33365. +* This function retrieves board dependend MPP register value.
  33366. +*
  33367. +* INPUT:
  33368. +* mppGroupNum - MPP group number.
  33369. +*
  33370. +* OUTPUT:
  33371. +* None.
  33372. +*
  33373. +* RETURN:
  33374. +* 32bit value describing MPP control register value.
  33375. +*
  33376. +*******************************************************************************/
  33377. +MV_32 mvBoardMppGet(MV_U32 mppGroupNum)
  33378. +{
  33379. + MV_U32 boardId;
  33380. +
  33381. + boardId = mvBoardIdGet();
  33382. +
  33383. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33384. + {
  33385. + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
  33386. + return MV_ERROR;
  33387. +
  33388. + }
  33389. +
  33390. + return BOARD_INFO(boardId)->pBoardMppConfigValue[0].mppGroup[mppGroupNum];
  33391. +}
  33392. +
  33393. +
  33394. +/*******************************************************************************
  33395. +* mvBoardMppGroupId - If MPP group type is AUTO then identify it using twsi
  33396. +*
  33397. +* DESCRIPTION:
  33398. +*
  33399. +* INPUT:
  33400. +*
  33401. +* OUTPUT:
  33402. +* None.
  33403. +*
  33404. +* RETURN:
  33405. +*
  33406. +*******************************************************************************/
  33407. +MV_VOID mvBoardMppGroupIdUpdate(MV_VOID)
  33408. +{
  33409. +
  33410. + MV_BOARD_MPP_GROUP_CLASS devClass;
  33411. + MV_BOARD_MODULE_ID_CLASS devClassId;
  33412. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  33413. + MV_U32 devId;
  33414. + MV_U32 maxMppGrp = 1;
  33415. +
  33416. + devId = mvCtrlModelGet();
  33417. +
  33418. + switch(devId){
  33419. + case MV_6281_DEV_ID:
  33420. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  33421. + break;
  33422. + case MV_6192_DEV_ID:
  33423. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  33424. + break;
  33425. + case MV_6190_DEV_ID:
  33426. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  33427. + break;
  33428. + case MV_6180_DEV_ID:
  33429. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  33430. + break;
  33431. + }
  33432. +
  33433. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  33434. + {
  33435. + /* If MPP group can be defined by the module connected to it */
  33436. + if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)
  33437. + {
  33438. + /* Get MPP module ID */
  33439. + devClassId = mvBoarModuleTypeGet(devClass);
  33440. + if (MV_ERROR != devClassId)
  33441. + {
  33442. + switch(devClassId)
  33443. + {
  33444. + case MV_BOARD_MODULE_TDM_ID:
  33445. + case MV_BOARD_MODULE_TDM_5CHAN_ID:
  33446. + mppGroupType = MV_BOARD_TDM;
  33447. + break;
  33448. + case MV_BOARD_MODULE_AUDIO_ID:
  33449. + mppGroupType = MV_BOARD_AUDIO;
  33450. + break;
  33451. + case MV_BOARD_MODULE_RGMII_ID:
  33452. + mppGroupType = MV_BOARD_RGMII;
  33453. + break;
  33454. + case MV_BOARD_MODULE_GMII_ID:
  33455. + mppGroupType = MV_BOARD_GMII;
  33456. + break;
  33457. + case MV_BOARD_MODULE_TS_ID:
  33458. + mppGroupType = MV_BOARD_TS;
  33459. + break;
  33460. + case MV_BOARD_MODULE_MII_ID:
  33461. + mppGroupType = MV_BOARD_MII;
  33462. + break;
  33463. + default:
  33464. + mppGroupType = MV_BOARD_OTHER;
  33465. + break;
  33466. + }
  33467. + }
  33468. + else
  33469. + /* The module bay is empty */
  33470. + mppGroupType = MV_BOARD_OTHER;
  33471. +
  33472. + /* Update MPP group type */
  33473. + mvBoardMppGroupTypeSet(devClass, mppGroupType);
  33474. + }
  33475. +
  33476. + /* Update MPP output voltage for RGMII 1.8V. Set port to GMII for GMII module */
  33477. + if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_RGMII))
  33478. + MV_REG_BIT_SET(MPP_OUTPUT_DRIVE_REG,MPP_1_8_RGMII1_OUTPUT_DRIVE | MPP_1_8_RGMII0_OUTPUT_DRIVE);
  33479. + else
  33480. + {
  33481. + if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII))
  33482. + {
  33483. + MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);
  33484. + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(0),BIT3);
  33485. + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);
  33486. + }
  33487. + else if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_MII))
  33488. + {
  33489. + /* Assumption that the MDC & MDIO should be 3.3V */
  33490. + MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);
  33491. + /* Assumption that only ETH1 can be MII when using modules on DB */
  33492. + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);
  33493. + }
  33494. + }
  33495. + }
  33496. +}
  33497. +
  33498. +/*******************************************************************************
  33499. +* mvBoardMppGroupTypeGet
  33500. +*
  33501. +* DESCRIPTION:
  33502. +*
  33503. +* INPUT:
  33504. +* mppGroupClass - MPP group number 0 for MPP[35:20] or 1 for MPP[49:36].
  33505. +*
  33506. +* OUTPUT:
  33507. +* None.
  33508. +*
  33509. +* RETURN:
  33510. +*
  33511. +*******************************************************************************/
  33512. +MV_BOARD_MPP_TYPE_CLASS mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass)
  33513. +{
  33514. + MV_U32 boardId;
  33515. +
  33516. + boardId = mvBoardIdGet();
  33517. +
  33518. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33519. + {
  33520. + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
  33521. + return MV_ERROR;
  33522. +
  33523. + }
  33524. +
  33525. + if (mppGroupClass == MV_BOARD_MPP_GROUP_1)
  33526. + return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1;
  33527. + else
  33528. + return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2;
  33529. +}
  33530. +
  33531. +/*******************************************************************************
  33532. +* mvBoardMppGroupTypeSet
  33533. +*
  33534. +* DESCRIPTION:
  33535. +*
  33536. +* INPUT:
  33537. +* mppGroupClass - MPP group number 0 for MPP[35:20] or 1 for MPP[49:36].
  33538. +* mppGroupType - MPP group type for MPP[35:20] or for MPP[49:36].
  33539. +*
  33540. +* OUTPUT:
  33541. +* None.
  33542. +*
  33543. +* RETURN:
  33544. +*
  33545. +*******************************************************************************/
  33546. +MV_VOID mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,
  33547. + MV_BOARD_MPP_TYPE_CLASS mppGroupType)
  33548. +{
  33549. + MV_U32 boardId;
  33550. +
  33551. + boardId = mvBoardIdGet();
  33552. +
  33553. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33554. + {
  33555. + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
  33556. + }
  33557. +
  33558. + if (mppGroupClass == MV_BOARD_MPP_GROUP_1)
  33559. + BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1 = mppGroupType;
  33560. + else
  33561. + BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2 = mppGroupType;
  33562. +
  33563. +}
  33564. +
  33565. +/*******************************************************************************
  33566. +* mvBoardMppMuxSet - Update MPP mux
  33567. +*
  33568. +* DESCRIPTION:
  33569. +*
  33570. +* INPUT:
  33571. +*
  33572. +* OUTPUT:
  33573. +* None.
  33574. +*
  33575. +* RETURN:
  33576. +*
  33577. +*******************************************************************************/
  33578. +MV_VOID mvBoardMppMuxSet(MV_VOID)
  33579. +{
  33580. +
  33581. + MV_BOARD_MPP_GROUP_CLASS devClass;
  33582. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  33583. + MV_U32 devId;
  33584. + MV_U8 muxVal = 0xf;
  33585. + MV_U32 maxMppGrp = 1;
  33586. + MV_TWSI_SLAVE twsiSlave;
  33587. + MV_TWSI_ADDR slave;
  33588. +
  33589. + devId = mvCtrlModelGet();
  33590. +
  33591. + switch(devId){
  33592. + case MV_6281_DEV_ID:
  33593. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  33594. + break;
  33595. + case MV_6192_DEV_ID:
  33596. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  33597. + break;
  33598. + case MV_6190_DEV_ID:
  33599. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  33600. + break;
  33601. + case MV_6180_DEV_ID:
  33602. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  33603. + break;
  33604. + }
  33605. +
  33606. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  33607. + {
  33608. + mppGroupType = mvBoardMppGroupTypeGet(devClass);
  33609. +
  33610. + switch(mppGroupType)
  33611. + {
  33612. + case MV_BOARD_TDM:
  33613. + muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);
  33614. + break;
  33615. + case MV_BOARD_AUDIO:
  33616. + muxVal &= ~(devClass ? 0x7 : 0x0); /*old Z0 value 0xd:0x0*/
  33617. + break;
  33618. + case MV_BOARD_TS:
  33619. + muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);
  33620. + break;
  33621. + default:
  33622. + muxVal |= (devClass ? 0xf : 0);
  33623. + break;
  33624. + }
  33625. + }
  33626. +
  33627. + /* TWSI init */
  33628. + slave.type = ADDR7_BIT;
  33629. + slave.address = 0;
  33630. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33631. +
  33632. + /* Read MPP module ID */
  33633. + DB(mvOsPrintf("Board: twsi exp set\n"));
  33634. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);
  33635. + twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);
  33636. + twsiSlave.validOffset = MV_TRUE;
  33637. + /* Offset is the first command after the address which indicate the register number to be read
  33638. + in next operation */
  33639. + twsiSlave.offset = 2;
  33640. + twsiSlave.moreThen256 = MV_FALSE;
  33641. +
  33642. +
  33643. +
  33644. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  33645. + {
  33646. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  33647. + return;
  33648. + }
  33649. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  33650. +
  33651. + /* Change twsi exp to output */
  33652. + twsiSlave.offset = 6;
  33653. + muxVal = 0;
  33654. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  33655. + {
  33656. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  33657. + return;
  33658. + }
  33659. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  33660. +
  33661. +}
  33662. +
  33663. +/*******************************************************************************
  33664. +* mvBoardTdmMppSet - set MPPs in TDM module
  33665. +*
  33666. +* DESCRIPTION:
  33667. +*
  33668. +* INPUT: type of second telephony device
  33669. +*
  33670. +* OUTPUT:
  33671. +* None.
  33672. +*
  33673. +* RETURN:
  33674. +*
  33675. +*******************************************************************************/
  33676. +MV_VOID mvBoardTdmMppSet(MV_32 chType)
  33677. +{
  33678. +
  33679. + MV_BOARD_MPP_GROUP_CLASS devClass;
  33680. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  33681. + MV_U32 devId;
  33682. + MV_U8 muxVal = 1;
  33683. + MV_U8 muxValMask = 1;
  33684. + MV_U8 twsiVal;
  33685. + MV_U32 maxMppGrp = 1;
  33686. + MV_TWSI_SLAVE twsiSlave;
  33687. + MV_TWSI_ADDR slave;
  33688. +
  33689. + devId = mvCtrlModelGet();
  33690. +
  33691. + switch(devId){
  33692. + case MV_6281_DEV_ID:
  33693. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  33694. + break;
  33695. + case MV_6192_DEV_ID:
  33696. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  33697. + break;
  33698. + case MV_6190_DEV_ID:
  33699. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  33700. + break;
  33701. + case MV_6180_DEV_ID:
  33702. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  33703. + break;
  33704. + }
  33705. +
  33706. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  33707. + {
  33708. + mppGroupType = mvBoardMppGroupTypeGet(devClass);
  33709. + if(mppGroupType == MV_BOARD_TDM)
  33710. + break;
  33711. + }
  33712. +
  33713. + if(devClass == maxMppGrp)
  33714. + return; /* TDM module not found */
  33715. +
  33716. + /* TWSI init */
  33717. + slave.type = ADDR7_BIT;
  33718. + slave.address = 0;
  33719. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33720. +
  33721. + /* Read MPP module ID */
  33722. + DB(mvOsPrintf("Board: twsi exp set\n"));
  33723. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);
  33724. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  33725. + twsiSlave.validOffset = MV_TRUE;
  33726. + /* Offset is the first command after the address which indicate the register number to be read
  33727. + in next operation */
  33728. + twsiSlave.offset = 3;
  33729. + twsiSlave.moreThen256 = MV_FALSE;
  33730. +
  33731. + if(mvBoardIdGet() == RD_88F6281A_ID)
  33732. + {
  33733. + muxVal = 0xc;
  33734. + muxValMask = 0xf3;
  33735. + }
  33736. +
  33737. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33738. + muxVal = (twsiVal & muxValMask) | muxVal;
  33739. +
  33740. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  33741. + {
  33742. + mvOsPrintf("Board: twsi exp out val fail\n");
  33743. + return;
  33744. + }
  33745. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  33746. +
  33747. + /* Change twsi exp to output */
  33748. + twsiSlave.offset = 7;
  33749. + muxVal = 0xfe;
  33750. + if(mvBoardIdGet() == RD_88F6281A_ID)
  33751. + muxVal = 0xf3;
  33752. +
  33753. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33754. + muxVal = (twsiVal & muxVal);
  33755. +
  33756. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  33757. + {
  33758. + mvOsPrintf("Board: twsi exp change to out fail\n");
  33759. + return;
  33760. + }
  33761. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  33762. + /* reset the line to 0 */
  33763. + twsiSlave.offset = 3;
  33764. + muxVal = 0;
  33765. + muxValMask = 1;
  33766. +
  33767. + if(mvBoardIdGet() == RD_88F6281A_ID) {
  33768. + muxVal = 0x0;
  33769. + muxValMask = 0xf3;
  33770. + }
  33771. +
  33772. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33773. + muxVal = (twsiVal & muxValMask) | muxVal;
  33774. +
  33775. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  33776. + {
  33777. + mvOsPrintf("Board: twsi exp out val fail\n");
  33778. + return;
  33779. + }
  33780. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  33781. +
  33782. + mvOsDelay(20);
  33783. +
  33784. + /* set the line to 1 */
  33785. + twsiSlave.offset = 3;
  33786. + muxVal = 1;
  33787. + muxValMask = 1;
  33788. +
  33789. + if(mvBoardIdGet() == RD_88F6281A_ID)
  33790. + {
  33791. + muxVal = 0xc;
  33792. + muxValMask = 0xf3;
  33793. + if(chType) /* FXS - issue reset properly */
  33794. + {
  33795. + MV_REG_BIT_SET(GPP_DATA_OUT_REG(1), MV_GPP12);
  33796. + mvOsDelay(50);
  33797. + MV_REG_BIT_RESET(GPP_DATA_OUT_REG(1), MV_GPP12);
  33798. + }
  33799. + else /* FXO - issue reset via TDM_CODEC_RST*/
  33800. + {
  33801. + /* change MPP44 type to TDM_CODEC_RST(0x2) */
  33802. + MV_REG_WRITE(MPP_CONTROL_REG5, ((MV_REG_READ(MPP_CONTROL_REG5) & 0xFFF0FFFF) | BIT17));
  33803. + }
  33804. + }
  33805. +
  33806. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33807. + muxVal = (twsiVal & muxValMask) | muxVal;
  33808. +
  33809. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  33810. + {
  33811. + mvOsPrintf("Board: twsi exp out val fail\n");
  33812. + return;
  33813. + }
  33814. +
  33815. + /* TBD - 5 channels */
  33816. +#if defined(MV_TDM_5CHANNELS)
  33817. + /* change MPP38 type to GPIO(0x0) & polarity for TDM_STROBE */
  33818. + MV_REG_WRITE(MPP_CONTROL_REG4, (MV_REG_READ(MPP_CONTROL_REG4) & 0xF0FFFFFF));
  33819. + mvGppPolaritySet(1, MV_GPP6, 0);
  33820. +
  33821. + twsiSlave.offset = 6;
  33822. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(2);
  33823. +
  33824. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33825. + muxVal = (twsiVal & ~BIT2);
  33826. +
  33827. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  33828. + {
  33829. + mvOsPrintf("Board: twsi exp change to out fail\n");
  33830. + return;
  33831. + }
  33832. +
  33833. +
  33834. + twsiSlave.offset = 2;
  33835. +
  33836. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33837. + muxVal = (twsiVal & ~BIT2);
  33838. +
  33839. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  33840. + {
  33841. + mvOsPrintf("Board: twsi exp change to out fail\n");
  33842. + return;
  33843. + }
  33844. +#endif
  33845. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  33846. +
  33847. +
  33848. +}
  33849. +/*******************************************************************************
  33850. +* mvBoardVoiceConnModeGet - return SLIC/DAA connection & interrupt modes
  33851. +*
  33852. +* DESCRIPTION:
  33853. +*
  33854. +* INPUT:
  33855. +*
  33856. +* OUTPUT:
  33857. +* None.
  33858. +*
  33859. +* RETURN:
  33860. +*
  33861. +*******************************************************************************/
  33862. +
  33863. +MV_VOID mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode)
  33864. +{
  33865. + switch(mvBoardIdGet())
  33866. + {
  33867. + case RD_88F6281A_ID:
  33868. + *connMode = DAISY_CHAIN_MODE;
  33869. + *irqMode = INTERRUPT_TO_TDM;
  33870. + break;
  33871. + case DB_88F6281A_BP_ID:
  33872. + *connMode = DUAL_CHIP_SELECT_MODE;
  33873. + *irqMode = INTERRUPT_TO_TDM;
  33874. + break;
  33875. + case RD_88F6192A_ID:
  33876. + *connMode = DUAL_CHIP_SELECT_MODE;
  33877. + *irqMode = INTERRUPT_TO_TDM;
  33878. + break;
  33879. + case DB_88F6192A_BP_ID:
  33880. + *connMode = DUAL_CHIP_SELECT_MODE;
  33881. + *irqMode = INTERRUPT_TO_TDM;
  33882. + break;
  33883. + default:
  33884. + *connMode = *irqMode = -1;
  33885. + mvOsPrintf("mvBoardVoiceAssembleModeGet: TDM not supported(boardId=0x%x)\n",mvBoardIdGet());
  33886. + }
  33887. + return;
  33888. +
  33889. +}
  33890. +
  33891. +/*******************************************************************************
  33892. +* mvBoardMppModuleTypePrint - print module detect
  33893. +*
  33894. +* DESCRIPTION:
  33895. +*
  33896. +* INPUT:
  33897. +*
  33898. +* OUTPUT:
  33899. +* None.
  33900. +*
  33901. +* RETURN:
  33902. +*
  33903. +*******************************************************************************/
  33904. +MV_VOID mvBoardMppModuleTypePrint(MV_VOID)
  33905. +{
  33906. +
  33907. + MV_BOARD_MPP_GROUP_CLASS devClass;
  33908. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  33909. + MV_U32 devId;
  33910. + MV_U32 maxMppGrp = 1;
  33911. +
  33912. + devId = mvCtrlModelGet();
  33913. +
  33914. + switch(devId){
  33915. + case MV_6281_DEV_ID:
  33916. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  33917. + break;
  33918. + case MV_6192_DEV_ID:
  33919. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  33920. + break;
  33921. + case MV_6190_DEV_ID:
  33922. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  33923. + break;
  33924. + case MV_6180_DEV_ID:
  33925. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  33926. + break;
  33927. + }
  33928. +
  33929. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  33930. + {
  33931. + mppGroupType = mvBoardMppGroupTypeGet(devClass);
  33932. +
  33933. + switch(mppGroupType)
  33934. + {
  33935. + case MV_BOARD_TDM:
  33936. + if(devId != MV_6190_DEV_ID)
  33937. + mvOsPrintf("Module %d is TDM\n", devClass);
  33938. + break;
  33939. + case MV_BOARD_AUDIO:
  33940. + if(devId != MV_6190_DEV_ID)
  33941. + mvOsPrintf("Module %d is AUDIO\n", devClass);
  33942. + break;
  33943. + case MV_BOARD_RGMII:
  33944. + if(devId != MV_6190_DEV_ID)
  33945. + mvOsPrintf("Module %d is RGMII\n", devClass);
  33946. + break;
  33947. + case MV_BOARD_GMII:
  33948. + if(devId != MV_6190_DEV_ID)
  33949. + mvOsPrintf("Module %d is GMII\n", devClass);
  33950. + break;
  33951. + case MV_BOARD_TS:
  33952. + if(devId != MV_6190_DEV_ID)
  33953. + mvOsPrintf("Module %d is TS\n", devClass);
  33954. + break;
  33955. + default:
  33956. + break;
  33957. + }
  33958. + }
  33959. +}
  33960. +
  33961. +/* Board devices API managments */
  33962. +
  33963. +/*******************************************************************************
  33964. +* mvBoardGetDeviceNumber - Get number of device of some type on the board
  33965. +*
  33966. +* DESCRIPTION:
  33967. +*
  33968. +* INPUT:
  33969. +* devType - The device type ( Flash,RTC , etc .. )
  33970. +*
  33971. +* OUTPUT:
  33972. +* None.
  33973. +*
  33974. +* RETURN:
  33975. +* If the device is found on the board the then the functions returns the
  33976. +* number of those devices else the function returns 0
  33977. +*
  33978. +*
  33979. +*******************************************************************************/
  33980. +MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass)
  33981. +{
  33982. + MV_U32 foundIndex=0,devNum;
  33983. + MV_U32 boardId= mvBoardIdGet();
  33984. +
  33985. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33986. + {
  33987. + mvOsPrintf("mvBoardGetDeviceNumber:Board unknown.\n");
  33988. + return 0xFFFFFFFF;
  33989. +
  33990. + }
  33991. +
  33992. + for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)
  33993. + {
  33994. + if (BOARD_INFO(boardId)->pDevCsInfo[devNum].devClass == devClass)
  33995. + {
  33996. + foundIndex++;
  33997. + }
  33998. + }
  33999. +
  34000. + return foundIndex;
  34001. +
  34002. +}
  34003. +
  34004. +/*******************************************************************************
  34005. +* mvBoardGetDeviceBaseAddr - Get base address of a device existing on the board
  34006. +*
  34007. +* DESCRIPTION:
  34008. +*
  34009. +* INPUT:
  34010. +* devIndex - The device sequential number on the board
  34011. +* devType - The device type ( Flash,RTC , etc .. )
  34012. +*
  34013. +* OUTPUT:
  34014. +* None.
  34015. +*
  34016. +* RETURN:
  34017. +* If the device is found on the board the then the functions returns the
  34018. +* Base address else the function returns 0xffffffff
  34019. +*
  34020. +*
  34021. +*******************************************************************************/
  34022. +MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  34023. +{
  34024. + MV_DEV_CS_INFO* devEntry;
  34025. + devEntry = boardGetDevEntry(devNum,devClass);
  34026. + if (devEntry != NULL)
  34027. + {
  34028. + return mvCpuIfTargetWinBaseLowGet(DEV_TO_TARGET(devEntry->deviceCS));
  34029. +
  34030. + }
  34031. +
  34032. + return 0xFFFFFFFF;
  34033. +}
  34034. +
  34035. +/*******************************************************************************
  34036. +* mvBoardGetDeviceBusWidth - Get Bus width of a device existing on the board
  34037. +*
  34038. +* DESCRIPTION:
  34039. +*
  34040. +* INPUT:
  34041. +* devIndex - The device sequential number on the board
  34042. +* devType - The device type ( Flash,RTC , etc .. )
  34043. +*
  34044. +* OUTPUT:
  34045. +* None.
  34046. +*
  34047. +* RETURN:
  34048. +* If the device is found on the board the then the functions returns the
  34049. +* Bus width else the function returns 0xffffffff
  34050. +*
  34051. +*
  34052. +*******************************************************************************/
  34053. +MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  34054. +{
  34055. + MV_DEV_CS_INFO* devEntry;
  34056. +
  34057. + devEntry = boardGetDevEntry(devNum,devClass);
  34058. + if (devEntry != NULL)
  34059. + {
  34060. + return 8;
  34061. + }
  34062. +
  34063. + return 0xFFFFFFFF;
  34064. +
  34065. +}
  34066. +
  34067. +/*******************************************************************************
  34068. +* mvBoardGetDeviceWidth - Get dev width of a device existing on the board
  34069. +*
  34070. +* DESCRIPTION:
  34071. +*
  34072. +* INPUT:
  34073. +* devIndex - The device sequential number on the board
  34074. +* devType - The device type ( Flash,RTC , etc .. )
  34075. +*
  34076. +* OUTPUT:
  34077. +* None.
  34078. +*
  34079. +* RETURN:
  34080. +* If the device is found on the board the then the functions returns the
  34081. +* dev width else the function returns 0xffffffff
  34082. +*
  34083. +*
  34084. +*******************************************************************************/
  34085. +MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  34086. +{
  34087. + MV_DEV_CS_INFO* devEntry;
  34088. + MV_U32 boardId= mvBoardIdGet();
  34089. +
  34090. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  34091. + {
  34092. + mvOsPrintf("Board unknown.\n");
  34093. + return 0xFFFFFFFF;
  34094. + }
  34095. +
  34096. + devEntry = boardGetDevEntry(devNum,devClass);
  34097. + if (devEntry != NULL)
  34098. + return devEntry->devWidth;
  34099. +
  34100. + return MV_ERROR;
  34101. +
  34102. +}
  34103. +
  34104. +/*******************************************************************************
  34105. +* mvBoardGetDeviceWinSize - Get the window size of a device existing on the board
  34106. +*
  34107. +* DESCRIPTION:
  34108. +*
  34109. +* INPUT:
  34110. +* devIndex - The device sequential number on the board
  34111. +* devType - The device type ( Flash,RTC , etc .. )
  34112. +*
  34113. +* OUTPUT:
  34114. +* None.
  34115. +*
  34116. +* RETURN:
  34117. +* If the device is found on the board the then the functions returns the
  34118. +* window size else the function returns 0xffffffff
  34119. +*
  34120. +*
  34121. +*******************************************************************************/
  34122. +MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  34123. +{
  34124. + MV_DEV_CS_INFO* devEntry;
  34125. + MV_U32 boardId = mvBoardIdGet();
  34126. +
  34127. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  34128. + {
  34129. + mvOsPrintf("Board unknown.\n");
  34130. + return 0xFFFFFFFF;
  34131. + }
  34132. +
  34133. + devEntry = boardGetDevEntry(devNum,devClass);
  34134. + if (devEntry != NULL)
  34135. + {
  34136. + return mvCpuIfTargetWinSizeGet(DEV_TO_TARGET(devEntry->deviceCS));
  34137. + }
  34138. +
  34139. + return 0xFFFFFFFF;
  34140. +}
  34141. +
  34142. +
  34143. +/*******************************************************************************
  34144. +* boardGetDevEntry - returns the entry pointer of a device on the board
  34145. +*
  34146. +* DESCRIPTION:
  34147. +*
  34148. +* INPUT:
  34149. +* devIndex - The device sequential number on the board
  34150. +* devType - The device type ( Flash,RTC , etc .. )
  34151. +*
  34152. +* OUTPUT:
  34153. +* None.
  34154. +*
  34155. +* RETURN:
  34156. +* If the device is found on the board the then the functions returns the
  34157. +* dev number else the function returns 0x0
  34158. +*
  34159. +*
  34160. +*******************************************************************************/
  34161. +static MV_DEV_CS_INFO* boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  34162. +{
  34163. + MV_U32 foundIndex=0,devIndex;
  34164. + MV_U32 boardId= mvBoardIdGet();
  34165. +
  34166. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  34167. + {
  34168. + mvOsPrintf("boardGetDevEntry: Board unknown.\n");
  34169. + return NULL;
  34170. +
  34171. + }
  34172. +
  34173. + for (devIndex = START_DEV_CS; devIndex < BOARD_INFO(boardId)->numBoardDeviceIf; devIndex++)
  34174. + {
  34175. + /* TBR */
  34176. + /*if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].deviceCS == MV_BOOTDEVICE_INDEX)
  34177. + continue;*/
  34178. +
  34179. + if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].devClass == devClass)
  34180. + {
  34181. + if (foundIndex == devNum)
  34182. + {
  34183. + return &(BOARD_INFO(boardId)->pDevCsInfo[devIndex]);
  34184. + }
  34185. + foundIndex++;
  34186. + }
  34187. + }
  34188. +
  34189. + /* device not found */
  34190. + return NULL;
  34191. +}
  34192. +
  34193. +/* Get device CS number */
  34194. +
  34195. +MV_U32 boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  34196. +{
  34197. + MV_DEV_CS_INFO* devEntry;
  34198. + MV_U32 boardId= mvBoardIdGet();
  34199. +
  34200. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  34201. + {
  34202. + mvOsPrintf("Board unknown.\n");
  34203. + return 0xFFFFFFFF;
  34204. +
  34205. + }
  34206. +
  34207. +
  34208. + devEntry = boardGetDevEntry(devNum,devClass);
  34209. + if (devEntry != NULL)
  34210. + return devEntry->deviceCS;
  34211. +
  34212. + return 0xFFFFFFFF;
  34213. +
  34214. +}
  34215. +
  34216. +/*******************************************************************************
  34217. +* mvBoardRtcTwsiAddrTypeGet -
  34218. +*
  34219. +* DESCRIPTION:
  34220. +*
  34221. +* INPUT:
  34222. +*
  34223. +* OUTPUT:
  34224. +* None.
  34225. +*
  34226. +* RETURN:
  34227. +*
  34228. +*
  34229. +*******************************************************************************/
  34230. +MV_U8 mvBoardRtcTwsiAddrTypeGet()
  34231. +{
  34232. + int i;
  34233. + MV_U32 boardId= mvBoardIdGet();
  34234. +
  34235. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34236. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)
  34237. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  34238. + return (MV_ERROR);
  34239. +}
  34240. +
  34241. +/*******************************************************************************
  34242. +* mvBoardRtcTwsiAddrGet -
  34243. +*
  34244. +* DESCRIPTION:
  34245. +*
  34246. +* INPUT:
  34247. +*
  34248. +* OUTPUT:
  34249. +* None.
  34250. +*
  34251. +* RETURN:
  34252. +*
  34253. +*
  34254. +*******************************************************************************/
  34255. +MV_U8 mvBoardRtcTwsiAddrGet()
  34256. +{
  34257. + int i;
  34258. + MV_U32 boardId= mvBoardIdGet();
  34259. +
  34260. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34261. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)
  34262. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  34263. + return (0xFF);
  34264. +}
  34265. +
  34266. +/*******************************************************************************
  34267. +* mvBoardA2DTwsiAddrTypeGet -
  34268. +*
  34269. +* DESCRIPTION:
  34270. +*
  34271. +* INPUT:
  34272. +*
  34273. +* OUTPUT:
  34274. +* None.
  34275. +*
  34276. +* RETURN:
  34277. +*
  34278. +*
  34279. +*******************************************************************************/
  34280. +MV_U8 mvBoardA2DTwsiAddrTypeGet()
  34281. +{
  34282. + int i;
  34283. + MV_U32 boardId= mvBoardIdGet();
  34284. +
  34285. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34286. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)
  34287. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  34288. + return (MV_ERROR);
  34289. +}
  34290. +
  34291. +/*******************************************************************************
  34292. +* mvBoardA2DTwsiAddrGet -
  34293. +*
  34294. +* DESCRIPTION:
  34295. +*
  34296. +* INPUT:
  34297. +*
  34298. +* OUTPUT:
  34299. +* None.
  34300. +*
  34301. +* RETURN:
  34302. +*
  34303. +*
  34304. +*******************************************************************************/
  34305. +MV_U8 mvBoardA2DTwsiAddrGet()
  34306. +{
  34307. + int i;
  34308. + MV_U32 boardId= mvBoardIdGet();
  34309. +
  34310. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34311. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)
  34312. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  34313. + return (0xFF);
  34314. +}
  34315. +
  34316. +/*******************************************************************************
  34317. +* mvBoardTwsiExpAddrTypeGet -
  34318. +*
  34319. +* DESCRIPTION:
  34320. +*
  34321. +* INPUT:
  34322. +*
  34323. +* OUTPUT:
  34324. +* None.
  34325. +*
  34326. +* RETURN:
  34327. +*
  34328. +*
  34329. +*******************************************************************************/
  34330. +MV_U8 mvBoardTwsiExpAddrTypeGet(MV_U32 index)
  34331. +{
  34332. + int i;
  34333. + MV_U32 indexFound = 0;
  34334. + MV_U32 boardId= mvBoardIdGet();
  34335. +
  34336. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34337. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)
  34338. + {
  34339. + if (indexFound == index)
  34340. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  34341. + else
  34342. + indexFound++;
  34343. + }
  34344. +
  34345. + return (MV_ERROR);
  34346. +}
  34347. +
  34348. +/*******************************************************************************
  34349. +* mvBoardTwsiExpAddrGet -
  34350. +*
  34351. +* DESCRIPTION:
  34352. +*
  34353. +* INPUT:
  34354. +*
  34355. +* OUTPUT:
  34356. +* None.
  34357. +*
  34358. +* RETURN:
  34359. +*
  34360. +*
  34361. +*******************************************************************************/
  34362. +MV_U8 mvBoardTwsiExpAddrGet(MV_U32 index)
  34363. +{
  34364. + int i;
  34365. + MV_U32 indexFound = 0;
  34366. + MV_U32 boardId= mvBoardIdGet();
  34367. +
  34368. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34369. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)
  34370. + {
  34371. + if (indexFound == index)
  34372. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  34373. + else
  34374. + indexFound++;
  34375. + }
  34376. +
  34377. + return (0xFF);
  34378. +}
  34379. +
  34380. +
  34381. +/*******************************************************************************
  34382. +* mvBoardTwsiSatRAddrTypeGet -
  34383. +*
  34384. +* DESCRIPTION:
  34385. +*
  34386. +* INPUT:
  34387. +*
  34388. +* OUTPUT:
  34389. +* None.
  34390. +*
  34391. +* RETURN:
  34392. +*
  34393. +*
  34394. +*******************************************************************************/
  34395. +MV_U8 mvBoardTwsiSatRAddrTypeGet(MV_U32 index)
  34396. +{
  34397. + int i;
  34398. + MV_U32 indexFound = 0;
  34399. + MV_U32 boardId= mvBoardIdGet();
  34400. +
  34401. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34402. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)
  34403. + {
  34404. + if (indexFound == index)
  34405. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  34406. + else
  34407. + indexFound++;
  34408. + }
  34409. +
  34410. + return (MV_ERROR);
  34411. +}
  34412. +
  34413. +/*******************************************************************************
  34414. +* mvBoardTwsiSatRAddrGet -
  34415. +*
  34416. +* DESCRIPTION:
  34417. +*
  34418. +* INPUT:
  34419. +*
  34420. +* OUTPUT:
  34421. +* None.
  34422. +*
  34423. +* RETURN:
  34424. +*
  34425. +*
  34426. +*******************************************************************************/
  34427. +MV_U8 mvBoardTwsiSatRAddrGet(MV_U32 index)
  34428. +{
  34429. + int i;
  34430. + MV_U32 indexFound = 0;
  34431. + MV_U32 boardId= mvBoardIdGet();
  34432. +
  34433. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34434. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)
  34435. + {
  34436. + if (indexFound == index)
  34437. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  34438. + else
  34439. + indexFound++;
  34440. + }
  34441. +
  34442. + return (0xFF);
  34443. +}
  34444. +
  34445. +/*******************************************************************************
  34446. +* mvBoardNandWidthGet -
  34447. +*
  34448. +* DESCRIPTION: Get the width of the first NAND device in byte.
  34449. +*
  34450. +* INPUT:
  34451. +*
  34452. +* OUTPUT:
  34453. +* None.
  34454. +*
  34455. +* RETURN: 1, 2, 4 or MV_ERROR
  34456. +*
  34457. +*
  34458. +*******************************************************************************/
  34459. +/* */
  34460. +MV_32 mvBoardNandWidthGet(void)
  34461. +{
  34462. + MV_U32 devNum;
  34463. + MV_U32 devWidth;
  34464. + MV_U32 boardId= mvBoardIdGet();
  34465. +
  34466. + for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)
  34467. + {
  34468. + devWidth = mvBoardGetDeviceWidth(devNum, BOARD_DEV_NAND_FLASH);
  34469. + if (devWidth != MV_ERROR)
  34470. + return (devWidth / 8);
  34471. + }
  34472. +
  34473. + /* NAND wasn't found */
  34474. + return MV_ERROR;
  34475. +}
  34476. +
  34477. +MV_U32 gBoardId = -1;
  34478. +
  34479. +/*******************************************************************************
  34480. +* mvBoardIdGet - Get Board model
  34481. +*
  34482. +* DESCRIPTION:
  34483. +* This function returns board ID.
  34484. +* Board ID is 32bit word constructed of board model (16bit) and
  34485. +* board revision (16bit) in the following way: 0xMMMMRRRR.
  34486. +*
  34487. +* INPUT:
  34488. +* None.
  34489. +*
  34490. +* OUTPUT:
  34491. +* None.
  34492. +*
  34493. +* RETURN:
  34494. +* 32bit board ID number, '-1' if board is undefined.
  34495. +*
  34496. +*******************************************************************************/
  34497. +MV_U32 mvBoardIdGet(MV_VOID)
  34498. +{
  34499. + MV_U32 tmpBoardId = -1;
  34500. +
  34501. + if(gBoardId == -1)
  34502. + {
  34503. + #if defined(DB_88F6281A)
  34504. + tmpBoardId = DB_88F6281A_BP_ID;
  34505. + #elif defined(RD_88F6281A)
  34506. + tmpBoardId = RD_88F6281A_ID;
  34507. + #elif defined(DB_88F6192A)
  34508. + tmpBoardId = DB_88F6192A_BP_ID;
  34509. + #elif defined(DB_88F6190A)
  34510. + tmpBoardId = DB_88F6190A_BP_ID;
  34511. + #elif defined(RD_88F6192A)
  34512. + tmpBoardId = RD_88F6192A_ID;
  34513. + #elif defined(RD_88F6190A)
  34514. + tmpBoardId = RD_88F6190A_ID;
  34515. + #elif defined(DB_88F6180A)
  34516. + tmpBoardId = DB_88F6180A_BP_ID;
  34517. + #elif defined(RD_88F6281A_PCAC)
  34518. + tmpBoardId = RD_88F6281A_PCAC_ID;
  34519. + #elif defined(RD_88F6281A_SHEEVA_PLUG)
  34520. + tmpBoardId = SHEEVA_PLUG_ID;
  34521. + #elif defined(DB_CUSTOMER)
  34522. + tmpBoardId = DB_CUSTOMER_ID;
  34523. + #endif
  34524. + gBoardId = tmpBoardId;
  34525. + }
  34526. +
  34527. + return gBoardId;
  34528. +}
  34529. +
  34530. +
  34531. +/*******************************************************************************
  34532. +* mvBoarModuleTypeGet - mvBoarModuleTypeGet
  34533. +*
  34534. +* DESCRIPTION:
  34535. +*
  34536. +* INPUT:
  34537. +* group num - MV_BOARD_MPP_GROUP_CLASS enum
  34538. +*
  34539. +* OUTPUT:
  34540. +* None.
  34541. +*
  34542. +* RETURN:
  34543. +* module num - MV_BOARD_MODULE_CLASS enum
  34544. +*
  34545. +*******************************************************************************/
  34546. +MV_BOARD_MODULE_ID_CLASS mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass)
  34547. +{
  34548. + MV_TWSI_SLAVE twsiSlave;
  34549. + MV_TWSI_ADDR slave;
  34550. + MV_U8 data;
  34551. +
  34552. + /* TWSI init */
  34553. + slave.type = ADDR7_BIT;
  34554. + slave.address = 0;
  34555. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  34556. +
  34557. + /* Read MPP module ID */
  34558. + DB(mvOsPrintf("Board: Read MPP module ID\n"));
  34559. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);
  34560. + twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(devClass);
  34561. + twsiSlave.validOffset = MV_TRUE;
  34562. + /* Offset is the first command after the address which indicate the register number to be read
  34563. + in next operation */
  34564. + twsiSlave.offset = 0;
  34565. + twsiSlave.moreThen256 = MV_FALSE;
  34566. +
  34567. +
  34568. +
  34569. + if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )
  34570. + {
  34571. + DB(mvOsPrintf("Board: Read MPP module ID fail\n"));
  34572. + return MV_ERROR;
  34573. + }
  34574. + DB(mvOsPrintf("Board: Read MPP module ID succeded\n"));
  34575. +
  34576. + return data;
  34577. +}
  34578. +
  34579. +/*******************************************************************************
  34580. +* mvBoarTwsiSatRGet -
  34581. +*
  34582. +* DESCRIPTION:
  34583. +*
  34584. +* INPUT:
  34585. +* device num - one of three devices
  34586. +* reg num - 0 or 1
  34587. +*
  34588. +* OUTPUT:
  34589. +* None.
  34590. +*
  34591. +* RETURN:
  34592. +* reg value
  34593. +*
  34594. +*******************************************************************************/
  34595. +MV_U8 mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum)
  34596. +{
  34597. + MV_TWSI_SLAVE twsiSlave;
  34598. + MV_TWSI_ADDR slave;
  34599. + MV_U8 data;
  34600. +
  34601. + /* TWSI init */
  34602. + slave.type = ADDR7_BIT;
  34603. + slave.address = 0;
  34604. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  34605. +
  34606. + /* Read MPP module ID */
  34607. + DB(mvOsPrintf("Board: Read S@R device read\n"));
  34608. + twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);
  34609. + twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);
  34610. + twsiSlave.validOffset = MV_TRUE;
  34611. + /* Use offset as command */
  34612. + twsiSlave.offset = regNum;
  34613. + twsiSlave.moreThen256 = MV_FALSE;
  34614. +
  34615. + if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )
  34616. + {
  34617. + DB(mvOsPrintf("Board: Read S@R fail\n"));
  34618. + return MV_ERROR;
  34619. + }
  34620. + DB(mvOsPrintf("Board: Read S@R succeded\n"));
  34621. +
  34622. + return data;
  34623. +}
  34624. +
  34625. +/*******************************************************************************
  34626. +* mvBoarTwsiSatRSet -
  34627. +*
  34628. +* DESCRIPTION:
  34629. +*
  34630. +* INPUT:
  34631. +* devNum - one of three devices
  34632. +* regNum - 0 or 1
  34633. +* regVal - value
  34634. +*
  34635. +*
  34636. +* OUTPUT:
  34637. +* None.
  34638. +*
  34639. +* RETURN:
  34640. +* reg value
  34641. +*
  34642. +*******************************************************************************/
  34643. +MV_STATUS mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal)
  34644. +{
  34645. + MV_TWSI_SLAVE twsiSlave;
  34646. + MV_TWSI_ADDR slave;
  34647. +
  34648. + /* TWSI init */
  34649. + slave.type = ADDR7_BIT;
  34650. + slave.address = 0;
  34651. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  34652. +
  34653. + /* Read MPP module ID */
  34654. + twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);
  34655. + twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);
  34656. + twsiSlave.validOffset = MV_TRUE;
  34657. + DB(mvOsPrintf("Board: Write S@R device addr %x, type %x, data %x\n", twsiSlave.slaveAddr.address,\
  34658. + twsiSlave.slaveAddr.type, regVal));
  34659. + /* Use offset as command */
  34660. + twsiSlave.offset = regNum;
  34661. + twsiSlave.moreThen256 = MV_FALSE;
  34662. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &regVal, 1) )
  34663. + {
  34664. + DB(mvOsPrintf("Board: Write S@R fail\n"));
  34665. + return MV_ERROR;
  34666. + }
  34667. + DB(mvOsPrintf("Board: Write S@R succeded\n"));
  34668. +
  34669. + return MV_OK;
  34670. +}
  34671. +
  34672. +/*******************************************************************************
  34673. +* mvBoardSlicGpioPinGet -
  34674. +*
  34675. +* DESCRIPTION:
  34676. +*
  34677. +* INPUT:
  34678. +*
  34679. +* OUTPUT:
  34680. +* None.
  34681. +*
  34682. +* RETURN:
  34683. +*
  34684. +*
  34685. +*******************************************************************************/
  34686. +MV_32 mvBoardSlicGpioPinGet(MV_U32 slicNum)
  34687. +{
  34688. + MV_U32 boardId;
  34689. + boardId = mvBoardIdGet();
  34690. +
  34691. + switch (boardId)
  34692. + {
  34693. + case DB_88F6281A_BP_ID:
  34694. + case RD_88F6281A_ID:
  34695. + default:
  34696. + return MV_ERROR;
  34697. + break;
  34698. +
  34699. + }
  34700. +}
  34701. +
  34702. +/*******************************************************************************
  34703. +* mvBoardFanPowerControl - Turn on/off the fan power control on the RD-6281A
  34704. +*
  34705. +* DESCRIPTION:
  34706. +*
  34707. +* INPUT:
  34708. +* mode - MV_TRUE = on ; MV_FALSE = off
  34709. +*
  34710. +* OUTPUT:
  34711. +* MV_STATUS - MV_OK , MV_ERROR.
  34712. +*
  34713. +* RETURN:
  34714. +*
  34715. +*******************************************************************************/
  34716. +MV_STATUS mvBoardFanPowerControl(MV_BOOL mode)
  34717. +{
  34718. +
  34719. + MV_U8 val = 1, twsiVal;
  34720. + MV_TWSI_SLAVE twsiSlave;
  34721. + MV_TWSI_ADDR slave;
  34722. +
  34723. + if(mvBoardIdGet() != RD_88F6281A_ID)
  34724. + return MV_ERROR;
  34725. +
  34726. + /* TWSI init */
  34727. + slave.type = ADDR7_BIT;
  34728. + slave.address = 0;
  34729. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  34730. +
  34731. + /* Read MPP module ID */
  34732. + DB(mvOsPrintf("Board: twsi exp set\n"));
  34733. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);
  34734. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  34735. + twsiSlave.validOffset = MV_TRUE;
  34736. + /* Offset is the first command after the address which indicate the register number to be read
  34737. + in next operation */
  34738. + twsiSlave.offset = 3;
  34739. + twsiSlave.moreThen256 = MV_FALSE;
  34740. + if(mode == MV_TRUE)
  34741. + val = 0x1;
  34742. + else
  34743. + val = 0;
  34744. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  34745. + val = (twsiVal & 0xfe) | val;
  34746. +
  34747. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  34748. + {
  34749. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  34750. + return MV_ERROR;
  34751. + }
  34752. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  34753. +
  34754. + /* Change twsi exp to output */
  34755. + twsiSlave.offset = 7;
  34756. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  34757. + val = (twsiVal & 0xfe);
  34758. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  34759. + {
  34760. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  34761. + return MV_ERROR;
  34762. + }
  34763. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  34764. + return MV_OK;
  34765. +}
  34766. +
  34767. +/*******************************************************************************
  34768. +* mvBoardHDDPowerControl - Turn on/off the HDD power control on the RD-6281A
  34769. +*
  34770. +* DESCRIPTION:
  34771. +*
  34772. +* INPUT:
  34773. +* mode - MV_TRUE = on ; MV_FALSE = off
  34774. +*
  34775. +* OUTPUT:
  34776. +* MV_STATUS - MV_OK , MV_ERROR.
  34777. +*
  34778. +* RETURN:
  34779. +*
  34780. +*******************************************************************************/
  34781. +MV_STATUS mvBoardHDDPowerControl(MV_BOOL mode)
  34782. +{
  34783. +
  34784. + MV_U8 val = 1, twsiVal;
  34785. + MV_TWSI_SLAVE twsiSlave;
  34786. + MV_TWSI_ADDR slave;
  34787. +
  34788. + if(mvBoardIdGet() != RD_88F6281A_ID)
  34789. + return MV_ERROR;
  34790. +
  34791. + /* TWSI init */
  34792. + slave.type = ADDR7_BIT;
  34793. + slave.address = 0;
  34794. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  34795. +
  34796. + /* Read MPP module ID */
  34797. + DB(mvOsPrintf("Board: twsi exp set\n"));
  34798. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);
  34799. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  34800. + twsiSlave.validOffset = MV_TRUE;
  34801. + /* Offset is the first command after the address which indicate the register number to be read
  34802. + in next operation */
  34803. + twsiSlave.offset = 3;
  34804. + twsiSlave.moreThen256 = MV_FALSE;
  34805. + if(mode == MV_TRUE)
  34806. + val = 0x2;
  34807. + else
  34808. + val = 0;
  34809. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  34810. + val = (twsiVal & 0xfd) | val;
  34811. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  34812. + {
  34813. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  34814. + return MV_ERROR;
  34815. + }
  34816. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  34817. +
  34818. + /* Change twsi exp to output */
  34819. + twsiSlave.offset = 7;
  34820. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  34821. + val = (twsiVal & 0xfd);
  34822. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  34823. + {
  34824. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  34825. + return MV_ERROR;
  34826. + }
  34827. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  34828. + return MV_OK;
  34829. +}
  34830. +
  34831. +/*******************************************************************************
  34832. +* mvBoardSDioWPControl - Turn on/off the SDIO WP on the RD-6281A
  34833. +*
  34834. +* DESCRIPTION:
  34835. +*
  34836. +* INPUT:
  34837. +* mode - MV_TRUE = on ; MV_FALSE = off
  34838. +*
  34839. +* OUTPUT:
  34840. +* MV_STATUS - MV_OK , MV_ERROR.
  34841. +*
  34842. +* RETURN:
  34843. +*
  34844. +*******************************************************************************/
  34845. +MV_STATUS mvBoardSDioWPControl(MV_BOOL mode)
  34846. +{
  34847. +
  34848. + MV_U8 val = 1, twsiVal;
  34849. + MV_TWSI_SLAVE twsiSlave;
  34850. + MV_TWSI_ADDR slave;
  34851. +
  34852. + if(mvBoardIdGet() != RD_88F6281A_ID)
  34853. + return MV_ERROR;
  34854. +
  34855. + /* TWSI init */
  34856. + slave.type = ADDR7_BIT;
  34857. + slave.address = 0;
  34858. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  34859. +
  34860. + /* Read MPP module ID */
  34861. + DB(mvOsPrintf("Board: twsi exp set\n"));
  34862. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(0);
  34863. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  34864. + twsiSlave.validOffset = MV_TRUE;
  34865. + /* Offset is the first command after the address which indicate the register number to be read
  34866. + in next operation */
  34867. + twsiSlave.offset = 3;
  34868. + twsiSlave.moreThen256 = MV_FALSE;
  34869. + if(mode == MV_TRUE)
  34870. + val = 0x10;
  34871. + else
  34872. + val = 0;
  34873. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  34874. + val = (twsiVal & 0xef) | val;
  34875. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  34876. + {
  34877. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  34878. + return MV_ERROR;
  34879. + }
  34880. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  34881. +
  34882. + /* Change twsi exp to output */
  34883. + twsiSlave.offset = 7;
  34884. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  34885. + val = (twsiVal & 0xef);
  34886. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  34887. + {
  34888. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  34889. + return MV_ERROR;
  34890. + }
  34891. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  34892. + return MV_OK;
  34893. +}
  34894. +
  34895. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h
  34896. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h 1970-01-01 01:00:00.000000000 +0100
  34897. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h 2011-07-31 11:31:56.417168808 +0200
  34898. @@ -0,0 +1,376 @@
  34899. +/*******************************************************************************
  34900. +Copyright (C) Marvell International Ltd. and its affiliates
  34901. +
  34902. +This software file (the "File") is owned and distributed by Marvell
  34903. +International Ltd. and/or its affiliates ("Marvell") under the following
  34904. +alternative licensing terms. Once you have made an election to distribute the
  34905. +File under one of the following license alternatives, please (i) delete this
  34906. +introductory statement regarding license alternatives, (ii) delete the two
  34907. +license alternatives that you have not elected to use and (iii) preserve the
  34908. +Marvell copyright notice above.
  34909. +
  34910. +********************************************************************************
  34911. +Marvell Commercial License Option
  34912. +
  34913. +If you received this File from Marvell and you have entered into a commercial
  34914. +license agreement (a "Commercial License") with Marvell, the File is licensed
  34915. +to you under the terms of the applicable Commercial License.
  34916. +
  34917. +********************************************************************************
  34918. +Marvell GPL License Option
  34919. +
  34920. +If you received this File from Marvell, you may opt to use, redistribute and/or
  34921. +modify this File in accordance with the terms and conditions of the General
  34922. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  34923. +available along with the File in the license.txt file or by writing to the Free
  34924. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  34925. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  34926. +
  34927. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  34928. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  34929. +DISCLAIMED. The GPL License provides additional details about this warranty
  34930. +disclaimer.
  34931. +********************************************************************************
  34932. +Marvell BSD License Option
  34933. +
  34934. +If you received this File from Marvell, you may opt to use, redistribute and/or
  34935. +modify this File under the following licensing terms.
  34936. +Redistribution and use in source and binary forms, with or without modification,
  34937. +are permitted provided that the following conditions are met:
  34938. +
  34939. + * Redistributions of source code must retain the above copyright notice,
  34940. + this list of conditions and the following disclaimer.
  34941. +
  34942. + * Redistributions in binary form must reproduce the above copyright
  34943. + notice, this list of conditions and the following disclaimer in the
  34944. + documentation and/or other materials provided with the distribution.
  34945. +
  34946. + * Neither the name of Marvell nor the names of its contributors may be
  34947. + used to endorse or promote products derived from this software without
  34948. + specific prior written permission.
  34949. +
  34950. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  34951. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  34952. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  34953. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  34954. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  34955. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  34956. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  34957. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  34958. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  34959. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34960. +
  34961. +*******************************************************************************/
  34962. +#ifndef __INCmvBoardEnvLibh
  34963. +#define __INCmvBoardEnvLibh
  34964. +
  34965. +/* defines */
  34966. +/* The below constant macros defines the board I2C EEPROM data offsets */
  34967. +
  34968. +
  34969. +
  34970. +#include "ctrlEnv/mvCtrlEnvLib.h"
  34971. +#include "mvSysHwConfig.h"
  34972. +#include "boardEnv/mvBoardEnvSpec.h"
  34973. +
  34974. +
  34975. +/* DUART stuff for Tclk detection only */
  34976. +#define DUART_BAUD_RATE 115200
  34977. +#define MAX_CLOCK_MARGINE 5000000 /* Maximum detected clock margine */
  34978. +
  34979. +/* Voice devices assembly modes */
  34980. +#define DAISY_CHAIN_MODE 1
  34981. +#define DUAL_CHIP_SELECT_MODE 0
  34982. +#define INTERRUPT_TO_MPP 1
  34983. +#define INTERRUPT_TO_TDM 0
  34984. +
  34985. +
  34986. +#define BOARD_ETH_PORT_NUM MV_ETH_MAX_PORTS
  34987. +#define BOARD_ETH_SWITCH_PORT_NUM 5
  34988. +
  34989. +#define MV_BOARD_MAX_USB_IF 1
  34990. +#define MV_BOARD_MAX_MPP 7
  34991. +#define MV_BOARD_NAME_LEN 0x20
  34992. +
  34993. +typedef struct _boardData
  34994. +{
  34995. + MV_U32 magic;
  34996. + MV_U16 boardId;
  34997. + MV_U8 boardVer;
  34998. + MV_U8 boardRev;
  34999. + MV_U32 reserved1;
  35000. + MV_U32 reserved2;
  35001. +
  35002. +}BOARD_DATA;
  35003. +
  35004. +typedef enum _devBoardMppGroupClass
  35005. +{
  35006. + MV_BOARD_MPP_GROUP_1,
  35007. + MV_BOARD_MPP_GROUP_2,
  35008. + MV_BOARD_MAX_MPP_GROUP
  35009. +}MV_BOARD_MPP_GROUP_CLASS;
  35010. +
  35011. +typedef enum _devBoardMppTypeClass
  35012. +{
  35013. + MV_BOARD_AUTO,
  35014. + MV_BOARD_TDM,
  35015. + MV_BOARD_AUDIO,
  35016. + MV_BOARD_RGMII,
  35017. + MV_BOARD_GMII,
  35018. + MV_BOARD_TS,
  35019. + MV_BOARD_MII,
  35020. + MV_BOARD_OTHER
  35021. +}MV_BOARD_MPP_TYPE_CLASS;
  35022. +
  35023. +typedef enum _devBoardModuleIdClass
  35024. +{
  35025. + MV_BOARD_MODULE_TDM_ID = 1,
  35026. + MV_BOARD_MODULE_AUDIO_ID,
  35027. + MV_BOARD_MODULE_RGMII_ID,
  35028. + MV_BOARD_MODULE_GMII_ID,
  35029. + MV_BOARD_MODULE_TS_ID,
  35030. + MV_BOARD_MODULE_MII_ID,
  35031. + MV_BOARD_MODULE_TDM_5CHAN_ID,
  35032. + MV_BOARD_MODULE_OTHER_ID
  35033. +}MV_BOARD_MODULE_ID_CLASS;
  35034. +
  35035. +typedef struct _boardMppTypeInfo
  35036. +{
  35037. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup1;
  35038. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2;
  35039. +
  35040. +}MV_BOARD_MPP_TYPE_INFO;
  35041. +
  35042. +
  35043. +typedef enum _devBoardClass
  35044. +{
  35045. + BOARD_DEV_NOR_FLASH,
  35046. + BOARD_DEV_NAND_FLASH,
  35047. + BOARD_DEV_SEVEN_SEG,
  35048. + BOARD_DEV_FPGA,
  35049. + BOARD_DEV_SRAM,
  35050. + BOARD_DEV_SPI_FLASH,
  35051. + BOARD_DEV_OTHER,
  35052. +}MV_BOARD_DEV_CLASS;
  35053. +
  35054. +typedef enum _devTwsiBoardClass
  35055. +{
  35056. + BOARD_TWSI_RTC,
  35057. + BOARD_DEV_TWSI_EXP,
  35058. + BOARD_DEV_TWSI_SATR,
  35059. + BOARD_TWSI_AUDIO_DEC,
  35060. + BOARD_TWSI_OTHER
  35061. +}MV_BOARD_TWSI_CLASS;
  35062. +
  35063. +typedef enum _devGppBoardClass
  35064. +{
  35065. + BOARD_GPP_RTC,
  35066. + BOARD_GPP_MV_SWITCH,
  35067. + BOARD_GPP_USB_VBUS,
  35068. + BOARD_GPP_USB_VBUS_EN,
  35069. + BOARD_GPP_USB_OC,
  35070. + BOARD_GPP_USB_HOST_DEVICE,
  35071. + BOARD_GPP_REF_CLCK,
  35072. + BOARD_GPP_VOIP_SLIC,
  35073. + BOARD_GPP_LIFELINE,
  35074. + BOARD_GPP_BUTTON,
  35075. + BOARD_GPP_TS_BUTTON_C,
  35076. + BOARD_GPP_TS_BUTTON_U,
  35077. + BOARD_GPP_TS_BUTTON_D,
  35078. + BOARD_GPP_TS_BUTTON_L,
  35079. + BOARD_GPP_TS_BUTTON_R,
  35080. + BOARD_GPP_POWER_BUTTON,
  35081. + BOARD_GPP_RESTOR_BUTTON,
  35082. + BOARD_GPP_WPS_BUTTON,
  35083. + BOARD_GPP_HDD0_POWER,
  35084. + BOARD_GPP_HDD1_POWER,
  35085. + BOARD_GPP_FAN_POWER,
  35086. + BOARD_GPP_RESET,
  35087. + BOARD_GPP_POWER_ON_LED,
  35088. + BOARD_GPP_HDD_POWER,
  35089. + BOARD_GPP_SDIO_POWER,
  35090. + BOARD_GPP_SDIO_DETECT,
  35091. + BOARD_GPP_SDIO_WP,
  35092. + BOARD_GPP_SWITCH_PHY_INT,
  35093. + BOARD_GPP_TSU_DIRCTION,
  35094. + BOARD_GPP_OTHER
  35095. +}MV_BOARD_GPP_CLASS;
  35096. +
  35097. +
  35098. +typedef struct _devCsInfo
  35099. +{
  35100. + MV_U8 deviceCS;
  35101. + MV_U32 params;
  35102. + MV_U32 devClass; /* MV_BOARD_DEV_CLASS */
  35103. + MV_U8 devWidth;
  35104. +
  35105. +}MV_DEV_CS_INFO;
  35106. +
  35107. +
  35108. +#define MV_BOARD_PHY_FORCE_10MB 0x0
  35109. +#define MV_BOARD_PHY_FORCE_100MB 0x1
  35110. +#define MV_BOARD_PHY_FORCE_1000MB 0x2
  35111. +#define MV_BOARD_PHY_SPEED_AUTO 0x3
  35112. +
  35113. +typedef struct _boardSwitchInfo
  35114. +{
  35115. + MV_32 linkStatusIrq;
  35116. + MV_32 qdPort[BOARD_ETH_SWITCH_PORT_NUM];
  35117. + MV_32 qdCpuPort;
  35118. + MV_32 smiScanMode; /* 1 for SMI_MANUAL_MODE, 0 otherwise */
  35119. + MV_32 switchOnPort;
  35120. +
  35121. +}MV_BOARD_SWITCH_INFO;
  35122. +
  35123. +typedef struct _boardLedInfo
  35124. +{
  35125. + MV_U8 activeLedsNumber;
  35126. + MV_U8 ledsPolarity; /* '0' or '1' to turn on led */
  35127. + MV_U8* gppPinNum; /* Pointer to GPP values */
  35128. +
  35129. +}MV_BOARD_LED_INFO;
  35130. +
  35131. +typedef struct _boardGppInfo
  35132. +{
  35133. + MV_BOARD_GPP_CLASS devClass;
  35134. + MV_U8 gppPinNum;
  35135. +
  35136. +}MV_BOARD_GPP_INFO;
  35137. +
  35138. +
  35139. +typedef struct _boardTwsiInfo
  35140. +{
  35141. + MV_BOARD_TWSI_CLASS devClass;
  35142. + MV_U8 twsiDevAddr;
  35143. + MV_U8 twsiDevAddrType;
  35144. +
  35145. +}MV_BOARD_TWSI_INFO;
  35146. +
  35147. +
  35148. +typedef enum _boardMacSpeed
  35149. +{
  35150. + BOARD_MAC_SPEED_10M,
  35151. + BOARD_MAC_SPEED_100M,
  35152. + BOARD_MAC_SPEED_1000M,
  35153. + BOARD_MAC_SPEED_AUTO,
  35154. +
  35155. +}MV_BOARD_MAC_SPEED;
  35156. +
  35157. +typedef struct _boardMacInfo
  35158. +{
  35159. + MV_BOARD_MAC_SPEED boardMacSpeed;
  35160. + MV_U8 boardEthSmiAddr;
  35161. +
  35162. +}MV_BOARD_MAC_INFO;
  35163. +
  35164. +typedef struct _boardMppInfo
  35165. +{
  35166. + MV_U32 mppGroup[MV_BOARD_MAX_MPP];
  35167. +
  35168. +}MV_BOARD_MPP_INFO;
  35169. +
  35170. +typedef struct _boardInfo
  35171. +{
  35172. + char boardName[MV_BOARD_NAME_LEN];
  35173. + MV_U8 numBoardMppTypeValue;
  35174. + MV_BOARD_MPP_TYPE_INFO* pBoardMppTypeValue;
  35175. + MV_U8 numBoardMppConfigValue;
  35176. + MV_BOARD_MPP_INFO* pBoardMppConfigValue;
  35177. + MV_U32 intsGppMaskLow;
  35178. + MV_U32 intsGppMaskHigh;
  35179. + MV_U8 numBoardDeviceIf;
  35180. + MV_DEV_CS_INFO* pDevCsInfo;
  35181. + MV_U8 numBoardTwsiDev;
  35182. + MV_BOARD_TWSI_INFO* pBoardTwsiDev;
  35183. + MV_U8 numBoardMacInfo;
  35184. + MV_BOARD_MAC_INFO* pBoardMacInfo;
  35185. + MV_U8 numBoardGppInfo;
  35186. + MV_BOARD_GPP_INFO* pBoardGppInfo;
  35187. + MV_U8 activeLedsNumber;
  35188. + MV_U8* pLedGppPin;
  35189. + MV_U8 ledsPolarity; /* '0' or '1' to turn on led */
  35190. + /* GPP values */
  35191. + MV_U32 gppOutEnValLow;
  35192. + MV_U32 gppOutEnValHigh;
  35193. + MV_U32 gppOutValLow;
  35194. + MV_U32 gppOutValHigh;
  35195. + MV_U32 gppPolarityValLow;
  35196. + MV_U32 gppPolarityValHigh;
  35197. +
  35198. + /* Switch Configuration */
  35199. + MV_BOARD_SWITCH_INFO* pSwitchInfo;
  35200. +}MV_BOARD_INFO;
  35201. +
  35202. +
  35203. +
  35204. +MV_VOID mvBoardEnvInit(MV_VOID);
  35205. +MV_U32 mvBoardIdGet(MV_VOID);
  35206. +MV_U16 mvBoardModelGet(MV_VOID);
  35207. +MV_U16 mvBoardRevGet(MV_VOID);
  35208. +MV_STATUS mvBoardNameGet(char *pNameBuff);
  35209. +MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum);
  35210. +MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum);
  35211. +MV_32 mvBoardLinkStatusIrqGet(MV_U32 ethPortNum);
  35212. +MV_32 mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum);
  35213. +MV_32 mvBoardSwitchCpuPortGet(MV_U32 ethPortNum);
  35214. +MV_32 mvBoardIsSwitchConnected(MV_U32 ethPortNum);
  35215. +MV_32 mvBoardSmiScanModeGet(MV_U32 ethPortNum);
  35216. +MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum);
  35217. +MV_BOOL mvBoardIsPortInGmii(MV_VOID);
  35218. +MV_U32 mvBoardTclkGet(MV_VOID);
  35219. +MV_U32 mvBoardSysClkGet(MV_VOID);
  35220. +MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId);
  35221. +MV_VOID mvBoardDebugLed(MV_U32 hexNum);
  35222. +MV_32 mvBoardMppGet(MV_U32 mppGroupNum);
  35223. +
  35224. +MV_U8 mvBoardRtcTwsiAddrTypeGet(MV_VOID);
  35225. +MV_U8 mvBoardRtcTwsiAddrGet(MV_VOID);
  35226. +
  35227. +MV_U8 mvBoardA2DTwsiAddrTypeGet(MV_VOID);
  35228. +MV_U8 mvBoardA2DTwsiAddrGet(MV_VOID);
  35229. +
  35230. +MV_U8 mvBoardTwsiExpAddrGet(MV_U32 index);
  35231. +MV_U8 mvBoardTwsiSatRAddrTypeGet(MV_U32 index);
  35232. +MV_U8 mvBoardTwsiSatRAddrGet(MV_U32 index);
  35233. +MV_U8 mvBoardTwsiExpAddrTypeGet(MV_U32 index);
  35234. +MV_BOARD_MODULE_ID_CLASS mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass);
  35235. +MV_BOARD_MPP_TYPE_CLASS mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass);
  35236. +MV_VOID mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,
  35237. + MV_BOARD_MPP_TYPE_CLASS mppGroupType);
  35238. +MV_VOID mvBoardMppGroupIdUpdate(MV_VOID);
  35239. +MV_VOID mvBoardMppMuxSet(MV_VOID);
  35240. +MV_VOID mvBoardTdmMppSet(MV_32 chType);
  35241. +MV_VOID mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode);
  35242. +
  35243. +MV_VOID mvBoardMppModuleTypePrint(MV_VOID);
  35244. +MV_VOID mvBoardReset(MV_VOID);
  35245. +MV_U8 mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum);
  35246. +MV_STATUS mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal);
  35247. +MV_BOOL mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data);
  35248. +/* Board devices API managments */
  35249. +MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass);
  35250. +MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  35251. +MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  35252. +MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  35253. +MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  35254. +MV_U32 boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  35255. +
  35256. +/* Gpio Pin Connections API */
  35257. +MV_32 mvBoardUSBVbusGpioPinGet(int devId);
  35258. +MV_32 mvBoardUSBVbusEnGpioPinGet(int devId);
  35259. +MV_U32 mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin);
  35260. +
  35261. +MV_32 mvBoardResetGpioPinGet(MV_VOID);
  35262. +MV_32 mvBoardRTCGpioPinGet(MV_VOID);
  35263. +MV_32 mvBoardGpioIntMaskLowGet(MV_VOID);
  35264. +MV_32 mvBoardGpioIntMaskHighGet(MV_VOID);
  35265. +MV_32 mvBoardSlicGpioPinGet(MV_U32 slicNum);
  35266. +
  35267. +MV_32 mvBoardSDIOGpioPinGet(MV_VOID);
  35268. +MV_STATUS mvBoardSDioWPControl(MV_BOOL mode);
  35269. +MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index);
  35270. +
  35271. +MV_32 mvBoardNandWidthGet(void);
  35272. +MV_STATUS mvBoardFanPowerControl(MV_BOOL mode);
  35273. +MV_STATUS mvBoardHDDPowerControl(MV_BOOL mode);
  35274. +#endif /* __INCmvBoardEnvLibh */
  35275. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c
  35276. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c 1970-01-01 01:00:00.000000000 +0100
  35277. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c 2011-07-31 11:31:56.473413613 +0200
  35278. @@ -0,0 +1,848 @@
  35279. +/*******************************************************************************
  35280. +Copyright (C) Marvell International Ltd. and its affiliates
  35281. +
  35282. +This software file (the "File") is owned and distributed by Marvell
  35283. +International Ltd. and/or its affiliates ("Marvell") under the following
  35284. +alternative licensing terms. Once you have made an election to distribute the
  35285. +File under one of the following license alternatives, please (i) delete this
  35286. +introductory statement regarding license alternatives, (ii) delete the two
  35287. +license alternatives that you have not elected to use and (iii) preserve the
  35288. +Marvell copyright notice above.
  35289. +
  35290. +********************************************************************************
  35291. +Marvell Commercial License Option
  35292. +
  35293. +If you received this File from Marvell and you have entered into a commercial
  35294. +license agreement (a "Commercial License") with Marvell, the File is licensed
  35295. +to you under the terms of the applicable Commercial License.
  35296. +
  35297. +********************************************************************************
  35298. +Marvell GPL License Option
  35299. +
  35300. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35301. +modify this File in accordance with the terms and conditions of the General
  35302. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  35303. +available along with the File in the license.txt file or by writing to the Free
  35304. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  35305. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  35306. +
  35307. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  35308. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  35309. +DISCLAIMED. The GPL License provides additional details about this warranty
  35310. +disclaimer.
  35311. +********************************************************************************
  35312. +Marvell BSD License Option
  35313. +
  35314. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35315. +modify this File under the following licensing terms.
  35316. +Redistribution and use in source and binary forms, with or without modification,
  35317. +are permitted provided that the following conditions are met:
  35318. +
  35319. + * Redistributions of source code must retain the above copyright notice,
  35320. + this list of conditions and the following disclaimer.
  35321. +
  35322. + * Redistributions in binary form must reproduce the above copyright
  35323. + notice, this list of conditions and the following disclaimer in the
  35324. + documentation and/or other materials provided with the distribution.
  35325. +
  35326. + * Neither the name of Marvell nor the names of its contributors may be
  35327. + used to endorse or promote products derived from this software without
  35328. + specific prior written permission.
  35329. +
  35330. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  35331. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  35332. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35333. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  35334. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  35335. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35336. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  35337. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35338. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35339. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35340. +
  35341. +*******************************************************************************/
  35342. +#include "mvCommon.h"
  35343. +#include "mvBoardEnvLib.h"
  35344. +#include "mvBoardEnvSpec.h"
  35345. +#include "twsi/mvTwsi.h"
  35346. +
  35347. +#define DB_88F6281A_BOARD_PCI_IF_NUM 0x0
  35348. +#define DB_88F6281A_BOARD_TWSI_DEF_NUM 0x7
  35349. +#define DB_88F6281A_BOARD_MAC_INFO_NUM 0x2
  35350. +#define DB_88F6281A_BOARD_GPP_INFO_NUM 0x3
  35351. +#define DB_88F6281A_BOARD_MPP_CONFIG_NUM 0x1
  35352. +#define DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  35353. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35354. + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  35355. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35356. + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x2
  35357. +#else
  35358. + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  35359. +#endif
  35360. +#define DB_88F6281A_BOARD_DEBUG_LED_NUM 0x0
  35361. +
  35362. +
  35363. +MV_BOARD_TWSI_INFO db88f6281AInfoBoardTwsiDev[] =
  35364. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  35365. + {
  35366. + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
  35367. + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
  35368. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
  35369. + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
  35370. + {BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},
  35371. + {BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},
  35372. + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
  35373. + };
  35374. +
  35375. +MV_BOARD_MAC_INFO db88f6281AInfoBoardMacInfo[] =
  35376. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35377. + {
  35378. + {BOARD_MAC_SPEED_AUTO, 0x8},
  35379. + {BOARD_MAC_SPEED_AUTO, 0x9}
  35380. + };
  35381. +
  35382. +MV_BOARD_MPP_TYPE_INFO db88f6281AInfoBoardMppTypeInfo[] =
  35383. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  35384. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  35385. + {{MV_BOARD_AUTO, MV_BOARD_AUTO}
  35386. + };
  35387. +
  35388. +MV_BOARD_GPP_INFO db88f6281AInfoBoardGppInfo[] =
  35389. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  35390. + {
  35391. + {BOARD_GPP_TSU_DIRCTION, 33}
  35392. + /*muxed with TDM/Audio module via IOexpender
  35393. + {BOARD_GPP_SDIO_DETECT, 38},
  35394. + {BOARD_GPP_USB_VBUS, 49}*/
  35395. + };
  35396. +
  35397. +MV_DEV_CS_INFO db88f6281AInfoBoardDeCsInfo[] =
  35398. + /*{deviceCS, params, devType, devWidth}*/
  35399. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35400. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  35401. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35402. + {
  35403. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  35404. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  35405. + };
  35406. +#else
  35407. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  35408. +#endif
  35409. +
  35410. +MV_BOARD_MPP_INFO db88f6281AInfoBoardMppConfigValue[] =
  35411. + {{{
  35412. + DB_88F6281A_MPP0_7,
  35413. + DB_88F6281A_MPP8_15,
  35414. + DB_88F6281A_MPP16_23,
  35415. + DB_88F6281A_MPP24_31,
  35416. + DB_88F6281A_MPP32_39,
  35417. + DB_88F6281A_MPP40_47,
  35418. + DB_88F6281A_MPP48_55
  35419. + }}};
  35420. +
  35421. +
  35422. +MV_BOARD_INFO db88f6281AInfo = {
  35423. + "DB-88F6281A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  35424. + DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  35425. + db88f6281AInfoBoardMppTypeInfo,
  35426. + DB_88F6281A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35427. + db88f6281AInfoBoardMppConfigValue,
  35428. + 0, /* intsGppMaskLow */
  35429. + 0, /* intsGppMaskHigh */
  35430. + DB_88F6281A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35431. + db88f6281AInfoBoardDeCsInfo,
  35432. + DB_88F6281A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35433. + db88f6281AInfoBoardTwsiDev,
  35434. + DB_88F6281A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35435. + db88f6281AInfoBoardMacInfo,
  35436. + DB_88F6281A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35437. + db88f6281AInfoBoardGppInfo,
  35438. + DB_88F6281A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35439. + NULL,
  35440. + 0, /* ledsPolarity */
  35441. + DB_88F6281A_OE_LOW, /* gppOutEnLow */
  35442. + DB_88F6281A_OE_HIGH, /* gppOutEnHigh */
  35443. + DB_88F6281A_OE_VAL_LOW, /* gppOutValLow */
  35444. + DB_88F6281A_OE_VAL_HIGH, /* gppOutValHigh */
  35445. + 0, /* gppPolarityValLow */
  35446. + BIT6, /* gppPolarityValHigh */
  35447. + NULL /* pSwitchInfo */
  35448. +};
  35449. +
  35450. +
  35451. +#define RD_88F6281A_BOARD_PCI_IF_NUM 0x0
  35452. +#define RD_88F6281A_BOARD_TWSI_DEF_NUM 0x2
  35453. +#define RD_88F6281A_BOARD_MAC_INFO_NUM 0x2
  35454. +#define RD_88F6281A_BOARD_GPP_INFO_NUM 0x5
  35455. +#define RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  35456. +#define RD_88F6281A_BOARD_MPP_CONFIG_NUM 0x1
  35457. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35458. + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  35459. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35460. + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x2
  35461. +#else
  35462. + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  35463. +#endif
  35464. +#define RD_88F6281A_BOARD_DEBUG_LED_NUM 0x0
  35465. +
  35466. +MV_BOARD_MAC_INFO rd88f6281AInfoBoardMacInfo[] =
  35467. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35468. + {{BOARD_MAC_SPEED_1000M, 0xa},
  35469. + {BOARD_MAC_SPEED_AUTO, 0xb}
  35470. + };
  35471. +
  35472. +MV_BOARD_SWITCH_INFO rd88f6281AInfoBoardSwitchInfo[] =
  35473. + /* MV_32 linkStatusIrq, {MV_32 qdPort0, MV_32 qdPort1, MV_32 qdPort2, MV_32 qdPort3, MV_32 qdPort4},
  35474. + MV_32 qdCpuPort, MV_32 smiScanMode, MV_32 switchOnPort} */
  35475. + {{38, {0, 1, 2, 3, -1}, 5, 2, 0},
  35476. + {-1, {-1}, -1, -1, -1}};
  35477. +
  35478. +MV_BOARD_TWSI_INFO rd88f6281AInfoBoardTwsiDev[] =
  35479. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  35480. + {
  35481. + {BOARD_DEV_TWSI_EXP, 0xFF, ADDR7_BIT}, /* dummy entry to align with modules indexes */
  35482. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT}
  35483. + };
  35484. +
  35485. +MV_BOARD_MPP_TYPE_INFO rd88f6281AInfoBoardMppTypeInfo[] =
  35486. + {{MV_BOARD_RGMII, MV_BOARD_TDM}
  35487. + };
  35488. +
  35489. +MV_DEV_CS_INFO rd88f6281AInfoBoardDeCsInfo[] =
  35490. + /*{deviceCS, params, devType, devWidth}*/
  35491. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35492. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  35493. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35494. + {
  35495. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  35496. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  35497. + };
  35498. +#else
  35499. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  35500. +#endif
  35501. +
  35502. +MV_BOARD_GPP_INFO rd88f6281AInfoBoardGppInfo[] =
  35503. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  35504. + {{BOARD_GPP_SDIO_DETECT, 28},
  35505. + {BOARD_GPP_USB_OC, 29},
  35506. + {BOARD_GPP_WPS_BUTTON, 35},
  35507. + {BOARD_GPP_MV_SWITCH, 38},
  35508. + {BOARD_GPP_USB_VBUS, 49}
  35509. + };
  35510. +
  35511. +MV_BOARD_MPP_INFO rd88f6281AInfoBoardMppConfigValue[] =
  35512. + {{{
  35513. + RD_88F6281A_MPP0_7,
  35514. + RD_88F6281A_MPP8_15,
  35515. + RD_88F6281A_MPP16_23,
  35516. + RD_88F6281A_MPP24_31,
  35517. + RD_88F6281A_MPP32_39,
  35518. + RD_88F6281A_MPP40_47,
  35519. + RD_88F6281A_MPP48_55
  35520. + }}};
  35521. +
  35522. +MV_BOARD_INFO rd88f6281AInfo = {
  35523. + "RD-88F6281A", /* boardName[MAX_BOARD_NAME_LEN] */
  35524. + RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  35525. + rd88f6281AInfoBoardMppTypeInfo,
  35526. + RD_88F6281A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35527. + rd88f6281AInfoBoardMppConfigValue,
  35528. + 0, /* intsGppMaskLow */
  35529. + (1 << 3), /* intsGppMaskHigh */
  35530. + RD_88F6281A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35531. + rd88f6281AInfoBoardDeCsInfo,
  35532. + RD_88F6281A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35533. + rd88f6281AInfoBoardTwsiDev,
  35534. + RD_88F6281A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35535. + rd88f6281AInfoBoardMacInfo,
  35536. + RD_88F6281A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35537. + rd88f6281AInfoBoardGppInfo,
  35538. + RD_88F6281A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35539. + NULL,
  35540. + 0, /* ledsPolarity */
  35541. + RD_88F6281A_OE_LOW, /* gppOutEnLow */
  35542. + RD_88F6281A_OE_HIGH, /* gppOutEnHigh */
  35543. + RD_88F6281A_OE_VAL_LOW, /* gppOutValLow */
  35544. + RD_88F6281A_OE_VAL_HIGH, /* gppOutValHigh */
  35545. + 0, /* gppPolarityValLow */
  35546. + BIT6, /* gppPolarityValHigh */
  35547. + rd88f6281AInfoBoardSwitchInfo /* pSwitchInfo */
  35548. +};
  35549. +
  35550. +
  35551. +#define DB_88F6192A_BOARD_PCI_IF_NUM 0x0
  35552. +#define DB_88F6192A_BOARD_TWSI_DEF_NUM 0x7
  35553. +#define DB_88F6192A_BOARD_MAC_INFO_NUM 0x2
  35554. +#define DB_88F6192A_BOARD_GPP_INFO_NUM 0x3
  35555. +#define DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  35556. +#define DB_88F6192A_BOARD_MPP_CONFIG_NUM 0x1
  35557. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35558. + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
  35559. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35560. + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x2
  35561. +#else
  35562. + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
  35563. +#endif
  35564. +#define DB_88F6192A_BOARD_DEBUG_LED_NUM 0x0
  35565. +
  35566. +MV_BOARD_TWSI_INFO db88f6192AInfoBoardTwsiDev[] =
  35567. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  35568. + {
  35569. + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
  35570. + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
  35571. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
  35572. + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
  35573. + {BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},
  35574. + {BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},
  35575. + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
  35576. + };
  35577. +
  35578. +MV_BOARD_MAC_INFO db88f6192AInfoBoardMacInfo[] =
  35579. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35580. + {
  35581. + {BOARD_MAC_SPEED_AUTO, 0x8},
  35582. + {BOARD_MAC_SPEED_AUTO, 0x9}
  35583. + };
  35584. +
  35585. +MV_BOARD_MPP_TYPE_INFO db88f6192AInfoBoardMppTypeInfo[] =
  35586. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  35587. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  35588. + {{MV_BOARD_AUTO, MV_BOARD_OTHER}
  35589. + };
  35590. +
  35591. +MV_DEV_CS_INFO db88f6192AInfoBoardDeCsInfo[] =
  35592. + /*{deviceCS, params, devType, devWidth}*/
  35593. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35594. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  35595. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35596. + {
  35597. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  35598. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  35599. + };
  35600. +#else
  35601. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  35602. +#endif
  35603. +
  35604. +MV_BOARD_GPP_INFO db88f6192AInfoBoardGppInfo[] =
  35605. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  35606. + {
  35607. + {BOARD_GPP_SDIO_WP, 20},
  35608. + {BOARD_GPP_USB_VBUS, 22},
  35609. + {BOARD_GPP_SDIO_DETECT, 23},
  35610. + };
  35611. +
  35612. +MV_BOARD_MPP_INFO db88f6192AInfoBoardMppConfigValue[] =
  35613. + {{{
  35614. + DB_88F6192A_MPP0_7,
  35615. + DB_88F6192A_MPP8_15,
  35616. + DB_88F6192A_MPP16_23,
  35617. + DB_88F6192A_MPP24_31,
  35618. + DB_88F6192A_MPP32_35
  35619. + }}};
  35620. +
  35621. +MV_BOARD_INFO db88f6192AInfo = {
  35622. + "DB-88F6192A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  35623. + DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  35624. + db88f6192AInfoBoardMppTypeInfo,
  35625. + DB_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35626. + db88f6192AInfoBoardMppConfigValue,
  35627. + 0, /* intsGppMaskLow */
  35628. + (1 << 3), /* intsGppMaskHigh */
  35629. + DB_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35630. + db88f6192AInfoBoardDeCsInfo,
  35631. + DB_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35632. + db88f6192AInfoBoardTwsiDev,
  35633. + DB_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35634. + db88f6192AInfoBoardMacInfo,
  35635. + DB_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35636. + db88f6192AInfoBoardGppInfo,
  35637. + DB_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35638. + NULL,
  35639. + 0, /* ledsPolarity */
  35640. + DB_88F6192A_OE_LOW, /* gppOutEnLow */
  35641. + DB_88F6192A_OE_HIGH, /* gppOutEnHigh */
  35642. + DB_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  35643. + DB_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  35644. + 0, /* gppPolarityValLow */
  35645. + 0, /* gppPolarityValHigh */
  35646. + NULL /* pSwitchInfo */
  35647. +};
  35648. +
  35649. +#define DB_88F6190A_BOARD_MAC_INFO_NUM 0x1
  35650. +
  35651. +MV_BOARD_INFO db88f6190AInfo = {
  35652. + "DB-88F6190A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  35653. + DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  35654. + db88f6192AInfoBoardMppTypeInfo,
  35655. + DB_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35656. + db88f6192AInfoBoardMppConfigValue,
  35657. + 0, /* intsGppMaskLow */
  35658. + (1 << 3), /* intsGppMaskHigh */
  35659. + DB_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35660. + db88f6192AInfoBoardDeCsInfo,
  35661. + DB_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35662. + db88f6192AInfoBoardTwsiDev,
  35663. + DB_88F6190A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35664. + db88f6192AInfoBoardMacInfo,
  35665. + DB_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35666. + db88f6192AInfoBoardGppInfo,
  35667. + DB_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35668. + NULL,
  35669. + 0, /* ledsPolarity */
  35670. + DB_88F6192A_OE_LOW, /* gppOutEnLow */
  35671. + DB_88F6192A_OE_HIGH, /* gppOutEnHigh */
  35672. + DB_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  35673. + DB_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  35674. + 0, /* gppPolarityValLow */
  35675. + 0, /* gppPolarityValHigh */
  35676. + NULL /* pSwitchInfo */
  35677. +};
  35678. +
  35679. +#define RD_88F6192A_BOARD_PCI_IF_NUM 0x0
  35680. +#define RD_88F6192A_BOARD_TWSI_DEF_NUM 0x0
  35681. +#define RD_88F6192A_BOARD_MAC_INFO_NUM 0x1
  35682. +#define RD_88F6192A_BOARD_GPP_INFO_NUM 0xE
  35683. +#define RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  35684. +#define RD_88F6192A_BOARD_MPP_CONFIG_NUM 0x1
  35685. +#define RD_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
  35686. +#define RD_88F6192A_BOARD_DEBUG_LED_NUM 0x3
  35687. +
  35688. +MV_U8 rd88f6192AInfoBoardDebugLedIf[] =
  35689. + {17, 28, 29};
  35690. +
  35691. +MV_BOARD_MAC_INFO rd88f6192AInfoBoardMacInfo[] =
  35692. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35693. + {{BOARD_MAC_SPEED_AUTO, 0x8}
  35694. + };
  35695. +
  35696. +MV_BOARD_MPP_TYPE_INFO rd88f6192AInfoBoardMppTypeInfo[] =
  35697. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  35698. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  35699. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  35700. + };
  35701. +
  35702. +MV_DEV_CS_INFO rd88f6192AInfoBoardDeCsInfo[] =
  35703. + /*{deviceCS, params, devType, devWidth}*/
  35704. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  35705. +
  35706. +MV_BOARD_GPP_INFO rd88f6192AInfoBoardGppInfo[] =
  35707. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  35708. + {
  35709. + {BOARD_GPP_USB_VBUS_EN, 10},
  35710. + {BOARD_GPP_USB_HOST_DEVICE, 11},
  35711. + {BOARD_GPP_RESET, 14},
  35712. + {BOARD_GPP_POWER_ON_LED, 15},
  35713. + {BOARD_GPP_HDD_POWER, 16},
  35714. + {BOARD_GPP_WPS_BUTTON, 24},
  35715. + {BOARD_GPP_TS_BUTTON_C, 25},
  35716. + {BOARD_GPP_USB_VBUS, 26},
  35717. + {BOARD_GPP_USB_OC, 27},
  35718. + {BOARD_GPP_TS_BUTTON_U, 30},
  35719. + {BOARD_GPP_TS_BUTTON_R, 31},
  35720. + {BOARD_GPP_TS_BUTTON_L, 32},
  35721. + {BOARD_GPP_TS_BUTTON_D, 34},
  35722. + {BOARD_GPP_FAN_POWER, 35}
  35723. + };
  35724. +
  35725. +MV_BOARD_MPP_INFO rd88f6192AInfoBoardMppConfigValue[] =
  35726. + {{{
  35727. + RD_88F6192A_MPP0_7,
  35728. + RD_88F6192A_MPP8_15,
  35729. + RD_88F6192A_MPP16_23,
  35730. + RD_88F6192A_MPP24_31,
  35731. + RD_88F6192A_MPP32_35
  35732. + }}};
  35733. +
  35734. +MV_BOARD_INFO rd88f6192AInfo = {
  35735. + "RD-88F6192A-NAS", /* boardName[MAX_BOARD_NAME_LEN] */
  35736. + RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  35737. + rd88f6192AInfoBoardMppTypeInfo,
  35738. + RD_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35739. + rd88f6192AInfoBoardMppConfigValue,
  35740. + 0, /* intsGppMaskLow */
  35741. + (1 << 3), /* intsGppMaskHigh */
  35742. + RD_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35743. + rd88f6192AInfoBoardDeCsInfo,
  35744. + RD_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35745. + NULL,
  35746. + RD_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35747. + rd88f6192AInfoBoardMacInfo,
  35748. + RD_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35749. + rd88f6192AInfoBoardGppInfo,
  35750. + RD_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35751. + rd88f6192AInfoBoardDebugLedIf,
  35752. + 0, /* ledsPolarity */
  35753. + RD_88F6192A_OE_LOW, /* gppOutEnLow */
  35754. + RD_88F6192A_OE_HIGH, /* gppOutEnHigh */
  35755. + RD_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  35756. + RD_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  35757. + 0, /* gppPolarityValLow */
  35758. + 0, /* gppPolarityValHigh */
  35759. + NULL /* pSwitchInfo */
  35760. +};
  35761. +
  35762. +MV_BOARD_INFO rd88f6190AInfo = {
  35763. + "RD-88F6190A-NAS", /* boardName[MAX_BOARD_NAME_LEN] */
  35764. + RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  35765. + rd88f6192AInfoBoardMppTypeInfo,
  35766. + RD_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35767. + rd88f6192AInfoBoardMppConfigValue,
  35768. + 0, /* intsGppMaskLow */
  35769. + (1 << 3), /* intsGppMaskHigh */
  35770. + RD_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35771. + rd88f6192AInfoBoardDeCsInfo,
  35772. + RD_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35773. + NULL,
  35774. + RD_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35775. + rd88f6192AInfoBoardMacInfo,
  35776. + RD_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35777. + rd88f6192AInfoBoardGppInfo,
  35778. + RD_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35779. + rd88f6192AInfoBoardDebugLedIf,
  35780. + 0, /* ledsPolarity */
  35781. + RD_88F6192A_OE_LOW, /* gppOutEnLow */
  35782. + RD_88F6192A_OE_HIGH, /* gppOutEnHigh */
  35783. + RD_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  35784. + RD_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  35785. + 0, /* gppPolarityValLow */
  35786. + 0, /* gppPolarityValHigh */
  35787. + NULL /* pSwitchInfo */
  35788. +};
  35789. +
  35790. +#define DB_88F6180A_BOARD_PCI_IF_NUM 0x0
  35791. +#define DB_88F6180A_BOARD_TWSI_DEF_NUM 0x5
  35792. +#define DB_88F6180A_BOARD_MAC_INFO_NUM 0x1
  35793. +#define DB_88F6180A_BOARD_GPP_INFO_NUM 0x0
  35794. +#define DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM 0x2
  35795. +#define DB_88F6180A_BOARD_MPP_CONFIG_NUM 0x1
  35796. +#define DB_88F6180A_BOARD_DEVICE_CONFIG_NUM 0x1
  35797. +#define DB_88F6180A_BOARD_DEBUG_LED_NUM 0x0
  35798. +
  35799. +MV_BOARD_TWSI_INFO db88f6180AInfoBoardTwsiDev[] =
  35800. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  35801. + {
  35802. + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
  35803. + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
  35804. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
  35805. + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
  35806. + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
  35807. + };
  35808. +
  35809. +MV_BOARD_MAC_INFO db88f6180AInfoBoardMacInfo[] =
  35810. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35811. + {{BOARD_MAC_SPEED_AUTO, 0x8}
  35812. + };
  35813. +
  35814. +MV_BOARD_GPP_INFO db88f6180AInfoBoardGppInfo[] =
  35815. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  35816. + {
  35817. + /* Muxed with TDM/Audio module via IOexpender
  35818. + {BOARD_GPP_USB_VBUS, 6} */
  35819. + };
  35820. +
  35821. +MV_BOARD_MPP_TYPE_INFO db88f6180AInfoBoardMppTypeInfo[] =
  35822. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  35823. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  35824. + {{MV_BOARD_OTHER, MV_BOARD_AUTO}
  35825. + };
  35826. +
  35827. +MV_DEV_CS_INFO db88f6180AInfoBoardDeCsInfo[] =
  35828. + /*{deviceCS, params, devType, devWidth}*/
  35829. +#if defined(MV_NAND_BOOT)
  35830. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  35831. +#else
  35832. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  35833. +#endif
  35834. +
  35835. +MV_BOARD_MPP_INFO db88f6180AInfoBoardMppConfigValue[] =
  35836. + {{{
  35837. + DB_88F6180A_MPP0_7,
  35838. + DB_88F6180A_MPP8_15,
  35839. + DB_88F6180A_MPP16_23,
  35840. + DB_88F6180A_MPP24_31,
  35841. + DB_88F6180A_MPP32_39,
  35842. + DB_88F6180A_MPP40_44
  35843. + }}};
  35844. +
  35845. +MV_BOARD_INFO db88f6180AInfo = {
  35846. + "DB-88F6180A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  35847. + DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  35848. + db88f6180AInfoBoardMppTypeInfo,
  35849. + DB_88F6180A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35850. + db88f6180AInfoBoardMppConfigValue,
  35851. + 0, /* intsGppMaskLow */
  35852. + 0, /* intsGppMaskHigh */
  35853. + DB_88F6180A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35854. + db88f6180AInfoBoardDeCsInfo,
  35855. + DB_88F6180A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35856. + db88f6180AInfoBoardTwsiDev,
  35857. + DB_88F6180A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35858. + db88f6180AInfoBoardMacInfo,
  35859. + DB_88F6180A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35860. + NULL,
  35861. + DB_88F6180A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35862. + NULL,
  35863. + 0, /* ledsPolarity */
  35864. + DB_88F6180A_OE_LOW, /* gppOutEnLow */
  35865. + DB_88F6180A_OE_HIGH, /* gppOutEnHigh */
  35866. + DB_88F6180A_OE_VAL_LOW, /* gppOutValLow */
  35867. + DB_88F6180A_OE_VAL_HIGH, /* gppOutValHigh */
  35868. + 0, /* gppPolarityValLow */
  35869. + 0, /* gppPolarityValHigh */
  35870. + NULL /* pSwitchInfo */
  35871. +};
  35872. +
  35873. +
  35874. +#define RD_88F6281A_PCAC_BOARD_PCI_IF_NUM 0x0
  35875. +#define RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM 0x1
  35876. +#define RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM 0x1
  35877. +#define RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM 0x0
  35878. +#define RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM 0x1
  35879. +#define RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM 0x1
  35880. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35881. + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x1
  35882. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35883. + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x2
  35884. +#else
  35885. + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x1
  35886. +#endif
  35887. +#define RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM 0x4
  35888. +
  35889. +MV_U8 rd88f6281APcacInfoBoardDebugLedIf[] =
  35890. + {38, 39, 40, 41};
  35891. +
  35892. +MV_BOARD_MAC_INFO rd88f6281APcacInfoBoardMacInfo[] =
  35893. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35894. + {{BOARD_MAC_SPEED_AUTO, 0x8}
  35895. + };
  35896. +
  35897. +MV_BOARD_TWSI_INFO rd88f6281APcacInfoBoardTwsiDev[] =
  35898. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  35899. + {
  35900. + {BOARD_TWSI_OTHER, 0xa7, ADDR7_BIT}
  35901. + };
  35902. +
  35903. +MV_BOARD_MPP_TYPE_INFO rd88f6281APcacInfoBoardMppTypeInfo[] =
  35904. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  35905. + };
  35906. +
  35907. +MV_DEV_CS_INFO rd88f6281APcacInfoBoardDeCsInfo[] =
  35908. + /*{deviceCS, params, devType, devWidth}*/
  35909. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35910. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  35911. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35912. + {
  35913. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  35914. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  35915. + };
  35916. +#else
  35917. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  35918. +#endif
  35919. +
  35920. +MV_BOARD_MPP_INFO rd88f6281APcacInfoBoardMppConfigValue[] =
  35921. + {{{
  35922. + RD_88F6281A_PCAC_MPP0_7,
  35923. + RD_88F6281A_PCAC_MPP8_15,
  35924. + RD_88F6281A_PCAC_MPP16_23,
  35925. + RD_88F6281A_PCAC_MPP24_31,
  35926. + RD_88F6281A_PCAC_MPP32_39,
  35927. + RD_88F6281A_PCAC_MPP40_47,
  35928. + RD_88F6281A_PCAC_MPP48_55
  35929. + }}};
  35930. +
  35931. +MV_BOARD_INFO rd88f6281APcacInfo = {
  35932. + "RD-88F6281A-PCAC", /* boardName[MAX_BOARD_NAME_LEN] */
  35933. + RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  35934. + rd88f6281APcacInfoBoardMppTypeInfo,
  35935. + RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35936. + rd88f6281APcacInfoBoardMppConfigValue,
  35937. + 0, /* intsGppMaskLow */
  35938. + (1 << 3), /* intsGppMaskHigh */
  35939. + RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35940. + rd88f6281APcacInfoBoardDeCsInfo,
  35941. + RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35942. + rd88f6281APcacInfoBoardTwsiDev,
  35943. + RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35944. + rd88f6281APcacInfoBoardMacInfo,
  35945. + RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35946. + 0,
  35947. + RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35948. + NULL,
  35949. + 0, /* ledsPolarity */
  35950. + RD_88F6281A_PCAC_OE_LOW, /* gppOutEnLow */
  35951. + RD_88F6281A_PCAC_OE_HIGH, /* gppOutEnHigh */
  35952. + RD_88F6281A_PCAC_OE_VAL_LOW, /* gppOutValLow */
  35953. + RD_88F6281A_PCAC_OE_VAL_HIGH, /* gppOutValHigh */
  35954. + 0, /* gppPolarityValLow */
  35955. + 0, /* gppPolarityValHigh */
  35956. + NULL /* pSwitchInfo */
  35957. +};
  35958. +
  35959. +
  35960. +/* 6281 Sheeva Plug*/
  35961. +
  35962. +#define SHEEVA_PLUG_BOARD_PCI_IF_NUM 0x0
  35963. +#define SHEEVA_PLUG_BOARD_TWSI_DEF_NUM 0x0
  35964. +#define SHEEVA_PLUG_BOARD_MAC_INFO_NUM 0x1
  35965. +#define SHEEVA_PLUG_BOARD_GPP_INFO_NUM 0x0
  35966. +#define SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN 0x1
  35967. +#define SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM 0x1
  35968. +#define SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM 0x1
  35969. +#define SHEEVA_PLUG_BOARD_DEBUG_LED_NUM 0x1
  35970. +
  35971. +MV_U8 sheevaPlugInfoBoardDebugLedIf[] =
  35972. + {49};
  35973. +
  35974. +MV_BOARD_MAC_INFO sheevaPlugInfoBoardMacInfo[] =
  35975. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35976. + {{BOARD_MAC_SPEED_AUTO, 0x0}};
  35977. +
  35978. +MV_BOARD_TWSI_INFO sheevaPlugInfoBoardTwsiDev[] =
  35979. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  35980. + {{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};
  35981. +
  35982. +MV_BOARD_MPP_TYPE_INFO sheevaPlugInfoBoardMppTypeInfo[] =
  35983. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  35984. + };
  35985. +
  35986. +MV_DEV_CS_INFO sheevaPlugInfoBoardDeCsInfo[] =
  35987. + /*{deviceCS, params, devType, devWidth}*/
  35988. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  35989. +
  35990. +MV_BOARD_MPP_INFO sheevaPlugInfoBoardMppConfigValue[] =
  35991. + {{{
  35992. + RD_SHEEVA_PLUG_MPP0_7,
  35993. + RD_SHEEVA_PLUG_MPP8_15,
  35994. + RD_SHEEVA_PLUG_MPP16_23,
  35995. + RD_SHEEVA_PLUG_MPP24_31,
  35996. + RD_SHEEVA_PLUG_MPP32_39,
  35997. + RD_SHEEVA_PLUG_MPP40_47,
  35998. + RD_SHEEVA_PLUG_MPP48_55
  35999. + }}};
  36000. +
  36001. +MV_BOARD_INFO sheevaPlugInfo = {
  36002. + "SHEEVA PLUG", /* boardName[MAX_BOARD_NAME_LEN] */
  36003. + SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN, /* numBoardMppGroupType */
  36004. + sheevaPlugInfoBoardMppTypeInfo,
  36005. + SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  36006. + sheevaPlugInfoBoardMppConfigValue,
  36007. + 0, /* intsGppMaskLow */
  36008. + 0, /* intsGppMaskHigh */
  36009. + SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  36010. + sheevaPlugInfoBoardDeCsInfo,
  36011. + SHEEVA_PLUG_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  36012. + sheevaPlugInfoBoardTwsiDev,
  36013. + SHEEVA_PLUG_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  36014. + sheevaPlugInfoBoardMacInfo,
  36015. + SHEEVA_PLUG_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  36016. + 0,
  36017. + SHEEVA_PLUG_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  36018. + sheevaPlugInfoBoardDebugLedIf,
  36019. + 0, /* ledsPolarity */
  36020. + RD_SHEEVA_PLUG_OE_LOW, /* gppOutEnLow */
  36021. + RD_SHEEVA_PLUG_OE_HIGH, /* gppOutEnHigh */
  36022. + RD_SHEEVA_PLUG_OE_VAL_LOW, /* gppOutValLow */
  36023. + RD_SHEEVA_PLUG_OE_VAL_HIGH, /* gppOutValHigh */
  36024. + 0, /* gppPolarityValLow */
  36025. + 0, /* gppPolarityValHigh */
  36026. + NULL /* pSwitchInfo */
  36027. +};
  36028. +
  36029. +/* Customer specific board place holder*/
  36030. +
  36031. +#define DB_CUSTOMER_BOARD_PCI_IF_NUM 0x0
  36032. +#define DB_CUSTOMER_BOARD_TWSI_DEF_NUM 0x0
  36033. +#define DB_CUSTOMER_BOARD_MAC_INFO_NUM 0x0
  36034. +#define DB_CUSTOMER_BOARD_GPP_INFO_NUM 0x0
  36035. +#define DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN 0x0
  36036. +#define DB_CUSTOMER_BOARD_MPP_CONFIG_NUM 0x0
  36037. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  36038. + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
  36039. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  36040. + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
  36041. +#else
  36042. + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
  36043. +#endif
  36044. +#define DB_CUSTOMER_BOARD_DEBUG_LED_NUM 0x0
  36045. +
  36046. +MV_U8 dbCustomerInfoBoardDebugLedIf[] =
  36047. + {0};
  36048. +
  36049. +MV_BOARD_MAC_INFO dbCustomerInfoBoardMacInfo[] =
  36050. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  36051. + {{BOARD_MAC_SPEED_AUTO, 0x0}};
  36052. +
  36053. +MV_BOARD_TWSI_INFO dbCustomerInfoBoardTwsiDev[] =
  36054. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  36055. + {{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};
  36056. +
  36057. +MV_BOARD_MPP_TYPE_INFO dbCustomerInfoBoardMppTypeInfo[] =
  36058. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  36059. + };
  36060. +
  36061. +MV_DEV_CS_INFO dbCustomerInfoBoardDeCsInfo[] =
  36062. + /*{deviceCS, params, devType, devWidth}*/
  36063. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  36064. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  36065. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  36066. + {
  36067. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  36068. + {2, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  36069. + };
  36070. +#else
  36071. + {{2, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  36072. +#endif
  36073. +
  36074. +MV_BOARD_MPP_INFO dbCustomerInfoBoardMppConfigValue[] =
  36075. + {{{
  36076. + DB_CUSTOMER_MPP0_7,
  36077. + DB_CUSTOMER_MPP8_15,
  36078. + DB_CUSTOMER_MPP16_23,
  36079. + DB_CUSTOMER_MPP24_31,
  36080. + DB_CUSTOMER_MPP32_39,
  36081. + DB_CUSTOMER_MPP40_47,
  36082. + DB_CUSTOMER_MPP48_55
  36083. + }}};
  36084. +
  36085. +MV_BOARD_INFO dbCustomerInfo = {
  36086. + "DB-CUSTOMER", /* boardName[MAX_BOARD_NAME_LEN] */
  36087. + DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN, /* numBoardMppGroupType */
  36088. + dbCustomerInfoBoardMppTypeInfo,
  36089. + DB_CUSTOMER_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  36090. + dbCustomerInfoBoardMppConfigValue,
  36091. + 0, /* intsGppMaskLow */
  36092. + 0, /* intsGppMaskHigh */
  36093. + DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  36094. + dbCustomerInfoBoardDeCsInfo,
  36095. + DB_CUSTOMER_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  36096. + dbCustomerInfoBoardTwsiDev,
  36097. + DB_CUSTOMER_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  36098. + dbCustomerInfoBoardMacInfo,
  36099. + DB_CUSTOMER_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  36100. + 0,
  36101. + DB_CUSTOMER_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  36102. + NULL,
  36103. + 0, /* ledsPolarity */
  36104. + DB_CUSTOMER_OE_LOW, /* gppOutEnLow */
  36105. + DB_CUSTOMER_OE_HIGH, /* gppOutEnHigh */
  36106. + DB_CUSTOMER_OE_VAL_LOW, /* gppOutValLow */
  36107. + DB_CUSTOMER_OE_VAL_HIGH, /* gppOutValHigh */
  36108. + 0, /* gppPolarityValLow */
  36109. + 0, /* gppPolarityValHigh */
  36110. + NULL /* pSwitchInfo */
  36111. +};
  36112. +
  36113. +MV_BOARD_INFO* boardInfoTbl[] = {
  36114. + &db88f6281AInfo,
  36115. + &rd88f6281AInfo,
  36116. + &db88f6192AInfo,
  36117. + &rd88f6192AInfo,
  36118. + &db88f6180AInfo,
  36119. + &db88f6190AInfo,
  36120. + &rd88f6190AInfo,
  36121. + &rd88f6281APcacInfo,
  36122. + &dbCustomerInfo,
  36123. + &sheevaPlugInfo
  36124. + };
  36125. +
  36126. +
  36127. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h
  36128. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h 1970-01-01 01:00:00.000000000 +0100
  36129. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h 2011-07-31 11:31:56.503416279 +0200
  36130. @@ -0,0 +1,262 @@
  36131. +/*******************************************************************************
  36132. +Copyright (C) Marvell International Ltd. and its affiliates
  36133. +
  36134. +This software file (the "File") is owned and distributed by Marvell
  36135. +International Ltd. and/or its affiliates ("Marvell") under the following
  36136. +alternative licensing terms. Once you have made an election to distribute the
  36137. +File under one of the following license alternatives, please (i) delete this
  36138. +introductory statement regarding license alternatives, (ii) delete the two
  36139. +license alternatives that you have not elected to use and (iii) preserve the
  36140. +Marvell copyright notice above.
  36141. +
  36142. +********************************************************************************
  36143. +Marvell Commercial License Option
  36144. +
  36145. +If you received this File from Marvell and you have entered into a commercial
  36146. +license agreement (a "Commercial License") with Marvell, the File is licensed
  36147. +to you under the terms of the applicable Commercial License.
  36148. +
  36149. +********************************************************************************
  36150. +Marvell GPL License Option
  36151. +
  36152. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36153. +modify this File in accordance with the terms and conditions of the General
  36154. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  36155. +available along with the File in the license.txt file or by writing to the Free
  36156. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  36157. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  36158. +
  36159. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  36160. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  36161. +DISCLAIMED. The GPL License provides additional details about this warranty
  36162. +disclaimer.
  36163. +********************************************************************************
  36164. +Marvell BSD License Option
  36165. +
  36166. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36167. +modify this File under the following licensing terms.
  36168. +Redistribution and use in source and binary forms, with or without modification,
  36169. +are permitted provided that the following conditions are met:
  36170. +
  36171. + * Redistributions of source code must retain the above copyright notice,
  36172. + this list of conditions and the following disclaimer.
  36173. +
  36174. + * Redistributions in binary form must reproduce the above copyright
  36175. + notice, this list of conditions and the following disclaimer in the
  36176. + documentation and/or other materials provided with the distribution.
  36177. +
  36178. + * Neither the name of Marvell nor the names of its contributors may be
  36179. + used to endorse or promote products derived from this software without
  36180. + specific prior written permission.
  36181. +
  36182. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  36183. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  36184. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  36185. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  36186. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36187. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36188. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  36189. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36190. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36191. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36192. +
  36193. +*******************************************************************************/
  36194. +
  36195. +
  36196. +#ifndef __INCmvBoardEnvSpech
  36197. +#define __INCmvBoardEnvSpech
  36198. +
  36199. +#include "mvSysHwConfig.h"
  36200. +
  36201. +
  36202. +/* For future use */
  36203. +#define BD_ID_DATA_START_OFFS 0x0
  36204. +#define BD_DETECT_SEQ_OFFS 0x0
  36205. +#define BD_SYS_NUM_OFFS 0x4
  36206. +#define BD_NAME_OFFS 0x8
  36207. +
  36208. +/* I2C bus addresses */
  36209. +#define MV_BOARD_CTRL_I2C_ADDR 0x0 /* Controller slave addr */
  36210. +#define MV_BOARD_CTRL_I2C_ADDR_TYPE ADDR7_BIT
  36211. +#define MV_BOARD_DIMM0_I2C_ADDR 0x56
  36212. +#define MV_BOARD_DIMM0_I2C_ADDR_TYPE ADDR7_BIT
  36213. +#define MV_BOARD_DIMM1_I2C_ADDR 0x54
  36214. +#define MV_BOARD_DIMM1_I2C_ADDR_TYPE ADDR7_BIT
  36215. +#define MV_BOARD_EEPROM_I2C_ADDR 0x51
  36216. +#define MV_BOARD_EEPROM_I2C_ADDR_TYPE ADDR7_BIT
  36217. +#define MV_BOARD_MAIN_EEPROM_I2C_ADDR 0x50
  36218. +#define MV_BOARD_MAIN_EEPROM_I2C_ADDR_TYPE ADDR7_BIT
  36219. +#define MV_BOARD_MUX_I2C_ADDR_ENTRY 0x2
  36220. +#define MV_BOARD_DIMM_I2C_CHANNEL 0x0
  36221. +
  36222. +#define BOOT_FLASH_INDEX 0
  36223. +#define MAIN_FLASH_INDEX 1
  36224. +
  36225. +#define BOARD_ETH_START_PORT_NUM 0
  36226. +
  36227. +/* Supported clocks */
  36228. +#define MV_BOARD_TCLK_100MHZ 100000000
  36229. +#define MV_BOARD_TCLK_125MHZ 125000000
  36230. +#define MV_BOARD_TCLK_133MHZ 133333333
  36231. +#define MV_BOARD_TCLK_150MHZ 150000000
  36232. +#define MV_BOARD_TCLK_166MHZ 166666667
  36233. +#define MV_BOARD_TCLK_200MHZ 200000000
  36234. +
  36235. +#define MV_BOARD_SYSCLK_100MHZ 100000000
  36236. +#define MV_BOARD_SYSCLK_125MHZ 125000000
  36237. +#define MV_BOARD_SYSCLK_133MHZ 133333333
  36238. +#define MV_BOARD_SYSCLK_150MHZ 150000000
  36239. +#define MV_BOARD_SYSCLK_166MHZ 166666667
  36240. +#define MV_BOARD_SYSCLK_200MHZ 200000000
  36241. +#define MV_BOARD_SYSCLK_233MHZ 233333333
  36242. +#define MV_BOARD_SYSCLK_250MHZ 250000000
  36243. +#define MV_BOARD_SYSCLK_267MHZ 266666667
  36244. +#define MV_BOARD_SYSCLK_300MHZ 300000000
  36245. +#define MV_BOARD_SYSCLK_333MHZ 333333334
  36246. +#define MV_BOARD_SYSCLK_400MHZ 400000000
  36247. +
  36248. +#define MV_BOARD_REFCLK_25MHZ 25000000
  36249. +
  36250. +/* Board specific */
  36251. +/* =============================== */
  36252. +
  36253. +/* boards ID numbers */
  36254. +
  36255. +#define BOARD_ID_BASE 0x0
  36256. +
  36257. +/* New board ID numbers */
  36258. +#define DB_88F6281A_BP_ID (BOARD_ID_BASE)
  36259. +#define DB_88F6281_BP_MLL_ID 1680
  36260. +#define RD_88F6281A_ID (BOARD_ID_BASE+0x1)
  36261. +#define RD_88F6281_MLL_ID 1682
  36262. +#define DB_88F6192A_BP_ID (BOARD_ID_BASE+0x2)
  36263. +#define RD_88F6192A_ID (BOARD_ID_BASE+0x3)
  36264. +#define RD_88F6192_MLL_ID 1681
  36265. +#define DB_88F6180A_BP_ID (BOARD_ID_BASE+0x4)
  36266. +#define DB_88F6190A_BP_ID (BOARD_ID_BASE+0x5)
  36267. +#define RD_88F6190A_ID (BOARD_ID_BASE+0x6)
  36268. +#define RD_88F6281A_PCAC_ID (BOARD_ID_BASE+0x7)
  36269. +#define DB_CUSTOMER_ID (BOARD_ID_BASE+0x8)
  36270. +#define SHEEVA_PLUG_ID (BOARD_ID_BASE+0x9)
  36271. +#define MV_MAX_BOARD_ID (SHEEVA_PLUG_ID + 1)
  36272. +
  36273. +/* DB-88F6281A-BP */
  36274. +#if defined(MV_NAND)
  36275. + #define DB_88F6281A_MPP0_7 0x21111111
  36276. +#else
  36277. + #define DB_88F6281A_MPP0_7 0x21112220
  36278. +#endif
  36279. +#define DB_88F6281A_MPP8_15 0x11113311
  36280. +#define DB_88F6281A_MPP16_23 0x00551111
  36281. +#define DB_88F6281A_MPP24_31 0x00000000
  36282. +#define DB_88F6281A_MPP32_39 0x00000000
  36283. +#define DB_88F6281A_MPP40_47 0x00000000
  36284. +#define DB_88F6281A_MPP48_55 0x00000000
  36285. +#define DB_88F6281A_OE_LOW 0x0
  36286. +#if defined(MV_TDM_5CHANNELS)
  36287. + #define DB_88F6281A_OE_HIGH (BIT6)
  36288. +#else
  36289. +#define DB_88F6281A_OE_HIGH 0x0
  36290. +#endif
  36291. +#define DB_88F6281A_OE_VAL_LOW 0x0
  36292. +#define DB_88F6281A_OE_VAL_HIGH 0x0
  36293. +
  36294. +/* RD-88F6281A */
  36295. +#if defined(MV_NAND)
  36296. + #define RD_88F6281A_MPP0_7 0x21111111
  36297. +#else
  36298. + #define RD_88F6281A_MPP0_7 0x21112220
  36299. +#endif
  36300. +#define RD_88F6281A_MPP8_15 0x11113311
  36301. +#define RD_88F6281A_MPP16_23 0x33331111
  36302. +#define RD_88F6281A_MPP24_31 0x33003333
  36303. +#define RD_88F6281A_MPP32_39 0x20440533
  36304. +#define RD_88F6281A_MPP40_47 0x22202222
  36305. +#define RD_88F6281A_MPP48_55 0x00000002
  36306. +#define RD_88F6281A_OE_LOW (BIT28 | BIT29)
  36307. +#define RD_88F6281A_OE_HIGH (BIT3 | BIT6 | BIT17)
  36308. +#define RD_88F6281A_OE_VAL_LOW 0x0
  36309. +#define RD_88F6281A_OE_VAL_HIGH 0x0
  36310. +
  36311. +/* DB-88F6192A-BP */
  36312. +#if defined(MV_NAND)
  36313. + #define DB_88F6192A_MPP0_7 0x21111111
  36314. +#else
  36315. + #define DB_88F6192A_MPP0_7 0x21112220
  36316. +#endif
  36317. +#define DB_88F6192A_MPP8_15 0x11113311
  36318. +#define DB_88F6192A_MPP16_23 0x00501111
  36319. +#define DB_88F6192A_MPP24_31 0x00000000
  36320. +#define DB_88F6192A_MPP32_35 0x00000000
  36321. +#define DB_88F6192A_OE_LOW (BIT22 | BIT23)
  36322. +#define DB_88F6192A_OE_HIGH 0x0
  36323. +#define DB_88F6192A_OE_VAL_LOW 0x0
  36324. +#define DB_88F6192A_OE_VAL_HIGH 0x0
  36325. +
  36326. +/* RD-88F6192A */
  36327. +#define RD_88F6192A_MPP0_7 0x01222222
  36328. +#define RD_88F6192A_MPP8_15 0x00000011
  36329. +#define RD_88F6192A_MPP16_23 0x05550000
  36330. +#define RD_88F6192A_MPP24_31 0x0
  36331. +#define RD_88F6192A_MPP32_35 0x0
  36332. +#define RD_88F6192A_OE_LOW (BIT11 | BIT14 | BIT24 | BIT25 | BIT26 | BIT27 | BIT30 | BIT31)
  36333. +#define RD_88F6192A_OE_HIGH (BIT0 | BIT2)
  36334. +#define RD_88F6192A_OE_VAL_LOW 0x18400
  36335. +#define RD_88F6192A_OE_VAL_HIGH 0x8
  36336. +
  36337. +/* DB-88F6180A-BP */
  36338. +#if defined(MV_NAND)
  36339. + #define DB_88F6180A_MPP0_7 0x21111111
  36340. +#else
  36341. + #define DB_88F6180A_MPP0_7 0x01112222
  36342. +#endif
  36343. +#define DB_88F6180A_MPP8_15 0x11113311
  36344. +#define DB_88F6180A_MPP16_23 0x00001111
  36345. +#define DB_88F6180A_MPP24_31 0x0
  36346. +#define DB_88F6180A_MPP32_39 0x4444c000
  36347. +#define DB_88F6180A_MPP40_44 0x00044444
  36348. +#define DB_88F6180A_OE_LOW 0x0
  36349. +#define DB_88F6180A_OE_HIGH 0x0
  36350. +#define DB_88F6180A_OE_VAL_LOW 0x0
  36351. +#define DB_88F6180A_OE_VAL_HIGH 0x0
  36352. +
  36353. +/* RD-88F6281A_PCAC */
  36354. +#define RD_88F6281A_PCAC_MPP0_7 0x21111111
  36355. +#define RD_88F6281A_PCAC_MPP8_15 0x00003311
  36356. +#define RD_88F6281A_PCAC_MPP16_23 0x00001100
  36357. +#define RD_88F6281A_PCAC_MPP24_31 0x00000000
  36358. +#define RD_88F6281A_PCAC_MPP32_39 0x00000000
  36359. +#define RD_88F6281A_PCAC_MPP40_47 0x00000000
  36360. +#define RD_88F6281A_PCAC_MPP48_55 0x00000000
  36361. +#define RD_88F6281A_PCAC_OE_LOW 0x0
  36362. +#define RD_88F6281A_PCAC_OE_HIGH 0x0
  36363. +#define RD_88F6281A_PCAC_OE_VAL_LOW 0x0
  36364. +#define RD_88F6281A_PCAC_OE_VAL_HIGH 0x0
  36365. +
  36366. +/* SHEEVA PLUG */
  36367. +#define RD_SHEEVA_PLUG_MPP0_7 0x01111111
  36368. +#define RD_SHEEVA_PLUG_MPP8_15 0x11113322
  36369. +#define RD_SHEEVA_PLUG_MPP16_23 0x00001111
  36370. +#define RD_SHEEVA_PLUG_MPP24_31 0x00100000
  36371. +#define RD_SHEEVA_PLUG_MPP32_39 0x00000000
  36372. +#define RD_SHEEVA_PLUG_MPP40_47 0x00000000
  36373. +#define RD_SHEEVA_PLUG_MPP48_55 0x00000000
  36374. +#define RD_SHEEVA_PLUG_OE_LOW 0x0
  36375. +#define RD_SHEEVA_PLUG_OE_HIGH 0x0
  36376. +#define RD_SHEEVA_PLUG_OE_VAL_LOW (BIT29)
  36377. +#define RD_SHEEVA_PLUG_OE_VAL_HIGH ((~(BIT17 | BIT16 | BIT15)) | BIT14)
  36378. +
  36379. +/* DB-CUSTOMER */
  36380. +#define DB_CUSTOMER_MPP0_7 0x21111111
  36381. +#define DB_CUSTOMER_MPP8_15 0x00003311
  36382. +#define DB_CUSTOMER_MPP16_23 0x00001100
  36383. +#define DB_CUSTOMER_MPP24_31 0x00000000
  36384. +#define DB_CUSTOMER_MPP32_39 0x00000000
  36385. +#define DB_CUSTOMER_MPP40_47 0x00000000
  36386. +#define DB_CUSTOMER_MPP48_55 0x00000000
  36387. +#define DB_CUSTOMER_OE_LOW 0x0
  36388. +#define DB_CUSTOMER_OE_HIGH (~((BIT6) | (BIT7) | (BIT8) | (BIT9)))
  36389. +#define DB_CUSTOMER_OE_VAL_LOW 0x0
  36390. +#define DB_CUSTOMER_OE_VAL_HIGH 0x0
  36391. +
  36392. +#endif /* __INCmvBoardEnvSpech */
  36393. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c
  36394. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c 1970-01-01 01:00:00.000000000 +0100
  36395. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c 2011-07-31 11:31:56.573422903 +0200
  36396. @@ -0,0 +1,320 @@
  36397. +/*******************************************************************************
  36398. +Copyright (C) Marvell International Ltd. and its affiliates
  36399. +
  36400. +This software file (the "File") is owned and distributed by Marvell
  36401. +International Ltd. and/or its affiliates ("Marvell") under the following
  36402. +alternative licensing terms. Once you have made an election to distribute the
  36403. +File under one of the following license alternatives, please (i) delete this
  36404. +introductory statement regarding license alternatives, (ii) delete the two
  36405. +license alternatives that you have not elected to use and (iii) preserve the
  36406. +Marvell copyright notice above.
  36407. +
  36408. +********************************************************************************
  36409. +Marvell Commercial License Option
  36410. +
  36411. +If you received this File from Marvell and you have entered into a commercial
  36412. +license agreement (a "Commercial License") with Marvell, the File is licensed
  36413. +to you under the terms of the applicable Commercial License.
  36414. +
  36415. +********************************************************************************
  36416. +Marvell GPL License Option
  36417. +
  36418. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36419. +modify this File in accordance with the terms and conditions of the General
  36420. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  36421. +available along with the File in the license.txt file or by writing to the Free
  36422. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  36423. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  36424. +
  36425. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  36426. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  36427. +DISCLAIMED. The GPL License provides additional details about this warranty
  36428. +disclaimer.
  36429. +********************************************************************************
  36430. +Marvell BSD License Option
  36431. +
  36432. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36433. +modify this File under the following licensing terms.
  36434. +Redistribution and use in source and binary forms, with or without modification,
  36435. +are permitted provided that the following conditions are met:
  36436. +
  36437. + * Redistributions of source code must retain the above copyright notice,
  36438. + this list of conditions and the following disclaimer.
  36439. +
  36440. + * Redistributions in binary form must reproduce the above copyright
  36441. + notice, this list of conditions and the following disclaimer in the
  36442. + documentation and/or other materials provided with the distribution.
  36443. +
  36444. + * Neither the name of Marvell nor the names of its contributors may be
  36445. + used to endorse or promote products derived from this software without
  36446. + specific prior written permission.
  36447. +
  36448. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  36449. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  36450. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  36451. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  36452. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36453. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36454. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  36455. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36456. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36457. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36458. +
  36459. +*******************************************************************************/
  36460. +
  36461. +
  36462. +#include "cpu/mvCpu.h"
  36463. +#include "ctrlEnv/mvCtrlEnvLib.h"
  36464. +#include "ctrlEnv/mvCtrlEnvRegs.h"
  36465. +#include "ctrlEnv/sys/mvCpuIfRegs.h"
  36466. +
  36467. +/* defines */
  36468. +#ifdef MV_DEBUG
  36469. + #define DB(x) x
  36470. +#else
  36471. + #define DB(x)
  36472. +#endif
  36473. +
  36474. +/* locals */
  36475. +
  36476. +/*******************************************************************************
  36477. +* mvCpuPclkGet - Get the CPU pClk (pipe clock)
  36478. +*
  36479. +* DESCRIPTION:
  36480. +* This routine extract the CPU core clock.
  36481. +*
  36482. +* INPUT:
  36483. +* None.
  36484. +*
  36485. +* OUTPUT:
  36486. +* None.
  36487. +*
  36488. +* RETURN:
  36489. +* 32bit clock cycles in MHertz.
  36490. +*
  36491. +*******************************************************************************/
  36492. +/* 6180 have different clk reset sampling */
  36493. +
  36494. +static MV_U32 mvCpu6180PclkGet(MV_VOID)
  36495. +{
  36496. + MV_U32 tmpPClkRate=0;
  36497. + MV_CPU_ARM_CLK cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
  36498. +
  36499. + tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  36500. + tmpPClkRate = tmpPClkRate & MSAR_CPUCLCK_MASK_6180;
  36501. + tmpPClkRate = tmpPClkRate >> MSAR_CPUCLCK_OFFS_6180;
  36502. +
  36503. + tmpPClkRate = cpu6180_ddr_l2_CLK[tmpPClkRate].cpuClk;
  36504. +
  36505. + return tmpPClkRate;
  36506. +}
  36507. +
  36508. +
  36509. +MV_U32 mvCpuPclkGet(MV_VOID)
  36510. +{
  36511. +#if defined(PCLCK_AUTO_DETECT)
  36512. + MV_U32 tmpPClkRate=0;
  36513. + MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;
  36514. +
  36515. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  36516. + return mvCpu6180PclkGet();
  36517. +
  36518. + tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  36519. + tmpPClkRate = MSAR_CPUCLCK_EXTRACT(tmpPClkRate);
  36520. + tmpPClkRate = cpuCLK[tmpPClkRate];
  36521. +
  36522. + return tmpPClkRate;
  36523. +#else
  36524. + return MV_DEFAULT_PCLK
  36525. +#endif
  36526. +}
  36527. +
  36528. +/*******************************************************************************
  36529. +* mvCpuL2ClkGet - Get the CPU L2 (CPU bus clock)
  36530. +*
  36531. +* DESCRIPTION:
  36532. +* This routine extract the CPU L2 clock.
  36533. +*
  36534. +* RETURN:
  36535. +* 32bit clock cycles in Hertz.
  36536. +*
  36537. +*******************************************************************************/
  36538. +static MV_U32 mvCpu6180L2ClkGet(MV_VOID)
  36539. +{
  36540. + MV_U32 L2ClkRate=0;
  36541. + MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
  36542. +
  36543. + L2ClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  36544. + L2ClkRate = L2ClkRate & MSAR_CPUCLCK_MASK_6180;
  36545. + L2ClkRate = L2ClkRate >> MSAR_CPUCLCK_OFFS_6180;
  36546. +
  36547. + L2ClkRate = _cpu6180_ddr_l2_CLK[L2ClkRate].l2Clk;
  36548. +
  36549. + return L2ClkRate;
  36550. +
  36551. +}
  36552. +
  36553. +MV_U32 mvCpuL2ClkGet(MV_VOID)
  36554. +{
  36555. +#ifdef L2CLK_AUTO_DETECT
  36556. + MV_U32 L2ClkRate, tmp, pClkRate, indexL2Rtio;
  36557. + MV_U32 L2Rtio[][2] = MV_L2_CLCK_RTIO_TBL;
  36558. +
  36559. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  36560. + return mvCpu6180L2ClkGet();
  36561. +
  36562. + pClkRate = mvCpuPclkGet();
  36563. +
  36564. + tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  36565. + indexL2Rtio = MSAR_L2CLCK_EXTRACT(tmp);
  36566. +
  36567. + L2ClkRate = ((pClkRate * L2Rtio[indexL2Rtio][1]) / L2Rtio[indexL2Rtio][0]);
  36568. +
  36569. + return L2ClkRate;
  36570. +#else
  36571. + return MV_BOARD_DEFAULT_L2CLK;
  36572. +#endif
  36573. +}
  36574. +
  36575. +
  36576. +/*******************************************************************************
  36577. +* mvCpuNameGet - Get CPU name
  36578. +*
  36579. +* DESCRIPTION:
  36580. +* This function returns a string describing the CPU model and revision.
  36581. +*
  36582. +* INPUT:
  36583. +* None.
  36584. +*
  36585. +* OUTPUT:
  36586. +* pNameBuff - Buffer to contain board name string. Minimum size 32 chars.
  36587. +*
  36588. +* RETURN:
  36589. +* None.
  36590. +*******************************************************************************/
  36591. +MV_VOID mvCpuNameGet(char *pNameBuff)
  36592. +{
  36593. + MV_U32 cpuModel;
  36594. +
  36595. + cpuModel = mvOsCpuPartGet();
  36596. +
  36597. + /* The CPU module is indicated in the Processor Version Register (PVR) */
  36598. + switch(cpuModel)
  36599. + {
  36600. + case CPU_PART_MRVL131:
  36601. + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "Marvell Feroceon",mvOsCpuRevGet());
  36602. + break;
  36603. + case CPU_PART_ARM926:
  36604. + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM926",mvOsCpuRevGet());
  36605. + break;
  36606. + case CPU_PART_ARM946:
  36607. + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM946",mvOsCpuRevGet());
  36608. + break;
  36609. + default:
  36610. + mvOsSPrintf(pNameBuff,"??? (0x%04x) (Rev %d)",cpuModel,mvOsCpuRevGet());
  36611. + break;
  36612. + } /* switch */
  36613. +
  36614. + return;
  36615. +}
  36616. +
  36617. +
  36618. +#define MV_PROC_STR_SIZE 50
  36619. +
  36620. +static void mvCpuIfGetL2EccMode(MV_8 *buf)
  36621. +{
  36622. + MV_U32 regVal = MV_REG_READ(CPU_L2_CONFIG_REG);
  36623. + if (regVal & BIT2)
  36624. + mvOsSPrintf(buf, "L2 ECC Enabled");
  36625. + else
  36626. + mvOsSPrintf(buf, "L2 ECC Disabled");
  36627. +}
  36628. +
  36629. +static void mvCpuIfGetL2Mode(MV_8 *buf)
  36630. +{
  36631. + MV_U32 regVal = 0;
  36632. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  36633. + if (regVal & BIT22)
  36634. + mvOsSPrintf(buf, "L2 Enabled");
  36635. + else
  36636. + mvOsSPrintf(buf, "L2 Disabled");
  36637. +}
  36638. +
  36639. +static void mvCpuIfGetL2PrefetchMode(MV_8 *buf)
  36640. +{
  36641. + MV_U32 regVal = 0;
  36642. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  36643. + if (regVal & BIT24)
  36644. + mvOsSPrintf(buf, "L2 Prefetch Disabled");
  36645. + else
  36646. + mvOsSPrintf(buf, "L2 Prefetch Enabled");
  36647. +}
  36648. +
  36649. +static void mvCpuIfGetWriteAllocMode(MV_8 *buf)
  36650. +{
  36651. + MV_U32 regVal = 0;
  36652. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  36653. + if (regVal & BIT28)
  36654. + mvOsSPrintf(buf, "Write Allocate Enabled");
  36655. + else
  36656. + mvOsSPrintf(buf, "Write Allocate Disabled");
  36657. +}
  36658. +
  36659. +static void mvCpuIfGetCpuStreamMode(MV_8 *buf)
  36660. +{
  36661. + MV_U32 regVal = 0;
  36662. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  36663. + if (regVal & BIT29)
  36664. + mvOsSPrintf(buf, "CPU Streaming Enabled");
  36665. + else
  36666. + mvOsSPrintf(buf, "CPU Streaming Disabled");
  36667. +}
  36668. +
  36669. +static void mvCpuIfPrintCpuRegs(void)
  36670. +{
  36671. + MV_U32 regVal = 0;
  36672. +
  36673. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  36674. + mvOsPrintf("Extra Feature Reg = 0x%x\n",regVal);
  36675. +
  36676. + __asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (regVal)); /* Read Control register */
  36677. + mvOsPrintf("Control Reg = 0x%x\n",regVal);
  36678. +
  36679. + __asm volatile ("mrc p15, 0, %0, c0, c0, 0" : "=r" (regVal)); /* Read ID Code register */
  36680. + mvOsPrintf("ID Code Reg = 0x%x\n",regVal);
  36681. +
  36682. + __asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r" (regVal)); /* Read Cache Type register */
  36683. + mvOsPrintf("Cache Type Reg = 0x%x\n",regVal);
  36684. +
  36685. +}
  36686. +
  36687. +MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index)
  36688. +{
  36689. + MV_U32 count = 0;
  36690. +
  36691. + MV_8 L2_ECC_str[MV_PROC_STR_SIZE];
  36692. + MV_8 L2_En_str[MV_PROC_STR_SIZE];
  36693. + MV_8 L2_Prefetch_str[MV_PROC_STR_SIZE];
  36694. + MV_8 Write_Alloc_str[MV_PROC_STR_SIZE];
  36695. + MV_8 Cpu_Stream_str[MV_PROC_STR_SIZE];
  36696. +
  36697. + mvCpuIfGetL2Mode(L2_En_str);
  36698. + mvCpuIfGetL2EccMode(L2_ECC_str);
  36699. + mvCpuIfGetL2PrefetchMode(L2_Prefetch_str);
  36700. + mvCpuIfGetWriteAllocMode(Write_Alloc_str);
  36701. + mvCpuIfGetCpuStreamMode(Cpu_Stream_str);
  36702. + mvCpuIfPrintCpuRegs();
  36703. +
  36704. + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_En_str);
  36705. + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_ECC_str);
  36706. + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_Prefetch_str);
  36707. + count += mvOsSPrintf(buffer + count + index, "%s\n", Write_Alloc_str);
  36708. + count += mvOsSPrintf(buffer + count + index, "%s\n", Cpu_Stream_str);
  36709. + return count;
  36710. +}
  36711. +
  36712. +MV_U32 whoAmI(MV_VOID)
  36713. +{
  36714. + return 0;
  36715. +}
  36716. +
  36717. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h
  36718. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h 1970-01-01 01:00:00.000000000 +0100
  36719. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h 2011-07-31 11:31:56.633426997 +0200
  36720. @@ -0,0 +1,99 @@
  36721. +/*******************************************************************************
  36722. +Copyright (C) Marvell International Ltd. and its affiliates
  36723. +
  36724. +This software file (the "File") is owned and distributed by Marvell
  36725. +International Ltd. and/or its affiliates ("Marvell") under the following
  36726. +alternative licensing terms. Once you have made an election to distribute the
  36727. +File under one of the following license alternatives, please (i) delete this
  36728. +introductory statement regarding license alternatives, (ii) delete the two
  36729. +license alternatives that you have not elected to use and (iii) preserve the
  36730. +Marvell copyright notice above.
  36731. +
  36732. +********************************************************************************
  36733. +Marvell Commercial License Option
  36734. +
  36735. +If you received this File from Marvell and you have entered into a commercial
  36736. +license agreement (a "Commercial License") with Marvell, the File is licensed
  36737. +to you under the terms of the applicable Commercial License.
  36738. +
  36739. +********************************************************************************
  36740. +Marvell GPL License Option
  36741. +
  36742. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36743. +modify this File in accordance with the terms and conditions of the General
  36744. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  36745. +available along with the File in the license.txt file or by writing to the Free
  36746. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  36747. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  36748. +
  36749. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  36750. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  36751. +DISCLAIMED. The GPL License provides additional details about this warranty
  36752. +disclaimer.
  36753. +********************************************************************************
  36754. +Marvell BSD License Option
  36755. +
  36756. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36757. +modify this File under the following licensing terms.
  36758. +Redistribution and use in source and binary forms, with or without modification,
  36759. +are permitted provided that the following conditions are met:
  36760. +
  36761. + * Redistributions of source code must retain the above copyright notice,
  36762. + this list of conditions and the following disclaimer.
  36763. +
  36764. + * Redistributions in binary form must reproduce the above copyright
  36765. + notice, this list of conditions and the following disclaimer in the
  36766. + documentation and/or other materials provided with the distribution.
  36767. +
  36768. + * Neither the name of Marvell nor the names of its contributors may be
  36769. + used to endorse or promote products derived from this software without
  36770. + specific prior written permission.
  36771. +
  36772. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  36773. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  36774. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  36775. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  36776. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36777. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36778. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  36779. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36780. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36781. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36782. +
  36783. +*******************************************************************************/
  36784. +
  36785. +
  36786. +#ifndef __INCmvCpuh
  36787. +#define __INCmvCpuh
  36788. +
  36789. +#include "mvCommon.h"
  36790. +#include "mvOs.h"
  36791. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  36792. +
  36793. +/* defines */
  36794. +#define CPU_PART_MRVL131 0x131
  36795. +#define CPU_PART_ARM926 0x926
  36796. +#define CPU_PART_ARM946 0x946
  36797. +#define MV_CPU_ARM_CLK_ELM_SIZE 12
  36798. +#define MV_CPU_ARM_CLK_RATIO_OFF 8
  36799. +#define MV_CPU_ARM_CLK_DDR_OFF 4
  36800. +
  36801. +#ifndef MV_ASMLANGUAGE
  36802. +typedef struct _mvCpuArmClk
  36803. +{
  36804. + MV_U32 cpuClk; /* CPU clock in MHz */
  36805. + MV_U32 ddrClk; /* DDR clock in MHz */
  36806. + MV_U32 l2Clk; /* CPU DDR clock ratio */
  36807. +
  36808. +}MV_CPU_ARM_CLK;
  36809. +
  36810. +MV_U32 mvCpuPclkGet(MV_VOID);
  36811. +MV_VOID mvCpuNameGet(char *pNameBuff);
  36812. +MV_U32 mvCpuL2ClkGet(MV_VOID);
  36813. +MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index);
  36814. +MV_U32 whoAmI(MV_VOID);
  36815. +
  36816. +#endif /* MV_ASMLANGUAGE */
  36817. +
  36818. +
  36819. +#endif /* __INCmvCpuh */
  36820. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c
  36821. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c 1970-01-01 01:00:00.000000000 +0100
  36822. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c 2011-07-31 11:31:56.697175341 +0200
  36823. @@ -0,0 +1,296 @@
  36824. +/*******************************************************************************
  36825. +Copyright (C) Marvell International Ltd. and its affiliates
  36826. +
  36827. +This software file (the "File") is owned and distributed by Marvell
  36828. +International Ltd. and/or its affiliates ("Marvell") under the following
  36829. +alternative licensing terms. Once you have made an election to distribute the
  36830. +File under one of the following license alternatives, please (i) delete this
  36831. +introductory statement regarding license alternatives, (ii) delete the two
  36832. +license alternatives that you have not elected to use and (iii) preserve the
  36833. +Marvell copyright notice above.
  36834. +
  36835. +********************************************************************************
  36836. +Marvell Commercial License Option
  36837. +
  36838. +If you received this File from Marvell and you have entered into a commercial
  36839. +license agreement (a "Commercial License") with Marvell, the File is licensed
  36840. +to you under the terms of the applicable Commercial License.
  36841. +
  36842. +********************************************************************************
  36843. +Marvell GPL License Option
  36844. +
  36845. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36846. +modify this File in accordance with the terms and conditions of the General
  36847. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  36848. +available along with the File in the license.txt file or by writing to the Free
  36849. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  36850. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  36851. +
  36852. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  36853. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  36854. +DISCLAIMED. The GPL License provides additional details about this warranty
  36855. +disclaimer.
  36856. +********************************************************************************
  36857. +Marvell BSD License Option
  36858. +
  36859. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36860. +modify this File under the following licensing terms.
  36861. +Redistribution and use in source and binary forms, with or without modification,
  36862. +are permitted provided that the following conditions are met:
  36863. +
  36864. + * Redistributions of source code must retain the above copyright notice,
  36865. + this list of conditions and the following disclaimer.
  36866. +
  36867. + * Redistributions in binary form must reproduce the above copyright
  36868. + notice, this list of conditions and the following disclaimer in the
  36869. + documentation and/or other materials provided with the distribution.
  36870. +
  36871. + * Neither the name of Marvell nor the names of its contributors may be
  36872. + used to endorse or promote products derived from this software without
  36873. + specific prior written permission.
  36874. +
  36875. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  36876. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  36877. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  36878. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  36879. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36880. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36881. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  36882. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36883. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36884. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36885. +
  36886. +*******************************************************************************/
  36887. +
  36888. +/*******************************************************************************
  36889. +* mvCtrlEnvAddrDec.h - Marvell controller address decode library
  36890. +*
  36891. +* DESCRIPTION:
  36892. +*
  36893. +* DEPENDENCIES:
  36894. +* None.
  36895. +*
  36896. +*******************************************************************************/
  36897. +
  36898. +/* includes */
  36899. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  36900. +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
  36901. +#include "ddr2/mvDramIfRegs.h"
  36902. +#include "pex/mvPexRegs.h"
  36903. +
  36904. +#define MV_DEBUG
  36905. +
  36906. +/* defines */
  36907. +#ifdef MV_DEBUG
  36908. + #define DB(x) x
  36909. +#else
  36910. + #define DB(x)
  36911. +#endif
  36912. +
  36913. +/* Default Attributes array */
  36914. +MV_TARGET_ATTRIB mvTargetDefaultsArray[] = TARGETS_DEF_ARRAY;
  36915. +extern MV_TARGET *sampleAtResetTargetArray;
  36916. +/* Dram\AHBToMbus\PEX share regsiter */
  36917. +
  36918. +#define CTRL_DEC_BASE_OFFS 16
  36919. +#define CTRL_DEC_BASE_MASK (0xffff << CTRL_DEC_BASE_OFFS)
  36920. +#define CTRL_DEC_BASE_ALIGNMENT 0x10000
  36921. +
  36922. +#define CTRL_DEC_SIZE_OFFS 16
  36923. +#define CTRL_DEC_SIZE_MASK (0xffff << CTRL_DEC_SIZE_OFFS)
  36924. +#define CTRL_DEC_SIZE_ALIGNMENT 0x10000
  36925. +
  36926. +#define CTRL_DEC_WIN_EN BIT0
  36927. +
  36928. +
  36929. +
  36930. +/*******************************************************************************
  36931. +* mvCtrlAddrDecToReg - Get address decode register format values
  36932. +*
  36933. +* DESCRIPTION:
  36934. +*
  36935. +* INPUT:
  36936. +*
  36937. +* OUTPUT:
  36938. +*
  36939. +* RETURN:
  36940. +*
  36941. +*******************************************************************************/
  36942. +MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin, MV_DEC_REGS *pAddrDecRegs)
  36943. +{
  36944. +
  36945. + MV_U32 baseToReg=0 , sizeToReg=0;
  36946. +
  36947. + /* BaseLow[31:16] => base register [31:16] */
  36948. + baseToReg = pAddrDecWin->baseLow & CTRL_DEC_BASE_MASK;
  36949. +
  36950. + /* Write to address decode Base Address Register */
  36951. + pAddrDecRegs->baseReg &= ~CTRL_DEC_BASE_MASK;
  36952. + pAddrDecRegs->baseReg |= baseToReg;
  36953. +
  36954. + /* Get size register value according to window size */
  36955. + sizeToReg = ctrlSizeToReg(pAddrDecWin->size, CTRL_DEC_SIZE_ALIGNMENT);
  36956. +
  36957. + /* Size parameter validity check. */
  36958. + if (-1 == sizeToReg)
  36959. + {
  36960. + return MV_BAD_PARAM;
  36961. + }
  36962. +
  36963. + /* set size */
  36964. + pAddrDecRegs->sizeReg &= ~CTRL_DEC_SIZE_MASK;
  36965. + pAddrDecRegs->sizeReg |= (sizeToReg << CTRL_DEC_SIZE_OFFS);
  36966. +
  36967. +
  36968. + return MV_OK;
  36969. +
  36970. +}
  36971. +
  36972. +/*******************************************************************************
  36973. +* mvCtrlRegToAddrDec - Extract address decode struct from registers.
  36974. +*
  36975. +* DESCRIPTION:
  36976. +* This function extract address decode struct from address decode
  36977. +* registers given as parameters.
  36978. +*
  36979. +* INPUT:
  36980. +* pAddrDecRegs - Address decode register struct.
  36981. +*
  36982. +* OUTPUT:
  36983. +* pAddrDecWin - Target window data structure.
  36984. +*
  36985. +* RETURN:
  36986. +* MV_BAD_PARAM if address decode registers data is invalid.
  36987. +*
  36988. +*******************************************************************************/
  36989. +MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs, MV_ADDR_WIN *pAddrDecWin)
  36990. +{
  36991. + MV_U32 sizeRegVal;
  36992. +
  36993. + sizeRegVal = (pAddrDecRegs->sizeReg & CTRL_DEC_SIZE_MASK) >>
  36994. + CTRL_DEC_SIZE_OFFS;
  36995. +
  36996. + pAddrDecWin->size = ctrlRegToSize(sizeRegVal, CTRL_DEC_SIZE_ALIGNMENT);
  36997. +
  36998. +
  36999. + /* Extract base address */
  37000. + /* Base register [31:16] ==> baseLow[31:16] */
  37001. + pAddrDecWin->baseLow = pAddrDecRegs->baseReg & CTRL_DEC_BASE_MASK;
  37002. +
  37003. + pAddrDecWin->baseHigh = 0;
  37004. +
  37005. + return MV_OK;
  37006. +
  37007. +}
  37008. +
  37009. +/*******************************************************************************
  37010. +* mvCtrlAttribGet -
  37011. +*
  37012. +* DESCRIPTION:
  37013. +*
  37014. +* INPUT:
  37015. +*
  37016. +* OUTPUT:
  37017. +*
  37018. +* RETURN:
  37019. +*
  37020. +*******************************************************************************/
  37021. +
  37022. +MV_STATUS mvCtrlAttribGet(MV_TARGET target,
  37023. + MV_TARGET_ATTRIB *targetAttrib)
  37024. +{
  37025. +
  37026. + targetAttrib->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].attrib;
  37027. + targetAttrib->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId;
  37028. +
  37029. + return MV_OK;
  37030. +
  37031. +}
  37032. +
  37033. +/*******************************************************************************
  37034. +* mvCtrlGetAttrib -
  37035. +*
  37036. +* DESCRIPTION:
  37037. +*
  37038. +* INPUT:
  37039. +*
  37040. +* OUTPUT:
  37041. +*
  37042. +* RETURN:
  37043. +*
  37044. +*******************************************************************************/
  37045. +MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib)
  37046. +{
  37047. + MV_TARGET target;
  37048. + MV_TARGET x;
  37049. + for (target = SDRAM_CS0; target < MAX_TARGETS ; target ++)
  37050. + {
  37051. + x = MV_CHANGE_BOOT_CS(target);
  37052. + if ((mvTargetDefaultsArray[x].attrib == targetAttrib->attrib) &&
  37053. + (mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId == targetAttrib->targetId))
  37054. + {
  37055. + /* found it */
  37056. + break;
  37057. + }
  37058. + }
  37059. +
  37060. + return target;
  37061. +}
  37062. +
  37063. +MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin,
  37064. + MV_DEC_WIN_PARAMS *pWinParam)
  37065. +{
  37066. + MV_U32 baseToReg=0, sizeToReg=0;
  37067. +
  37068. + /* BaseLow[31:16] => base register [31:16] */
  37069. + baseToReg = pAddrDecWin->addrWin.baseLow & CTRL_DEC_BASE_MASK;
  37070. +
  37071. + /* Write to address decode Base Address Register */
  37072. + pWinParam->baseAddr &= ~CTRL_DEC_BASE_MASK;
  37073. + pWinParam->baseAddr |= baseToReg;
  37074. +
  37075. + /* Get size register value according to window size */
  37076. + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, CTRL_DEC_SIZE_ALIGNMENT);
  37077. +
  37078. + /* Size parameter validity check. */
  37079. + if (-1 == sizeToReg)
  37080. + {
  37081. + mvOsPrintf("mvCtrlAddrDecToParams: ERR. ctrlSizeToReg failed.\n");
  37082. + return MV_BAD_PARAM;
  37083. + }
  37084. + pWinParam->size = sizeToReg;
  37085. +
  37086. + pWinParam->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].attrib;
  37087. + pWinParam->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].targetId;
  37088. +
  37089. + return MV_OK;
  37090. +}
  37091. +
  37092. +MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam,
  37093. + MV_DEC_WIN *pAddrDecWin)
  37094. +{
  37095. + MV_TARGET_ATTRIB targetAttrib;
  37096. +
  37097. + pAddrDecWin->addrWin.baseLow = pWinParam->baseAddr;
  37098. +
  37099. + /* Upper 32bit address base is supported under PCI High Address remap */
  37100. + pAddrDecWin->addrWin.baseHigh = 0;
  37101. +
  37102. + /* Prepare sizeReg to ctrlRegToSize function */
  37103. + pAddrDecWin->addrWin.size = ctrlRegToSize(pWinParam->size, CTRL_DEC_SIZE_ALIGNMENT);
  37104. +
  37105. + if (-1 == pAddrDecWin->addrWin.size)
  37106. + {
  37107. + DB(mvOsPrintf("mvCtrlParamsToAddrDec: ERR. ctrlRegToSize failed.\n"));
  37108. + return MV_BAD_PARAM;
  37109. + }
  37110. + targetAttrib.targetId = pWinParam->targetId;
  37111. + targetAttrib.attrib = pWinParam->attrib;
  37112. +
  37113. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  37114. +
  37115. + return MV_OK;
  37116. +}
  37117. +
  37118. +
  37119. +
  37120. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h
  37121. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h 1970-01-01 01:00:00.000000000 +0100
  37122. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h 2011-07-31 11:31:56.763415440 +0200
  37123. @@ -0,0 +1,203 @@
  37124. +/*******************************************************************************
  37125. +Copyright (C) Marvell International Ltd. and its affiliates
  37126. +
  37127. +This software file (the "File") is owned and distributed by Marvell
  37128. +International Ltd. and/or its affiliates ("Marvell") under the following
  37129. +alternative licensing terms. Once you have made an election to distribute the
  37130. +File under one of the following license alternatives, please (i) delete this
  37131. +introductory statement regarding license alternatives, (ii) delete the two
  37132. +license alternatives that you have not elected to use and (iii) preserve the
  37133. +Marvell copyright notice above.
  37134. +
  37135. +********************************************************************************
  37136. +Marvell Commercial License Option
  37137. +
  37138. +If you received this File from Marvell and you have entered into a commercial
  37139. +license agreement (a "Commercial License") with Marvell, the File is licensed
  37140. +to you under the terms of the applicable Commercial License.
  37141. +
  37142. +********************************************************************************
  37143. +Marvell GPL License Option
  37144. +
  37145. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37146. +modify this File in accordance with the terms and conditions of the General
  37147. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  37148. +available along with the File in the license.txt file or by writing to the Free
  37149. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  37150. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  37151. +
  37152. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  37153. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  37154. +DISCLAIMED. The GPL License provides additional details about this warranty
  37155. +disclaimer.
  37156. +********************************************************************************
  37157. +Marvell BSD License Option
  37158. +
  37159. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37160. +modify this File under the following licensing terms.
  37161. +Redistribution and use in source and binary forms, with or without modification,
  37162. +are permitted provided that the following conditions are met:
  37163. +
  37164. + * Redistributions of source code must retain the above copyright notice,
  37165. + this list of conditions and the following disclaimer.
  37166. +
  37167. + * Redistributions in binary form must reproduce the above copyright
  37168. + notice, this list of conditions and the following disclaimer in the
  37169. + documentation and/or other materials provided with the distribution.
  37170. +
  37171. + * Neither the name of Marvell nor the names of its contributors may be
  37172. + used to endorse or promote products derived from this software without
  37173. + specific prior written permission.
  37174. +
  37175. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  37176. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  37177. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  37178. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  37179. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  37180. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37181. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  37182. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  37183. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37184. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37185. +
  37186. +*******************************************************************************/
  37187. +
  37188. +
  37189. +#ifndef __INCmvCtrlEnvAddrDech
  37190. +#define __INCmvCtrlEnvAddrDech
  37191. +
  37192. +/* includes */
  37193. +#include "ctrlEnv/mvCtrlEnvLib.h"
  37194. +#include "ctrlEnv/mvCtrlEnvRegs.h"
  37195. +
  37196. +
  37197. +/* defines */
  37198. +/* DUnit attributes */
  37199. +#define ATMWCR_WIN_DUNIT_CS0_OFFS 0
  37200. +#define ATMWCR_WIN_DUNIT_CS0_MASK BIT0
  37201. +#define ATMWCR_WIN_DUNIT_CS0_REQ (0 << ATMWCR_WIN_DUNIT_CS0_OFFS)
  37202. +
  37203. +#define ATMWCR_WIN_DUNIT_CS1_OFFS 1
  37204. +#define ATMWCR_WIN_DUNIT_CS1_MASK BIT1
  37205. +#define ATMWCR_WIN_DUNIT_CS1_REQ (0 << ATMWCR_WIN_DUNIT_CS1_OFFS)
  37206. +
  37207. +#define ATMWCR_WIN_DUNIT_CS2_OFFS 2
  37208. +#define ATMWCR_WIN_DUNIT_CS2_MASK BIT2
  37209. +#define ATMWCR_WIN_DUNIT_CS2_REQ (0 << ATMWCR_WIN_DUNIT_CS2_OFFS)
  37210. +
  37211. +#define ATMWCR_WIN_DUNIT_CS3_OFFS 3
  37212. +#define ATMWCR_WIN_DUNIT_CS3_MASK BIT3
  37213. +#define ATMWCR_WIN_DUNIT_CS3_REQ (0 << ATMWCR_WIN_DUNIT_CS3_OFFS)
  37214. +
  37215. +/* RUnit (Device) attributes */
  37216. +#define ATMWCR_WIN_RUNIT_DEVCS0_OFFS 0
  37217. +#define ATMWCR_WIN_RUNIT_DEVCS0_MASK BIT0
  37218. +#define ATMWCR_WIN_RUNIT_DEVCS0_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS0_OFFS)
  37219. +
  37220. +#define ATMWCR_WIN_RUNIT_DEVCS1_OFFS 1
  37221. +#define ATMWCR_WIN_RUNIT_DEVCS1_MASK BIT1
  37222. +#define ATMWCR_WIN_RUNIT_DEVCS1_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS1_OFFS)
  37223. +
  37224. +#define ATMWCR_WIN_RUNIT_DEVCS2_OFFS 2
  37225. +#define ATMWCR_WIN_RUNIT_DEVCS2_MASK BIT2
  37226. +#define ATMWCR_WIN_RUNIT_DEVCS2_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS2_OFFS)
  37227. +
  37228. +#define ATMWCR_WIN_RUNIT_BOOTCS_OFFS 4
  37229. +#define ATMWCR_WIN_RUNIT_BOOTCS_MASK BIT4
  37230. +#define ATMWCR_WIN_RUNIT_BOOTCS_REQ (0 << ATMWCR_WIN_RUNIT_BOOTCS_OFFS)
  37231. +
  37232. +/* LMaster (PCI) attributes */
  37233. +#define ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS 0
  37234. +#define ATMWCR_WIN_LUNIT_BYTE_SWP_MASK BIT0
  37235. +#define ATMWCR_WIN_LUNIT_BYTE_SWP (0 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)
  37236. +#define ATMWCR_WIN_LUNIT_BYTE_NO_SWP (1 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)
  37237. +
  37238. +
  37239. +#define ATMWCR_WIN_LUNIT_WORD_SWP_OFFS 1
  37240. +#define ATMWCR_WIN_LUNIT_WORD_SWP_MASK BIT1
  37241. +#define ATMWCR_WIN_LUNIT_WORD_SWP (0 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)
  37242. +#define ATMWCR_WIN_LUNIT_WORD_NO_SWP (1 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)
  37243. +
  37244. +#define ATMWCR_WIN_LUNIT_NO_SNOOP BIT2
  37245. +
  37246. +#define ATMWCR_WIN_LUNIT_TYPE_OFFS 3
  37247. +#define ATMWCR_WIN_LUNIT_TYPE_MASK BIT3
  37248. +#define ATMWCR_WIN_LUNIT_TYPE_IO (0 << ATMWCR_WIN_LUNIT_TYPE_OFFS)
  37249. +#define ATMWCR_WIN_LUNIT_TYPE_MEM (1 << ATMWCR_WIN_LUNIT_TYPE_OFFS)
  37250. +
  37251. +#define ATMWCR_WIN_LUNIT_FORCE64_OFFS 4
  37252. +#define ATMWCR_WIN_LUNIT_FORCE64_MASK BIT4
  37253. +#define ATMWCR_WIN_LUNIT_FORCE64 (0 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)
  37254. +
  37255. +#define ATMWCR_WIN_LUNIT_ORDERING_OFFS 6
  37256. +#define ATMWCR_WIN_LUNIT_ORDERING_MASK BIT6
  37257. +#define ATMWCR_WIN_LUNIT_ORDERING (1 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)
  37258. +
  37259. +/* PEX Attributes */
  37260. +#define ATMWCR_WIN_PEX_TYPE_OFFS 3
  37261. +#define ATMWCR_WIN_PEX_TYPE_MASK BIT3
  37262. +#define ATMWCR_WIN_PEX_TYPE_IO (0 << ATMWCR_WIN_PEX_TYPE_OFFS)
  37263. +#define ATMWCR_WIN_PEX_TYPE_MEM (1 << ATMWCR_WIN_PEX_TYPE_OFFS)
  37264. +
  37265. +/* typedefs */
  37266. +
  37267. +/* Unsupported attributes for address decode: */
  37268. +/* 2) PCI0/1_REQ64n control */
  37269. +
  37270. +typedef struct _mvDecRegs
  37271. +{
  37272. + MV_U32 baseReg;
  37273. + MV_U32 baseRegHigh;
  37274. + MV_U32 sizeReg;
  37275. +
  37276. +}MV_DEC_REGS;
  37277. +
  37278. +typedef struct _mvTargetAttrib
  37279. +{
  37280. + MV_U8 attrib; /* chip select attributes */
  37281. + MV_TARGET_ID targetId; /* Target Id of this MV_TARGET */
  37282. +
  37283. +}MV_TARGET_ATTRIB;
  37284. +
  37285. +
  37286. +/* This structure describes address decode window */
  37287. +typedef struct _mvDecWin
  37288. +{
  37289. + MV_TARGET target; /* Target for addr decode window */
  37290. + MV_ADDR_WIN addrWin; /* Address window of target */
  37291. + MV_BOOL enable; /* Window enable/disable */
  37292. +}MV_DEC_WIN;
  37293. +
  37294. +typedef struct _mvDecWinParams
  37295. +{
  37296. + MV_TARGET_ID targetId; /* Target ID field */
  37297. + MV_U8 attrib; /* Attribute field */
  37298. + MV_U32 baseAddr; /* Base address in register format */
  37299. + MV_U32 size; /* Size in register format */
  37300. +}MV_DEC_WIN_PARAMS;
  37301. +
  37302. +
  37303. +/* mvCtrlEnvAddrDec API list */
  37304. +
  37305. +MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin,
  37306. + MV_DEC_REGS *pAddrDecRegs);
  37307. +
  37308. +MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs,
  37309. + MV_ADDR_WIN *pAddrDecWin);
  37310. +
  37311. +MV_STATUS mvCtrlAttribGet(MV_TARGET target,
  37312. + MV_TARGET_ATTRIB *targetAttrib);
  37313. +
  37314. +MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib);
  37315. +
  37316. +
  37317. +MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin,
  37318. + MV_DEC_WIN_PARAMS *pWinParam);
  37319. +
  37320. +MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam,
  37321. + MV_DEC_WIN *pAddrDecWin);
  37322. +
  37323. +
  37324. +
  37325. +
  37326. +#endif /* __INCmvCtrlEnvAddrDech */
  37327. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h
  37328. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h 1970-01-01 01:00:00.000000000 +0100
  37329. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h 2011-07-31 11:31:56.813498621 +0200
  37330. @@ -0,0 +1,98 @@
  37331. +/*******************************************************************************
  37332. +Copyright (C) Marvell International Ltd. and its affiliates
  37333. +
  37334. +This software file (the "File") is owned and distributed by Marvell
  37335. +International Ltd. and/or its affiliates ("Marvell") under the following
  37336. +alternative licensing terms. Once you have made an election to distribute the
  37337. +File under one of the following license alternatives, please (i) delete this
  37338. +introductory statement regarding license alternatives, (ii) delete the two
  37339. +license alternatives that you have not elected to use and (iii) preserve the
  37340. +Marvell copyright notice above.
  37341. +
  37342. +********************************************************************************
  37343. +Marvell Commercial License Option
  37344. +
  37345. +If you received this File from Marvell and you have entered into a commercial
  37346. +license agreement (a "Commercial License") with Marvell, the File is licensed
  37347. +to you under the terms of the applicable Commercial License.
  37348. +
  37349. +********************************************************************************
  37350. +Marvell GPL License Option
  37351. +
  37352. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37353. +modify this File in accordance with the terms and conditions of the General
  37354. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  37355. +available along with the File in the license.txt file or by writing to the Free
  37356. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  37357. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  37358. +
  37359. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  37360. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  37361. +DISCLAIMED. The GPL License provides additional details about this warranty
  37362. +disclaimer.
  37363. +********************************************************************************
  37364. +Marvell BSD License Option
  37365. +
  37366. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37367. +modify this File under the following licensing terms.
  37368. +Redistribution and use in source and binary forms, with or without modification,
  37369. +are permitted provided that the following conditions are met:
  37370. +
  37371. + * Redistributions of source code must retain the above copyright notice,
  37372. + this list of conditions and the following disclaimer.
  37373. +
  37374. + * Redistributions in binary form must reproduce the above copyright
  37375. + notice, this list of conditions and the following disclaimer in the
  37376. + documentation and/or other materials provided with the distribution.
  37377. +
  37378. + * Neither the name of Marvell nor the names of its contributors may be
  37379. + used to endorse or promote products derived from this software without
  37380. + specific prior written permission.
  37381. +
  37382. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  37383. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  37384. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  37385. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  37386. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  37387. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37388. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  37389. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  37390. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37391. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37392. +
  37393. +*******************************************************************************/
  37394. +
  37395. +
  37396. +#ifndef __INCmvCtrlEnvAsmh
  37397. +#define __INCmvCtrlEnvAsmh
  37398. +#include "pex/mvPexRegs.h"
  37399. +
  37400. +#define CHIP_BOND_REG 0x10034
  37401. +#define PCKG_OPT_MASK_AS #3
  37402. +#define PXCCARI_REVID_MASK_AS #PXCCARI_REVID_MASK
  37403. +
  37404. +/* Read device ID into toReg bits 15:0 from 0xd0000000 */
  37405. +/* defines */
  37406. +#define MV_DV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \
  37407. + MV_DV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\
  37408. + and toReg, toReg, PCKG_OPT_MASK_AS /* Mask for package ID */
  37409. +
  37410. +/* Read device ID into toReg bits 15:0 from 0xf1000000*/
  37411. +#define MV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \
  37412. + MV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\
  37413. + and toReg, toReg, PCKG_OPT_MASK_AS /* Mask for package ID */
  37414. +
  37415. +/* Read Revision into toReg bits 7:0 0xd0000000*/
  37416. +#define MV_DV_CTRL_REV_GET_ASM(toReg, tmpReg) \
  37417. + /* Read device revision */ \
  37418. + MV_DV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\
  37419. + and toReg, toReg, PXCCARI_REVID_MASK_AS /* Mask for calss ID */
  37420. +
  37421. +/* Read Revision into toReg bits 7:0 0xf1000000*/
  37422. +#define MV_CTRL_REV_GET_ASM(toReg, tmpReg) \
  37423. + /* Read device revision */ \
  37424. + MV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\
  37425. + and toReg, toReg, PXCCARI_REVID_MASK_AS /* Mask for calss ID */
  37426. +
  37427. +
  37428. +#endif /* __INCmvCtrlEnvAsmh */
  37429. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c
  37430. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c 1970-01-01 01:00:00.000000000 +0100
  37431. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c 2011-07-31 11:31:56.873923660 +0200
  37432. @@ -0,0 +1,1825 @@
  37433. +/*******************************************************************************
  37434. +Copyright (C) Marvell International Ltd. and its affiliates
  37435. +
  37436. +This software file (the "File") is owned and distributed by Marvell
  37437. +International Ltd. and/or its affiliates ("Marvell") under the following
  37438. +alternative licensing terms. Once you have made an election to distribute the
  37439. +File under one of the following license alternatives, please (i) delete this
  37440. +introductory statement regarding license alternatives, (ii) delete the two
  37441. +license alternatives that you have not elected to use and (iii) preserve the
  37442. +Marvell copyright notice above.
  37443. +
  37444. +********************************************************************************
  37445. +Marvell Commercial License Option
  37446. +
  37447. +If you received this File from Marvell and you have entered into a commercial
  37448. +license agreement (a "Commercial License") with Marvell, the File is licensed
  37449. +to you under the terms of the applicable Commercial License.
  37450. +
  37451. +********************************************************************************
  37452. +Marvell GPL License Option
  37453. +
  37454. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37455. +modify this File in accordance with the terms and conditions of the General
  37456. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  37457. +available along with the File in the license.txt file or by writing to the Free
  37458. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  37459. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  37460. +
  37461. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  37462. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  37463. +DISCLAIMED. The GPL License provides additional details about this warranty
  37464. +disclaimer.
  37465. +********************************************************************************
  37466. +Marvell BSD License Option
  37467. +
  37468. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37469. +modify this File under the following licensing terms.
  37470. +Redistribution and use in source and binary forms, with or without modification,
  37471. +are permitted provided that the following conditions are met:
  37472. +
  37473. + * Redistributions of source code must retain the above copyright notice,
  37474. + this list of conditions and the following disclaimer.
  37475. +
  37476. + * Redistributions in binary form must reproduce the above copyright
  37477. + notice, this list of conditions and the following disclaimer in the
  37478. + documentation and/or other materials provided with the distribution.
  37479. +
  37480. + * Neither the name of Marvell nor the names of its contributors may be
  37481. + used to endorse or promote products derived from this software without
  37482. + specific prior written permission.
  37483. +
  37484. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  37485. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  37486. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  37487. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  37488. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  37489. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37490. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  37491. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  37492. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37493. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37494. +
  37495. +*******************************************************************************/
  37496. +
  37497. +
  37498. +/* includes */
  37499. +#include "mvCommon.h"
  37500. +#include "mvCtrlEnvLib.h"
  37501. +#include "ctrlEnv/sys/mvCpuIf.h"
  37502. +
  37503. +#if defined(MV_INCLUDE_PEX)
  37504. +#include "pex/mvPex.h"
  37505. +#include "ctrlEnv/sys/mvSysPex.h"
  37506. +#endif
  37507. +
  37508. +#if defined(MV_INCLUDE_GIG_ETH)
  37509. +#include "ctrlEnv/sys/mvSysGbe.h"
  37510. +#endif
  37511. +
  37512. +#if defined(MV_INCLUDE_XOR)
  37513. +#include "ctrlEnv/sys/mvSysXor.h"
  37514. +#endif
  37515. +
  37516. +#if defined(MV_INCLUDE_SATA)
  37517. +#include "ctrlEnv/sys/mvSysSata.h"
  37518. +#endif
  37519. +
  37520. +#if defined(MV_INCLUDE_USB)
  37521. +#include "ctrlEnv/sys/mvSysUsb.h"
  37522. +#endif
  37523. +
  37524. +#if defined(MV_INCLUDE_AUDIO)
  37525. +#include "ctrlEnv/sys/mvSysAudio.h"
  37526. +#endif
  37527. +
  37528. +#if defined(MV_INCLUDE_CESA)
  37529. +#include "ctrlEnv/sys/mvSysCesa.h"
  37530. +#endif
  37531. +
  37532. +#if defined(MV_INCLUDE_TS)
  37533. +#include "ctrlEnv/sys/mvSysTs.h"
  37534. +#endif
  37535. +
  37536. +/* defines */
  37537. +#ifdef MV_DEBUG
  37538. + #define DB(x) x
  37539. +#else
  37540. + #define DB(x)
  37541. +#endif
  37542. +
  37543. +/*******************************************************************************
  37544. +* mvCtrlEnvInit - Initialize Marvell controller environment.
  37545. +*
  37546. +* DESCRIPTION:
  37547. +* This function get environment information and initialize controller
  37548. +* internal/external environment. For example
  37549. +* 1) MPP settings according to board MPP macros.
  37550. +* NOTE: It is the user responsibility to shut down all DMA channels
  37551. +* in device and disable controller sub units interrupts during
  37552. +* boot process.
  37553. +*
  37554. +* INPUT:
  37555. +* None.
  37556. +*
  37557. +* OUTPUT:
  37558. +* None.
  37559. +*
  37560. +* RETURN:
  37561. +* None.
  37562. +*
  37563. +*******************************************************************************/
  37564. +MV_STATUS mvCtrlEnvInit(MV_VOID)
  37565. +{
  37566. + MV_U32 mppGroup;
  37567. + MV_U32 devId;
  37568. + MV_U32 boardId;
  37569. + MV_U32 i;
  37570. + MV_U32 maxMppGrp = 1;
  37571. + MV_U32 mppVal = 0;
  37572. + MV_U32 bootVal = 0;
  37573. + MV_U32 mppGroupType = 0;
  37574. + MV_U32 mppGroup1[][3] = MPP_GROUP_1_TYPE;
  37575. + MV_U32 mppGroup2[][3] = MPP_GROUP_2_TYPE;
  37576. +
  37577. + devId = mvCtrlModelGet();
  37578. + boardId= mvBoardIdGet();
  37579. +
  37580. + switch(devId){
  37581. + case MV_6281_DEV_ID:
  37582. + maxMppGrp = MV_6281_MPP_MAX_GROUP;
  37583. + break;
  37584. + case MV_6192_DEV_ID:
  37585. + maxMppGrp = MV_6192_MPP_MAX_GROUP;
  37586. + break;
  37587. + case MV_6190_DEV_ID:
  37588. + maxMppGrp = MV_6190_MPP_MAX_GROUP;
  37589. + break;
  37590. + case MV_6180_DEV_ID:
  37591. + maxMppGrp = MV_6180_MPP_MAX_GROUP;
  37592. + break;
  37593. + }
  37594. +
  37595. + /* MPP Init */
  37596. + /* We split mpp init to 3 phases:
  37597. + * 1. We init mpp[19:0] from the board info. mpp[23:20] will be over write
  37598. + * in phase 2.
  37599. + * 2. We detect the mpp group type and according the mpp values [35:20].
  37600. + * 3. We detect the mpp group type and according the mpp values [49:36].
  37601. + */
  37602. + /* Mpp phase 1 mpp[19:0] */
  37603. + /* Read MPP group from board level and assign to MPP register */
  37604. + for (mppGroup = 0; mppGroup < 3; mppGroup++)
  37605. + {
  37606. + mppVal = mvBoardMppGet(mppGroup);
  37607. + if (mppGroup == 0)
  37608. + {
  37609. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  37610. + if (mvCtrlIsBootFromSPI())
  37611. + {
  37612. + mppVal &= ~0xffff;
  37613. + bootVal &= 0xffff;
  37614. + mppVal |= bootVal;
  37615. + }
  37616. + else if (mvCtrlIsBootFromSPIUseNAND())
  37617. + {
  37618. + mppVal &= ~0xf0000000;
  37619. + bootVal &= 0xf0000000;
  37620. + mppVal |= bootVal;
  37621. + }
  37622. + else if (mvCtrlIsBootFromNAND())
  37623. + {
  37624. + mppVal &= ~0xffffff;
  37625. + bootVal &= 0xffffff;
  37626. + mppVal |= bootVal;
  37627. + }
  37628. + }
  37629. +
  37630. + if (mppGroup == 2)
  37631. + {
  37632. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  37633. + if (mvCtrlIsBootFromNAND())
  37634. + {
  37635. + mppVal &= ~0xff00;
  37636. + bootVal &= 0xff00;
  37637. + mppVal |= bootVal;
  37638. + }
  37639. + }
  37640. +
  37641. + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
  37642. + }
  37643. +
  37644. + /* Identify MPPs group */
  37645. + mvBoardMppGroupIdUpdate();
  37646. +
  37647. + /* Update MPPs mux relevent only on Marvell DB */
  37648. + if ((boardId == DB_88F6281A_BP_ID) ||
  37649. + (boardId == DB_88F6180A_BP_ID))
  37650. + mvBoardMppMuxSet();
  37651. +
  37652. + mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_1);
  37653. +
  37654. + /* Mpp phase 2 */
  37655. + /* Read MPP group from board level and assign to MPP register */
  37656. + if (devId != MV_6180_DEV_ID)
  37657. + {
  37658. + i = 0;
  37659. + for (mppGroup = 2; mppGroup < 5; mppGroup++)
  37660. + {
  37661. + if ((mppGroupType == MV_BOARD_OTHER) ||
  37662. + (boardId == RD_88F6281A_ID) ||
  37663. + (boardId == RD_88F6192A_ID) ||
  37664. + (boardId == RD_88F6190A_ID) ||
  37665. + (boardId == RD_88F6281A_PCAC_ID) ||
  37666. + (boardId == SHEEVA_PLUG_ID))
  37667. + mppVal = mvBoardMppGet(mppGroup);
  37668. + else
  37669. + {
  37670. + mppVal = mppGroup1[mppGroupType][i];
  37671. + i++;
  37672. + }
  37673. +
  37674. + /* Group 2 is shared mpp[23:16] */
  37675. + if (mppGroup == 2)
  37676. + {
  37677. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  37678. + mppVal &= ~0xffff;
  37679. + bootVal &= 0xffff;
  37680. + mppVal |= bootVal;
  37681. + }
  37682. +
  37683. + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
  37684. + }
  37685. + }
  37686. +
  37687. + if ((devId == MV_6192_DEV_ID) || (devId == MV_6190_DEV_ID))
  37688. + return MV_OK;
  37689. +
  37690. + /* Mpp phase 3 */
  37691. + mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_2);
  37692. + /* Read MPP group from board level and assign to MPP register */
  37693. + i = 0;
  37694. + for (mppGroup = 4; mppGroup < 7; mppGroup++)
  37695. + {
  37696. + if ((mppGroupType == MV_BOARD_OTHER) ||
  37697. + (boardId == RD_88F6281A_ID) ||
  37698. + (boardId == RD_88F6281A_PCAC_ID) ||
  37699. + (boardId == SHEEVA_PLUG_ID))
  37700. + mppVal = mvBoardMppGet(mppGroup);
  37701. + else
  37702. + {
  37703. + mppVal = mppGroup2[mppGroupType][i];
  37704. + i++;
  37705. + }
  37706. +
  37707. + /* Group 4 is shared mpp[35:32] */
  37708. + if (mppGroup == 4)
  37709. + {
  37710. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  37711. + mppVal &= ~0xffff;
  37712. + bootVal &= 0xffff;
  37713. + mppVal |= bootVal;
  37714. + }
  37715. +
  37716. + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
  37717. + }
  37718. + /* Update SSCG configuration register*/
  37719. + if(mvBoardIdGet() == DB_88F6281A_BP_ID || mvBoardIdGet() == DB_88F6192A_BP_ID ||
  37720. + mvBoardIdGet() == DB_88F6190A_BP_ID || mvBoardIdGet() == DB_88F6180A_BP_ID)
  37721. + MV_REG_WRITE(0x100d8, 0x53);
  37722. +
  37723. + return MV_OK;
  37724. +}
  37725. +
  37726. +/*******************************************************************************
  37727. +* mvCtrlMppRegGet - return reg address of mpp group
  37728. +*
  37729. +* DESCRIPTION:
  37730. +*
  37731. +* INPUT:
  37732. +* mppGroup - MPP group.
  37733. +*
  37734. +* OUTPUT:
  37735. +* None.
  37736. +*
  37737. +* RETURN:
  37738. +* MV_U32 - Register address.
  37739. +*
  37740. +*******************************************************************************/
  37741. +MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup)
  37742. +{
  37743. + MV_U32 ret;
  37744. +
  37745. + switch(mppGroup){
  37746. + case (0): ret = MPP_CONTROL_REG0;
  37747. + break;
  37748. + case (1): ret = MPP_CONTROL_REG1;
  37749. + break;
  37750. + case (2): ret = MPP_CONTROL_REG2;
  37751. + break;
  37752. + case (3): ret = MPP_CONTROL_REG3;
  37753. + break;
  37754. + case (4): ret = MPP_CONTROL_REG4;
  37755. + break;
  37756. + case (5): ret = MPP_CONTROL_REG5;
  37757. + break;
  37758. + case (6): ret = MPP_CONTROL_REG6;
  37759. + break;
  37760. + default: ret = MPP_CONTROL_REG0;
  37761. + break;
  37762. + }
  37763. + return ret;
  37764. +}
  37765. +#if defined(MV_INCLUDE_PEX)
  37766. +/*******************************************************************************
  37767. +* mvCtrlPexMaxIfGet - Get Marvell controller number of PEX interfaces.
  37768. +*
  37769. +* DESCRIPTION:
  37770. +* This function returns Marvell controller number of PEX interfaces.
  37771. +*
  37772. +* INPUT:
  37773. +* None.
  37774. +*
  37775. +* OUTPUT:
  37776. +* None.
  37777. +*
  37778. +* RETURN:
  37779. +* Marvell controller number of PEX interfaces. If controller
  37780. +* ID is undefined the function returns '0'.
  37781. +*
  37782. +*******************************************************************************/
  37783. +MV_U32 mvCtrlPexMaxIfGet(MV_VOID)
  37784. +{
  37785. +
  37786. + return MV_PEX_MAX_IF;
  37787. +}
  37788. +#endif
  37789. +
  37790. +#if defined(MV_INCLUDE_GIG_ETH)
  37791. +/*******************************************************************************
  37792. +* mvCtrlEthMaxPortGet - Get Marvell controller number of etherent ports.
  37793. +*
  37794. +* DESCRIPTION:
  37795. +* This function returns Marvell controller number of etherent port.
  37796. +*
  37797. +* INPUT:
  37798. +* None.
  37799. +*
  37800. +* OUTPUT:
  37801. +* None.
  37802. +*
  37803. +* RETURN:
  37804. +* Marvell controller number of etherent port.
  37805. +*
  37806. +*******************************************************************************/
  37807. +MV_U32 mvCtrlEthMaxPortGet(MV_VOID)
  37808. +{
  37809. + MV_U32 devId;
  37810. +
  37811. + devId = mvCtrlModelGet();
  37812. +
  37813. + switch(devId){
  37814. + case MV_6281_DEV_ID:
  37815. + return MV_6281_ETH_MAX_PORTS;
  37816. + break;
  37817. + case MV_6192_DEV_ID:
  37818. + return MV_6192_ETH_MAX_PORTS;
  37819. + break;
  37820. + case MV_6190_DEV_ID:
  37821. + return MV_6190_ETH_MAX_PORTS;
  37822. + break;
  37823. + case MV_6180_DEV_ID:
  37824. + return MV_6180_ETH_MAX_PORTS;
  37825. + break;
  37826. + }
  37827. + return 0;
  37828. +
  37829. +}
  37830. +#endif
  37831. +
  37832. +#if defined(MV_INCLUDE_XOR)
  37833. +/*******************************************************************************
  37834. +* mvCtrlXorMaxChanGet - Get Marvell controller number of XOR channels.
  37835. +*
  37836. +* DESCRIPTION:
  37837. +* This function returns Marvell controller number of XOR channels.
  37838. +*
  37839. +* INPUT:
  37840. +* None.
  37841. +*
  37842. +* OUTPUT:
  37843. +* None.
  37844. +*
  37845. +* RETURN:
  37846. +* Marvell controller number of XOR channels.
  37847. +*
  37848. +*******************************************************************************/
  37849. +MV_U32 mvCtrlXorMaxChanGet(MV_VOID)
  37850. +{
  37851. + return MV_XOR_MAX_CHAN;
  37852. +}
  37853. +#endif
  37854. +
  37855. +#if defined(MV_INCLUDE_USB)
  37856. +/*******************************************************************************
  37857. +* mvCtrlUsbHostMaxGet - Get number of Marvell Usb controllers
  37858. +*
  37859. +* DESCRIPTION:
  37860. +*
  37861. +* INPUT:
  37862. +* None.
  37863. +*
  37864. +* OUTPUT:
  37865. +* None.
  37866. +*
  37867. +* RETURN:
  37868. +* returns number of Marvell USB controllers.
  37869. +*
  37870. +*******************************************************************************/
  37871. +MV_U32 mvCtrlUsbMaxGet(void)
  37872. +{
  37873. + return MV_USB_MAX_PORTS;
  37874. +}
  37875. +#endif
  37876. +
  37877. +
  37878. +#if defined(MV_INCLUDE_NAND)
  37879. +/*******************************************************************************
  37880. +* mvCtrlNandSupport - Return if this controller has integrated NAND flash support
  37881. +*
  37882. +* DESCRIPTION:
  37883. +*
  37884. +* INPUT:
  37885. +* None.
  37886. +*
  37887. +* OUTPUT:
  37888. +* None.
  37889. +*
  37890. +* RETURN:
  37891. +* MV_TRUE if NAND is supported and MV_FALSE otherwise
  37892. +*
  37893. +*******************************************************************************/
  37894. +MV_U32 mvCtrlNandSupport(MV_VOID)
  37895. +{
  37896. + MV_U32 devId;
  37897. +
  37898. + devId = mvCtrlModelGet();
  37899. +
  37900. + switch(devId){
  37901. + case MV_6281_DEV_ID:
  37902. + return MV_6281_NAND;
  37903. + break;
  37904. + case MV_6192_DEV_ID:
  37905. + return MV_6192_NAND;
  37906. + break;
  37907. + case MV_6190_DEV_ID:
  37908. + return MV_6190_NAND;
  37909. + break;
  37910. + case MV_6180_DEV_ID:
  37911. + return MV_6180_NAND;
  37912. + break;
  37913. + }
  37914. + return 0;
  37915. +
  37916. +}
  37917. +#endif
  37918. +
  37919. +#if defined(MV_INCLUDE_SDIO)
  37920. +/*******************************************************************************
  37921. +* mvCtrlSdioSupport - Return if this controller has integrated SDIO flash support
  37922. +*
  37923. +* DESCRIPTION:
  37924. +*
  37925. +* INPUT:
  37926. +* None.
  37927. +*
  37928. +* OUTPUT:
  37929. +* None.
  37930. +*
  37931. +* RETURN:
  37932. +* MV_TRUE if SDIO is supported and MV_FALSE otherwise
  37933. +*
  37934. +*******************************************************************************/
  37935. +MV_U32 mvCtrlSdioSupport(MV_VOID)
  37936. +{
  37937. + MV_U32 devId;
  37938. +
  37939. + devId = mvCtrlModelGet();
  37940. +
  37941. + switch(devId){
  37942. + case MV_6281_DEV_ID:
  37943. + return MV_6281_SDIO;
  37944. + break;
  37945. + case MV_6192_DEV_ID:
  37946. + return MV_6192_SDIO;
  37947. + break;
  37948. + case MV_6190_DEV_ID:
  37949. + return MV_6190_SDIO;
  37950. + break;
  37951. + case MV_6180_DEV_ID:
  37952. + return MV_6180_SDIO;
  37953. + break;
  37954. + }
  37955. + return 0;
  37956. +
  37957. +}
  37958. +#endif
  37959. +
  37960. +#if defined(MV_INCLUDE_TS)
  37961. +/*******************************************************************************
  37962. +* mvCtrlTsSupport - Return if this controller has integrated TS flash support
  37963. +*
  37964. +* DESCRIPTION:
  37965. +*
  37966. +* INPUT:
  37967. +* None.
  37968. +*
  37969. +* OUTPUT:
  37970. +* None.
  37971. +*
  37972. +* RETURN:
  37973. +* MV_TRUE if TS is supported and MV_FALSE otherwise
  37974. +*
  37975. +*******************************************************************************/
  37976. +MV_U32 mvCtrlTsSupport(MV_VOID)
  37977. +{
  37978. + MV_U32 devId;
  37979. +
  37980. + devId = mvCtrlModelGet();
  37981. +
  37982. + switch(devId){
  37983. + case MV_6281_DEV_ID:
  37984. + return MV_6281_TS;
  37985. + break;
  37986. + case MV_6192_DEV_ID:
  37987. + return MV_6192_TS;
  37988. + break;
  37989. + case MV_6190_DEV_ID:
  37990. + return MV_6190_TS;
  37991. + break;
  37992. + case MV_6180_DEV_ID:
  37993. + return MV_6180_TS;
  37994. + break;
  37995. + }
  37996. + return 0;
  37997. +}
  37998. +#endif
  37999. +
  38000. +#if defined(MV_INCLUDE_AUDIO)
  38001. +/*******************************************************************************
  38002. +* mvCtrlAudioSupport - Return if this controller has integrated AUDIO flash support
  38003. +*
  38004. +* DESCRIPTION:
  38005. +*
  38006. +* INPUT:
  38007. +* None.
  38008. +*
  38009. +* OUTPUT:
  38010. +* None.
  38011. +*
  38012. +* RETURN:
  38013. +* MV_TRUE if AUDIO is supported and MV_FALSE otherwise
  38014. +*
  38015. +*******************************************************************************/
  38016. +MV_U32 mvCtrlAudioSupport(MV_VOID)
  38017. +{
  38018. + MV_U32 devId;
  38019. +
  38020. + devId = mvCtrlModelGet();
  38021. +
  38022. + switch(devId){
  38023. + case MV_6281_DEV_ID:
  38024. + return MV_6281_AUDIO;
  38025. + break;
  38026. + case MV_6192_DEV_ID:
  38027. + return MV_6192_AUDIO;
  38028. + break;
  38029. + case MV_6190_DEV_ID:
  38030. + return MV_6190_AUDIO;
  38031. + break;
  38032. + case MV_6180_DEV_ID:
  38033. + return MV_6180_AUDIO;
  38034. + break;
  38035. + }
  38036. + return 0;
  38037. +
  38038. +}
  38039. +#endif
  38040. +
  38041. +#if defined(MV_INCLUDE_TDM)
  38042. +/*******************************************************************************
  38043. +* mvCtrlTdmSupport - Return if this controller has integrated TDM flash support
  38044. +*
  38045. +* DESCRIPTION:
  38046. +*
  38047. +* INPUT:
  38048. +* None.
  38049. +*
  38050. +* OUTPUT:
  38051. +* None.
  38052. +*
  38053. +* RETURN:
  38054. +* MV_TRUE if TDM is supported and MV_FALSE otherwise
  38055. +*
  38056. +*******************************************************************************/
  38057. +MV_U32 mvCtrlTdmSupport(MV_VOID)
  38058. +{
  38059. + MV_U32 devId;
  38060. +
  38061. + devId = mvCtrlModelGet();
  38062. +
  38063. + switch(devId){
  38064. + case MV_6281_DEV_ID:
  38065. + return MV_6281_TDM;
  38066. + break;
  38067. + case MV_6192_DEV_ID:
  38068. + return MV_6192_TDM;
  38069. + break;
  38070. + case MV_6190_DEV_ID:
  38071. + return MV_6190_TDM;
  38072. + break;
  38073. + case MV_6180_DEV_ID:
  38074. + return MV_6180_TDM;
  38075. + break;
  38076. + }
  38077. + return 0;
  38078. +
  38079. +}
  38080. +#endif
  38081. +
  38082. +/*******************************************************************************
  38083. +* mvCtrlModelGet - Get Marvell controller device model (Id)
  38084. +*
  38085. +* DESCRIPTION:
  38086. +* This function returns 16bit describing the device model (ID) as defined
  38087. +* in PCI Device and Vendor ID configuration register offset 0x0.
  38088. +*
  38089. +* INPUT:
  38090. +* None.
  38091. +*
  38092. +* OUTPUT:
  38093. +* None.
  38094. +*
  38095. +* RETURN:
  38096. +* 16bit desscribing Marvell controller ID
  38097. +*
  38098. +*******************************************************************************/
  38099. +MV_U16 mvCtrlModelGet(MV_VOID)
  38100. +{
  38101. + MV_U32 devId;
  38102. +
  38103. + devId = MV_REG_READ(CHIP_BOND_REG);
  38104. + devId &= PCKG_OPT_MASK;
  38105. +
  38106. + switch(devId){
  38107. + case 2:
  38108. + return MV_6281_DEV_ID;
  38109. + break;
  38110. + case 1:
  38111. + if (((MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PEX_DEVICE_AND_VENDOR_ID))& 0xffff0000) >> 16)
  38112. + == MV_6190_DEV_ID)
  38113. + return MV_6190_DEV_ID;
  38114. + else
  38115. + return MV_6192_DEV_ID;
  38116. + break;
  38117. + case 0:
  38118. + return MV_6180_DEV_ID;
  38119. + break;
  38120. + }
  38121. +
  38122. + return 0;
  38123. +}
  38124. +/*******************************************************************************
  38125. +* mvCtrlRevGet - Get Marvell controller device revision number
  38126. +*
  38127. +* DESCRIPTION:
  38128. +* This function returns 8bit describing the device revision as defined
  38129. +* in PCI Express Class Code and Revision ID Register.
  38130. +*
  38131. +* INPUT:
  38132. +* None.
  38133. +*
  38134. +* OUTPUT:
  38135. +* None.
  38136. +*
  38137. +* RETURN:
  38138. +* 8bit desscribing Marvell controller revision number
  38139. +*
  38140. +*******************************************************************************/
  38141. +MV_U8 mvCtrlRevGet(MV_VOID)
  38142. +{
  38143. + MV_U8 revNum;
  38144. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  38145. + /* Check pex power state */
  38146. + MV_U32 pexPower;
  38147. + pexPower = mvCtrlPwrClckGet(PEX_UNIT_ID,0);
  38148. + if (pexPower == MV_FALSE)
  38149. + mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_TRUE);
  38150. +#endif
  38151. + revNum = (MV_U8)MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PCI_CLASS_CODE_AND_REVISION_ID));
  38152. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  38153. + /* Return to power off state */
  38154. + if (pexPower == MV_FALSE)
  38155. + mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_FALSE);
  38156. +#endif
  38157. + return ((revNum & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS);
  38158. +}
  38159. +
  38160. +/*******************************************************************************
  38161. +* mvCtrlNameGet - Get Marvell controller name
  38162. +*
  38163. +* DESCRIPTION:
  38164. +* This function returns a string describing the device model and revision.
  38165. +*
  38166. +* INPUT:
  38167. +* None.
  38168. +*
  38169. +* OUTPUT:
  38170. +* pNameBuff - Buffer to contain device name string. Minimum size 30 chars.
  38171. +*
  38172. +* RETURN:
  38173. +*
  38174. +* MV_ERROR if informantion can not be read.
  38175. +*******************************************************************************/
  38176. +MV_STATUS mvCtrlNameGet(char *pNameBuff)
  38177. +{
  38178. + mvOsSPrintf (pNameBuff, "%s%x Rev %d", SOC_NAME_PREFIX,
  38179. + mvCtrlModelGet(), mvCtrlRevGet());
  38180. +
  38181. + return MV_OK;
  38182. +}
  38183. +
  38184. +/*******************************************************************************
  38185. +* mvCtrlModelRevGet - Get Controller Model (Device ID) and Revision
  38186. +*
  38187. +* DESCRIPTION:
  38188. +* This function returns 32bit value describing both Device ID and Revision
  38189. +* as defined in PCI Express Device and Vendor ID Register and device revision
  38190. +* as defined in PCI Express Class Code and Revision ID Register.
  38191. +
  38192. +*
  38193. +* INPUT:
  38194. +* None.
  38195. +*
  38196. +* OUTPUT:
  38197. +* None.
  38198. +*
  38199. +* RETURN:
  38200. +* 32bit describing both controller device ID and revision number
  38201. +*
  38202. +*******************************************************************************/
  38203. +MV_U32 mvCtrlModelRevGet(MV_VOID)
  38204. +{
  38205. + return ((mvCtrlModelGet() << 16) | mvCtrlRevGet());
  38206. +}
  38207. +
  38208. +/*******************************************************************************
  38209. +* mvCtrlModelRevNameGet - Get Marvell controller name
  38210. +*
  38211. +* DESCRIPTION:
  38212. +* This function returns a string describing the device model and revision.
  38213. +*
  38214. +* INPUT:
  38215. +* None.
  38216. +*
  38217. +* OUTPUT:
  38218. +* pNameBuff - Buffer to contain device name string. Minimum size 30 chars.
  38219. +*
  38220. +* RETURN:
  38221. +*
  38222. +* MV_ERROR if informantion can not be read.
  38223. +*******************************************************************************/
  38224. +
  38225. +MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff)
  38226. +{
  38227. +
  38228. + switch (mvCtrlModelRevGet())
  38229. + {
  38230. + case MV_6281_A0_ID:
  38231. + mvOsSPrintf (pNameBuff, "%s",MV_6281_A0_NAME);
  38232. + break;
  38233. + case MV_6192_A0_ID:
  38234. + mvOsSPrintf (pNameBuff, "%s",MV_6192_A0_NAME);
  38235. + break;
  38236. + case MV_6180_A0_ID:
  38237. + mvOsSPrintf (pNameBuff, "%s",MV_6180_A0_NAME);
  38238. + break;
  38239. + case MV_6190_A0_ID:
  38240. + mvOsSPrintf (pNameBuff, "%s",MV_6190_A0_NAME);
  38241. + break;
  38242. + case MV_6281_A1_ID:
  38243. + mvOsSPrintf (pNameBuff, "%s",MV_6281_A1_NAME);
  38244. + break;
  38245. + case MV_6192_A1_ID:
  38246. + mvOsSPrintf (pNameBuff, "%s",MV_6192_A1_NAME);
  38247. + break;
  38248. + case MV_6180_A1_ID:
  38249. + mvOsSPrintf (pNameBuff, "%s",MV_6180_A1_NAME);
  38250. + break;
  38251. + case MV_6190_A1_ID:
  38252. + mvOsSPrintf (pNameBuff, "%s",MV_6190_A1_NAME);
  38253. + break;
  38254. + default:
  38255. + mvCtrlNameGet(pNameBuff);
  38256. + break;
  38257. + }
  38258. +
  38259. + return MV_OK;
  38260. +}
  38261. +
  38262. +
  38263. +/*******************************************************************************
  38264. +* ctrlWinOverlapTest - Test address windows for overlaping.
  38265. +*
  38266. +* DESCRIPTION:
  38267. +* This function checks the given two address windows for overlaping.
  38268. +*
  38269. +* INPUT:
  38270. +* pAddrWin1 - Address window 1.
  38271. +* pAddrWin2 - Address window 2.
  38272. +*
  38273. +* OUTPUT:
  38274. +* None.
  38275. +*
  38276. +* RETURN:
  38277. +*
  38278. +* MV_TRUE if address window overlaps, MV_FALSE otherwise.
  38279. +*******************************************************************************/
  38280. +MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)
  38281. +{
  38282. + MV_U32 winBase1, winBase2;
  38283. + MV_U32 winTop1, winTop2;
  38284. +
  38285. + /* check if we have overflow than 4G*/
  38286. + if (((0xffffffff - pAddrWin1->baseLow) < pAddrWin1->size-1)||
  38287. + ((0xffffffff - pAddrWin2->baseLow) < pAddrWin2->size-1))
  38288. + {
  38289. + return MV_TRUE;
  38290. + }
  38291. +
  38292. + winBase1 = pAddrWin1->baseLow;
  38293. + winBase2 = pAddrWin2->baseLow;
  38294. + winTop1 = winBase1 + pAddrWin1->size-1;
  38295. + winTop2 = winBase2 + pAddrWin2->size-1;
  38296. +
  38297. +
  38298. + if (((winBase1 <= winTop2 ) && ( winTop2 <= winTop1)) ||
  38299. + ((winBase1 <= winBase2) && (winBase2 <= winTop1)))
  38300. + {
  38301. + return MV_TRUE;
  38302. + }
  38303. + else
  38304. + {
  38305. + return MV_FALSE;
  38306. + }
  38307. +}
  38308. +
  38309. +/*******************************************************************************
  38310. +* ctrlWinWithinWinTest - Test address windows for overlaping.
  38311. +*
  38312. +* DESCRIPTION:
  38313. +* This function checks the given win1 boundries is within
  38314. +* win2 boundries.
  38315. +*
  38316. +* INPUT:
  38317. +* pAddrWin1 - Address window 1.
  38318. +* pAddrWin2 - Address window 2.
  38319. +*
  38320. +* OUTPUT:
  38321. +* None.
  38322. +*
  38323. +* RETURN:
  38324. +*
  38325. +* MV_TRUE if found win1 inside win2, MV_FALSE otherwise.
  38326. +*******************************************************************************/
  38327. +MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)
  38328. +{
  38329. + MV_U32 winBase1, winBase2;
  38330. + MV_U32 winTop1, winTop2;
  38331. +
  38332. + winBase1 = pAddrWin1->baseLow;
  38333. + winBase2 = pAddrWin2->baseLow;
  38334. + winTop1 = winBase1 + pAddrWin1->size -1;
  38335. + winTop2 = winBase2 + pAddrWin2->size -1;
  38336. +
  38337. + if (((winBase1 >= winBase2 ) && ( winBase1 <= winTop2)) ||
  38338. + ((winTop1 >= winBase2) && (winTop1 <= winTop2)))
  38339. + {
  38340. + return MV_TRUE;
  38341. + }
  38342. + else
  38343. + {
  38344. + return MV_FALSE;
  38345. + }
  38346. +}
  38347. +
  38348. +static const char* cntrlName[] = TARGETS_NAME_ARRAY;
  38349. +
  38350. +/*******************************************************************************
  38351. +* mvCtrlTargetNameGet - Get Marvell controller target name
  38352. +*
  38353. +* DESCRIPTION:
  38354. +* This function convert the trget enumeration to string.
  38355. +*
  38356. +* INPUT:
  38357. +* None.
  38358. +*
  38359. +* OUTPUT:
  38360. +* None.
  38361. +*
  38362. +* RETURN:
  38363. +* Target name (const MV_8 *)
  38364. +*******************************************************************************/
  38365. +const MV_8* mvCtrlTargetNameGet( MV_TARGET target )
  38366. +{
  38367. +
  38368. + if (target >= MAX_TARGETS)
  38369. + {
  38370. + return "target unknown";
  38371. + }
  38372. +
  38373. + return cntrlName[target];
  38374. +}
  38375. +
  38376. +/*******************************************************************************
  38377. +* mvCtrlAddrDecShow - Print the Controller units address decode map.
  38378. +*
  38379. +* DESCRIPTION:
  38380. +* This function the Controller units address decode map.
  38381. +*
  38382. +* INPUT:
  38383. +* None.
  38384. +*
  38385. +* OUTPUT:
  38386. +* None.
  38387. +*
  38388. +* RETURN:
  38389. +* None.
  38390. +*
  38391. +*******************************************************************************/
  38392. +MV_VOID mvCtrlAddrDecShow(MV_VOID)
  38393. +{
  38394. + mvCpuIfAddDecShow();
  38395. + mvAhbToMbusAddDecShow();
  38396. +#if defined(MV_INCLUDE_PEX)
  38397. + mvPexAddrDecShow();
  38398. +#endif
  38399. +#if defined(MV_INCLUDE_USB)
  38400. + mvUsbAddrDecShow();
  38401. +#endif
  38402. +#if defined(MV_INCLUDE_GIG_ETH)
  38403. + mvEthAddrDecShow();
  38404. +#endif
  38405. +#if defined(MV_INCLUDE_XOR)
  38406. + mvXorAddrDecShow();
  38407. +#endif
  38408. +#if defined(MV_INCLUDE_SATA)
  38409. + mvSataAddrDecShow();
  38410. +#endif
  38411. +#if defined(MV_INCLUDE_AUDIO)
  38412. + mvAudioAddrDecShow();
  38413. +#endif
  38414. +#if defined(MV_INCLUDE_TS)
  38415. + mvTsuAddrDecShow();
  38416. +#endif
  38417. +}
  38418. +
  38419. +/*******************************************************************************
  38420. +* ctrlSizeToReg - Extract size value for register assignment.
  38421. +*
  38422. +* DESCRIPTION:
  38423. +* Address decode size parameter must be programed from LSB to MSB as
  38424. +* sequence of 1's followed by sequence of 0's. The number of 1's
  38425. +* specifies the size of the window in 64 KB granularity (e.g. a
  38426. +* value of 0x00ff specifies 256x64k = 16 MB).
  38427. +* This function extract the size value from the size parameter according
  38428. +* to given aligment paramter. For example for size 0x1000000 (16MB) and
  38429. +* aligment 0x10000 (64KB) the function will return 0x00FF.
  38430. +*
  38431. +* INPUT:
  38432. +* size - Size.
  38433. +* alignment - Size alignment. Note that alignment must be power of 2!
  38434. +*
  38435. +* OUTPUT:
  38436. +* None.
  38437. +*
  38438. +* RETURN:
  38439. +* 32bit describing size register value correspond to size parameter.
  38440. +* If value is '-1' size parameter or aligment are invalid.
  38441. +*******************************************************************************/
  38442. +MV_U32 ctrlSizeToReg(MV_U32 size, MV_U32 alignment)
  38443. +{
  38444. + MV_U32 retVal;
  38445. +
  38446. + /* Check size parameter alignment */
  38447. + if ((0 == size) || (MV_IS_NOT_ALIGN(size, alignment)))
  38448. + {
  38449. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Size is zero or not aligned.\n"));
  38450. + return -1;
  38451. + }
  38452. +
  38453. + /* Take out the "alignment" portion out of the size parameter */
  38454. + alignment--; /* Now the alignmet is a sequance of '1' (e.g. 0xffff) */
  38455. + /* and size is 0x1000000 (16MB) for example */
  38456. + while(alignment & 1) /* Check that alignmet LSB is set */
  38457. + {
  38458. + size = (size >> 1); /* If LSB is set, move 'size' one bit to right */
  38459. + alignment = (alignment >> 1);
  38460. + }
  38461. +
  38462. + /* If after the alignment first '0' was met we still have '1' in */
  38463. + /* it then aligment is invalid (not power of 2) */
  38464. + if (alignment)
  38465. + {
  38466. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n",
  38467. + (MV_U32)alignment));
  38468. + return -1;
  38469. + }
  38470. +
  38471. + /* Now the size is shifted right according to aligment: 0x0100 */
  38472. + size--; /* Now the size is a sequance of '1': 0x00ff */
  38473. +
  38474. + retVal = size ;
  38475. +
  38476. + /* Check that LSB to MSB is sequence of 1's followed by sequence of 0's */
  38477. + while(size & 1) /* Check that LSB is set */
  38478. + {
  38479. + size = (size >> 1); /* If LSB is set, move one bit to the right */
  38480. + }
  38481. +
  38482. + if (size) /* Sequance of 1's is over. Check that we have no other 1's */
  38483. + {
  38484. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Size parameter 0x%x invalid.\n",
  38485. + size));
  38486. + return -1;
  38487. + }
  38488. +
  38489. + return retVal;
  38490. +
  38491. +}
  38492. +
  38493. +/*******************************************************************************
  38494. +* ctrlRegToSize - Extract size value from register value.
  38495. +*
  38496. +* DESCRIPTION:
  38497. +* This function extract a size value from the register size parameter
  38498. +* according to given aligment paramter. For example for register size
  38499. +* value 0xff and aligment 0x10000 the function will return 0x01000000.
  38500. +*
  38501. +* INPUT:
  38502. +* regSize - Size as in register format. See ctrlSizeToReg.
  38503. +* alignment - Size alignment. Note that alignment must be power of 2!
  38504. +*
  38505. +* OUTPUT:
  38506. +* None.
  38507. +*
  38508. +* RETURN:
  38509. +* 32bit describing size.
  38510. +* If value is '-1' size parameter or aligment are invalid.
  38511. +*******************************************************************************/
  38512. +MV_U32 ctrlRegToSize(MV_U32 regSize, MV_U32 alignment)
  38513. +{
  38514. + MV_U32 temp;
  38515. +
  38516. + /* Check that LSB to MSB is sequence of 1's followed by sequence of 0's */
  38517. + temp = regSize; /* Now the size is a sequance of '1': 0x00ff */
  38518. +
  38519. + while(temp & 1) /* Check that LSB is set */
  38520. + {
  38521. + temp = (temp >> 1); /* If LSB is set, move one bit to the right */
  38522. + }
  38523. +
  38524. + if (temp) /* Sequance of 1's is over. Check that we have no other 1's */
  38525. + {
  38526. + DB(mvOsPrintf("ctrlRegToSize: ERR. Size parameter 0x%x invalid.\n",
  38527. + regSize));
  38528. + return -1;
  38529. + }
  38530. +
  38531. +
  38532. + /* Check that aligment is a power of two */
  38533. + temp = alignment - 1;/* Now the alignmet is a sequance of '1' (0xffff) */
  38534. +
  38535. + while(temp & 1) /* Check that alignmet LSB is set */
  38536. + {
  38537. + temp = (temp >> 1); /* If LSB is set, move 'size' one bit to right */
  38538. + }
  38539. +
  38540. + /* If after the 'temp' first '0' was met we still have '1' in 'temp' */
  38541. + /* then 'temp' is invalid (not power of 2) */
  38542. + if (temp)
  38543. + {
  38544. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n",
  38545. + alignment));
  38546. + return -1;
  38547. + }
  38548. +
  38549. + regSize++; /* Now the size is 0x0100 */
  38550. +
  38551. + /* Add in the "alignment" portion to the register size parameter */
  38552. + alignment--; /* Now the alignmet is a sequance of '1' (e.g. 0xffff) */
  38553. +
  38554. + while(alignment & 1) /* Check that alignmet LSB is set */
  38555. + {
  38556. + regSize = (regSize << 1); /* LSB is set, move 'size' one bit left */
  38557. + alignment = (alignment >> 1);
  38558. + }
  38559. +
  38560. + return regSize;
  38561. +}
  38562. +
  38563. +
  38564. +/*******************************************************************************
  38565. +* ctrlSizeRegRoundUp - Round up given size
  38566. +*
  38567. +* DESCRIPTION:
  38568. +* This function round up a given size to a size that fits the
  38569. +* restrictions of size format given an aligment parameter.
  38570. +* to given aligment paramter. For example for size parameter 0xa1000 and
  38571. +* aligment 0x1000 the function will return 0xFF000.
  38572. +*
  38573. +* INPUT:
  38574. +* size - Size.
  38575. +* alignment - Size alignment. Note that alignment must be power of 2!
  38576. +*
  38577. +* OUTPUT:
  38578. +* None.
  38579. +*
  38580. +* RETURN:
  38581. +* 32bit describing size value correspond to size in register.
  38582. +*******************************************************************************/
  38583. +MV_U32 ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment)
  38584. +{
  38585. + MV_U32 msbBit = 0;
  38586. + MV_U32 retSize;
  38587. +
  38588. + /* Check if size parameter is already comply with restriction */
  38589. + if (!(-1 == ctrlSizeToReg(size, alignment)))
  38590. + {
  38591. + return size;
  38592. + }
  38593. +
  38594. + while(size)
  38595. + {
  38596. + size = (size >> 1);
  38597. + msbBit++;
  38598. + }
  38599. +
  38600. + retSize = (1 << msbBit);
  38601. +
  38602. + if (retSize < alignment)
  38603. + {
  38604. + return alignment;
  38605. + }
  38606. + else
  38607. + {
  38608. + return retSize;
  38609. + }
  38610. +}
  38611. +/*******************************************************************************
  38612. +* mvCtrlSysRstLengthCounterGet - Return number of milliseconds the reset button
  38613. +* was pressed and clear counter
  38614. +*
  38615. +* DESCRIPTION:
  38616. +*
  38617. +* INPUT:
  38618. +*
  38619. +* OUTPUT:
  38620. +*
  38621. +* RETURN: number of milliseconds the reset button was pressed
  38622. +*******************************************************************************/
  38623. +MV_U32 mvCtrlSysRstLengthCounterGet(MV_VOID)
  38624. +{
  38625. + static volatile MV_U32 Count = 0;
  38626. +
  38627. + if(!Count) {
  38628. + Count = (MV_REG_READ(SYSRST_LENGTH_COUNTER_REG) & SLCR_COUNT_MASK);
  38629. + Count = (Count / (MV_BOARD_REFCLK_25MHZ / 1000));
  38630. + /* clear counter for next boot */
  38631. + MV_REG_BIT_SET(SYSRST_LENGTH_COUNTER_REG, SLCR_CLR_MASK);
  38632. + }
  38633. +
  38634. + DB(mvOsPrintf("mvCtrlSysRstLengthCounterGet: Reset button was pressed for %u milliseconds\n", Count));
  38635. +
  38636. + return Count;
  38637. +}
  38638. +
  38639. +MV_BOOL mvCtrlIsBootFromSPI(MV_VOID)
  38640. +{
  38641. + MV_U32 satr = 0;
  38642. + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  38643. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  38644. + {
  38645. + if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_SPI_WITH_BOOTROM_6180)
  38646. + return MV_TRUE;
  38647. + else
  38648. + return MV_FALSE;
  38649. + }
  38650. + satr = satr & MSAR_BOOT_MODE_MASK;
  38651. + if (satr == MSAR_BOOT_SPI_WITH_BOOTROM)
  38652. + return MV_TRUE;
  38653. + else
  38654. + return MV_FALSE;
  38655. +}
  38656. +
  38657. +MV_BOOL mvCtrlIsBootFromSPIUseNAND(MV_VOID)
  38658. +{
  38659. + MV_U32 satr = 0;
  38660. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  38661. + return MV_FALSE;
  38662. + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  38663. + satr = satr & MSAR_BOOT_MODE_MASK;
  38664. +
  38665. + if (satr == MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM)
  38666. + return MV_TRUE;
  38667. + else
  38668. + return MV_FALSE;
  38669. +}
  38670. +
  38671. +MV_BOOL mvCtrlIsBootFromNAND(MV_VOID)
  38672. +{
  38673. + MV_U32 satr = 0;
  38674. + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  38675. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  38676. + {
  38677. + if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_NAND_WITH_BOOTROM_6180)
  38678. + return MV_TRUE;
  38679. + else
  38680. + return MV_FALSE;
  38681. + }
  38682. + satr = satr & MSAR_BOOT_MODE_MASK;
  38683. + if ((satr == MSAR_BOOT_NAND_WITH_BOOTROM))
  38684. + return MV_TRUE;
  38685. + else
  38686. + return MV_FALSE;
  38687. +}
  38688. +
  38689. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  38690. +/*******************************************************************************
  38691. +* mvCtrlPwrSaveOn - Set Power save mode
  38692. +*
  38693. +* DESCRIPTION:
  38694. +*
  38695. +* INPUT:
  38696. +*
  38697. +* OUTPUT:
  38698. +*
  38699. +* RETURN:
  38700. +*******************************************************************************/
  38701. +MV_VOID mvCtrlPwrSaveOn(MV_VOID)
  38702. +{
  38703. + unsigned long old,temp;
  38704. + /* Disable int */
  38705. + __asm__ __volatile__("mrs %0, cpsr\n"
  38706. + "orr %1, %0, #0xc0\n"
  38707. + "msr cpsr_c, %1"
  38708. + : "=r" (old), "=r" (temp)
  38709. + :
  38710. + : "memory");
  38711. +
  38712. + /* Set SoC in power save */
  38713. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, BIT11);
  38714. + /* Wait for int */
  38715. + __asm__ __volatile__("mcr p15, 0, r0, c7, c0, 4");
  38716. +
  38717. + /* Enabled int */
  38718. + __asm__ __volatile__("msr cpsr_c, %0"
  38719. + :
  38720. + : "r" (old)
  38721. + : "memory");
  38722. +}
  38723. +
  38724. +
  38725. +
  38726. +/*******************************************************************************
  38727. +* mvCtrlPwrSaveOff - Go out of power save mode
  38728. +*
  38729. +* DESCRIPTION:
  38730. +*
  38731. +* INPUT:
  38732. +*
  38733. +* OUTPUT:
  38734. +*
  38735. +* RETURN:
  38736. +*******************************************************************************/
  38737. +MV_VOID mvCtrlPwrSaveOff(MV_VOID)
  38738. +{
  38739. + unsigned long old,temp;
  38740. + /* Disable int */
  38741. + __asm__ __volatile__("mrs %0, cpsr\n"
  38742. + "orr %1, %0, #0xc0\n"
  38743. + "msr cpsr_c, %1"
  38744. + : "=r" (old), "=r" (temp)
  38745. + :
  38746. + : "memory");
  38747. +
  38748. + /* Set SoC in power save */
  38749. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, BIT11);
  38750. + /* Wait for int */
  38751. + __asm__ __volatile__("mcr p15, 0, r0, c7, c0, 4");
  38752. +
  38753. + /* Enabled int */
  38754. + __asm__ __volatile__("msr cpsr_c, %0"
  38755. + :
  38756. + : "r" (old)
  38757. + : "memory");
  38758. +}
  38759. +
  38760. +/*******************************************************************************
  38761. +* mvCtrlPwrClckSet - Set Power State for specific Unit
  38762. +*
  38763. +* DESCRIPTION:
  38764. +*
  38765. +* INPUT:
  38766. +*
  38767. +* OUTPUT:
  38768. +*
  38769. +* RETURN:
  38770. +*******************************************************************************/
  38771. +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)
  38772. +{
  38773. + switch (unitId)
  38774. + {
  38775. +#if defined(MV_INCLUDE_PEX)
  38776. + case PEX_UNIT_ID:
  38777. + if (enable == MV_FALSE)
  38778. + {
  38779. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
  38780. + }
  38781. + else
  38782. + {
  38783. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
  38784. + }
  38785. + break;
  38786. +#endif
  38787. +#if defined(MV_INCLUDE_GIG_ETH)
  38788. + case ETH_GIG_UNIT_ID:
  38789. + if (enable == MV_FALSE)
  38790. + {
  38791. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
  38792. + }
  38793. + else
  38794. + {
  38795. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
  38796. + }
  38797. + break;
  38798. +#endif
  38799. +#if defined(MV_INCLUDE_INTEG_SATA)
  38800. + case SATA_UNIT_ID:
  38801. + if (enable == MV_FALSE)
  38802. + {
  38803. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));
  38804. + }
  38805. + else
  38806. + {
  38807. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));
  38808. + }
  38809. + break;
  38810. +#endif
  38811. +#if defined(MV_INCLUDE_CESA)
  38812. + case CESA_UNIT_ID:
  38813. + if (enable == MV_FALSE)
  38814. + {
  38815. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);
  38816. + }
  38817. + else
  38818. + {
  38819. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);
  38820. + }
  38821. + break;
  38822. +#endif
  38823. +#if defined(MV_INCLUDE_USB)
  38824. + case USB_UNIT_ID:
  38825. + if (enable == MV_FALSE)
  38826. + {
  38827. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);
  38828. + }
  38829. + else
  38830. + {
  38831. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);
  38832. + }
  38833. + break;
  38834. +#endif
  38835. +#if defined(MV_INCLUDE_AUDIO)
  38836. + case AUDIO_UNIT_ID:
  38837. + if (enable == MV_FALSE)
  38838. + {
  38839. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);
  38840. + }
  38841. + else
  38842. + {
  38843. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);
  38844. + }
  38845. + break;
  38846. +#endif
  38847. +#if defined(MV_INCLUDE_TS)
  38848. + case TS_UNIT_ID:
  38849. + if (enable == MV_FALSE)
  38850. + {
  38851. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);
  38852. + }
  38853. + else
  38854. + {
  38855. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);
  38856. + }
  38857. + break;
  38858. +#endif
  38859. +#if defined(MV_INCLUDE_SDIO)
  38860. + case SDIO_UNIT_ID:
  38861. + if (enable == MV_FALSE)
  38862. + {
  38863. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
  38864. + }
  38865. + else
  38866. + {
  38867. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
  38868. + }
  38869. + break;
  38870. +#endif
  38871. +#if defined(MV_INCLUDE_TDM)
  38872. + case TDM_UNIT_ID:
  38873. + if (enable == MV_FALSE)
  38874. + {
  38875. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);
  38876. + }
  38877. + else
  38878. + {
  38879. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);
  38880. + }
  38881. + break;
  38882. +#endif
  38883. +
  38884. + default:
  38885. +
  38886. + break;
  38887. +
  38888. + }
  38889. +}
  38890. +
  38891. +/*******************************************************************************
  38892. +* mvCtrlPwrClckGet - Get Power State of specific Unit
  38893. +*
  38894. +* DESCRIPTION:
  38895. +*
  38896. +* INPUT:
  38897. +*
  38898. +* OUTPUT:
  38899. +*
  38900. +* RETURN:
  38901. +******************************************************************************/
  38902. +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index)
  38903. +{
  38904. + MV_U32 reg = MV_REG_READ(POWER_MNG_CTRL_REG);
  38905. + MV_BOOL state = MV_TRUE;
  38906. +
  38907. + switch (unitId)
  38908. + {
  38909. +#if defined(MV_INCLUDE_PEX)
  38910. + case PEX_UNIT_ID:
  38911. + if ((reg & PMC_PEXSTOPCLOCK_MASK) == PMC_PEXSTOPCLOCK_STOP)
  38912. + {
  38913. + state = MV_FALSE;
  38914. + }
  38915. + else state = MV_TRUE;
  38916. +
  38917. + break;
  38918. +#endif
  38919. +#if defined(MV_INCLUDE_GIG_ETH)
  38920. + case ETH_GIG_UNIT_ID:
  38921. + if ((reg & PMC_GESTOPCLOCK_MASK(index)) == PMC_GESTOPCLOCK_STOP(index))
  38922. + {
  38923. + state = MV_FALSE;
  38924. + }
  38925. + else state = MV_TRUE;
  38926. + break;
  38927. +#endif
  38928. +#if defined(MV_INCLUDE_SATA)
  38929. + case SATA_UNIT_ID:
  38930. + if ((reg & PMC_SATASTOPCLOCK_MASK(index)) == PMC_SATASTOPCLOCK_STOP(index))
  38931. + {
  38932. + state = MV_FALSE;
  38933. + }
  38934. + else state = MV_TRUE;
  38935. + break;
  38936. +#endif
  38937. +#if defined(MV_INCLUDE_CESA)
  38938. + case CESA_UNIT_ID:
  38939. + if ((reg & PMC_SESTOPCLOCK_MASK) == PMC_SESTOPCLOCK_STOP)
  38940. + {
  38941. + state = MV_FALSE;
  38942. + }
  38943. + else state = MV_TRUE;
  38944. + break;
  38945. +#endif
  38946. +#if defined(MV_INCLUDE_USB)
  38947. + case USB_UNIT_ID:
  38948. + if ((reg & PMC_USBSTOPCLOCK_MASK) == PMC_USBSTOPCLOCK_STOP)
  38949. + {
  38950. + state = MV_FALSE;
  38951. + }
  38952. + else state = MV_TRUE;
  38953. + break;
  38954. +#endif
  38955. +#if defined(MV_INCLUDE_AUDIO)
  38956. + case AUDIO_UNIT_ID:
  38957. + if ((reg & PMC_AUDIOSTOPCLOCK_MASK) == PMC_AUDIOSTOPCLOCK_STOP)
  38958. + {
  38959. + state = MV_FALSE;
  38960. + }
  38961. + else state = MV_TRUE;
  38962. + break;
  38963. +#endif
  38964. +#if defined(MV_INCLUDE_TS)
  38965. + case TS_UNIT_ID:
  38966. + if ((reg & PMC_TSSTOPCLOCK_MASK) == PMC_TSSTOPCLOCK_STOP)
  38967. + {
  38968. + state = MV_FALSE;
  38969. + }
  38970. + else state = MV_TRUE;
  38971. + break;
  38972. +#endif
  38973. +#if defined(MV_INCLUDE_SDIO)
  38974. + case SDIO_UNIT_ID:
  38975. + if ((reg & PMC_SDIOSTOPCLOCK_MASK)== PMC_SDIOSTOPCLOCK_STOP)
  38976. + {
  38977. + state = MV_FALSE;
  38978. + }
  38979. + else state = MV_TRUE;
  38980. + break;
  38981. +#endif
  38982. +#if defined(MV_INCLUDE_TDM)
  38983. + case TDM_UNIT_ID:
  38984. + if ((reg & PMC_TDMSTOPCLOCK_MASK) == PMC_TDMSTOPCLOCK_STOP)
  38985. + {
  38986. + state = MV_FALSE;
  38987. + }
  38988. + else state = MV_TRUE;
  38989. + break;
  38990. +#endif
  38991. +
  38992. + default:
  38993. + state = MV_TRUE;
  38994. + break;
  38995. + }
  38996. +
  38997. +
  38998. + return state;
  38999. +}
  39000. +/*******************************************************************************
  39001. +* mvCtrlPwrMemSet - Set Power State for memory on specific Unit
  39002. +*
  39003. +* DESCRIPTION:
  39004. +*
  39005. +* INPUT:
  39006. +*
  39007. +* OUTPUT:
  39008. +*
  39009. +* RETURN:
  39010. +*******************************************************************************/
  39011. +MV_VOID mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)
  39012. +{
  39013. + switch (unitId)
  39014. + {
  39015. +#if defined(MV_INCLUDE_PEX)
  39016. + case PEX_UNIT_ID:
  39017. + if (enable == MV_FALSE)
  39018. + {
  39019. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);
  39020. + }
  39021. + else
  39022. + {
  39023. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);
  39024. + }
  39025. + break;
  39026. +#endif
  39027. +#if defined(MV_INCLUDE_GIG_ETH)
  39028. + case ETH_GIG_UNIT_ID:
  39029. + if (enable == MV_FALSE)
  39030. + {
  39031. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));
  39032. + }
  39033. + else
  39034. + {
  39035. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));
  39036. + }
  39037. + break;
  39038. +#endif
  39039. +#if defined(MV_INCLUDE_INTEG_SATA)
  39040. + case SATA_UNIT_ID:
  39041. + if (enable == MV_FALSE)
  39042. + {
  39043. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));
  39044. + }
  39045. + else
  39046. + {
  39047. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));
  39048. + }
  39049. + break;
  39050. +#endif
  39051. +#if defined(MV_INCLUDE_CESA)
  39052. + case CESA_UNIT_ID:
  39053. + if (enable == MV_FALSE)
  39054. + {
  39055. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);
  39056. + }
  39057. + else
  39058. + {
  39059. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);
  39060. + }
  39061. + break;
  39062. +#endif
  39063. +#if defined(MV_INCLUDE_USB)
  39064. + case USB_UNIT_ID:
  39065. + if (enable == MV_FALSE)
  39066. + {
  39067. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);
  39068. + }
  39069. + else
  39070. + {
  39071. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);
  39072. + }
  39073. + break;
  39074. +#endif
  39075. +#if defined(MV_INCLUDE_AUDIO)
  39076. + case AUDIO_UNIT_ID:
  39077. + if (enable == MV_FALSE)
  39078. + {
  39079. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);
  39080. + }
  39081. + else
  39082. + {
  39083. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);
  39084. + }
  39085. + break;
  39086. +#endif
  39087. +#if defined(MV_INCLUDE_XOR)
  39088. + case XOR_UNIT_ID:
  39089. + if (enable == MV_FALSE)
  39090. + {
  39091. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));
  39092. + }
  39093. + else
  39094. + {
  39095. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));
  39096. + }
  39097. + break;
  39098. +#endif
  39099. + default:
  39100. +
  39101. + break;
  39102. +
  39103. + }
  39104. +}
  39105. +
  39106. +/*******************************************************************************
  39107. +* mvCtrlPwrMemGet - Get Power State of memory on specific Unit
  39108. +*
  39109. +* DESCRIPTION:
  39110. +*
  39111. +* INPUT:
  39112. +*
  39113. +* OUTPUT:
  39114. +*
  39115. +* RETURN:
  39116. +******************************************************************************/
  39117. +MV_BOOL mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index)
  39118. +{
  39119. + MV_U32 reg = MV_REG_READ(POWER_MNG_MEM_CTRL_REG);
  39120. + MV_BOOL state = MV_TRUE;
  39121. +
  39122. + switch (unitId)
  39123. + {
  39124. +#if defined(MV_INCLUDE_PEX)
  39125. + case PEX_UNIT_ID:
  39126. + if ((reg & PMC_PEXSTOPMEM_MASK) == PMC_PEXSTOPMEM_STOP)
  39127. + {
  39128. + state = MV_FALSE;
  39129. + }
  39130. + else state = MV_TRUE;
  39131. +
  39132. + break;
  39133. +#endif
  39134. +#if defined(MV_INCLUDE_GIG_ETH)
  39135. + case ETH_GIG_UNIT_ID:
  39136. + if ((reg & PMC_GESTOPMEM_MASK(index)) == PMC_GESTOPMEM_STOP(index))
  39137. + {
  39138. + state = MV_FALSE;
  39139. + }
  39140. + else state = MV_TRUE;
  39141. + break;
  39142. +#endif
  39143. +#if defined(MV_INCLUDE_SATA)
  39144. + case SATA_UNIT_ID:
  39145. + if ((reg & PMC_SATASTOPMEM_MASK(index)) == PMC_SATASTOPMEM_STOP(index))
  39146. + {
  39147. + state = MV_FALSE;
  39148. + }
  39149. + else state = MV_TRUE;
  39150. + break;
  39151. +#endif
  39152. +#if defined(MV_INCLUDE_CESA)
  39153. + case CESA_UNIT_ID:
  39154. + if ((reg & PMC_SESTOPMEM_MASK) == PMC_SESTOPMEM_STOP)
  39155. + {
  39156. + state = MV_FALSE;
  39157. + }
  39158. + else state = MV_TRUE;
  39159. + break;
  39160. +#endif
  39161. +#if defined(MV_INCLUDE_USB)
  39162. + case USB_UNIT_ID:
  39163. + if ((reg & PMC_USBSTOPMEM_MASK) == PMC_USBSTOPMEM_STOP)
  39164. + {
  39165. + state = MV_FALSE;
  39166. + }
  39167. + else state = MV_TRUE;
  39168. + break;
  39169. +#endif
  39170. +#if defined(MV_INCLUDE_AUDIO)
  39171. + case AUDIO_UNIT_ID:
  39172. + if ((reg & PMC_AUDIOSTOPMEM_MASK) == PMC_AUDIOSTOPMEM_STOP)
  39173. + {
  39174. + state = MV_FALSE;
  39175. + }
  39176. + else state = MV_TRUE;
  39177. + break;
  39178. +#endif
  39179. +#if defined(MV_INCLUDE_XOR)
  39180. + case XOR_UNIT_ID:
  39181. + if ((reg & PMC_XORSTOPMEM_MASK(index)) == PMC_XORSTOPMEM_STOP(index))
  39182. + {
  39183. + state = MV_FALSE;
  39184. + }
  39185. + else state = MV_TRUE;
  39186. + break;
  39187. +#endif
  39188. +
  39189. + default:
  39190. + state = MV_TRUE;
  39191. + break;
  39192. + }
  39193. +
  39194. +
  39195. + return state;
  39196. +}
  39197. +#else
  39198. +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable) {return;}
  39199. +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index) {return MV_TRUE;}
  39200. +#endif /* #if defined(MV_INCLUDE_CLK_PWR_CNTRL) */
  39201. +
  39202. +
  39203. +/*******************************************************************************
  39204. +* mvMPPConfigToSPI - Change MPP[3:0] configuration to SPI mode
  39205. +*
  39206. +* DESCRIPTION:
  39207. +*
  39208. +* INPUT:
  39209. +*
  39210. +* OUTPUT:
  39211. +*
  39212. +* RETURN:
  39213. +******************************************************************************/
  39214. +MV_VOID mvMPPConfigToSPI(MV_VOID)
  39215. +{
  39216. + MV_U32 mppVal = 0;
  39217. + MV_U32 bootVal = 0;
  39218. +
  39219. + if(!mvCtrlIsBootFromSPIUseNAND())
  39220. + return;
  39221. + mppVal = 0x00002220; /* Set MPP [3:1] to SPI mode */
  39222. + bootVal = MV_REG_READ(mvCtrlMppRegGet(0));
  39223. + bootVal &= 0xffff000f;
  39224. + mppVal |= bootVal;
  39225. +
  39226. + MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);
  39227. +}
  39228. +
  39229. +
  39230. +/*******************************************************************************
  39231. +* mvMPPConfigToDefault - Change MPP[7:0] configuration to default configuration
  39232. +*
  39233. +* DESCRIPTION:
  39234. +*
  39235. +* INPUT:
  39236. +*
  39237. +* OUTPUT:
  39238. +*
  39239. +* RETURN:
  39240. +******************************************************************************/
  39241. +MV_VOID mvMPPConfigToDefault(MV_VOID)
  39242. +{
  39243. + MV_U32 mppVal = 0;
  39244. + MV_U32 bootVal = 0;
  39245. +
  39246. + if(!mvCtrlIsBootFromSPIUseNAND())
  39247. + return;
  39248. + mppVal = mvBoardMppGet(0);
  39249. + bootVal = MV_REG_READ(mvCtrlMppRegGet(0));
  39250. + mppVal &= ~0xffff000f;
  39251. + bootVal &= 0xffff000f;
  39252. + mppVal |= bootVal;
  39253. +
  39254. + MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);
  39255. +}
  39256. +
  39257. +
  39258. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h
  39259. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h 1970-01-01 01:00:00.000000000 +0100
  39260. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h 2011-07-31 11:31:56.927164968 +0200
  39261. @@ -0,0 +1,185 @@
  39262. +/*******************************************************************************
  39263. +Copyright (C) Marvell International Ltd. and its affiliates
  39264. +
  39265. +This software file (the "File") is owned and distributed by Marvell
  39266. +International Ltd. and/or its affiliates ("Marvell") under the following
  39267. +alternative licensing terms. Once you have made an election to distribute the
  39268. +File under one of the following license alternatives, please (i) delete this
  39269. +introductory statement regarding license alternatives, (ii) delete the two
  39270. +license alternatives that you have not elected to use and (iii) preserve the
  39271. +Marvell copyright notice above.
  39272. +
  39273. +********************************************************************************
  39274. +Marvell Commercial License Option
  39275. +
  39276. +If you received this File from Marvell and you have entered into a commercial
  39277. +license agreement (a "Commercial License") with Marvell, the File is licensed
  39278. +to you under the terms of the applicable Commercial License.
  39279. +
  39280. +********************************************************************************
  39281. +Marvell GPL License Option
  39282. +
  39283. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39284. +modify this File in accordance with the terms and conditions of the General
  39285. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  39286. +available along with the File in the license.txt file or by writing to the Free
  39287. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  39288. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  39289. +
  39290. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  39291. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  39292. +DISCLAIMED. The GPL License provides additional details about this warranty
  39293. +disclaimer.
  39294. +********************************************************************************
  39295. +Marvell BSD License Option
  39296. +
  39297. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39298. +modify this File under the following licensing terms.
  39299. +Redistribution and use in source and binary forms, with or without modification,
  39300. +are permitted provided that the following conditions are met:
  39301. +
  39302. + * Redistributions of source code must retain the above copyright notice,
  39303. + this list of conditions and the following disclaimer.
  39304. +
  39305. + * Redistributions in binary form must reproduce the above copyright
  39306. + notice, this list of conditions and the following disclaimer in the
  39307. + documentation and/or other materials provided with the distribution.
  39308. +
  39309. + * Neither the name of Marvell nor the names of its contributors may be
  39310. + used to endorse or promote products derived from this software without
  39311. + specific prior written permission.
  39312. +
  39313. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  39314. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  39315. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39316. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  39317. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  39318. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  39319. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  39320. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  39321. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  39322. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39323. +
  39324. +*******************************************************************************/
  39325. +
  39326. +
  39327. +#ifndef __INCmvCtrlEnvLibh
  39328. +#define __INCmvCtrlEnvLibh
  39329. +
  39330. +/* includes */
  39331. +#include "mvSysHwConfig.h"
  39332. +#include "mvCommon.h"
  39333. +#include "mvTypes.h"
  39334. +#include "mvOs.h"
  39335. +#include "boardEnv/mvBoardEnvLib.h"
  39336. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  39337. +#include "ctrlEnv/mvCtrlEnvRegs.h"
  39338. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  39339. +
  39340. +
  39341. +/* typedefs */
  39342. +
  39343. +/* This enumerator describes the possible HW cache coherency policies the */
  39344. +/* controllers supports. */
  39345. +typedef enum _mvCachePolicy
  39346. +{
  39347. + NO_COHERENCY, /* No HW cache coherency support */
  39348. + WT_COHERENCY, /* HW cache coherency supported in Write Through policy */
  39349. + WB_COHERENCY /* HW cache coherency supported in Write Back policy */
  39350. +}MV_CACHE_POLICY;
  39351. +
  39352. +
  39353. +/* The swapping is referred to a 64-bit words (as this is the controller */
  39354. +/* internal data path width). This enumerator describes the possible */
  39355. +/* data swap types. Below is an example of the data 0x0011223344556677 */
  39356. +typedef enum _mvSwapType
  39357. +{
  39358. + MV_BYTE_SWAP, /* Byte Swap 77 66 55 44 33 22 11 00 */
  39359. + MV_NO_SWAP, /* No swapping 00 11 22 33 44 55 66 77 */
  39360. + MV_BYTE_WORD_SWAP, /* Both byte and word swap 33 22 11 00 77 66 55 44 */
  39361. + MV_WORD_SWAP, /* Word swap 44 55 66 77 00 11 22 33 */
  39362. + SWAP_TYPE_MAX /* Delimiter for this enumerator */
  39363. +}MV_SWAP_TYPE;
  39364. +
  39365. +/* This structure describes access rights for Access protection windows */
  39366. +/* that can be found in IDMA, XOR, Ethernet and MPSC units. */
  39367. +/* Note that the permission enumerator coresponds to its register format. */
  39368. +/* For example, Read only premission is presented as "1" in register field. */
  39369. +typedef enum _mvAccessRights
  39370. +{
  39371. + NO_ACCESS_ALLOWED = 0, /* No access allowed */
  39372. + READ_ONLY = 1, /* Read only permission */
  39373. + ACC_RESERVED = 2, /* Reserved access right */
  39374. + FULL_ACCESS = 3, /* Read and Write permission */
  39375. + MAX_ACC_RIGHTS
  39376. +}MV_ACCESS_RIGHTS;
  39377. +
  39378. +
  39379. +/* mcspLib.h API list */
  39380. +
  39381. +MV_STATUS mvCtrlEnvInit(MV_VOID);
  39382. +MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup);
  39383. +
  39384. +#if defined(MV_INCLUDE_PEX)
  39385. +MV_U32 mvCtrlPexMaxIfGet(MV_VOID);
  39386. +#else
  39387. +#define mvCtrlPexMaxIfGet() (0)
  39388. +#endif
  39389. +
  39390. +#define mvCtrlPciIfMaxIfGet() (0)
  39391. +
  39392. +#if defined(MV_INCLUDE_GIG_ETH)
  39393. +MV_U32 mvCtrlEthMaxPortGet(MV_VOID);
  39394. +#endif
  39395. +#if defined(MV_INCLUDE_XOR)
  39396. +MV_U32 mvCtrlXorMaxChanGet(MV_VOID);
  39397. +#endif
  39398. +#if defined(MV_INCLUDE_USB)
  39399. +MV_U32 mvCtrlUsbMaxGet(MV_VOID);
  39400. +#endif
  39401. +#if defined(MV_INCLUDE_NAND)
  39402. +MV_U32 mvCtrlNandSupport(MV_VOID);
  39403. +#endif
  39404. +#if defined(MV_INCLUDE_SDIO)
  39405. +MV_U32 mvCtrlSdioSupport(MV_VOID);
  39406. +#endif
  39407. +#if defined(MV_INCLUDE_TS)
  39408. +MV_U32 mvCtrlTsSupport(MV_VOID);
  39409. +#endif
  39410. +#if defined(MV_INCLUDE_AUDIO)
  39411. +MV_U32 mvCtrlAudioSupport(MV_VOID);
  39412. +#endif
  39413. +#if defined(MV_INCLUDE_TDM)
  39414. +MV_U32 mvCtrlTdmSupport(MV_VOID);
  39415. +#endif
  39416. +
  39417. +MV_U16 mvCtrlModelGet(MV_VOID);
  39418. +MV_U8 mvCtrlRevGet(MV_VOID);
  39419. +MV_STATUS mvCtrlNameGet(char *pNameBuff);
  39420. +MV_U32 mvCtrlModelRevGet(MV_VOID);
  39421. +MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff);
  39422. +MV_VOID mvCtrlAddrDecShow(MV_VOID);
  39423. +const MV_8* mvCtrlTargetNameGet(MV_TARGET target);
  39424. +MV_U32 ctrlSizeToReg(MV_U32 size, MV_U32 alignment);
  39425. +MV_U32 ctrlRegToSize(MV_U32 regSize, MV_U32 alignment);
  39426. +MV_U32 ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment);
  39427. +MV_U32 mvCtrlSysRstLengthCounterGet(MV_VOID);
  39428. +MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);
  39429. +MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);
  39430. +
  39431. +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);
  39432. +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index);
  39433. +MV_VOID mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);
  39434. +MV_BOOL mvCtrlIsBootFromSPI(MV_VOID);
  39435. +MV_BOOL mvCtrlIsBootFromSPIUseNAND(MV_VOID);
  39436. +MV_BOOL mvCtrlIsBootFromNAND(MV_VOID);
  39437. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  39438. +MV_VOID mvCtrlPwrSaveOn(MV_VOID);
  39439. +MV_VOID mvCtrlPwrSaveOff(MV_VOID);
  39440. +#endif
  39441. +MV_BOOL mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index);
  39442. +MV_VOID mvMPPConfigToSPI(MV_VOID);
  39443. +MV_VOID mvMPPConfigToDefault(MV_VOID);
  39444. +
  39445. +
  39446. +#endif /* __INCmvCtrlEnvLibh */
  39447. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h
  39448. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h 1970-01-01 01:00:00.000000000 +0100
  39449. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h 2011-07-31 11:31:56.963763359 +0200
  39450. @@ -0,0 +1,419 @@
  39451. +/*******************************************************************************
  39452. +Copyright (C) Marvell International Ltd. and its affiliates
  39453. +
  39454. +This software file (the "File") is owned and distributed by Marvell
  39455. +International Ltd. and/or its affiliates ("Marvell") under the following
  39456. +alternative licensing terms. Once you have made an election to distribute the
  39457. +File under one of the following license alternatives, please (i) delete this
  39458. +introductory statement regarding license alternatives, (ii) delete the two
  39459. +license alternatives that you have not elected to use and (iii) preserve the
  39460. +Marvell copyright notice above.
  39461. +
  39462. +********************************************************************************
  39463. +Marvell Commercial License Option
  39464. +
  39465. +If you received this File from Marvell and you have entered into a commercial
  39466. +license agreement (a "Commercial License") with Marvell, the File is licensed
  39467. +to you under the terms of the applicable Commercial License.
  39468. +
  39469. +********************************************************************************
  39470. +Marvell GPL License Option
  39471. +
  39472. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39473. +modify this File in accordance with the terms and conditions of the General
  39474. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  39475. +available along with the File in the license.txt file or by writing to the Free
  39476. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  39477. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  39478. +
  39479. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  39480. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  39481. +DISCLAIMED. The GPL License provides additional details about this warranty
  39482. +disclaimer.
  39483. +********************************************************************************
  39484. +Marvell BSD License Option
  39485. +
  39486. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39487. +modify this File under the following licensing terms.
  39488. +Redistribution and use in source and binary forms, with or without modification,
  39489. +are permitted provided that the following conditions are met:
  39490. +
  39491. + * Redistributions of source code must retain the above copyright notice,
  39492. + this list of conditions and the following disclaimer.
  39493. +
  39494. + * Redistributions in binary form must reproduce the above copyright
  39495. + notice, this list of conditions and the following disclaimer in the
  39496. + documentation and/or other materials provided with the distribution.
  39497. +
  39498. + * Neither the name of Marvell nor the names of its contributors may be
  39499. + used to endorse or promote products derived from this software without
  39500. + specific prior written permission.
  39501. +
  39502. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  39503. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  39504. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39505. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  39506. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  39507. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  39508. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  39509. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  39510. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  39511. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39512. +
  39513. +*******************************************************************************/
  39514. +
  39515. +#ifndef __INCmvCtrlEnvRegsh
  39516. +#define __INCmvCtrlEnvRegsh
  39517. +
  39518. +#ifdef __cplusplus
  39519. +extern "C" {
  39520. +#endif /* __cplusplus */
  39521. +
  39522. +/* CV Support */
  39523. +#define PEX0_MEM0 PEX0_MEM
  39524. +#define PCI0_MEM0 PEX0_MEM
  39525. +
  39526. +/* Controller revision info */
  39527. +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008
  39528. +#define PCCRIR_REVID_OFFS 0 /* Revision ID */
  39529. +#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS)
  39530. +
  39531. +/* Controler environment registers offsets */
  39532. +
  39533. +/* Power Managment Control */
  39534. +#define POWER_MNG_MEM_CTRL_REG 0x20118
  39535. +
  39536. +#define PMC_GESTOPMEM_OFFS(port) ((port)? 13 : 0)
  39537. +#define PMC_GESTOPMEM_MASK(port) (1 << PMC_GESTOPMEM_OFFS(port))
  39538. +#define PMC_GESTOPMEM_EN(port) (0 << PMC_GESTOPMEM_OFFS(port))
  39539. +#define PMC_GESTOPMEM_STOP(port) (1 << PMC_GESTOPMEM_OFFS(port))
  39540. +
  39541. +#define PMC_PEXSTOPMEM_OFFS 1
  39542. +#define PMC_PEXSTOPMEM_MASK (1 << PMC_PEXSTOPMEM_OFFS)
  39543. +#define PMC_PEXSTOPMEM_EN (0 << PMC_PEXSTOPMEM_OFFS)
  39544. +#define PMC_PEXSTOPMEM_STOP (1 << PMC_PEXSTOPMEM_OFFS)
  39545. +
  39546. +#define PMC_USBSTOPMEM_OFFS 2
  39547. +#define PMC_USBSTOPMEM_MASK (1 << PMC_USBSTOPMEM_OFFS)
  39548. +#define PMC_USBSTOPMEM_EN (0 << PMC_USBSTOPMEM_OFFS)
  39549. +#define PMC_USBSTOPMEM_STOP (1 << PMC_USBSTOPMEM_OFFS)
  39550. +
  39551. +#define PMC_DUNITSTOPMEM_OFFS 3
  39552. +#define PMC_DUNITSTOPMEM_MASK (1 << PMC_DUNITSTOPMEM_OFFS)
  39553. +#define PMC_DUNITSTOPMEM_EN (0 << PMC_DUNITSTOPMEM_OFFS)
  39554. +#define PMC_DUNITSTOPMEM_STOP (1 << PMC_DUNITSTOPMEM_OFFS)
  39555. +
  39556. +#define PMC_RUNITSTOPMEM_OFFS 4
  39557. +#define PMC_RUNITSTOPMEM_MASK (1 << PMC_RUNITSTOPMEM_OFFS)
  39558. +#define PMC_RUNITSTOPMEM_EN (0 << PMC_RUNITSTOPMEM_OFFS)
  39559. +#define PMC_RUNITSTOPMEM_STOP (1 << PMC_RUNITSTOPMEM_OFFS)
  39560. +
  39561. +#define PMC_XORSTOPMEM_OFFS(port) (5+(port*2))
  39562. +#define PMC_XORSTOPMEM_MASK(port) (1 << PMC_XORSTOPMEM_OFFS(port))
  39563. +#define PMC_XORSTOPMEM_EN(port) (0 << PMC_XORSTOPMEM_OFFS(port))
  39564. +#define PMC_XORSTOPMEM_STOP(port) (1 << PMC_XORSTOPMEM_OFFS(port))
  39565. +
  39566. +#define PMC_SATASTOPMEM_OFFS(port) (6+(port*5))
  39567. +#define PMC_SATASTOPMEM_MASK(port) (1 << PMC_SATASTOPMEM_OFFS(port))
  39568. +#define PMC_SATASTOPMEM_EN(port) (0 << PMC_SATASTOPMEM_OFFS(port))
  39569. +#define PMC_SATASTOPMEM_STOP(port) (1 << PMC_SATASTOPMEM_OFFS(port))
  39570. +
  39571. +#define PMC_SESTOPMEM_OFFS 8
  39572. +#define PMC_SESTOPMEM_MASK (1 << PMC_SESTOPMEM_OFFS)
  39573. +#define PMC_SESTOPMEM_EN (0 << PMC_SESTOPMEM_OFFS)
  39574. +#define PMC_SESTOPMEM_STOP (1 << PMC_SESTOPMEM_OFFS)
  39575. +
  39576. +#define PMC_AUDIOSTOPMEM_OFFS 9
  39577. +#define PMC_AUDIOSTOPMEM_MASK (1 << PMC_AUDIOSTOPMEM_OFFS)
  39578. +#define PMC_AUDIOSTOPMEM_EN (0 << PMC_AUDIOSTOPMEM_OFFS)
  39579. +#define PMC_AUDIOSTOPMEM_STOP (1 << PMC_AUDIOSTOPMEM_OFFS)
  39580. +
  39581. +#define POWER_MNG_CTRL_REG 0x2011C
  39582. +
  39583. +#define PMC_GESTOPCLOCK_OFFS(port) ((port)? 19 : 0)
  39584. +#define PMC_GESTOPCLOCK_MASK(port) (1 << PMC_GESTOPCLOCK_OFFS(port))
  39585. +#define PMC_GESTOPCLOCK_EN(port) (1 << PMC_GESTOPCLOCK_OFFS(port))
  39586. +#define PMC_GESTOPCLOCK_STOP(port) (0 << PMC_GESTOPCLOCK_OFFS(port))
  39587. +
  39588. +#define PMC_PEXPHYSTOPCLOCK_OFFS 1
  39589. +#define PMC_PEXPHYSTOPCLOCK_MASK (1 << PMC_PEXPHYSTOPCLOCK_OFFS)
  39590. +#define PMC_PEXPHYSTOPCLOCK_EN (1 << PMC_PEXPHYSTOPCLOCK_OFFS)
  39591. +#define PMC_PEXPHYSTOPCLOCK_STOP (0 << PMC_PEXPHYSTOPCLOCK_OFFS)
  39592. +
  39593. +#define PMC_PEXSTOPCLOCK_OFFS 2
  39594. +#define PMC_PEXSTOPCLOCK_MASK (1 << PMC_PEXSTOPCLOCK_OFFS)
  39595. +#define PMC_PEXSTOPCLOCK_EN (1 << PMC_PEXSTOPCLOCK_OFFS)
  39596. +#define PMC_PEXSTOPCLOCK_STOP (0 << PMC_PEXSTOPCLOCK_OFFS)
  39597. +
  39598. +#define PMC_USBSTOPCLOCK_OFFS 3
  39599. +#define PMC_USBSTOPCLOCK_MASK (1 << PMC_USBSTOPCLOCK_OFFS)
  39600. +#define PMC_USBSTOPCLOCK_EN (1 << PMC_USBSTOPCLOCK_OFFS)
  39601. +#define PMC_USBSTOPCLOCK_STOP (0 << PMC_USBSTOPCLOCK_OFFS)
  39602. +
  39603. +#define PMC_SDIOSTOPCLOCK_OFFS 4
  39604. +#define PMC_SDIOSTOPCLOCK_MASK (1 << PMC_SDIOSTOPCLOCK_OFFS)
  39605. +#define PMC_SDIOSTOPCLOCK_EN (1 << PMC_SDIOSTOPCLOCK_OFFS)
  39606. +#define PMC_SDIOSTOPCLOCK_STOP (0 << PMC_SDIOSTOPCLOCK_OFFS)
  39607. +
  39608. +#define PMC_TSSTOPCLOCK_OFFS 5
  39609. +#define PMC_TSSTOPCLOCK_MASK (1 << PMC_TSSTOPCLOCK_OFFS)
  39610. +#define PMC_TSSTOPCLOCK_EN (1 << PMC_TSSTOPCLOCK_OFFS)
  39611. +#define PMC_TSSTOPCLOCK_STOP (0 << PMC_TSSTOPCLOCK_OFFS)
  39612. +
  39613. +#define PMC_AUDIOSTOPCLOCK_OFFS 9
  39614. +#define PMC_AUDIOSTOPCLOCK_MASK (1 << PMC_AUDIOSTOPCLOCK_OFFS)
  39615. +#define PMC_AUDIOSTOPCLOCK_EN (1 << PMC_AUDIOSTOPCLOCK_OFFS)
  39616. +#define PMC_AUDIOSTOPCLOCK_STOP (0 << PMC_AUDIOSTOPCLOCK_OFFS)
  39617. +
  39618. +#define PMC_POWERSAVE_OFFS 11
  39619. +#define PMC_POWERSAVE_MASK (1 << PMC_POWERSAVE_OFFS)
  39620. +#define PMC_POWERSAVE_EN (1 << PMC_POWERSAVE_OFFS)
  39621. +#define PMC_POWERSAVE_STOP (0 << PMC_POWERSAVE_OFFS)
  39622. +
  39623. +
  39624. +
  39625. +
  39626. +#define PMC_SATASTOPCLOCK_OFFS(port) (14+(port))
  39627. +#define PMC_SATASTOPCLOCK_MASK(port) (1 << PMC_SATASTOPCLOCK_OFFS(port))
  39628. +#define PMC_SATASTOPCLOCK_EN(port) (1 << PMC_SATASTOPCLOCK_OFFS(port))
  39629. +#define PMC_SATASTOPCLOCK_STOP(port) (0 << PMC_SATASTOPCLOCK_OFFS(port))
  39630. +
  39631. +#define PMC_SESTOPCLOCK_OFFS 17
  39632. +#define PMC_SESTOPCLOCK_MASK (1 << PMC_SESTOPCLOCK_OFFS)
  39633. +#define PMC_SESTOPCLOCK_EN (1 << PMC_SESTOPCLOCK_OFFS)
  39634. +#define PMC_SESTOPCLOCK_STOP (0 << PMC_SESTOPCLOCK_OFFS)
  39635. +
  39636. +#define PMC_TDMSTOPCLOCK_OFFS 20
  39637. +#define PMC_TDMSTOPCLOCK_MASK (1 << PMC_TDMSTOPCLOCK_OFFS)
  39638. +#define PMC_TDMSTOPCLOCK_EN (1 << PMC_TDMSTOPCLOCK_OFFS)
  39639. +#define PMC_TDMSTOPCLOCK_STOP (0 << PMC_TDMSTOPCLOCK_OFFS)
  39640. +
  39641. +
  39642. +/* Controler environment registers offsets */
  39643. +#define MPP_CONTROL_REG0 0x10000
  39644. +#define MPP_CONTROL_REG1 0x10004
  39645. +#define MPP_CONTROL_REG2 0x10008
  39646. +#define MPP_CONTROL_REG3 0x1000C
  39647. +#define MPP_CONTROL_REG4 0x10010
  39648. +#define MPP_CONTROL_REG5 0x10014
  39649. +#define MPP_CONTROL_REG6 0x10018
  39650. +#define MPP_SAMPLE_AT_RESET 0x10030
  39651. +#define CHIP_BOND_REG 0x10034
  39652. +#define SYSRST_LENGTH_COUNTER_REG 0x10050
  39653. +#define SLCR_COUNT_OFFS 0
  39654. +#define SLCR_COUNT_MASK (0x1FFFFFFF << SLCR_COUNT_OFFS)
  39655. +#define SLCR_CLR_OFFS 31
  39656. +#define SLCR_CLR_MASK (1 << SLCR_CLR_OFFS)
  39657. +#define PCKG_OPT_MASK 0x3
  39658. +#define MPP_OUTPUT_DRIVE_REG 0x100E0
  39659. +#define MPP_RGMII0_OUTPUT_DRIVE_OFFS 7
  39660. +#define MPP_3_3_RGMII0_OUTPUT_DRIVE (0x0 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)
  39661. +#define MPP_1_8_RGMII0_OUTPUT_DRIVE (0x1 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)
  39662. +#define MPP_RGMII1_OUTPUT_DRIVE_OFFS 15
  39663. +#define MPP_3_3_RGMII1_OUTPUT_DRIVE (0x0 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)
  39664. +#define MPP_1_8_RGMII1_OUTPUT_DRIVE (0x1 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)
  39665. +
  39666. +#define MSAR_BOOT_MODE_OFFS 12
  39667. +#define MSAR_BOOT_MODE_MASK (0x7 << MSAR_BOOT_MODE_OFFS)
  39668. +#define MSAR_BOOT_NAND_WITH_BOOTROM (0x5 << MSAR_BOOT_MODE_OFFS)
  39669. +#define MSAR_BOOT_SPI_WITH_BOOTROM (0x4 << MSAR_BOOT_MODE_OFFS)
  39670. +#define MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM (0x2 << MSAR_BOOT_MODE_OFFS)
  39671. +
  39672. +#define MSAR_BOOT_MODE_6180(X) (((X & 0x3000) >> 12) | \
  39673. + ((X & 0x2) << 1))
  39674. +#define MSAR_BOOT_SPI_WITH_BOOTROM_6180 0x1
  39675. +#define MSAR_BOOT_NAND_WITH_BOOTROM_6180 0x5
  39676. +
  39677. +#define MSAR_TCLCK_OFFS 21
  39678. +#define MSAR_TCLCK_MASK (0x1 << MSAR_TCLCK_OFFS)
  39679. +#define MSAR_TCLCK_166 (0x1 << MSAR_TCLCK_OFFS)
  39680. +#define MSAR_TCLCK_200 (0x0 << MSAR_TCLCK_OFFS)
  39681. +
  39682. +
  39683. +#define MSAR_CPUCLCK_EXTRACT(X) (((X & 0x2) >> 1) | ((X & 0x400000) >> 21) | \
  39684. + ((X & 0x18) >> 1))
  39685. +
  39686. +#define MSAR_CPUCLCK_OFFS_6180 2
  39687. +#define MSAR_CPUCLCK_MASK_6180 (0x7 << MSAR_CPUCLCK_OFFS_6180)
  39688. +
  39689. +#define MSAR_DDRCLCK_RTIO_OFFS 5
  39690. +#define MSAR_DDRCLCK_RTIO_MASK (0xF << MSAR_DDRCLCK_RTIO_OFFS)
  39691. +
  39692. +#define MSAR_L2CLCK_EXTRACT(X) (((X & 0x600) >> 9) | ((X & 0x80000) >> 17))
  39693. +
  39694. +#ifndef MV_ASMLANGUAGE
  39695. +/* CPU clock for 6281,6192 0->Resereved */
  39696. +#define MV_CPU_CLCK_TBL { 0, 0, 0, 0, \
  39697. + 600000000, 0, 800000000, 1000000000, \
  39698. + 0, 1200000000, 0, 0, \
  39699. + 1500000000, 0, 0, 0}
  39700. +
  39701. +/* DDR clock RATIO for 6281,6192 {0,0}->Reserved */
  39702. +#define MV_DDR_CLCK_RTIO_TBL {\
  39703. + {0, 0}, {0, 0}, {2, 1}, {0, 0}, \
  39704. + {3, 1}, {0, 0}, {4, 1}, {9, 2}, \
  39705. + {5, 1}, {6, 1}, {0, 0}, {0, 0}, \
  39706. + {0, 0}, {0, 0}, {0, 0}, {0, 0} \
  39707. +}
  39708. +
  39709. +/* L2 clock RATIO for 6281,6192 {1,1}->Reserved */
  39710. +#define MV_L2_CLCK_RTIO_TBL {\
  39711. + {0, 0}, {2, 1}, {0, 0}, {3, 1}, \
  39712. + {0, 0}, {0, 0}, {0, 0}, {0, 0} \
  39713. +}
  39714. +
  39715. +/* 6180 have different clk reset sampling */
  39716. +/* ARM CPU, DDR, L2 clock for 6180 {0,0,0}->Reserved */
  39717. +#define MV_CPU6180_DDR_L2_CLCK_TBL { \
  39718. + {0, 0, 0 },\
  39719. + {0, 0, 0 },\
  39720. + {0, 0, 0 },\
  39721. + {0, 0, 0 },\
  39722. + {0, 0, 0 },\
  39723. + {600000000, 200000000, 300000000 },\
  39724. + {800000000, 200000000, 400000000 },\
  39725. + {0, 0, 0 }\
  39726. +}
  39727. +
  39728. +
  39729. +
  39730. +/* These macros help units to identify a target Mbus Arbiter group */
  39731. +#define MV_TARGET_IS_DRAM(target) \
  39732. + ((target >= SDRAM_CS0) && (target <= SDRAM_CS3))
  39733. +
  39734. +#define MV_TARGET_IS_PEX0(target) \
  39735. + ((target >= PEX0_MEM) && (target <= PEX0_IO))
  39736. +
  39737. +#define MV_TARGET_IS_PEX1(target) 0
  39738. +
  39739. +#define MV_TARGET_IS_PEX(target) (MV_TARGET_IS_PEX0(target) || MV_TARGET_IS_PEX1(target))
  39740. +
  39741. +#define MV_TARGET_IS_DEVICE(target) \
  39742. + ((target >= DEVICE_CS0) && (target <= DEVICE_CS3))
  39743. +
  39744. +#define MV_PCI_DRAM_BAR_TO_DRAM_TARGET(bar) 0
  39745. +
  39746. +#define MV_TARGET_IS_AS_BOOT(target) ((target) == (sampleAtResetTargetArray[ \
  39747. + (mvCtrlModelGet() == MV_6180_DEV_ID)? MSAR_BOOT_MODE_6180 \
  39748. + (MV_REG_READ(MPP_SAMPLE_AT_RESET)):((MV_REG_READ(MPP_SAMPLE_AT_RESET)\
  39749. + & MSAR_BOOT_MODE_MASK) >> MSAR_BOOT_MODE_OFFS)]))
  39750. +
  39751. +
  39752. +#define MV_CHANGE_BOOT_CS(target) (((target) == DEV_BOOCS)?\
  39753. + sampleAtResetTargetArray[(mvCtrlModelGet() == MV_6180_DEV_ID)? \
  39754. + MSAR_BOOT_MODE_6180(MV_REG_READ(MPP_SAMPLE_AT_RESET)): \
  39755. + ((MV_REG_READ(MPP_SAMPLE_AT_RESET) & MSAR_BOOT_MODE_MASK)\
  39756. + >> MSAR_BOOT_MODE_OFFS)]:(target))
  39757. +
  39758. +#define TCLK_TO_COUNTER_RATIO 1 /* counters running in Tclk */
  39759. +
  39760. +#define BOOT_TARGETS_NAME_ARRAY { \
  39761. + TBL_TERM, \
  39762. + TBL_TERM, \
  39763. + BOOT_ROM_CS, \
  39764. + TBL_TERM, \
  39765. + BOOT_ROM_CS, \
  39766. + BOOT_ROM_CS, \
  39767. + TBL_TERM, \
  39768. + TBL_TERM \
  39769. +}
  39770. +
  39771. +#define BOOT_TARGETS_NAME_ARRAY_6180 { \
  39772. + TBL_TERM, \
  39773. + BOOT_ROM_CS, \
  39774. + TBL_TERM, \
  39775. + TBL_TERM, \
  39776. + TBL_TERM, \
  39777. + BOOT_ROM_CS, \
  39778. + TBL_TERM, \
  39779. + TBL_TERM \
  39780. +}
  39781. +
  39782. +
  39783. +/* For old competability */
  39784. +#define DEVICE_CS0 NFLASH_CS
  39785. +#define DEVICE_CS1 SPI_CS
  39786. +#define DEVICE_CS2 BOOT_ROM_CS
  39787. +#define DEVICE_CS3 DEV_BOOCS
  39788. +#define MV_BOOTDEVICE_INDEX 0
  39789. +
  39790. +#define START_DEV_CS DEV_CS0
  39791. +#define DEV_TO_TARGET(dev) ((dev) + DEVICE_CS0)
  39792. +
  39793. +#define PCI_IF0_MEM0 PEX0_MEM
  39794. +#define PCI_IF0_IO PEX0_IO
  39795. +
  39796. +
  39797. +/* This enumerator defines the Marvell controller target ID */
  39798. +typedef enum _mvTargetId
  39799. +{
  39800. + DRAM_TARGET_ID = 0 , /* Port 0 -> DRAM interface */
  39801. + DEV_TARGET_ID = 1, /* Port 1 -> Nand/SPI */
  39802. + PEX0_TARGET_ID = 4 , /* Port 4 -> PCI Express0 */
  39803. + CRYPT_TARGET_ID = 3 , /* Port 3 --> Crypto Engine */
  39804. + SAGE_TARGET_ID = 12 , /* Port 12 -> SAGE Unit */
  39805. + MAX_TARGETS_ID
  39806. +}MV_TARGET_ID;
  39807. +
  39808. +
  39809. +/* This enumerator described the possible Controller paripheral targets. */
  39810. +/* Controller peripherals are designated memory/IO address spaces that the */
  39811. +/* controller can access. They are also refered as "targets" */
  39812. +typedef enum _mvTarget
  39813. +{
  39814. + TBL_TERM = -1, /* none valid target, used as targets list terminator*/
  39815. + SDRAM_CS0, /* SDRAM chip select 0 */
  39816. + SDRAM_CS1, /* SDRAM chip select 1 */
  39817. + SDRAM_CS2, /* SDRAM chip select 2 */
  39818. + SDRAM_CS3, /* SDRAM chip select 3 */
  39819. + PEX0_MEM, /* PCI Express 0 Memory */
  39820. + PEX0_IO, /* PCI Express 0 IO */
  39821. + INTER_REGS, /* Internal registers */
  39822. + NFLASH_CS, /* NFLASH_CS */
  39823. + SPI_CS, /* SPI_CS */
  39824. + BOOT_ROM_CS, /* BOOT_ROM_CS */
  39825. + DEV_BOOCS, /* DEV_BOOCS */
  39826. + CRYPT_ENG, /* Crypto Engine */
  39827. +#ifdef MV_INCLUDE_SAGE
  39828. + SAGE_UNIT, /* SAGE Unit */
  39829. +#endif
  39830. + MAX_TARGETS
  39831. +
  39832. +}MV_TARGET;
  39833. +
  39834. +#define TARGETS_DEF_ARRAY { \
  39835. + {0x0E, DRAM_TARGET_ID }, /* SDRAM_CS0 */ \
  39836. + {0x0D, DRAM_TARGET_ID }, /* SDRAM_CS1 */ \
  39837. + {0x0B, DRAM_TARGET_ID }, /* SDRAM_CS0 */ \
  39838. + {0x07, DRAM_TARGET_ID }, /* SDRAM_CS1 */ \
  39839. + {0xE8, PEX0_TARGET_ID }, /* PEX0_MEM */ \
  39840. + {0xE0, PEX0_TARGET_ID }, /* PEX0_IO */ \
  39841. + {0xFF, 0xFF }, /* INTER_REGS */ \
  39842. + {0x2F, DEV_TARGET_ID }, /* NFLASH_CS */ \
  39843. + {0x1E, DEV_TARGET_ID }, /* SPI_CS */ \
  39844. + {0x1D, DEV_TARGET_ID }, /* BOOT_ROM_CS */ \
  39845. + {0x1E, DEV_TARGET_ID }, /* DEV_BOOCS */ \
  39846. + {0x01, CRYPT_TARGET_ID}, /* CRYPT_ENG */ \
  39847. + {0x00, SAGE_TARGET_ID } \
  39848. +}
  39849. +
  39850. +
  39851. +#define TARGETS_NAME_ARRAY { \
  39852. + "SDRAM_CS0", /* SDRAM_CS0 */ \
  39853. + "SDRAM_CS1", /* SDRAM_CS1 */ \
  39854. + "SDRAM_CS2", /* SDRAM_CS2 */ \
  39855. + "SDRAM_CS3", /* SDRAM_CS3 */ \
  39856. + "PEX0_MEM", /* PEX0_MEM */ \
  39857. + "PEX0_IO", /* PEX0_IO */ \
  39858. + "INTER_REGS", /* INTER_REGS */ \
  39859. + "NFLASH_CS", /* NFLASH_CS */ \
  39860. + "SPI_CS", /* SPI_CS */ \
  39861. + "BOOT_ROM_CS", /* BOOT_ROM_CS */ \
  39862. + "DEV_BOOTCS", /* DEV_BOOCS */ \
  39863. + "CRYPT_ENG", /* CRYPT_ENG */ \
  39864. + "SAGE_UNIT" /* SAGE_UNIT */ \
  39865. +}
  39866. +#endif /* MV_ASMLANGUAGE */
  39867. +
  39868. +
  39869. +#endif
  39870. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h
  39871. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h 1970-01-01 01:00:00.000000000 +0100
  39872. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h 2011-07-31 11:31:57.053422104 +0200
  39873. @@ -0,0 +1,257 @@
  39874. +/*******************************************************************************
  39875. +Copyright (C) Marvell International Ltd. and its affiliates
  39876. +
  39877. +This software file (the "File") is owned and distributed by Marvell
  39878. +International Ltd. and/or its affiliates ("Marvell") under the following
  39879. +alternative licensing terms. Once you have made an election to distribute the
  39880. +File under one of the following license alternatives, please (i) delete this
  39881. +introductory statement regarding license alternatives, (ii) delete the two
  39882. +license alternatives that you have not elected to use and (iii) preserve the
  39883. +Marvell copyright notice above.
  39884. +
  39885. +********************************************************************************
  39886. +Marvell Commercial License Option
  39887. +
  39888. +If you received this File from Marvell and you have entered into a commercial
  39889. +license agreement (a "Commercial License") with Marvell, the File is licensed
  39890. +to you under the terms of the applicable Commercial License.
  39891. +
  39892. +********************************************************************************
  39893. +Marvell GPL License Option
  39894. +
  39895. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39896. +modify this File in accordance with the terms and conditions of the General
  39897. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  39898. +available along with the File in the license.txt file or by writing to the Free
  39899. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  39900. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  39901. +
  39902. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  39903. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  39904. +DISCLAIMED. The GPL License provides additional details about this warranty
  39905. +disclaimer.
  39906. +********************************************************************************
  39907. +Marvell BSD License Option
  39908. +
  39909. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39910. +modify this File under the following licensing terms.
  39911. +Redistribution and use in source and binary forms, with or without modification,
  39912. +are permitted provided that the following conditions are met:
  39913. +
  39914. + * Redistributions of source code must retain the above copyright notice,
  39915. + this list of conditions and the following disclaimer.
  39916. +
  39917. + * Redistributions in binary form must reproduce the above copyright
  39918. + notice, this list of conditions and the following disclaimer in the
  39919. + documentation and/or other materials provided with the distribution.
  39920. +
  39921. + * Neither the name of Marvell nor the names of its contributors may be
  39922. + used to endorse or promote products derived from this software without
  39923. + specific prior written permission.
  39924. +
  39925. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  39926. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  39927. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39928. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  39929. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  39930. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  39931. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  39932. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  39933. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  39934. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39935. +
  39936. +*******************************************************************************/
  39937. +
  39938. +#ifndef __INCmvCtrlEnvSpech
  39939. +#define __INCmvCtrlEnvSpech
  39940. +
  39941. +#include "mvDeviceId.h"
  39942. +#include "mvSysHwConfig.h"
  39943. +
  39944. +#ifdef __cplusplus
  39945. +extern "C" {
  39946. +#endif /* __cplusplus */
  39947. +
  39948. +#define MV_ARM_SOC
  39949. +#define SOC_NAME_PREFIX "MV88F"
  39950. +
  39951. +
  39952. +/* units base and port numbers */
  39953. +#ifdef MV_ASMLANGUAGE
  39954. +#define XOR_UNIT_BASE(unit) 0x60800
  39955. +#else
  39956. +#define MV_XOR_REG_BASE 0x60000
  39957. +#define XOR_UNIT_BASE(unit) ((unit)? 0x60900:0x60800)
  39958. +#endif
  39959. +
  39960. +#define TDM_REG_BASE 0xD0000
  39961. +#define USB_REG_BASE(dev) 0x50000
  39962. +#define AUDIO_REG_BASE 0xA0000
  39963. +#define SATA_REG_BASE 0x80000
  39964. +#define MV_CESA_REG_BASE 0x3D000
  39965. +#define MV_CESA_TDMA_REG_BASE 0x30000
  39966. +#define MV_SDIO_REG_BASE 0x90000
  39967. +#define MV_ETH_REG_BASE(port) (((port) == 0) ? 0x72000 : 0x76000)
  39968. +#define MV_UART_CHAN_BASE(chanNum) (0x12000 + (chanNum * 0x100))
  39969. +#define DRAM_BASE 0x0
  39970. +#define CNTMR_BASE 0x20300
  39971. +#define TWSI_SLAVE_BASE(chanNum) 0x11000
  39972. +#define PEX_IF_BASE(pexIf) 0x40000
  39973. +#define MPP_REG_BASE 0x10000
  39974. +#define TSU_GLOBAL_REG_BASE 0xB4000
  39975. +#define MAX_AHB_TO_MBUS_REG_BASE 0x20000
  39976. +
  39977. +#define INTER_REGS_SIZE _1M
  39978. +/* This define describes the TWSI interrupt bit and location */
  39979. +#define TWSI_CPU_MAIN_INT_CAUSE_REG 0x20200
  39980. +#define TWSI0_CPU_MAIN_INT_BIT (1<<29)
  39981. +#define TWSI_SPEED 100000
  39982. +
  39983. +#define MV_GPP_MAX_GROUP 2
  39984. +#define MV_CNTMR_MAX_COUNTER 2
  39985. +#define MV_UART_MAX_CHAN 2
  39986. +#define MV_XOR_MAX_UNIT 2
  39987. +#define MV_XOR_MAX_CHAN 4 /* total channels for all units together*/
  39988. +#define MV_XOR_MAX_CHAN_PER_UNIT 2 /* channels for units */
  39989. +#define MV_SATA_MAX_CHAN 2
  39990. +
  39991. +#define MV_6281_MPP_MAX_MODULE 2
  39992. +#define MV_6192_MPP_MAX_MODULE 1
  39993. +#define MV_6190_MPP_MAX_MODULE 1
  39994. +#define MV_6180_MPP_MAX_MODULE 2
  39995. +#define MV_6281_MPP_MAX_GROUP 7
  39996. +#define MV_6192_MPP_MAX_GROUP 4
  39997. +#define MV_6190_MPP_MAX_GROUP 4
  39998. +#define MV_6180_MPP_MAX_GROUP 3
  39999. +
  40000. +#define MV_DRAM_MAX_CS 4
  40001. +
  40002. +/* This define describes the maximum number of supported PCI\PCIX Interfaces*/
  40003. +#define MV_PCI_MAX_IF 0
  40004. +#define MV_PCI_START_IF 0
  40005. +
  40006. +/* This define describes the maximum number of supported PEX Interfaces */
  40007. +#define MV_INCLUDE_PEX0
  40008. +#define MV_DISABLE_PEX_DEVICE_BAR
  40009. +#define MV_PEX_MAX_IF 1
  40010. +#define MV_PEX_START_IF MV_PCI_MAX_IF
  40011. +
  40012. +/* This define describes the maximum number of supported PCI Interfaces */
  40013. +#define MV_PCI_IF_MAX_IF (MV_PEX_MAX_IF+MV_PCI_MAX_IF)
  40014. +
  40015. +#define MV_ETH_MAX_PORTS 2
  40016. +#define MV_6281_ETH_MAX_PORTS 2
  40017. +#define MV_6192_ETH_MAX_PORTS 2
  40018. +#define MV_6190_ETH_MAX_PORTS 1
  40019. +#define MV_6180_ETH_MAX_PORTS 1
  40020. +
  40021. +#define MV_IDMA_MAX_CHAN 0
  40022. +
  40023. +#define MV_USB_MAX_PORTS 1
  40024. +
  40025. +#define MV_USB_VERSION 1
  40026. +
  40027. +
  40028. +#define MV_6281_NAND 1
  40029. +#define MV_6192_NAND 1
  40030. +#define MV_6190_NAND 1
  40031. +#define MV_6180_NAND 0
  40032. +
  40033. +#define MV_6281_SDIO 1
  40034. +#define MV_6192_SDIO 1
  40035. +#define MV_6190_SDIO 1
  40036. +#define MV_6180_SDIO 1
  40037. +
  40038. +#define MV_6281_TS 1
  40039. +#define MV_6192_TS 1
  40040. +#define MV_6190_TS 0
  40041. +#define MV_6180_TS 0
  40042. +
  40043. +#define MV_6281_AUDIO 1
  40044. +#define MV_6192_AUDIO 1
  40045. +#define MV_6190_AUDIO 0
  40046. +#define MV_6180_AUDIO 1
  40047. +
  40048. +#define MV_6281_TDM 1
  40049. +#define MV_6192_TDM 1
  40050. +#define MV_6190_TDM 0
  40051. +#define MV_6180_TDM 0
  40052. +
  40053. +#define MV_DEVICE_MAX_CS 4
  40054. +
  40055. +/* Others */
  40056. +#define PEX_HOST_BUS_NUM(pciIf) (pciIf)
  40057. +#define PEX_HOST_DEV_NUM(pciIf) 0
  40058. +
  40059. +#define PCI_IO(pciIf) (PEX0_IO)
  40060. +#define PCI_MEM(pciIf, memNum) (PEX0_MEM0)
  40061. +/* CESA version #2: One channel, 2KB SRAM, TDMA */
  40062. +#if defined(MV_CESA_CHAIN_MODE_SUPPORT)
  40063. + #define MV_CESA_VERSION 3
  40064. +#else
  40065. +#define MV_CESA_VERSION 2
  40066. +#endif
  40067. +#define MV_CESA_SRAM_SIZE 2*1024
  40068. +/* This define describes the maximum number of supported Ethernet ports */
  40069. +#define MV_ETH_VERSION 4
  40070. +#define MV_ETH_MAX_RXQ 8
  40071. +#define MV_ETH_MAX_TXQ 8
  40072. +#define MV_ETH_PORT_SGMII { MV_FALSE, MV_FALSE }
  40073. +/* This define describes the the support of USB */
  40074. +#define MV_USB_VERSION 1
  40075. +
  40076. +#define MV_INCLUDE_SDRAM_CS0
  40077. +#define MV_INCLUDE_SDRAM_CS1
  40078. +#define MV_INCLUDE_SDRAM_CS2
  40079. +#define MV_INCLUDE_SDRAM_CS3
  40080. +
  40081. +#define MV_INCLUDE_DEVICE_CS0
  40082. +#define MV_INCLUDE_DEVICE_CS1
  40083. +#define MV_INCLUDE_DEVICE_CS2
  40084. +#define MV_INCLUDE_DEVICE_CS3
  40085. +
  40086. +#define MPP_GROUP_1_TYPE {\
  40087. + {0, 0, 0}, /* Reserved for AUTO */ \
  40088. + {0x22220000, 0x22222222, 0x2222}, /* TDM */ \
  40089. + {0x44440000, 0x00044444, 0x0000}, /* AUDIO */ \
  40090. + {0x33330000, 0x33003333, 0x0033}, /* RGMII */ \
  40091. + {0x33330000, 0x03333333, 0x0033}, /* GMII */ \
  40092. + {0x11110000, 0x11111111, 0x0001}, /* TS */ \
  40093. + {0x33330000, 0x33333333, 0x3333} /* MII */ \
  40094. +}
  40095. +
  40096. +#define MPP_GROUP_2_TYPE {\
  40097. + {0, 0, 0}, /* Reserved for AUTO */ \
  40098. + {0x22220000, 0x22222222, 0x22}, /* TDM */ \
  40099. + {0x44440000, 0x00044444, 0x0}, /* AUDIO */ \
  40100. + {0, 0, 0}, /* N_A */ \
  40101. + {0, 0, 0}, /* N_A */ \
  40102. + {0x11110000, 0x11111111, 0x01} /* TS */ \
  40103. +}
  40104. +
  40105. +#ifndef MV_ASMLANGUAGE
  40106. +
  40107. +/* This enumerator defines the Marvell Units ID */
  40108. +typedef enum _mvUnitId
  40109. +{
  40110. + DRAM_UNIT_ID,
  40111. + PEX_UNIT_ID,
  40112. + ETH_GIG_UNIT_ID,
  40113. + USB_UNIT_ID,
  40114. + IDMA_UNIT_ID,
  40115. + XOR_UNIT_ID,
  40116. + SATA_UNIT_ID,
  40117. + TDM_UNIT_ID,
  40118. + UART_UNIT_ID,
  40119. + CESA_UNIT_ID,
  40120. + SPI_UNIT_ID,
  40121. + AUDIO_UNIT_ID,
  40122. + SDIO_UNIT_ID,
  40123. + TS_UNIT_ID,
  40124. + MAX_UNITS_ID
  40125. +
  40126. +}MV_UNIT_ID;
  40127. +
  40128. +#endif
  40129. +
  40130. +#endif /* __INCmvCtrlEnvSpech */
  40131. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c
  40132. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c 1970-01-01 01:00:00.000000000 +0100
  40133. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c 2011-07-31 11:31:57.093457179 +0200
  40134. @@ -0,0 +1,1048 @@
  40135. +/*******************************************************************************
  40136. +Copyright (C) Marvell International Ltd. and its affiliates
  40137. +
  40138. +This software file (the "File") is owned and distributed by Marvell
  40139. +International Ltd. and/or its affiliates ("Marvell") under the following
  40140. +alternative licensing terms. Once you have made an election to distribute the
  40141. +File under one of the following license alternatives, please (i) delete this
  40142. +introductory statement regarding license alternatives, (ii) delete the two
  40143. +license alternatives that you have not elected to use and (iii) preserve the
  40144. +Marvell copyright notice above.
  40145. +
  40146. +********************************************************************************
  40147. +Marvell Commercial License Option
  40148. +
  40149. +If you received this File from Marvell and you have entered into a commercial
  40150. +license agreement (a "Commercial License") with Marvell, the File is licensed
  40151. +to you under the terms of the applicable Commercial License.
  40152. +
  40153. +********************************************************************************
  40154. +Marvell GPL License Option
  40155. +
  40156. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40157. +modify this File in accordance with the terms and conditions of the General
  40158. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  40159. +available along with the File in the license.txt file or by writing to the Free
  40160. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  40161. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  40162. +
  40163. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  40164. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  40165. +DISCLAIMED. The GPL License provides additional details about this warranty
  40166. +disclaimer.
  40167. +********************************************************************************
  40168. +Marvell BSD License Option
  40169. +
  40170. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40171. +modify this File under the following licensing terms.
  40172. +Redistribution and use in source and binary forms, with or without modification,
  40173. +are permitted provided that the following conditions are met:
  40174. +
  40175. + * Redistributions of source code must retain the above copyright notice,
  40176. + this list of conditions and the following disclaimer.
  40177. +
  40178. + * Redistributions in binary form must reproduce the above copyright
  40179. + notice, this list of conditions and the following disclaimer in the
  40180. + documentation and/or other materials provided with the distribution.
  40181. +
  40182. + * Neither the name of Marvell nor the names of its contributors may be
  40183. + used to endorse or promote products derived from this software without
  40184. + specific prior written permission.
  40185. +
  40186. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  40187. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  40188. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  40189. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  40190. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  40191. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  40192. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  40193. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  40194. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  40195. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40196. +
  40197. +*******************************************************************************/
  40198. +
  40199. +
  40200. +/* includes */
  40201. +#include "ctrlEnv/sys/mvAhbToMbus.h"
  40202. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  40203. +
  40204. +#undef MV_DEBUG
  40205. +/* defines */
  40206. +#ifdef MV_DEBUG
  40207. + #define DB(x) x
  40208. +#else
  40209. + #define DB(x)
  40210. +#endif
  40211. +
  40212. +/* typedefs */
  40213. +
  40214. +
  40215. +/* CPU address remap registers offsets are inconsecutive. This struct */
  40216. +/* describes address remap register offsets */
  40217. +typedef struct _ahbToMbusRemapRegOffs
  40218. +{
  40219. + MV_U32 lowRegOffs; /* Low 32-bit remap register offset */
  40220. + MV_U32 highRegOffs; /* High 32 bit remap register offset */
  40221. +}AHB_TO_MBUS_REMAP_REG_OFFS;
  40222. +
  40223. +/* locals */
  40224. +static MV_STATUS ahbToMbusRemapRegOffsGet (MV_U32 winNum,
  40225. + AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs);
  40226. +
  40227. +/*******************************************************************************
  40228. +* mvAhbToMbusInit - Initialize Ahb To Mbus Address Map !
  40229. +*
  40230. +* DESCRIPTION:
  40231. +*
  40232. +* INPUT:
  40233. +* None.
  40234. +*
  40235. +* OUTPUT:
  40236. +* None.
  40237. +*
  40238. +* RETURN:
  40239. +* MV_OK laways.
  40240. +*
  40241. +*******************************************************************************/
  40242. +MV_STATUS mvAhbToMbusInit(void)
  40243. +{
  40244. + return MV_OK;
  40245. +
  40246. +}
  40247. +
  40248. +/*******************************************************************************
  40249. +* mvAhbToMbusWinSet - Set CPU-to-peripheral winNum address window
  40250. +*
  40251. +* DESCRIPTION:
  40252. +* This function sets
  40253. +* address window, also known as address decode window.
  40254. +* A new address decode window is set for specified winNum address window.
  40255. +* If address decode window parameter structure enables the window,
  40256. +* the routine will also enable the winNum window, allowing CPU to access
  40257. +* the winNum window.
  40258. +*
  40259. +* INPUT:
  40260. +* winNum - Windows number.
  40261. +* pAddrDecWin - CPU winNum window data structure.
  40262. +*
  40263. +* OUTPUT:
  40264. +* N/A
  40265. +*
  40266. +* RETURN:
  40267. +* MV_OK if CPU winNum window was set correctly, MV_ERROR in case of
  40268. +* address window overlapps with other active CPU winNum window or
  40269. +* trying to assign 36bit base address while CPU does not support that.
  40270. +* The function returns MV_NOT_SUPPORTED, if the winNum is unsupported.
  40271. +*
  40272. +*******************************************************************************/
  40273. +MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
  40274. +{
  40275. + MV_TARGET_ATTRIB targetAttribs;
  40276. + MV_DEC_REGS decRegs;
  40277. +
  40278. + /* Parameter checking */
  40279. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  40280. + {
  40281. + mvOsPrintf("mvAhbToMbusWinSet: ERR. Invalid winNum %d\n", winNum);
  40282. + return MV_NOT_SUPPORTED;
  40283. + }
  40284. +
  40285. +
  40286. + /* read base register*/
  40287. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40288. + {
  40289. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
  40290. + }
  40291. + else
  40292. + {
  40293. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
  40294. + }
  40295. +
  40296. + /* check if address is aligned to the size */
  40297. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  40298. + {
  40299. + mvOsPrintf("mvAhbToMbusWinSet:Error setting AHB to MBUS window %d to "\
  40300. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  40301. + winNum,
  40302. + mvCtrlTargetNameGet(pAddrDecWin->target),
  40303. + pAddrDecWin->addrWin.baseLow,
  40304. + pAddrDecWin->addrWin.size);
  40305. + return MV_ERROR;
  40306. + }
  40307. +
  40308. + /* read control register*/
  40309. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40310. + {
  40311. + decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
  40312. + }
  40313. +
  40314. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  40315. + {
  40316. + mvOsPrintf("mvAhbToMbusWinSet:mvCtrlAddrDecToReg Failed\n");
  40317. + return MV_ERROR;
  40318. + }
  40319. +
  40320. + /* enable\Disable */
  40321. + if (MV_TRUE == pAddrDecWin->enable)
  40322. + {
  40323. + decRegs.sizeReg |= ATMWCR_WIN_ENABLE;
  40324. + }
  40325. + else
  40326. + {
  40327. + decRegs.sizeReg &= ~ATMWCR_WIN_ENABLE;
  40328. + }
  40329. +
  40330. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  40331. +
  40332. + /* set attributes */
  40333. + decRegs.sizeReg &= ~ATMWCR_WIN_ATTR_MASK;
  40334. + decRegs.sizeReg |= targetAttribs.attrib << ATMWCR_WIN_ATTR_OFFS;
  40335. + /* set target ID */
  40336. + decRegs.sizeReg &= ~ATMWCR_WIN_TARGET_MASK;
  40337. + decRegs.sizeReg |= targetAttribs.targetId << ATMWCR_WIN_TARGET_OFFS;
  40338. +
  40339. +#if !defined(MV_RUN_FROM_FLASH)
  40340. + /* To be on the safe side we disable the window before writing the */
  40341. + /* new values. */
  40342. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40343. + {
  40344. + mvAhbToMbusWinEnable(winNum,MV_FALSE);
  40345. + }
  40346. +#endif
  40347. +
  40348. + /* 3) Write to address decode Base Address Register */
  40349. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40350. + {
  40351. + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum), decRegs.baseReg);
  40352. + }
  40353. + else
  40354. + {
  40355. + MV_REG_WRITE(AHB_TO_MBUS_WIN_INTEREG_REG, decRegs.baseReg);
  40356. + }
  40357. +
  40358. +
  40359. + /* Internal register space have no size */
  40360. + /* register. Do not perform size register assigment for those targets */
  40361. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40362. + {
  40363. + /* Write to address decode Size Register */
  40364. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), decRegs.sizeReg);
  40365. + }
  40366. +
  40367. + return MV_OK;
  40368. +}
  40369. +
  40370. +/*******************************************************************************
  40371. +* mvAhbToMbusWinGet - Get CPU-to-peripheral winNum address window
  40372. +*
  40373. +* DESCRIPTION:
  40374. +* Get the CPU peripheral winNum address window.
  40375. +*
  40376. +* INPUT:
  40377. +* winNum - Peripheral winNum enumerator
  40378. +*
  40379. +* OUTPUT:
  40380. +* pAddrDecWin - CPU winNum window information data structure.
  40381. +*
  40382. +* RETURN:
  40383. +* MV_OK if winNum exist, MV_ERROR otherwise.
  40384. +*
  40385. +*******************************************************************************/
  40386. +MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
  40387. +{
  40388. + MV_DEC_REGS decRegs;
  40389. + MV_TARGET_ATTRIB targetAttrib;
  40390. +
  40391. +
  40392. + /* Parameter checking */
  40393. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  40394. + {
  40395. + mvOsPrintf("mvAhbToMbusWinGet: ERR. Invalid winNum %d\n", winNum);
  40396. + return MV_NOT_SUPPORTED;
  40397. + }
  40398. +
  40399. +
  40400. + /* Internal register space size have no size register*/
  40401. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40402. + {
  40403. + decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
  40404. + }
  40405. + else
  40406. + {
  40407. + decRegs.sizeReg = 0;
  40408. + }
  40409. +
  40410. +
  40411. + /* Read base and size */
  40412. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40413. + {
  40414. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
  40415. + }
  40416. + else
  40417. + {
  40418. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
  40419. + }
  40420. +
  40421. +
  40422. +
  40423. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  40424. + {
  40425. + mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");
  40426. + return MV_ERROR;
  40427. + }
  40428. +
  40429. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  40430. + {
  40431. + pAddrDecWin->addrWin.size = INTER_REGS_SIZE;
  40432. + pAddrDecWin->target = INTER_REGS;
  40433. + pAddrDecWin->enable = MV_TRUE;
  40434. +
  40435. + return MV_OK;
  40436. + }
  40437. +
  40438. +
  40439. + if (decRegs.sizeReg & ATMWCR_WIN_ENABLE)
  40440. + {
  40441. + pAddrDecWin->enable = MV_TRUE;
  40442. + }
  40443. + else
  40444. + {
  40445. + pAddrDecWin->enable = MV_FALSE;
  40446. +
  40447. + }
  40448. +
  40449. +
  40450. +
  40451. + if (-1 == pAddrDecWin->addrWin.size)
  40452. + {
  40453. + return MV_ERROR;
  40454. + }
  40455. +
  40456. + /* attrib and targetId */
  40457. + targetAttrib.attrib = (decRegs.sizeReg & ATMWCR_WIN_ATTR_MASK) >>
  40458. + ATMWCR_WIN_ATTR_OFFS;
  40459. + targetAttrib.targetId = (decRegs.sizeReg & ATMWCR_WIN_TARGET_MASK) >>
  40460. + ATMWCR_WIN_TARGET_OFFS;
  40461. +
  40462. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  40463. +
  40464. + return MV_OK;
  40465. +}
  40466. +
  40467. +/*******************************************************************************
  40468. +* mvAhbToMbusWinTargetGet - Get Window number associated with target
  40469. +*
  40470. +* DESCRIPTION:
  40471. +*
  40472. +* INPUT:
  40473. +*
  40474. +* OUTPUT:
  40475. +*
  40476. +* RETURN:
  40477. +*
  40478. +*******************************************************************************/
  40479. +MV_U32 mvAhbToMbusWinTargetGet(MV_TARGET target)
  40480. +{
  40481. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  40482. + MV_U32 winNum;
  40483. +
  40484. + /* Check parameters */
  40485. + if (target >= MAX_TARGETS)
  40486. + {
  40487. + mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);
  40488. + return 0xffffffff;
  40489. + }
  40490. +
  40491. + if (INTER_REGS == target)
  40492. + {
  40493. + return MV_AHB_TO_MBUS_INTREG_WIN;
  40494. + }
  40495. +
  40496. + for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)
  40497. + {
  40498. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  40499. + continue;
  40500. +
  40501. + if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)
  40502. + {
  40503. + mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");
  40504. + return 0xffffffff;
  40505. +
  40506. + }
  40507. +
  40508. + if (decWin.enable == MV_TRUE)
  40509. + {
  40510. + if (decWin.target == target)
  40511. + {
  40512. + return winNum;
  40513. + }
  40514. +
  40515. + }
  40516. +
  40517. + }
  40518. +
  40519. + return 0xFFFFFFFF;
  40520. +
  40521. +
  40522. +}
  40523. +
  40524. +/*******************************************************************************
  40525. +* mvAhbToMbusWinAvailGet - Get First Available window number.
  40526. +*
  40527. +* DESCRIPTION:
  40528. +*
  40529. +* INPUT:
  40530. +*
  40531. +* OUTPUT:
  40532. +*
  40533. +* RETURN:
  40534. +*
  40535. +*******************************************************************************/
  40536. +MV_U32 mvAhbToMbusWinAvailGet(MV_VOID)
  40537. +{
  40538. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  40539. + MV_U32 winNum;
  40540. +
  40541. + for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)
  40542. + {
  40543. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  40544. + continue;
  40545. +
  40546. + if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)
  40547. + {
  40548. + mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");
  40549. + return 0xffffffff;
  40550. +
  40551. + }
  40552. +
  40553. + if (decWin.enable == MV_FALSE)
  40554. + {
  40555. + return winNum;
  40556. + }
  40557. +
  40558. + }
  40559. +
  40560. + return 0xFFFFFFFF;
  40561. +}
  40562. +
  40563. +
  40564. +/*******************************************************************************
  40565. +* mvAhbToMbusWinEnable - Enable/disable a CPU address decode window
  40566. +*
  40567. +* DESCRIPTION:
  40568. +* This function enable/disable a CPU address decode window.
  40569. +* if parameter 'enable' == MV_TRUE the routine will enable the
  40570. +* window, thus enabling CPU accesses (before enabling the window it is
  40571. +* tested for overlapping). Otherwise, the window will be disabled.
  40572. +*
  40573. +* INPUT:
  40574. +* winNum - Peripheral winNum enumerator.
  40575. +* enable - Enable/disable parameter.
  40576. +*
  40577. +* OUTPUT:
  40578. +* N/A
  40579. +*
  40580. +* RETURN:
  40581. +* MV_ERROR if protection window number was wrong, or the window
  40582. +* overlapps other winNum window.
  40583. +*
  40584. +*******************************************************************************/
  40585. +MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum, MV_BOOL enable)
  40586. +{
  40587. +
  40588. + /* Parameter checking */
  40589. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  40590. + {
  40591. + mvOsPrintf("mvAhbToMbusWinEnable: ERR. Invalid winNum %d\n", winNum);
  40592. + return MV_NOT_SUPPORTED;
  40593. + }
  40594. +
  40595. + /* Internal registers bar can't be disable or enabled */
  40596. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  40597. + {
  40598. + return (enable ? MV_OK : MV_ERROR);
  40599. + }
  40600. +
  40601. + if (enable == MV_TRUE)
  40602. + {
  40603. + /* enable the window */
  40604. + MV_REG_BIT_SET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
  40605. + }
  40606. + else
  40607. + { /* Disable address decode winNum window */
  40608. + MV_REG_BIT_RESET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
  40609. + }
  40610. +
  40611. + return MV_OK;
  40612. +}
  40613. +
  40614. +
  40615. +/*******************************************************************************
  40616. +* mvAhbToMbusWinRemap - Set CPU remap register for address windows.
  40617. +*
  40618. +* DESCRIPTION:
  40619. +* After a CPU address hits one of PCI address decode windows there is an
  40620. +* option to remap the address to a different one. For example, CPU
  40621. +* executes a read from PCI winNum window address 0x1200.0000. This
  40622. +* can be modified so the address on the PCI bus would be 0x1400.0000
  40623. +* Using the PCI address remap mechanism.
  40624. +*
  40625. +* INPUT:
  40626. +* winNum - Peripheral winNum enumerator. Must be a PCI winNum.
  40627. +* pAddrDecWin - CPU winNum window information data structure.
  40628. +* Note that caller has to fill in the base field only. The
  40629. +* size field is ignored.
  40630. +*
  40631. +* OUTPUT:
  40632. +* None.
  40633. +*
  40634. +* RETURN:
  40635. +* MV_ERROR if winNum is not a PCI one, MV_OK otherwise.
  40636. +*
  40637. +*******************************************************************************/
  40638. +MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  40639. +{
  40640. + MV_U32 baseAddr;
  40641. + AHB_TO_MBUS_REMAP_REG_OFFS remapRegOffs;
  40642. +
  40643. + MV_U32 effectiveBaseAddress=0,
  40644. + baseAddrValue=0,windowSizeValue=0;
  40645. +
  40646. +
  40647. + /* Get registers offsets of given winNum */
  40648. + if (MV_NO_SUCH == ahbToMbusRemapRegOffsGet(winNum, &remapRegOffs))
  40649. + {
  40650. + return 0xffffffff;
  40651. + }
  40652. +
  40653. + /* 1) Set address remap low */
  40654. + baseAddr = pAddrWin->baseLow;
  40655. +
  40656. + /* Check base address aligment */
  40657. + /*
  40658. + if (MV_IS_NOT_ALIGN(baseAddr, ATMWRLR_REMAP_LOW_ALIGNMENT))
  40659. + {
  40660. + mvOsPrintf("mvAhbToMbusPciRemap: Warning. Target base 0x%x unaligned\n",
  40661. + baseAddr);
  40662. + return MV_ERROR;
  40663. + }
  40664. + */
  40665. +
  40666. + /* BaseLow[31:16] => base register [31:16] */
  40667. + baseAddr = baseAddr & ATMWRLR_REMAP_LOW_MASK;
  40668. +
  40669. + MV_REG_WRITE(remapRegOffs.lowRegOffs, baseAddr);
  40670. +
  40671. + MV_REG_WRITE(remapRegOffs.highRegOffs, pAddrWin->baseHigh);
  40672. +
  40673. +
  40674. + baseAddrValue = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
  40675. + windowSizeValue = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
  40676. +
  40677. + baseAddrValue &= ATMWBR_BASE_MASK;
  40678. + windowSizeValue &=ATMWCR_WIN_SIZE_MASK;
  40679. +
  40680. + /* Start calculating the effective Base Address */
  40681. + effectiveBaseAddress = baseAddrValue ;
  40682. +
  40683. + /* The effective base address will be combined from the chopped (if any)
  40684. + remap value (according to the size value and remap mechanism) and the
  40685. + window's base address */
  40686. + effectiveBaseAddress |= (((windowSizeValue) | 0xffff) & pAddrWin->baseLow);
  40687. + /* If the effectiveBaseAddress exceed the window boundaries return an
  40688. + invalid value. */
  40689. +
  40690. + if (effectiveBaseAddress > (baseAddrValue + (windowSizeValue | 0xffff)))
  40691. + {
  40692. + mvOsPrintf("mvAhbToMbusPciRemap: Error\n");
  40693. + return 0xffffffff;
  40694. + }
  40695. +
  40696. + return effectiveBaseAddress;
  40697. +
  40698. +
  40699. +}
  40700. +/*******************************************************************************
  40701. +* mvAhbToMbusWinTargetSwap - Swap AhbToMbus windows between targets
  40702. +*
  40703. +* DESCRIPTION:
  40704. +*
  40705. +* INPUT:
  40706. +* target1 - CPU Interface target 1
  40707. +* target2 - CPU Interface target 2
  40708. +*
  40709. +* OUTPUT:
  40710. +* None.
  40711. +*
  40712. +* RETURN:
  40713. +* MV_ERROR if targets are illigal, or if one of the targets is not
  40714. +* associated to a valid window .
  40715. +* MV_OK otherwise.
  40716. +*
  40717. +*******************************************************************************/
  40718. +
  40719. +
  40720. +MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2)
  40721. +{
  40722. + MV_U32 winNum1,winNum2;
  40723. + MV_AHB_TO_MBUS_DEC_WIN winDec1,winDec2,winDecTemp;
  40724. + AHB_TO_MBUS_REMAP_REG_OFFS remapRegs1,remapRegs2;
  40725. + MV_U32 remapBaseLow1=0,remapBaseLow2=0;
  40726. + MV_U32 remapBaseHigh1=0,remapBaseHigh2=0;
  40727. +
  40728. +
  40729. + /* Check parameters */
  40730. + if (target1 >= MAX_TARGETS)
  40731. + {
  40732. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);
  40733. + return MV_ERROR;
  40734. + }
  40735. +
  40736. + if (target2 >= MAX_TARGETS)
  40737. + {
  40738. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);
  40739. + return MV_ERROR;
  40740. + }
  40741. +
  40742. +
  40743. + /* get window associated with this target */
  40744. + winNum1 = mvAhbToMbusWinTargetGet(target1);
  40745. +
  40746. + if (winNum1 == 0xffffffff)
  40747. + {
  40748. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",
  40749. + target1,winNum1);
  40750. + return MV_ERROR;
  40751. +
  40752. + }
  40753. +
  40754. + /* get window associated with this target */
  40755. + winNum2 = mvAhbToMbusWinTargetGet(target2);
  40756. +
  40757. + if (winNum2 == 0xffffffff)
  40758. + {
  40759. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",
  40760. + target2,winNum2);
  40761. + return MV_ERROR;
  40762. +
  40763. + }
  40764. +
  40765. + /* now Get original values of both Windows */
  40766. + if (MV_OK != mvAhbToMbusWinGet(winNum1,&winDec1))
  40767. + {
  40768. + mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",
  40769. + winNum1);
  40770. + return MV_ERROR;
  40771. +
  40772. + }
  40773. + if (MV_OK != mvAhbToMbusWinGet(winNum2,&winDec2))
  40774. + {
  40775. + mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",
  40776. + winNum2);
  40777. + return MV_ERROR;
  40778. +
  40779. + }
  40780. +
  40781. +
  40782. + /* disable both windows */
  40783. + if (MV_OK != mvAhbToMbusWinEnable(winNum1,MV_FALSE))
  40784. + {
  40785. + mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable window %d\n",
  40786. + winNum1);
  40787. + return MV_ERROR;
  40788. +
  40789. + }
  40790. + if (MV_OK != mvAhbToMbusWinEnable(winNum2,MV_FALSE))
  40791. + {
  40792. + mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable windo %d\n",
  40793. + winNum2);
  40794. + return MV_ERROR;
  40795. +
  40796. + }
  40797. +
  40798. +
  40799. + /* now swap targets */
  40800. +
  40801. + /* first save winDec2 values */
  40802. + winDecTemp.addrWin.baseHigh = winDec2.addrWin.baseHigh;
  40803. + winDecTemp.addrWin.baseLow = winDec2.addrWin.baseLow;
  40804. + winDecTemp.addrWin.size = winDec2.addrWin.size;
  40805. + winDecTemp.enable = winDec2.enable;
  40806. + winDecTemp.target = winDec2.target;
  40807. +
  40808. + /* winDec2 = winDec1 */
  40809. + winDec2.addrWin.baseHigh = winDec1.addrWin.baseHigh;
  40810. + winDec2.addrWin.baseLow = winDec1.addrWin.baseLow;
  40811. + winDec2.addrWin.size = winDec1.addrWin.size;
  40812. + winDec2.enable = winDec1.enable;
  40813. + winDec2.target = winDec1.target;
  40814. +
  40815. +
  40816. + /* winDec1 = winDecTemp */
  40817. + winDec1.addrWin.baseHigh = winDecTemp.addrWin.baseHigh;
  40818. + winDec1.addrWin.baseLow = winDecTemp.addrWin.baseLow;
  40819. + winDec1.addrWin.size = winDecTemp.addrWin.size;
  40820. + winDec1.enable = winDecTemp.enable;
  40821. + winDec1.target = winDecTemp.target;
  40822. +
  40823. +
  40824. + /* now set the new values */
  40825. +
  40826. +
  40827. + mvAhbToMbusWinSet(winNum1,&winDec1);
  40828. + mvAhbToMbusWinSet(winNum2,&winDec2);
  40829. +
  40830. +
  40831. +
  40832. +
  40833. +
  40834. + /* now we will treat the remap windows if exist */
  40835. +
  40836. +
  40837. + /* now check if one or both windows has a remap window
  40838. + as well after the swap ! */
  40839. +
  40840. + /* if a window had a remap value differnt than the base value
  40841. + before the swap , then after the swap the remap value will be
  40842. + equal to the base value unless both windows has a remap windows*/
  40843. +
  40844. + /* first get old values */
  40845. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))
  40846. + {
  40847. + remapBaseLow1 = MV_REG_READ(remapRegs1.lowRegOffs);
  40848. + remapBaseHigh1 = MV_REG_READ(remapRegs1.highRegOffs);
  40849. +
  40850. + }
  40851. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
  40852. + {
  40853. + remapBaseLow2 = MV_REG_READ(remapRegs2.lowRegOffs);
  40854. + remapBaseHigh2 = MV_REG_READ(remapRegs2.highRegOffs);
  40855. +
  40856. +
  40857. + }
  40858. +
  40859. + /* now do the swap */
  40860. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))
  40861. + {
  40862. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
  40863. + {
  40864. + /* Two windows has a remap !!! so swap */
  40865. +
  40866. + MV_REG_WRITE(remapRegs2.highRegOffs,remapBaseHigh1);
  40867. + MV_REG_WRITE(remapRegs2.lowRegOffs,remapBaseLow1);
  40868. +
  40869. + MV_REG_WRITE(remapRegs1.highRegOffs,remapBaseHigh2);
  40870. + MV_REG_WRITE(remapRegs1.lowRegOffs,remapBaseLow2);
  40871. +
  40872. +
  40873. +
  40874. + }
  40875. + else
  40876. + {
  40877. + /* remap == base */
  40878. + MV_REG_WRITE(remapRegs1.highRegOffs,winDec1.addrWin.baseHigh);
  40879. + MV_REG_WRITE(remapRegs1.lowRegOffs,winDec1.addrWin.baseLow);
  40880. +
  40881. + }
  40882. +
  40883. + }
  40884. + else if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
  40885. + {
  40886. + /* remap == base */
  40887. + MV_REG_WRITE(remapRegs2.highRegOffs,winDec2.addrWin.baseHigh);
  40888. + MV_REG_WRITE(remapRegs2.lowRegOffs,winDec2.addrWin.baseLow);
  40889. +
  40890. + }
  40891. +
  40892. +
  40893. +
  40894. + return MV_OK;
  40895. +
  40896. +
  40897. +}
  40898. +
  40899. +
  40900. +
  40901. +#if defined(MV_88F1181)
  40902. +
  40903. +/*******************************************************************************
  40904. +* mvAhbToMbusXbarCtrlSet - Set The CPU master Xbar arbitration.
  40905. +*
  40906. +* DESCRIPTION:
  40907. +* This function sets CPU Mbus Arbiter
  40908. +*
  40909. +* INPUT:
  40910. +* pPizzaArbArray - A priority Structure describing 16 "pizza slices". At
  40911. +* each clock cycle, the crossbar arbiter samples all
  40912. +* requests and gives the bus to the next agent according
  40913. +* to the "pizza".
  40914. +*
  40915. +* OUTPUT:
  40916. +* N/A
  40917. +*
  40918. +* RETURN:
  40919. +* MV_ERROR if paramers to function invalid.
  40920. +*
  40921. +*******************************************************************************/
  40922. +MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray)
  40923. +{
  40924. + MV_U32 sliceNum;
  40925. + MV_U32 xbarCtrl = 0;
  40926. + MV_MBUS_ARB_TARGET xbarTarget;
  40927. +
  40928. + /* 1) Set crossbar control low register */
  40929. + for (sliceNum = 0; sliceNum < MRLR_SLICE_NUM; sliceNum++)
  40930. + {
  40931. + xbarTarget = pPizzaArbArray[sliceNum];
  40932. +
  40933. + /* sliceNum parameter check */
  40934. + if (xbarTarget > MAX_MBUS_ARB_TARGETS)
  40935. + {
  40936. + mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",
  40937. + xbarTarget);
  40938. + return MV_ERROR;
  40939. + }
  40940. + xbarCtrl |= (xbarTarget << MRLR_LOW_ARB_OFFS(sliceNum));
  40941. + }
  40942. + /* Write to crossbar control low register */
  40943. + MV_REG_WRITE(MBUS_ARBITER_LOW_REG, xbarCtrl);
  40944. +
  40945. + xbarCtrl = 0;
  40946. +
  40947. + /* 2) Set crossbar control high register */
  40948. + for (sliceNum = MRLR_SLICE_NUM;
  40949. + sliceNum < MRLR_SLICE_NUM+MRHR_SLICE_NUM;
  40950. + sliceNum++)
  40951. + {
  40952. +
  40953. + xbarTarget = pPizzaArbArray[sliceNum];
  40954. +
  40955. + /* sliceNum parameter check */
  40956. + if (xbarTarget > MAX_MBUS_ARB_TARGETS)
  40957. + {
  40958. + mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",
  40959. + xbarTarget);
  40960. + return MV_ERROR;
  40961. + }
  40962. + xbarCtrl |= (xbarTarget << MRHR_HIGH_ARB_OFFS(sliceNum));
  40963. + }
  40964. + /* Write to crossbar control high register */
  40965. + MV_REG_WRITE(MBUS_ARBITER_HIGH_REG, xbarCtrl);
  40966. +
  40967. + return MV_OK;
  40968. +}
  40969. +
  40970. +/*******************************************************************************
  40971. +* mvMbusArbCtrlSet - Set MBus Arbiter control register
  40972. +*
  40973. +* DESCRIPTION:
  40974. +*
  40975. +* INPUT:
  40976. +* ctrl - pointer to MV_MBUS_ARB_CTRL register
  40977. +*
  40978. +* OUTPUT:
  40979. +* N/A
  40980. +*
  40981. +* RETURN:
  40982. +* MV_ERROR if paramers to function invalid.
  40983. +*
  40984. +*******************************************************************************/
  40985. +MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl)
  40986. +{
  40987. +
  40988. + if (ctrl->highPrio == MV_FALSE)
  40989. + {
  40990. + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);
  40991. + }
  40992. + else
  40993. + {
  40994. + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);
  40995. + }
  40996. +
  40997. + if (ctrl->fixedRoundRobin == MV_FALSE)
  40998. + {
  40999. + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);
  41000. + }
  41001. + else
  41002. + {
  41003. + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);
  41004. + }
  41005. +
  41006. + if (ctrl->starvEn == MV_FALSE)
  41007. + {
  41008. + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);
  41009. + }
  41010. + else
  41011. + {
  41012. + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);
  41013. + }
  41014. +
  41015. + return MV_OK;
  41016. +}
  41017. +
  41018. +/*******************************************************************************
  41019. +* mvMbusArbCtrlGet - Get MBus Arbiter control register
  41020. +*
  41021. +* DESCRIPTION:
  41022. +*
  41023. +* INPUT:
  41024. +* ctrl - pointer to MV_MBUS_ARB_CTRL register
  41025. +*
  41026. +* OUTPUT:
  41027. +* ctrl - pointer to MV_MBUS_ARB_CTRL register
  41028. +*
  41029. +* RETURN:
  41030. +* MV_ERROR if paramers to function invalid.
  41031. +*
  41032. +*******************************************************************************/
  41033. +MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl)
  41034. +{
  41035. +
  41036. + MV_U32 ctrlReg = MV_REG_READ(MBUS_ARBITER_CTRL_REG);
  41037. +
  41038. + if (ctrlReg & MACR_ARB_ARM_TOP)
  41039. + {
  41040. + ctrl->highPrio = MV_TRUE;
  41041. + }
  41042. + else
  41043. + {
  41044. + ctrl->highPrio = MV_FALSE;
  41045. + }
  41046. +
  41047. + if (ctrlReg & MACR_ARB_TARGET_FIXED)
  41048. + {
  41049. + ctrl->fixedRoundRobin = MV_TRUE;
  41050. + }
  41051. + else
  41052. + {
  41053. + ctrl->fixedRoundRobin = MV_FALSE;
  41054. + }
  41055. +
  41056. + if (ctrlReg & MACR_ARB_REQ_CTRL_EN)
  41057. + {
  41058. + ctrl->starvEn = MV_TRUE;
  41059. + }
  41060. + else
  41061. + {
  41062. + ctrl->starvEn = MV_FALSE;
  41063. + }
  41064. +
  41065. +
  41066. + return MV_OK;
  41067. +}
  41068. +
  41069. +#endif /* #if defined(MV_88F1181) */
  41070. +
  41071. +
  41072. +
  41073. +/*******************************************************************************
  41074. +* ahbToMbusRemapRegOffsGet - Get CPU address remap register offsets
  41075. +*
  41076. +* DESCRIPTION:
  41077. +* CPU to PCI address remap registers offsets are inconsecutive.
  41078. +* This function returns PCI address remap registers offsets.
  41079. +*
  41080. +* INPUT:
  41081. +* winNum - Address decode window number. See MV_U32 enumerator.
  41082. +*
  41083. +* OUTPUT:
  41084. +* None.
  41085. +*
  41086. +* RETURN:
  41087. +* MV_ERROR if winNum is not a PCI one.
  41088. +*
  41089. +*******************************************************************************/
  41090. +static MV_STATUS ahbToMbusRemapRegOffsGet(MV_U32 winNum,
  41091. + AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs)
  41092. +{
  41093. + switch (winNum)
  41094. + {
  41095. + case 0:
  41096. + case 1:
  41097. + pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);
  41098. + pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);
  41099. + break;
  41100. + case 2:
  41101. + case 3:
  41102. + if((mvCtrlModelGet() == MV_5281_DEV_ID) ||
  41103. + (mvCtrlModelGet() == MV_1281_DEV_ID) ||
  41104. + (mvCtrlModelGet() == MV_6183_DEV_ID) ||
  41105. + (mvCtrlModelGet() == MV_6183L_DEV_ID))
  41106. + {
  41107. + pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);
  41108. + pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);
  41109. + break;
  41110. + }
  41111. + else
  41112. + {
  41113. + pRemapRegs->lowRegOffs = 0;
  41114. + pRemapRegs->highRegOffs = 0;
  41115. +
  41116. + DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",
  41117. + winNum));
  41118. + return MV_NO_SUCH;
  41119. + }
  41120. + default:
  41121. + {
  41122. + pRemapRegs->lowRegOffs = 0;
  41123. + pRemapRegs->highRegOffs = 0;
  41124. +
  41125. + DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",
  41126. + winNum));
  41127. + return MV_NO_SUCH;
  41128. + }
  41129. + }
  41130. +
  41131. + return MV_OK;
  41132. +}
  41133. +
  41134. +/*******************************************************************************
  41135. +* mvAhbToMbusAddDecShow - Print the AHB to MBus bridge address decode map.
  41136. +*
  41137. +* DESCRIPTION:
  41138. +* This function print the CPU address decode map.
  41139. +*
  41140. +* INPUT:
  41141. +* None.
  41142. +*
  41143. +* OUTPUT:
  41144. +* None.
  41145. +*
  41146. +* RETURN:
  41147. +* None.
  41148. +*
  41149. +*******************************************************************************/
  41150. +MV_VOID mvAhbToMbusAddDecShow(MV_VOID)
  41151. +{
  41152. + MV_AHB_TO_MBUS_DEC_WIN win;
  41153. + MV_U32 winNum;
  41154. + mvOsOutput( "\n" );
  41155. + mvOsOutput( "AHB To MBUS Bridge:\n" );
  41156. + mvOsOutput( "-------------------\n" );
  41157. +
  41158. + for( winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS; winNum++ )
  41159. + {
  41160. + memset( &win, 0, sizeof(MV_AHB_TO_MBUS_DEC_WIN) );
  41161. +
  41162. + mvOsOutput( "win%d - ", winNum );
  41163. +
  41164. + if( mvAhbToMbusWinGet( winNum, &win ) == MV_OK )
  41165. + {
  41166. + if( win.enable )
  41167. + {
  41168. + mvOsOutput( "%s base %08x, ",
  41169. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  41170. + mvOsOutput( "...." );
  41171. + mvSizePrint( win.addrWin.size );
  41172. +
  41173. + mvOsOutput( "\n" );
  41174. +
  41175. + }
  41176. + else
  41177. + mvOsOutput( "disable\n" );
  41178. + }
  41179. + }
  41180. +
  41181. +}
  41182. +
  41183. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h
  41184. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h 1970-01-01 01:00:00.000000000 +0100
  41185. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h 2011-07-31 11:31:57.163532892 +0200
  41186. @@ -0,0 +1,130 @@
  41187. +/*******************************************************************************
  41188. +Copyright (C) Marvell International Ltd. and its affiliates
  41189. +
  41190. +This software file (the "File") is owned and distributed by Marvell
  41191. +International Ltd. and/or its affiliates ("Marvell") under the following
  41192. +alternative licensing terms. Once you have made an election to distribute the
  41193. +File under one of the following license alternatives, please (i) delete this
  41194. +introductory statement regarding license alternatives, (ii) delete the two
  41195. +license alternatives that you have not elected to use and (iii) preserve the
  41196. +Marvell copyright notice above.
  41197. +
  41198. +********************************************************************************
  41199. +Marvell Commercial License Option
  41200. +
  41201. +If you received this File from Marvell and you have entered into a commercial
  41202. +license agreement (a "Commercial License") with Marvell, the File is licensed
  41203. +to you under the terms of the applicable Commercial License.
  41204. +
  41205. +********************************************************************************
  41206. +Marvell GPL License Option
  41207. +
  41208. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41209. +modify this File in accordance with the terms and conditions of the General
  41210. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  41211. +available along with the File in the license.txt file or by writing to the Free
  41212. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  41213. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  41214. +
  41215. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  41216. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  41217. +DISCLAIMED. The GPL License provides additional details about this warranty
  41218. +disclaimer.
  41219. +********************************************************************************
  41220. +Marvell BSD License Option
  41221. +
  41222. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41223. +modify this File under the following licensing terms.
  41224. +Redistribution and use in source and binary forms, with or without modification,
  41225. +are permitted provided that the following conditions are met:
  41226. +
  41227. + * Redistributions of source code must retain the above copyright notice,
  41228. + this list of conditions and the following disclaimer.
  41229. +
  41230. + * Redistributions in binary form must reproduce the above copyright
  41231. + notice, this list of conditions and the following disclaimer in the
  41232. + documentation and/or other materials provided with the distribution.
  41233. +
  41234. + * Neither the name of Marvell nor the names of its contributors may be
  41235. + used to endorse or promote products derived from this software without
  41236. + specific prior written permission.
  41237. +
  41238. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  41239. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  41240. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41241. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  41242. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  41243. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  41244. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41245. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  41246. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  41247. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  41248. +
  41249. +*******************************************************************************/
  41250. +
  41251. +
  41252. +#ifndef __INCmvAhbToMbush
  41253. +#define __INCmvAhbToMbush
  41254. +
  41255. +/* includes */
  41256. +#include "ctrlEnv/mvCtrlEnvLib.h"
  41257. +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
  41258. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  41259. +
  41260. +/* defines */
  41261. +
  41262. +#if defined(MV_88F1181)
  41263. +/* This enumerator defines the Marvell controller possible MBUS arbiter */
  41264. +/* target ports. It is used to define crossbar priority scheame (pizza) */
  41265. +typedef enum _mvMBusArbTargetId
  41266. +{
  41267. + DRAM_MBUS_ARB_TARGET = 0, /* Port 0 -> DRAM interface */
  41268. + TWSI_MBUS_ARB_TARGET = 1, /* Port 1 -> TWSI */
  41269. + ARM_MBUS_ARB_TARGET = 2, /* Port 2 -> ARM */
  41270. + PEX1_MBUS_ARB_TARGET = 3, /* Port 3 -> PCI Express 1 */
  41271. + PEX0_MBUS_ARB_TARGET = 4, /* Port 4 -> PCI Express0 */
  41272. + MAX_MBUS_ARB_TARGETS
  41273. +}MV_MBUS_ARB_TARGET;
  41274. +
  41275. +typedef struct _mvMBusArbCtrl
  41276. +{
  41277. + MV_BOOL starvEn;
  41278. + MV_BOOL highPrio;
  41279. + MV_BOOL fixedRoundRobin;
  41280. +
  41281. +}MV_MBUS_ARB_CTRL;
  41282. +
  41283. +#endif /* #if defined(MV_88F1181) */
  41284. +
  41285. +typedef struct _mvAhbtoMbusDecWin
  41286. +{
  41287. + MV_TARGET target;
  41288. + MV_ADDR_WIN addrWin; /* An address window*/
  41289. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  41290. +
  41291. +}MV_AHB_TO_MBUS_DEC_WIN;
  41292. +
  41293. +/* mvAhbToMbus.h API list */
  41294. +
  41295. +MV_STATUS mvAhbToMbusInit(MV_VOID);
  41296. +MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);
  41297. +MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);
  41298. +MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum,MV_BOOL enable);
  41299. +MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrDecWin);
  41300. +MV_U32 mvAhbToMbusWinTargetGet(MV_TARGET target);
  41301. +MV_U32 mvAhbToMbusWinAvailGet(MV_VOID);
  41302. +MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2);
  41303. +
  41304. +#if defined(MV_88F1181)
  41305. +
  41306. +MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray);
  41307. +MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl);
  41308. +MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl);
  41309. +
  41310. +#endif /* #if defined(MV_88F1181) */
  41311. +
  41312. +
  41313. +MV_VOID mvAhbToMbusAddDecShow(MV_VOID);
  41314. +
  41315. +
  41316. +#endif /* __INCmvAhbToMbush */
  41317. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h
  41318. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h 1970-01-01 01:00:00.000000000 +0100
  41319. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h 2011-07-31 11:31:57.253415286 +0200
  41320. @@ -0,0 +1,143 @@
  41321. +/*******************************************************************************
  41322. +Copyright (C) Marvell International Ltd. and its affiliates
  41323. +
  41324. +This software file (the "File") is owned and distributed by Marvell
  41325. +International Ltd. and/or its affiliates ("Marvell") under the following
  41326. +alternative licensing terms. Once you have made an election to distribute the
  41327. +File under one of the following license alternatives, please (i) delete this
  41328. +introductory statement regarding license alternatives, (ii) delete the two
  41329. +license alternatives that you have not elected to use and (iii) preserve the
  41330. +Marvell copyright notice above.
  41331. +
  41332. +********************************************************************************
  41333. +Marvell Commercial License Option
  41334. +
  41335. +If you received this File from Marvell and you have entered into a commercial
  41336. +license agreement (a "Commercial License") with Marvell, the File is licensed
  41337. +to you under the terms of the applicable Commercial License.
  41338. +
  41339. +********************************************************************************
  41340. +Marvell GPL License Option
  41341. +
  41342. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41343. +modify this File in accordance with the terms and conditions of the General
  41344. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  41345. +available along with the File in the license.txt file or by writing to the Free
  41346. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  41347. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  41348. +
  41349. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  41350. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  41351. +DISCLAIMED. The GPL License provides additional details about this warranty
  41352. +disclaimer.
  41353. +********************************************************************************
  41354. +Marvell BSD License Option
  41355. +
  41356. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41357. +modify this File under the following licensing terms.
  41358. +Redistribution and use in source and binary forms, with or without modification,
  41359. +are permitted provided that the following conditions are met:
  41360. +
  41361. + * Redistributions of source code must retain the above copyright notice,
  41362. + this list of conditions and the following disclaimer.
  41363. +
  41364. + * Redistributions in binary form must reproduce the above copyright
  41365. + notice, this list of conditions and the following disclaimer in the
  41366. + documentation and/or other materials provided with the distribution.
  41367. +
  41368. + * Neither the name of Marvell nor the names of its contributors may be
  41369. + used to endorse or promote products derived from this software without
  41370. + specific prior written permission.
  41371. +
  41372. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  41373. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  41374. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41375. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  41376. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  41377. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  41378. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41379. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  41380. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  41381. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  41382. +
  41383. +*******************************************************************************/
  41384. +
  41385. +
  41386. +#ifndef __INCmvAhbToMbusRegsh
  41387. +#define __INCmvAhbToMbusRegsh
  41388. +
  41389. +/******************************/
  41390. +/* ARM Address Map Registers */
  41391. +/******************************/
  41392. +
  41393. +#define MAX_AHB_TO_MBUS_WINS 9
  41394. +#define MV_AHB_TO_MBUS_INTREG_WIN 8
  41395. +
  41396. +
  41397. +#define AHB_TO_MBUS_WIN_CTRL_REG(winNum) (0x20000 + (winNum)*0x10)
  41398. +#define AHB_TO_MBUS_WIN_BASE_REG(winNum) (0x20004 + (winNum)*0x10)
  41399. +#define AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum) (0x20008 + (winNum)*0x10)
  41400. +#define AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum) (0x2000C + (winNum)*0x10)
  41401. +#define AHB_TO_MBUS_WIN_INTEREG_REG 0x20080
  41402. +
  41403. +/* Window Control Register */
  41404. +/* AHB_TO_MBUS_WIN_CTRL_REG (ATMWCR)*/
  41405. +#define ATMWCR_WIN_ENABLE BIT0 /* Window Enable */
  41406. +
  41407. +#define ATMWCR_WIN_TARGET_OFFS 4 /* The target interface associated
  41408. + with this window*/
  41409. +#define ATMWCR_WIN_TARGET_MASK (0xf << ATMWCR_WIN_TARGET_OFFS)
  41410. +
  41411. +#define ATMWCR_WIN_ATTR_OFFS 8 /* The target interface attributes
  41412. + Associated with this window */
  41413. +#define ATMWCR_WIN_ATTR_MASK (0xff << ATMWCR_WIN_ATTR_OFFS)
  41414. +
  41415. +
  41416. +/*
  41417. +Used with the Base register to set the address window size and location
  41418. +Must be programed from LSB to MSB as sequence of 1’s followed
  41419. +by sequence of 0’s. The number of 1’s specifies the size of the window
  41420. +in 64 KB granularity (e.g. a value of 0x00FF specifies 256 = 16 MB).
  41421. +
  41422. +NOTE: A value of 0x0 specifies 64KB size.
  41423. +*/
  41424. +#define ATMWCR_WIN_SIZE_OFFS 16 /* Window Size */
  41425. +#define ATMWCR_WIN_SIZE_MASK (0xffff << ATMWCR_WIN_SIZE_OFFS)
  41426. +#define ATMWCR_WIN_SIZE_ALIGNMENT 0x10000
  41427. +
  41428. +/* Window Base Register */
  41429. +/* AHB_TO_MBUS_WIN_BASE_REG (ATMWBR) */
  41430. +
  41431. +/*
  41432. +Used with the size field to set the address window size and location.
  41433. +Corresponds to transaction address[31:16]
  41434. +*/
  41435. +#define ATMWBR_BASE_OFFS 16 /* Base Address */
  41436. +#define ATMWBR_BASE_MASK (0xffff << ATMWBR_BASE_OFFS)
  41437. +#define ATMWBR_BASE_ALIGNMENT 0x10000
  41438. +
  41439. +/* Window Remap Low Register */
  41440. +/* AHB_TO_MBUS_WIN_REMAP_LOW_REG (ATMWRLR) */
  41441. +
  41442. +/*
  41443. +Used with the size field to specifies address bits[31:0] to be driven to
  41444. +the target interface.:
  41445. +target_addr[31:16] = (addr[31:16] & size[15:0]) | (remap[31:16] & ~size[15:0])
  41446. +*/
  41447. +#define ATMWRLR_REMAP_LOW_OFFS 16 /* Remap Address */
  41448. +#define ATMWRLR_REMAP_LOW_MASK (0xffff << ATMWRLR_REMAP_LOW_OFFS)
  41449. +#define ATMWRLR_REMAP_LOW_ALIGNMENT 0x10000
  41450. +
  41451. +/* Window Remap High Register */
  41452. +/* AHB_TO_MBUS_WIN_REMAP_HIGH_REG (ATMWRHR) */
  41453. +
  41454. +/*
  41455. +Specifies address bits[63:32] to be driven to the target interface.
  41456. +target_addr[63:32] = (RemapHigh[31:0]
  41457. +*/
  41458. +#define ATMWRHR_REMAP_HIGH_OFFS 0 /* Remap Address */
  41459. +#define ATMWRHR_REMAP_HIGH_MASK (0xffffffff << ATMWRHR_REMAP_HIGH_OFFS)
  41460. +
  41461. +
  41462. +#endif /* __INCmvAhbToMbusRegsh */
  41463. +
  41464. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c
  41465. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c 1970-01-01 01:00:00.000000000 +0100
  41466. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c 2011-07-31 11:31:57.313426138 +0200
  41467. @@ -0,0 +1,1036 @@
  41468. +/*******************************************************************************
  41469. +Copyright (C) Marvell International Ltd. and its affiliates
  41470. +
  41471. +This software file (the "File") is owned and distributed by Marvell
  41472. +International Ltd. and/or its affiliates ("Marvell") under the following
  41473. +alternative licensing terms. Once you have made an election to distribute the
  41474. +File under one of the following license alternatives, please (i) delete this
  41475. +introductory statement regarding license alternatives, (ii) delete the two
  41476. +license alternatives that you have not elected to use and (iii) preserve the
  41477. +Marvell copyright notice above.
  41478. +
  41479. +********************************************************************************
  41480. +Marvell Commercial License Option
  41481. +
  41482. +If you received this File from Marvell and you have entered into a commercial
  41483. +license agreement (a "Commercial License") with Marvell, the File is licensed
  41484. +to you under the terms of the applicable Commercial License.
  41485. +
  41486. +********************************************************************************
  41487. +Marvell GPL License Option
  41488. +
  41489. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41490. +modify this File in accordance with the terms and conditions of the General
  41491. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  41492. +available along with the File in the license.txt file or by writing to the Free
  41493. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  41494. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  41495. +
  41496. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  41497. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  41498. +DISCLAIMED. The GPL License provides additional details about this warranty
  41499. +disclaimer.
  41500. +********************************************************************************
  41501. +Marvell BSD License Option
  41502. +
  41503. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41504. +modify this File under the following licensing terms.
  41505. +Redistribution and use in source and binary forms, with or without modification,
  41506. +are permitted provided that the following conditions are met:
  41507. +
  41508. + * Redistributions of source code must retain the above copyright notice,
  41509. + this list of conditions and the following disclaimer.
  41510. +
  41511. + * Redistributions in binary form must reproduce the above copyright
  41512. + notice, this list of conditions and the following disclaimer in the
  41513. + documentation and/or other materials provided with the distribution.
  41514. +
  41515. + * Neither the name of Marvell nor the names of its contributors may be
  41516. + used to endorse or promote products derived from this software without
  41517. + specific prior written permission.
  41518. +
  41519. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  41520. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  41521. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41522. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  41523. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  41524. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  41525. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41526. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  41527. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  41528. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  41529. +
  41530. +*******************************************************************************/
  41531. +
  41532. +
  41533. +/* includes */
  41534. +#include "ctrlEnv/sys/mvCpuIf.h"
  41535. +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
  41536. +#include "cpu/mvCpu.h"
  41537. +#include "ctrlEnv/mvCtrlEnvLib.h"
  41538. +#include "mvSysHwConfig.h"
  41539. +#include "mvSysDram.h"
  41540. +
  41541. +/*#define MV_DEBUG*/
  41542. +/* defines */
  41543. +
  41544. +#ifdef MV_DEBUG
  41545. + #define DB(x) x
  41546. +#else
  41547. + #define DB(x)
  41548. +#endif
  41549. +
  41550. +/* locals */
  41551. +/* static functions */
  41552. +static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
  41553. +
  41554. +MV_TARGET * sampleAtResetTargetArray;
  41555. +MV_TARGET sampleAtResetTargetArrayP[] = BOOT_TARGETS_NAME_ARRAY;
  41556. +MV_TARGET sampleAtResetTargetArray6180P[] = BOOT_TARGETS_NAME_ARRAY_6180;
  41557. +/*******************************************************************************
  41558. +* mvCpuIfInit - Initialize Controller CPU interface
  41559. +*
  41560. +* DESCRIPTION:
  41561. +* This function initialize Controller CPU interface:
  41562. +* 1. Set CPU interface configuration registers.
  41563. +* 2. Set CPU master Pizza arbiter control according to static
  41564. +* configuration described in configuration file.
  41565. +* 3. Opens CPU address decode windows. DRAM windows are assumed to be
  41566. +* already set (auto detection).
  41567. +*
  41568. +* INPUT:
  41569. +* None.
  41570. +*
  41571. +* OUTPUT:
  41572. +* None.
  41573. +*
  41574. +* RETURN:
  41575. +* None.
  41576. +*
  41577. +*******************************************************************************/
  41578. +MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap)
  41579. +{
  41580. + MV_U32 regVal;
  41581. + MV_TARGET target;
  41582. + MV_ADDR_WIN addrWin;
  41583. +
  41584. + if (cpuAddrWinMap == NULL)
  41585. + {
  41586. + DB(mvOsPrintf("mvCpuIfInit:ERR. cpuAddrWinMap == NULL\n"));
  41587. + return MV_ERROR;
  41588. + }
  41589. +
  41590. + /*Initialize the boot target array according to device type*/
  41591. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  41592. + sampleAtResetTargetArray = sampleAtResetTargetArray6180P;
  41593. + else
  41594. + sampleAtResetTargetArray = sampleAtResetTargetArrayP;
  41595. +
  41596. + /* Set ARM Configuration register */
  41597. + regVal = MV_REG_READ(CPU_CONFIG_REG);
  41598. + regVal &= ~CPU_CONFIG_DEFAULT_MASK;
  41599. + regVal |= CPU_CONFIG_DEFAULT;
  41600. + MV_REG_WRITE(CPU_CONFIG_REG,regVal);
  41601. +
  41602. + /* First disable all CPU target windows */
  41603. + for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
  41604. + {
  41605. + if ((MV_TARGET_IS_DRAM(target))||(target == INTER_REGS))
  41606. + {
  41607. + continue;
  41608. + }
  41609. +
  41610. +#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
  41611. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  41612. + if (MV_TARGET_IS_PCI(target))
  41613. + {
  41614. + continue;
  41615. + }
  41616. +#endif
  41617. +
  41618. +#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
  41619. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  41620. + if (MV_TARGET_IS_PEX(target))
  41621. + {
  41622. + continue;
  41623. + }
  41624. +#endif
  41625. +#if defined(MV_RUN_FROM_FLASH)
  41626. + /* Don't disable the boot device. */
  41627. + if (target == DEV_BOOCS)
  41628. + {
  41629. + continue;
  41630. + }
  41631. +#endif /* MV_RUN_FROM_FLASH */
  41632. + mvCpuIfTargetWinEnable(MV_CHANGE_BOOT_CS(target),MV_FALSE);
  41633. + }
  41634. +
  41635. +#if defined(MV_RUN_FROM_FLASH)
  41636. + /* Resize the bootcs windows before other windows, because this */
  41637. + /* window is enabled and will cause an overlap if not resized. */
  41638. + target = DEV_BOOCS;
  41639. +
  41640. + if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
  41641. + {
  41642. + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
  41643. + return MV_ERROR;
  41644. + }
  41645. +
  41646. + addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
  41647. + addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
  41648. + if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
  41649. + {
  41650. + DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
  41651. + cpuAddrWinMap[target].winNum));
  41652. + }
  41653. +
  41654. +#endif /* MV_RUN_FROM_FLASH */
  41655. +
  41656. + /* Go through all targets in user table until table terminator */
  41657. + for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
  41658. + {
  41659. +
  41660. +#if defined(MV_RUN_FROM_FLASH)
  41661. + if (target == DEV_BOOCS)
  41662. + {
  41663. + continue;
  41664. + }
  41665. +#endif /* MV_RUN_FROM_FLASH */
  41666. +
  41667. + /* if DRAM auto sizing is used do not initialized DRAM target windows, */
  41668. + /* assuming this already has been done earlier. */
  41669. +#ifdef MV_DRAM_AUTO_SIZE
  41670. + if (MV_TARGET_IS_DRAM(target))
  41671. + {
  41672. + continue;
  41673. + }
  41674. +#endif
  41675. +
  41676. +#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
  41677. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  41678. + if (MV_TARGET_IS_PCI(target))
  41679. + {
  41680. + continue;
  41681. + }
  41682. +#endif
  41683. +
  41684. +#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
  41685. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  41686. + if (MV_TARGET_IS_PEX(target))
  41687. + {
  41688. + continue;
  41689. + }
  41690. +#endif
  41691. + /* If the target attribute is the same as the boot device attribute */
  41692. + /* then it's stays disable */
  41693. + if (MV_TARGET_IS_AS_BOOT(target))
  41694. + {
  41695. + continue;
  41696. + }
  41697. +
  41698. + if((0 == cpuAddrWinMap[target].addrWin.size) ||
  41699. + (DIS == cpuAddrWinMap[target].enable))
  41700. +
  41701. + {
  41702. + if (MV_OK != mvCpuIfTargetWinEnable(target, MV_FALSE))
  41703. + {
  41704. + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinEnable fail\n"));
  41705. + return MV_ERROR;
  41706. + }
  41707. +
  41708. + }
  41709. + else
  41710. + {
  41711. + if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
  41712. + {
  41713. + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
  41714. + return MV_ERROR;
  41715. + }
  41716. +
  41717. + addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
  41718. + addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
  41719. + if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
  41720. + {
  41721. + DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
  41722. + cpuAddrWinMap[target].winNum));
  41723. + }
  41724. +
  41725. +
  41726. + }
  41727. + }
  41728. +
  41729. + return MV_OK;
  41730. +
  41731. +
  41732. +}
  41733. +
  41734. +
  41735. +/*******************************************************************************
  41736. +* mvCpuIfTargetWinSet - Set CPU-to-peripheral target address window
  41737. +*
  41738. +* DESCRIPTION:
  41739. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI0_MEM0)
  41740. +* address window, also known as address decode window.
  41741. +* A new address decode window is set for specified target address window.
  41742. +* If address decode window parameter structure enables the window,
  41743. +* the routine will also enable the target window, allowing CPU to access
  41744. +* the target window.
  41745. +*
  41746. +* INPUT:
  41747. +* target - Peripheral target enumerator.
  41748. +* pAddrDecWin - CPU target window data structure.
  41749. +*
  41750. +* OUTPUT:
  41751. +* N/A
  41752. +*
  41753. +* RETURN:
  41754. +* MV_OK if CPU target window was set correctly, MV_ERROR in case of
  41755. +* address window overlapps with other active CPU target window or
  41756. +* trying to assign 36bit base address while CPU does not support that.
  41757. +* The function returns MV_NOT_SUPPORTED, if the target is unsupported.
  41758. +*
  41759. +*******************************************************************************/
  41760. +MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)
  41761. +{
  41762. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  41763. + MV_U32 existingWinNum;
  41764. + MV_DRAM_DEC_WIN addrDecWin;
  41765. +
  41766. + target = MV_CHANGE_BOOT_CS(target);
  41767. +
  41768. + /* Check parameters */
  41769. + if (target >= MAX_TARGETS)
  41770. + {
  41771. + mvOsPrintf("mvCpuIfTargetWinSet: target %d is Illigal\n", target);
  41772. + return MV_ERROR;
  41773. + }
  41774. +
  41775. + /* 2) Check if the requested window overlaps with current windows */
  41776. + if (MV_TRUE == cpuTargetWinOverlap(target, &pAddrDecWin->addrWin))
  41777. + {
  41778. + mvOsPrintf("mvCpuIfTargetWinSet: ERR. Target %d overlap\n", target);
  41779. + return MV_BAD_PARAM;
  41780. + }
  41781. +
  41782. + if (MV_TARGET_IS_DRAM(target))
  41783. + {
  41784. + /* copy relevant data to MV_DRAM_DEC_WIN structure */
  41785. + addrDecWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
  41786. + addrDecWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
  41787. + addrDecWin.addrWin.size = pAddrDecWin->addrWin.size;
  41788. + addrDecWin.enable = pAddrDecWin->enable;
  41789. +
  41790. +
  41791. + if (mvDramIfWinSet(target,&addrDecWin) != MV_OK);
  41792. + {
  41793. + mvOsPrintf("mvCpuIfTargetWinSet: mvDramIfWinSet Failed\n");
  41794. + return MV_ERROR;
  41795. + }
  41796. +
  41797. + }
  41798. + else
  41799. + {
  41800. + /* copy relevant data to MV_AHB_TO_MBUS_DEC_WIN structure */
  41801. + decWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
  41802. + decWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
  41803. + decWin.addrWin.size = pAddrDecWin->addrWin.size;
  41804. + decWin.enable = pAddrDecWin->enable;
  41805. + decWin.target = target;
  41806. +
  41807. + existingWinNum = mvAhbToMbusWinTargetGet(target);
  41808. +
  41809. + /* check if there is already another Window configured
  41810. + for this target */
  41811. + if ((existingWinNum < MAX_AHB_TO_MBUS_WINS )&&
  41812. + (existingWinNum != pAddrDecWin->winNum))
  41813. + {
  41814. + /* if we want to enable the new winow number
  41815. + passed by the user , then the old one should
  41816. + be disabled */
  41817. + if (MV_TRUE == pAddrDecWin->enable)
  41818. + {
  41819. + /* be sure it is disabled */
  41820. + mvAhbToMbusWinEnable(existingWinNum , MV_FALSE);
  41821. + }
  41822. + }
  41823. +
  41824. + if (mvAhbToMbusWinSet(pAddrDecWin->winNum,&decWin) != MV_OK)
  41825. + {
  41826. + mvOsPrintf("mvCpuIfTargetWinSet: mvAhbToMbusWinSet Failed\n");
  41827. + return MV_ERROR;
  41828. + }
  41829. +
  41830. + }
  41831. +
  41832. + return MV_OK;
  41833. +}
  41834. +
  41835. +/*******************************************************************************
  41836. +* mvCpuIfTargetWinGet - Get CPU-to-peripheral target address window
  41837. +*
  41838. +* DESCRIPTION:
  41839. +* Get the CPU peripheral target address window.
  41840. +*
  41841. +* INPUT:
  41842. +* target - Peripheral target enumerator
  41843. +*
  41844. +* OUTPUT:
  41845. +* pAddrDecWin - CPU target window information data structure.
  41846. +*
  41847. +* RETURN:
  41848. +* MV_OK if target exist, MV_ERROR otherwise.
  41849. +*
  41850. +*******************************************************************************/
  41851. +MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)
  41852. +{
  41853. +
  41854. + MV_U32 winNum=0xffffffff;
  41855. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  41856. + MV_DRAM_DEC_WIN addrDecWin;
  41857. +
  41858. + target = MV_CHANGE_BOOT_CS(target);
  41859. +
  41860. + /* Check parameters */
  41861. + if (target >= MAX_TARGETS)
  41862. + {
  41863. + mvOsPrintf("mvCpuIfTargetWinGet: target %d is Illigal\n", target);
  41864. + return MV_ERROR;
  41865. + }
  41866. +
  41867. + if (MV_TARGET_IS_DRAM(target))
  41868. + {
  41869. + if (mvDramIfWinGet(target,&addrDecWin) != MV_OK)
  41870. + {
  41871. + mvOsPrintf("mvCpuIfTargetWinGet: Failed to get window target %d\n",
  41872. + target);
  41873. + return MV_ERROR;
  41874. + }
  41875. +
  41876. + /* copy relevant data to MV_CPU_DEC_WIN structure */
  41877. + pAddrDecWin->addrWin.baseLow = addrDecWin.addrWin.baseLow;
  41878. + pAddrDecWin->addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  41879. + pAddrDecWin->addrWin.size = addrDecWin.addrWin.size;
  41880. + pAddrDecWin->enable = addrDecWin.enable;
  41881. + pAddrDecWin->winNum = 0xffffffff;
  41882. +
  41883. + }
  41884. + else
  41885. + {
  41886. + /* get the Window number associated with this target */
  41887. +
  41888. + winNum = mvAhbToMbusWinTargetGet(target);
  41889. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  41890. + {
  41891. + return MV_NO_SUCH;
  41892. +
  41893. + }
  41894. +
  41895. + if (mvAhbToMbusWinGet(winNum , &decWin) != MV_OK)
  41896. + {
  41897. + mvOsPrintf("%s: mvAhbToMbusWinGet Failed at winNum = %d\n",
  41898. + __FUNCTION__, winNum);
  41899. + return MV_ERROR;
  41900. +
  41901. + }
  41902. +
  41903. + /* copy relevant data to MV_CPU_DEC_WIN structure */
  41904. + pAddrDecWin->addrWin.baseLow = decWin.addrWin.baseLow;
  41905. + pAddrDecWin->addrWin.baseHigh = decWin.addrWin.baseHigh;
  41906. + pAddrDecWin->addrWin.size = decWin.addrWin.size;
  41907. + pAddrDecWin->enable = decWin.enable;
  41908. + pAddrDecWin->winNum = winNum;
  41909. +
  41910. + }
  41911. +
  41912. +
  41913. +
  41914. +
  41915. + return MV_OK;
  41916. +}
  41917. +
  41918. +
  41919. +/*******************************************************************************
  41920. +* mvCpuIfTargetWinEnable - Enable/disable a CPU address decode window
  41921. +*
  41922. +* DESCRIPTION:
  41923. +* This function enable/disable a CPU address decode window.
  41924. +* if parameter 'enable' == MV_TRUE the routine will enable the
  41925. +* window, thus enabling CPU accesses (before enabling the window it is
  41926. +* tested for overlapping). Otherwise, the window will be disabled.
  41927. +*
  41928. +* INPUT:
  41929. +* target - Peripheral target enumerator.
  41930. +* enable - Enable/disable parameter.
  41931. +*
  41932. +* OUTPUT:
  41933. +* N/A
  41934. +*
  41935. +* RETURN:
  41936. +* MV_ERROR if protection window number was wrong, or the window
  41937. +* overlapps other target window.
  41938. +*
  41939. +*******************************************************************************/
  41940. +MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable)
  41941. +{
  41942. + MV_U32 winNum, temp;
  41943. + MV_CPU_DEC_WIN addrDecWin;
  41944. +
  41945. + target = MV_CHANGE_BOOT_CS(target);
  41946. +
  41947. + /* Check parameters */
  41948. + if (target >= MAX_TARGETS)
  41949. + {
  41950. + mvOsPrintf("mvCpuIfTargetWinEnable: target %d is Illigal\n", target);
  41951. + return MV_ERROR;
  41952. + }
  41953. +
  41954. + /* get the window and check if it exist */
  41955. + temp = mvCpuIfTargetWinGet(target, &addrDecWin);
  41956. + if (MV_NO_SUCH == temp)
  41957. + {
  41958. + return (enable? MV_ERROR: MV_OK);
  41959. + }
  41960. + else if( MV_OK != temp)
  41961. + {
  41962. + mvOsPrintf("%s: ERR. Getting target %d failed.\n",__FUNCTION__, target);
  41963. + return MV_ERROR;
  41964. + }
  41965. +
  41966. +
  41967. + /* check overlap */
  41968. +
  41969. + if (MV_TRUE == enable)
  41970. + {
  41971. + if (MV_TRUE == cpuTargetWinOverlap(target, &addrDecWin.addrWin))
  41972. + {
  41973. + DB(mvOsPrintf("%s: ERR. Target %d overlap\n",__FUNCTION__, target));
  41974. + return MV_ERROR;
  41975. + }
  41976. +
  41977. + }
  41978. +
  41979. +
  41980. + if (MV_TARGET_IS_DRAM(target))
  41981. + {
  41982. + if (mvDramIfWinEnable(target , enable) != MV_OK)
  41983. + {
  41984. + mvOsPrintf("mvCpuIfTargetWinGet: mvDramIfWinEnable Failed at \n");
  41985. + return MV_ERROR;
  41986. +
  41987. + }
  41988. +
  41989. + }
  41990. + else
  41991. + {
  41992. + /* get the Window number associated with this target */
  41993. +
  41994. + winNum = mvAhbToMbusWinTargetGet(target);
  41995. +
  41996. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  41997. + {
  41998. + return (enable? MV_ERROR: MV_OK);
  41999. + }
  42000. +
  42001. + if (mvAhbToMbusWinEnable(winNum , enable) != MV_OK)
  42002. + {
  42003. + mvOsPrintf("mvCpuIfTargetWinGet: Failed to enable window = %d\n",
  42004. + winNum);
  42005. + return MV_ERROR;
  42006. +
  42007. + }
  42008. +
  42009. + }
  42010. +
  42011. + return MV_OK;
  42012. +}
  42013. +
  42014. +
  42015. +/*******************************************************************************
  42016. +* mvCpuIfTargetWinSizeGet - Get CPU target address window size
  42017. +*
  42018. +* DESCRIPTION:
  42019. +* Get the size of CPU-to-peripheral target window.
  42020. +*
  42021. +* INPUT:
  42022. +* target - Peripheral target enumerator
  42023. +*
  42024. +* OUTPUT:
  42025. +* None.
  42026. +*
  42027. +* RETURN:
  42028. +* 32bit size. Function also returns '0' if window is closed.
  42029. +* Function returns 0xFFFFFFFF in case of an error.
  42030. +*
  42031. +*******************************************************************************/
  42032. +MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target)
  42033. +{
  42034. + MV_CPU_DEC_WIN addrDecWin;
  42035. +
  42036. + target = MV_CHANGE_BOOT_CS(target);
  42037. +
  42038. + /* Check parameters */
  42039. + if (target >= MAX_TARGETS)
  42040. + {
  42041. + mvOsPrintf("mvCpuIfTargetWinSizeGet: target %d is Illigal\n", target);
  42042. + return 0;
  42043. + }
  42044. +
  42045. + /* Get the winNum window */
  42046. + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
  42047. + {
  42048. + mvOsPrintf("mvCpuIfTargetWinSizeGet:ERR. Getting target %d failed.\n",
  42049. + target);
  42050. + return 0;
  42051. + }
  42052. +
  42053. + /* Check if window is enabled */
  42054. + if (addrDecWin.enable == MV_TRUE)
  42055. + {
  42056. + return (addrDecWin.addrWin.size);
  42057. + }
  42058. + else
  42059. + {
  42060. + return 0; /* Window disabled. return 0 */
  42061. + }
  42062. +}
  42063. +
  42064. +/*******************************************************************************
  42065. +* mvCpuIfTargetWinBaseLowGet - Get CPU target address window base low
  42066. +*
  42067. +* DESCRIPTION:
  42068. +* CPU-to-peripheral target address window base is constructed of
  42069. +* two parts: Low and high.
  42070. +* This function gets the CPU peripheral target low base address.
  42071. +*
  42072. +* INPUT:
  42073. +* target - Peripheral target enumerator
  42074. +*
  42075. +* OUTPUT:
  42076. +* None.
  42077. +*
  42078. +* RETURN:
  42079. +* 32bit low base address.
  42080. +*
  42081. +*******************************************************************************/
  42082. +MV_U32 mvCpuIfTargetWinBaseLowGet(MV_TARGET target)
  42083. +{
  42084. + MV_CPU_DEC_WIN addrDecWin;
  42085. +
  42086. + target = MV_CHANGE_BOOT_CS(target);
  42087. +
  42088. + /* Check parameters */
  42089. + if (target >= MAX_TARGETS)
  42090. + {
  42091. + mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);
  42092. + return 0xffffffff;
  42093. + }
  42094. +
  42095. + /* Get the target window */
  42096. + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
  42097. + {
  42098. + mvOsPrintf("mvCpuIfTargetWinBaseLowGet:ERR. Getting target %d failed.\n",
  42099. + target);
  42100. + return 0xffffffff;
  42101. + }
  42102. +
  42103. + if (MV_FALSE == addrDecWin.enable)
  42104. + {
  42105. + return 0xffffffff;
  42106. + }
  42107. + return (addrDecWin.addrWin.baseLow);
  42108. +}
  42109. +
  42110. +/*******************************************************************************
  42111. +* mvCpuIfTargetWinBaseHighGet - Get CPU target address window base high
  42112. +*
  42113. +* DESCRIPTION:
  42114. +* CPU-to-peripheral target address window base is constructed of
  42115. +* two parts: Low and high.
  42116. +* This function gets the CPU peripheral target high base address.
  42117. +*
  42118. +* INPUT:
  42119. +* target - Peripheral target enumerator
  42120. +*
  42121. +* OUTPUT:
  42122. +* None.
  42123. +*
  42124. +* RETURN:
  42125. +* 32bit high base address.
  42126. +*
  42127. +*******************************************************************************/
  42128. +MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target)
  42129. +{
  42130. + MV_CPU_DEC_WIN addrDecWin;
  42131. +
  42132. + target = MV_CHANGE_BOOT_CS(target);
  42133. +
  42134. + /* Check parameters */
  42135. + if (target >= MAX_TARGETS)
  42136. + {
  42137. + mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);
  42138. + return 0xffffffff;
  42139. + }
  42140. +
  42141. + /* Get the target window */
  42142. + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
  42143. + {
  42144. + mvOsPrintf("mvCpuIfTargetWinBaseHighGet:ERR. Getting target %d failed.\n",
  42145. + target);
  42146. + return 0xffffffff;
  42147. + }
  42148. +
  42149. + if (MV_FALSE == addrDecWin.enable)
  42150. + {
  42151. + return 0;
  42152. + }
  42153. +
  42154. + return (addrDecWin.addrWin.baseHigh);
  42155. +}
  42156. +
  42157. +#if defined(MV_INCLUDE_PEX)
  42158. +/*******************************************************************************
  42159. +* mvCpuIfPexRemap - Set CPU remap register for address windows.
  42160. +*
  42161. +* DESCRIPTION:
  42162. +*
  42163. +* INPUT:
  42164. +* pexTarget - Peripheral target enumerator. Must be a PEX target.
  42165. +* pAddrDecWin - CPU target window information data structure.
  42166. +* Note that caller has to fill in the base field only. The
  42167. +* size field is ignored.
  42168. +*
  42169. +* OUTPUT:
  42170. +* None.
  42171. +*
  42172. +* RETURN:
  42173. +* MV_ERROR if target is not a PEX one, MV_OK otherwise.
  42174. +*
  42175. +*******************************************************************************/
  42176. +MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin)
  42177. +{
  42178. + MV_U32 winNum;
  42179. +
  42180. + /* Check parameters */
  42181. +
  42182. + if (mvCtrlPexMaxIfGet() > 1)
  42183. + {
  42184. + if ((!MV_TARGET_IS_PEX1(pexTarget))&&(!MV_TARGET_IS_PEX0(pexTarget)))
  42185. + {
  42186. + mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);
  42187. + return 0xffffffff;
  42188. + }
  42189. +
  42190. + }
  42191. + else
  42192. + {
  42193. + if (!MV_TARGET_IS_PEX0(pexTarget))
  42194. + {
  42195. + mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);
  42196. + return 0xffffffff;
  42197. + }
  42198. +
  42199. + }
  42200. +
  42201. + /* get the Window number associated with this target */
  42202. + winNum = mvAhbToMbusWinTargetGet(pexTarget);
  42203. +
  42204. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  42205. + {
  42206. + mvOsPrintf("mvCpuIfPexRemap: mvAhbToMbusWinTargetGet Failed\n");
  42207. + return 0xffffffff;
  42208. +
  42209. + }
  42210. +
  42211. + return mvAhbToMbusWinRemap(winNum , pAddrDecWin);
  42212. +}
  42213. +
  42214. +#endif
  42215. +
  42216. +#if defined(MV_INCLUDE_PCI)
  42217. +/*******************************************************************************
  42218. +* mvCpuIfPciRemap - Set CPU remap register for address windows.
  42219. +*
  42220. +* DESCRIPTION:
  42221. +*
  42222. +* INPUT:
  42223. +* pciTarget - Peripheral target enumerator. Must be a PCI target.
  42224. +* pAddrDecWin - CPU target window information data structure.
  42225. +* Note that caller has to fill in the base field only. The
  42226. +* size field is ignored.
  42227. +*
  42228. +* OUTPUT:
  42229. +* None.
  42230. +*
  42231. +* RETURN:
  42232. +* MV_ERROR if target is not a PCI one, MV_OK otherwise.
  42233. +*
  42234. +*******************************************************************************/
  42235. +MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin)
  42236. +{
  42237. + MV_U32 winNum;
  42238. +
  42239. + /* Check parameters */
  42240. + if (!MV_TARGET_IS_PCI(pciTarget))
  42241. + {
  42242. + mvOsPrintf("mvCpuIfPciRemap: target %d is Illigal\n",pciTarget);
  42243. + return 0xffffffff;
  42244. + }
  42245. +
  42246. + /* get the Window number associated with this target */
  42247. + winNum = mvAhbToMbusWinTargetGet(pciTarget);
  42248. +
  42249. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  42250. + {
  42251. + mvOsPrintf("mvCpuIfPciRemap: mvAhbToMbusWinTargetGet Failed\n");
  42252. + return 0xffffffff;
  42253. +
  42254. + }
  42255. +
  42256. + return mvAhbToMbusWinRemap(winNum , pAddrDecWin);
  42257. +}
  42258. +#endif /* MV_INCLUDE_PCI */
  42259. +
  42260. +
  42261. +/*******************************************************************************
  42262. +* mvCpuIfPciIfRemap - Set CPU remap register for address windows.
  42263. +*
  42264. +* DESCRIPTION:
  42265. +*
  42266. +* INPUT:
  42267. +* pciTarget - Peripheral target enumerator. Must be a PCI target.
  42268. +* pAddrDecWin - CPU target window information data structure.
  42269. +* Note that caller has to fill in the base field only. The
  42270. +* size field is ignored.
  42271. +*
  42272. +* OUTPUT:
  42273. +* None.
  42274. +*
  42275. +* RETURN:
  42276. +* MV_ERROR if target is not a PCI one, MV_OK otherwise.
  42277. +*
  42278. +*******************************************************************************/
  42279. +MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciIfTarget, MV_ADDR_WIN *pAddrDecWin)
  42280. +{
  42281. +#if defined(MV_INCLUDE_PEX)
  42282. + if (MV_TARGET_IS_PEX(pciIfTarget))
  42283. + {
  42284. + return mvCpuIfPexRemap(pciIfTarget,pAddrDecWin);
  42285. + }
  42286. +#endif
  42287. +#if defined(MV_INCLUDE_PCI)
  42288. +
  42289. + if (MV_TARGET_IS_PCI(pciIfTarget))
  42290. + {
  42291. + return mvCpuIfPciRemap(pciIfTarget,pAddrDecWin);
  42292. + }
  42293. +#endif
  42294. + return 0;
  42295. +}
  42296. +
  42297. +
  42298. +
  42299. +/*******************************************************************************
  42300. +* mvCpuIfTargetOfBaseAddressGet - Get the target according to base address
  42301. +*
  42302. +* DESCRIPTION:
  42303. +*
  42304. +* INPUT:
  42305. +* baseAddress - base address to be checked
  42306. +*
  42307. +* OUTPUT:
  42308. +* None.
  42309. +*
  42310. +* RETURN:
  42311. +* the target number that baseAddress belongs to or MAX_TARGETS is not
  42312. +* found
  42313. +*
  42314. +*******************************************************************************/
  42315. +
  42316. +MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress)
  42317. +{
  42318. + MV_CPU_DEC_WIN win;
  42319. + MV_U32 target;
  42320. +
  42321. + for( target = 0; target < MAX_TARGETS; target++ )
  42322. + {
  42323. + if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )
  42324. + {
  42325. + if( win.enable )
  42326. + {
  42327. + if ((baseAddress >= win.addrWin.baseLow) &&
  42328. + (baseAddress < win.addrWin.baseLow + win.addrWin.size)) break;
  42329. + }
  42330. + }
  42331. + else return MAX_TARGETS;
  42332. +
  42333. + }
  42334. +
  42335. + return target;
  42336. +}
  42337. +/*******************************************************************************
  42338. +* cpuTargetWinOverlap - Detect CPU address decode windows overlapping
  42339. +*
  42340. +* DESCRIPTION:
  42341. +* An unpredicted behaviur is expected in case CPU address decode
  42342. +* windows overlapps.
  42343. +* This function detects CPU address decode windows overlapping of a
  42344. +* specified target. The function does not check the target itself for
  42345. +* overlapping. The function also skipps disabled address decode windows.
  42346. +*
  42347. +* INPUT:
  42348. +* target - Peripheral target enumerator.
  42349. +* pAddrDecWin - An address decode window struct.
  42350. +*
  42351. +* OUTPUT:
  42352. +* None.
  42353. +*
  42354. +* RETURN:
  42355. +* MV_TRUE if the given address window overlaps current address
  42356. +* decode map, MV_FALSE otherwise.
  42357. +*
  42358. +*******************************************************************************/
  42359. +static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
  42360. +{
  42361. + MV_U32 targetNum;
  42362. + MV_CPU_DEC_WIN addrDecWin;
  42363. + MV_STATUS status;
  42364. +
  42365. +
  42366. + for(targetNum = 0; targetNum < MAX_TARGETS; targetNum++)
  42367. + {
  42368. +#if defined(MV_RUN_FROM_FLASH)
  42369. + if(MV_TARGET_IS_AS_BOOT(target))
  42370. + {
  42371. + if (MV_CHANGE_BOOT_CS(targetNum) == target)
  42372. + continue;
  42373. + }
  42374. +#endif /* MV_RUN_FROM_FLASH */
  42375. +
  42376. + /* don't check our target or illegal targets */
  42377. + if (targetNum == target)
  42378. + {
  42379. + continue;
  42380. + }
  42381. +
  42382. + /* Get window parameters */
  42383. + status = mvCpuIfTargetWinGet(targetNum, &addrDecWin);
  42384. + if(MV_NO_SUCH == status)
  42385. + {
  42386. + continue;
  42387. + }
  42388. + if(MV_OK != status)
  42389. + {
  42390. + DB(mvOsPrintf("cpuTargetWinOverlap: ERR. TargetWinGet failed\n"));
  42391. + return MV_TRUE;
  42392. + }
  42393. +
  42394. + /* Do not check disabled windows */
  42395. + if (MV_FALSE == addrDecWin.enable)
  42396. + {
  42397. + continue;
  42398. + }
  42399. +
  42400. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  42401. + {
  42402. + DB(mvOsPrintf(
  42403. + "cpuTargetWinOverlap: Required target %d overlap current %d\n",
  42404. + target, targetNum));
  42405. + return MV_TRUE;
  42406. + }
  42407. + }
  42408. +
  42409. + return MV_FALSE;
  42410. +
  42411. +}
  42412. +
  42413. +/*******************************************************************************
  42414. +* mvCpuIfAddDecShow - Print the CPU address decode map.
  42415. +*
  42416. +* DESCRIPTION:
  42417. +* This function print the CPU address decode map.
  42418. +*
  42419. +* INPUT:
  42420. +* None.
  42421. +*
  42422. +* OUTPUT:
  42423. +* None.
  42424. +*
  42425. +* RETURN:
  42426. +* None.
  42427. +*
  42428. +*******************************************************************************/
  42429. +MV_VOID mvCpuIfAddDecShow(MV_VOID)
  42430. +{
  42431. + MV_CPU_DEC_WIN win;
  42432. + MV_U32 target;
  42433. + mvOsOutput( "\n" );
  42434. + mvOsOutput( "CPU Interface\n" );
  42435. + mvOsOutput( "-------------\n" );
  42436. +
  42437. + for( target = 0; target < MAX_TARGETS; target++ )
  42438. + {
  42439. +
  42440. + memset( &win, 0, sizeof(MV_CPU_DEC_WIN) );
  42441. +
  42442. + mvOsOutput( "%s ",mvCtrlTargetNameGet(target));
  42443. + mvOsOutput( "...." );
  42444. +
  42445. + if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )
  42446. + {
  42447. + if( win.enable )
  42448. + {
  42449. + mvOsOutput( "base %08x, ", win.addrWin.baseLow );
  42450. + mvSizePrint( win.addrWin.size );
  42451. + mvOsOutput( "\n" );
  42452. +
  42453. + }
  42454. + else
  42455. + mvOsOutput( "disable\n" );
  42456. + }
  42457. + else if( mvCpuIfTargetWinGet( target, &win ) == MV_NO_SUCH )
  42458. + {
  42459. + mvOsOutput( "no such\n" );
  42460. + }
  42461. + }
  42462. +}
  42463. +
  42464. +/*******************************************************************************
  42465. +* mvCpuIfEnablePex - Enable PCI Express.
  42466. +*
  42467. +* DESCRIPTION:
  42468. +* This function Enable PCI Express.
  42469. +*
  42470. +* INPUT:
  42471. +* pexIf - PEX interface number.
  42472. +* pexType - MV_PEX_ROOT_COMPLEX - root complex device
  42473. +* MV_PEX_END_POINT - end point device
  42474. +* OUTPUT:
  42475. +* None.
  42476. +*
  42477. +* RETURN:
  42478. +* None.
  42479. +*
  42480. +*******************************************************************************/
  42481. +#if defined(MV_INCLUDE_PEX)
  42482. +MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType)
  42483. +{
  42484. + /* Set pex mode incase S@R not exist */
  42485. + if( pexType == MV_PEX_END_POINT)
  42486. + {
  42487. + MV_REG_BIT_RESET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
  42488. + /* Change pex mode in capability reg */
  42489. + MV_REG_BIT_RESET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT22);
  42490. + MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT20);
  42491. +
  42492. + }
  42493. + else
  42494. + {
  42495. + MV_REG_BIT_SET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
  42496. + }
  42497. +
  42498. + /* CPU config register Pex enable */
  42499. + MV_REG_BIT_SET(CPU_CTRL_STAT_REG,CCSR_PCI_ACCESS_MASK);
  42500. +}
  42501. +#endif
  42502. +
  42503. +
  42504. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h
  42505. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h 1970-01-01 01:00:00.000000000 +0100
  42506. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h 2011-07-31 11:31:57.353571728 +0200
  42507. @@ -0,0 +1,120 @@
  42508. +/*******************************************************************************
  42509. +Copyright (C) Marvell International Ltd. and its affiliates
  42510. +
  42511. +This software file (the "File") is owned and distributed by Marvell
  42512. +International Ltd. and/or its affiliates ("Marvell") under the following
  42513. +alternative licensing terms. Once you have made an election to distribute the
  42514. +File under one of the following license alternatives, please (i) delete this
  42515. +introductory statement regarding license alternatives, (ii) delete the two
  42516. +license alternatives that you have not elected to use and (iii) preserve the
  42517. +Marvell copyright notice above.
  42518. +
  42519. +********************************************************************************
  42520. +Marvell Commercial License Option
  42521. +
  42522. +If you received this File from Marvell and you have entered into a commercial
  42523. +license agreement (a "Commercial License") with Marvell, the File is licensed
  42524. +to you under the terms of the applicable Commercial License.
  42525. +
  42526. +********************************************************************************
  42527. +Marvell GPL License Option
  42528. +
  42529. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42530. +modify this File in accordance with the terms and conditions of the General
  42531. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  42532. +available along with the File in the license.txt file or by writing to the Free
  42533. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  42534. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  42535. +
  42536. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  42537. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  42538. +DISCLAIMED. The GPL License provides additional details about this warranty
  42539. +disclaimer.
  42540. +********************************************************************************
  42541. +Marvell BSD License Option
  42542. +
  42543. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42544. +modify this File under the following licensing terms.
  42545. +Redistribution and use in source and binary forms, with or without modification,
  42546. +are permitted provided that the following conditions are met:
  42547. +
  42548. + * Redistributions of source code must retain the above copyright notice,
  42549. + this list of conditions and the following disclaimer.
  42550. +
  42551. + * Redistributions in binary form must reproduce the above copyright
  42552. + notice, this list of conditions and the following disclaimer in the
  42553. + documentation and/or other materials provided with the distribution.
  42554. +
  42555. + * Neither the name of Marvell nor the names of its contributors may be
  42556. + used to endorse or promote products derived from this software without
  42557. + specific prior written permission.
  42558. +
  42559. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42560. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42561. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42562. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42563. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42564. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42565. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42566. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42567. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42568. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42569. +
  42570. +*******************************************************************************/
  42571. +
  42572. +
  42573. +#ifndef __INCmvCpuIfh
  42574. +#define __INCmvCpuIfh
  42575. +
  42576. +/* includes */
  42577. +#include "ctrlEnv/mvCtrlEnvLib.h"
  42578. +#include "ctrlEnv/sys/mvCpuIfRegs.h"
  42579. +#include "ctrlEnv/sys/mvAhbToMbus.h"
  42580. +#include "ddr2/mvDramIf.h"
  42581. +#include "ctrlEnv/sys/mvSysDram.h"
  42582. +#if defined(MV_INCLUDE_PEX)
  42583. +#include "pex/mvPex.h"
  42584. +#endif
  42585. +
  42586. +/* defines */
  42587. +
  42588. +/* typedefs */
  42589. +/* This structure describes CPU interface address decode window */
  42590. +typedef struct _mvCpuIfDecWin
  42591. +{
  42592. + MV_ADDR_WIN addrWin; /* An address window*/
  42593. + MV_U32 winNum; /* Window Number in the AHB To Mbus bridge */
  42594. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  42595. +
  42596. +}MV_CPU_DEC_WIN;
  42597. +
  42598. +
  42599. +
  42600. +/* mvCpuIfLib.h API list */
  42601. +
  42602. +/* mvCpuIfLib.h API list */
  42603. +
  42604. +MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap);
  42605. +MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);
  42606. +MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);
  42607. +MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable);
  42608. +MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target);
  42609. +MV_U32 mvCpuIfTargetWinBaseLowGet(MV_TARGET target);
  42610. +MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target);
  42611. +MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress);
  42612. +#if defined(MV_INCLUDE_PEX)
  42613. +MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin);
  42614. +MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType);
  42615. +#endif
  42616. +#if defined(MV_INCLUDE_PCI)
  42617. +MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);
  42618. +#endif
  42619. +MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);
  42620. +
  42621. +MV_VOID mvCpuIfAddDecShow(MV_VOID);
  42622. +
  42623. +#if defined(MV88F6281)
  42624. +MV_STATUS mvCpuIfBridgeReorderWAInit(void);
  42625. +#endif
  42626. +
  42627. +#endif /* __INCmvCpuIfh */
  42628. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h
  42629. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  42630. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h 2011-07-31 11:31:57.383475045 +0200
  42631. @@ -0,0 +1,304 @@
  42632. +/*******************************************************************************
  42633. +Copyright (C) Marvell International Ltd. and its affiliates
  42634. +
  42635. +This software file (the "File") is owned and distributed by Marvell
  42636. +International Ltd. and/or its affiliates ("Marvell") under the following
  42637. +alternative licensing terms. Once you have made an election to distribute the
  42638. +File under one of the following license alternatives, please (i) delete this
  42639. +introductory statement regarding license alternatives, (ii) delete the two
  42640. +license alternatives that you have not elected to use and (iii) preserve the
  42641. +Marvell copyright notice above.
  42642. +
  42643. +********************************************************************************
  42644. +Marvell Commercial License Option
  42645. +
  42646. +If you received this File from Marvell and you have entered into a commercial
  42647. +license agreement (a "Commercial License") with Marvell, the File is licensed
  42648. +to you under the terms of the applicable Commercial License.
  42649. +
  42650. +********************************************************************************
  42651. +Marvell GPL License Option
  42652. +
  42653. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42654. +modify this File in accordance with the terms and conditions of the General
  42655. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  42656. +available along with the File in the license.txt file or by writing to the Free
  42657. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  42658. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  42659. +
  42660. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  42661. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  42662. +DISCLAIMED. The GPL License provides additional details about this warranty
  42663. +disclaimer.
  42664. +********************************************************************************
  42665. +Marvell BSD License Option
  42666. +
  42667. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42668. +modify this File under the following licensing terms.
  42669. +Redistribution and use in source and binary forms, with or without modification,
  42670. +are permitted provided that the following conditions are met:
  42671. +
  42672. + * Redistributions of source code must retain the above copyright notice,
  42673. + this list of conditions and the following disclaimer.
  42674. +
  42675. + * Redistributions in binary form must reproduce the above copyright
  42676. + notice, this list of conditions and the following disclaimer in the
  42677. + documentation and/or other materials provided with the distribution.
  42678. +
  42679. + * Neither the name of Marvell nor the names of its contributors may be
  42680. + used to endorse or promote products derived from this software without
  42681. + specific prior written permission.
  42682. +
  42683. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42684. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42685. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42686. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42687. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42688. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42689. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42690. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42691. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42692. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42693. +
  42694. +*******************************************************************************/
  42695. +
  42696. +
  42697. +#ifndef __INCmvCpuIfRegsh
  42698. +#define __INCmvCpuIfRegsh
  42699. +
  42700. +/****************************************/
  42701. +/* ARM Control and Status Registers Map */
  42702. +/****************************************/
  42703. +
  42704. +#define CPU_CONFIG_REG 0x20100
  42705. +#define CPU_CTRL_STAT_REG 0x20104
  42706. +#define CPU_RSTOUTN_MASK_REG 0x20108
  42707. +#define CPU_SYS_SOFT_RST_REG 0x2010C
  42708. +#define CPU_AHB_MBUS_CAUSE_INT_REG 0x20110
  42709. +#define CPU_AHB_MBUS_MASK_INT_REG 0x20114
  42710. +#define CPU_FTDLL_CONFIG_REG 0x20120
  42711. +#define CPU_L2_CONFIG_REG 0x20128
  42712. +
  42713. +
  42714. +
  42715. +/* ARM Configuration register */
  42716. +/* CPU_CONFIG_REG (CCR) */
  42717. +
  42718. +
  42719. +/* Reset vector location */
  42720. +#define CCR_VEC_INIT_LOC_OFFS 1
  42721. +#define CCR_VEC_INIT_LOC_MASK BIT1
  42722. +/* reset at 0x00000000 */
  42723. +#define CCR_VEC_INIT_LOC_0000 (0 << CCR_VEC_INIT_LOC_OFFS)
  42724. +/* reset at 0xFFFF0000 */
  42725. +#define CCR_VEC_INIT_LOC_FF00 (1 << CCR_VEC_INIT_LOC_OFFS)
  42726. +
  42727. +
  42728. +#define CCR_AHB_ERROR_PROP_OFFS 2
  42729. +#define CCR_AHB_ERROR_PROP_MASK BIT2
  42730. +/* Erros are not propogated to AHB */
  42731. +#define CCR_AHB_ERROR_PROP_NO_INDICATE (0 << CCR_AHB_ERROR_PROP_OFFS)
  42732. +/* Erros are propogated to AHB */
  42733. +#define CCR_AHB_ERROR_PROP_INDICATE (1 << CCR_AHB_ERROR_PROP_OFFS)
  42734. +
  42735. +
  42736. +#define CCR_ENDIAN_INIT_OFFS 3
  42737. +#define CCR_ENDIAN_INIT_MASK BIT3
  42738. +#define CCR_ENDIAN_INIT_LITTLE (0 << CCR_ENDIAN_INIT_OFFS)
  42739. +#define CCR_ENDIAN_INIT_BIG (1 << CCR_ENDIAN_INIT_OFFS)
  42740. +
  42741. +
  42742. +#define CCR_INCR_EN_OFFS 4
  42743. +#define CCR_INCR_EN_MASK BIT4
  42744. +#define CCR_INCR_EN BIT4
  42745. +
  42746. +
  42747. +#define CCR_NCB_BLOCKING_OFFS 5
  42748. +#define CCR_NCB_BLOCKING_MASK (1 << CCR_NCB_BLOCKING_OFFS)
  42749. +#define CCR_NCB_BLOCKING_NON (0 << CCR_NCB_BLOCKING_OFFS)
  42750. +#define CCR_NCB_BLOCKING_EN (1 << CCR_NCB_BLOCKING_OFFS)
  42751. +
  42752. +#define CCR_CPU_2_MBUSL_TICK_DRV_OFFS 8
  42753. +#define CCR_CPU_2_MBUSL_TICK_DRV_MASK (0xF << CCR_CPU_2_MBUSL_TICK_DRV_OFFS)
  42754. +#define CCR_CPU_2_MBUSL_TICK_SMPL_OFFS 12
  42755. +#define CCR_CPU_2_MBUSL_TICK_SMPL_MASK (0xF << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS)
  42756. +#define CCR_ICACH_PREF_BUF_ENABLE BIT16
  42757. +#define CCR_DCACH_PREF_BUF_ENABLE BIT17
  42758. +
  42759. +/* Ratio options for CPU to DDR for 6281/6192/6190 */
  42760. +#define CPU_2_DDR_CLK_1x3 4
  42761. +#define CPU_2_DDR_CLK_1x4 6
  42762. +
  42763. +/* Ratio options for CPU to DDR for 6281 only */
  42764. +#define CPU_2_DDR_CLK_2x9 7
  42765. +#define CPU_2_DDR_CLK_1x5 8
  42766. +#define CPU_2_DDR_CLK_1x6 9
  42767. +
  42768. +/* Ratio options for CPU to DDR for 6180 only */
  42769. +#define CPU_2_DDR_CLK_1x3_1 0x5
  42770. +#define CPU_2_DDR_CLK_1x4_1 0x6
  42771. +
  42772. +/* Default values for CPU to Mbus-L DDR Interface Tick Driver and */
  42773. +/* CPU to Mbus-L Tick Sample fields in CPU config register */
  42774. +
  42775. +#define TICK_DRV_1x1 0
  42776. +#define TICK_DRV_1x2 0
  42777. +#define TICK_DRV_1x3 1
  42778. +#define TICK_DRV_1x4 2
  42779. +#define TICK_SMPL_1x1 0
  42780. +#define TICK_SMPL_1x2 1
  42781. +#define TICK_SMPL_1x3 0
  42782. +#define TICK_SMPL_1x4 0
  42783. +
  42784. +#define CPU_2_MBUSL_DDR_CLK_1x2 \
  42785. + ((TICK_DRV_1x2 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
  42786. + (TICK_SMPL_1x2 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
  42787. +#define CPU_2_MBUSL_DDR_CLK_1x3 \
  42788. + ((TICK_DRV_1x3 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
  42789. + (TICK_SMPL_1x3 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
  42790. +#define CPU_2_MBUSL_DDR_CLK_1x4 \
  42791. + ((TICK_DRV_1x4 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
  42792. + (TICK_SMPL_1x4 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
  42793. +
  42794. +/* ARM Control and Status register */
  42795. +/* CPU_CTRL_STAT_REG (CCSR) */
  42796. +
  42797. +
  42798. +/*
  42799. +This is used to block PCI express\PCI from access Socrates/Feroceon GP
  42800. +while ARM boot is still in progress
  42801. +*/
  42802. +
  42803. +#define CCSR_PCI_ACCESS_OFFS 0
  42804. +#define CCSR_PCI_ACCESS_MASK BIT0
  42805. +#define CCSR_PCI_ACCESS_ENABLE (0 << CCSR_PCI_ACCESS_OFFS)
  42806. +#define CCSR_PCI_ACCESS_DISBALE (1 << CCSR_PCI_ACCESS_OFFS)
  42807. +
  42808. +#define CCSR_ARM_RESET BIT1
  42809. +#define CCSR_SELF_INT BIT2
  42810. +#define CCSR_BIG_ENDIAN BIT15
  42811. +
  42812. +
  42813. +/* RSTOUTn Mask Register */
  42814. +/* CPU_RSTOUTN_MASK_REG (CRMR) */
  42815. +
  42816. +#define CRMR_PEX_RST_OUT_OFFS 0
  42817. +#define CRMR_PEX_RST_OUT_MASK BIT0
  42818. +#define CRMR_PEX_RST_OUT_ENABLE (1 << CRMR_PEX_RST_OUT_OFFS)
  42819. +#define CRMR_PEX_RST_OUT_DISABLE (0 << CRMR_PEX_RST_OUT_OFFS)
  42820. +
  42821. +#define CRMR_WD_RST_OUT_OFFS 1
  42822. +#define CRMR_WD_RST_OUT_MASK BIT1
  42823. +#define CRMR_WD_RST_OUT_ENABLE (1 << CRMR_WD_RST_OUT_OFFS)
  42824. +#define CRMR_WD_RST_OUT_DISBALE (0 << CRMR_WD_RST_OUT_OFFS)
  42825. +
  42826. +#define CRMR_SOFT_RST_OUT_OFFS 2
  42827. +#define CRMR_SOFT_RST_OUT_MASK BIT2
  42828. +#define CRMR_SOFT_RST_OUT_ENABLE (1 << CRMR_SOFT_RST_OUT_OFFS)
  42829. +#define CRMR_SOFT_RST_OUT_DISBALE (0 << CRMR_SOFT_RST_OUT_OFFS)
  42830. +
  42831. +/* System Software Reset Register */
  42832. +/* CPU_SYS_SOFT_RST_REG (CSSRR) */
  42833. +
  42834. +#define CSSRR_SYSTEM_SOFT_RST BIT0
  42835. +
  42836. +/* AHB to Mbus Bridge Interrupt Cause Register*/
  42837. +/* CPU_AHB_MBUS_CAUSE_INT_REG (CAMCIR) */
  42838. +
  42839. +#define CAMCIR_ARM_SELF_INT BIT0
  42840. +#define CAMCIR_ARM_TIMER0_INT_REQ BIT1
  42841. +#define CAMCIR_ARM_TIMER1_INT_REQ BIT2
  42842. +#define CAMCIR_ARM_WD_TIMER_INT_REQ BIT3
  42843. +
  42844. +
  42845. +/* AHB to Mbus Bridge Interrupt Mask Register*/
  42846. +/* CPU_AHB_MBUS_MASK_INT_REG (CAMMIR) */
  42847. +
  42848. +#define CAMCIR_ARM_SELF_INT_OFFS 0
  42849. +#define CAMCIR_ARM_SELF_INT_MASK BIT0
  42850. +#define CAMCIR_ARM_SELF_INT_EN (1 << CAMCIR_ARM_SELF_INT_OFFS)
  42851. +#define CAMCIR_ARM_SELF_INT_DIS (0 << CAMCIR_ARM_SELF_INT_OFFS)
  42852. +
  42853. +
  42854. +#define CAMCIR_ARM_TIMER0_INT_REQ_OFFS 1
  42855. +#define CAMCIR_ARM_TIMER0_INT_REQ_MASK BIT1
  42856. +#define CAMCIR_ARM_TIMER0_INT_REQ_EN (1 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS)
  42857. +#define CAMCIR_ARM_TIMER0_INT_REQ_DIS (0 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS)
  42858. +
  42859. +#define CAMCIR_ARM_TIMER1_INT_REQ_OFFS 2
  42860. +#define CAMCIR_ARM_TIMER1_INT_REQ_MASK BIT2
  42861. +#define CAMCIR_ARM_TIMER1_INT_REQ_EN (1 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS)
  42862. +#define CAMCIR_ARM_TIMER1_INT_REQ_DIS (0 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS)
  42863. +
  42864. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS 3
  42865. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_MASK BIT3
  42866. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_EN (1 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS)
  42867. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_DIS (0 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS)
  42868. +
  42869. +/* CPU FTDLL Config register (CFCR) fields */
  42870. +#define CFCR_FTDLL_ICACHE_TAG_OFFS 0
  42871. +#define CFCR_FTDLL_ICACHE_TAG_MASK (0x7F << CFCR_FTDLL_ICACHE_TAG_OFFS)
  42872. +#define CFCR_FTDLL_DCACHE_TAG_OFFS 8
  42873. +#define CFCR_FTDLL_DCACHE_TAG_MASK (0x7F << CFCR_FTDLL_DCACHE_TAG_OFFS)
  42874. +#define CFCR_FTDLL_OVERWRITE_ENABLE (1 << 15)
  42875. +/* For Orion 2 D2 only */
  42876. +#define CFCR_MRVL_CPU_ID_OFFS 16
  42877. +#define CFCR_MRVL_CPU_ID_MASK (0x1 << CFCR_MRVL_CPU_ID_OFFS)
  42878. +#define CFCR_ARM_CPU_ID (0x0 << CFCR_MRVL_CPU_ID_OFFS)
  42879. +#define CFCR_MRVL_CPU_ID (0x1 << CFCR_MRVL_CPU_ID_OFFS)
  42880. +#define CFCR_VFP_SUB_ARC_NUM_OFFS 7
  42881. +#define CFCR_VFP_SUB_ARC_NUM_MASK (0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)
  42882. +#define CFCR_VFP_SUB_ARC_NUM_1 (0x0 << CFCR_VFP_SUB_ARC_NUM_OFFS)
  42883. +#define CFCR_VFP_SUB_ARC_NUM_2 (0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)
  42884. +
  42885. +/* CPU_L2_CONFIG_REG fields */
  42886. +#ifdef MV_CPU_LE
  42887. +#define CL2CR_L2_ECC_EN_OFFS 2
  42888. +#define CL2CR_L2_WT_MODE_OFFS 4
  42889. +#else
  42890. +#define CL2CR_L2_ECC_EN_OFFS 26
  42891. +#define CL2CR_L2_WT_MODE_OFFS 28
  42892. +#endif
  42893. +
  42894. +#define CL2CR_L2_ECC_EN_MASK (1 << CL2CR_L2_ECC_EN_OFFS)
  42895. +#define CL2CR_L2_WT_MODE_MASK (1 << CL2CR_L2_WT_MODE_OFFS)
  42896. +
  42897. +/*******************************************/
  42898. +/* Main Interrupt Controller Registers Map */
  42899. +/*******************************************/
  42900. +
  42901. +#define CPU_MAIN_INT_CAUSE_REG 0x20200
  42902. +#define CPU_MAIN_IRQ_MASK_REG 0x20204
  42903. +#define CPU_MAIN_FIQ_MASK_REG 0x20208
  42904. +#define CPU_ENPOINT_MASK_REG 0x2020C
  42905. +#define CPU_MAIN_INT_CAUSE_HIGH_REG 0x20210
  42906. +#define CPU_MAIN_IRQ_MASK_HIGH_REG 0x20214
  42907. +#define CPU_MAIN_FIQ_MASK_HIGH_REG 0x20218
  42908. +#define CPU_ENPOINT_MASK_HIGH_REG 0x2021C
  42909. +
  42910. +
  42911. +/*******************************************/
  42912. +/* ARM Doorbell Registers Map */
  42913. +/*******************************************/
  42914. +
  42915. +#define CPU_HOST_TO_ARM_DRBL_REG 0x20400
  42916. +#define CPU_HOST_TO_ARM_MASK_REG 0x20404
  42917. +#define CPU_ARM_TO_HOST_DRBL_REG 0x20408
  42918. +#define CPU_ARM_TO_HOST_MASK_REG 0x2040C
  42919. +
  42920. +
  42921. +
  42922. +/* CPU control register map */
  42923. +/* Set bits means value is about to change according to new value */
  42924. +#define CPU_CONFIG_DEFAULT_MASK (CCR_VEC_INIT_LOC_MASK | CCR_AHB_ERROR_PROP_MASK)
  42925. +
  42926. +#define CPU_CONFIG_DEFAULT (CCR_VEC_INIT_LOC_FF00)
  42927. +
  42928. +/* CPU Control and status defaults */
  42929. +#define CPU_CTRL_STAT_DEFAULT_MASK (CCSR_PCI_ACCESS_MASK)
  42930. +
  42931. +
  42932. +#define CPU_CTRL_STAT_DEFAULT (CCSR_PCI_ACCESS_ENABLE)
  42933. +
  42934. +#endif /* __INCmvCpuIfRegsh */
  42935. +
  42936. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c
  42937. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c 1970-01-01 01:00:00.000000000 +0100
  42938. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c 2011-07-31 11:31:57.454031576 +0200
  42939. @@ -0,0 +1,324 @@
  42940. +/*******************************************************************************
  42941. +Copyright (C) Marvell International Ltd. and its affiliates
  42942. +
  42943. +This software file (the "File") is owned and distributed by Marvell
  42944. +International Ltd. and/or its affiliates ("Marvell") under the following
  42945. +alternative licensing terms. Once you have made an election to distribute the
  42946. +File under one of the following license alternatives, please (i) delete this
  42947. +introductory statement regarding license alternatives, (ii) delete the two
  42948. +license alternatives that you have not elected to use and (iii) preserve the
  42949. +Marvell copyright notice above.
  42950. +
  42951. +********************************************************************************
  42952. +Marvell Commercial License Option
  42953. +
  42954. +If you received this File from Marvell and you have entered into a commercial
  42955. +license agreement (a "Commercial License") with Marvell, the File is licensed
  42956. +to you under the terms of the applicable Commercial License.
  42957. +
  42958. +********************************************************************************
  42959. +Marvell GPL License Option
  42960. +
  42961. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42962. +modify this File in accordance with the terms and conditions of the General
  42963. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  42964. +available along with the File in the license.txt file or by writing to the Free
  42965. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  42966. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  42967. +
  42968. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  42969. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  42970. +DISCLAIMED. The GPL License provides additional details about this warranty
  42971. +disclaimer.
  42972. +********************************************************************************
  42973. +Marvell BSD License Option
  42974. +
  42975. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42976. +modify this File under the following licensing terms.
  42977. +Redistribution and use in source and binary forms, with or without modification,
  42978. +are permitted provided that the following conditions are met:
  42979. +
  42980. + * Redistributions of source code must retain the above copyright notice,
  42981. + this list of conditions and the following disclaimer.
  42982. +
  42983. + * Redistributions in binary form must reproduce the above copyright
  42984. + notice, this list of conditions and the following disclaimer in the
  42985. + documentation and/or other materials provided with the distribution.
  42986. +
  42987. + * Neither the name of Marvell nor the names of its contributors may be
  42988. + used to endorse or promote products derived from this software without
  42989. + specific prior written permission.
  42990. +
  42991. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42992. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42993. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42994. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42995. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42996. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42997. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42998. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42999. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  43000. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43001. +
  43002. +*******************************************************************************/
  43003. +#include "mvSysAudio.h"
  43004. +
  43005. +/*******************************************************************************
  43006. +* mvAudioWinSet - Set AUDIO target address window
  43007. +*
  43008. +* DESCRIPTION:
  43009. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  43010. +* address window, also known as address decode window.
  43011. +* After setting this target window, the AUDIO will be able to access the
  43012. +* target within the address window.
  43013. +*
  43014. +* INPUT:
  43015. +* winNum - AUDIO target address decode window number.
  43016. +* pAddrDecWin - AUDIO target window data structure.
  43017. +*
  43018. +* OUTPUT:
  43019. +* None.
  43020. +*
  43021. +* RETURN:
  43022. +* MV_ERROR if address window overlapps with other address decode windows.
  43023. +* MV_BAD_PARAM if base address is invalid parameter or target is
  43024. +* unknown.
  43025. +*
  43026. +*******************************************************************************/
  43027. +MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)
  43028. +{
  43029. + MV_TARGET_ATTRIB targetAttribs;
  43030. + MV_DEC_REGS decRegs;
  43031. +
  43032. + /* Parameter checking */
  43033. + if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)
  43034. + {
  43035. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  43036. + return MV_BAD_PARAM;
  43037. + }
  43038. +
  43039. + /* check if address is aligned to the size */
  43040. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  43041. + {
  43042. + mvOsPrintf("mvAudioWinSet:Error setting AUDIO window %d to "\
  43043. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  43044. + winNum,
  43045. + mvCtrlTargetNameGet(pAddrDecWin->target),
  43046. + pAddrDecWin->addrWin.baseLow,
  43047. + pAddrDecWin->addrWin.size);
  43048. + return MV_ERROR;
  43049. + }
  43050. +
  43051. + decRegs.baseReg = 0;
  43052. + decRegs.sizeReg = 0;
  43053. +
  43054. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  43055. + {
  43056. + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
  43057. + return MV_ERROR;
  43058. + }
  43059. +
  43060. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  43061. +
  43062. + /* set attributes */
  43063. + decRegs.sizeReg &= ~MV_AUDIO_WIN_ATTR_MASK;
  43064. + decRegs.sizeReg |= (targetAttribs.attrib << MV_AUDIO_WIN_ATTR_OFFSET);
  43065. +
  43066. + /* set target ID */
  43067. + decRegs.sizeReg &= ~MV_AUDIO_WIN_TARGET_MASK;
  43068. + decRegs.sizeReg |= (targetAttribs.targetId << MV_AUDIO_WIN_TARGET_OFFSET);
  43069. +
  43070. + if (pAddrDecWin->enable == MV_TRUE)
  43071. + {
  43072. + decRegs.sizeReg |= MV_AUDIO_WIN_ENABLE_MASK;
  43073. + }
  43074. + else
  43075. + {
  43076. + decRegs.sizeReg &= ~MV_AUDIO_WIN_ENABLE_MASK;
  43077. + }
  43078. +
  43079. + MV_REG_WRITE( MV_AUDIO_WIN_CTRL_REG(winNum), decRegs.sizeReg);
  43080. + MV_REG_WRITE( MV_AUDIO_WIN_BASE_REG(winNum), decRegs.baseReg);
  43081. +
  43082. + return MV_OK;
  43083. +}
  43084. +
  43085. +/*******************************************************************************
  43086. +* mvAudioWinGet - Get AUDIO peripheral target address window.
  43087. +*
  43088. +* DESCRIPTION:
  43089. +* Get AUDIO peripheral target address window.
  43090. +*
  43091. +* INPUT:
  43092. +* winNum - AUDIO target address decode window number.
  43093. +*
  43094. +* OUTPUT:
  43095. +* pAddrDecWin - AUDIO target window data structure.
  43096. +*
  43097. +* RETURN:
  43098. +* MV_ERROR if register parameters are invalid.
  43099. +*
  43100. +*******************************************************************************/
  43101. +MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)
  43102. +{
  43103. + MV_DEC_REGS decRegs;
  43104. + MV_TARGET_ATTRIB targetAttrib;
  43105. +
  43106. + /* Parameter checking */
  43107. + if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)
  43108. + {
  43109. + mvOsPrintf("%s : ERR. Invalid winNum %d\n",
  43110. + __FUNCTION__, winNum);
  43111. + return MV_NOT_SUPPORTED;
  43112. + }
  43113. +
  43114. + decRegs.baseReg = MV_REG_READ( MV_AUDIO_WIN_BASE_REG(winNum) );
  43115. + decRegs.sizeReg = MV_REG_READ( MV_AUDIO_WIN_CTRL_REG(winNum) );
  43116. +
  43117. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
  43118. + {
  43119. + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
  43120. + return MV_ERROR;
  43121. + }
  43122. +
  43123. + /* attrib and targetId */
  43124. + targetAttrib.attrib = (decRegs.sizeReg & MV_AUDIO_WIN_ATTR_MASK) >>
  43125. + MV_AUDIO_WIN_ATTR_OFFSET;
  43126. + targetAttrib.targetId = (decRegs.sizeReg & MV_AUDIO_WIN_TARGET_MASK) >>
  43127. + MV_AUDIO_WIN_TARGET_OFFSET;
  43128. +
  43129. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  43130. +
  43131. + /* Check if window is enabled */
  43132. + if(decRegs.sizeReg & MV_AUDIO_WIN_ENABLE_MASK)
  43133. + {
  43134. + pAddrDecWin->enable = MV_TRUE;
  43135. + }
  43136. + else
  43137. + {
  43138. + pAddrDecWin->enable = MV_FALSE;
  43139. + }
  43140. + return MV_OK;
  43141. +}
  43142. +/*******************************************************************************
  43143. +* mvAudioAddrDecShow - Print the AUDIO address decode map.
  43144. +*
  43145. +* DESCRIPTION:
  43146. +* This function print the AUDIO address decode map.
  43147. +*
  43148. +* INPUT:
  43149. +* None.
  43150. +*
  43151. +* OUTPUT:
  43152. +* None.
  43153. +*
  43154. +* RETURN:
  43155. +* None.
  43156. +*
  43157. +*******************************************************************************/
  43158. +MV_VOID mvAudioAddrDecShow(MV_VOID)
  43159. +{
  43160. +
  43161. + MV_AUDIO_DEC_WIN win;
  43162. + int i;
  43163. +
  43164. + if (MV_FALSE == mvCtrlPwrClckGet(AUDIO_UNIT_ID, 0))
  43165. + return;
  43166. +
  43167. +
  43168. + mvOsOutput( "\n" );
  43169. + mvOsOutput( "AUDIO:\n" );
  43170. + mvOsOutput( "----\n" );
  43171. +
  43172. + for( i = 0; i < MV_AUDIO_MAX_ADDR_DECODE_WIN; i++ )
  43173. + {
  43174. + memset( &win, 0, sizeof(MV_AUDIO_DEC_WIN) );
  43175. +
  43176. + mvOsOutput( "win%d - ", i );
  43177. +
  43178. + if( mvAudioWinGet( i, &win ) == MV_OK )
  43179. + {
  43180. + if( win.enable )
  43181. + {
  43182. + mvOsOutput( "%s base %08x, ",
  43183. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  43184. + mvOsOutput( "...." );
  43185. +
  43186. + mvSizePrint( win.addrWin.size );
  43187. +
  43188. + mvOsOutput( "\n" );
  43189. + }
  43190. + else
  43191. + mvOsOutput( "disable\n" );
  43192. + }
  43193. + }
  43194. +}
  43195. +
  43196. +
  43197. +/*******************************************************************************
  43198. +* mvAudioWinInit - Initialize the integrated AUDIO target address window.
  43199. +*
  43200. +* DESCRIPTION:
  43201. +* Initialize the AUDIO peripheral target address window.
  43202. +*
  43203. +* INPUT:
  43204. +*
  43205. +*
  43206. +* OUTPUT:
  43207. +*
  43208. +*
  43209. +* RETURN:
  43210. +* MV_ERROR if register parameters are invalid.
  43211. +*
  43212. +*******************************************************************************/
  43213. +MV_STATUS mvAudioInit(MV_VOID)
  43214. +{
  43215. + int winNum;
  43216. + MV_AUDIO_DEC_WIN audioWin;
  43217. + MV_CPU_DEC_WIN cpuAddrDecWin;
  43218. + MV_U32 status;
  43219. +
  43220. + mvAudioHalInit();
  43221. +
  43222. + /* Initiate Audio address decode */
  43223. +
  43224. + /* First disable all address decode windows */
  43225. + for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)
  43226. + {
  43227. + MV_U32 regVal = MV_REG_READ(MV_AUDIO_WIN_CTRL_REG(winNum));
  43228. + regVal &= ~MV_AUDIO_WIN_ENABLE_MASK;
  43229. + MV_REG_WRITE(MV_AUDIO_WIN_CTRL_REG(winNum), regVal);
  43230. + }
  43231. +
  43232. + for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)
  43233. + {
  43234. +
  43235. + /* We will set the Window to DRAM_CS0 in default */
  43236. + /* first get attributes from CPU If */
  43237. + status = mvCpuIfTargetWinGet(SDRAM_CS0,
  43238. + &cpuAddrDecWin);
  43239. +
  43240. + if (MV_OK != status)
  43241. + {
  43242. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  43243. + return MV_ERROR;
  43244. + }
  43245. +
  43246. + if (cpuAddrDecWin.enable == MV_TRUE)
  43247. + {
  43248. + audioWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  43249. + audioWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  43250. + audioWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  43251. + audioWin.enable = MV_TRUE;
  43252. + audioWin.target = SDRAM_CS0;
  43253. +
  43254. + if(MV_OK != mvAudioWinSet(winNum, &audioWin))
  43255. + {
  43256. + return MV_ERROR;
  43257. + }
  43258. + }
  43259. + }
  43260. +
  43261. + return MV_OK;
  43262. +}
  43263. +
  43264. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h
  43265. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h 1970-01-01 01:00:00.000000000 +0100
  43266. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h 2011-07-31 11:31:57.513425449 +0200
  43267. @@ -0,0 +1,123 @@
  43268. +/*******************************************************************************
  43269. +Copyright (C) Marvell International Ltd. and its affiliates
  43270. +
  43271. +This software file (the "File") is owned and distributed by Marvell
  43272. +International Ltd. and/or its affiliates ("Marvell") under the following
  43273. +alternative licensing terms. Once you have made an election to distribute the
  43274. +File under one of the following license alternatives, please (i) delete this
  43275. +introductory statement regarding license alternatives, (ii) delete the two
  43276. +license alternatives that you have not elected to use and (iii) preserve the
  43277. +Marvell copyright notice above.
  43278. +
  43279. +********************************************************************************
  43280. +Marvell Commercial License Option
  43281. +
  43282. +If you received this File from Marvell and you have entered into a commercial
  43283. +license agreement (a "Commercial License") with Marvell, the File is licensed
  43284. +to you under the terms of the applicable Commercial License.
  43285. +
  43286. +********************************************************************************
  43287. +Marvell GPL License Option
  43288. +
  43289. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43290. +modify this File in accordance with the terms and conditions of the General
  43291. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  43292. +available along with the File in the license.txt file or by writing to the Free
  43293. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  43294. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  43295. +
  43296. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  43297. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  43298. +DISCLAIMED. The GPL License provides additional details about this warranty
  43299. +disclaimer.
  43300. +********************************************************************************
  43301. +Marvell BSD License Option
  43302. +
  43303. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43304. +modify this File under the following licensing terms.
  43305. +Redistribution and use in source and binary forms, with or without modification,
  43306. +are permitted provided that the following conditions are met:
  43307. +
  43308. + * Redistributions of source code must retain the above copyright notice,
  43309. + this list of conditions and the following disclaimer.
  43310. +
  43311. + * Redistributions in binary form must reproduce the above copyright
  43312. + notice, this list of conditions and the following disclaimer in the
  43313. + documentation and/or other materials provided with the distribution.
  43314. +
  43315. + * Neither the name of Marvell nor the names of its contributors may be
  43316. + used to endorse or promote products derived from this software without
  43317. + specific prior written permission.
  43318. +
  43319. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  43320. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  43321. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  43322. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  43323. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  43324. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43325. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  43326. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43327. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  43328. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43329. +
  43330. +*******************************************************************************/
  43331. +#ifndef __INCMVSysAudioH
  43332. +#define __INCMVSysAudioH
  43333. +
  43334. +#include "mvCommon.h"
  43335. +#include "audio/mvAudio.h"
  43336. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  43337. +#include "ctrlEnv/sys/mvCpuIf.h"
  43338. +
  43339. +/***********************************/
  43340. +/* Audio Address Decoding registers*/
  43341. +/***********************************/
  43342. +
  43343. +#define MV_AUDIO_MAX_ADDR_DECODE_WIN 2
  43344. +#define MV_AUDIO_RECORD_WIN_NUM 0
  43345. +#define MV_AUDIO_PLAYBACK_WIN_NUM 1
  43346. +
  43347. +#define MV_AUDIO_WIN_CTRL_REG(win) (AUDIO_REG_BASE + 0xA04 + ((win)<<3))
  43348. +#define MV_AUDIO_WIN_BASE_REG(win) (AUDIO_REG_BASE + 0xA00 + ((win)<<3))
  43349. +
  43350. +#define MV_AUDIO_RECORD_WIN_CTRL_REG MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_RECORD_WIN_NUM)
  43351. +#define MV_AUDIO_RECORD_WIN_BASE_REG MV_AUDIO_WIN_BASE_REG(MV_AUDIO_RECORD_WIN_NUM)
  43352. +#define MV_AUDIO_PLAYBACK_WIN_CTRL_REG MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_PLAYBACK_WIN_NUM)
  43353. +#define MV_AUDIO_PLAYBACK_WIN_BASE_REG MV_AUDIO_WIN_BASE_REG(MV_AUDIO_PLAYBACK_WIN_NUM)
  43354. +
  43355. +
  43356. +/* BITs in Windows 0-3 Control and Base Registers */
  43357. +#define MV_AUDIO_WIN_ENABLE_BIT 0
  43358. +#define MV_AUDIO_WIN_ENABLE_MASK (1<<MV_AUDIO_WIN_ENABLE_BIT)
  43359. +
  43360. +#define MV_AUDIO_WIN_TARGET_OFFSET 4
  43361. +#define MV_AUDIO_WIN_TARGET_MASK (0xF<<MV_AUDIO_WIN_TARGET_OFFSET)
  43362. +
  43363. +#define MV_AUDIO_WIN_ATTR_OFFSET 8
  43364. +#define MV_AUDIO_WIN_ATTR_MASK (0xFF<<MV_AUDIO_WIN_ATTR_OFFSET)
  43365. +
  43366. +#define MV_AUDIO_WIN_SIZE_OFFSET 16
  43367. +#define MV_AUDIO_WIN_SIZE_MASK (0xFFFF<<MV_AUDIO_WIN_SIZE_OFFSET)
  43368. +
  43369. +#define MV_AUDIO_WIN_BASE_OFFSET 16
  43370. +#define MV_AUDIO_WIN_BASE_MASK (0xFFFF<<MV_AUDIO_WIN_BASE_OFFSET)
  43371. +
  43372. +
  43373. +typedef struct _mvAudioDecWin
  43374. +{
  43375. + MV_TARGET target;
  43376. + MV_ADDR_WIN addrWin; /* An address window*/
  43377. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  43378. +
  43379. +} MV_AUDIO_DEC_WIN;
  43380. +
  43381. +
  43382. +MV_STATUS mvAudioInit(MV_VOID);
  43383. +MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);
  43384. +MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);
  43385. +MV_STATUS mvAudioWinInit(MV_VOID);
  43386. +MV_VOID mvAudioAddrDecShow(MV_VOID);
  43387. +
  43388. +
  43389. +#endif
  43390. +
  43391. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c
  43392. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c 1970-01-01 01:00:00.000000000 +0100
  43393. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c 2011-07-31 11:31:57.565858871 +0200
  43394. @@ -0,0 +1,382 @@
  43395. +/*******************************************************************************
  43396. +Copyright (C) Marvell International Ltd. and its affiliates
  43397. +
  43398. +This software file (the "File") is owned and distributed by Marvell
  43399. +International Ltd. and/or its affiliates ("Marvell") under the following
  43400. +alternative licensing terms. Once you have made an election to distribute the
  43401. +File under one of the following license alternatives, please (i) delete this
  43402. +introductory statement regarding license alternatives, (ii) delete the two
  43403. +license alternatives that you have not elected to use and (iii) preserve the
  43404. +Marvell copyright notice above.
  43405. +
  43406. +********************************************************************************
  43407. +Marvell Commercial License Option
  43408. +
  43409. +If you received this File from Marvell and you have entered into a commercial
  43410. +license agreement (a "Commercial License") with Marvell, the File is licensed
  43411. +to you under the terms of the applicable Commercial License.
  43412. +
  43413. +********************************************************************************
  43414. +Marvell GPL License Option
  43415. +
  43416. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43417. +modify this File in accordance with the terms and conditions of the General
  43418. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  43419. +available along with the File in the license.txt file or by writing to the Free
  43420. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  43421. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  43422. +
  43423. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  43424. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  43425. +DISCLAIMED. The GPL License provides additional details about this warranty
  43426. +disclaimer.
  43427. +********************************************************************************
  43428. +Marvell BSD License Option
  43429. +
  43430. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43431. +modify this File under the following licensing terms.
  43432. +Redistribution and use in source and binary forms, with or without modification,
  43433. +are permitted provided that the following conditions are met:
  43434. +
  43435. + * Redistributions of source code must retain the above copyright notice,
  43436. + this list of conditions and the following disclaimer.
  43437. +
  43438. + * Redistributions in binary form must reproduce the above copyright
  43439. + notice, this list of conditions and the following disclaimer in the
  43440. + documentation and/or other materials provided with the distribution.
  43441. +
  43442. + * Neither the name of Marvell nor the names of its contributors may be
  43443. + used to endorse or promote products derived from this software without
  43444. + specific prior written permission.
  43445. +
  43446. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  43447. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  43448. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  43449. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  43450. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  43451. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43452. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  43453. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43454. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  43455. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43456. +
  43457. +*******************************************************************************/
  43458. +
  43459. +#include "mvSysCesa.h"
  43460. +
  43461. +#if (MV_CESA_VERSION >= 2)
  43462. +MV_TARGET tdmaAddrDecPrioTable[] =
  43463. +{
  43464. +#if defined(MV_INCLUDE_SDRAM_CS0)
  43465. + SDRAM_CS0,
  43466. +#endif
  43467. +#if defined(MV_INCLUDE_SDRAM_CS1)
  43468. + SDRAM_CS1,
  43469. +#endif
  43470. +#if defined(MV_INCLUDE_SDRAM_CS2)
  43471. + SDRAM_CS2,
  43472. +#endif
  43473. +#if defined(MV_INCLUDE_SDRAM_CS3)
  43474. + SDRAM_CS3,
  43475. +#endif
  43476. +#if defined(MV_INCLUDE_PEX)
  43477. + PEX0_MEM,
  43478. +#endif
  43479. +
  43480. + TBL_TERM
  43481. +};
  43482. +
  43483. +/*******************************************************************************
  43484. +* mvCesaWinGet - Get TDMA target address window.
  43485. +*
  43486. +* DESCRIPTION:
  43487. +* Get TDMA target address window.
  43488. +*
  43489. +* INPUT:
  43490. +* winNum - TDMA target address decode window number.
  43491. +*
  43492. +* OUTPUT:
  43493. +* pDecWin - TDMA target window data structure.
  43494. +*
  43495. +* RETURN:
  43496. +* MV_ERROR if register parameters are invalid.
  43497. +*
  43498. +*******************************************************************************/
  43499. +static MV_STATUS mvCesaWinGet(MV_U32 winNum, MV_DEC_WIN *pDecWin)
  43500. +{
  43501. + MV_DEC_WIN_PARAMS winParam;
  43502. + MV_U32 sizeReg, baseReg;
  43503. +
  43504. + /* Parameter checking */
  43505. + if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)
  43506. + {
  43507. + mvOsPrintf("%s : ERR. Invalid winNum %d\n",
  43508. + __FUNCTION__, winNum);
  43509. + return MV_NOT_SUPPORTED;
  43510. + }
  43511. +
  43512. + baseReg = MV_REG_READ( MV_CESA_TDMA_BASE_ADDR_REG(winNum) );
  43513. + sizeReg = MV_REG_READ( MV_CESA_TDMA_WIN_CTRL_REG(winNum) );
  43514. +
  43515. + /* Check if window is enabled */
  43516. + if(sizeReg & MV_CESA_TDMA_WIN_ENABLE_MASK)
  43517. + {
  43518. + pDecWin->enable = MV_TRUE;
  43519. +
  43520. + /* Extract window parameters from registers */
  43521. + winParam.targetId = (sizeReg & MV_CESA_TDMA_WIN_TARGET_MASK) >> MV_CESA_TDMA_WIN_TARGET_OFFSET;
  43522. + winParam.attrib = (sizeReg & MV_CESA_TDMA_WIN_ATTR_MASK) >> MV_CESA_TDMA_WIN_ATTR_OFFSET;
  43523. + winParam.size = (sizeReg & MV_CESA_TDMA_WIN_SIZE_MASK) >> MV_CESA_TDMA_WIN_SIZE_OFFSET;
  43524. + winParam.baseAddr = (baseReg & MV_CESA_TDMA_WIN_BASE_MASK);
  43525. +
  43526. + /* Translate the decode window parameters to address decode struct */
  43527. + if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))
  43528. + {
  43529. + mvOsPrintf("Failed to translate register parameters to CESA address" \
  43530. + " decode window structure\n");
  43531. + return MV_ERROR;
  43532. + }
  43533. + }
  43534. + else
  43535. + {
  43536. + pDecWin->enable = MV_FALSE;
  43537. + }
  43538. + return MV_OK;
  43539. +}
  43540. +
  43541. +/*******************************************************************************
  43542. +* cesaWinOverlapDetect - Detect CESA TDMA address windows overlapping
  43543. +*
  43544. +* DESCRIPTION:
  43545. +* An unpredicted behaviur is expected in case TDMA address decode
  43546. +* windows overlapps.
  43547. +* This function detects TDMA address decode windows overlapping of a
  43548. +* specified window. The function does not check the window itself for
  43549. +* overlapping. The function also skipps disabled address decode windows.
  43550. +*
  43551. +* INPUT:
  43552. +* winNum - address decode window number.
  43553. +* pAddrDecWin - An address decode window struct.
  43554. +*
  43555. +* OUTPUT:
  43556. +* None.
  43557. +*
  43558. +* RETURN:
  43559. +* MV_TRUE - if the given address window overlap current address
  43560. +* decode map,
  43561. +* MV_FALSE - otherwise, MV_ERROR if reading invalid data
  43562. +* from registers.
  43563. +*
  43564. +*******************************************************************************/
  43565. +static MV_STATUS cesaWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  43566. +{
  43567. + MV_U32 winNumIndex;
  43568. + MV_DEC_WIN addrDecWin;
  43569. +
  43570. + for(winNumIndex=0; winNumIndex<MV_CESA_TDMA_ADDR_DEC_WIN; winNumIndex++)
  43571. + {
  43572. + /* Do not check window itself */
  43573. + if (winNumIndex == winNum)
  43574. + {
  43575. + continue;
  43576. + }
  43577. +
  43578. + /* Get window parameters */
  43579. + if (MV_OK != mvCesaWinGet(winNumIndex, &addrDecWin))
  43580. + {
  43581. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  43582. + return MV_ERROR;
  43583. + }
  43584. +
  43585. + /* Do not check disabled windows */
  43586. + if(addrDecWin.enable == MV_FALSE)
  43587. + {
  43588. + continue;
  43589. + }
  43590. +
  43591. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  43592. + {
  43593. + return MV_TRUE;
  43594. + }
  43595. + }
  43596. + return MV_FALSE;
  43597. +}
  43598. +
  43599. +/*******************************************************************************
  43600. +* mvCesaTdmaWinSet - Set CESA TDMA target address window
  43601. +*
  43602. +* DESCRIPTION:
  43603. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  43604. +* address window, also known as address decode window.
  43605. +* After setting this target window, the CESA TDMA will be able to access the
  43606. +* target within the address window.
  43607. +*
  43608. +* INPUT:
  43609. +* winNum - CESA TDMA target address decode window number.
  43610. +* pAddrDecWin - CESA TDMA target window data structure.
  43611. +*
  43612. +* OUTPUT:
  43613. +* None.
  43614. +*
  43615. +* RETURN:
  43616. +* MV_ERROR - if address window overlapps with other address decode windows.
  43617. +* MV_BAD_PARAM - if base address is invalid parameter or target is
  43618. +* unknown.
  43619. +*
  43620. +*******************************************************************************/
  43621. +static MV_STATUS mvCesaTdmaWinSet(MV_U32 winNum, MV_DEC_WIN *pDecWin)
  43622. +{
  43623. + MV_DEC_WIN_PARAMS winParams;
  43624. + MV_U32 sizeReg, baseReg;
  43625. +
  43626. + /* Parameter checking */
  43627. + if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)
  43628. + {
  43629. + mvOsPrintf("mvCesaTdmaWinSet: ERR. Invalid win num %d\n",winNum);
  43630. + return MV_BAD_PARAM;
  43631. + }
  43632. +
  43633. + /* Check if the requested window overlapps with current windows */
  43634. + if (MV_TRUE == cesaWinOverlapDetect(winNum, &pDecWin->addrWin))
  43635. + {
  43636. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  43637. + return MV_ERROR;
  43638. + }
  43639. +
  43640. + /* check if address is aligned to the size */
  43641. + if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))
  43642. + {
  43643. + mvOsPrintf("mvCesaTdmaWinSet: Error setting CESA TDMA window %d to "\
  43644. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  43645. + winNum,
  43646. + mvCtrlTargetNameGet(pDecWin->target),
  43647. + pDecWin->addrWin.baseLow,
  43648. + pDecWin->addrWin.size);
  43649. + return MV_ERROR;
  43650. + }
  43651. +
  43652. + if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))
  43653. + {
  43654. + mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);
  43655. + return MV_ERROR;
  43656. + }
  43657. +
  43658. + /* set Size, Attributes and TargetID */
  43659. + sizeReg = (((winParams.targetId << MV_CESA_TDMA_WIN_TARGET_OFFSET) & MV_CESA_TDMA_WIN_TARGET_MASK) |
  43660. + ((winParams.attrib << MV_CESA_TDMA_WIN_ATTR_OFFSET) & MV_CESA_TDMA_WIN_ATTR_MASK) |
  43661. + ((winParams.size << MV_CESA_TDMA_WIN_SIZE_OFFSET) & MV_CESA_TDMA_WIN_SIZE_MASK));
  43662. +
  43663. + if (pDecWin->enable == MV_TRUE)
  43664. + {
  43665. + sizeReg |= MV_CESA_TDMA_WIN_ENABLE_MASK;
  43666. + }
  43667. + else
  43668. + {
  43669. + sizeReg &= ~MV_CESA_TDMA_WIN_ENABLE_MASK;
  43670. + }
  43671. +
  43672. + /* Update Base value */
  43673. + baseReg = (winParams.baseAddr & MV_CESA_TDMA_WIN_BASE_MASK);
  43674. +
  43675. + MV_REG_WRITE( MV_CESA_TDMA_WIN_CTRL_REG(winNum), sizeReg);
  43676. + MV_REG_WRITE( MV_CESA_TDMA_BASE_ADDR_REG(winNum), baseReg);
  43677. +
  43678. + return MV_OK;
  43679. +}
  43680. +
  43681. +
  43682. +static MV_STATUS mvCesaTdmaAddrDecInit (void)
  43683. +{
  43684. + MV_U32 winNum;
  43685. + MV_STATUS status;
  43686. + MV_CPU_DEC_WIN cpuAddrDecWin;
  43687. + MV_DEC_WIN cesaWin;
  43688. + MV_U32 winPrioIndex = 0;
  43689. +
  43690. + /* First disable all address decode windows */
  43691. + for(winNum=0; winNum<MV_CESA_TDMA_ADDR_DEC_WIN; winNum++)
  43692. + {
  43693. + MV_REG_BIT_RESET(MV_CESA_TDMA_WIN_CTRL_REG(winNum), MV_CESA_TDMA_WIN_ENABLE_MASK);
  43694. + }
  43695. +
  43696. + /* Go through all windows in user table until table terminator */
  43697. + winNum = 0;
  43698. + while( (tdmaAddrDecPrioTable[winPrioIndex] != TBL_TERM) &&
  43699. + (winNum < MV_CESA_TDMA_ADDR_DEC_WIN) ) {
  43700. +
  43701. + /* first get attributes from CPU If */
  43702. + status = mvCpuIfTargetWinGet(tdmaAddrDecPrioTable[winPrioIndex],
  43703. + &cpuAddrDecWin);
  43704. + if(MV_NO_SUCH == status){
  43705. + winPrioIndex++;
  43706. + continue;
  43707. + }
  43708. +
  43709. + if (MV_OK != status)
  43710. + {
  43711. + mvOsPrintf("cesaInit: TargetWinGet failed. winNum=%d, winIdx=%d, target=%d, status=0x%x\n",
  43712. + winNum, winPrioIndex, tdmaAddrDecPrioTable[winPrioIndex], status);
  43713. + return MV_ERROR;
  43714. + }
  43715. + if (cpuAddrDecWin.enable == MV_TRUE)
  43716. + {
  43717. + cesaWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  43718. + cesaWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  43719. + cesaWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  43720. + cesaWin.enable = MV_TRUE;
  43721. + cesaWin.target = tdmaAddrDecPrioTable[winPrioIndex];
  43722. +
  43723. +#if defined(MV646xx)
  43724. + /* Get the default attributes for that target window */
  43725. + mvCtrlDefAttribGet(cesaWin.target, &cesaWin.addrWinAttr);
  43726. +#endif /* MV646xx */
  43727. +
  43728. + if(MV_OK != mvCesaTdmaWinSet(winNum, &cesaWin))
  43729. + {
  43730. + mvOsPrintf("mvCesaTdmaWinSet FAILED: winNum=%d\n",
  43731. + winNum);
  43732. + return MV_ERROR;
  43733. + }
  43734. + winNum++;
  43735. + }
  43736. + winPrioIndex++;
  43737. + }
  43738. + return MV_OK;
  43739. +}
  43740. +#endif /* MV_CESA_VERSION >= 2 */
  43741. +
  43742. +
  43743. +
  43744. +
  43745. +MV_STATUS mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle)
  43746. +{
  43747. + MV_U32 cesaCryptEngBase;
  43748. + MV_CPU_DEC_WIN addrDecWin;
  43749. +
  43750. + if(sizeof(MV_CESA_SRAM_MAP) > MV_CESA_SRAM_SIZE)
  43751. + {
  43752. + mvOsPrintf("mvCesaInit: Wrong SRAM map - %ld > %d\n",
  43753. + sizeof(MV_CESA_SRAM_MAP), MV_CESA_SRAM_SIZE);
  43754. + return MV_FAIL;
  43755. + }
  43756. +#if 0
  43757. + if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)
  43758. + cesaCryptEngBase = addrDecWin.addrWin.baseLow;
  43759. + else
  43760. + {
  43761. + mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");
  43762. + return MV_ERROR;
  43763. + }
  43764. +#else
  43765. + cesaCryptEngBase = (MV_U32)pSramBase;
  43766. +#endif
  43767. +
  43768. +#if 0 /* Already done in the platform init */
  43769. +#if (MV_CESA_VERSION >= 2)
  43770. + mvCesaTdmaAddrDecInit();
  43771. +#endif /* MV_CESA_VERSION >= 2 */
  43772. +#endif
  43773. + return mvCesaHalInit(numOfSession, queueDepth, pSramBase, cesaCryptEngBase,
  43774. + osHandle);
  43775. +
  43776. +}
  43777. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h
  43778. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h 1970-01-01 01:00:00.000000000 +0100
  43779. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h 2011-07-31 11:31:57.625566357 +0200
  43780. @@ -0,0 +1,100 @@
  43781. +/*******************************************************************************
  43782. +Copyright (C) Marvell International Ltd. and its affiliates
  43783. +
  43784. +This software file (the "File") is owned and distributed by Marvell
  43785. +International Ltd. and/or its affiliates ("Marvell") under the following
  43786. +alternative licensing terms. Once you have made an election to distribute the
  43787. +File under one of the following license alternatives, please (i) delete this
  43788. +introductory statement regarding license alternatives, (ii) delete the two
  43789. +license alternatives that you have not elected to use and (iii) preserve the
  43790. +Marvell copyright notice above.
  43791. +
  43792. +********************************************************************************
  43793. +Marvell Commercial License Option
  43794. +
  43795. +If you received this File from Marvell and you have entered into a commercial
  43796. +license agreement (a "Commercial License") with Marvell, the File is licensed
  43797. +to you under the terms of the applicable Commercial License.
  43798. +
  43799. +********************************************************************************
  43800. +Marvell GPL License Option
  43801. +
  43802. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43803. +modify this File in accordance with the terms and conditions of the General
  43804. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  43805. +available along with the File in the license.txt file or by writing to the Free
  43806. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  43807. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  43808. +
  43809. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  43810. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  43811. +DISCLAIMED. The GPL License provides additional details about this warranty
  43812. +disclaimer.
  43813. +********************************************************************************
  43814. +Marvell BSD License Option
  43815. +
  43816. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43817. +modify this File under the following licensing terms.
  43818. +Redistribution and use in source and binary forms, with or without modification,
  43819. +are permitted provided that the following conditions are met:
  43820. +
  43821. + * Redistributions of source code must retain the above copyright notice,
  43822. + this list of conditions and the following disclaimer.
  43823. +
  43824. + * Redistributions in binary form must reproduce the above copyright
  43825. + notice, this list of conditions and the following disclaimer in the
  43826. + documentation and/or other materials provided with the distribution.
  43827. +
  43828. + * Neither the name of Marvell nor the names of its contributors may be
  43829. + used to endorse or promote products derived from this software without
  43830. + specific prior written permission.
  43831. +
  43832. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  43833. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  43834. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  43835. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  43836. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  43837. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43838. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  43839. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43840. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  43841. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43842. +
  43843. +*******************************************************************************/
  43844. +
  43845. +#ifndef __mvSysCesa_h__
  43846. +#define __mvSysCesa_h__
  43847. +
  43848. +
  43849. +#include "mvCommon.h"
  43850. +#include "cesa/mvCesa.h"
  43851. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  43852. +#include "ctrlEnv/sys/mvCpuIf.h"
  43853. +
  43854. +/***************************** TDMA Registers *************************************/
  43855. +
  43856. +#define MV_CESA_TDMA_ADDR_DEC_WIN 4
  43857. +
  43858. +#define MV_CESA_TDMA_BASE_ADDR_REG(win) (MV_CESA_TDMA_REG_BASE + 0xa00 + (win<<3))
  43859. +
  43860. +#define MV_CESA_TDMA_WIN_CTRL_REG(win) (MV_CESA_TDMA_REG_BASE + 0xa04 + (win<<3))
  43861. +
  43862. +#define MV_CESA_TDMA_WIN_ENABLE_BIT 0
  43863. +#define MV_CESA_TDMA_WIN_ENABLE_MASK (1 << MV_CESA_TDMA_WIN_ENABLE_BIT)
  43864. +
  43865. +#define MV_CESA_TDMA_WIN_TARGET_OFFSET 4
  43866. +#define MV_CESA_TDMA_WIN_TARGET_MASK (0xf << MV_CESA_TDMA_WIN_TARGET_OFFSET)
  43867. +
  43868. +#define MV_CESA_TDMA_WIN_ATTR_OFFSET 8
  43869. +#define MV_CESA_TDMA_WIN_ATTR_MASK (0xff << MV_CESA_TDMA_WIN_ATTR_OFFSET)
  43870. +
  43871. +#define MV_CESA_TDMA_WIN_SIZE_OFFSET 16
  43872. +#define MV_CESA_TDMA_WIN_SIZE_MASK (0xFFFF << MV_CESA_TDMA_WIN_SIZE_OFFSET)
  43873. +
  43874. +#define MV_CESA_TDMA_WIN_BASE_OFFSET 16
  43875. +#define MV_CESA_TDMA_WIN_BASE_MASK (0xFFFF << MV_CESA_TDMA_WIN_BASE_OFFSET)
  43876. +
  43877. +
  43878. +MV_STATUS mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle);
  43879. +
  43880. +#endif
  43881. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c
  43882. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c 1970-01-01 01:00:00.000000000 +0100
  43883. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c 2011-07-31 11:31:57.673735086 +0200
  43884. @@ -0,0 +1,348 @@
  43885. +/*******************************************************************************
  43886. +Copyright (C) Marvell International Ltd. and its affiliates
  43887. +
  43888. +This software file (the "File") is owned and distributed by Marvell
  43889. +International Ltd. and/or its affiliates ("Marvell") under the following
  43890. +alternative licensing terms. Once you have made an election to distribute the
  43891. +File under one of the following license alternatives, please (i) delete this
  43892. +introductory statement regarding license alternatives, (ii) delete the two
  43893. +license alternatives that you have not elected to use and (iii) preserve the
  43894. +Marvell copyright notice above.
  43895. +
  43896. +********************************************************************************
  43897. +Marvell Commercial License Option
  43898. +
  43899. +If you received this File from Marvell and you have entered into a commercial
  43900. +license agreement (a "Commercial License") with Marvell, the File is licensed
  43901. +to you under the terms of the applicable Commercial License.
  43902. +
  43903. +********************************************************************************
  43904. +Marvell GPL License Option
  43905. +
  43906. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43907. +modify this File in accordance with the terms and conditions of the General
  43908. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  43909. +available along with the File in the license.txt file or by writing to the Free
  43910. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  43911. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  43912. +
  43913. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  43914. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  43915. +DISCLAIMED. The GPL License provides additional details about this warranty
  43916. +disclaimer.
  43917. +********************************************************************************
  43918. +Marvell BSD License Option
  43919. +
  43920. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43921. +modify this File under the following licensing terms.
  43922. +Redistribution and use in source and binary forms, with or without modification,
  43923. +are permitted provided that the following conditions are met:
  43924. +
  43925. + * Redistributions of source code must retain the above copyright notice,
  43926. + this list of conditions and the following disclaimer.
  43927. +
  43928. + * Redistributions in binary form must reproduce the above copyright
  43929. + notice, this list of conditions and the following disclaimer in the
  43930. + documentation and/or other materials provided with the distribution.
  43931. +
  43932. + * Neither the name of Marvell nor the names of its contributors may be
  43933. + used to endorse or promote products derived from this software without
  43934. + specific prior written permission.
  43935. +
  43936. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  43937. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  43938. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  43939. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  43940. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  43941. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43942. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  43943. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43944. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  43945. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43946. +
  43947. +*******************************************************************************/
  43948. +
  43949. +
  43950. +/* includes */
  43951. +
  43952. +#include "ddr2/mvDramIf.h"
  43953. +#include "ctrlEnv/sys/mvCpuIf.h"
  43954. +#include "ctrlEnv/sys/mvSysDram.h"
  43955. +
  43956. +/* #define MV_DEBUG */
  43957. +#ifdef MV_DEBUG
  43958. +#define DB(x) x
  43959. +#else
  43960. +#define DB(x)
  43961. +#endif
  43962. +
  43963. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
  43964. +
  43965. +/*******************************************************************************
  43966. +* mvDramIfWinSet - Set DRAM interface address decode window
  43967. +*
  43968. +* DESCRIPTION:
  43969. +* This function sets DRAM interface address decode window.
  43970. +*
  43971. +* INPUT:
  43972. +* target - System target. Use only SDRAM targets.
  43973. +* pAddrDecWin - SDRAM address window structure.
  43974. +*
  43975. +* OUTPUT:
  43976. +* None
  43977. +*
  43978. +* RETURN:
  43979. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  43980. +* otherwise.
  43981. +*******************************************************************************/
  43982. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  43983. +{
  43984. + MV_U32 baseReg=0,sizeReg=0;
  43985. + MV_U32 baseToReg=0 , sizeToReg=0;
  43986. +
  43987. + /* Check parameters */
  43988. + if (!MV_TARGET_IS_DRAM(target))
  43989. + {
  43990. + mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
  43991. + return MV_BAD_PARAM;
  43992. + }
  43993. +
  43994. + /* Check if the requested window overlaps with current enabled windows */
  43995. + if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
  43996. + {
  43997. + mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
  43998. + return MV_BAD_PARAM;
  43999. + }
  44000. +
  44001. + /* check if address is aligned to the size */
  44002. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  44003. + {
  44004. + mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
  44005. + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
  44006. + target,
  44007. + pAddrDecWin->addrWin.baseLow,
  44008. + pAddrDecWin->addrWin.size);
  44009. + return MV_ERROR;
  44010. + }
  44011. +
  44012. + /* read base register*/
  44013. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));
  44014. +
  44015. + /* read size register */
  44016. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));
  44017. +
  44018. + /* BaseLow[31:16] => base register [31:16] */
  44019. + baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;
  44020. +
  44021. + /* Write to address decode Base Address Register */
  44022. + baseReg &= ~SCBAR_BASE_MASK;
  44023. + baseReg |= baseToReg;
  44024. +
  44025. + /* Translate the given window size to register format */
  44026. + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);
  44027. +
  44028. + /* Size parameter validity check. */
  44029. + if (-1 == sizeToReg)
  44030. + {
  44031. + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
  44032. + return MV_BAD_PARAM;
  44033. + }
  44034. +
  44035. + /* set size */
  44036. + sizeReg &= ~SCSR_SIZE_MASK;
  44037. + /* Size is located at upper 16 bits */
  44038. + sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);
  44039. +
  44040. + /* enable/Disable */
  44041. + if (MV_TRUE == pAddrDecWin->enable)
  44042. + {
  44043. + sizeReg |= SCSR_WIN_EN;
  44044. + }
  44045. + else
  44046. + {
  44047. + sizeReg &= ~SCSR_WIN_EN;
  44048. + }
  44049. +
  44050. + /* 3) Write to address decode Base Address Register */
  44051. + MV_REG_WRITE(SDRAM_BASE_ADDR_REG(0,target), baseReg);
  44052. +
  44053. + /* Write to address decode Size Register */
  44054. + MV_REG_WRITE(SDRAM_SIZE_REG(0,target), sizeReg);
  44055. +
  44056. + return MV_OK;
  44057. +}
  44058. +/*******************************************************************************
  44059. +* mvDramIfWinGet - Get DRAM interface address decode window
  44060. +*
  44061. +* DESCRIPTION:
  44062. +* This function gets DRAM interface address decode window.
  44063. +*
  44064. +* INPUT:
  44065. +* target - System target. Use only SDRAM targets.
  44066. +*
  44067. +* OUTPUT:
  44068. +* pAddrDecWin - SDRAM address window structure.
  44069. +*
  44070. +* RETURN:
  44071. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  44072. +* otherwise.
  44073. +*******************************************************************************/
  44074. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  44075. +{
  44076. + MV_U32 baseReg,sizeReg;
  44077. + MV_U32 sizeRegVal;
  44078. + /* Check parameters */
  44079. + if (!MV_TARGET_IS_DRAM(target))
  44080. + {
  44081. + mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);
  44082. + return MV_ERROR;
  44083. + }
  44084. +
  44085. + /* Read base and size registers */
  44086. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));
  44087. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));
  44088. +
  44089. + sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;
  44090. +
  44091. + pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,
  44092. + SCSR_SIZE_ALIGNMENT);
  44093. +
  44094. + /* Check if ctrlRegToSize returned OK */
  44095. + if (-1 == pAddrDecWin->addrWin.size)
  44096. + {
  44097. + mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);
  44098. + return MV_ERROR;
  44099. + }
  44100. +
  44101. + /* Extract base address */
  44102. + /* Base register [31:16] ==> baseLow[31:16] */
  44103. + pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;
  44104. +
  44105. + pAddrDecWin->addrWin.baseHigh = 0;
  44106. +
  44107. +
  44108. + if (sizeReg & SCSR_WIN_EN)
  44109. + {
  44110. + pAddrDecWin->enable = MV_TRUE;
  44111. + }
  44112. + else
  44113. + {
  44114. + pAddrDecWin->enable = MV_FALSE;
  44115. + }
  44116. +
  44117. + return MV_OK;
  44118. +}
  44119. +/*******************************************************************************
  44120. +* mvDramIfWinEnable - Enable/Disable SDRAM address decode window
  44121. +*
  44122. +* DESCRIPTION:
  44123. +* This function enable/Disable SDRAM address decode window.
  44124. +*
  44125. +* INPUT:
  44126. +* target - System target. Use only SDRAM targets.
  44127. +*
  44128. +* OUTPUT:
  44129. +* None.
  44130. +*
  44131. +* RETURN:
  44132. +* MV_ERROR in case function parameter are invalid, MV_OK otherewise.
  44133. +*
  44134. +*******************************************************************************/
  44135. +MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable)
  44136. +{
  44137. + MV_DRAM_DEC_WIN addrDecWin;
  44138. +
  44139. + /* Check parameters */
  44140. + if (!MV_TARGET_IS_DRAM(target))
  44141. + {
  44142. + mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
  44143. + return MV_ERROR;
  44144. + }
  44145. +
  44146. + if (enable == MV_TRUE)
  44147. + { /* First check for overlap with other enabled windows */
  44148. + if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
  44149. + {
  44150. + mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n",
  44151. + target);
  44152. + return MV_ERROR;
  44153. + }
  44154. + /* Check for overlapping */
  44155. + if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
  44156. + {
  44157. + /* No Overlap. Enable address decode winNum window */
  44158. + MV_REG_BIT_SET(SDRAM_SIZE_REG(0,target), SCSR_WIN_EN);
  44159. + }
  44160. + else
  44161. + { /* Overlap detected */
  44162. + mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
  44163. + target);
  44164. + return MV_ERROR;
  44165. + }
  44166. + }
  44167. + else
  44168. + { /* Disable address decode winNum window */
  44169. + MV_REG_BIT_RESET(SDRAM_SIZE_REG(0, target), SCSR_WIN_EN);
  44170. + }
  44171. +
  44172. + return MV_OK;
  44173. +}
  44174. +
  44175. +/*******************************************************************************
  44176. +* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window
  44177. +*
  44178. +* DESCRIPTION:
  44179. +* This function scan each SDRAM address decode window to test if it
  44180. +* overlapps the given address windoow
  44181. +*
  44182. +* INPUT:
  44183. +* target - SDRAM target where the function skips checking.
  44184. +* pAddrDecWin - The tested address window for overlapping with
  44185. +* SDRAM windows.
  44186. +*
  44187. +* OUTPUT:
  44188. +* None.
  44189. +*
  44190. +* RETURN:
  44191. +* MV_TRUE if the given address window overlaps any enabled address
  44192. +* decode map, MV_FALSE otherwise.
  44193. +*
  44194. +*******************************************************************************/
  44195. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
  44196. +{
  44197. + MV_TARGET targetNum;
  44198. + MV_DRAM_DEC_WIN addrDecWin;
  44199. +
  44200. + for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)
  44201. + {
  44202. + /* don't check our winNum or illegal targets */
  44203. + if (targetNum == target)
  44204. + {
  44205. + continue;
  44206. + }
  44207. +
  44208. + /* Get window parameters */
  44209. + if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))
  44210. + {
  44211. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  44212. + return MV_ERROR;
  44213. + }
  44214. +
  44215. + /* Do not check disabled windows */
  44216. + if (MV_FALSE == addrDecWin.enable)
  44217. + {
  44218. + continue;
  44219. + }
  44220. +
  44221. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  44222. + {
  44223. + mvOsPrintf(
  44224. + "sdramIfWinOverlap: Required target %d overlap winNum %d\n",
  44225. + target, targetNum);
  44226. + return MV_TRUE;
  44227. + }
  44228. + }
  44229. +
  44230. + return MV_FALSE;
  44231. +}
  44232. +
  44233. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h
  44234. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h 1970-01-01 01:00:00.000000000 +0100
  44235. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h 2011-07-31 11:31:57.713929774 +0200
  44236. @@ -0,0 +1,80 @@
  44237. +/*******************************************************************************
  44238. +Copyright (C) Marvell International Ltd. and its affiliates
  44239. +
  44240. +This software file (the "File") is owned and distributed by Marvell
  44241. +International Ltd. and/or its affiliates ("Marvell") under the following
  44242. +alternative licensing terms. Once you have made an election to distribute the
  44243. +File under one of the following license alternatives, please (i) delete this
  44244. +introductory statement regarding license alternatives, (ii) delete the two
  44245. +license alternatives that you have not elected to use and (iii) preserve the
  44246. +Marvell copyright notice above.
  44247. +
  44248. +********************************************************************************
  44249. +Marvell Commercial License Option
  44250. +
  44251. +If you received this File from Marvell and you have entered into a commercial
  44252. +license agreement (a "Commercial License") with Marvell, the File is licensed
  44253. +to you under the terms of the applicable Commercial License.
  44254. +
  44255. +********************************************************************************
  44256. +Marvell GPL License Option
  44257. +
  44258. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44259. +modify this File in accordance with the terms and conditions of the General
  44260. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  44261. +available along with the File in the license.txt file or by writing to the Free
  44262. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  44263. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  44264. +
  44265. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  44266. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  44267. +DISCLAIMED. The GPL License provides additional details about this warranty
  44268. +disclaimer.
  44269. +********************************************************************************
  44270. +Marvell BSD License Option
  44271. +
  44272. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44273. +modify this File under the following licensing terms.
  44274. +Redistribution and use in source and binary forms, with or without modification,
  44275. +are permitted provided that the following conditions are met:
  44276. +
  44277. + * Redistributions of source code must retain the above copyright notice,
  44278. + this list of conditions and the following disclaimer.
  44279. +
  44280. + * Redistributions in binary form must reproduce the above copyright
  44281. + notice, this list of conditions and the following disclaimer in the
  44282. + documentation and/or other materials provided with the distribution.
  44283. +
  44284. + * Neither the name of Marvell nor the names of its contributors may be
  44285. + used to endorse or promote products derived from this software without
  44286. + specific prior written permission.
  44287. +
  44288. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  44289. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  44290. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44291. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  44292. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  44293. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  44294. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  44295. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  44296. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  44297. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44298. +
  44299. +*******************************************************************************/
  44300. +
  44301. +
  44302. +#ifndef __sysDram
  44303. +#define __sysDram
  44304. +
  44305. +/* This structure describes CPU interface address decode window */
  44306. +typedef struct _mvDramIfDecWin
  44307. +{
  44308. + MV_ADDR_WIN addrWin; /* An address window*/
  44309. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  44310. +}MV_DRAM_DEC_WIN;
  44311. +
  44312. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  44313. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  44314. +MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable);
  44315. +
  44316. +#endif
  44317. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c
  44318. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c 1970-01-01 01:00:00.000000000 +0100
  44319. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c 2011-07-31 11:31:57.783424250 +0200
  44320. @@ -0,0 +1,658 @@
  44321. +/*******************************************************************************
  44322. +Copyright (C) Marvell International Ltd. and its affiliates
  44323. +
  44324. +This software file (the "File") is owned and distributed by Marvell
  44325. +International Ltd. and/or its affiliates ("Marvell") under the following
  44326. +alternative licensing terms. Once you have made an election to distribute the
  44327. +File under one of the following license alternatives, please (i) delete this
  44328. +introductory statement regarding license alternatives, (ii) delete the two
  44329. +license alternatives that you have not elected to use and (iii) preserve the
  44330. +Marvell copyright notice above.
  44331. +
  44332. +********************************************************************************
  44333. +Marvell Commercial License Option
  44334. +
  44335. +If you received this File from Marvell and you have entered into a commercial
  44336. +license agreement (a "Commercial License") with Marvell, the File is licensed
  44337. +to you under the terms of the applicable Commercial License.
  44338. +
  44339. +********************************************************************************
  44340. +Marvell GPL License Option
  44341. +
  44342. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44343. +modify this File in accordance with the terms and conditions of the General
  44344. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  44345. +available along with the File in the license.txt file or by writing to the Free
  44346. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  44347. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  44348. +
  44349. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  44350. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  44351. +DISCLAIMED. The GPL License provides additional details about this warranty
  44352. +disclaimer.
  44353. +********************************************************************************
  44354. +Marvell BSD License Option
  44355. +
  44356. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44357. +modify this File under the following licensing terms.
  44358. +Redistribution and use in source and binary forms, with or without modification,
  44359. +are permitted provided that the following conditions are met:
  44360. +
  44361. + * Redistributions of source code must retain the above copyright notice,
  44362. + this list of conditions and the following disclaimer.
  44363. +
  44364. + * Redistributions in binary form must reproduce the above copyright
  44365. + notice, this list of conditions and the following disclaimer in the
  44366. + documentation and/or other materials provided with the distribution.
  44367. +
  44368. + * Neither the name of Marvell nor the names of its contributors may be
  44369. + used to endorse or promote products derived from this software without
  44370. + specific prior written permission.
  44371. +
  44372. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  44373. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  44374. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44375. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  44376. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  44377. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  44378. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  44379. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  44380. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  44381. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44382. +
  44383. +*******************************************************************************/
  44384. +
  44385. +
  44386. +#include "ctrlEnv/sys/mvSysGbe.h"
  44387. +
  44388. +
  44389. +
  44390. +typedef struct _mvEthDecWin
  44391. +{
  44392. + MV_TARGET target;
  44393. + MV_ADDR_WIN addrWin; /* An address window*/
  44394. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  44395. +
  44396. +}MV_ETH_DEC_WIN;
  44397. +
  44398. +MV_TARGET ethAddrDecPrioTap[] =
  44399. +{
  44400. +#if defined(MV_INCLUDE_SDRAM_CS0)
  44401. + SDRAM_CS0,
  44402. +#endif
  44403. +#if defined(MV_INCLUDE_SDRAM_CS1)
  44404. + SDRAM_CS1,
  44405. +#endif
  44406. +#if defined(MV_INCLUDE_SDRAM_CS2)
  44407. + SDRAM_CS2,
  44408. +#endif
  44409. +#if defined(MV_INCLUDE_SDRAM_CS3)
  44410. + SDRAM_CS3,
  44411. +#endif
  44412. +#if defined(MV_INCLUDE_DEVICE_CS0)
  44413. + DEVICE_CS0,
  44414. +#endif
  44415. +#if defined(MV_INCLUDE_DEVICE_CS1)
  44416. + DEVICE_CS1,
  44417. +#endif
  44418. +#if defined(MV_INCLUDE_DEVICE_CS2)
  44419. + DEVICE_CS2,
  44420. +#endif
  44421. +#if defined(MV_INCLUDE_DEVICE_CS3)
  44422. + DEVICE_CS3,
  44423. +#endif
  44424. +#if defined(MV_INCLUDE_PEX)
  44425. + PEX0_IO,
  44426. +#endif
  44427. + TBL_TERM
  44428. +};
  44429. +
  44430. +static MV_STATUS ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  44431. +static MV_STATUS mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);
  44432. +static MV_STATUS mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);
  44433. +
  44434. +
  44435. +/*******************************************************************************
  44436. +* mvEthWinInit - Initialize ETH address decode windows
  44437. +*
  44438. +* DESCRIPTION:
  44439. +* This function initialize ETH window decode unit. It set the
  44440. +* default address decode windows of the unit.
  44441. +*
  44442. +* INPUT:
  44443. +* None.
  44444. +*
  44445. +* OUTPUT:
  44446. +* None.
  44447. +*
  44448. +* RETURN:
  44449. +* MV_ERROR if setting fail.
  44450. +*******************************************************************************/
  44451. +/* Configure EthDrv memory map registes. */
  44452. +MV_STATUS mvEthWinInit (int port)
  44453. +{
  44454. + MV_U32 winNum, status, winPrioIndex=0, i, regVal=0;
  44455. + MV_ETH_DEC_WIN ethWin;
  44456. + MV_CPU_DEC_WIN cpuAddrDecWin;
  44457. + static MV_U32 accessProtReg = 0;
  44458. +
  44459. +#if (MV_ETH_VERSION <= 1)
  44460. + static MV_BOOL isFirst = MV_TRUE;
  44461. +
  44462. + if(isFirst == MV_FALSE)
  44463. + {
  44464. + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);
  44465. + return MV_OK;
  44466. + }
  44467. + isFirst = MV_FALSE;
  44468. +#endif /* MV_GIGA_ETH_VERSION */
  44469. +
  44470. + /* Initiate Ethernet address decode */
  44471. +
  44472. + /* First disable all address decode windows */
  44473. + for(winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)
  44474. + {
  44475. + regVal |= MV_BIT_MASK(winNum);
  44476. + }
  44477. + MV_REG_WRITE(ETH_BASE_ADDR_ENABLE_REG(port), regVal);
  44478. +
  44479. + /* Go through all windows in user table until table terminator */
  44480. + for (winNum=0; ((ethAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  44481. + (winNum < ETH_MAX_DECODE_WIN)); )
  44482. + {
  44483. + /* first get attributes from CPU If */
  44484. + status = mvCpuIfTargetWinGet(ethAddrDecPrioTap[winPrioIndex],
  44485. + &cpuAddrDecWin);
  44486. +
  44487. + if(MV_NO_SUCH == status)
  44488. + {
  44489. + winPrioIndex++;
  44490. + continue;
  44491. + }
  44492. + if (MV_OK != status)
  44493. + {
  44494. + mvOsPrintf("mvEthWinInit: ERR. mvCpuIfTargetWinGet failed\n");
  44495. + return MV_ERROR;
  44496. + }
  44497. +
  44498. + if (cpuAddrDecWin.enable == MV_TRUE)
  44499. + {
  44500. + ethWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  44501. + ethWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  44502. + ethWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  44503. + ethWin.enable = MV_TRUE;
  44504. + ethWin.target = ethAddrDecPrioTap[winPrioIndex];
  44505. +
  44506. + if(MV_OK != mvEthWinSet(port, winNum, &ethWin))
  44507. + {
  44508. + mvOsPrintf("mvEthWinInit: ERR. mvEthWinSet failed winNum=%d\n",
  44509. + winNum);
  44510. + return MV_ERROR;
  44511. + }
  44512. + winNum++;
  44513. + }
  44514. + winPrioIndex ++;
  44515. + }
  44516. +
  44517. + /* set full access to all windows. */
  44518. + for(i=0; i<winNum; i++)
  44519. + {
  44520. + accessProtReg |= (FULL_ACCESS << (i*2));
  44521. + }
  44522. + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);
  44523. +
  44524. + return MV_OK;
  44525. +}
  44526. +
  44527. +/*******************************************************************************
  44528. +* mvEthWinSet - Set ETH target address window
  44529. +*
  44530. +* DESCRIPTION:
  44531. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  44532. +* address window, also known as address decode window.
  44533. +* After setting this target window, the ETH will be able to access the
  44534. +* target within the address window.
  44535. +*
  44536. +* INPUT:
  44537. +* winNum - ETH to target address decode window number.
  44538. +* pAddrDecWin - ETH target window data structure.
  44539. +*
  44540. +* OUTPUT:
  44541. +* None.
  44542. +*
  44543. +* RETURN:
  44544. +* MV_ERROR if address window overlapps with other address decode windows.
  44545. +* MV_BAD_PARAM if base address is invalid parameter or target is
  44546. +* unknown.
  44547. +*
  44548. +*******************************************************************************/
  44549. +MV_STATUS mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)
  44550. +{
  44551. + MV_TARGET_ATTRIB targetAttribs;
  44552. + MV_DEC_REGS decRegs;
  44553. +
  44554. + /* Parameter checking */
  44555. + if (winNum >= ETH_MAX_DECODE_WIN)
  44556. + {
  44557. + mvOsPrintf("mvEthWinSet: ERR. Invalid win num %d\n",winNum);
  44558. + return MV_BAD_PARAM;
  44559. + }
  44560. +
  44561. + /* Check if the requested window overlapps with current windows */
  44562. + if (MV_TRUE == ethWinOverlapDetect(port, winNum, &pAddrDecWin->addrWin))
  44563. + {
  44564. + mvOsPrintf("mvEthWinSet: ERR. Window %d overlap\n", winNum);
  44565. + return MV_ERROR;
  44566. + }
  44567. +
  44568. + /* check if address is aligned to the size */
  44569. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  44570. + {
  44571. + mvOsPrintf("mvEthWinSet: Error setting Ethernet window %d to "\
  44572. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  44573. + winNum,
  44574. + mvCtrlTargetNameGet(pAddrDecWin->target),
  44575. + pAddrDecWin->addrWin.baseLow,
  44576. + pAddrDecWin->addrWin.size);
  44577. + return MV_ERROR;
  44578. + }
  44579. +
  44580. +
  44581. + decRegs.baseReg = MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));
  44582. + decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));
  44583. +
  44584. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  44585. + {
  44586. + mvOsPrintf("mvEthWinSet:mvCtrlAddrDecToReg Failed\n");
  44587. + return MV_ERROR;
  44588. + }
  44589. +
  44590. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  44591. +
  44592. + /* set attributes */
  44593. + decRegs.baseReg &= ~ETH_WIN_ATTR_MASK;
  44594. + decRegs.baseReg |= targetAttribs.attrib << ETH_WIN_ATTR_OFFS;
  44595. + /* set target ID */
  44596. + decRegs.baseReg &= ~ETH_WIN_TARGET_MASK;
  44597. + decRegs.baseReg |= targetAttribs.targetId << ETH_WIN_TARGET_OFFS;
  44598. +
  44599. + /* for the safe side we disable the window before writing the new
  44600. + values */
  44601. + mvEthWinEnable(port, winNum, MV_FALSE);
  44602. + MV_REG_WRITE(ETH_WIN_BASE_REG(port, winNum), decRegs.baseReg);
  44603. +
  44604. + /* Write to address decode Size Register */
  44605. + MV_REG_WRITE(ETH_WIN_SIZE_REG(port, winNum), decRegs.sizeReg);
  44606. +
  44607. + /* Enable address decode target window */
  44608. + if (pAddrDecWin->enable == MV_TRUE)
  44609. + {
  44610. + mvEthWinEnable(port, winNum, MV_TRUE);
  44611. + }
  44612. +
  44613. + return MV_OK;
  44614. +}
  44615. +
  44616. +/*******************************************************************************
  44617. +* mvETHWinGet - Get dma peripheral target address window.
  44618. +*
  44619. +* DESCRIPTION:
  44620. +* Get ETH peripheral target address window.
  44621. +*
  44622. +* INPUT:
  44623. +* winNum - ETH to target address decode window number.
  44624. +*
  44625. +* OUTPUT:
  44626. +* pAddrDecWin - ETH target window data structure.
  44627. +*
  44628. +* RETURN:
  44629. +* MV_ERROR if register parameters are invalid.
  44630. +*
  44631. +*******************************************************************************/
  44632. +MV_STATUS mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)
  44633. +{
  44634. + MV_DEC_REGS decRegs;
  44635. + MV_TARGET_ATTRIB targetAttrib;
  44636. +
  44637. + /* Parameter checking */
  44638. + if (winNum >= ETH_MAX_DECODE_WIN)
  44639. + {
  44640. + mvOsPrintf("mvEthWinGet: ERR. Invalid winNum %d\n", winNum);
  44641. + return MV_NOT_SUPPORTED;
  44642. + }
  44643. +
  44644. + decRegs.baseReg = MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));
  44645. + decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));
  44646. +
  44647. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  44648. + {
  44649. + mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");
  44650. + return MV_ERROR;
  44651. + }
  44652. +
  44653. + /* attrib and targetId */
  44654. + targetAttrib.attrib =
  44655. + (decRegs.baseReg & ETH_WIN_ATTR_MASK) >> ETH_WIN_ATTR_OFFS;
  44656. + targetAttrib.targetId =
  44657. + (decRegs.baseReg & ETH_WIN_TARGET_MASK) >> ETH_WIN_TARGET_OFFS;
  44658. +
  44659. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  44660. +
  44661. + /* Check if window is enabled */
  44662. + if (~(MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port))) & (1 << winNum) )
  44663. + {
  44664. + pAddrDecWin->enable = MV_TRUE;
  44665. + }
  44666. + else
  44667. + {
  44668. + pAddrDecWin->enable = MV_FALSE;
  44669. + }
  44670. +
  44671. + return MV_OK;
  44672. +}
  44673. +
  44674. +/*******************************************************************************
  44675. +* mvEthWinEnable - Enable/disable a ETH to target address window
  44676. +*
  44677. +* DESCRIPTION:
  44678. +* This function enable/disable a ETH to target address window.
  44679. +* According to parameter 'enable' the routine will enable the
  44680. +* window, thus enabling ETH accesses (before enabling the window it is
  44681. +* tested for overlapping). Otherwise, the window will be disabled.
  44682. +*
  44683. +* INPUT:
  44684. +* winNum - ETH to target address decode window number.
  44685. +* enable - Enable/disable parameter.
  44686. +*
  44687. +* OUTPUT:
  44688. +* N/A
  44689. +*
  44690. +* RETURN:
  44691. +* MV_ERROR if decode window number was wrong or enabled window overlapps.
  44692. +*
  44693. +*******************************************************************************/
  44694. +MV_STATUS mvEthWinEnable(int port, MV_U32 winNum,MV_BOOL enable)
  44695. +{
  44696. + MV_ETH_DEC_WIN addrDecWin;
  44697. +
  44698. + /* Parameter checking */
  44699. + if (winNum >= ETH_MAX_DECODE_WIN)
  44700. + {
  44701. + mvOsPrintf("mvEthTargetWinEnable:ERR. Invalid winNum%d\n",winNum);
  44702. + return MV_ERROR;
  44703. + }
  44704. +
  44705. + if (enable == MV_TRUE)
  44706. + { /* First check for overlap with other enabled windows */
  44707. + /* Get current window */
  44708. + if (MV_OK != mvEthWinGet(port, winNum, &addrDecWin))
  44709. + {
  44710. + mvOsPrintf("mvEthTargetWinEnable:ERR. targetWinGet fail\n");
  44711. + return MV_ERROR;
  44712. + }
  44713. + /* Check for overlapping */
  44714. + if (MV_FALSE == ethWinOverlapDetect(port, winNum, &(addrDecWin.addrWin)))
  44715. + {
  44716. + /* No Overlap. Enable address decode target window */
  44717. + MV_REG_BIT_RESET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));
  44718. + }
  44719. + else
  44720. + { /* Overlap detected */
  44721. + mvOsPrintf("mvEthTargetWinEnable:ERR. Overlap detected\n");
  44722. + return MV_ERROR;
  44723. + }
  44724. + }
  44725. + else
  44726. + { /* Disable address decode target window */
  44727. + MV_REG_BIT_SET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));
  44728. + }
  44729. + return MV_OK;
  44730. +}
  44731. +
  44732. +/*******************************************************************************
  44733. +* mvEthWinTargetGet - Get Window number associated with target
  44734. +*
  44735. +* DESCRIPTION:
  44736. +*
  44737. +* INPUT:
  44738. +*
  44739. +* OUTPUT:
  44740. +*
  44741. +* RETURN:
  44742. +* window number
  44743. +*
  44744. +*******************************************************************************/
  44745. +MV_U32 mvEthWinTargetGet(int port, MV_TARGET target)
  44746. +{
  44747. + MV_ETH_DEC_WIN decWin;
  44748. + MV_U32 winNum;
  44749. +
  44750. + /* Check parameters */
  44751. + if (target >= MAX_TARGETS)
  44752. + {
  44753. + mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);
  44754. + return 0xffffffff;
  44755. + }
  44756. +
  44757. + for (winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)
  44758. + {
  44759. + if (mvEthWinGet(port, winNum,&decWin) != MV_OK)
  44760. + {
  44761. + mvOsPrintf("mvAhbToMbusWinTargetGet: window returned error\n");
  44762. + return 0xffffffff;
  44763. + }
  44764. +
  44765. + if (decWin.enable == MV_TRUE)
  44766. + {
  44767. + if (decWin.target == target)
  44768. + {
  44769. + return winNum;
  44770. + }
  44771. + }
  44772. + }
  44773. + return 0xFFFFFFFF;
  44774. +}
  44775. +
  44776. +/*******************************************************************************
  44777. +* mvEthProtWinSet - Set access protection of Ethernet to target window.
  44778. +*
  44779. +* DESCRIPTION:
  44780. +* Each Ethernet port can be configured with access attributes for each
  44781. +* of the Ethenret to target windows (address decode windows). This
  44782. +* function sets access attributes to a given window for the given channel.
  44783. +*
  44784. +* INPUTS:
  44785. +* ethPort - ETH channel number. See MV_ETH_CHANNEL enumerator.
  44786. +* winNum - IETH to target address decode window number.
  44787. +* access - IETH access rights. See MV_ACCESS_RIGHTS enumerator.
  44788. +*
  44789. +* OUTPUT:
  44790. +* None.
  44791. +*
  44792. +* RETURN:
  44793. +* MV_ERROR in case window number is invalid or access right reserved.
  44794. +*
  44795. +*******************************************************************************/
  44796. +MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS access)
  44797. +{
  44798. + MV_U32 protReg;
  44799. +
  44800. + /* Parameter checking */
  44801. + if(portNo >= mvCtrlEthMaxPortGet())
  44802. + {
  44803. + mvOsPrintf("mvEthProtWinSet:ERR. Invalid port number %d\n", portNo);
  44804. + return MV_ERROR;
  44805. + }
  44806. +
  44807. + if (winNum >= ETH_MAX_DECODE_WIN)
  44808. + {
  44809. + mvOsPrintf("mvEthProtWinSet:ERR. Invalid winNum%d\n",winNum);
  44810. + return MV_ERROR;
  44811. + }
  44812. +
  44813. + if((access == ACC_RESERVED) || (access >= MAX_ACC_RIGHTS))
  44814. + {
  44815. + mvOsPrintf("mvEthProtWinSet:ERR. Inv access param %d\n", access);
  44816. + return MV_ERROR;
  44817. + }
  44818. + /* Read current protection register */
  44819. + protReg = MV_REG_READ(ETH_ACCESS_PROTECT_REG(portNo));
  44820. +
  44821. + /* Clear protection window field */
  44822. + protReg &= ~(ETH_PROT_WIN_MASK(winNum));
  44823. +
  44824. + /* Set new protection field value */
  44825. + protReg |= (access << (ETH_PROT_WIN_OFFS(winNum)));
  44826. +
  44827. + /* Write protection register back */
  44828. + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(portNo), protReg);
  44829. +
  44830. + return MV_OK;
  44831. +}
  44832. +
  44833. +/*******************************************************************************
  44834. +* ethWinOverlapDetect - Detect ETH address windows overlapping
  44835. +*
  44836. +* DESCRIPTION:
  44837. +* An unpredicted behaviur is expected in case ETH address decode
  44838. +* windows overlapps.
  44839. +* This function detects ETH address decode windows overlapping of a
  44840. +* specified window. The function does not check the window itself for
  44841. +* overlapping. The function also skipps disabled address decode windows.
  44842. +*
  44843. +* INPUT:
  44844. +* winNum - address decode window number.
  44845. +* pAddrDecWin - An address decode window struct.
  44846. +*
  44847. +* OUTPUT:
  44848. +* None.
  44849. +*
  44850. +* RETURN:
  44851. +* MV_TRUE if the given address window overlap current address
  44852. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  44853. +* from registers.
  44854. +*
  44855. +*******************************************************************************/
  44856. +static MV_STATUS ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  44857. +{
  44858. + MV_U32 baseAddrEnableReg;
  44859. + MV_U32 winNumIndex;
  44860. + MV_ETH_DEC_WIN addrDecWin;
  44861. +
  44862. + /* Read base address enable register. Do not check disabled windows */
  44863. + baseAddrEnableReg = MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port));
  44864. +
  44865. + for (winNumIndex=0; winNumIndex<ETH_MAX_DECODE_WIN; winNumIndex++)
  44866. + {
  44867. + /* Do not check window itself */
  44868. + if (winNumIndex == winNum)
  44869. + {
  44870. + continue;
  44871. + }
  44872. +
  44873. + /* Do not check disabled windows */
  44874. + if (baseAddrEnableReg & (1 << winNumIndex))
  44875. + {
  44876. + continue;
  44877. + }
  44878. +
  44879. + /* Get window parameters */
  44880. + if (MV_OK != mvEthWinGet(port, winNumIndex, &addrDecWin))
  44881. + {
  44882. + mvOsPrintf("ethWinOverlapDetect: ERR. TargetWinGet failed\n");
  44883. + return MV_ERROR;
  44884. + }
  44885. +/*
  44886. + mvOsPrintf("ethWinOverlapDetect:\n
  44887. + winNumIndex =%d baseHigh =0x%x baseLow=0x%x size=0x%x enable=0x%x\n",
  44888. + winNumIndex,
  44889. + addrDecWin.addrWin.baseHigh,
  44890. + addrDecWin.addrWin.baseLow,
  44891. + addrDecWin.addrWin.size,
  44892. + addrDecWin.enable);
  44893. +*/
  44894. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  44895. + {
  44896. + return MV_TRUE;
  44897. + }
  44898. + }
  44899. + return MV_FALSE;
  44900. +}
  44901. +
  44902. +/*******************************************************************************
  44903. +* mvEthAddrDecShow - Print the Etherent address decode map.
  44904. +*
  44905. +* DESCRIPTION:
  44906. +* This function print the Etherent address decode map.
  44907. +*
  44908. +* INPUT:
  44909. +* None.
  44910. +*
  44911. +* OUTPUT:
  44912. +* None.
  44913. +*
  44914. +* RETURN:
  44915. +* None.
  44916. +*
  44917. +*******************************************************************************/
  44918. +void mvEthPortAddrDecShow(int port)
  44919. +{
  44920. + MV_ETH_DEC_WIN win;
  44921. + int i;
  44922. +
  44923. + mvOsOutput( "\n" );
  44924. + mvOsOutput( "ETH %d:\n", port );
  44925. + mvOsOutput( "----\n" );
  44926. +
  44927. + for( i = 0; i < ETH_MAX_DECODE_WIN; i++ )
  44928. + {
  44929. + memset( &win, 0, sizeof(ETH_MAX_DECODE_WIN) );
  44930. +
  44931. + mvOsOutput( "win%d - ", i );
  44932. +
  44933. + if( mvEthWinGet(port, i, &win ) == MV_OK )
  44934. + {
  44935. + if( win.enable )
  44936. + {
  44937. + mvOsOutput( "%s base %08x, ",
  44938. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  44939. + mvOsOutput( "...." );
  44940. + mvSizePrint( win.addrWin.size );
  44941. +
  44942. + mvOsOutput( "\n" );
  44943. + }
  44944. + else
  44945. + mvOsOutput( "disable\n" );
  44946. + }
  44947. + }
  44948. + return;
  44949. +}
  44950. +
  44951. +void mvEthAddrDecShow(void)
  44952. +{
  44953. + int port;
  44954. +
  44955. + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
  44956. + {
  44957. + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;
  44958. +
  44959. + mvEthPortAddrDecShow(port);
  44960. + }
  44961. +}
  44962. +
  44963. +
  44964. +void mvEthInit(void)
  44965. +{
  44966. + MV_U32 port;
  44967. +
  44968. + /* Power down all existing ports */
  44969. + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
  44970. + {
  44971. + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port))
  44972. + continue;
  44973. +
  44974. + mvEthPortPowerUp(port);
  44975. + mvEthWinInit(port);
  44976. + }
  44977. + mvEthHalInit();
  44978. +}
  44979. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h
  44980. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h 1970-01-01 01:00:00.000000000 +0100
  44981. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h 2011-07-31 11:31:57.823424990 +0200
  44982. @@ -0,0 +1,113 @@
  44983. +/*******************************************************************************
  44984. +Copyright (C) Marvell International Ltd. and its affiliates
  44985. +
  44986. +This software file (the "File") is owned and distributed by Marvell
  44987. +International Ltd. and/or its affiliates ("Marvell") under the following
  44988. +alternative licensing terms. Once you have made an election to distribute the
  44989. +File under one of the following license alternatives, please (i) delete this
  44990. +introductory statement regarding license alternatives, (ii) delete the two
  44991. +license alternatives that you have not elected to use and (iii) preserve the
  44992. +Marvell copyright notice above.
  44993. +
  44994. +********************************************************************************
  44995. +Marvell Commercial License Option
  44996. +
  44997. +If you received this File from Marvell and you have entered into a commercial
  44998. +license agreement (a "Commercial License") with Marvell, the File is licensed
  44999. +to you under the terms of the applicable Commercial License.
  45000. +
  45001. +********************************************************************************
  45002. +Marvell GPL License Option
  45003. +
  45004. +If you received this File from Marvell, you may opt to use, redistribute and/or
  45005. +modify this File in accordance with the terms and conditions of the General
  45006. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  45007. +available along with the File in the license.txt file or by writing to the Free
  45008. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  45009. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  45010. +
  45011. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  45012. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  45013. +DISCLAIMED. The GPL License provides additional details about this warranty
  45014. +disclaimer.
  45015. +********************************************************************************
  45016. +Marvell BSD License Option
  45017. +
  45018. +If you received this File from Marvell, you may opt to use, redistribute and/or
  45019. +modify this File under the following licensing terms.
  45020. +Redistribution and use in source and binary forms, with or without modification,
  45021. +are permitted provided that the following conditions are met:
  45022. +
  45023. + * Redistributions of source code must retain the above copyright notice,
  45024. + this list of conditions and the following disclaimer.
  45025. +
  45026. + * Redistributions in binary form must reproduce the above copyright
  45027. + notice, this list of conditions and the following disclaimer in the
  45028. + documentation and/or other materials provided with the distribution.
  45029. +
  45030. + * Neither the name of Marvell nor the names of its contributors may be
  45031. + used to endorse or promote products derived from this software without
  45032. + specific prior written permission.
  45033. +
  45034. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  45035. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  45036. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  45037. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  45038. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  45039. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45040. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  45041. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  45042. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  45043. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  45044. +
  45045. +*******************************************************************************/
  45046. +
  45047. +#ifndef __INCmvSysGbeh
  45048. +#define __INCmvSysGbeh
  45049. +
  45050. +#include "mvCommon.h"
  45051. +#include "eth/mvEth.h"
  45052. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  45053. +#include "ctrlEnv/sys/mvCpuIf.h"
  45054. +
  45055. +#define ETH_WIN_BASE_REG(port, win) (MV_ETH_REG_BASE(port) + 0x200 + ((win)<<3))
  45056. +#define ETH_WIN_SIZE_REG(port, win) (MV_ETH_REG_BASE(port) + 0x204 + ((win)<<3))
  45057. +#define ETH_WIN_REMAP_REG(port, win) (MV_ETH_REG_BASE(port) + 0x280 + ((win)<<2))
  45058. +#define ETH_BASE_ADDR_ENABLE_REG(port) (MV_ETH_REG_BASE(port) + 0x290)
  45059. +#define ETH_ACCESS_PROTECT_REG(port) (MV_ETH_REG_BASE(port) + 0x294)
  45060. +
  45061. +/**** Address decode parameters ****/
  45062. +
  45063. +/* Ethernet Base Address Register bits */
  45064. +#define ETH_MAX_DECODE_WIN 6
  45065. +#define ETH_MAX_HIGH_ADDR_REMAP_WIN 4
  45066. +
  45067. +/* Ethernet Port Access Protect (EPAP) register */
  45068. +
  45069. +/* The target associated with this window*/
  45070. +#define ETH_WIN_TARGET_OFFS 0
  45071. +#define ETH_WIN_TARGET_MASK (0xf << ETH_WIN_TARGET_OFFS)
  45072. +/* The target attributes Associated with window */
  45073. +#define ETH_WIN_ATTR_OFFS 8
  45074. +#define ETH_WIN_ATTR_MASK (0xff << ETH_WIN_ATTR_OFFS)
  45075. +
  45076. +/* Ethernet Port Access Protect Register (EPAPR) */
  45077. +#define ETH_PROT_NO_ACCESS NO_ACCESS_ALLOWED
  45078. +#define ETH_PROT_READ_ONLY READ_ONLY
  45079. +#define ETH_PROT_FULL_ACCESS FULL_ACCESS
  45080. +#define ETH_PROT_WIN_OFFS(winNum) (2 * (winNum))
  45081. +#define ETH_PROT_WIN_MASK(winNum) (0x3 << ETH_PROT_WIN_OFFS(winNum))
  45082. +
  45083. +MV_STATUS mvEthWinInit (int port);
  45084. +MV_STATUS mvEthWinEnable(int port, MV_U32 winNum, MV_BOOL enable);
  45085. +MV_U32 mvEthWinTargetGet(int port, MV_TARGET target);
  45086. +MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS
  45087. + access);
  45088. +
  45089. +void mvEthPortAddrDecShow(int port);
  45090. +
  45091. +MV_VOID mvEthAddrDecShow(MV_VOID);
  45092. +
  45093. +void mvEthInit(void);
  45094. +
  45095. +#endif
  45096. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c
  45097. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c 1970-01-01 01:00:00.000000000 +0100
  45098. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c 2011-07-31 11:31:57.883646977 +0200
  45099. @@ -0,0 +1,1697 @@
  45100. +/*******************************************************************************
  45101. +Copyright (C) Marvell International Ltd. and its affiliates
  45102. +
  45103. +This software file (the "File") is owned and distributed by Marvell
  45104. +International Ltd. and/or its affiliates ("Marvell") under the following
  45105. +alternative licensing terms. Once you have made an election to distribute the
  45106. +File under one of the following license alternatives, please (i) delete this
  45107. +introductory statement regarding license alternatives, (ii) delete the two
  45108. +license alternatives that you have not elected to use and (iii) preserve the
  45109. +Marvell copyright notice above.
  45110. +
  45111. +********************************************************************************
  45112. +Marvell Commercial License Option
  45113. +
  45114. +If you received this File from Marvell and you have entered into a commercial
  45115. +license agreement (a "Commercial License") with Marvell, the File is licensed
  45116. +to you under the terms of the applicable Commercial License.
  45117. +
  45118. +********************************************************************************
  45119. +Marvell GPL License Option
  45120. +
  45121. +If you received this File from Marvell, you may opt to use, redistribute and/or
  45122. +modify this File in accordance with the terms and conditions of the General
  45123. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  45124. +available along with the File in the license.txt file or by writing to the Free
  45125. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  45126. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  45127. +
  45128. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  45129. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  45130. +DISCLAIMED. The GPL License provides additional details about this warranty
  45131. +disclaimer.
  45132. +********************************************************************************
  45133. +Marvell BSD License Option
  45134. +
  45135. +If you received this File from Marvell, you may opt to use, redistribute and/or
  45136. +modify this File under the following licensing terms.
  45137. +Redistribution and use in source and binary forms, with or without modification,
  45138. +are permitted provided that the following conditions are met:
  45139. +
  45140. + * Redistributions of source code must retain the above copyright notice,
  45141. + this list of conditions and the following disclaimer.
  45142. +
  45143. + * Redistributions in binary form must reproduce the above copyright
  45144. + notice, this list of conditions and the following disclaimer in the
  45145. + documentation and/or other materials provided with the distribution.
  45146. +
  45147. + * Neither the name of Marvell nor the names of its contributors may be
  45148. + used to endorse or promote products derived from this software without
  45149. + specific prior written permission.
  45150. +
  45151. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  45152. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  45153. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  45154. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  45155. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  45156. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45157. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  45158. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  45159. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  45160. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  45161. +
  45162. +*******************************************************************************/
  45163. +
  45164. +#include "ctrlEnv/sys/mvSysPex.h"
  45165. +
  45166. +/* this structure describes the mapping between a Pex Window and a CPU target*/
  45167. +typedef struct _pexWinToTarget
  45168. +{
  45169. + MV_TARGET target;
  45170. + MV_BOOL enable;
  45171. +
  45172. +}PEX_WIN_TO_TARGET;
  45173. +
  45174. +/* this array is a priority array that define How Pex windows should be
  45175. +configured , We have only 6 Pex Windows that can be configured , but we
  45176. +have maximum of 9 CPU target windows ! the following array is a priority
  45177. +array where the lowest index has the highest priotiy and the highest
  45178. +index has the lowest priority of being cnfigured */
  45179. +
  45180. +MV_U32 pexDevBarPrioTable[] =
  45181. +{
  45182. +#if defined(MV_INCLUDE_DEVICE_CS0)
  45183. + DEVICE_CS0,
  45184. +#endif
  45185. +#if defined(MV_INCLUDE_DEVICE_CS1)
  45186. + DEVICE_CS1,
  45187. +#endif
  45188. +#if defined(MV_INCLUDE_DEVICE_CS2)
  45189. + DEVICE_CS2,
  45190. +#endif
  45191. +#if defined(MV_INCLUDE_DEVICE_CS3)
  45192. + DEVICE_CS3,
  45193. +#endif
  45194. +/*
  45195. +#if defined(MV_INCLUDE_DEVICE_CS4)
  45196. + DEVICE_CS4,
  45197. +#endif
  45198. +*/
  45199. + TBL_TERM
  45200. +};
  45201. +
  45202. +
  45203. +/* PEX Wins registers offsets are inconsecutive. This struct describes WIN */
  45204. +/* register offsets and its function where its is located. */
  45205. +/* Also, PEX address remap registers offsets are inconsecutive. This struct */
  45206. +/* describes address remap register offsets */
  45207. +typedef struct _pexWinRegInfo
  45208. +{
  45209. + MV_U32 baseLowRegOffs;
  45210. + MV_U32 baseHighRegOffs;
  45211. + MV_U32 sizeRegOffs;
  45212. + MV_U32 remapLowRegOffs;
  45213. + MV_U32 remapHighRegOffs;
  45214. +
  45215. +}PEX_WIN_REG_INFO;
  45216. +
  45217. +static MV_STATUS pexWinOverlapDetect(MV_U32 pexIf, MV_U32 winNum,
  45218. + MV_ADDR_WIN *pAddrWin);
  45219. +static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf, MV_U32 winNum,
  45220. + PEX_WIN_REG_INFO *pWinRegInfo);
  45221. +
  45222. +static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size);
  45223. +
  45224. +static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,MV_ADDR_WIN *pAddrWin);
  45225. +static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,MV_U32 barNum,
  45226. + MV_ADDR_WIN *pAddrWin);
  45227. +const MV_8* pexBarNameGet( MV_U32 bar );
  45228. +
  45229. +
  45230. +/*******************************************************************************
  45231. +* mvPexInit - Initialize PEX interfaces
  45232. +*
  45233. +* DESCRIPTION:
  45234. +*
  45235. +* This function is responsible of intialization of the Pex Interface , It
  45236. +* configure the Pex Bars and Windows in the following manner:
  45237. +*
  45238. +* Assumptions :
  45239. +* Bar0 is always internal registers bar
  45240. +* Bar1 is always the DRAM bar
  45241. +* Bar2 is always the Device bar
  45242. +*
  45243. +* 1) Sets the Internal registers bar base by obtaining the base from
  45244. +* the CPU Interface
  45245. +* 2) Sets the DRAM bar base and size by getting the base and size from
  45246. +* the CPU Interface when the size is the sum of all enabled DRAM
  45247. +* chip selects and the base is the base of CS0 .
  45248. +* 3) Sets the Device bar base and size by getting these values from the
  45249. +* CPU Interface when the base is the base of the lowest base of the
  45250. +* Device chip selects, and the
  45251. +*
  45252. +*
  45253. +* INPUT:
  45254. +*
  45255. +* pexIf - PEX interface number.
  45256. +*
  45257. +*
  45258. +* OUTPUT:
  45259. +* None.
  45260. +*
  45261. +* RETURN:
  45262. +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
  45263. +*
  45264. +*******************************************************************************/
  45265. +MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
  45266. +{
  45267. + MV_U32 bar;
  45268. + MV_U32 winNum;
  45269. + MV_PEX_BAR pexBar;
  45270. + MV_PEX_DEC_WIN pexWin;
  45271. + MV_CPU_DEC_WIN addrDecWin;
  45272. + MV_TARGET target;
  45273. + MV_U32 pexCurrWin=0;
  45274. + MV_U32 status;
  45275. + /* default and exapntion rom
  45276. + are always configured */
  45277. +
  45278. +#ifndef MV_DISABLE_PEX_DEVICE_BAR
  45279. + MV_U32 winIndex;
  45280. + MV_U32 maxBase=0, sizeOfMaxBase=0;
  45281. + MV_U32 pexStartWindow;
  45282. +#endif
  45283. +
  45284. + /* Parameter checking */
  45285. + if(pexIf >= mvCtrlPexMaxIfGet())
  45286. + {
  45287. + mvOsPrintf("mvPexInit: ERR. Invalid PEX interface %d\n", pexIf);
  45288. + return MV_BAD_PARAM;
  45289. + }
  45290. +
  45291. + /* Enabled CPU access to PCI-Express */
  45292. + mvCpuIfEnablePex(pexIf, pexType);
  45293. +
  45294. + /* Start with bars */
  45295. + /* First disable all PEX bars*/
  45296. + for (bar = 0; bar < PEX_MAX_BARS; bar++)
  45297. + {
  45298. + if (PEX_INTER_REGS_BAR != bar)
  45299. + {
  45300. + if (MV_OK != mvPexBarEnable(pexIf, bar, MV_FALSE))
  45301. + {
  45302. + mvOsPrintf("mvPexInit:mvPexBarEnable bar =%d failed \n",bar);
  45303. + return MV_ERROR;
  45304. + }
  45305. +
  45306. + }
  45307. +
  45308. + }
  45309. +
  45310. + /* and disable all PEX target windows */
  45311. + for (winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
  45312. + {
  45313. + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_FALSE))
  45314. + {
  45315. + mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
  45316. + winNum);
  45317. + return MV_ERROR;
  45318. +
  45319. + }
  45320. + }
  45321. +
  45322. + /* Now, go through all bars*/
  45323. +
  45324. +
  45325. +
  45326. +/******************************************************************************/
  45327. +/* Internal registers bar */
  45328. +/******************************************************************************/
  45329. + bar = PEX_INTER_REGS_BAR;
  45330. +
  45331. + /* we only open the bar , no need to open windows for this bar */
  45332. +
  45333. + /* first get the CS attribute from the CPU Interface */
  45334. + if (MV_OK !=mvCpuIfTargetWinGet(INTER_REGS,&addrDecWin))
  45335. + {
  45336. + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",INTER_REGS);
  45337. + return MV_ERROR;
  45338. + }
  45339. +
  45340. + pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  45341. + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  45342. + pexBar.addrWin.size = addrDecWin.addrWin.size;
  45343. + pexBar.enable = MV_TRUE;
  45344. +
  45345. + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
  45346. + {
  45347. + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
  45348. + return MV_ERROR;
  45349. + }
  45350. +
  45351. +/******************************************************************************/
  45352. +/* DRAM bar */
  45353. +/******************************************************************************/
  45354. +
  45355. + bar = PEX_DRAM_BAR;
  45356. +
  45357. + pexBar.addrWin.size = 0;
  45358. +
  45359. + for (target = SDRAM_CS0;target < MV_DRAM_MAX_CS; target++ )
  45360. + {
  45361. +
  45362. + status = mvCpuIfTargetWinGet(target,&addrDecWin);
  45363. +
  45364. + if((MV_NO_SUCH == status)&&(target != SDRAM_CS0))
  45365. + {
  45366. + continue;
  45367. + }
  45368. +
  45369. + /* first get attributes from CPU If */
  45370. + if (MV_OK != status)
  45371. + {
  45372. + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
  45373. + return MV_ERROR;
  45374. + }
  45375. + if (addrDecWin.enable == MV_TRUE)
  45376. + {
  45377. + /* the base is the base of DRAM CS0 always */
  45378. + if (SDRAM_CS0 == target )
  45379. + {
  45380. + pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  45381. + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  45382. +
  45383. + }
  45384. +
  45385. + /* increment the bar size to be the sum of the size of all
  45386. + DRAM chips selecs */
  45387. + pexBar.addrWin.size += addrDecWin.addrWin.size;
  45388. +
  45389. + /* set a Pex window for this target !
  45390. + DRAM CS always will have a Pex Window , and is not a
  45391. + part of the priority table */
  45392. + pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  45393. + pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  45394. + pexWin.addrWin.size = addrDecWin.addrWin.size;
  45395. +
  45396. + /* we disable the windows at first because we are not
  45397. + sure that it is witihin bar boundries */
  45398. + pexWin.enable =MV_FALSE;
  45399. + pexWin.target = target;
  45400. + pexWin.targetBar = bar;
  45401. +
  45402. + if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,&pexWin))
  45403. + {
  45404. + mvOsPrintf("mvPexInit: ERR. mvPexTargetWinSet failed\n");
  45405. + return MV_ERROR;
  45406. + }
  45407. + }
  45408. + }
  45409. +
  45410. + /* check if the size of the bar is illeggal */
  45411. + if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
  45412. + {
  45413. + /* try to get a good size */
  45414. + pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
  45415. + PXBCR_BAR_SIZE_ALIGNMENT);
  45416. + }
  45417. +
  45418. + /* check if the size and base are valid */
  45419. + if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
  45420. + {
  45421. + mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
  45422. + mvOsPrintf("it will be disabled\n");
  45423. + mvOsPrintf("please check Pex and CPU windows configuration\n");
  45424. + }
  45425. + else
  45426. + {
  45427. + pexBar.enable = MV_TRUE;
  45428. +
  45429. + /* configure the bar */
  45430. + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
  45431. + {
  45432. + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
  45433. + return MV_ERROR;
  45434. + }
  45435. +
  45436. + /* after the bar was configured then we enable the Pex windows*/
  45437. + for (winNum = 0;winNum < pexCurrWin ;winNum++)
  45438. + {
  45439. + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
  45440. + {
  45441. + mvOsPrintf("mvPexInit: Can't enable window =%d\n",winNum);
  45442. + return MV_ERROR;
  45443. + }
  45444. +
  45445. + }
  45446. + }
  45447. +
  45448. +/******************************************************************************/
  45449. +/* DEVICE bar */
  45450. +/******************************************************************************/
  45451. +
  45452. +/* Open the Device BAR for non linux only */
  45453. +#ifndef MV_DISABLE_PEX_DEVICE_BAR
  45454. +
  45455. + /* then device bar*/
  45456. + bar = PEX_DEVICE_BAR;
  45457. +
  45458. + /* save the starting window */
  45459. + pexStartWindow = pexCurrWin;
  45460. + pexBar.addrWin.size = 0;
  45461. + pexBar.addrWin.baseLow = 0xffffffff;
  45462. + pexBar.addrWin.baseHigh = 0;
  45463. + maxBase = 0;
  45464. +
  45465. + for (target = DEV_TO_TARGET(START_DEV_CS);target < DEV_TO_TARGET(MV_DEV_MAX_CS); target++ )
  45466. + {
  45467. + status = mvCpuIfTargetWinGet(target,&addrDecWin);
  45468. +
  45469. + if (MV_NO_SUCH == status)
  45470. + {
  45471. + continue;
  45472. + }
  45473. +
  45474. + if (MV_OK != status)
  45475. + {
  45476. + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
  45477. + return MV_ERROR;
  45478. + }
  45479. +
  45480. + if (addrDecWin.enable == MV_TRUE)
  45481. + {
  45482. + /* get the minimum base */
  45483. + if (addrDecWin.addrWin.baseLow < pexBar.addrWin.baseLow)
  45484. + {
  45485. + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  45486. + }
  45487. +
  45488. + /* get the maximum base */
  45489. + if (addrDecWin.addrWin.baseLow > maxBase)
  45490. + {
  45491. + maxBase = addrDecWin.addrWin.baseLow;
  45492. + sizeOfMaxBase = addrDecWin.addrWin.size;
  45493. + }
  45494. +
  45495. + /* search in the priority table for this target */
  45496. + for (winIndex = 0; pexDevBarPrioTable[winIndex] != TBL_TERM;
  45497. + winIndex++)
  45498. + {
  45499. + if (pexDevBarPrioTable[winIndex] != target)
  45500. + {
  45501. + continue;
  45502. + }
  45503. + else if (pexDevBarPrioTable[winIndex] == target)
  45504. + {
  45505. + /*found it */
  45506. +
  45507. + /* if the index of this target in the prio table is valid
  45508. + then we set the Pex window for this target, a valid index is
  45509. + an index that is lower than the number of the windows that
  45510. + was not configured yet */
  45511. +
  45512. + /* we subtract 2 always because the default and expantion
  45513. + rom windows are always configured */
  45514. + if ( pexCurrWin < PEX_MAX_TARGET_WIN - 2)
  45515. + {
  45516. + /* set a Pex window for this target ! */
  45517. + pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  45518. + pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  45519. + pexWin.addrWin.size = addrDecWin.addrWin.size;
  45520. +
  45521. + /* we disable the windows at first because we are not
  45522. + sure that it is witihin bar boundries */
  45523. + pexWin.enable = MV_FALSE;
  45524. + pexWin.target = target;
  45525. + pexWin.targetBar = bar;
  45526. +
  45527. + if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,
  45528. + &pexWin))
  45529. + {
  45530. + mvOsPrintf("mvPexInit: ERR. Window Set failed\n");
  45531. + return MV_ERROR;
  45532. + }
  45533. + }
  45534. + }
  45535. + }
  45536. + }
  45537. + }
  45538. +
  45539. + pexBar.addrWin.size = maxBase - pexBar.addrWin.baseLow + sizeOfMaxBase;
  45540. + pexBar.enable = MV_TRUE;
  45541. +
  45542. + /* check if the size of the bar is illegal */
  45543. + if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
  45544. + {
  45545. + /* try to get a good size */
  45546. + pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
  45547. + PXBCR_BAR_SIZE_ALIGNMENT);
  45548. + }
  45549. +
  45550. + /* check if the size and base are valid */
  45551. + if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
  45552. + {
  45553. + mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
  45554. + mvOsPrintf("it will be disabled\n");
  45555. + mvOsPrintf("please check Pex and CPU windows configuration\n");
  45556. + }
  45557. + else
  45558. + {
  45559. + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
  45560. + {
  45561. + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
  45562. + return MV_ERROR;
  45563. + }
  45564. +
  45565. + /* now enable the windows */
  45566. + for (winNum = pexStartWindow; winNum < pexCurrWin ; winNum++)
  45567. + {
  45568. + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
  45569. + {
  45570. + mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
  45571. + winNum);
  45572. + return MV_ERROR;
  45573. + }
  45574. + }
  45575. + }
  45576. +
  45577. +#endif
  45578. +
  45579. + return mvPexHalInit(pexIf, pexType);
  45580. +
  45581. +}
  45582. +
  45583. +/*******************************************************************************
  45584. +* mvPexTargetWinSet - Set PEX to peripheral target address window BAR
  45585. +*
  45586. +* DESCRIPTION:
  45587. +*
  45588. +* INPUT:
  45589. +*
  45590. +* OUTPUT:
  45591. +* N/A
  45592. +*
  45593. +* RETURN:
  45594. +* MV_OK if PEX BAR target window was set correctly,
  45595. +* MV_BAD_PARAM on bad params
  45596. +* MV_ERROR otherwise
  45597. +* (e.g. address window overlapps with other active PEX target window).
  45598. +*
  45599. +*******************************************************************************/
  45600. +MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum,
  45601. + MV_PEX_DEC_WIN *pAddrDecWin)
  45602. +{
  45603. +
  45604. + MV_DEC_REGS decRegs;
  45605. + PEX_WIN_REG_INFO winRegInfo;
  45606. + MV_TARGET_ATTRIB targetAttribs;
  45607. +
  45608. + /* Parameter checking */
  45609. + if(pexIf >= mvCtrlPexMaxIfGet())
  45610. + {
  45611. + mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX interface %d\n", pexIf);
  45612. + return MV_BAD_PARAM;
  45613. + }
  45614. +
  45615. + if (winNum >= PEX_MAX_TARGET_WIN)
  45616. + {
  45617. + mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX winNum %d\n", winNum);
  45618. + return MV_BAD_PARAM;
  45619. +
  45620. + }
  45621. +
  45622. + /* get the pex Window registers offsets */
  45623. + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
  45624. +
  45625. +
  45626. + if (MV_TRUE == pAddrDecWin->enable)
  45627. + {
  45628. +
  45629. + /* 2) Check if the requested window overlaps with current windows */
  45630. + if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &pAddrDecWin->addrWin))
  45631. + {
  45632. + mvOsPrintf("mvPexTargetWinSet: ERR. Target %d overlap\n", winNum);
  45633. + return MV_BAD_PARAM;
  45634. + }
  45635. +
  45636. + /* 2) Check if the requested window overlaps with current windows */
  45637. + if (MV_FALSE == pexIsWinWithinBar(pexIf,&pAddrDecWin->addrWin))
  45638. + {
  45639. + mvOsPrintf("mvPexTargetWinSet: Win %d should be in bar boundries\n",
  45640. + winNum);
  45641. + return MV_BAD_PARAM;
  45642. + }
  45643. +
  45644. + }
  45645. +
  45646. +
  45647. +
  45648. + /* read base register*/
  45649. +
  45650. + if (winRegInfo.baseLowRegOffs)
  45651. + {
  45652. + decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
  45653. + }
  45654. + else
  45655. + {
  45656. + decRegs.baseReg = 0;
  45657. + }
  45658. +
  45659. + if (winRegInfo.sizeRegOffs)
  45660. + {
  45661. + decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
  45662. + }
  45663. + else
  45664. + {
  45665. + decRegs.sizeReg =0;
  45666. + }
  45667. +
  45668. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  45669. + {
  45670. + mvOsPrintf("mvPexTargetWinSet:mvCtrlAddrDecToReg Failed\n");
  45671. + return MV_ERROR;
  45672. + }
  45673. +
  45674. + /* enable\Disable */
  45675. + if (MV_TRUE == pAddrDecWin->enable)
  45676. + {
  45677. + decRegs.sizeReg |= PXWCR_WIN_EN;
  45678. + }
  45679. + else
  45680. + {
  45681. + decRegs.sizeReg &= ~PXWCR_WIN_EN;
  45682. + }
  45683. +
  45684. +
  45685. + /* clear bit location */
  45686. + decRegs.sizeReg &= ~PXWCR_WIN_BAR_MAP_MASK;
  45687. +
  45688. + /* set bar Mapping */
  45689. + if (pAddrDecWin->targetBar == 1)
  45690. + {
  45691. + decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR1;
  45692. + }
  45693. + else if (pAddrDecWin->targetBar == 2)
  45694. + {
  45695. + decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR2;
  45696. + }
  45697. +
  45698. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  45699. +
  45700. + /* set attributes */
  45701. + decRegs.sizeReg &= ~PXWCR_ATTRIB_MASK;
  45702. + decRegs.sizeReg |= targetAttribs.attrib << PXWCR_ATTRIB_OFFS;
  45703. + /* set target ID */
  45704. + decRegs.sizeReg &= ~PXWCR_TARGET_MASK;
  45705. + decRegs.sizeReg |= targetAttribs.targetId << PXWCR_TARGET_OFFS;
  45706. +
  45707. +
  45708. + /* 3) Write to address decode Base Address Register */
  45709. +
  45710. + if (winRegInfo.baseLowRegOffs)
  45711. + {
  45712. + MV_REG_WRITE(winRegInfo.baseLowRegOffs, decRegs.baseReg);
  45713. + }
  45714. +
  45715. + /* write size reg */
  45716. + if (winRegInfo.sizeRegOffs)
  45717. + {
  45718. + if ((MV_PEX_WIN_DEFAULT == winNum)||
  45719. + (MV_PEX_WIN_EXP_ROM == winNum))
  45720. + {
  45721. + /* clear size because there is no size field*/
  45722. + decRegs.sizeReg &= ~PXWCR_SIZE_MASK;
  45723. +
  45724. + /* clear enable because there is no enable field*/
  45725. + decRegs.sizeReg &= ~PXWCR_WIN_EN;
  45726. +
  45727. + }
  45728. +
  45729. + MV_REG_WRITE(winRegInfo.sizeRegOffs, decRegs.sizeReg);
  45730. + }
  45731. +
  45732. +
  45733. + return MV_OK;
  45734. +
  45735. +}
  45736. +
  45737. +/*******************************************************************************
  45738. +* mvPexTargetWinGet - Get PEX to peripheral target address window
  45739. +*
  45740. +* DESCRIPTION:
  45741. +* Get the PEX to peripheral target address window BAR.
  45742. +*
  45743. +* INPUT:
  45744. +* pexIf - PEX interface number.
  45745. +* bar - BAR to be accessed by slave.
  45746. +*
  45747. +* OUTPUT:
  45748. +* pAddrBarWin - PEX target window information data structure.
  45749. +*
  45750. +* RETURN:
  45751. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  45752. +*
  45753. +*******************************************************************************/
  45754. +MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum,
  45755. + MV_PEX_DEC_WIN *pAddrDecWin)
  45756. +{
  45757. + MV_TARGET_ATTRIB targetAttrib;
  45758. + MV_DEC_REGS decRegs;
  45759. +
  45760. + PEX_WIN_REG_INFO winRegInfo;
  45761. +
  45762. + /* Parameter checking */
  45763. + if(pexIf >= mvCtrlPexMaxIfGet())
  45764. + {
  45765. + mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX interface %d\n", pexIf);
  45766. + return MV_BAD_PARAM;
  45767. + }
  45768. +
  45769. + if (winNum >= PEX_MAX_TARGET_WIN)
  45770. + {
  45771. + mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX winNum %d\n", winNum);
  45772. + return MV_BAD_PARAM;
  45773. +
  45774. + }
  45775. +
  45776. + /* get the pex Window registers offsets */
  45777. + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
  45778. +
  45779. + /* read base register*/
  45780. + if (winRegInfo.baseLowRegOffs)
  45781. + {
  45782. + decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
  45783. + }
  45784. + else
  45785. + {
  45786. + decRegs.baseReg = 0;
  45787. + }
  45788. +
  45789. + /* read size reg */
  45790. + if (winRegInfo.sizeRegOffs)
  45791. + {
  45792. + decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
  45793. + }
  45794. + else
  45795. + {
  45796. + decRegs.sizeReg =0;
  45797. + }
  45798. +
  45799. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  45800. + {
  45801. + mvOsPrintf("mvPexTargetWinGet: mvCtrlRegToAddrDec Failed \n");
  45802. + return MV_ERROR;
  45803. +
  45804. + }
  45805. +
  45806. + if (decRegs.sizeReg & PXWCR_WIN_EN)
  45807. + {
  45808. + pAddrDecWin->enable = MV_TRUE;
  45809. + }
  45810. + else
  45811. + {
  45812. + pAddrDecWin->enable = MV_FALSE;
  45813. +
  45814. + }
  45815. +
  45816. +
  45817. + #if 0
  45818. + if (-1 == pAddrDecWin->addrWin.size)
  45819. + {
  45820. + return MV_ERROR;
  45821. + }
  45822. + #endif
  45823. +
  45824. +
  45825. + /* get target bar */
  45826. + if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) == PXWCR_WIN_BAR_MAP_BAR1 )
  45827. + {
  45828. + pAddrDecWin->targetBar = 1;
  45829. + }
  45830. + else if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) ==
  45831. + PXWCR_WIN_BAR_MAP_BAR2 )
  45832. + {
  45833. + pAddrDecWin->targetBar = 2;
  45834. + }
  45835. +
  45836. + /* attrib and targetId */
  45837. + pAddrDecWin->attrib = (decRegs.sizeReg & PXWCR_ATTRIB_MASK) >>
  45838. + PXWCR_ATTRIB_OFFS;
  45839. + pAddrDecWin->targetId = (decRegs.sizeReg & PXWCR_TARGET_MASK) >>
  45840. + PXWCR_TARGET_OFFS;
  45841. +
  45842. + targetAttrib.attrib = pAddrDecWin->attrib;
  45843. + targetAttrib.targetId = pAddrDecWin->targetId;
  45844. +
  45845. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  45846. +
  45847. + return MV_OK;
  45848. +
  45849. +}
  45850. +
  45851. +
  45852. +/*******************************************************************************
  45853. +* mvPexTargetWinEnable - Enable/disable a PEX BAR window
  45854. +*
  45855. +* DESCRIPTION:
  45856. +* This function enable/disable a PEX BAR window.
  45857. +* if parameter 'enable' == MV_TRUE the routine will enable the
  45858. +* window, thus enabling PEX accesses for that BAR (before enabling the
  45859. +* window it is tested for overlapping). Otherwise, the window will
  45860. +* be disabled.
  45861. +*
  45862. +* INPUT:
  45863. +* pexIf - PEX interface number.
  45864. +* bar - BAR to be accessed by slave.
  45865. +* enable - Enable/disable parameter.
  45866. +*
  45867. +* OUTPUT:
  45868. +* None.
  45869. +*
  45870. +* RETURN:
  45871. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  45872. +*
  45873. +*******************************************************************************/
  45874. +MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable)
  45875. +{
  45876. + PEX_WIN_REG_INFO winRegInfo;
  45877. + MV_PEX_DEC_WIN addrDecWin;
  45878. +
  45879. + /* Parameter checking */
  45880. + if(pexIf >= mvCtrlPexMaxIfGet())
  45881. + {
  45882. + mvOsPrintf("mvPexTargetWinEnable: ERR. Invalid PEX If %d\n", pexIf);
  45883. + return MV_BAD_PARAM;
  45884. + }
  45885. +
  45886. + if (winNum >= PEX_MAX_TARGET_WIN)
  45887. + {
  45888. + mvOsPrintf("mvPexTargetWinEnable ERR. Invalid PEX winNum %d\n", winNum);
  45889. + return MV_BAD_PARAM;
  45890. +
  45891. + }
  45892. +
  45893. +
  45894. + /* get the pex Window registers offsets */
  45895. + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
  45896. +
  45897. +
  45898. + /* if the address windows is disabled , we only disable the appropriare
  45899. + pex window and ignore other settings */
  45900. +
  45901. + if (MV_FALSE == enable)
  45902. + {
  45903. +
  45904. + /* this is not relevant to default and expantion rom
  45905. + windows */
  45906. + if (winRegInfo.sizeRegOffs)
  45907. + {
  45908. + if ((MV_PEX_WIN_DEFAULT != winNum)&&
  45909. + (MV_PEX_WIN_EXP_ROM != winNum))
  45910. + {
  45911. + MV_REG_BIT_RESET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
  45912. + }
  45913. + }
  45914. +
  45915. + }
  45916. + else
  45917. + {
  45918. + if (MV_OK != mvPexTargetWinGet(pexIf,winNum, &addrDecWin))
  45919. + {
  45920. + mvOsPrintf("mvPexTargetWinEnable: mvPexTargetWinGet Failed\n");
  45921. + return MV_ERROR;
  45922. + }
  45923. +
  45924. + /* Check if the requested window overlaps with current windows */
  45925. + if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &addrDecWin.addrWin))
  45926. + {
  45927. + mvOsPrintf("mvPexTargetWinEnable: ERR. Target %d overlap\n", winNum);
  45928. + return MV_BAD_PARAM;
  45929. + }
  45930. +
  45931. + if (MV_FALSE == pexIsWinWithinBar(pexIf,&addrDecWin.addrWin))
  45932. + {
  45933. + mvOsPrintf("mvPexTargetWinEnable: Win %d should be in bar boundries\n",
  45934. + winNum);
  45935. + return MV_BAD_PARAM;
  45936. + }
  45937. +
  45938. +
  45939. + /* this is not relevant to default and expantion rom
  45940. + windows */
  45941. + if (winRegInfo.sizeRegOffs)
  45942. + {
  45943. + if ((MV_PEX_WIN_DEFAULT != winNum)&&
  45944. + (MV_PEX_WIN_EXP_ROM != winNum))
  45945. + {
  45946. + MV_REG_BIT_SET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
  45947. + }
  45948. + }
  45949. +
  45950. +
  45951. + }
  45952. +
  45953. + return MV_OK;
  45954. +
  45955. +}
  45956. +
  45957. +
  45958. +
  45959. +/*******************************************************************************
  45960. +* mvPexTargetWinRemap - Set PEX to target address window remap.
  45961. +*
  45962. +* DESCRIPTION:
  45963. +* The PEX interface supports remap of the BAR original address window.
  45964. +* For each BAR it is possible to define a remap address. For example
  45965. +* an address 0x12345678 that hits BAR 0x10 (SDRAM CS[0]) will be modified
  45966. +* according to remap register but will also be targeted to the
  45967. +* SDRAM CS[0].
  45968. +*
  45969. +* INPUT:
  45970. +* pexIf - PEX interface number.
  45971. +* bar - Peripheral target enumerator accessed by slave.
  45972. +* pAddrWin - Address window to be checked.
  45973. +*
  45974. +* OUTPUT:
  45975. +* None.
  45976. +*
  45977. +* RETURN:
  45978. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  45979. +*
  45980. +*******************************************************************************/
  45981. +MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum,
  45982. + MV_PEX_REMAP_WIN *pAddrWin)
  45983. +{
  45984. +
  45985. + PEX_WIN_REG_INFO winRegInfo;
  45986. +
  45987. + /* Parameter checking */
  45988. + if (pexIf >= mvCtrlPexMaxIfGet())
  45989. + {
  45990. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
  45991. + pexIf);
  45992. + return MV_BAD_PARAM;
  45993. + }
  45994. + if (MV_PEX_WIN_DEFAULT == winNum)
  45995. + {
  45996. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
  45997. + winNum);
  45998. + return MV_BAD_PARAM;
  45999. +
  46000. + }
  46001. +
  46002. + if (MV_IS_NOT_ALIGN(pAddrWin->addrWin.baseLow, PXWRR_REMAP_ALIGNMENT))
  46003. + {
  46004. + mvOsPrintf("mvPexTargetWinRemap: Error remap PEX interface %d win %d."\
  46005. + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
  46006. + pexIf,
  46007. + winNum,
  46008. + pAddrWin->addrWin.baseLow,
  46009. + pAddrWin->addrWin.size);
  46010. +
  46011. + return MV_ERROR;
  46012. + }
  46013. +
  46014. + pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
  46015. +
  46016. + /* Set remap low register value */
  46017. + MV_REG_WRITE(winRegInfo.remapLowRegOffs, pAddrWin->addrWin.baseLow);
  46018. +
  46019. + /* Skip base high settings if the BAR has only base low (32-bit) */
  46020. + if (0 != winRegInfo.remapHighRegOffs)
  46021. + {
  46022. + MV_REG_WRITE(winRegInfo.remapHighRegOffs, pAddrWin->addrWin.baseHigh);
  46023. + }
  46024. +
  46025. +
  46026. + if (pAddrWin->enable == MV_TRUE)
  46027. + {
  46028. + MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  46029. + }
  46030. + else
  46031. + {
  46032. + MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  46033. + }
  46034. +
  46035. + return MV_OK;
  46036. +}
  46037. +
  46038. +/*******************************************************************************
  46039. +* mvPexTargetWinRemapEnable -
  46040. +*
  46041. +* DESCRIPTION:
  46042. +*
  46043. +* INPUT:
  46044. +*
  46045. +* OUTPUT:
  46046. +*
  46047. +* RETURN:
  46048. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  46049. +*
  46050. +*******************************************************************************/
  46051. +
  46052. +MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum,
  46053. + MV_BOOL enable)
  46054. +{
  46055. + PEX_WIN_REG_INFO winRegInfo;
  46056. +
  46057. + /* Parameter checking */
  46058. + if (pexIf >= mvCtrlPexMaxIfGet())
  46059. + {
  46060. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
  46061. + pexIf);
  46062. + return MV_BAD_PARAM;
  46063. + }
  46064. + if (MV_PEX_WIN_DEFAULT == winNum)
  46065. + {
  46066. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
  46067. + winNum);
  46068. + return MV_BAD_PARAM;
  46069. +
  46070. + }
  46071. +
  46072. +
  46073. + pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
  46074. +
  46075. + if (enable == MV_TRUE)
  46076. + {
  46077. + MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  46078. + }
  46079. + else
  46080. + {
  46081. + MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  46082. + }
  46083. +
  46084. + return MV_OK;
  46085. +
  46086. +}
  46087. +
  46088. +/*******************************************************************************
  46089. +* mvPexBarSet - Set PEX bar address and size
  46090. +*
  46091. +* DESCRIPTION:
  46092. +*
  46093. +* INPUT:
  46094. +*
  46095. +* OUTPUT:
  46096. +* None.
  46097. +*
  46098. +* RETURN:
  46099. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  46100. +*
  46101. +*******************************************************************************/
  46102. +MV_STATUS mvPexBarSet(MV_U32 pexIf,
  46103. + MV_U32 barNum,
  46104. + MV_PEX_BAR *pAddrWin)
  46105. +{
  46106. + MV_U32 regBaseLow;
  46107. + MV_U32 regSize,sizeToReg;
  46108. +
  46109. +
  46110. + /* check parameters */
  46111. + if(pexIf >= mvCtrlPexMaxIfGet())
  46112. + {
  46113. + mvOsPrintf("mvPexBarSet: ERR. Invalid PEX interface %d\n", pexIf);
  46114. + return MV_BAD_PARAM;
  46115. + }
  46116. +
  46117. + if(barNum >= PEX_MAX_BARS)
  46118. + {
  46119. + mvOsPrintf("mvPexBarSet: ERR. Invalid bar number %d\n", barNum);
  46120. + return MV_BAD_PARAM;
  46121. + }
  46122. +
  46123. +
  46124. + if (pAddrWin->addrWin.size == 0)
  46125. + {
  46126. + mvOsPrintf("mvPexBarSet: Size zero is Illigal\n" );
  46127. + return MV_BAD_PARAM;
  46128. + }
  46129. +
  46130. +
  46131. + /* Check if the window complies with PEX spec */
  46132. + if (MV_TRUE != pexBarIsValid(pAddrWin->addrWin.baseLow,
  46133. + pAddrWin->addrWin.size))
  46134. + {
  46135. + mvOsPrintf("mvPexBarSet: ERR. Target %d window invalid\n", barNum);
  46136. + return MV_BAD_PARAM;
  46137. + }
  46138. +
  46139. + /* 2) Check if the requested bar overlaps with current bars */
  46140. + if (MV_TRUE == pexBarOverlapDetect(pexIf,barNum, &pAddrWin->addrWin))
  46141. + {
  46142. + mvOsPrintf("mvPexBarSet: ERR. Target %d overlap\n", barNum);
  46143. + return MV_BAD_PARAM;
  46144. + }
  46145. +
  46146. + /* Get size register value according to window size */
  46147. + sizeToReg = ctrlSizeToReg(pAddrWin->addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT);
  46148. +
  46149. + /* Read bar size */
  46150. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
  46151. + {
  46152. + regSize = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
  46153. +
  46154. + /* Size parameter validity check. */
  46155. + if (-1 == sizeToReg)
  46156. + {
  46157. + mvOsPrintf("mvPexBarSet: ERR. Target BAR %d size invalid.\n",barNum);
  46158. + return MV_BAD_PARAM;
  46159. + }
  46160. +
  46161. + regSize &= ~PXBCR_BAR_SIZE_MASK;
  46162. + regSize |= (sizeToReg << PXBCR_BAR_SIZE_OFFS) ;
  46163. +
  46164. + MV_REG_WRITE(PEX_BAR_CTRL_REG(pexIf,barNum),regSize);
  46165. +
  46166. + }
  46167. +
  46168. + /* set size */
  46169. +
  46170. +
  46171. +
  46172. + /* Read base address low */
  46173. + regBaseLow = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
  46174. + PEX_MV_BAR_BASE(barNum)));
  46175. +
  46176. + /* clear current base */
  46177. + if (PEX_INTER_REGS_BAR == barNum)
  46178. + {
  46179. + regBaseLow &= ~PXBIR_BASE_MASK;
  46180. + regBaseLow |= (pAddrWin->addrWin.baseLow & PXBIR_BASE_MASK);
  46181. + }
  46182. + else
  46183. + {
  46184. + regBaseLow &= ~PXBR_BASE_MASK;
  46185. + regBaseLow |= (pAddrWin->addrWin.baseLow & PXBR_BASE_MASK);
  46186. + }
  46187. +
  46188. + /* if we had a previous value that contain the bar type (MeM\IO), we want to
  46189. + restore it */
  46190. + regBaseLow |= PEX_BAR_DEFAULT_ATTRIB;
  46191. +
  46192. +
  46193. +
  46194. + /* write base low */
  46195. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)),
  46196. + regBaseLow);
  46197. +
  46198. + if (pAddrWin->addrWin.baseHigh != 0)
  46199. + {
  46200. + /* Read base address high */
  46201. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)),
  46202. + pAddrWin->addrWin.baseHigh);
  46203. +
  46204. + }
  46205. +
  46206. + /* lastly enable the Bar */
  46207. + if (pAddrWin->enable == MV_TRUE)
  46208. + {
  46209. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers
  46210. + are enabled always */
  46211. + {
  46212. + MV_REG_BIT_SET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
  46213. + }
  46214. + }
  46215. + else if (MV_FALSE == pAddrWin->enable)
  46216. + {
  46217. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers
  46218. + are enabled always */
  46219. + {
  46220. + MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
  46221. + }
  46222. +
  46223. + }
  46224. +
  46225. +
  46226. +
  46227. + return MV_OK;
  46228. +}
  46229. +
  46230. +
  46231. +/*******************************************************************************
  46232. +* mvPexBarGet - Get PEX bar address and size
  46233. +*
  46234. +* DESCRIPTION:
  46235. +*
  46236. +* INPUT:
  46237. +*
  46238. +* OUTPUT:
  46239. +* None.
  46240. +*
  46241. +* RETURN:
  46242. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  46243. +*
  46244. +*******************************************************************************/
  46245. +
  46246. +MV_STATUS mvPexBarGet(MV_U32 pexIf,
  46247. + MV_U32 barNum,
  46248. + MV_PEX_BAR *pAddrWin)
  46249. +{
  46250. + /* check parameters */
  46251. + if(pexIf >= mvCtrlPexMaxIfGet())
  46252. + {
  46253. + mvOsPrintf("mvPexBarGet: ERR. Invalid PEX interface %d\n", pexIf);
  46254. + return MV_BAD_PARAM;
  46255. + }
  46256. +
  46257. + if(barNum >= PEX_MAX_BARS)
  46258. + {
  46259. + mvOsPrintf("mvPexBarGet: ERR. Invalid bar number %d\n", barNum);
  46260. + return MV_BAD_PARAM;
  46261. + }
  46262. +
  46263. + /* read base low */
  46264. + pAddrWin->addrWin.baseLow =
  46265. + MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)));
  46266. +
  46267. +
  46268. + if (PEX_INTER_REGS_BAR == barNum)
  46269. + {
  46270. + pAddrWin->addrWin.baseLow &= PXBIR_BASE_MASK;
  46271. + }
  46272. + else
  46273. + {
  46274. + pAddrWin->addrWin.baseLow &= PXBR_BASE_MASK;
  46275. + }
  46276. +
  46277. +
  46278. + /* read base high */
  46279. + pAddrWin->addrWin.baseHigh =
  46280. + MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)));
  46281. +
  46282. +
  46283. + /* Read bar size */
  46284. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
  46285. + {
  46286. + pAddrWin->addrWin.size = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
  46287. +
  46288. + /* check if enable or not */
  46289. + if (pAddrWin->addrWin.size & PXBCR_BAR_EN)
  46290. + {
  46291. + pAddrWin->enable = MV_TRUE;
  46292. + }
  46293. + else
  46294. + {
  46295. + pAddrWin->enable = MV_FALSE;
  46296. + }
  46297. +
  46298. + /* now get the size */
  46299. + pAddrWin->addrWin.size &= PXBCR_BAR_SIZE_MASK;
  46300. + pAddrWin->addrWin.size >>= PXBCR_BAR_SIZE_OFFS;
  46301. +
  46302. + pAddrWin->addrWin.size = ctrlRegToSize(pAddrWin->addrWin.size,
  46303. + PXBCR_BAR_SIZE_ALIGNMENT);
  46304. +
  46305. + }
  46306. + else /* PEX_INTER_REGS_BAR */
  46307. + {
  46308. + pAddrWin->addrWin.size = INTER_REGS_SIZE;
  46309. + pAddrWin->enable = MV_TRUE;
  46310. + }
  46311. +
  46312. +
  46313. + return MV_OK;
  46314. +}
  46315. +
  46316. +/*******************************************************************************
  46317. +* mvPexBarEnable -
  46318. +*
  46319. +* DESCRIPTION:
  46320. +*
  46321. +* INPUT:
  46322. +*
  46323. +* OUTPUT:
  46324. +* None.
  46325. +*
  46326. +* RETURN:
  46327. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  46328. +*
  46329. +*******************************************************************************/
  46330. +
  46331. +
  46332. +MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable)
  46333. +{
  46334. +
  46335. + MV_PEX_BAR pexBar;
  46336. +
  46337. + /* check parameters */
  46338. + if(pexIf >= mvCtrlPexMaxIfGet())
  46339. + {
  46340. + mvOsPrintf("mvPexBarEnable: ERR. Invalid PEX interface %d\n", pexIf);
  46341. + return MV_BAD_PARAM;
  46342. + }
  46343. +
  46344. +
  46345. + if(barNum >= PEX_MAX_BARS)
  46346. + {
  46347. + mvOsPrintf("mvPexBarEnable: ERR. Invalid bar number %d\n", barNum);
  46348. + return MV_BAD_PARAM;
  46349. + }
  46350. +
  46351. + if (PEX_INTER_REGS_BAR == barNum)
  46352. + {
  46353. + if (MV_TRUE == enable)
  46354. + {
  46355. + return MV_OK;
  46356. + }
  46357. + else
  46358. + {
  46359. + return MV_ERROR;
  46360. + }
  46361. + }
  46362. +
  46363. +
  46364. + if (MV_FALSE == enable)
  46365. + {
  46366. + /* disable bar and quit */
  46367. + MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
  46368. + return MV_OK;
  46369. + }
  46370. +
  46371. + /* else */
  46372. +
  46373. + if (mvPexBarGet(pexIf,barNum,&pexBar) != MV_OK)
  46374. + {
  46375. + mvOsPrintf("mvPexBarEnable: mvPexBarGet Failed\n");
  46376. + return MV_ERROR;
  46377. +
  46378. + }
  46379. +
  46380. + if (MV_TRUE == pexBar.enable)
  46381. + {
  46382. + /* it is already enabled !!! */
  46383. + return MV_OK;
  46384. + }
  46385. +
  46386. + /* else enable the bar*/
  46387. +
  46388. + pexBar.enable = MV_TRUE;
  46389. +
  46390. + if (mvPexBarSet(pexIf,barNum,&pexBar) != MV_OK)
  46391. + {
  46392. + mvOsPrintf("mvPexBarEnable: mvPexBarSet Failed\n");
  46393. + return MV_ERROR;
  46394. +
  46395. + }
  46396. +
  46397. + return MV_OK;
  46398. +}
  46399. +
  46400. +
  46401. +/*******************************************************************************
  46402. +* pexWinOverlapDetect - Detect address windows overlapping
  46403. +*
  46404. +* DESCRIPTION:
  46405. +* This function detects address window overlapping of a given address
  46406. +* window in PEX BARs.
  46407. +*
  46408. +* INPUT:
  46409. +* pAddrWin - Address window to be checked.
  46410. +* bar - BAR to be accessed by slave.
  46411. +*
  46412. +* OUTPUT:
  46413. +* None.
  46414. +*
  46415. +* RETURN:
  46416. +* MV_TRUE if the given address window overlap current address
  46417. +* decode map, MV_FALSE otherwise.
  46418. +*
  46419. +*******************************************************************************/
  46420. +static MV_BOOL pexWinOverlapDetect(MV_U32 pexIf,
  46421. + MV_U32 winNum,
  46422. + MV_ADDR_WIN *pAddrWin)
  46423. +{
  46424. + MV_U32 win;
  46425. + MV_PEX_DEC_WIN addrDecWin;
  46426. +
  46427. +
  46428. + for(win = 0; win < PEX_MAX_TARGET_WIN -2 ; win++)
  46429. + {
  46430. + /* don't check our target or illegal targets */
  46431. + if (winNum == win)
  46432. + {
  46433. + continue;
  46434. + }
  46435. +
  46436. + /* Get window parameters */
  46437. + if (MV_OK != mvPexTargetWinGet(pexIf, win, &addrDecWin))
  46438. + {
  46439. + mvOsPrintf("pexWinOverlapDetect: ERR. TargetWinGet failed win=%x\n",
  46440. + win);
  46441. + return MV_ERROR;
  46442. + }
  46443. +
  46444. + /* Do not check disabled windows */
  46445. + if (MV_FALSE == addrDecWin.enable)
  46446. + {
  46447. + continue;
  46448. + }
  46449. +
  46450. +
  46451. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  46452. + {
  46453. + mvOsPrintf("pexWinOverlapDetect: winNum %d overlap current %d\n",
  46454. + winNum, win);
  46455. + return MV_TRUE;
  46456. + }
  46457. + }
  46458. +
  46459. + return MV_FALSE;
  46460. +}
  46461. +
  46462. +/*******************************************************************************
  46463. +* pexIsWinWithinBar - Detect if address is within PEX bar boundries
  46464. +*
  46465. +* DESCRIPTION:
  46466. +*
  46467. +* INPUT:
  46468. +*
  46469. +* OUTPUT:
  46470. +* None.
  46471. +*
  46472. +* RETURN:
  46473. +* MV_TRUE if the given address window overlap current address
  46474. +* decode map, MV_FALSE otherwise.
  46475. +*
  46476. +*******************************************************************************/
  46477. +static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,
  46478. + MV_ADDR_WIN *pAddrWin)
  46479. +{
  46480. + MV_U32 bar;
  46481. + MV_PEX_BAR addrDecWin;
  46482. +
  46483. + for(bar = 0; bar < PEX_MAX_BARS; bar++)
  46484. + {
  46485. +
  46486. + /* Get window parameters */
  46487. + if (MV_OK != mvPexBarGet(pexIf, bar, &addrDecWin))
  46488. + {
  46489. + mvOsPrintf("pexIsWinWithinBar: ERR. mvPexBarGet failed\n");
  46490. + return MV_ERROR;
  46491. + }
  46492. +
  46493. + /* Do not check disabled bars */
  46494. + if (MV_FALSE == addrDecWin.enable)
  46495. + {
  46496. + continue;
  46497. + }
  46498. +
  46499. +
  46500. + if(MV_TRUE == ctrlWinWithinWinTest(pAddrWin, &addrDecWin.addrWin))
  46501. + {
  46502. + return MV_TRUE;
  46503. + }
  46504. + }
  46505. +
  46506. + return MV_FALSE;
  46507. +
  46508. +}
  46509. +
  46510. +/*******************************************************************************
  46511. +* pexBarOverlapDetect - Detect address windows overlapping
  46512. +*
  46513. +* DESCRIPTION:
  46514. +* This function detects address window overlapping of a given address
  46515. +* window in PEX BARs.
  46516. +*
  46517. +* INPUT:
  46518. +* pAddrWin - Address window to be checked.
  46519. +* bar - BAR to be accessed by slave.
  46520. +*
  46521. +* OUTPUT:
  46522. +* None.
  46523. +*
  46524. +* RETURN:
  46525. +* MV_TRUE if the given address window overlap current address
  46526. +* decode map, MV_FALSE otherwise.
  46527. +*
  46528. +*******************************************************************************/
  46529. +static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,
  46530. + MV_U32 barNum,
  46531. + MV_ADDR_WIN *pAddrWin)
  46532. +{
  46533. + MV_U32 bar;
  46534. + MV_PEX_BAR barDecWin;
  46535. +
  46536. +
  46537. + for(bar = 0; bar < PEX_MAX_BARS; bar++)
  46538. + {
  46539. + /* don't check our target or illegal targets */
  46540. + if (barNum == bar)
  46541. + {
  46542. + continue;
  46543. + }
  46544. +
  46545. + /* Get window parameters */
  46546. + if (MV_OK != mvPexBarGet(pexIf, bar, &barDecWin))
  46547. + {
  46548. + mvOsPrintf("pexBarOverlapDetect: ERR. TargetWinGet failed\n");
  46549. + return MV_ERROR;
  46550. + }
  46551. +
  46552. + /* don'nt check disabled bars */
  46553. + if (barDecWin.enable == MV_FALSE)
  46554. + {
  46555. + continue;
  46556. + }
  46557. +
  46558. +
  46559. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &barDecWin.addrWin))
  46560. + {
  46561. + mvOsPrintf("pexBarOverlapDetect: winNum %d overlap current %d\n",
  46562. + barNum, bar);
  46563. + return MV_TRUE;
  46564. + }
  46565. + }
  46566. +
  46567. + return MV_FALSE;
  46568. +}
  46569. +
  46570. +/*******************************************************************************
  46571. +* pexBarIsValid - Check if the given address window is valid
  46572. +*
  46573. +* DESCRIPTION:
  46574. +* PEX spec restrict BAR base to be aligned to BAR size.
  46575. +* This function checks if the given address window is valid.
  46576. +*
  46577. +* INPUT:
  46578. +* baseLow - 32bit low base address.
  46579. +* size - Window size.
  46580. +*
  46581. +* OUTPUT:
  46582. +* None.
  46583. +*
  46584. +* RETURN:
  46585. +* MV_TRUE if the address window is valid, MV_FALSE otherwise.
  46586. +*
  46587. +*******************************************************************************/
  46588. +static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size)
  46589. +{
  46590. +
  46591. + /* PCI spec restrict BAR base to be aligned to BAR size */
  46592. + if(MV_IS_NOT_ALIGN(baseLow, size))
  46593. + {
  46594. + return MV_ERROR;
  46595. + }
  46596. + else
  46597. + {
  46598. + return MV_TRUE;
  46599. + }
  46600. +
  46601. + return MV_TRUE;
  46602. +}
  46603. +
  46604. +/*******************************************************************************
  46605. +* pexBarRegInfoGet - Get BAR register information
  46606. +*
  46607. +* DESCRIPTION:
  46608. +* PEX BARs registers offsets are inconsecutive.
  46609. +* This function gets a PEX BAR register information like register offsets
  46610. +* and function location of the BAR.
  46611. +*
  46612. +* INPUT:
  46613. +* pexIf - PEX interface number.
  46614. +* bar - The PEX BAR in question.
  46615. +*
  46616. +* OUTPUT:
  46617. +* pBarRegInfo - BAR register info struct.
  46618. +*
  46619. +* RETURN:
  46620. +* MV_BAD_PARAM when bad parameters ,MV_ERROR on error ,othewise MV_OK
  46621. +*
  46622. +*******************************************************************************/
  46623. +static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf,
  46624. + MV_U32 winNum,
  46625. + PEX_WIN_REG_INFO *pWinRegInfo)
  46626. +{
  46627. +
  46628. + if ((winNum >= 0)&&(winNum <=3))
  46629. + {
  46630. + pWinRegInfo->baseLowRegOffs = PEX_WIN0_3_BASE_REG(pexIf,winNum);
  46631. + pWinRegInfo->baseHighRegOffs = 0;
  46632. + pWinRegInfo->sizeRegOffs = PEX_WIN0_3_CTRL_REG(pexIf,winNum);
  46633. + pWinRegInfo->remapLowRegOffs = PEX_WIN0_3_REMAP_REG(pexIf,winNum);
  46634. + pWinRegInfo->remapHighRegOffs = 0;
  46635. + }
  46636. + else if ((winNum >= 4)&&(winNum <=5))
  46637. + {
  46638. + pWinRegInfo->baseLowRegOffs = PEX_WIN4_5_BASE_REG(pexIf,winNum);
  46639. + pWinRegInfo->baseHighRegOffs = 0;
  46640. + pWinRegInfo->sizeRegOffs = PEX_WIN4_5_CTRL_REG(pexIf,winNum);
  46641. + pWinRegInfo->remapLowRegOffs = PEX_WIN4_5_REMAP_REG(pexIf,winNum);
  46642. + pWinRegInfo->remapHighRegOffs = PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum);
  46643. +
  46644. + }
  46645. + else if (MV_PEX_WIN_DEFAULT == winNum)
  46646. + {
  46647. + pWinRegInfo->baseLowRegOffs = 0;
  46648. + pWinRegInfo->baseHighRegOffs = 0;
  46649. + pWinRegInfo->sizeRegOffs = PEX_WIN_DEFAULT_CTRL_REG(pexIf);
  46650. + pWinRegInfo->remapLowRegOffs = 0;
  46651. + pWinRegInfo->remapHighRegOffs = 0;
  46652. + }
  46653. + else if (MV_PEX_WIN_EXP_ROM == winNum)
  46654. + {
  46655. + pWinRegInfo->baseLowRegOffs = 0;
  46656. + pWinRegInfo->baseHighRegOffs = 0;
  46657. + pWinRegInfo->sizeRegOffs = PEX_WIN_EXP_ROM_CTRL_REG(pexIf);
  46658. + pWinRegInfo->remapLowRegOffs = PEX_WIN_EXP_ROM_REMAP_REG(pexIf);
  46659. + pWinRegInfo->remapHighRegOffs = 0;
  46660. +
  46661. + }
  46662. +
  46663. + return MV_OK;
  46664. +}
  46665. +
  46666. +/*******************************************************************************
  46667. +* pexBarNameGet - Get the string name of PEX BAR.
  46668. +*
  46669. +* DESCRIPTION:
  46670. +* This function get the string name of PEX BAR.
  46671. +*
  46672. +* INPUT:
  46673. +* bar - PEX bar number.
  46674. +*
  46675. +* OUTPUT:
  46676. +* None.
  46677. +*
  46678. +* RETURN:
  46679. +* pointer to the string name of PEX BAR.
  46680. +*
  46681. +*******************************************************************************/
  46682. +const MV_8* pexBarNameGet( MV_U32 bar )
  46683. +{
  46684. + switch( bar )
  46685. + {
  46686. + case PEX_INTER_REGS_BAR:
  46687. + return "Internal Regs Bar0....";
  46688. + case PEX_DRAM_BAR:
  46689. + return "DRAM Bar1.............";
  46690. + case PEX_DEVICE_BAR:
  46691. + return "Devices Bar2..........";
  46692. + default:
  46693. + return "Bar unknown";
  46694. + }
  46695. +}
  46696. +/*******************************************************************************
  46697. +* mvPexAddrDecShow - Print the PEX address decode map (BARs and windows).
  46698. +*
  46699. +* DESCRIPTION:
  46700. +* This function print the PEX address decode map (BARs and windows).
  46701. +*
  46702. +* INPUT:
  46703. +* None.
  46704. +*
  46705. +* OUTPUT:
  46706. +* None.
  46707. +*
  46708. +* RETURN:
  46709. +* None.
  46710. +*
  46711. +*******************************************************************************/
  46712. +MV_VOID mvPexAddrDecShow(MV_VOID)
  46713. +{
  46714. + MV_PEX_BAR pexBar;
  46715. + MV_PEX_DEC_WIN win;
  46716. + MV_U32 pexIf;
  46717. + MV_U32 bar,winNum;
  46718. +
  46719. + for( pexIf = 0; pexIf < mvCtrlPexMaxIfGet(); pexIf++ )
  46720. + {
  46721. + if (MV_FALSE == mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf)) continue;
  46722. + mvOsOutput( "\n" );
  46723. + mvOsOutput( "PEX%d:\n", pexIf );
  46724. + mvOsOutput( "-----\n" );
  46725. +
  46726. + mvOsOutput( "\nPex Bars \n\n");
  46727. +
  46728. + for( bar = 0; bar < PEX_MAX_BARS; bar++ )
  46729. + {
  46730. + memset( &pexBar, 0, sizeof(MV_PEX_BAR) );
  46731. +
  46732. + mvOsOutput( "%s ", pexBarNameGet(bar) );
  46733. +
  46734. + if( mvPexBarGet( pexIf, bar, &pexBar ) == MV_OK )
  46735. + {
  46736. + if( pexBar.enable )
  46737. + {
  46738. + mvOsOutput( "base %08x, ", pexBar.addrWin.baseLow );
  46739. + mvSizePrint( pexBar.addrWin.size );
  46740. + mvOsOutput( "\n" );
  46741. + }
  46742. + else
  46743. + mvOsOutput( "disable\n" );
  46744. + }
  46745. + }
  46746. + mvOsOutput( "\nPex Decode Windows\n\n");
  46747. +
  46748. + for( winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
  46749. + {
  46750. + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
  46751. +
  46752. + mvOsOutput( "win%d - ", winNum );
  46753. +
  46754. + if ( mvPexTargetWinGet(pexIf,winNum,&win) == MV_OK)
  46755. + {
  46756. + if (win.enable)
  46757. + {
  46758. + mvOsOutput( "%s base %08x, ",
  46759. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  46760. + mvOsOutput( "...." );
  46761. + mvSizePrint( win.addrWin.size );
  46762. +
  46763. + mvOsOutput( "\n" );
  46764. + }
  46765. + else
  46766. + mvOsOutput( "disable\n" );
  46767. +
  46768. +
  46769. + }
  46770. + }
  46771. +
  46772. + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
  46773. +
  46774. + mvOsOutput( "default win - " );
  46775. +
  46776. + if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_DEFAULT, &win) == MV_OK)
  46777. + {
  46778. + mvOsOutput( "%s ",
  46779. + mvCtrlTargetNameGet(win.target) );
  46780. + mvOsOutput( "\n" );
  46781. + }
  46782. + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
  46783. +
  46784. + mvOsOutput( "Expansion ROM - " );
  46785. +
  46786. + if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_EXP_ROM, &win) == MV_OK)
  46787. + {
  46788. + mvOsOutput( "%s ",
  46789. + mvCtrlTargetNameGet(win.target) );
  46790. + mvOsOutput( "\n" );
  46791. + }
  46792. +
  46793. + }
  46794. +}
  46795. +
  46796. +
  46797. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h
  46798. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h 1970-01-01 01:00:00.000000000 +0100
  46799. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h 2011-07-31 11:31:57.943425007 +0200
  46800. @@ -0,0 +1,348 @@
  46801. +/*******************************************************************************
  46802. +Copyright (C) Marvell International Ltd. and its affiliates
  46803. +
  46804. +This software file (the "File") is owned and distributed by Marvell
  46805. +International Ltd. and/or its affiliates ("Marvell") under the following
  46806. +alternative licensing terms. Once you have made an election to distribute the
  46807. +File under one of the following license alternatives, please (i) delete this
  46808. +introductory statement regarding license alternatives, (ii) delete the two
  46809. +license alternatives that you have not elected to use and (iii) preserve the
  46810. +Marvell copyright notice above.
  46811. +
  46812. +********************************************************************************
  46813. +Marvell Commercial License Option
  46814. +
  46815. +If you received this File from Marvell and you have entered into a commercial
  46816. +license agreement (a "Commercial License") with Marvell, the File is licensed
  46817. +to you under the terms of the applicable Commercial License.
  46818. +
  46819. +********************************************************************************
  46820. +Marvell GPL License Option
  46821. +
  46822. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46823. +modify this File in accordance with the terms and conditions of the General
  46824. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  46825. +available along with the File in the license.txt file or by writing to the Free
  46826. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  46827. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  46828. +
  46829. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  46830. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  46831. +DISCLAIMED. The GPL License provides additional details about this warranty
  46832. +disclaimer.
  46833. +********************************************************************************
  46834. +Marvell BSD License Option
  46835. +
  46836. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46837. +modify this File under the following licensing terms.
  46838. +Redistribution and use in source and binary forms, with or without modification,
  46839. +are permitted provided that the following conditions are met:
  46840. +
  46841. + * Redistributions of source code must retain the above copyright notice,
  46842. + this list of conditions and the following disclaimer.
  46843. +
  46844. + * Redistributions in binary form must reproduce the above copyright
  46845. + notice, this list of conditions and the following disclaimer in the
  46846. + documentation and/or other materials provided with the distribution.
  46847. +
  46848. + * Neither the name of Marvell nor the names of its contributors may be
  46849. + used to endorse or promote products derived from this software without
  46850. + specific prior written permission.
  46851. +
  46852. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  46853. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  46854. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  46855. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  46856. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  46857. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46858. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  46859. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  46860. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  46861. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  46862. +
  46863. +*******************************************************************************/
  46864. +
  46865. +#ifndef __INCSysPEXH
  46866. +#define __INCSysPEXH
  46867. +
  46868. +#include "mvCommon.h"
  46869. +#include "ctrlEnv/sys/mvCpuIf.h"
  46870. +#include "ctrlEnv/mvCtrlEnvLib.h"
  46871. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  46872. +
  46873. +/* 4KB granularity */
  46874. +#define MINIMUM_WINDOW_SIZE 0x1000
  46875. +#define MINIMUM_BAR_SIZE 0x1000
  46876. +#define MINIMUM_BAR_SIZE_MASK 0xFFFFF000
  46877. +#define BAR_SIZE_OFFS 12
  46878. +#define BAR_SIZE_MASK (0xFFFFF << BAR_SIZE_OFFS)
  46879. +
  46880. +
  46881. +
  46882. +#define MV_PEX_WIN_DEFAULT 6
  46883. +#define MV_PEX_WIN_EXP_ROM 7
  46884. +#define PEX_MAX_TARGET_WIN 8
  46885. +
  46886. +
  46887. +#define PEX_MAX_BARS 3
  46888. +#define PEX_INTER_REGS_BAR 0
  46889. +#define PEX_DRAM_BAR 1
  46890. +#define PEX_DEVICE_BAR 2
  46891. +
  46892. +/*************************************/
  46893. +/* PCI Express BAR Control Registers */
  46894. +/*************************************/
  46895. +#define PEX_BAR_CTRL_REG(pexIf,bar) (0x41804 + (bar-1)*4- (pexIf)*0x10000)
  46896. +#define PEX_EXP_ROM_BAR_CTRL_REG(pexIf) (0x4180C - (pexIf)*0x10000)
  46897. +
  46898. +
  46899. +/* PCI Express BAR Control Register */
  46900. +/* PEX_BAR_CTRL_REG (PXBCR) */
  46901. +
  46902. +#define PXBCR_BAR_EN BIT0
  46903. +#define PXBCR_BAR_SIZE_OFFS 16
  46904. +#define PXBCR_BAR_SIZE_MASK (0xffff << PXBCR_BAR_SIZE_OFFS)
  46905. +#define PXBCR_BAR_SIZE_ALIGNMENT 0x10000
  46906. +
  46907. +
  46908. +
  46909. +/* PCI Express Expansion ROM BAR Control Register */
  46910. +/* PEX_EXP_ROM_BAR_CTRL_REG (PXERBCR) */
  46911. +
  46912. +#define PXERBCR_EXPROM_EN BIT0
  46913. +#define PXERBCR_EXPROMSZ_OFFS 19
  46914. +#define PXERBCR_EXPROMSZ_MASK (0xf << PXERBCR_EXPROMSZ_OFFS)
  46915. +#define PXERBCR_EXPROMSZ_512KB (0x0 << PXERBCR_EXPROMSZ_OFFS)
  46916. +#define PXERBCR_EXPROMSZ_1024KB (0x1 << PXERBCR_EXPROMSZ_OFFS)
  46917. +#define PXERBCR_EXPROMSZ_2048KB (0x3 << PXERBCR_EXPROMSZ_OFFS)
  46918. +#define PXERBCR_EXPROMSZ_4096KB (0x7 << PXERBCR_EXPROMSZ_OFFS)
  46919. +
  46920. +/************************************************/
  46921. +/* PCI Express Address Window Control Registers */
  46922. +/************************************************/
  46923. +#define PEX_WIN0_3_CTRL_REG(pexIf,winNum) \
  46924. + (0x41820 + (winNum) * 0x10 - (pexIf) * 0x10000)
  46925. +#define PEX_WIN0_3_BASE_REG(pexIf,winNum) \
  46926. + (0x41824 + (winNum) * 0x10 - (pexIf) * 0x10000)
  46927. +#define PEX_WIN0_3_REMAP_REG(pexIf,winNum) \
  46928. + (0x4182C + (winNum) * 0x10 - (pexIf) * 0x10000)
  46929. +#define PEX_WIN4_5_CTRL_REG(pexIf,winNum) \
  46930. + (0x41860 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  46931. +#define PEX_WIN4_5_BASE_REG(pexIf,winNum) \
  46932. + (0x41864 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  46933. +#define PEX_WIN4_5_REMAP_REG(pexIf,winNum) \
  46934. + (0x4186C + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  46935. +#define PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum) \
  46936. + (0x41870 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  46937. +
  46938. +#define PEX_WIN_DEFAULT_CTRL_REG(pexIf) (0x418B0 - (pexIf) * 0x10000)
  46939. +#define PEX_WIN_EXP_ROM_CTRL_REG(pexIf) (0x418C0 - (pexIf) * 0x10000)
  46940. +#define PEX_WIN_EXP_ROM_REMAP_REG(pexIf) (0x418C4 - (pexIf) * 0x10000)
  46941. +
  46942. +/* PCI Express Window Control Register */
  46943. +/* PEX_WIN_CTRL_REG (PXWCR) */
  46944. +
  46945. +#define PXWCR_WIN_EN BIT0 /* Window Enable.*/
  46946. +
  46947. +#define PXWCR_WIN_BAR_MAP_OFFS 1 /* Mapping to BAR.*/
  46948. +#define PXWCR_WIN_BAR_MAP_MASK BIT1
  46949. +#define PXWCR_WIN_BAR_MAP_BAR1 (0 << PXWCR_WIN_BAR_MAP_OFFS)
  46950. +#define PXWCR_WIN_BAR_MAP_BAR2 (1 << PXWCR_WIN_BAR_MAP_OFFS)
  46951. +
  46952. +#define PXWCR_TARGET_OFFS 4 /*Unit ID */
  46953. +#define PXWCR_TARGET_MASK (0xf << PXWCR_TARGET_OFFS)
  46954. +
  46955. +#define PXWCR_ATTRIB_OFFS 8 /* target attributes */
  46956. +#define PXWCR_ATTRIB_MASK (0xff << PXWCR_ATTRIB_OFFS)
  46957. +
  46958. +#define PXWCR_SIZE_OFFS 16 /* size */
  46959. +#define PXWCR_SIZE_MASK (0xffff << PXWCR_SIZE_OFFS)
  46960. +#define PXWCR_SIZE_ALIGNMENT 0x10000
  46961. +
  46962. +/* PCI Express Window Base Register */
  46963. +/* PEX_WIN_BASE_REG (PXWBR)*/
  46964. +
  46965. +#define PXWBR_BASE_OFFS 16 /* address[31:16] */
  46966. +#define PXWBR_BASE_MASK (0xffff << PXWBR_BASE_OFFS)
  46967. +#define PXWBR_BASE_ALIGNMENT 0x10000
  46968. +
  46969. +/* PCI Express Window Remap Register */
  46970. +/* PEX_WIN_REMAP_REG (PXWRR)*/
  46971. +
  46972. +#define PXWRR_REMAP_EN BIT0
  46973. +#define PXWRR_REMAP_OFFS 16
  46974. +#define PXWRR_REMAP_MASK (0xffff << PXWRR_REMAP_OFFS)
  46975. +#define PXWRR_REMAP_ALIGNMENT 0x10000
  46976. +
  46977. +/* PCI Express Window Remap (High) Register */
  46978. +/* PEX_WIN_REMAP_HIGH_REG (PXWRHR)*/
  46979. +
  46980. +#define PXWRHR_REMAP_HIGH_OFFS 0
  46981. +#define PXWRHR_REMAP_HIGH_MASK (0xffffffff << PXWRHR_REMAP_HIGH_OFFS)
  46982. +
  46983. +/* PCI Express Default Window Control Register */
  46984. +/* PEX_WIN_DEFAULT_CTRL_REG (PXWDCR) */
  46985. +
  46986. +#define PXWDCR_TARGET_OFFS 4 /*Unit ID */
  46987. +#define PXWDCR_TARGET_MASK (0xf << PXWDCR_TARGET_OFFS)
  46988. +#define PXWDCR_ATTRIB_OFFS 8 /* target attributes */
  46989. +#define PXWDCR_ATTRIB_MASK (0xff << PXWDCR_ATTRIB_OFFS)
  46990. +
  46991. +/* PCI Express Expansion ROM Window Control Register */
  46992. +/* PEX_WIN_EXP_ROM_CTRL_REG (PXWERCR)*/
  46993. +
  46994. +#define PXWERCR_TARGET_OFFS 4 /*Unit ID */
  46995. +#define PXWERCR_TARGET_MASK (0xf << PXWERCR_TARGET_OFFS)
  46996. +#define PXWERCR_ATTRIB_OFFS 8 /* target attributes */
  46997. +#define PXWERCR_ATTRIB_MASK (0xff << PXWERCR_ATTRIB_OFFS)
  46998. +
  46999. +/* PCI Express Expansion ROM Window Remap Register */
  47000. +/* PEX_WIN_EXP_ROM_REMAP_REG (PXWERRR)*/
  47001. +
  47002. +#define PXWERRR_REMAP_EN BIT0
  47003. +#define PXWERRR_REMAP_OFFS 16
  47004. +#define PXWERRR_REMAP_MASK (0xffff << PXWERRR_REMAP_OFFS)
  47005. +#define PXWERRR_REMAP_ALIGNMENT 0x10000
  47006. +
  47007. +
  47008. +
  47009. +/*PEX_MEMORY_BAR_BASE_ADDR(barNum) (PXMBBA)*/
  47010. +/* PCI Express BAR0 Internal Register*/
  47011. +/*PEX BAR0_INTER_REG (PXBIR)*/
  47012. +
  47013. +#define PXBIR_IOSPACE BIT0 /* Memory Space Indicator */
  47014. +
  47015. +#define PXBIR_TYPE_OFFS 1 /* BAR Type/Init Val. */
  47016. +#define PXBIR_TYPE_MASK (0x3 << PXBIR_TYPE_OFFS)
  47017. +#define PXBIR_TYPE_32BIT_ADDR (0x0 << PXBIR_TYPE_OFFS)
  47018. +#define PXBIR_TYPE_64BIT_ADDR (0x2 << PXBIR_TYPE_OFFS)
  47019. +
  47020. +#define PXBIR_PREFETCH_EN BIT3 /* Prefetch Enable */
  47021. +
  47022. +#define PXBIR_BASE_OFFS 20 /* Base address. Address bits [31:20] */
  47023. +#define PXBIR_BASE_MASK (0xfff << PXBIR_BASE_OFFS)
  47024. +#define PXBIR_BASE_ALIGNMET (1 << PXBIR_BASE_OFFS)
  47025. +
  47026. +
  47027. +/* PCI Express BAR0 Internal (High) Register*/
  47028. +/*PEX BAR0_INTER_REG_HIGH (PXBIRH)*/
  47029. +
  47030. +#define PXBIRH_BASE_OFFS 0 /* Base address. Bits [63:32] */
  47031. +#define PXBIRH_BASE_MASK (0xffffffff << PBBHR_BASE_OFFS)
  47032. +
  47033. +
  47034. +#define PEX_BAR_DEFAULT_ATTRIB 0xc /* Memory - Prefetch - 64 bit address */
  47035. +#define PEX_BAR0_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
  47036. +#define PEX_BAR1_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
  47037. +#define PEX_BAR2_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
  47038. +
  47039. +
  47040. +/* PCI Express BAR1 Register */
  47041. +/* PCI Express BAR2 Register*/
  47042. +/*PEX BAR1_REG (PXBR)*/
  47043. +/*PEX BAR2_REG (PXBR)*/
  47044. +
  47045. +#define PXBR_IOSPACE BIT0 /* Memory Space Indicator */
  47046. +
  47047. +#define PXBR_TYPE_OFFS 1 /* BAR Type/Init Val. */
  47048. +#define PXBR_TYPE_MASK (0x3 << PXBR_TYPE_OFFS)
  47049. +#define PXBR_TYPE_32BIT_ADDR (0x0 << PXBR_TYPE_OFFS)
  47050. +#define PXBR_TYPE_64BIT_ADDR (0x2 << PXBR_TYPE_OFFS)
  47051. +
  47052. +#define PXBR_PREFETCH_EN BIT3 /* Prefetch Enable */
  47053. +
  47054. +#define PXBR_BASE_OFFS 16 /* Base address. Address bits [31:16] */
  47055. +#define PXBR_BASE_MASK (0xffff << PXBR_BASE_OFFS)
  47056. +#define PXBR_BASE_ALIGNMET (1 << PXBR_BASE_OFFS)
  47057. +
  47058. +
  47059. +/* PCI Express BAR1 (High) Register*/
  47060. +/* PCI Express BAR2 (High) Register*/
  47061. +/*PEX BAR1_REG_HIGH (PXBRH)*/
  47062. +/*PEX BAR2_REG_HIGH (PXBRH)*/
  47063. +
  47064. +#define PXBRH_BASE_OFFS 0 /* Base address. Address bits [63:32] */
  47065. +#define PXBRH_BASE_MASK (0xffffffff << PXBRH_BASE_OFFS)
  47066. +
  47067. +/* PCI Express Expansion ROM BAR Register*/
  47068. +/*PEX_EXPANSION_ROM_BASE_ADDR_REG (PXERBAR)*/
  47069. +
  47070. +#define PXERBAR_EXPROMEN BIT0 /* Expansion ROM Enable */
  47071. +
  47072. +#define PXERBAR_BASE_512K_OFFS 19 /* Expansion ROM Base Address */
  47073. +#define PXERBAR_BASE_512K_MASK (0x1fff << PXERBAR_BASE_512K_OFFS)
  47074. +
  47075. +#define PXERBAR_BASE_1MB_OFFS 20 /* Expansion ROM Base Address */
  47076. +#define PXERBAR_BASE_1MB_MASK (0xfff << PXERBAR_BASE_1MB_OFFS)
  47077. +
  47078. +#define PXERBAR_BASE_2MB_OFFS 21 /* Expansion ROM Base Address */
  47079. +#define PXERBAR_BASE_2MB_MASK (0x7ff << PXERBAR_BASE_2MB_OFFS)
  47080. +
  47081. +#define PXERBAR_BASE_4MB_OFFS 22 /* Expansion ROM Base Address */
  47082. +#define PXERBAR_BASE_4MB_MASK (0x3ff << PXERBAR_BASE_4MB_OFFS)
  47083. +
  47084. +/* PEX Bar attributes */
  47085. +typedef struct _mvPexBar
  47086. +{
  47087. + MV_ADDR_WIN addrWin; /* An address window*/
  47088. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47089. +
  47090. +}MV_PEX_BAR;
  47091. +
  47092. +/* PEX Remap Window attributes */
  47093. +typedef struct _mvPexRemapWin
  47094. +{
  47095. + MV_ADDR_WIN addrWin; /* An address window*/
  47096. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47097. +
  47098. +}MV_PEX_REMAP_WIN;
  47099. +
  47100. +/* PEX Remap Window attributes */
  47101. +typedef struct _mvPexDecWin
  47102. +{
  47103. + MV_TARGET target;
  47104. + MV_ADDR_WIN addrWin; /* An address window*/
  47105. + MV_U32 targetBar;
  47106. + MV_U8 attrib; /* chip select attributes */
  47107. + MV_TARGET_ID targetId; /* Target Id of this MV_TARGET */
  47108. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47109. +
  47110. +}MV_PEX_DEC_WIN;
  47111. +
  47112. +/* Global Functions prototypes */
  47113. +/* mvPexHalInit - Initialize PEX interfaces*/
  47114. +MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType);
  47115. +
  47116. +
  47117. +/* mvPexTargetWinSet - Set PEX to peripheral target address window BAR*/
  47118. +MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum,
  47119. + MV_PEX_DEC_WIN *pAddrDecWin);
  47120. +
  47121. +/* mvPexTargetWinGet - Get PEX to peripheral target address window*/
  47122. +MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum,
  47123. + MV_PEX_DEC_WIN *pAddrDecWin);
  47124. +
  47125. +/* mvPexTargetWinEnable - Enable/disable a PEX BAR window*/
  47126. +MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable);
  47127. +
  47128. +/* mvPexTargetWinRemap - Set PEX to target address window remap.*/
  47129. +MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum,
  47130. + MV_PEX_REMAP_WIN *pAddrWin);
  47131. +
  47132. +/* mvPexTargetWinRemapEnable -enable\disable a PEX Window remap.*/
  47133. +MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum,
  47134. + MV_BOOL enable);
  47135. +
  47136. +/* mvPexBarSet - Set PEX bar address and size */
  47137. +MV_STATUS mvPexBarSet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);
  47138. +
  47139. +/* mvPexBarGet - Get PEX bar address and size */
  47140. +MV_STATUS mvPexBarGet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);
  47141. +
  47142. +/* mvPexBarEnable - enable\disable a PEX bar*/
  47143. +MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable);
  47144. +
  47145. +/* mvPexAddrDecShow - Display address decode windows attributes */
  47146. +MV_VOID mvPexAddrDecShow(MV_VOID);
  47147. +
  47148. +#endif
  47149. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c
  47150. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c 1970-01-01 01:00:00.000000000 +0100
  47151. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c 2011-07-31 11:31:57.993424994 +0200
  47152. @@ -0,0 +1,430 @@
  47153. +/*******************************************************************************
  47154. +Copyright (C) Marvell International Ltd. and its affiliates
  47155. +
  47156. +This software file (the "File") is owned and distributed by Marvell
  47157. +International Ltd. and/or its affiliates ("Marvell") under the following
  47158. +alternative licensing terms. Once you have made an election to distribute the
  47159. +File under one of the following license alternatives, please (i) delete this
  47160. +introductory statement regarding license alternatives, (ii) delete the two
  47161. +license alternatives that you have not elected to use and (iii) preserve the
  47162. +Marvell copyright notice above.
  47163. +
  47164. +********************************************************************************
  47165. +Marvell Commercial License Option
  47166. +
  47167. +If you received this File from Marvell and you have entered into a commercial
  47168. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47169. +to you under the terms of the applicable Commercial License.
  47170. +
  47171. +********************************************************************************
  47172. +Marvell GPL License Option
  47173. +
  47174. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47175. +modify this File in accordance with the terms and conditions of the General
  47176. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47177. +available along with the File in the license.txt file or by writing to the Free
  47178. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47179. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47180. +
  47181. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47182. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47183. +DISCLAIMED. The GPL License provides additional details about this warranty
  47184. +disclaimer.
  47185. +********************************************************************************
  47186. +Marvell BSD License Option
  47187. +
  47188. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47189. +modify this File under the following licensing terms.
  47190. +Redistribution and use in source and binary forms, with or without modification,
  47191. +are permitted provided that the following conditions are met:
  47192. +
  47193. + * Redistributions of source code must retain the above copyright notice,
  47194. + this list of conditions and the following disclaimer.
  47195. +
  47196. + * Redistributions in binary form must reproduce the above copyright
  47197. + notice, this list of conditions and the following disclaimer in the
  47198. + documentation and/or other materials provided with the distribution.
  47199. +
  47200. + * Neither the name of Marvell nor the names of its contributors may be
  47201. + used to endorse or promote products derived from this software without
  47202. + specific prior written permission.
  47203. +
  47204. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47205. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47206. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47207. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47208. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47209. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47210. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47211. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47212. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47213. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47214. +
  47215. +*******************************************************************************/
  47216. +
  47217. +
  47218. +#include "mvTypes.h"
  47219. +#include "mvCommon.h"
  47220. +#include "mvOs.h"
  47221. +#include "ctrlEnv/mvCtrlEnvLib.h"
  47222. +#include "cpu/mvCpu.h"
  47223. +#include "ctrlEnv/sys/mvCpuIf.h"
  47224. +#include "sata/CoreDriver/mvRegs.h"
  47225. +#include "ctrlEnv/sys/mvSysSata.h"
  47226. +
  47227. +MV_TARGET sataAddrDecPrioTab[] =
  47228. +{
  47229. +#if defined(MV_INCLUDE_SDRAM_CS0)
  47230. + SDRAM_CS0,
  47231. +#endif
  47232. +#if defined(MV_INCLUDE_SDRAM_CS1)
  47233. + SDRAM_CS1,
  47234. +#endif
  47235. +#if defined(MV_INCLUDE_SDRAM_CS2)
  47236. + SDRAM_CS2,
  47237. +#endif
  47238. +#if defined(MV_INCLUDE_SDRAM_CS3)
  47239. + SDRAM_CS3,
  47240. +#endif
  47241. +#if defined(MV_INCLUDE_PEX)
  47242. + PEX0_MEM,
  47243. +#endif
  47244. + TBL_TERM
  47245. +};
  47246. +
  47247. +
  47248. +/*******************************************************************************
  47249. +* sataWinOverlapDetect - Detect SATA address windows overlapping
  47250. +*
  47251. +* DESCRIPTION:
  47252. +* An unpredicted behaviur is expected in case SATA address decode
  47253. +* windows overlapps.
  47254. +* This function detects SATA address decode windows overlapping of a
  47255. +* specified window. The function does not check the window itself for
  47256. +* overlapping. The function also skipps disabled address decode windows.
  47257. +*
  47258. +* INPUT:
  47259. +* winNum - address decode window number.
  47260. +* pAddrDecWin - An address decode window struct.
  47261. +*
  47262. +* OUTPUT:
  47263. +* None.
  47264. +*
  47265. +* RETURN:
  47266. +* MV_TRUE if the given address window overlap current address
  47267. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  47268. +* from registers.
  47269. +*
  47270. +*******************************************************************************/
  47271. +static MV_STATUS sataWinOverlapDetect(int dev, MV_U32 winNum,
  47272. + MV_ADDR_WIN *pAddrWin)
  47273. +{
  47274. + MV_U32 winNumIndex;
  47275. + MV_SATA_DEC_WIN addrDecWin;
  47276. +
  47277. + for(winNumIndex=0; winNumIndex<MV_SATA_MAX_ADDR_DECODE_WIN; winNumIndex++)
  47278. + {
  47279. + /* Do not check window itself */
  47280. + if (winNumIndex == winNum)
  47281. + {
  47282. + continue;
  47283. + }
  47284. +
  47285. + /* Get window parameters */
  47286. + if (MV_OK != mvSataWinGet(dev, winNumIndex, &addrDecWin))
  47287. + {
  47288. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  47289. + return MV_ERROR;
  47290. + }
  47291. +
  47292. + /* Do not check disabled windows */
  47293. + if(addrDecWin.enable == MV_FALSE)
  47294. + {
  47295. + continue;
  47296. + }
  47297. +
  47298. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  47299. + {
  47300. + return MV_TRUE;
  47301. + }
  47302. + }
  47303. + return MV_FALSE;
  47304. +}
  47305. +
  47306. +
  47307. +/*******************************************************************************
  47308. +* mvSataWinSet - Set SATA target address window
  47309. +*
  47310. +* DESCRIPTION:
  47311. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  47312. +* address window, also known as address decode window.
  47313. +* After setting this target window, the SATA will be able to access the
  47314. +* target within the address window.
  47315. +*
  47316. +* INPUT:
  47317. +* winNum - SATA target address decode window number.
  47318. +* pAddrDecWin - SATA target window data structure.
  47319. +*
  47320. +* OUTPUT:
  47321. +* None.
  47322. +*
  47323. +* RETURN:
  47324. +* MV_ERROR if address window overlapps with other address decode windows.
  47325. +* MV_BAD_PARAM if base address is invalid parameter or target is
  47326. +* unknown.
  47327. +*
  47328. +*******************************************************************************/
  47329. +MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)
  47330. +{
  47331. + MV_TARGET_ATTRIB targetAttribs;
  47332. + MV_DEC_REGS decRegs;
  47333. +
  47334. + /* Parameter checking */
  47335. + if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)
  47336. + {
  47337. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  47338. + return MV_BAD_PARAM;
  47339. + }
  47340. +
  47341. + /* Check if the requested window overlapps with current windows */
  47342. + if (MV_TRUE == sataWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))
  47343. + {
  47344. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  47345. + return MV_ERROR;
  47346. + }
  47347. +
  47348. + /* check if address is aligned to the size */
  47349. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  47350. + {
  47351. + mvOsPrintf("mvSataWinSet:Error setting SATA window %d to "\
  47352. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  47353. + winNum,
  47354. + mvCtrlTargetNameGet(pAddrDecWin->target),
  47355. + pAddrDecWin->addrWin.baseLow,
  47356. + pAddrDecWin->addrWin.size);
  47357. + return MV_ERROR;
  47358. + }
  47359. +
  47360. + decRegs.baseReg = 0;
  47361. + decRegs.sizeReg = 0;
  47362. +
  47363. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  47364. + {
  47365. + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
  47366. + return MV_ERROR;
  47367. + }
  47368. +
  47369. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  47370. +
  47371. + /* set attributes */
  47372. + decRegs.sizeReg &= ~MV_SATA_WIN_ATTR_MASK;
  47373. + decRegs.sizeReg |= (targetAttribs.attrib << MV_SATA_WIN_ATTR_OFFSET);
  47374. +
  47375. + /* set target ID */
  47376. + decRegs.sizeReg &= ~MV_SATA_WIN_TARGET_MASK;
  47377. + decRegs.sizeReg |= (targetAttribs.targetId << MV_SATA_WIN_TARGET_OFFSET);
  47378. +
  47379. + if (pAddrDecWin->enable == MV_TRUE)
  47380. + {
  47381. + decRegs.sizeReg |= MV_SATA_WIN_ENABLE_MASK;
  47382. + }
  47383. + else
  47384. + {
  47385. + decRegs.sizeReg &= ~MV_SATA_WIN_ENABLE_MASK;
  47386. + }
  47387. +
  47388. + MV_REG_WRITE( MV_SATA_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);
  47389. + MV_REG_WRITE( MV_SATA_WIN_BASE_REG(dev, winNum), decRegs.baseReg);
  47390. +
  47391. + return MV_OK;
  47392. +}
  47393. +
  47394. +/*******************************************************************************
  47395. +* mvSataWinGet - Get SATA peripheral target address window.
  47396. +*
  47397. +* DESCRIPTION:
  47398. +* Get SATA peripheral target address window.
  47399. +*
  47400. +* INPUT:
  47401. +* winNum - SATA target address decode window number.
  47402. +*
  47403. +* OUTPUT:
  47404. +* pAddrDecWin - SATA target window data structure.
  47405. +*
  47406. +* RETURN:
  47407. +* MV_ERROR if register parameters are invalid.
  47408. +*
  47409. +*******************************************************************************/
  47410. +MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)
  47411. +{
  47412. + MV_DEC_REGS decRegs;
  47413. + MV_TARGET_ATTRIB targetAttrib;
  47414. +
  47415. + /* Parameter checking */
  47416. + if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)
  47417. + {
  47418. + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
  47419. + __FUNCTION__, dev, winNum);
  47420. + return MV_NOT_SUPPORTED;
  47421. + }
  47422. +
  47423. + decRegs.baseReg = MV_REG_READ( MV_SATA_WIN_BASE_REG(dev, winNum) );
  47424. + decRegs.sizeReg = MV_REG_READ( MV_SATA_WIN_CTRL_REG(dev, winNum) );
  47425. +
  47426. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
  47427. + {
  47428. + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
  47429. + return MV_ERROR;
  47430. + }
  47431. +
  47432. + /* attrib and targetId */
  47433. + targetAttrib.attrib = (decRegs.sizeReg & MV_SATA_WIN_ATTR_MASK) >>
  47434. + MV_SATA_WIN_ATTR_OFFSET;
  47435. + targetAttrib.targetId = (decRegs.sizeReg & MV_SATA_WIN_TARGET_MASK) >>
  47436. + MV_SATA_WIN_TARGET_OFFSET;
  47437. +
  47438. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  47439. +
  47440. + /* Check if window is enabled */
  47441. + if(decRegs.sizeReg & MV_SATA_WIN_ENABLE_MASK)
  47442. + {
  47443. + pAddrDecWin->enable = MV_TRUE;
  47444. + }
  47445. + else
  47446. + {
  47447. + pAddrDecWin->enable = MV_FALSE;
  47448. + }
  47449. + return MV_OK;
  47450. +}
  47451. +/*******************************************************************************
  47452. +* mvSataAddrDecShow - Print the SATA address decode map.
  47453. +*
  47454. +* DESCRIPTION:
  47455. +* This function print the SATA address decode map.
  47456. +*
  47457. +* INPUT:
  47458. +* None.
  47459. +*
  47460. +* OUTPUT:
  47461. +* None.
  47462. +*
  47463. +* RETURN:
  47464. +* None.
  47465. +*
  47466. +*******************************************************************************/
  47467. +MV_VOID mvSataAddrDecShow(MV_VOID)
  47468. +{
  47469. +
  47470. + MV_SATA_DEC_WIN win;
  47471. + int i,j;
  47472. +
  47473. +
  47474. +
  47475. + for( j = 0; j < MV_SATA_MAX_CHAN; j++ )
  47476. + {
  47477. + if (MV_FALSE == mvCtrlPwrClckGet(SATA_UNIT_ID, j))
  47478. + return;
  47479. +
  47480. + mvOsOutput( "\n" );
  47481. + mvOsOutput( "SATA %d:\n", j );
  47482. + mvOsOutput( "----\n" );
  47483. +
  47484. + for( i = 0; i < MV_SATA_MAX_ADDR_DECODE_WIN; i++ )
  47485. + {
  47486. + memset( &win, 0, sizeof(MV_SATA_DEC_WIN) );
  47487. +
  47488. + mvOsOutput( "win%d - ", i );
  47489. +
  47490. + if( mvSataWinGet(j, i, &win ) == MV_OK )
  47491. + {
  47492. + if( win.enable )
  47493. + {
  47494. + mvOsOutput( "%s base %08x, ",
  47495. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  47496. + mvOsOutput( "...." );
  47497. +
  47498. + mvSizePrint( win.addrWin.size );
  47499. +
  47500. + mvOsOutput( "\n" );
  47501. + }
  47502. + else
  47503. + mvOsOutput( "disable\n" );
  47504. + }
  47505. + }
  47506. + }
  47507. +}
  47508. +
  47509. +
  47510. +/*******************************************************************************
  47511. +* mvSataWinInit - Initialize the integrated SATA target address window.
  47512. +*
  47513. +* DESCRIPTION:
  47514. +* Initialize the SATA peripheral target address window.
  47515. +*
  47516. +* INPUT:
  47517. +*
  47518. +*
  47519. +* OUTPUT:
  47520. +*
  47521. +*
  47522. +* RETURN:
  47523. +* MV_ERROR if register parameters are invalid.
  47524. +*
  47525. +*******************************************************************************/
  47526. +MV_STATUS mvSataWinInit(MV_VOID)
  47527. +{
  47528. + int winNum;
  47529. + MV_SATA_DEC_WIN sataWin;
  47530. + MV_CPU_DEC_WIN cpuAddrDecWin;
  47531. + MV_U32 status, winPrioIndex = 0;
  47532. +
  47533. + /* Initiate Sata address decode */
  47534. +
  47535. + /* First disable all address decode windows */
  47536. + for(winNum = 0; winNum < MV_SATA_MAX_ADDR_DECODE_WIN; winNum++)
  47537. + {
  47538. + MV_U32 regVal = MV_REG_READ(MV_SATA_WIN_CTRL_REG(0, winNum));
  47539. + regVal &= ~MV_SATA_WIN_ENABLE_MASK;
  47540. + MV_REG_WRITE(MV_SATA_WIN_CTRL_REG(0, winNum), regVal);
  47541. + }
  47542. +
  47543. + winNum = 0;
  47544. + while( (sataAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
  47545. + (winNum < MV_SATA_MAX_ADDR_DECODE_WIN) )
  47546. + {
  47547. + /* first get attributes from CPU If */
  47548. + status = mvCpuIfTargetWinGet(sataAddrDecPrioTab[winPrioIndex],
  47549. + &cpuAddrDecWin);
  47550. +
  47551. + if(MV_NO_SUCH == status)
  47552. + {
  47553. + winPrioIndex++;
  47554. + continue;
  47555. + }
  47556. + if (MV_OK != status)
  47557. + {
  47558. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  47559. + return MV_ERROR;
  47560. + }
  47561. +
  47562. + if (cpuAddrDecWin.enable == MV_TRUE)
  47563. + {
  47564. + sataWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  47565. + sataWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  47566. + sataWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  47567. + sataWin.enable = MV_TRUE;
  47568. + sataWin.target = sataAddrDecPrioTab[winPrioIndex];
  47569. +
  47570. + if(MV_OK != mvSataWinSet(0/*dev*/, winNum, &sataWin))
  47571. + {
  47572. + return MV_ERROR;
  47573. + }
  47574. + winNum++;
  47575. + }
  47576. + winPrioIndex++;
  47577. + }
  47578. + return MV_OK;
  47579. +}
  47580. +
  47581. +
  47582. +
  47583. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h
  47584. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h 1970-01-01 01:00:00.000000000 +0100
  47585. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h 2011-07-31 11:31:58.043427224 +0200
  47586. @@ -0,0 +1,128 @@
  47587. +
  47588. +/*******************************************************************************
  47589. +Copyright (C) Marvell International Ltd. and its affiliates
  47590. +
  47591. +This software file (the "File") is owned and distributed by Marvell
  47592. +International Ltd. and/or its affiliates ("Marvell") under the following
  47593. +alternative licensing terms. Once you have made an election to distribute the
  47594. +File under one of the following license alternatives, please (i) delete this
  47595. +introductory statement regarding license alternatives, (ii) delete the two
  47596. +license alternatives that you have not elected to use and (iii) preserve the
  47597. +Marvell copyright notice above.
  47598. +
  47599. +********************************************************************************
  47600. +Marvell Commercial License Option
  47601. +
  47602. +If you received this File from Marvell and you have entered into a commercial
  47603. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47604. +to you under the terms of the applicable Commercial License.
  47605. +
  47606. +********************************************************************************
  47607. +Marvell GPL License Option
  47608. +
  47609. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47610. +modify this File in accordance with the terms and conditions of the General
  47611. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47612. +available along with the File in the license.txt file or by writing to the Free
  47613. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47614. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47615. +
  47616. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47617. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47618. +DISCLAIMED. The GPL License provides additional details about this warranty
  47619. +disclaimer.
  47620. +********************************************************************************
  47621. +Marvell BSD License Option
  47622. +
  47623. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47624. +modify this File under the following licensing terms.
  47625. +Redistribution and use in source and binary forms, with or without modification,
  47626. +are permitted provided that the following conditions are met:
  47627. +
  47628. + * Redistributions of source code must retain the above copyright notice,
  47629. + this list of conditions and the following disclaimer.
  47630. +
  47631. + * Redistributions in binary form must reproduce the above copyright
  47632. + notice, this list of conditions and the following disclaimer in the
  47633. + documentation and/or other materials provided with the distribution.
  47634. +
  47635. + * Neither the name of Marvell nor the names of its contributors may be
  47636. + used to endorse or promote products derived from this software without
  47637. + specific prior written permission.
  47638. +
  47639. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47640. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47641. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47642. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47643. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47644. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47645. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47646. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47647. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47648. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47649. +
  47650. +*******************************************************************************/
  47651. +#ifndef __INCMVSysSataAddrDech
  47652. +#define __INCMVSysSataAddrDech
  47653. +
  47654. +#include "mvCommon.h"
  47655. +#include "ctrlEnv/mvCtrlEnvLib.h"
  47656. +#include "ctrlEnv/sys/mvCpuIf.h"
  47657. +
  47658. +
  47659. +#ifdef __cplusplus
  47660. +extern "C" {
  47661. +#endif
  47662. +
  47663. +typedef struct _mvSataDecWin
  47664. +{
  47665. + MV_TARGET target;
  47666. + MV_ADDR_WIN addrWin; /* An address window*/
  47667. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47668. +
  47669. +} MV_SATA_DEC_WIN;
  47670. +
  47671. +
  47672. +#define MV_SATA_MAX_ADDR_DECODE_WIN 4
  47673. +
  47674. +#define MV_SATA_WIN_CTRL_REG(dev, win) (SATA_REG_BASE + 0x30 + ((win)<<4))
  47675. +#define MV_SATA_WIN_BASE_REG(dev, win) (SATA_REG_BASE + 0x34 + ((win)<<4))
  47676. +
  47677. +/* BITs in Bridge Interrupt Cause and Mask registers */
  47678. +#define MV_SATA_ADDR_DECODE_ERROR_BIT 0
  47679. +#define MV_SATA_ADDR_DECODE_ERROR_MASK (1<<MV_SATA_ADDR_DECODE_ERROR_BIT)
  47680. +
  47681. +/* BITs in Windows 0-3 Control and Base Registers */
  47682. +#define MV_SATA_WIN_ENABLE_BIT 0
  47683. +#define MV_SATA_WIN_ENABLE_MASK (1<<MV_SATA_WIN_ENABLE_BIT)
  47684. +
  47685. +#define MV_SATA_WIN_TARGET_OFFSET 4
  47686. +#define MV_SATA_WIN_TARGET_MASK (0xF<<MV_SATA_WIN_TARGET_OFFSET)
  47687. +
  47688. +#define MV_SATA_WIN_ATTR_OFFSET 8
  47689. +#define MV_SATA_WIN_ATTR_MASK (0xFF<<MV_SATA_WIN_ATTR_OFFSET)
  47690. +
  47691. +#define MV_SATA_WIN_SIZE_OFFSET 16
  47692. +#define MV_SATA_WIN_SIZE_MASK (0xFFFF<<MV_SATA_WIN_SIZE_OFFSET)
  47693. +
  47694. +#define MV_SATA_WIN_BASE_OFFSET 16
  47695. +#define MV_SATA_WIN_BASE_MASK (0xFFFF<<MV_SATA_WIN_BASE_OFFSET)
  47696. +
  47697. +MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);
  47698. +MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);
  47699. +MV_STATUS mvSataWinByTargetGet(MV_TARGET target, MV_SATA_DEC_WIN *pAddrDecWin);
  47700. +MV_STATUS mvSataWinInit(MV_VOID);
  47701. +MV_VOID mvSataAddrDecShow(MV_VOID);
  47702. +
  47703. +
  47704. +#ifdef __cplusplus
  47705. +}
  47706. +#endif
  47707. +
  47708. +
  47709. +#endif
  47710. +
  47711. +
  47712. +
  47713. +
  47714. +
  47715. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c
  47716. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c 1970-01-01 01:00:00.000000000 +0100
  47717. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c 2011-07-31 11:31:58.103936453 +0200
  47718. @@ -0,0 +1,427 @@
  47719. +/*******************************************************************************
  47720. +Copyright (C) Marvell International Ltd. and its affiliates
  47721. +
  47722. +This software file (the "File") is owned and distributed by Marvell
  47723. +International Ltd. and/or its affiliates ("Marvell") under the following
  47724. +alternative licensing terms. Once you have made an election to distribute the
  47725. +File under one of the following license alternatives, please (i) delete this
  47726. +introductory statement regarding license alternatives, (ii) delete the two
  47727. +license alternatives that you have not elected to use and (iii) preserve the
  47728. +Marvell copyright notice above.
  47729. +
  47730. +********************************************************************************
  47731. +Marvell Commercial License Option
  47732. +
  47733. +If you received this File from Marvell and you have entered into a commercial
  47734. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47735. +to you under the terms of the applicable Commercial License.
  47736. +
  47737. +********************************************************************************
  47738. +Marvell GPL License Option
  47739. +
  47740. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47741. +modify this File in accordance with the terms and conditions of the General
  47742. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47743. +available along with the File in the license.txt file or by writing to the Free
  47744. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47745. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47746. +
  47747. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47748. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47749. +DISCLAIMED. The GPL License provides additional details about this warranty
  47750. +disclaimer.
  47751. +********************************************************************************
  47752. +Marvell BSD License Option
  47753. +
  47754. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47755. +modify this File under the following licensing terms.
  47756. +Redistribution and use in source and binary forms, with or without modification,
  47757. +are permitted provided that the following conditions are met:
  47758. +
  47759. + * Redistributions of source code must retain the above copyright notice,
  47760. + this list of conditions and the following disclaimer.
  47761. +
  47762. + * Redistributions in binary form must reproduce the above copyright
  47763. + notice, this list of conditions and the following disclaimer in the
  47764. + documentation and/or other materials provided with the distribution.
  47765. +
  47766. + * Neither the name of Marvell nor the names of its contributors may be
  47767. + used to endorse or promote products derived from this software without
  47768. + specific prior written permission.
  47769. +
  47770. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47771. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47772. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47773. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47774. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47775. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47776. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47777. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47778. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47779. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47780. +
  47781. +*******************************************************************************/
  47782. +
  47783. +
  47784. +#include "mvTypes.h"
  47785. +#include "mvCommon.h"
  47786. +#include "mvOs.h"
  47787. +#include "ctrlEnv/mvCtrlEnvLib.h"
  47788. +#include "cpu/mvCpu.h"
  47789. +#include "ctrlEnv/sys/mvCpuIf.h"
  47790. +#include "mvRegs.h"
  47791. +#include "ctrlEnv/sys/mvSysSdmmc.h"
  47792. +
  47793. +MV_TARGET sdmmcAddrDecPrioTab[] =
  47794. +{
  47795. +#if defined(MV_INCLUDE_SDRAM_CS0)
  47796. + SDRAM_CS0,
  47797. +#endif
  47798. +#if defined(MV_INCLUDE_SDRAM_CS1)
  47799. + SDRAM_CS1,
  47800. +#endif
  47801. +#if defined(MV_INCLUDE_SDRAM_CS2)
  47802. + SDRAM_CS2,
  47803. +#endif
  47804. +#if defined(MV_INCLUDE_SDRAM_CS3)
  47805. + SDRAM_CS3,
  47806. +#endif
  47807. +#if defined(MV_INCLUDE_PEX)
  47808. + PEX0_MEM,
  47809. +#endif
  47810. + TBL_TERM
  47811. +};
  47812. +
  47813. +
  47814. +/*******************************************************************************
  47815. +* sdmmcWinOverlapDetect - Detect SDMMC address windows overlapping
  47816. +*
  47817. +* DESCRIPTION:
  47818. +* An unpredicted behaviur is expected in case SDMMC address decode
  47819. +* windows overlapps.
  47820. +* This function detects SDMMC address decode windows overlapping of a
  47821. +* specified window. The function does not check the window itself for
  47822. +* overlapping. The function also skipps disabled address decode windows.
  47823. +*
  47824. +* INPUT:
  47825. +* winNum - address decode window number.
  47826. +* pAddrDecWin - An address decode window struct.
  47827. +*
  47828. +* OUTPUT:
  47829. +* None.
  47830. +*
  47831. +* RETURN:
  47832. +* MV_TRUE if the given address window overlap current address
  47833. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  47834. +* from registers.
  47835. +*
  47836. +*******************************************************************************/
  47837. +static MV_STATUS sdmmcWinOverlapDetect(int dev, MV_U32 winNum,
  47838. + MV_ADDR_WIN *pAddrWin)
  47839. +{
  47840. + MV_U32 winNumIndex;
  47841. + MV_SDMMC_DEC_WIN addrDecWin;
  47842. +
  47843. + for(winNumIndex=0; winNumIndex<MV_SDMMC_MAX_ADDR_DECODE_WIN; winNumIndex++)
  47844. + {
  47845. + /* Do not check window itself */
  47846. + if (winNumIndex == winNum)
  47847. + {
  47848. + continue;
  47849. + }
  47850. +
  47851. + /* Get window parameters */
  47852. + if (MV_OK != mvSdmmcWinGet(dev, winNumIndex, &addrDecWin))
  47853. + {
  47854. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  47855. + return MV_ERROR;
  47856. + }
  47857. +
  47858. + /* Do not check disabled windows */
  47859. + if(addrDecWin.enable == MV_FALSE)
  47860. + {
  47861. + continue;
  47862. + }
  47863. +
  47864. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  47865. + {
  47866. + return MV_TRUE;
  47867. + }
  47868. + }
  47869. + return MV_FALSE;
  47870. +}
  47871. +
  47872. +
  47873. +/*******************************************************************************
  47874. +* mvSdmmcWinSet - Set SDMMC target address window
  47875. +*
  47876. +* DESCRIPTION:
  47877. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  47878. +* address window, also known as address decode window.
  47879. +* After setting this target window, the SDMMC will be able to access the
  47880. +* target within the address window.
  47881. +*
  47882. +* INPUT:
  47883. +* winNum - SDMMC target address decode window number.
  47884. +* pAddrDecWin - SDMMC target window data structure.
  47885. +*
  47886. +* OUTPUT:
  47887. +* None.
  47888. +*
  47889. +* RETURN:
  47890. +* MV_ERROR if address window overlapps with other address decode windows.
  47891. +* MV_BAD_PARAM if base address is invalid parameter or target is
  47892. +* unknown.
  47893. +*
  47894. +*******************************************************************************/
  47895. +MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
  47896. +{
  47897. + MV_TARGET_ATTRIB targetAttribs;
  47898. + MV_DEC_REGS decRegs;
  47899. +
  47900. + /* Parameter checking */
  47901. + if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
  47902. + {
  47903. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  47904. + return MV_BAD_PARAM;
  47905. + }
  47906. +
  47907. + /* Check if the requested window overlapps with current windows */
  47908. + if (MV_TRUE == sdmmcWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))
  47909. + {
  47910. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  47911. + return MV_ERROR;
  47912. + }
  47913. +
  47914. + /* check if address is aligned to the size */
  47915. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  47916. + {
  47917. + mvOsPrintf("mvSdmmcWinSet:Error setting SDMMC window %d to "\
  47918. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  47919. + winNum,
  47920. + mvCtrlTargetNameGet(pAddrDecWin->target),
  47921. + pAddrDecWin->addrWin.baseLow,
  47922. + pAddrDecWin->addrWin.size);
  47923. + return MV_ERROR;
  47924. + }
  47925. +
  47926. + decRegs.baseReg = 0;
  47927. + decRegs.sizeReg = 0;
  47928. +
  47929. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  47930. + {
  47931. + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
  47932. + return MV_ERROR;
  47933. + }
  47934. +
  47935. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  47936. +
  47937. + /* set attributes */
  47938. + decRegs.sizeReg &= ~MV_SDMMC_WIN_ATTR_MASK;
  47939. + decRegs.sizeReg |= (targetAttribs.attrib << MV_SDMMC_WIN_ATTR_OFFSET);
  47940. +
  47941. + /* set target ID */
  47942. + decRegs.sizeReg &= ~MV_SDMMC_WIN_TARGET_MASK;
  47943. + decRegs.sizeReg |= (targetAttribs.targetId << MV_SDMMC_WIN_TARGET_OFFSET);
  47944. +
  47945. + if (pAddrDecWin->enable == MV_TRUE)
  47946. + {
  47947. + decRegs.sizeReg |= MV_SDMMC_WIN_ENABLE_MASK;
  47948. + }
  47949. + else
  47950. + {
  47951. + decRegs.sizeReg &= ~MV_SDMMC_WIN_ENABLE_MASK;
  47952. + }
  47953. +
  47954. + MV_REG_WRITE( MV_SDMMC_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);
  47955. + MV_REG_WRITE( MV_SDMMC_WIN_BASE_REG(dev, winNum), decRegs.baseReg);
  47956. +
  47957. + return MV_OK;
  47958. +}
  47959. +
  47960. +/*******************************************************************************
  47961. +* mvSdmmcWinGet - Get SDMMC peripheral target address window.
  47962. +*
  47963. +* DESCRIPTION:
  47964. +* Get SDMMC peripheral target address window.
  47965. +*
  47966. +* INPUT:
  47967. +* winNum - SDMMC target address decode window number.
  47968. +*d
  47969. +* OUTPUT:
  47970. +* pAddrDecWin - SDMMC target window data structure.
  47971. +*
  47972. +* RETURN:
  47973. +* MV_ERROR if register parameters are invalid.
  47974. +*
  47975. +*******************************************************************************/
  47976. +MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
  47977. +{
  47978. + MV_DEC_REGS decRegs;
  47979. + MV_TARGET_ATTRIB targetAttrib;
  47980. +
  47981. + /* Parameter checking */
  47982. + if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
  47983. + {
  47984. + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
  47985. + __FUNCTION__, dev, winNum);
  47986. + return MV_NOT_SUPPORTED;
  47987. + }
  47988. +
  47989. + decRegs.baseReg = MV_REG_READ( MV_SDMMC_WIN_BASE_REG(dev, winNum) );
  47990. + decRegs.sizeReg = MV_REG_READ( MV_SDMMC_WIN_CTRL_REG(dev, winNum) );
  47991. +
  47992. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
  47993. + {
  47994. + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
  47995. + return MV_ERROR;
  47996. + }
  47997. +
  47998. + /* attrib and targetId */
  47999. + targetAttrib.attrib = (decRegs.sizeReg & MV_SDMMC_WIN_ATTR_MASK) >>
  48000. + MV_SDMMC_WIN_ATTR_OFFSET;
  48001. + targetAttrib.targetId = (decRegs.sizeReg & MV_SDMMC_WIN_TARGET_MASK) >>
  48002. + MV_SDMMC_WIN_TARGET_OFFSET;
  48003. +
  48004. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  48005. +
  48006. + /* Check if window is enabled */
  48007. + if(decRegs.sizeReg & MV_SDMMC_WIN_ENABLE_MASK)
  48008. + {
  48009. + pAddrDecWin->enable = MV_TRUE;
  48010. + }
  48011. + else
  48012. + {
  48013. + pAddrDecWin->enable = MV_FALSE;
  48014. + }
  48015. + return MV_OK;
  48016. +}
  48017. +/*******************************************************************************
  48018. +* mvSdmmcAddrDecShow - Print the SDMMC address decode map.
  48019. +*
  48020. +* DESCRIPTION:
  48021. +* This function print the SDMMC address decode map.
  48022. +*
  48023. +* INPUT:
  48024. +* None.
  48025. +*
  48026. +* OUTPUT:
  48027. +* None.
  48028. +*
  48029. +* RETURN:
  48030. +* None.
  48031. +*
  48032. +*******************************************************************************/
  48033. +MV_VOID mvSdmmcAddrDecShow(MV_VOID)
  48034. +{
  48035. +
  48036. + MV_SDMMC_DEC_WIN win;
  48037. + int i,j=0;
  48038. +
  48039. +
  48040. +
  48041. + if (MV_FALSE == mvCtrlPwrClckGet(SDIO_UNIT_ID, 0))
  48042. + return;
  48043. +
  48044. + mvOsOutput( "\n" );
  48045. + mvOsOutput( "SDMMC %d:\n", j );
  48046. + mvOsOutput( "----\n" );
  48047. +
  48048. + for( i = 0; i < MV_SDMMC_MAX_ADDR_DECODE_WIN; i++ )
  48049. + {
  48050. + memset( &win, 0, sizeof(MV_SDMMC_DEC_WIN) );
  48051. +
  48052. + mvOsOutput( "win%d - ", i );
  48053. +
  48054. + if( mvSdmmcWinGet(j, i, &win ) == MV_OK )
  48055. + {
  48056. + if( win.enable )
  48057. + {
  48058. + mvOsOutput( "%s base %08x, ",
  48059. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  48060. + mvOsOutput( "...." );
  48061. +
  48062. + mvSizePrint( win.addrWin.size );
  48063. +
  48064. + mvOsOutput( "\n" );
  48065. + }
  48066. + else
  48067. + mvOsOutput( "disable\n" );
  48068. + }
  48069. + }
  48070. +}
  48071. +
  48072. +
  48073. +/*******************************************************************************
  48074. +* mvSdmmcWinInit - Initialize the integrated SDMMC target address window.
  48075. +*
  48076. +* DESCRIPTION:
  48077. +* Initialize the SDMMC peripheral target address window.
  48078. +*
  48079. +* INPUT:
  48080. +*
  48081. +*
  48082. +* OUTPUT:
  48083. +*
  48084. +*
  48085. +* RETURN:
  48086. +* MV_ERROR if register parameters are invalid.
  48087. +*
  48088. +*******************************************************************************/
  48089. +MV_STATUS mvSdmmcWinInit(MV_VOID)
  48090. +{
  48091. + int winNum;
  48092. + MV_SDMMC_DEC_WIN sdmmcWin;
  48093. + MV_CPU_DEC_WIN cpuAddrDecWin;
  48094. + MV_U32 status, winPrioIndex = 0;
  48095. +
  48096. + /* Initiate Sdmmc address decode */
  48097. +
  48098. + /* First disable all address decode windows */
  48099. + for(winNum = 0; winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN; winNum++)
  48100. + {
  48101. + MV_U32 regVal = MV_REG_READ(MV_SDMMC_WIN_CTRL_REG(0, winNum));
  48102. + regVal &= ~MV_SDMMC_WIN_ENABLE_MASK;
  48103. + MV_REG_WRITE(MV_SDMMC_WIN_CTRL_REG(0, winNum), regVal);
  48104. + }
  48105. +
  48106. + winNum = 0;
  48107. + while( (sdmmcAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
  48108. + (winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN) )
  48109. + {
  48110. + /* first get attributes from CPU If */
  48111. + status = mvCpuIfTargetWinGet(sdmmcAddrDecPrioTab[winPrioIndex],
  48112. + &cpuAddrDecWin);
  48113. +
  48114. + if(MV_NO_SUCH == status)
  48115. + {
  48116. + winPrioIndex++;
  48117. + continue;
  48118. + }
  48119. + if (MV_OK != status)
  48120. + {
  48121. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  48122. + return MV_ERROR;
  48123. + }
  48124. +
  48125. + if (cpuAddrDecWin.enable == MV_TRUE)
  48126. + {
  48127. + sdmmcWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  48128. + sdmmcWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  48129. + sdmmcWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  48130. + sdmmcWin.enable = MV_TRUE;
  48131. + sdmmcWin.target = sdmmcAddrDecPrioTab[winPrioIndex];
  48132. +
  48133. + if(MV_OK != mvSdmmcWinSet(0/*dev*/, winNum, &sdmmcWin))
  48134. + {
  48135. + return MV_ERROR;
  48136. + }
  48137. + winNum++;
  48138. + }
  48139. + winPrioIndex++;
  48140. + }
  48141. + return MV_OK;
  48142. +}
  48143. +
  48144. +
  48145. +
  48146. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h
  48147. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h 1970-01-01 01:00:00.000000000 +0100
  48148. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h 2011-07-31 11:31:58.143424686 +0200
  48149. @@ -0,0 +1,125 @@
  48150. +
  48151. +/*******************************************************************************
  48152. +Copyright (C) Marvell International Ltd. and its affiliates
  48153. +
  48154. +This software file (the "File") is owned and distributed by Marvell
  48155. +International Ltd. and/or its affiliates ("Marvell") under the following
  48156. +alternative licensing terms. Once you have made an election to distribute the
  48157. +File under one of the following license alternatives, please (i) delete this
  48158. +introductory statement regarding license alternatives, (ii) delete the two
  48159. +license alternatives that you have not elected to use and (iii) preserve the
  48160. +Marvell copyright notice above.
  48161. +
  48162. +********************************************************************************
  48163. +Marvell Commercial License Option
  48164. +
  48165. +If you received this File from Marvell and you have entered into a commercial
  48166. +license agreement (a "Commercial License") with Marvell, the File is licensed
  48167. +to you under the terms of the applicable Commercial License.
  48168. +
  48169. +********************************************************************************
  48170. +Marvell GPL License Option
  48171. +
  48172. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48173. +modify this File in accordance with the terms and conditions of the General
  48174. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  48175. +available along with the File in the license.txt file or by writing to the Free
  48176. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  48177. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  48178. +
  48179. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  48180. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  48181. +DISCLAIMED. The GPL License provides additional details about this warranty
  48182. +disclaimer.
  48183. +********************************************************************************
  48184. +Marvell BSD License Option
  48185. +
  48186. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48187. +modify this File under the following licensing terms.
  48188. +Redistribution and use in source and binary forms, with or without modification,
  48189. +are permitted provided that the following conditions are met:
  48190. +
  48191. + * Redistributions of source code must retain the above copyright notice,
  48192. + this list of conditions and the following disclaimer.
  48193. +
  48194. + * Redistributions in binary form must reproduce the above copyright
  48195. + notice, this list of conditions and the following disclaimer in the
  48196. + documentation and/or other materials provided with the distribution.
  48197. +
  48198. + * Neither the name of Marvell nor the names of its contributors may be
  48199. + used to endorse or promote products derived from this software without
  48200. + specific prior written permission.
  48201. +
  48202. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  48203. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  48204. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  48205. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  48206. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  48207. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  48208. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  48209. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  48210. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  48211. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48212. +
  48213. +*******************************************************************************/
  48214. +#ifndef __INCMVSysSdmmcAddrDech
  48215. +#define __INCMVSysSdmmcAddrDech
  48216. +
  48217. +#include "mvCommon.h"
  48218. +#include "ctrlEnv/mvCtrlEnvLib.h"
  48219. +#include "ctrlEnv/sys/mvCpuIf.h"
  48220. +
  48221. +
  48222. +#ifdef __cplusplus
  48223. +extern "C" {
  48224. +#endif
  48225. +
  48226. +typedef struct _mvSdmmcDecWin
  48227. +{
  48228. + MV_TARGET target;
  48229. + MV_ADDR_WIN addrWin; /* An address window*/
  48230. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  48231. +
  48232. +} MV_SDMMC_DEC_WIN;
  48233. +
  48234. +
  48235. +#define MV_SDMMC_MAX_ADDR_DECODE_WIN 4
  48236. +
  48237. +#define MV_SDMMC_WIN_CTRL_REG(dev, win) (MV_SDIO_REG_BASE + 0x108 + ((win)<<3))
  48238. +#define MV_SDMMC_WIN_BASE_REG(dev, win) (MV_SDIO_REG_BASE + 0x10c + ((win)<<3))
  48239. +
  48240. +
  48241. +/* BITs in Windows 0-3 Control and Base Registers */
  48242. +#define MV_SDMMC_WIN_ENABLE_BIT 0
  48243. +#define MV_SDMMC_WIN_ENABLE_MASK (1<<MV_SDMMC_WIN_ENABLE_BIT)
  48244. +
  48245. +#define MV_SDMMC_WIN_TARGET_OFFSET 4
  48246. +#define MV_SDMMC_WIN_TARGET_MASK (0xF<<MV_SDMMC_WIN_TARGET_OFFSET)
  48247. +
  48248. +#define MV_SDMMC_WIN_ATTR_OFFSET 8
  48249. +#define MV_SDMMC_WIN_ATTR_MASK (0xFF<<MV_SDMMC_WIN_ATTR_OFFSET)
  48250. +
  48251. +#define MV_SDMMC_WIN_SIZE_OFFSET 16
  48252. +#define MV_SDMMC_WIN_SIZE_MASK (0xFFFF<<MV_SDMMC_WIN_SIZE_OFFSET)
  48253. +
  48254. +#define MV_SDMMC_WIN_BASE_OFFSET 16
  48255. +#define MV_SDMMC_WIN_BASE_MASK (0xFFFF<<MV_SDMMC_WIN_BASE_OFFSET)
  48256. +
  48257. +MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);
  48258. +MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);
  48259. +MV_STATUS mvSdmmcWinByTargetGet(MV_TARGET target, MV_SDMMC_DEC_WIN *pAddrDecWin);
  48260. +MV_STATUS mvSdmmcWinInit(MV_VOID);
  48261. +MV_VOID mvSdmmcAddrDecShow(MV_VOID);
  48262. +
  48263. +
  48264. +#ifdef __cplusplus
  48265. +}
  48266. +#endif
  48267. +
  48268. +
  48269. +#endif
  48270. +
  48271. +
  48272. +
  48273. +
  48274. +
  48275. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c
  48276. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c 1970-01-01 01:00:00.000000000 +0100
  48277. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c 2011-07-31 11:31:58.195923950 +0200
  48278. @@ -0,0 +1,462 @@
  48279. +/*******************************************************************************
  48280. +Copyright (C) Marvell International Ltd. and its affiliates
  48281. +
  48282. +This software file (the "File") is owned and distributed by Marvell
  48283. +International Ltd. and/or its affiliates ("Marvell") under the following
  48284. +alternative licensing terms. Once you have made an election to distribute the
  48285. +File under one of the following license alternatives, please (i) delete this
  48286. +introductory statement regarding license alternatives, (ii) delete the two
  48287. +license alternatives that you have not elected to use and (iii) preserve the
  48288. +Marvell copyright notice above.
  48289. +
  48290. +********************************************************************************
  48291. +Marvell Commercial License Option
  48292. +
  48293. +If you received this File from Marvell and you have entered into a commercial
  48294. +license agreement (a "Commercial License") with Marvell, the File is licensed
  48295. +to you under the terms of the applicable Commercial License.
  48296. +
  48297. +********************************************************************************
  48298. +Marvell GPL License Option
  48299. +
  48300. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48301. +modify this File in accordance with the terms and conditions of the General
  48302. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  48303. +available along with the File in the license.txt file or by writing to the Free
  48304. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  48305. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  48306. +
  48307. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  48308. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  48309. +DISCLAIMED. The GPL License provides additional details about this warranty
  48310. +disclaimer.
  48311. +********************************************************************************
  48312. +Marvell BSD License Option
  48313. +
  48314. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48315. +modify this File under the following licensing terms.
  48316. +Redistribution and use in source and binary forms, with or without modification,
  48317. +are permitted provided that the following conditions are met:
  48318. +
  48319. + * Redistributions of source code must retain the above copyright notice,
  48320. + this list of conditions and the following disclaimer.
  48321. +
  48322. + * Redistributions in binary form must reproduce the above copyright
  48323. + notice, this list of conditions and the following disclaimer in the
  48324. + documentation and/or other materials provided with the distribution.
  48325. +
  48326. + * Neither the name of Marvell nor the names of its contributors may be
  48327. + used to endorse or promote products derived from this software without
  48328. + specific prior written permission.
  48329. +
  48330. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  48331. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  48332. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  48333. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  48334. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  48335. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  48336. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  48337. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  48338. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  48339. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48340. +
  48341. +*******************************************************************************/
  48342. +
  48343. +#include "mvSysTdm.h"
  48344. +
  48345. +
  48346. +/* defines */
  48347. +#ifdef MV_DEBUG
  48348. + #define DB(x) x
  48349. +#else
  48350. + #define DB(x)
  48351. +#endif
  48352. +
  48353. +static MV_TARGET tdmAddrDecPrioTap[] =
  48354. +{
  48355. + PEX0_MEM,
  48356. + SDRAM_CS0,
  48357. + SDRAM_CS1,
  48358. + SDRAM_CS2,
  48359. + SDRAM_CS3,
  48360. + DEVICE_CS0,
  48361. + DEVICE_CS1,
  48362. + DEVICE_CS2,
  48363. + DEV_BOOCS,
  48364. + PEX0_IO,
  48365. + TBL_TERM
  48366. +};
  48367. +
  48368. +static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  48369. +
  48370. +/*******************************************************************************
  48371. +* mvTdmWinInit - Initialize TDM address decode windows
  48372. +*
  48373. +* DESCRIPTION:
  48374. +* This function initialize TDM window decode unit. It set the
  48375. +* default address decode
  48376. +* windows of the unit.
  48377. +*
  48378. +* INPUT:
  48379. +* None.
  48380. +*
  48381. +* OUTPUT:
  48382. +* None.
  48383. +*
  48384. +* RETURN:
  48385. +* MV_ERROR if setting fail.
  48386. +*******************************************************************************/
  48387. +
  48388. +MV_STATUS mvTdmWinInit(void)
  48389. +{
  48390. + MV_U32 winNum;
  48391. + MV_U32 winPrioIndex = 0;
  48392. + MV_CPU_DEC_WIN cpuAddrDecWin;
  48393. + MV_TDM_DEC_WIN tdmWin;
  48394. + MV_STATUS status;
  48395. +
  48396. + /*Disable all windows*/
  48397. + for (winNum = 0; winNum < TDM_MBUS_MAX_WIN; winNum++)
  48398. + {
  48399. + mvTdmWinEnable(winNum, MV_FALSE);
  48400. + }
  48401. +
  48402. + for (winNum = 0; ((tdmAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  48403. + (winNum < TDM_MBUS_MAX_WIN)); )
  48404. + {
  48405. + status = mvCpuIfTargetWinGet(tdmAddrDecPrioTap[winPrioIndex],
  48406. + &cpuAddrDecWin);
  48407. + if (MV_NO_SUCH == status)
  48408. + {
  48409. + winPrioIndex++;
  48410. + continue;
  48411. + }
  48412. + if (MV_OK != status)
  48413. + {
  48414. + mvOsPrintf("mvTdmInit: ERR. mvCpuIfTargetWinGet failed\n");
  48415. + return MV_ERROR;
  48416. + }
  48417. +
  48418. + if (cpuAddrDecWin.enable == MV_TRUE)
  48419. + {
  48420. + tdmWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  48421. + tdmWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  48422. + tdmWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  48423. + tdmWin.enable = MV_TRUE;
  48424. + tdmWin.target = tdmAddrDecPrioTap[winPrioIndex];
  48425. + if (MV_OK != mvTdmWinSet(winNum, &tdmWin))
  48426. + {
  48427. + return MV_ERROR;
  48428. + }
  48429. + winNum++;
  48430. + }
  48431. + winPrioIndex++;
  48432. + }
  48433. + return MV_OK;
  48434. +}
  48435. +
  48436. +/*******************************************************************************
  48437. +* mvTdmWinSet - Set TDM target address window
  48438. +*
  48439. +* DESCRIPTION:
  48440. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  48441. +* address window, also known as address decode window.
  48442. +* After setting this target window, the TDM will be able to access the
  48443. +* target within the address window.
  48444. +*
  48445. +* INPUT:
  48446. +* winNum - TDM to target address decode window number.
  48447. +* pAddrDecWin - TDM target window data structure.
  48448. +*
  48449. +* OUTPUT:
  48450. +* None.
  48451. +*
  48452. +* RETURN:
  48453. +* MV_ERROR if address window overlapps with other address decode windows.
  48454. +* MV_BAD_PARAM if base address is invalid parameter or target is
  48455. +* unknown.
  48456. +*
  48457. +*******************************************************************************/
  48458. +
  48459. +MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
  48460. +{
  48461. + MV_TARGET_ATTRIB targetAttribs;
  48462. + MV_DEC_REGS decRegs;
  48463. + MV_U32 ctrlReg = 0;
  48464. +
  48465. + /* Parameter checking */
  48466. + if (winNum >= TDM_MBUS_MAX_WIN)
  48467. + {
  48468. + mvOsPrintf("mvTdmWinSet: ERR. Invalid win num %d\n",winNum);
  48469. + return MV_BAD_PARAM;
  48470. + }
  48471. +
  48472. + /* Check if the requested window overlapps with current windows */
  48473. + if (MV_TRUE == tdmWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
  48474. + {
  48475. + mvOsPrintf("mvTdmWinSet: ERR. Window %d overlap\n", winNum);
  48476. + return MV_ERROR;
  48477. + }
  48478. +
  48479. + /* check if address is aligned to the size */
  48480. + if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  48481. + {
  48482. + mvOsPrintf("mvTdmWinSet: Error setting TDM window %d to "\
  48483. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  48484. + winNum,
  48485. + mvCtrlTargetNameGet(pAddrDecWin->target),
  48486. + pAddrDecWin->addrWin.baseLow,
  48487. + pAddrDecWin->addrWin.size);
  48488. + return MV_ERROR;
  48489. + }
  48490. +
  48491. + decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
  48492. + decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
  48493. +
  48494. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  48495. + {
  48496. + mvOsPrintf("mvTdmWinSet: mvCtrlAddrDecToReg Failed\n");
  48497. + return MV_ERROR;
  48498. + }
  48499. +
  48500. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  48501. +
  48502. + /* for the safe side we disable the window before writing the new
  48503. + values */
  48504. + mvTdmWinEnable(winNum, MV_FALSE);
  48505. +
  48506. + ctrlReg |= (targetAttribs.attrib << TDM_WIN_ATTRIB_OFFS);
  48507. + ctrlReg |= (targetAttribs.targetId << TDM_WIN_TARGET_OFFS);
  48508. + ctrlReg |= (decRegs.sizeReg & TDM_WIN_SIZE_MASK);
  48509. +
  48510. + /* Write to address base and control registers */
  48511. + MV_REG_WRITE(TDM_WIN_BASE_REG(winNum), decRegs.baseReg);
  48512. + MV_REG_WRITE(TDM_WIN_CTRL_REG(winNum), ctrlReg);
  48513. + /* Enable address decode target window */
  48514. + if (pAddrDecWin->enable == MV_TRUE)
  48515. + {
  48516. + mvTdmWinEnable(winNum, MV_TRUE);
  48517. + }
  48518. + return MV_OK;
  48519. +}
  48520. +
  48521. +/*******************************************************************************
  48522. +* mvTdmWinGet - Get peripheral target address window.
  48523. +*
  48524. +* DESCRIPTION:
  48525. +* Get TDM peripheral target address window.
  48526. +*
  48527. +* INPUT:
  48528. +* winNum - TDM to target address decode window number.
  48529. +*
  48530. +* OUTPUT:
  48531. +* pAddrDecWin - TDM target window data structure.
  48532. +*
  48533. +* RETURN:
  48534. +* MV_ERROR if register parameters are invalid.
  48535. +*
  48536. +*******************************************************************************/
  48537. +
  48538. +MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
  48539. +{
  48540. +
  48541. + MV_DEC_REGS decRegs;
  48542. + MV_TARGET_ATTRIB targetAttrib;
  48543. +
  48544. + /* Parameter checking */
  48545. + if (winNum >= TDM_MBUS_MAX_WIN)
  48546. + {
  48547. + mvOsPrintf("mvTdmWinGet: ERR. Invalid winNum %d\n", winNum);
  48548. + return MV_NOT_SUPPORTED;
  48549. + }
  48550. +
  48551. + decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
  48552. + decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
  48553. +
  48554. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  48555. + {
  48556. + mvOsPrintf("mvTdmWinGet: mvCtrlRegToAddrDec Failed \n");
  48557. + return MV_ERROR;
  48558. + }
  48559. +
  48560. + /* attrib and targetId */
  48561. + targetAttrib.attrib =
  48562. + (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ATTRIB_MASK) >> TDM_WIN_ATTRIB_OFFS;
  48563. + targetAttrib.targetId =
  48564. + (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_TARGET_MASK) >> TDM_WIN_TARGET_OFFS;
  48565. +
  48566. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  48567. +
  48568. + /* Check if window is enabled */
  48569. + if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
  48570. + {
  48571. + pAddrDecWin->enable = MV_TRUE;
  48572. + }
  48573. + else
  48574. + {
  48575. + pAddrDecWin->enable = MV_FALSE;
  48576. + }
  48577. +
  48578. + return MV_OK;
  48579. +}
  48580. +
  48581. +/*******************************************************************************
  48582. +* mvTdmWinEnable - Enable/disable a TDM to target address window
  48583. +*
  48584. +* DESCRIPTION:
  48585. +* This function enable/disable a TDM to target address window.
  48586. +* According to parameter 'enable' the routine will enable the
  48587. +* window, thus enabling TDM accesses (before enabling the window it is
  48588. +* tested for overlapping). Otherwise, the window will be disabled.
  48589. +*
  48590. +* INPUT:
  48591. +* winNum - TDM to target address decode window number.
  48592. +* enable - Enable/disable parameter.
  48593. +*
  48594. +* OUTPUT:
  48595. +* N/A
  48596. +*
  48597. +* RETURN:
  48598. +* MV_ERROR if decode window number was wrong or enabled window overlapps.
  48599. +*
  48600. +*******************************************************************************/
  48601. +MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable)
  48602. +{
  48603. + MV_TDM_DEC_WIN addrDecWin;
  48604. +
  48605. + if (MV_TRUE == enable)
  48606. + {
  48607. + if (winNum >= TDM_MBUS_MAX_WIN)
  48608. + {
  48609. + mvOsPrintf("mvTdmWinEnable:ERR. Invalid winNum%d\n",winNum);
  48610. + return MV_ERROR;
  48611. + }
  48612. +
  48613. + /* First check for overlap with other enabled windows */
  48614. + /* Get current window */
  48615. + if (MV_OK != mvTdmWinGet(winNum, &addrDecWin))
  48616. + {
  48617. + mvOsPrintf("mvTdmWinEnable:ERR. targetWinGet fail\n");
  48618. + return MV_ERROR;
  48619. + }
  48620. + /* Check for overlapping */
  48621. + if (MV_FALSE == tdmWinOverlapDetect(winNum, &(addrDecWin.addrWin)))
  48622. + {
  48623. + /* No Overlap. Enable address decode target window */
  48624. + MV_REG_BIT_SET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
  48625. + }
  48626. + else
  48627. + { /* Overlap detected */
  48628. + mvOsPrintf("mvTdmWinEnable:ERR. Overlap detected\n");
  48629. + return MV_ERROR;
  48630. + }
  48631. + }
  48632. + else
  48633. + {
  48634. + MV_REG_BIT_RESET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
  48635. + }
  48636. + return MV_OK;
  48637. +}
  48638. +
  48639. +
  48640. +/*******************************************************************************
  48641. +* tdmWinOverlapDetect - Detect TDM address windows overlapping
  48642. +*
  48643. +* DESCRIPTION:
  48644. +* An unpredicted behaviour is expected in case TDM address decode
  48645. +* windows overlapps.
  48646. +* This function detects TDM address decode windows overlapping of a
  48647. +* specified window. The function does not check the window itself for
  48648. +* overlapping. The function also skipps disabled address decode windows.
  48649. +*
  48650. +* INPUT:
  48651. +* winNum - address decode window number.
  48652. +* pAddrDecWin - An address decode window struct.
  48653. +*
  48654. +* OUTPUT:
  48655. +* None.
  48656. +*
  48657. +* RETURN:
  48658. +* MV_TRUE if the given address window overlap current address
  48659. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  48660. +* from registers.
  48661. +*
  48662. +*******************************************************************************/
  48663. +static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  48664. +{
  48665. + MV_U32 winNumIndex;
  48666. + MV_TDM_DEC_WIN addrDecWin;
  48667. +
  48668. + for (winNumIndex = 0; winNumIndex < TDM_MBUS_MAX_WIN; winNumIndex++)
  48669. + {
  48670. + /* Do not check window itself */
  48671. + if (winNumIndex == winNum)
  48672. + {
  48673. + continue;
  48674. + }
  48675. + /* Do not check disabled windows */
  48676. + if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
  48677. + {
  48678. + /* Get window parameters */
  48679. + if (MV_OK != mvTdmWinGet(winNumIndex, &addrDecWin))
  48680. + {
  48681. + DB(mvOsPrintf("dmaWinOverlapDetect: ERR. TargetWinGet failed\n"));
  48682. + return MV_ERROR;
  48683. + }
  48684. +
  48685. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  48686. + {
  48687. + return MV_TRUE;
  48688. + }
  48689. + }
  48690. + }
  48691. + return MV_FALSE;
  48692. +}
  48693. +
  48694. +/*******************************************************************************
  48695. +* mvTdmAddrDecShow - Print the TDM address decode map.
  48696. +*
  48697. +* DESCRIPTION:
  48698. +* This function print the TDM address decode map.
  48699. +*
  48700. +* INPUT:
  48701. +* None.
  48702. +*
  48703. +* OUTPUT:
  48704. +* None.
  48705. +*
  48706. +* RETURN:
  48707. +* None.
  48708. +*
  48709. +*******************************************************************************/
  48710. +MV_VOID mvTdmAddrDecShow(MV_VOID)
  48711. +{
  48712. + MV_TDM_DEC_WIN win;
  48713. + int i;
  48714. +
  48715. + mvOsOutput( "\n" );
  48716. + mvOsOutput( "TDM:\n" );
  48717. + mvOsOutput( "----\n" );
  48718. +
  48719. + for( i = 0; i < TDM_MBUS_MAX_WIN; i++ )
  48720. + {
  48721. + memset( &win, 0, sizeof(MV_TDM_DEC_WIN) );
  48722. +
  48723. + mvOsOutput( "win%d - ", i );
  48724. +
  48725. + if (mvTdmWinGet(i, &win ) == MV_OK )
  48726. + {
  48727. + if( win.enable )
  48728. + {
  48729. + mvOsOutput( "%s base %08x, ",
  48730. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow);
  48731. + mvOsOutput( "...." );
  48732. + mvSizePrint( win.addrWin.size );
  48733. + mvOsOutput( "\n" );
  48734. + }
  48735. + else
  48736. + mvOsOutput( "disable\n" );
  48737. + }
  48738. + }
  48739. +}
  48740. +
  48741. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h
  48742. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h 1970-01-01 01:00:00.000000000 +0100
  48743. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h 2011-07-31 11:31:58.283937404 +0200
  48744. @@ -0,0 +1,106 @@
  48745. +/*******************************************************************************
  48746. +Copyright (C) Marvell International Ltd. and its affiliates
  48747. +
  48748. +This software file (the "File") is owned and distributed by Marvell
  48749. +International Ltd. and/or its affiliates ("Marvell") under the following
  48750. +alternative licensing terms. Once you have made an election to distribute the
  48751. +File under one of the following license alternatives, please (i) delete this
  48752. +introductory statement regarding license alternatives, (ii) delete the two
  48753. +license alternatives that you have not elected to use and (iii) preserve the
  48754. +Marvell copyright notice above.
  48755. +
  48756. +********************************************************************************
  48757. +Marvell Commercial License Option
  48758. +
  48759. +If you received this File from Marvell and you have entered into a commercial
  48760. +license agreement (a "Commercial License") with Marvell, the File is licensed
  48761. +to you under the terms of the applicable Commercial License.
  48762. +
  48763. +********************************************************************************
  48764. +Marvell GPL License Option
  48765. +
  48766. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48767. +modify this File in accordance with the terms and conditions of the General
  48768. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  48769. +available along with the File in the license.txt file or by writing to the Free
  48770. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  48771. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  48772. +
  48773. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  48774. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  48775. +DISCLAIMED. The GPL License provides additional details about this warranty
  48776. +disclaimer.
  48777. +********************************************************************************
  48778. +Marvell BSD License Option
  48779. +
  48780. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48781. +modify this File under the following licensing terms.
  48782. +Redistribution and use in source and binary forms, with or without modification,
  48783. +are permitted provided that the following conditions are met:
  48784. +
  48785. + * Redistributions of source code must retain the above copyright notice,
  48786. + this list of conditions and the following disclaimer.
  48787. +
  48788. + * Redistributions in binary form must reproduce the above copyright
  48789. + notice, this list of conditions and the following disclaimer in the
  48790. + documentation and/or other materials provided with the distribution.
  48791. +
  48792. + * Neither the name of Marvell nor the names of its contributors may be
  48793. + used to endorse or promote products derived from this software without
  48794. + specific prior written permission.
  48795. +
  48796. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  48797. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  48798. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  48799. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  48800. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  48801. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  48802. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  48803. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  48804. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  48805. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48806. +
  48807. +*******************************************************************************/
  48808. +
  48809. +#ifndef __INCmvSysTdmh
  48810. +#define __INCmvSysTdmh
  48811. +
  48812. +#include "ctrlEnv/sys/mvCpuIf.h"
  48813. +#include "ctrlEnv/mvCtrlEnvLib.h"
  48814. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  48815. +
  48816. +typedef struct _mvTdmDecWin
  48817. +{
  48818. + MV_TARGET target;
  48819. + MV_ADDR_WIN addrWin; /* An address window*/
  48820. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  48821. +} MV_TDM_DEC_WIN;
  48822. +
  48823. +MV_STATUS mvTdmWinInit(MV_VOID);
  48824. +MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);
  48825. +MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);
  48826. +MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable);
  48827. +MV_VOID mvTdmAddrDecShow(MV_VOID);
  48828. +
  48829. +
  48830. +#define TDM_MBUS_MAX_WIN 4
  48831. +#define TDM_WIN_CTRL_REG(win) ((TDM_REG_BASE + 0x4030) + (win<<4))
  48832. +#define TDM_WIN_BASE_REG(win) ((TDM_REG_BASE +0x4034) + (win<<4))
  48833. +
  48834. +/* TDM_WIN_CTRL_REG bits */
  48835. +#define TDM_WIN_ENABLE_OFFS 0
  48836. +#define TDM_WIN_ENABLE_MASK (1<<TDM_WIN_ENABLE_OFFS)
  48837. +#define TDM_WIN_ENABLE 1
  48838. +#define TDM_WIN_TARGET_OFFS 4
  48839. +#define TDM_WIN_TARGET_MASK (0xf<<TDM_WIN_TARGET_OFFS)
  48840. +#define TDM_WIN_ATTRIB_OFFS 8
  48841. +#define TDM_WIN_ATTRIB_MASK (0xff<<TDM_WIN_ATTRIB_OFFS)
  48842. +#define TDM_WIN_SIZE_OFFS 16
  48843. +#define TDM_WIN_SIZE_MASK (0xffff<<TDM_WIN_SIZE_OFFS)
  48844. +
  48845. +/* TDM_WIN_BASE_REG bits */
  48846. +#define TDM_BASE_OFFS 16
  48847. +#define TDM_BASE_MASK (0xffff<<TDM_BASE_OFFS)
  48848. +
  48849. +#endif /*__INCmvSysTdmh*/
  48850. +
  48851. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c
  48852. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c 1970-01-01 01:00:00.000000000 +0100
  48853. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c 2011-07-31 11:31:58.373938021 +0200
  48854. @@ -0,0 +1,591 @@
  48855. +/*******************************************************************************
  48856. +Copyright (C) Marvell International Ltd. and its affiliates
  48857. +
  48858. +This software file (the "File") is owned and distributed by Marvell
  48859. +International Ltd. and/or its affiliates ("Marvell") under the following
  48860. +alternative licensing terms. Once you have made an election to distribute the
  48861. +File under one of the following license alternatives, please (i) delete this
  48862. +introductory statement regarding license alternatives, (ii) delete the two
  48863. +license alternatives that you have not elected to use and (iii) preserve the
  48864. +Marvell copyright notice above.
  48865. +
  48866. +********************************************************************************
  48867. +Marvell Commercial License Option
  48868. +
  48869. +If you received this File from Marvell and you have entered into a commercial
  48870. +license agreement (a "Commercial License") with Marvell, the File is licensed
  48871. +to you under the terms of the applicable Commercial License.
  48872. +
  48873. +********************************************************************************
  48874. +Marvell GPL License Option
  48875. +
  48876. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48877. +modify this File in accordance with the terms and conditions of the General
  48878. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  48879. +available along with the File in the license.txt file or by writing to the Free
  48880. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  48881. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  48882. +
  48883. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  48884. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  48885. +DISCLAIMED. The GPL License provides additional details about this warranty
  48886. +disclaimer.
  48887. +********************************************************************************
  48888. +Marvell BSD License Option
  48889. +
  48890. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48891. +modify this File under the following licensing terms.
  48892. +Redistribution and use in source and binary forms, with or without modification,
  48893. +are permitted provided that the following conditions are met:
  48894. +
  48895. + * Redistributions of source code must retain the above copyright notice,
  48896. + this list of conditions and the following disclaimer.
  48897. +
  48898. + * Redistributions in binary form must reproduce the above copyright
  48899. + notice, this list of conditions and the following disclaimer in the
  48900. + documentation and/or other materials provided with the distribution.
  48901. +
  48902. + * Neither the name of Marvell nor the names of its contributors may be
  48903. + used to endorse or promote products derived from this software without
  48904. + specific prior written permission.
  48905. +
  48906. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  48907. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  48908. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  48909. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  48910. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  48911. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  48912. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  48913. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  48914. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  48915. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48916. +
  48917. +*******************************************************************************/
  48918. +
  48919. +
  48920. +#include "ctrlEnv/sys/mvSysTs.h"
  48921. +
  48922. +
  48923. +typedef struct _mvTsuDecWin
  48924. +{
  48925. + MV_TARGET target;
  48926. + MV_ADDR_WIN addrWin; /* An address window*/
  48927. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  48928. +
  48929. +}MV_TSU_DEC_WIN;
  48930. +
  48931. +
  48932. +MV_TARGET tsuAddrDecPrioTap[] =
  48933. +{
  48934. +#if defined(MV_INCLUDE_PEX)
  48935. + PEX0_MEM,
  48936. +#endif
  48937. +#if defined(MV_INCLUDE_PCI)
  48938. + PCI0_MEM,
  48939. +#endif
  48940. +#if defined(MV_INCLUDE_SDRAM_CS0)
  48941. + SDRAM_CS0,
  48942. +#endif
  48943. +#if defined(MV_INCLUDE_SDRAM_CS1)
  48944. + SDRAM_CS1,
  48945. +#endif
  48946. +#if defined(MV_INCLUDE_SDRAM_CS2)
  48947. + SDRAM_CS2,
  48948. +#endif
  48949. +#if defined(MV_INCLUDE_SDRAM_CS3)
  48950. + SDRAM_CS3,
  48951. +#endif
  48952. +#if defined(MV_INCLUDE_DEVICE_CS0)
  48953. + DEVICE_CS0,
  48954. +#endif
  48955. +#if defined(MV_INCLUDE_DEVICE_CS1)
  48956. + DEVICE_CS1,
  48957. +#endif
  48958. +#if defined(MV_INCLUDE_DEVICE_CS2)
  48959. + DEVICE_CS2,
  48960. +#endif
  48961. +#if defined(MV_INCLUDE_DEVICE_CS3)
  48962. + DEVICE_CS3,
  48963. +#endif
  48964. +#if defined(MV_INCLUDE_PEX)
  48965. + PEX0_IO,
  48966. +#endif
  48967. +#if defined(MV_INCLUDE_PCI)
  48968. + PCI0_IO,
  48969. +#endif
  48970. + TBL_TERM
  48971. +};
  48972. +
  48973. +static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  48974. +static MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);
  48975. +static MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);
  48976. +MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable);
  48977. +
  48978. +/*******************************************************************************
  48979. +* mvTsuWinInit
  48980. +*
  48981. +* DESCRIPTION:
  48982. +* Initialize the TSU unit address decode windows.
  48983. +*
  48984. +* INPUT:
  48985. +* None.
  48986. +* OUTPUT:
  48987. +* None.
  48988. +* RETURN:
  48989. +* MV_OK - on success,
  48990. +*
  48991. +*******************************************************************************/
  48992. +MV_STATUS mvTsuWinInit(void)
  48993. +{
  48994. + MV_U32 winNum, status, winPrioIndex=0;
  48995. + MV_TSU_DEC_WIN tsuWin;
  48996. + MV_CPU_DEC_WIN cpuAddrDecWin;
  48997. +
  48998. + /* First disable all address decode windows */
  48999. + for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)
  49000. + {
  49001. + MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),
  49002. + TSU_WIN_CTRL_EN_MASK);
  49003. + }
  49004. +
  49005. + /* Go through all windows in user table until table terminator */
  49006. + for(winNum = 0; ((tsuAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  49007. + (winNum < TSU_MAX_DECODE_WIN));)
  49008. + {
  49009. + /* first get attributes from CPU If */
  49010. + status = mvCpuIfTargetWinGet(tsuAddrDecPrioTap[winPrioIndex],
  49011. + &cpuAddrDecWin);
  49012. +
  49013. + if(MV_NO_SUCH == status)
  49014. + {
  49015. + winPrioIndex++;
  49016. + continue;
  49017. + }
  49018. + if(MV_OK != status)
  49019. + {
  49020. + mvOsPrintf("mvTsuWinInit: ERR. mvCpuIfTargetWinGet failed\n");
  49021. + return MV_ERROR;
  49022. + }
  49023. +
  49024. + if (cpuAddrDecWin.enable == MV_TRUE)
  49025. + {
  49026. + tsuWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  49027. + tsuWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  49028. + tsuWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  49029. + tsuWin.enable = MV_TRUE;
  49030. + tsuWin.target = tsuAddrDecPrioTap[winPrioIndex];
  49031. +
  49032. + if(MV_OK != mvTsuWinSet(winNum, &tsuWin))
  49033. + {
  49034. + mvOsPrintf("mvTsuWinInit: ERR. mvTsuWinSet failed winNum=%d\n",
  49035. + winNum);
  49036. + return MV_ERROR;
  49037. + }
  49038. + winNum++;
  49039. + }
  49040. + winPrioIndex ++;
  49041. + }
  49042. +
  49043. + return MV_OK;
  49044. +}
  49045. +
  49046. +
  49047. +/*******************************************************************************
  49048. +* mvTsuWinSet
  49049. +*
  49050. +* DESCRIPTION:
  49051. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  49052. +* address window, also known as address decode window.
  49053. +* After setting this target window, the TSU will be able to access the
  49054. +* target within the address window.
  49055. +*
  49056. +* INPUT:
  49057. +* winNum - TSU to target address decode window number.
  49058. +* pAddrDecWin - TSU target window data structure.
  49059. +*
  49060. +* OUTPUT:
  49061. +* None.
  49062. +*
  49063. +* RETURN:
  49064. +* MV_ERROR - if address window overlapps with other address decode
  49065. +* windows.
  49066. +* MV_BAD_PARAM - if base address is invalid parameter or target is
  49067. +* unknown.
  49068. +*
  49069. +*******************************************************************************/
  49070. +MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)
  49071. +{
  49072. + MV_TARGET_ATTRIB targetAttribs;
  49073. + MV_DEC_REGS decRegs;
  49074. +
  49075. + /* Parameter checking */
  49076. + if(winNum >= TSU_MAX_DECODE_WIN)
  49077. + {
  49078. + mvOsPrintf("mvTsuWinSet: ERR. Invalid win num %d\n",winNum);
  49079. + return MV_BAD_PARAM;
  49080. + }
  49081. +
  49082. + /* Check if the requested window overlapps with current windows */
  49083. + if(MV_TRUE == tsuWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
  49084. + {
  49085. + mvOsPrintf("mvTsuWinSet: ERR. Window %d overlap\n", winNum);
  49086. + return MV_ERROR;
  49087. + }
  49088. +
  49089. + /* check if address is aligned to the size */
  49090. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow,pAddrDecWin->addrWin.size))
  49091. + {
  49092. + mvOsPrintf("mvTsuWinSet: Error setting TSU window %d to target "
  49093. + "%s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  49094. + winNum, mvCtrlTargetNameGet(pAddrDecWin->target),
  49095. + pAddrDecWin->addrWin.baseLow,
  49096. + pAddrDecWin->addrWin.size);
  49097. + return MV_ERROR;
  49098. + }
  49099. +
  49100. + decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));
  49101. + decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));
  49102. +
  49103. + if(MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  49104. + {
  49105. + mvOsPrintf("mvTsuWinSet: mvCtrlAddrDecToReg Failed\n");
  49106. + return MV_ERROR;
  49107. + }
  49108. +
  49109. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  49110. +
  49111. + /* set attributes */
  49112. + decRegs.sizeReg &= ~TSU_WIN_CTRL_ATTR_MASK;
  49113. + decRegs.sizeReg |= targetAttribs.attrib << TSU_WIN_CTRL_ATTR_OFFS;
  49114. + /* set target ID */
  49115. + decRegs.sizeReg &= ~TSU_WIN_CTRL_TARGET_MASK;
  49116. + decRegs.sizeReg |= targetAttribs.targetId << TSU_WIN_CTRL_TARGET_OFFS;
  49117. +
  49118. + /* for the safe side we disable the window before writing the new */
  49119. + /* values */
  49120. + mvTsuWinEnable(winNum, MV_FALSE);
  49121. + MV_REG_WRITE(MV_TSU_WIN_CTRL_REG(winNum),decRegs.sizeReg);
  49122. +
  49123. + /* Write to address decode Size Register */
  49124. + MV_REG_WRITE(MV_TSU_WIN_BASE_REG(winNum), decRegs.baseReg);
  49125. +
  49126. + /* Enable address decode target window */
  49127. + if(pAddrDecWin->enable == MV_TRUE)
  49128. + {
  49129. + mvTsuWinEnable(winNum,MV_TRUE);
  49130. + }
  49131. +
  49132. + return MV_OK;
  49133. +}
  49134. +
  49135. +
  49136. +/*******************************************************************************
  49137. +* mvTsuWinGet
  49138. +*
  49139. +* DESCRIPTION:
  49140. +* Get TSU peripheral target address window.
  49141. +*
  49142. +* INPUT:
  49143. +* winNum - TSU to target address decode window number.
  49144. +*
  49145. +* OUTPUT:
  49146. +* pAddrDecWin - TSU target window data structure.
  49147. +*
  49148. +* RETURN:
  49149. +* MV_ERROR if register parameters are invalid.
  49150. +*
  49151. +*******************************************************************************/
  49152. +MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)
  49153. +{
  49154. + MV_DEC_REGS decRegs;
  49155. + MV_TARGET_ATTRIB targetAttrib;
  49156. +
  49157. + /* Parameter checking */
  49158. + if(winNum >= TSU_MAX_DECODE_WIN)
  49159. + {
  49160. + mvOsPrintf("mvTsuWinGet: ERR. Invalid winNum %d\n", winNum);
  49161. + return MV_NOT_SUPPORTED;
  49162. + }
  49163. +
  49164. + decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));
  49165. + decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));
  49166. +
  49167. + if(MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  49168. + {
  49169. + mvOsPrintf("mvTsuWinGet: mvCtrlRegToAddrDec Failed \n");
  49170. + return MV_ERROR;
  49171. + }
  49172. +
  49173. + /* attrib and targetId */
  49174. + targetAttrib.attrib =
  49175. + (decRegs.sizeReg & TSU_WIN_CTRL_ATTR_MASK) >> TSU_WIN_CTRL_ATTR_OFFS;
  49176. + targetAttrib.targetId =
  49177. + (decRegs.sizeReg & TSU_WIN_CTRL_TARGET_MASK) >> TSU_WIN_CTRL_TARGET_OFFS;
  49178. +
  49179. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  49180. +
  49181. + /* Check if window is enabled */
  49182. + if((MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum)) & TSU_WIN_CTRL_EN_MASK))
  49183. + {
  49184. + pAddrDecWin->enable = MV_TRUE;
  49185. + }
  49186. + else
  49187. + {
  49188. + pAddrDecWin->enable = MV_FALSE;
  49189. + }
  49190. +
  49191. + return MV_OK;
  49192. +}
  49193. +
  49194. +
  49195. +/*******************************************************************************
  49196. +* mvTsuWinEnable
  49197. +*
  49198. +* DESCRIPTION:
  49199. +* This function enable/disable a TSU to target address window.
  49200. +* According to parameter 'enable' the routine will enable the
  49201. +* window, thus enabling TSU accesses (before enabling the window it is
  49202. +* tested for overlapping). Otherwise, the window will be disabled.
  49203. +*
  49204. +* INPUT:
  49205. +* winNum - TSU to target address decode window number.
  49206. +* enable - Enable / disable parameter.
  49207. +*
  49208. +* OUTPUT:
  49209. +* N/A
  49210. +*
  49211. +* RETURN:
  49212. +* MV_ERROR if decode window number was wrong or enabled window overlapps.
  49213. +*
  49214. +*******************************************************************************/
  49215. +MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable)
  49216. +{
  49217. + MV_TSU_DEC_WIN addrDecWin;
  49218. +
  49219. + /* Parameter checking */
  49220. + if(winNum >= TSU_MAX_DECODE_WIN)
  49221. + {
  49222. + mvOsPrintf("mvTsuWinEnable: ERR. Invalid winNum%d\n",winNum);
  49223. + return MV_ERROR;
  49224. + }
  49225. +
  49226. + if(enable == MV_TRUE)
  49227. + {
  49228. + /* First check for overlap with other enabled windows */
  49229. + /* Get current window. */
  49230. + if(MV_OK != mvTsuWinGet(winNum,&addrDecWin))
  49231. + {
  49232. + mvOsPrintf("mvTsuWinEnable: ERR. targetWinGet fail\n");
  49233. + return MV_ERROR;
  49234. + }
  49235. + /* Check for overlapping. */
  49236. + if(MV_FALSE == tsuWinOverlapDetect(winNum,&(addrDecWin.addrWin)))
  49237. + {
  49238. + /* No Overlap. Enable address decode target window */
  49239. + MV_REG_BIT_SET(MV_TSU_WIN_CTRL_REG(winNum),
  49240. + TSU_WIN_CTRL_EN_MASK);
  49241. + }
  49242. + else
  49243. + {
  49244. + /* Overlap detected */
  49245. + mvOsPrintf("mvTsuWinEnable: ERR. Overlap detected\n");
  49246. + return MV_ERROR;
  49247. + }
  49248. + }
  49249. + else
  49250. + {
  49251. + /* Disable address decode target window */
  49252. + MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),
  49253. + TSU_WIN_CTRL_EN_MASK);
  49254. + }
  49255. + return MV_OK;
  49256. +}
  49257. +
  49258. +/*******************************************************************************
  49259. +* mvTsuWinTargetGet
  49260. +*
  49261. +* DESCRIPTION:
  49262. +* Get Window number associated with target
  49263. +*
  49264. +* INPUT:
  49265. +* target - Target ID to get the window number for.
  49266. +* OUTPUT:
  49267. +*
  49268. +* RETURN:
  49269. +* window number or 0xFFFFFFFF on error.
  49270. +*
  49271. +*******************************************************************************/
  49272. +MV_U32 mvTsuWinTargetGet(MV_TARGET target)
  49273. +{
  49274. + MV_TSU_DEC_WIN decWin;
  49275. + MV_U32 winNum;
  49276. +
  49277. + /* Check parameters */
  49278. + if(target >= MAX_TARGETS)
  49279. + {
  49280. + mvOsPrintf("mvTsuWinTargetGet: target %d is Illigal\n", target);
  49281. + return 0xffffffff;
  49282. + }
  49283. +
  49284. + for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)
  49285. + {
  49286. + if(mvTsuWinGet(winNum,&decWin) != MV_OK)
  49287. + {
  49288. + mvOsPrintf("mvTsuWinGet: window returned error\n");
  49289. + return 0xffffffff;
  49290. + }
  49291. +
  49292. + if (decWin.enable == MV_TRUE)
  49293. + {
  49294. + if(decWin.target == target)
  49295. + {
  49296. + return winNum;
  49297. + }
  49298. + }
  49299. + }
  49300. + return 0xFFFFFFFF;
  49301. +}
  49302. +
  49303. +
  49304. +/*******************************************************************************
  49305. +* tsuWinOverlapDetect
  49306. +*
  49307. +* DESCRIPTION:
  49308. +* Detect TSU address windows overlapping
  49309. +* An unpredicted behaviur is expected in case TSU address decode
  49310. +* windows overlapps.
  49311. +* This function detects TSU address decode windows overlapping of a
  49312. +* specified window. The function does not check the window itself for
  49313. +* overlapping. The function also skipps disabled address decode windows.
  49314. +*
  49315. +* INPUT:
  49316. +* winNum - address decode window number.
  49317. +* pAddrDecWin - An address decode window struct.
  49318. +*
  49319. +* OUTPUT:
  49320. +* None.
  49321. +*
  49322. +* RETURN:
  49323. +* MV_TRUE if the given address window overlap current address
  49324. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  49325. +* from registers.
  49326. +*
  49327. +*******************************************************************************/
  49328. +static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  49329. +{
  49330. + MV_U32 ctrlReg;
  49331. + MV_U32 winNumIndex;
  49332. + MV_TSU_DEC_WIN addrDecWin;
  49333. +
  49334. + for(winNumIndex = 0; winNumIndex < TSU_MAX_DECODE_WIN; winNumIndex++)
  49335. + {
  49336. + /* Do not check window itself */
  49337. + if(winNumIndex == winNum)
  49338. + {
  49339. + continue;
  49340. + }
  49341. +
  49342. + /* Do not check disabled windows */
  49343. + ctrlReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNumIndex));
  49344. + if((ctrlReg & TSU_WIN_CTRL_EN_MASK) == 0)
  49345. + {
  49346. + continue;
  49347. + }
  49348. +
  49349. + /* Get window parameters */
  49350. + if (MV_OK != mvTsuWinGet(winNumIndex, &addrDecWin))
  49351. + {
  49352. + mvOsPrintf("tsuWinOverlapDetect: ERR. mvTsuWinGet failed\n");
  49353. + return MV_ERROR;
  49354. + }
  49355. +
  49356. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  49357. + {
  49358. + return MV_TRUE;
  49359. + }
  49360. + }
  49361. + return MV_FALSE;
  49362. +}
  49363. +
  49364. +
  49365. +/*******************************************************************************
  49366. +* mvTsuAddrDecShow
  49367. +*
  49368. +* DESCRIPTION:
  49369. +* Print the TSU address decode map.
  49370. +*
  49371. +* INPUT:
  49372. +* None.
  49373. +*
  49374. +* OUTPUT:
  49375. +* None.
  49376. +*
  49377. +* RETURN:
  49378. +* None.
  49379. +*
  49380. +*******************************************************************************/
  49381. +void mvTsuAddrDecShow(void)
  49382. +{
  49383. + MV_TSU_DEC_WIN win;
  49384. + int i;
  49385. +
  49386. + if (MV_FALSE == mvCtrlPwrClckGet(TS_UNIT_ID, 0))
  49387. + return;
  49388. +
  49389. + mvOsOutput( "\n" );
  49390. + mvOsOutput( "TSU:\n");
  49391. + mvOsOutput( "----\n" );
  49392. +
  49393. + for(i = 0; i < TSU_MAX_DECODE_WIN; i++)
  49394. + {
  49395. + memset(&win, 0, sizeof(TSU_MAX_DECODE_WIN));
  49396. + mvOsOutput( "win%d - ", i );
  49397. +
  49398. + if(mvTsuWinGet(i, &win ) == MV_OK )
  49399. + {
  49400. + if(win.enable == MV_TRUE)
  49401. + {
  49402. + mvOsOutput("%s base %08x, ",
  49403. + mvCtrlTargetNameGet(win.target),
  49404. + win.addrWin.baseLow);
  49405. + mvOsOutput( "...." );
  49406. + mvSizePrint(win.addrWin.size );
  49407. + mvOsOutput( "\n" );
  49408. + }
  49409. + else
  49410. + {
  49411. + mvOsOutput( "disable\n" );
  49412. + }
  49413. + }
  49414. + }
  49415. + return;
  49416. +}
  49417. +
  49418. +
  49419. +/*******************************************************************************
  49420. +* mvTsuInit
  49421. +*
  49422. +* DESCRIPTION:
  49423. +* Initialize the TSU unit, and get unit out of reset.
  49424. +*
  49425. +* INPUT:
  49426. +* coreClock - The core clock at which the TSU should operate.
  49427. +* mode - The mode on configure the unit into (serial/parallel).
  49428. +* memHandle - Memory handle used for memory allocations.
  49429. +* OUTPUT:
  49430. +* None.
  49431. +* RETURN:
  49432. +* MV_OK - on success,
  49433. +*
  49434. +*******************************************************************************/
  49435. +MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,
  49436. + void *osHandle)
  49437. +{
  49438. + MV_STATUS status;
  49439. +
  49440. + status = mvTsuWinInit();
  49441. + if(status == MV_OK)
  49442. + status = mvTsuHalInit(coreClock,mode,osHandle);
  49443. +
  49444. + return status;
  49445. +}
  49446. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h
  49447. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h 1970-01-01 01:00:00.000000000 +0100
  49448. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h 2011-07-31 11:31:58.443934991 +0200
  49449. @@ -0,0 +1,110 @@
  49450. +/*******************************************************************************
  49451. +Copyright (C) Marvell International Ltd. and its affiliates
  49452. +
  49453. +This software file (the "File") is owned and distributed by Marvell
  49454. +International Ltd. and/or its affiliates ("Marvell") under the following
  49455. +alternative licensing terms. Once you have made an election to distribute the
  49456. +File under one of the following license alternatives, please (i) delete this
  49457. +introductory statement regarding license alternatives, (ii) delete the two
  49458. +license alternatives that you have not elected to use and (iii) preserve the
  49459. +Marvell copyright notice above.
  49460. +
  49461. +********************************************************************************
  49462. +Marvell Commercial License Option
  49463. +
  49464. +If you received this File from Marvell and you have entered into a commercial
  49465. +license agreement (a "Commercial License") with Marvell, the File is licensed
  49466. +to you under the terms of the applicable Commercial License.
  49467. +
  49468. +********************************************************************************
  49469. +Marvell GPL License Option
  49470. +
  49471. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49472. +modify this File in accordance with the terms and conditions of the General
  49473. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  49474. +available along with the File in the license.txt file or by writing to the Free
  49475. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  49476. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  49477. +
  49478. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  49479. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  49480. +DISCLAIMED. The GPL License provides additional details about this warranty
  49481. +disclaimer.
  49482. +********************************************************************************
  49483. +Marvell BSD License Option
  49484. +
  49485. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49486. +modify this File under the following licensing terms.
  49487. +Redistribution and use in source and binary forms, with or without modification,
  49488. +are permitted provided that the following conditions are met:
  49489. +
  49490. + * Redistributions of source code must retain the above copyright notice,
  49491. + this list of conditions and the following disclaimer.
  49492. +
  49493. + * Redistributions in binary form must reproduce the above copyright
  49494. + notice, this list of conditions and the following disclaimer in the
  49495. + documentation and/or other materials provided with the distribution.
  49496. +
  49497. + * Neither the name of Marvell nor the names of its contributors may be
  49498. + used to endorse or promote products derived from this software without
  49499. + specific prior written permission.
  49500. +
  49501. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  49502. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49503. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  49504. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  49505. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  49506. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  49507. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  49508. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  49509. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  49510. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49511. +
  49512. +*******************************************************************************/
  49513. +
  49514. +#ifndef __INCmvSysTsh
  49515. +#define __INCmvSysTsh
  49516. +
  49517. +#ifdef __cplusplus
  49518. +extern "C" {
  49519. +#endif /* __cplusplus */
  49520. +
  49521. +/* includes */
  49522. +#include "ts/mvTsu.h"
  49523. +#include "ctrlEnv/sys/mvCpuIf.h"
  49524. +#include "ctrlEnv/mvCtrlEnvLib.h"
  49525. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  49526. +
  49527. +#define TSU_MAX_DECODE_WIN 4
  49528. +
  49529. +
  49530. +/*******************************************/
  49531. +/* TSU Windows Registers */
  49532. +/*******************************************/
  49533. +#define MV_TSU_WIN_CTRL_REG(win) (TSU_GLOBAL_REG_BASE +0x30 + 0x10 * win)
  49534. +#define MV_TSU_WIN_BASE_REG(win) (TSU_GLOBAL_REG_BASE +0x34 + 0x10 * win)
  49535. +
  49536. +/* TSU windows control register. */
  49537. +#define TSU_WIN_CTRL_EN_MASK (0x1 << 0)
  49538. +#define TSU_WIN_CTRL_TARGET_OFFS 4
  49539. +#define TSU_WIN_CTRL_TARGET_MASK (0xF << TSU_WIN_CTRL_TARGET_OFFS)
  49540. +#define TSU_WIN_CTRL_ATTR_OFFS 8
  49541. +#define TSU_WIN_CTRL_ATTR_MASK (0xFF << TSU_WIN_CTRL_ATTR_OFFS)
  49542. +#define TSU_WIN_CTRL_SIZE_OFFS 16
  49543. +#define TSU_WIN_CTRL_SIZE_MASK (0xFFFF << TSU_WIN_CTRL_SIZE_OFFS)
  49544. +
  49545. +/* TSU windows base register. */
  49546. +#define TSU_WIN_BASE_OFFS 16
  49547. +#define TSU_WIN_BASE_MASK (0xFFFF << TSU_WIN_BASE_OFFS)
  49548. +
  49549. +MV_STATUS mvTsuWinInit(void);
  49550. +
  49551. +void mvTsuAddrDecShow(void);
  49552. +MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,
  49553. + void *osHandle);
  49554. +
  49555. +#ifdef __cplusplus
  49556. +}
  49557. +#endif /* __cplusplus */
  49558. +
  49559. +#endif /* __INCmvTsh */
  49560. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c
  49561. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c 1970-01-01 01:00:00.000000000 +0100
  49562. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c 2011-07-31 11:31:58.513939269 +0200
  49563. @@ -0,0 +1,497 @@
  49564. +/*******************************************************************************
  49565. +Copyright (C) Marvell International Ltd. and its affiliates
  49566. +
  49567. +This software file (the "File") is owned and distributed by Marvell
  49568. +International Ltd. and/or its affiliates ("Marvell") under the following
  49569. +alternative licensing terms. Once you have made an election to distribute the
  49570. +File under one of the following license alternatives, please (i) delete this
  49571. +introductory statement regarding license alternatives, (ii) delete the two
  49572. +license alternatives that you have not elected to use and (iii) preserve the
  49573. +Marvell copyright notice above.
  49574. +
  49575. +********************************************************************************
  49576. +Marvell Commercial License Option
  49577. +
  49578. +If you received this File from Marvell and you have entered into a commercial
  49579. +license agreement (a "Commercial License") with Marvell, the File is licensed
  49580. +to you under the terms of the applicable Commercial License.
  49581. +
  49582. +********************************************************************************
  49583. +Marvell GPL License Option
  49584. +
  49585. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49586. +modify this File in accordance with the terms and conditions of the General
  49587. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  49588. +available along with the File in the license.txt file or by writing to the Free
  49589. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  49590. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  49591. +
  49592. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  49593. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  49594. +DISCLAIMED. The GPL License provides additional details about this warranty
  49595. +disclaimer.
  49596. +********************************************************************************
  49597. +Marvell BSD License Option
  49598. +
  49599. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49600. +modify this File under the following licensing terms.
  49601. +Redistribution and use in source and binary forms, with or without modification,
  49602. +are permitted provided that the following conditions are met:
  49603. +
  49604. + * Redistributions of source code must retain the above copyright notice,
  49605. + this list of conditions and the following disclaimer.
  49606. +
  49607. + * Redistributions in binary form must reproduce the above copyright
  49608. + notice, this list of conditions and the following disclaimer in the
  49609. + documentation and/or other materials provided with the distribution.
  49610. +
  49611. + * Neither the name of Marvell nor the names of its contributors may be
  49612. + used to endorse or promote products derived from this software without
  49613. + specific prior written permission.
  49614. +
  49615. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  49616. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49617. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  49618. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  49619. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  49620. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  49621. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  49622. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  49623. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  49624. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49625. +
  49626. +*******************************************************************************/
  49627. +
  49628. +#include "ctrlEnv/sys/mvSysUsb.h"
  49629. +
  49630. +MV_TARGET usbAddrDecPrioTab[] =
  49631. +{
  49632. +#if defined(MV_INCLUDE_SDRAM_CS0)
  49633. + SDRAM_CS0,
  49634. +#endif
  49635. +#if defined(MV_INCLUDE_SDRAM_CS1)
  49636. + SDRAM_CS1,
  49637. +#endif
  49638. +#if defined(MV_INCLUDE_SDRAM_CS2)
  49639. + SDRAM_CS2,
  49640. +#endif
  49641. +#if defined(MV_INCLUDE_SDRAM_CS3)
  49642. + SDRAM_CS3,
  49643. +#endif
  49644. +#if defined(MV_INCLUDE_CESA) && defined(USB_UNDERRUN_WA)
  49645. + CRYPT_ENG,
  49646. +#endif
  49647. +#if defined(MV_INCLUDE_PEX)
  49648. + PEX0_MEM,
  49649. +#endif
  49650. + TBL_TERM
  49651. +};
  49652. +
  49653. +
  49654. +
  49655. +MV_STATUS mvUsbInit(int dev, MV_BOOL isHost)
  49656. +{
  49657. + MV_STATUS status;
  49658. +
  49659. + status = mvUsbWinInit(dev);
  49660. + if(status != MV_OK)
  49661. + return status;
  49662. +
  49663. + return mvUsbHalInit(dev, isHost);
  49664. +}
  49665. +
  49666. +
  49667. +/*******************************************************************************
  49668. +* usbWinOverlapDetect - Detect USB address windows overlapping
  49669. +*
  49670. +* DESCRIPTION:
  49671. +* An unpredicted behaviur is expected in case USB address decode
  49672. +* windows overlapps.
  49673. +* This function detects USB address decode windows overlapping of a
  49674. +* specified window. The function does not check the window itself for
  49675. +* overlapping. The function also skipps disabled address decode windows.
  49676. +*
  49677. +* INPUT:
  49678. +* winNum - address decode window number.
  49679. +* pAddrDecWin - An address decode window struct.
  49680. +*
  49681. +* OUTPUT:
  49682. +* None.
  49683. +*
  49684. +* RETURN:
  49685. +* MV_TRUE if the given address window overlap current address
  49686. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  49687. +* from registers.
  49688. +*
  49689. +*******************************************************************************/
  49690. +static MV_STATUS usbWinOverlapDetect(int dev, MV_U32 winNum,
  49691. + MV_ADDR_WIN *pAddrWin)
  49692. +{
  49693. + MV_U32 winNumIndex;
  49694. + MV_DEC_WIN addrDecWin;
  49695. +
  49696. + for(winNumIndex=0; winNumIndex<MV_USB_MAX_ADDR_DECODE_WIN; winNumIndex++)
  49697. + {
  49698. + /* Do not check window itself */
  49699. + if (winNumIndex == winNum)
  49700. + {
  49701. + continue;
  49702. + }
  49703. +
  49704. + /* Get window parameters */
  49705. + if (MV_OK != mvUsbWinGet(dev, winNumIndex, &addrDecWin))
  49706. + {
  49707. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  49708. + return MV_ERROR;
  49709. + }
  49710. +
  49711. + /* Do not check disabled windows */
  49712. + if(addrDecWin.enable == MV_FALSE)
  49713. + {
  49714. + continue;
  49715. + }
  49716. +
  49717. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  49718. + {
  49719. + return MV_TRUE;
  49720. + }
  49721. + }
  49722. + return MV_FALSE;
  49723. +}
  49724. +
  49725. +/*******************************************************************************
  49726. +* mvUsbWinSet - Set USB target address window
  49727. +*
  49728. +* DESCRIPTION:
  49729. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  49730. +* address window, also known as address decode window.
  49731. +* After setting this target window, the USB will be able to access the
  49732. +* target within the address window.
  49733. +*
  49734. +* INPUT:
  49735. +* winNum - USB target address decode window number.
  49736. +* pAddrDecWin - USB target window data structure.
  49737. +*
  49738. +* OUTPUT:
  49739. +* None.
  49740. +*
  49741. +* RETURN:
  49742. +* MV_ERROR if address window overlapps with other address decode windows.
  49743. +* MV_BAD_PARAM if base address is invalid parameter or target is
  49744. +* unknown.
  49745. +*
  49746. +*******************************************************************************/
  49747. +MV_STATUS mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)
  49748. +{
  49749. + MV_DEC_WIN_PARAMS winParams;
  49750. + MV_U32 sizeReg, baseReg;
  49751. +
  49752. + /* Parameter checking */
  49753. + if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)
  49754. + {
  49755. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  49756. + return MV_BAD_PARAM;
  49757. + }
  49758. +
  49759. + /* Check if the requested window overlapps with current windows */
  49760. + if (MV_TRUE == usbWinOverlapDetect(dev, winNum, &pDecWin->addrWin))
  49761. + {
  49762. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  49763. + return MV_ERROR;
  49764. + }
  49765. +
  49766. + /* check if address is aligned to the size */
  49767. + if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))
  49768. + {
  49769. + mvOsPrintf("mvUsbWinSet:Error setting USB window %d to "\
  49770. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  49771. + winNum,
  49772. + mvCtrlTargetNameGet(pDecWin->target),
  49773. + pDecWin->addrWin.baseLow,
  49774. + pDecWin->addrWin.size);
  49775. + return MV_ERROR;
  49776. + }
  49777. +
  49778. + if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))
  49779. + {
  49780. + mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);
  49781. + return MV_ERROR;
  49782. + }
  49783. +
  49784. + /* set Size, Attributes and TargetID */
  49785. + sizeReg = (((winParams.targetId << MV_USB_WIN_TARGET_OFFSET) & MV_USB_WIN_TARGET_MASK) |
  49786. + ((winParams.attrib << MV_USB_WIN_ATTR_OFFSET) & MV_USB_WIN_ATTR_MASK) |
  49787. + ((winParams.size << MV_USB_WIN_SIZE_OFFSET) & MV_USB_WIN_SIZE_MASK));
  49788. +
  49789. +#if defined(MV645xx) || defined(MV646xx)
  49790. + /* If window is DRAM with HW cache coherency, make sure bit2 is set */
  49791. + sizeReg &= ~MV_USB_WIN_BURST_WR_LIMIT_MASK;
  49792. +
  49793. + if((MV_TARGET_IS_DRAM(pDecWin->target)) &&
  49794. + (pDecWin->addrWinAttr.cachePolicy != NO_COHERENCY))
  49795. + {
  49796. + sizeReg |= MV_USB_WIN_BURST_WR_32BIT_LIMIT;
  49797. + }
  49798. + else
  49799. + {
  49800. + sizeReg |= MV_USB_WIN_BURST_WR_NO_LIMIT;
  49801. + }
  49802. +#endif /* MV645xx || MV646xx */
  49803. +
  49804. + if (pDecWin->enable == MV_TRUE)
  49805. + {
  49806. + sizeReg |= MV_USB_WIN_ENABLE_MASK;
  49807. + }
  49808. + else
  49809. + {
  49810. + sizeReg &= ~MV_USB_WIN_ENABLE_MASK;
  49811. + }
  49812. +
  49813. + /* Update Base value */
  49814. + baseReg = (winParams.baseAddr & MV_USB_WIN_BASE_MASK);
  49815. +
  49816. + MV_REG_WRITE( MV_USB_WIN_CTRL_REG(dev, winNum), sizeReg);
  49817. + MV_REG_WRITE( MV_USB_WIN_BASE_REG(dev, winNum), baseReg);
  49818. +
  49819. + return MV_OK;
  49820. +}
  49821. +
  49822. +/*******************************************************************************
  49823. +* mvUsbWinGet - Get USB peripheral target address window.
  49824. +*
  49825. +* DESCRIPTION:
  49826. +* Get USB peripheral target address window.
  49827. +*
  49828. +* INPUT:
  49829. +* winNum - USB target address decode window number.
  49830. +*
  49831. +* OUTPUT:
  49832. +* pDecWin - USB target window data structure.
  49833. +*
  49834. +* RETURN:
  49835. +* MV_ERROR if register parameters are invalid.
  49836. +*
  49837. +*******************************************************************************/
  49838. +MV_STATUS mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)
  49839. +{
  49840. + MV_DEC_WIN_PARAMS winParam;
  49841. + MV_U32 sizeReg, baseReg;
  49842. +
  49843. + /* Parameter checking */
  49844. + if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)
  49845. + {
  49846. + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
  49847. + __FUNCTION__, dev, winNum);
  49848. + return MV_NOT_SUPPORTED;
  49849. + }
  49850. +
  49851. + baseReg = MV_REG_READ( MV_USB_WIN_BASE_REG(dev, winNum) );
  49852. + sizeReg = MV_REG_READ( MV_USB_WIN_CTRL_REG(dev, winNum) );
  49853. +
  49854. + /* Check if window is enabled */
  49855. + if(sizeReg & MV_USB_WIN_ENABLE_MASK)
  49856. + {
  49857. + pDecWin->enable = MV_TRUE;
  49858. +
  49859. + /* Extract window parameters from registers */
  49860. + winParam.targetId = (sizeReg & MV_USB_WIN_TARGET_MASK) >> MV_USB_WIN_TARGET_OFFSET;
  49861. + winParam.attrib = (sizeReg & MV_USB_WIN_ATTR_MASK) >> MV_USB_WIN_ATTR_OFFSET;
  49862. + winParam.size = (sizeReg & MV_USB_WIN_SIZE_MASK) >> MV_USB_WIN_SIZE_OFFSET;
  49863. + winParam.baseAddr = (baseReg & MV_USB_WIN_BASE_MASK);
  49864. +
  49865. + /* Translate the decode window parameters to address decode struct */
  49866. + if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))
  49867. + {
  49868. + mvOsPrintf("Failed to translate register parameters to USB address" \
  49869. + " decode window structure\n");
  49870. + return MV_ERROR;
  49871. + }
  49872. + }
  49873. + else
  49874. + {
  49875. + pDecWin->enable = MV_FALSE;
  49876. + }
  49877. + return MV_OK;
  49878. +}
  49879. +
  49880. +/*******************************************************************************
  49881. +* mvUsbWinInit -
  49882. +*
  49883. +* INPUT:
  49884. +*
  49885. +* OUTPUT:
  49886. +*
  49887. +* RETURN:
  49888. +* MV_ERROR if register parameters are invalid.
  49889. +*
  49890. +*******************************************************************************/
  49891. +MV_STATUS mvUsbWinInit(int dev)
  49892. +{
  49893. + MV_STATUS status;
  49894. + MV_DEC_WIN usbWin;
  49895. + MV_CPU_DEC_WIN cpuAddrDecWin;
  49896. + int winNum;
  49897. + MV_U32 winPrioIndex = 0;
  49898. +
  49899. + /* First disable all address decode windows */
  49900. + for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)
  49901. + {
  49902. + MV_REG_BIT_RESET(MV_USB_WIN_CTRL_REG(dev, winNum), MV_USB_WIN_ENABLE_MASK);
  49903. + }
  49904. +
  49905. + /* Go through all windows in user table until table terminator */
  49906. + winNum = 0;
  49907. + while( (usbAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
  49908. + (winNum < MV_USB_MAX_ADDR_DECODE_WIN) )
  49909. + {
  49910. + /* first get attributes from CPU If */
  49911. + status = mvCpuIfTargetWinGet(usbAddrDecPrioTab[winPrioIndex],
  49912. + &cpuAddrDecWin);
  49913. +
  49914. + if(MV_NO_SUCH == status)
  49915. + {
  49916. + winPrioIndex++;
  49917. + continue;
  49918. + }
  49919. + if (MV_OK != status)
  49920. + {
  49921. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  49922. + return MV_ERROR;
  49923. + }
  49924. +
  49925. + if (cpuAddrDecWin.enable == MV_TRUE)
  49926. + {
  49927. + usbWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  49928. + usbWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  49929. + usbWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  49930. + usbWin.enable = MV_TRUE;
  49931. + usbWin.target = usbAddrDecPrioTab[winPrioIndex];
  49932. +
  49933. +#if defined(MV645xx) || defined(MV646xx)
  49934. + /* Get the default attributes for that target window */
  49935. + mvCtrlDefAttribGet(usbWin.target, &usbWin.addrWinAttr);
  49936. +#endif /* MV645xx || MV646xx */
  49937. +
  49938. + if(MV_OK != mvUsbWinSet(dev, winNum, &usbWin))
  49939. + {
  49940. + return MV_ERROR;
  49941. + }
  49942. + winNum++;
  49943. + }
  49944. + winPrioIndex++;
  49945. + }
  49946. + return MV_OK;
  49947. +}
  49948. +
  49949. +/*******************************************************************************
  49950. +* mvUsbAddrDecShow - Print the USB address decode map.
  49951. +*
  49952. +* DESCRIPTION:
  49953. +* This function print the USB address decode map.
  49954. +*
  49955. +* INPUT:
  49956. +* None.
  49957. +*
  49958. +* OUTPUT:
  49959. +* None.
  49960. +*
  49961. +* RETURN:
  49962. +* None.
  49963. +*
  49964. +*******************************************************************************/
  49965. +MV_VOID mvUsbAddrDecShow(MV_VOID)
  49966. +{
  49967. + MV_DEC_WIN addrDecWin;
  49968. + int i, winNum;
  49969. +
  49970. + mvOsOutput( "\n" );
  49971. + mvOsOutput( "USB:\n" );
  49972. + mvOsOutput( "----\n" );
  49973. +
  49974. + for(i=0; i<mvCtrlUsbMaxGet(); i++)
  49975. + {
  49976. + mvOsOutput( "Device %d:\n", i);
  49977. +
  49978. + for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)
  49979. + {
  49980. + memset(&addrDecWin, 0, sizeof(MV_DEC_WIN) );
  49981. +
  49982. + mvOsOutput( "win%d - ", winNum );
  49983. +
  49984. + if( mvUsbWinGet(i, winNum, &addrDecWin ) == MV_OK )
  49985. + {
  49986. + if( addrDecWin.enable )
  49987. + {
  49988. + mvOsOutput( "%s base %08x, ",
  49989. + mvCtrlTargetNameGet(addrDecWin.target), addrDecWin.addrWin.baseLow );
  49990. +
  49991. + mvSizePrint( addrDecWin.addrWin.size );
  49992. +
  49993. +#if defined(MV645xx) || defined(MV646xx)
  49994. + switch( addrDecWin.addrWinAttr.swapType)
  49995. + {
  49996. + case MV_BYTE_SWAP:
  49997. + mvOsOutput( "BYTE_SWAP, " );
  49998. + break;
  49999. + case MV_NO_SWAP:
  50000. + mvOsOutput( "NO_SWAP , " );
  50001. + break;
  50002. + case MV_BYTE_WORD_SWAP:
  50003. + mvOsOutput( "BYTE_WORD_SWAP, " );
  50004. + break;
  50005. + case MV_WORD_SWAP:
  50006. + mvOsOutput( "WORD_SWAP, " );
  50007. + break;
  50008. + default:
  50009. + mvOsOutput( "SWAP N/A , " );
  50010. + }
  50011. +
  50012. + switch( addrDecWin.addrWinAttr.cachePolicy )
  50013. + {
  50014. + case NO_COHERENCY:
  50015. + mvOsOutput( "NO_COHERENCY , " );
  50016. + break;
  50017. + case WT_COHERENCY:
  50018. + mvOsOutput( "WT_COHERENCY , " );
  50019. + break;
  50020. + case WB_COHERENCY:
  50021. + mvOsOutput( "WB_COHERENCY , " );
  50022. + break;
  50023. + default:
  50024. + mvOsOutput( "COHERENCY N/A, " );
  50025. + }
  50026. +
  50027. + switch( addrDecWin.addrWinAttr.pcixNoSnoop )
  50028. + {
  50029. + case 0:
  50030. + mvOsOutput( "PCI-X NS inactive, " );
  50031. + break;
  50032. + case 1:
  50033. + mvOsOutput( "PCI-X NS active , " );
  50034. + break;
  50035. + default:
  50036. + mvOsOutput( "PCI-X NS N/A , " );
  50037. + }
  50038. +
  50039. + switch( addrDecWin.addrWinAttr.p2pReq64 )
  50040. + {
  50041. + case 0:
  50042. + mvOsOutput( "REQ64 force" );
  50043. + break;
  50044. + case 1:
  50045. + mvOsOutput( "REQ64 detect" );
  50046. + break;
  50047. + default:
  50048. + mvOsOutput( "REQ64 N/A" );
  50049. + }
  50050. +#endif /* MV645xx || MV646xx */
  50051. + mvOsOutput( "\n" );
  50052. + }
  50053. + else
  50054. + mvOsOutput( "disable\n" );
  50055. + }
  50056. + }
  50057. + }
  50058. +}
  50059. +
  50060. +
  50061. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h
  50062. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h 1970-01-01 01:00:00.000000000 +0100
  50063. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h 2011-07-31 11:31:58.583425510 +0200
  50064. @@ -0,0 +1,125 @@
  50065. +/*******************************************************************************
  50066. +Copyright (C) Marvell International Ltd. and its affiliates
  50067. +
  50068. +This software file (the "File") is owned and distributed by Marvell
  50069. +International Ltd. and/or its affiliates ("Marvell") under the following
  50070. +alternative licensing terms. Once you have made an election to distribute the
  50071. +File under one of the following license alternatives, please (i) delete this
  50072. +introductory statement regarding license alternatives, (ii) delete the two
  50073. +license alternatives that you have not elected to use and (iii) preserve the
  50074. +Marvell copyright notice above.
  50075. +
  50076. +********************************************************************************
  50077. +Marvell Commercial License Option
  50078. +
  50079. +If you received this File from Marvell and you have entered into a commercial
  50080. +license agreement (a "Commercial License") with Marvell, the File is licensed
  50081. +to you under the terms of the applicable Commercial License.
  50082. +
  50083. +********************************************************************************
  50084. +Marvell GPL License Option
  50085. +
  50086. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50087. +modify this File in accordance with the terms and conditions of the General
  50088. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50089. +available along with the File in the license.txt file or by writing to the Free
  50090. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50091. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50092. +
  50093. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50094. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50095. +DISCLAIMED. The GPL License provides additional details about this warranty
  50096. +disclaimer.
  50097. +********************************************************************************
  50098. +Marvell BSD License Option
  50099. +
  50100. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50101. +modify this File under the following licensing terms.
  50102. +Redistribution and use in source and binary forms, with or without modification,
  50103. +are permitted provided that the following conditions are met:
  50104. +
  50105. + * Redistributions of source code must retain the above copyright notice,
  50106. + this list of conditions and the following disclaimer.
  50107. +
  50108. + * Redistributions in binary form must reproduce the above copyright
  50109. + notice, this list of conditions and the following disclaimer in the
  50110. + documentation and/or other materials provided with the distribution.
  50111. +
  50112. + * Neither the name of Marvell nor the names of its contributors may be
  50113. + used to endorse or promote products derived from this software without
  50114. + specific prior written permission.
  50115. +
  50116. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  50117. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  50118. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  50119. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  50120. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  50121. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  50122. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  50123. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50124. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  50125. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50126. +
  50127. +*******************************************************************************/
  50128. +
  50129. +#ifndef __INCmvSysUsbh
  50130. +#define __INCmvSysUsbh
  50131. +
  50132. +#ifdef __cplusplus
  50133. +extern "C" {
  50134. +#endif /* __cplusplus */
  50135. +
  50136. +/* includes */
  50137. +#include "usb/mvUsb.h"
  50138. +#include "ctrlEnv/sys/mvCpuIf.h"
  50139. +#include "ctrlEnv/mvCtrlEnvLib.h"
  50140. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  50141. +
  50142. +#define MV_USB_MAX_ADDR_DECODE_WIN 4
  50143. +
  50144. +/*******************************************/
  50145. +/* USB Bridge Registers */
  50146. +/*******************************************/
  50147. +#define MV_USB_BRIDGE_CTRL_REG(dev) (USB_REG_BASE(dev) + 0x300)
  50148. +
  50149. +#define MV_USB_WIN_CTRL_REG(dev, win) (USB_REG_BASE(dev) + 0x320 + ((win)<<4))
  50150. +#define MV_USB_WIN_BASE_REG(dev, win) (USB_REG_BASE(dev) + 0x324 + ((win)<<4))
  50151. +
  50152. +/* BITs in Windows 0-3 Control and Base Registers */
  50153. +#define MV_USB_WIN_ENABLE_BIT 0
  50154. +#define MV_USB_WIN_ENABLE_MASK (1 << MV_USB_WIN_ENABLE_BIT)
  50155. +
  50156. +#define MV_USB_WIN_BURST_WR_LIMIT_BIT 1
  50157. +#define MV_USB_WIN_BURST_WR_LIMIT_MASK (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
  50158. +#define MV_USB_WIN_BURST_WR_NO_LIMIT (0 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
  50159. +#define MV_USB_WIN_BURST_WR_32BIT_LIMIT (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
  50160. +
  50161. +#define MV_USB_WIN_TARGET_OFFSET 4
  50162. +#define MV_USB_WIN_TARGET_MASK (0xF << MV_USB_WIN_TARGET_OFFSET)
  50163. +
  50164. +#define MV_USB_WIN_ATTR_OFFSET 8
  50165. +#define MV_USB_WIN_ATTR_MASK (0xFF << MV_USB_WIN_ATTR_OFFSET)
  50166. +
  50167. +#define MV_USB_WIN_SIZE_OFFSET 16
  50168. +#define MV_USB_WIN_SIZE_MASK (0xFFFF << MV_USB_WIN_SIZE_OFFSET)
  50169. +
  50170. +#define MV_USB_WIN_BASE_OFFSET 16
  50171. +#define MV_USB_WIN_BASE_MASK (0xFFFF << MV_USB_WIN_BASE_OFFSET)
  50172. +
  50173. +
  50174. +#define MV_USB_BRIDGE_IPG_REG(dev) (USB_REG_BASE(dev) + 0x360)
  50175. +
  50176. +
  50177. +MV_STATUS mvUsbInit(int dev, MV_BOOL isHost);
  50178. +
  50179. +MV_STATUS mvUsbWinInit(int dev);
  50180. +MV_STATUS mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);
  50181. +MV_STATUS mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);
  50182. +
  50183. +void mvUsbAddrDecShow(void);
  50184. +
  50185. +#ifdef __cplusplus
  50186. +}
  50187. +#endif /* __cplusplus */
  50188. +
  50189. +#endif /* __INCmvUsbh */
  50190. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c
  50191. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c 1970-01-01 01:00:00.000000000 +0100
  50192. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c 2011-07-31 11:31:58.643939960 +0200
  50193. @@ -0,0 +1,662 @@
  50194. +/*******************************************************************************
  50195. +Copyright (C) Marvell International Ltd. and its affiliates
  50196. +
  50197. +This software file (the "File") is owned and distributed by Marvell
  50198. +International Ltd. and/or its affiliates ("Marvell") under the following
  50199. +alternative licensing terms. Once you have made an election to distribute the
  50200. +File under one of the following license alternatives, please (i) delete this
  50201. +introductory statement regarding license alternatives, (ii) delete the two
  50202. +license alternatives that you have not elected to use and (iii) preserve the
  50203. +Marvell copyright notice above.
  50204. +
  50205. +********************************************************************************
  50206. +Marvell Commercial License Option
  50207. +
  50208. +If you received this File from Marvell and you have entered into a commercial
  50209. +license agreement (a "Commercial License") with Marvell, the File is licensed
  50210. +to you under the terms of the applicable Commercial License.
  50211. +
  50212. +********************************************************************************
  50213. +Marvell GPL License Option
  50214. +
  50215. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50216. +modify this File in accordance with the terms and conditions of the General
  50217. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50218. +available along with the File in the license.txt file or by writing to the Free
  50219. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50220. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50221. +
  50222. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50223. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50224. +DISCLAIMED. The GPL License provides additional details about this warranty
  50225. +disclaimer.
  50226. +********************************************************************************
  50227. +Marvell BSD License Option
  50228. +
  50229. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50230. +modify this File under the following licensing terms.
  50231. +Redistribution and use in source and binary forms, with or without modification,
  50232. +are permitted provided that the following conditions are met:
  50233. +
  50234. + * Redistributions of source code must retain the above copyright notice,
  50235. + this list of conditions and the following disclaimer.
  50236. +
  50237. + * Redistributions in binary form must reproduce the above copyright
  50238. + notice, this list of conditions and the following disclaimer in the
  50239. + documentation and/or other materials provided with the distribution.
  50240. +
  50241. + * Neither the name of Marvell nor the names of its contributors may be
  50242. + used to endorse or promote products derived from this software without
  50243. + specific prior written permission.
  50244. +
  50245. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  50246. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  50247. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  50248. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  50249. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  50250. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  50251. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  50252. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50253. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  50254. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50255. +
  50256. +*******************************************************************************/
  50257. +
  50258. +#include "xor/mvXor.h"
  50259. +#include "mvSysXor.h"
  50260. +
  50261. +/* defines */
  50262. +#ifdef MV_DEBUG
  50263. + #define DB(x) x
  50264. +#else
  50265. + #define DB(x)
  50266. +#endif
  50267. +
  50268. +
  50269. +static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  50270. +
  50271. +MV_TARGET xorAddrDecPrioTap[] =
  50272. +{
  50273. +#if defined(MV_INCLUDE_DEVICE_CS0)
  50274. + DEVICE_CS0,
  50275. +#endif
  50276. +#if defined(MV_INCLUDE_PEX)
  50277. + PEX0_MEM,
  50278. +#endif
  50279. +#if defined(MV_INCLUDE_SDRAM_CS0)
  50280. + SDRAM_CS0,
  50281. +#endif
  50282. +#if defined(MV_INCLUDE_SDRAM_CS1)
  50283. + SDRAM_CS1,
  50284. +#endif
  50285. +#if defined(MV_INCLUDE_SDRAM_CS2)
  50286. + SDRAM_CS2,
  50287. +#endif
  50288. +#if defined(MV_INCLUDE_SDRAM_CS3)
  50289. + SDRAM_CS3,
  50290. +#endif
  50291. +#if defined(MV_INCLUDE_DEVICE_CS1)
  50292. + DEVICE_CS1,
  50293. +#endif
  50294. +#if defined(MV_INCLUDE_CESA)
  50295. + CRYPT_ENG,
  50296. +#endif
  50297. + TBL_TERM
  50298. +};
  50299. +static MV_STATUS mvXorInitWinsUnit (MV_U32 unit)
  50300. +{
  50301. + MV_U32 winNum;
  50302. + MV_XOR_DEC_WIN addrDecWin;
  50303. + MV_CPU_DEC_WIN cpuAddrDecWin;
  50304. + MV_U32 status;
  50305. + MV_U32 winPrioIndex=0;
  50306. +
  50307. + /* Initiate XOR address decode */
  50308. +
  50309. + /* First disable all address decode windows */
  50310. + for(winNum = 0; winNum < XOR_MAX_ADDR_DEC_WIN; winNum++)
  50311. + {
  50312. + mvXorTargetWinEnable(unit,winNum, MV_FALSE);
  50313. + }
  50314. +
  50315. + /* Go through all windows in user table until table terminator */
  50316. + for (winNum = 0; ((xorAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  50317. + (winNum < XOR_MAX_ADDR_DEC_WIN));)
  50318. + {
  50319. + /* first get attributes from CPU If */
  50320. + status = mvCpuIfTargetWinGet(xorAddrDecPrioTap[winPrioIndex],
  50321. + &cpuAddrDecWin);
  50322. +
  50323. + if(MV_NO_SUCH == status)
  50324. + {
  50325. + winPrioIndex++;
  50326. + continue;
  50327. + }
  50328. + if (MV_OK != status)
  50329. + {
  50330. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  50331. + return MV_ERROR;
  50332. + }
  50333. +
  50334. +
  50335. + if (cpuAddrDecWin.enable == MV_TRUE)
  50336. + {
  50337. +
  50338. + addrDecWin.target = xorAddrDecPrioTap[winPrioIndex];
  50339. + addrDecWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  50340. + addrDecWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  50341. + addrDecWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  50342. + addrDecWin.enable = MV_TRUE;
  50343. +
  50344. + if (MV_OK != mvXorTargetWinSet(unit,winNum, &addrDecWin))
  50345. + {
  50346. + DB(mvOsPrintf("mvXorInit: ERR. mvDmaTargetWinSet failed\n"));
  50347. + return MV_ERROR;
  50348. + }
  50349. + winNum++;
  50350. + }
  50351. + winPrioIndex++;
  50352. +
  50353. + }
  50354. +
  50355. + return MV_OK;
  50356. +}
  50357. +
  50358. +
  50359. +/*******************************************************************************
  50360. +* mvXorInit - Initialize XOR engine
  50361. +*
  50362. +* DESCRIPTION:
  50363. +* This function initialize XOR unit. It set the default address decode
  50364. +* windows of the unit.
  50365. +* Note that if the address window is disabled in xorAddrDecMap, the
  50366. +* window parameters will be set but the window will remain disabled.
  50367. +*
  50368. +* INPUT:
  50369. +* None.
  50370. +*
  50371. +* OUTPUT:
  50372. +* None.
  50373. +*
  50374. +* RETURN:
  50375. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  50376. +*******************************************************************************/
  50377. +MV_STATUS mvXorInit (MV_VOID)
  50378. +{
  50379. + MV_U32 i;
  50380. +
  50381. + /* Initiate XOR address decode */
  50382. + for(i = 0; i < MV_XOR_MAX_UNIT; i++)
  50383. + mvXorInitWinsUnit(i);
  50384. +
  50385. + mvXorHalInit(MV_XOR_MAX_CHAN);
  50386. +
  50387. + return MV_OK;
  50388. +}
  50389. +
  50390. +/*******************************************************************************
  50391. +* mvXorTargetWinSet - Set XOR target address window
  50392. +*
  50393. +* DESCRIPTION:
  50394. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  50395. +* address window. After setting this target window, the XOR will be
  50396. +* able to access the target within the address window.
  50397. +*
  50398. +* INPUT:
  50399. +* winNum - One of the possible XOR memory decode windows.
  50400. +* target - Peripheral target enumerator.
  50401. +* base - Window base address.
  50402. +* size - Window size.
  50403. +* enable - Window enable/disable.
  50404. +*
  50405. +* OUTPUT:
  50406. +* None.
  50407. +*
  50408. +* RETURN:
  50409. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  50410. +*
  50411. +*******************************************************************************/
  50412. +MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)
  50413. +{
  50414. + MV_DEC_REGS xorDecRegs;
  50415. + MV_TARGET_ATTRIB targetAttribs;
  50416. + MV_U32 chan;
  50417. +
  50418. + /* Parameter checking */
  50419. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  50420. + {
  50421. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum));
  50422. + return MV_BAD_PARAM;
  50423. + }
  50424. + if (pAddrDecWin == NULL)
  50425. + {
  50426. + DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));
  50427. + return MV_BAD_PTR;
  50428. + }
  50429. + /* Check if the requested window overlaps with current windows */
  50430. + if (MV_TRUE == xorWinOverlapDetect(unit, winNum, &pAddrDecWin->addrWin))
  50431. + {
  50432. + DB(mvOsPrintf("%s: ERR. Window %d overlap\n",__FUNCTION__,winNum));
  50433. + return MV_ERROR;
  50434. + }
  50435. +
  50436. + xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));
  50437. + xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));
  50438. +
  50439. + /* Get Base Address and size registers values */
  50440. + if(MV_OK != mvCtrlAddrDecToReg(&pAddrDecWin->addrWin, &xorDecRegs))
  50441. + {
  50442. + DB(mvOsPrintf("%s: ERR. Invalid addr dec window\n",__FUNCTION__));
  50443. + return MV_BAD_PARAM;
  50444. + }
  50445. +
  50446. +
  50447. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  50448. +
  50449. + /* set attributes */
  50450. + xorDecRegs.baseReg &= ~XEBARX_ATTR_MASK;
  50451. + xorDecRegs.baseReg |= targetAttribs.attrib << XEBARX_ATTR_OFFS;
  50452. + /* set target ID */
  50453. + xorDecRegs.baseReg &= ~XEBARX_TARGET_MASK;
  50454. + xorDecRegs.baseReg |= targetAttribs.targetId << XEBARX_TARGET_OFFS;
  50455. +
  50456. +
  50457. + /* Write to address decode Base Address Register */
  50458. + MV_REG_WRITE(XOR_BASE_ADDR_REG(unit,winNum), xorDecRegs.baseReg);
  50459. +
  50460. + /* Write to Size Register */
  50461. + MV_REG_WRITE(XOR_SIZE_MASK_REG(unit,winNum), xorDecRegs.sizeReg);
  50462. +
  50463. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  50464. + {
  50465. + if (pAddrDecWin->enable)
  50466. + {
  50467. + MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
  50468. + XEXWCR_WIN_EN_MASK(winNum));
  50469. + }
  50470. + else
  50471. + {
  50472. + MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
  50473. + XEXWCR_WIN_EN_MASK(winNum));
  50474. + }
  50475. + }
  50476. + return MV_OK;
  50477. +}
  50478. +
  50479. +/*******************************************************************************
  50480. +* mvXorTargetWinGet - Get xor peripheral target address window.
  50481. +*
  50482. +* DESCRIPTION:
  50483. +* Get xor peripheral target address window.
  50484. +*
  50485. +* INPUT:
  50486. +* winNum - One of the possible XOR memory decode windows.
  50487. +*
  50488. +* OUTPUT:
  50489. +* base - Window base address.
  50490. +* size - Window size.
  50491. +* enable - window enable/disable.
  50492. +*
  50493. +* RETURN:
  50494. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  50495. +*
  50496. +*******************************************************************************/
  50497. +MV_STATUS mvXorTargetWinGet(MV_U32 unit,MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)
  50498. +{
  50499. + MV_DEC_REGS xorDecRegs;
  50500. + MV_TARGET_ATTRIB targetAttrib;
  50501. + MV_U32 chan=0,chanWinEn;
  50502. +
  50503. + /* Parameter checking */
  50504. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  50505. + {
  50506. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__ , winNum));
  50507. + return MV_ERROR;
  50508. + }
  50509. +
  50510. + if (NULL == pAddrDecWin)
  50511. + {
  50512. + DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));
  50513. + return MV_BAD_PTR;
  50514. + }
  50515. +
  50516. + chanWinEn = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,0)) & XEXWCR_WIN_EN_MASK(winNum);
  50517. +
  50518. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++) /* we should scan here all channels per unit */
  50519. + {
  50520. + /* Check if enable bit is equal for all channels */
  50521. + if ((MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) &
  50522. + XEXWCR_WIN_EN_MASK(winNum)) != chanWinEn)
  50523. + {
  50524. + mvOsPrintf("%s: ERR. Window enable field must be equal in "
  50525. + "all channels(chan=%d)\n",__FUNCTION__, chan);
  50526. + return MV_ERROR;
  50527. + }
  50528. + }
  50529. +
  50530. +
  50531. +
  50532. + xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));
  50533. + xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));
  50534. +
  50535. + if (MV_OK != mvCtrlRegToAddrDec(&xorDecRegs, &pAddrDecWin->addrWin))
  50536. + {
  50537. + mvOsPrintf("%s: ERR. mvCtrlRegToAddrDec failed\n", __FUNCTION__);
  50538. + return MV_ERROR;
  50539. + }
  50540. +
  50541. + /* attrib and targetId */
  50542. + targetAttrib.attrib =
  50543. + (xorDecRegs.baseReg & XEBARX_ATTR_MASK) >> XEBARX_ATTR_OFFS;
  50544. + targetAttrib.targetId =
  50545. + (xorDecRegs.baseReg & XEBARX_TARGET_MASK) >> XEBARX_TARGET_OFFS;
  50546. +
  50547. +
  50548. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  50549. +
  50550. + if(chanWinEn)
  50551. + {
  50552. + pAddrDecWin->enable = MV_TRUE;
  50553. + }
  50554. + else pAddrDecWin->enable = MV_FALSE;
  50555. +
  50556. + return MV_OK;
  50557. +}
  50558. +
  50559. +/*******************************************************************************
  50560. +* mvXorTargetWinEnable - Enable/disable a Xor address decode window
  50561. +*
  50562. +* DESCRIPTION:
  50563. +* This function enable/disable a XOR address decode window.
  50564. +* if parameter 'enable' == MV_TRUE the routine will enable the
  50565. +* window, thus enabling XOR accesses (before enabling the window it is
  50566. +* tested for overlapping). Otherwise, the window will be disabled.
  50567. +*
  50568. +* INPUT:
  50569. +* winNum - Decode window number.
  50570. +* enable - Enable/disable parameter.
  50571. +*
  50572. +* OUTPUT:
  50573. +* None.
  50574. +*
  50575. +* RETURN:
  50576. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  50577. +*
  50578. +*******************************************************************************/
  50579. +MV_STATUS mvXorTargetWinEnable(MV_U32 unit,MV_U32 winNum, MV_BOOL enable)
  50580. +{
  50581. + MV_XOR_DEC_WIN addrDecWin;
  50582. + MV_U32 chan;
  50583. +
  50584. + /* Parameter checking */
  50585. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  50586. + {
  50587. + DB(mvOsPrintf("%s: ERR. Invalid winNum%d\n", __FUNCTION__, winNum));
  50588. + return MV_ERROR;
  50589. + }
  50590. +
  50591. + if (enable == MV_TRUE)
  50592. + {
  50593. + /* Get current window */
  50594. + if (MV_OK != mvXorTargetWinGet(unit,winNum, &addrDecWin))
  50595. + {
  50596. + DB(mvOsPrintf("%s: ERR. targetWinGet fail\n", __FUNCTION__));
  50597. + return MV_ERROR;
  50598. + }
  50599. +
  50600. + /* Check for overlapping */
  50601. + if (MV_TRUE == xorWinOverlapDetect(unit,winNum, &(addrDecWin.addrWin)))
  50602. + {
  50603. + /* Overlap detected */
  50604. + DB(mvOsPrintf("%s: ERR. Overlap detected\n", __FUNCTION__));
  50605. + return MV_ERROR;
  50606. + }
  50607. +
  50608. + /* No Overlap. Enable address decode target window */
  50609. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  50610. + {
  50611. + MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
  50612. + XEXWCR_WIN_EN_MASK(winNum));
  50613. + }
  50614. +
  50615. + }
  50616. + else
  50617. + {
  50618. + /* Disable address decode target window */
  50619. +
  50620. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  50621. + {
  50622. + MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
  50623. + XEXWCR_WIN_EN_MASK(winNum));
  50624. + }
  50625. +
  50626. + }
  50627. +
  50628. + return MV_OK;
  50629. +}
  50630. +
  50631. +/*******************************************************************************
  50632. +* mvXorSetProtWinSet - Configure access attributes of a XOR engine
  50633. +* to one of the XOR memory windows.
  50634. +*
  50635. +* DESCRIPTION:
  50636. +* Each engine can be configured with access attributes for each of the
  50637. +* memory spaces. This function sets access attributes
  50638. +* to a given window for the given engine
  50639. +*
  50640. +* INPUTS:
  50641. +* chan - One of the possible engines.
  50642. +* winNum - One of the possible XOR memory spaces.
  50643. +* access - Protection access rights.
  50644. +* write - Write rights.
  50645. +*
  50646. +* OUTPUT:
  50647. +* None.
  50648. +*
  50649. +* RETURN:
  50650. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  50651. +*
  50652. +*******************************************************************************/
  50653. +MV_STATUS mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access,
  50654. + MV_BOOL write)
  50655. +{
  50656. + MV_U32 temp;
  50657. +
  50658. + /* Parameter checking */
  50659. + if (chan >= MV_XOR_MAX_CHAN_PER_UNIT)
  50660. + {
  50661. + DB(mvOsPrintf("%s: ERR. Invalid chan num %d\n", __FUNCTION__ , chan));
  50662. + return MV_BAD_PARAM;
  50663. + }
  50664. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  50665. + {
  50666. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));
  50667. + return MV_BAD_PARAM;
  50668. + }
  50669. +
  50670. + temp = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) &
  50671. + (~XEXWCR_WIN_ACC_MASK(winNum));
  50672. +
  50673. + /* if access is disable */
  50674. + if (!access)
  50675. + {
  50676. + /* disable access */
  50677. + temp |= XEXWCR_WIN_ACC_NO_ACC(winNum);
  50678. + }
  50679. + /* if access is enable */
  50680. + else
  50681. + {
  50682. + /* if write is enable */
  50683. + if (write)
  50684. + {
  50685. + /* enable write */
  50686. + temp |= XEXWCR_WIN_ACC_RW(winNum);
  50687. + }
  50688. + /* if write is disable */
  50689. + else
  50690. + {
  50691. + /* disable write */
  50692. + temp |= XEXWCR_WIN_ACC_RO(winNum);
  50693. + }
  50694. + }
  50695. + MV_REG_WRITE(XOR_WINDOW_CTRL_REG(unit,chan),temp);
  50696. + return MV_OK;
  50697. +}
  50698. +
  50699. +/*******************************************************************************
  50700. +* mvXorPciRemap - Set XOR remap register for PCI address windows.
  50701. +*
  50702. +* DESCRIPTION:
  50703. +* only Windows 0-3 can be remapped.
  50704. +*
  50705. +* INPUT:
  50706. +* winNum - window number
  50707. +* pAddrDecWin - pointer to address space window structure
  50708. +* OUTPUT:
  50709. +* None.
  50710. +*
  50711. +* RETURN:
  50712. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  50713. +*
  50714. +*******************************************************************************/
  50715. +MV_STATUS mvXorPciRemap(MV_U32 unit,MV_U32 winNum, MV_U32 addrHigh)
  50716. +{
  50717. + /* Parameter checking */
  50718. + if (winNum >= XOR_MAX_REMAP_WIN)
  50719. + {
  50720. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));
  50721. + return MV_BAD_PARAM;
  50722. + }
  50723. +
  50724. + MV_REG_WRITE(XOR_HIGH_ADDR_REMAP_REG(unit,winNum), addrHigh);
  50725. +
  50726. + return MV_OK;
  50727. +}
  50728. +
  50729. +/*******************************************************************************
  50730. +* xorWinOverlapDetect - Detect XOR address windows overlaping
  50731. +*
  50732. +* DESCRIPTION:
  50733. +* An unpredicted behaviour is expected in case XOR address decode
  50734. +* windows overlaps.
  50735. +* This function detects XOR address decode windows overlaping of a
  50736. +* specified window. The function does not check the window itself for
  50737. +* overlaping. The function also skipps disabled address decode windows.
  50738. +*
  50739. +* INPUT:
  50740. +* winNum - address decode window number.
  50741. +* pAddrDecWin - An address decode window struct.
  50742. +*
  50743. +* OUTPUT:
  50744. +* None.
  50745. +*
  50746. +* RETURN:
  50747. +* MV_TRUE if the given address window overlap current address
  50748. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  50749. +* from registers.
  50750. +*
  50751. +*******************************************************************************/
  50752. +static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  50753. +{
  50754. + MV_U32 baseAddrEnableReg;
  50755. + MV_U32 winNumIndex,chan;
  50756. + MV_XOR_DEC_WIN addrDecWin;
  50757. +
  50758. + if (pAddrWin == NULL)
  50759. + {
  50760. + DB(mvOsPrintf("%s: ERR. pAddrWin is NULL pointer\n", __FUNCTION__ ));
  50761. + return MV_BAD_PTR;
  50762. + }
  50763. +
  50764. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  50765. + {
  50766. + /* Read base address enable register. Do not check disabled windows */
  50767. + baseAddrEnableReg = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan));
  50768. +
  50769. + for (winNumIndex = 0; winNumIndex < XOR_MAX_ADDR_DEC_WIN; winNumIndex++)
  50770. + {
  50771. + /* Do not check window itself */
  50772. + if (winNumIndex == winNum)
  50773. + {
  50774. + continue;
  50775. + }
  50776. +
  50777. + /* Do not check disabled windows */
  50778. + if ((baseAddrEnableReg & XEXWCR_WIN_EN_MASK(winNumIndex)) == 0)
  50779. + {
  50780. + continue;
  50781. + }
  50782. +
  50783. + /* Get window parameters */
  50784. + if (MV_OK != mvXorTargetWinGet(unit,winNumIndex, &addrDecWin))
  50785. + {
  50786. + DB(mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__ ));
  50787. + return MV_ERROR;
  50788. + }
  50789. +
  50790. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  50791. + {
  50792. + return MV_TRUE;
  50793. + }
  50794. + }
  50795. + }
  50796. +
  50797. + return MV_FALSE;
  50798. +}
  50799. +
  50800. +static MV_VOID mvXorAddrDecShowUnit(MV_U32 unit)
  50801. +{
  50802. + MV_XOR_DEC_WIN win;
  50803. + int i;
  50804. +
  50805. + mvOsOutput( "\n" );
  50806. + mvOsOutput( "XOR %d:\n", unit );
  50807. + mvOsOutput( "----\n" );
  50808. +
  50809. + for( i = 0; i < XOR_MAX_ADDR_DEC_WIN; i++ )
  50810. + {
  50811. + memset( &win, 0, sizeof(MV_XOR_DEC_WIN) );
  50812. +
  50813. + mvOsOutput( "win%d - ", i );
  50814. +
  50815. + if( mvXorTargetWinGet(unit, i, &win ) == MV_OK )
  50816. + {
  50817. + if( win.enable )
  50818. + {
  50819. + mvOsOutput( "%s base %x, ",
  50820. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  50821. +
  50822. + mvSizePrint( win.addrWin.size );
  50823. +
  50824. + mvOsOutput( "\n" );
  50825. + }
  50826. + else
  50827. + mvOsOutput( "disable\n" );
  50828. + }
  50829. + }
  50830. +}
  50831. +
  50832. +/*******************************************************************************
  50833. +* mvXorAddrDecShow - Print the XOR address decode map.
  50834. +*
  50835. +* DESCRIPTION:
  50836. +* This function print the XOR address decode map.
  50837. +*
  50838. +* INPUT:
  50839. +* None.
  50840. +*
  50841. +* OUTPUT:
  50842. +* None.
  50843. +*
  50844. +* RETURN:
  50845. +* None.
  50846. +*
  50847. +*******************************************************************************/
  50848. +MV_VOID mvXorAddrDecShow(MV_VOID)
  50849. +{
  50850. + int i;
  50851. +
  50852. + for( i = 0; i < MV_XOR_MAX_UNIT; i++ )
  50853. + mvXorAddrDecShowUnit(i);
  50854. +
  50855. +}
  50856. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h
  50857. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h 1970-01-01 01:00:00.000000000 +0100
  50858. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h 2011-07-31 11:31:58.703940068 +0200
  50859. @@ -0,0 +1,140 @@
  50860. +/*******************************************************************************
  50861. +Copyright (C) Marvell International Ltd. and its affiliates
  50862. +
  50863. +This software file (the "File") is owned and distributed by Marvell
  50864. +International Ltd. and/or its affiliates ("Marvell") under the following
  50865. +alternative licensing terms. Once you have made an election to distribute the
  50866. +File under one of the following license alternatives, please (i) delete this
  50867. +introductory statement regarding license alternatives, (ii) delete the two
  50868. +license alternatives that you have not elected to use and (iii) preserve the
  50869. +Marvell copyright notice above.
  50870. +
  50871. +********************************************************************************
  50872. +Marvell Commercial License Option
  50873. +
  50874. +If you received this File from Marvell and you have entered into a commercial
  50875. +license agreement (a "Commercial License") with Marvell, the File is licensed
  50876. +to you under the terms of the applicable Commercial License.
  50877. +
  50878. +********************************************************************************
  50879. +Marvell GPL License Option
  50880. +
  50881. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50882. +modify this File in accordance with the terms and conditions of the General
  50883. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50884. +available along with the File in the license.txt file or by writing to the Free
  50885. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50886. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50887. +
  50888. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50889. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50890. +DISCLAIMED. The GPL License provides additional details about this warranty
  50891. +disclaimer.
  50892. +********************************************************************************
  50893. +Marvell BSD License Option
  50894. +
  50895. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50896. +modify this File under the following licensing terms.
  50897. +Redistribution and use in source and binary forms, with or without modification,
  50898. +are permitted provided that the following conditions are met:
  50899. +
  50900. + * Redistributions of source code must retain the above copyright notice,
  50901. + this list of conditions and the following disclaimer.
  50902. +
  50903. + * Redistributions in binary form must reproduce the above copyright
  50904. + notice, this list of conditions and the following disclaimer in the
  50905. + documentation and/or other materials provided with the distribution.
  50906. +
  50907. + * Neither the name of Marvell nor the names of its contributors may be
  50908. + used to endorse or promote products derived from this software without
  50909. + specific prior written permission.
  50910. +
  50911. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  50912. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  50913. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  50914. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  50915. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  50916. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  50917. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  50918. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50919. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  50920. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50921. +
  50922. +*******************************************************************************/
  50923. +
  50924. +#ifndef __INCMVSysXorh
  50925. +#define __INCMVSysXorh
  50926. +
  50927. +
  50928. +#ifdef __cplusplus
  50929. +extern "C" {
  50930. +#endif
  50931. +
  50932. +#include "ctrlEnv/sys/mvCpuIf.h"
  50933. +
  50934. +#include "ctrlEnv/mvCtrlEnvLib.h"
  50935. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  50936. +
  50937. +#define XOR_MAX_ADDR_DEC_WIN 8 /* Maximum address decode windows */
  50938. +#define XOR_MAX_REMAP_WIN 4 /* Maximum address arbiter windows */
  50939. +
  50940. +/* XOR Engine Address Decoding Register Map */
  50941. +#define XOR_WINDOW_CTRL_REG(unit,chan) (XOR_UNIT_BASE(unit)+(0x240 + ((chan) * 4)))
  50942. +#define XOR_BASE_ADDR_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x250 + ((winNum) * 4)))
  50943. +#define XOR_SIZE_MASK_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x270 + ((winNum) * 4)))
  50944. +#define XOR_HIGH_ADDR_REMAP_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x290 + ((winNum) * 4)))
  50945. +
  50946. +/* XOR Engine [0..1] Window Control Registers (XExWCR) */
  50947. +#define XEXWCR_WIN_EN_OFFS(winNum) (winNum)
  50948. +#define XEXWCR_WIN_EN_MASK(winNum) (1 << (XEXWCR_WIN_EN_OFFS(winNum)))
  50949. +#define XEXWCR_WIN_EN_ENABLE(winNum) (1 << (XEXWCR_WIN_EN_OFFS(winNum)))
  50950. +#define XEXWCR_WIN_EN_DISABLE(winNum) (0 << (XEXWCR_WIN_EN_OFFS(winNum)))
  50951. +
  50952. +#define XEXWCR_WIN_ACC_OFFS(winNum) ((2 * winNum) + 16)
  50953. +#define XEXWCR_WIN_ACC_MASK(winNum) (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  50954. +#define XEXWCR_WIN_ACC_NO_ACC(winNum) (0 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  50955. +#define XEXWCR_WIN_ACC_RO(winNum) (1 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  50956. +#define XEXWCR_WIN_ACC_RW(winNum) (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  50957. +
  50958. +/* XOR Engine Base Address Registers (XEBARx) */
  50959. +#define XEBARX_TARGET_OFFS (0)
  50960. +#define XEBARX_TARGET_MASK (0xF << XEBARX_TARGET_OFFS)
  50961. +#define XEBARX_ATTR_OFFS (8)
  50962. +#define XEBARX_ATTR_MASK (0xFF << XEBARX_ATTR_OFFS)
  50963. +#define XEBARX_BASE_OFFS (16)
  50964. +#define XEBARX_BASE_MASK (0xFFFF << XEBARX_BASE_OFFS)
  50965. +
  50966. +/* XOR Engine Size Mask Registers (XESMRx) */
  50967. +#define XESMRX_SIZE_MASK_OFFS (16)
  50968. +#define XESMRX_SIZE_MASK_MASK (0xFFFF << XESMRX_SIZE_MASK_OFFS)
  50969. +
  50970. +/* XOR Engine High Address Remap Register (XEHARRx1) */
  50971. +#define XEHARRX_REMAP_OFFS (0)
  50972. +#define XEHARRX_REMAP_MASK (0xFFFFFFFF << XEHARRX_REMAP_OFFS)
  50973. +
  50974. +typedef struct _mvXorDecWin
  50975. +{
  50976. + MV_TARGET target;
  50977. + MV_ADDR_WIN addrWin; /* An address window*/
  50978. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  50979. +
  50980. +}MV_XOR_DEC_WIN;
  50981. +
  50982. +MV_STATUS mvXorInit (MV_VOID);
  50983. +MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum,
  50984. + MV_XOR_DEC_WIN *pAddrDecWin);
  50985. +MV_STATUS mvXorTargetWinGet(MV_U32 unit, MV_U32 winNum,
  50986. + MV_XOR_DEC_WIN *pAddrDecWin);
  50987. +MV_STATUS mvXorTargetWinEnable(MV_U32 unit,
  50988. + MV_U32 winNum, MV_BOOL enable);
  50989. +MV_STATUS mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access,
  50990. + MV_BOOL write);
  50991. +MV_STATUS mvXorPciRemap(MV_U32 unit, MV_U32 winNum, MV_U32 addrHigh);
  50992. +
  50993. +MV_VOID mvXorAddrDecShow(MV_VOID);
  50994. +
  50995. +#ifdef __cplusplus
  50996. +}
  50997. +#endif
  50998. +
  50999. +#endif
  51000. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c
  51001. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c 1970-01-01 01:00:00.000000000 +0100
  51002. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c 2011-07-31 11:31:58.773480789 +0200
  51003. @@ -0,0 +1,75 @@
  51004. +/*******************************************************************************
  51005. +Copyright (C) Marvell International Ltd. and its affiliates
  51006. +
  51007. +This software file (the "File") is owned and distributed by Marvell
  51008. +International Ltd. and/or its affiliates ("Marvell") under the following
  51009. +alternative licensing terms. Once you have made an election to distribute the
  51010. +File under one of the following license alternatives, please (i) delete this
  51011. +introductory statement regarding license alternatives, (ii) delete the two
  51012. +license alternatives that you have not elected to use and (iii) preserve the
  51013. +Marvell copyright notice above.
  51014. +
  51015. +********************************************************************************
  51016. +Marvell Commercial License Option
  51017. +
  51018. +If you received this File from Marvell and you have entered into a commercial
  51019. +license agreement (a "Commercial License") with Marvell, the File is licensed
  51020. +to you under the terms of the applicable Commercial License.
  51021. +
  51022. +********************************************************************************
  51023. +Marvell GPL License Option
  51024. +
  51025. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51026. +modify this File in accordance with the terms and conditions of the General
  51027. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51028. +available along with the File in the license.txt file or by writing to the Free
  51029. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51030. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51031. +
  51032. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51033. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51034. +DISCLAIMED. The GPL License provides additional details about this warranty
  51035. +disclaimer.
  51036. +********************************************************************************
  51037. +Marvell BSD License Option
  51038. +
  51039. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51040. +modify this File under the following licensing terms.
  51041. +Redistribution and use in source and binary forms, with or without modification,
  51042. +are permitted provided that the following conditions are met:
  51043. +
  51044. + * Redistributions of source code must retain the above copyright notice,
  51045. + this list of conditions and the following disclaimer.
  51046. +
  51047. + * Redistributions in binary form must reproduce the above copyright
  51048. + notice, this list of conditions and the following disclaimer in the
  51049. + documentation and/or other materials provided with the distribution.
  51050. +
  51051. + * Neither the name of Marvell nor the names of its contributors may be
  51052. + used to endorse or promote products derived from this software without
  51053. + specific prior written permission.
  51054. +
  51055. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  51056. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  51057. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  51058. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  51059. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  51060. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  51061. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  51062. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51063. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  51064. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51065. +
  51066. +*******************************************************************************/
  51067. +
  51068. +#include "device/mvDevice.h"
  51069. +
  51070. +/* defines */
  51071. +#ifdef MV_DEBUG
  51072. + #define DB(x) x
  51073. +#else
  51074. + #define DB(x)
  51075. +#endif
  51076. +
  51077. +
  51078. +
  51079. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h
  51080. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h 1970-01-01 01:00:00.000000000 +0100
  51081. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h 2011-07-31 11:31:58.833424302 +0200
  51082. @@ -0,0 +1,74 @@
  51083. +/*******************************************************************************
  51084. +Copyright (C) Marvell International Ltd. and its affiliates
  51085. +
  51086. +This software file (the "File") is owned and distributed by Marvell
  51087. +International Ltd. and/or its affiliates ("Marvell") under the following
  51088. +alternative licensing terms. Once you have made an election to distribute the
  51089. +File under one of the following license alternatives, please (i) delete this
  51090. +introductory statement regarding license alternatives, (ii) delete the two
  51091. +license alternatives that you have not elected to use and (iii) preserve the
  51092. +Marvell copyright notice above.
  51093. +
  51094. +********************************************************************************
  51095. +Marvell Commercial License Option
  51096. +
  51097. +If you received this File from Marvell and you have entered into a commercial
  51098. +license agreement (a "Commercial License") with Marvell, the File is licensed
  51099. +to you under the terms of the applicable Commercial License.
  51100. +
  51101. +********************************************************************************
  51102. +Marvell GPL License Option
  51103. +
  51104. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51105. +modify this File in accordance with the terms and conditions of the General
  51106. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51107. +available along with the File in the license.txt file or by writing to the Free
  51108. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51109. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51110. +
  51111. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51112. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51113. +DISCLAIMED. The GPL License provides additional details about this warranty
  51114. +disclaimer.
  51115. +********************************************************************************
  51116. +Marvell BSD License Option
  51117. +
  51118. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51119. +modify this File under the following licensing terms.
  51120. +Redistribution and use in source and binary forms, with or without modification,
  51121. +are permitted provided that the following conditions are met:
  51122. +
  51123. + * Redistributions of source code must retain the above copyright notice,
  51124. + this list of conditions and the following disclaimer.
  51125. +
  51126. + * Redistributions in binary form must reproduce the above copyright
  51127. + notice, this list of conditions and the following disclaimer in the
  51128. + documentation and/or other materials provided with the distribution.
  51129. +
  51130. + * Neither the name of Marvell nor the names of its contributors may be
  51131. + used to endorse or promote products derived from this software without
  51132. + specific prior written permission.
  51133. +
  51134. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  51135. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  51136. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  51137. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  51138. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  51139. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  51140. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  51141. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51142. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  51143. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51144. +
  51145. +*******************************************************************************/
  51146. +
  51147. +#ifndef __INCmvDeviceH
  51148. +#define __INCmvDeviceH
  51149. +
  51150. +#include "mvCommon.h"
  51151. +#include "mvOs.h"
  51152. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  51153. +#include "device/mvDeviceRegs.h"
  51154. +
  51155. +
  51156. +#endif /* #ifndef __INCmvDeviceH */
  51157. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h
  51158. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h 1970-01-01 01:00:00.000000000 +0100
  51159. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h 2011-07-31 11:31:58.893415953 +0200
  51160. @@ -0,0 +1,101 @@
  51161. +/*******************************************************************************
  51162. +Copyright (C) Marvell International Ltd. and its affiliates
  51163. +
  51164. +This software file (the "File") is owned and distributed by Marvell
  51165. +International Ltd. and/or its affiliates ("Marvell") under the following
  51166. +alternative licensing terms. Once you have made an election to distribute the
  51167. +File under one of the following license alternatives, please (i) delete this
  51168. +introductory statement regarding license alternatives, (ii) delete the two
  51169. +license alternatives that you have not elected to use and (iii) preserve the
  51170. +Marvell copyright notice above.
  51171. +
  51172. +********************************************************************************
  51173. +Marvell Commercial License Option
  51174. +
  51175. +If you received this File from Marvell and you have entered into a commercial
  51176. +license agreement (a "Commercial License") with Marvell, the File is licensed
  51177. +to you under the terms of the applicable Commercial License.
  51178. +
  51179. +********************************************************************************
  51180. +Marvell GPL License Option
  51181. +
  51182. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51183. +modify this File in accordance with the terms and conditions of the General
  51184. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51185. +available along with the File in the license.txt file or by writing to the Free
  51186. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51187. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51188. +
  51189. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51190. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51191. +DISCLAIMED. The GPL License provides additional details about this warranty
  51192. +disclaimer.
  51193. +********************************************************************************
  51194. +Marvell BSD License Option
  51195. +
  51196. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51197. +modify this File under the following licensing terms.
  51198. +Redistribution and use in source and binary forms, with or without modification,
  51199. +are permitted provided that the following conditions are met:
  51200. +
  51201. + * Redistributions of source code must retain the above copyright notice,
  51202. + this list of conditions and the following disclaimer.
  51203. +
  51204. + * Redistributions in binary form must reproduce the above copyright
  51205. + notice, this list of conditions and the following disclaimer in the
  51206. + documentation and/or other materials provided with the distribution.
  51207. +
  51208. + * Neither the name of Marvell nor the names of its contributors may be
  51209. + used to endorse or promote products derived from this software without
  51210. + specific prior written permission.
  51211. +
  51212. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  51213. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  51214. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  51215. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  51216. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  51217. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  51218. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  51219. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51220. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  51221. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51222. +
  51223. +*******************************************************************************/
  51224. +
  51225. +#ifndef __INCmvDeviceRegsH
  51226. +#define __INCmvDeviceRegsH
  51227. +
  51228. +#ifndef MV_ASMLANGUAGE
  51229. +#include "ctrlEnv/mvCtrlEnvLib.h"
  51230. +/* This enumerator describes the Marvell controller possible devices that */
  51231. +/* can be connected to its device interface. */
  51232. +typedef enum _mvDevice
  51233. +{
  51234. +#if defined(MV_INCLUDE_DEVICE_CS0)
  51235. + DEV_CS0 = 0, /* Device connected to dev CS[0] */
  51236. +#endif
  51237. +#if defined(MV_INCLUDE_DEVICE_CS1)
  51238. + DEV_CS1 = 1, /* Device connected to dev CS[1] */
  51239. +#endif
  51240. +#if defined(MV_INCLUDE_DEVICE_CS2)
  51241. + DEV_CS2 = 2, /* Device connected to dev CS[2] */
  51242. +#endif
  51243. +#if defined(MV_INCLUDE_DEVICE_CS3)
  51244. + DEV_CS3 = 3, /* Device connected to dev CS[2] */
  51245. +#endif
  51246. +#if defined(MV_INCLUDE_DEVICE_CS4)
  51247. + DEV_CS4 = 4, /* Device connected to BOOT dev */
  51248. +#endif
  51249. + MV_DEV_MAX_CS = MV_DEVICE_MAX_CS
  51250. +}MV_DEVICE;
  51251. +
  51252. +
  51253. +#endif /* MV_ASMLANGUAGE */
  51254. +
  51255. +
  51256. +#define NAND_CTRL_REG 0x10470
  51257. +
  51258. +#define NAND_ACTCEBOOT_BIT BIT1
  51259. +
  51260. +
  51261. +#endif /* #ifndef __INCmvDeviceRegsH */
  51262. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c
  51263. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c 1970-01-01 01:00:00.000000000 +0100
  51264. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c 2011-07-31 11:31:58.983415088 +0200
  51265. @@ -0,0 +1,211 @@
  51266. +/*******************************************************************************
  51267. +Copyright (C) Marvell International Ltd. and its affiliates
  51268. +
  51269. +This software file (the "File") is owned and distributed by Marvell
  51270. +International Ltd. and/or its affiliates ("Marvell") under the following
  51271. +alternative licensing terms. Once you have made an election to distribute the
  51272. +File under one of the following license alternatives, please (i) delete this
  51273. +introductory statement regarding license alternatives, (ii) delete the two
  51274. +license alternatives that you have not elected to use and (iii) preserve the
  51275. +Marvell copyright notice above.
  51276. +
  51277. +
  51278. +********************************************************************************
  51279. +Marvell GPL License Option
  51280. +
  51281. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51282. +modify this File in accordance with the terms and conditions of the General
  51283. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51284. +available along with the File in the license.txt file or by writing to the Free
  51285. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51286. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51287. +
  51288. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51289. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51290. +DISCLAIMED. The GPL License provides additional details about this warranty
  51291. +disclaimer.
  51292. +*******************************************************************************/
  51293. +/*******************************************************************************
  51294. +* mvOsCpuArchLib.c - Marvell CPU architecture library
  51295. +*
  51296. +* DESCRIPTION:
  51297. +* This library introduce Marvell API for OS dependent CPU architecture
  51298. +* APIs. This library introduce single CPU architecture services APKI
  51299. +* cross OS.
  51300. +*
  51301. +* DEPENDENCIES:
  51302. +* None.
  51303. +*
  51304. +*******************************************************************************/
  51305. +
  51306. +/* includes */
  51307. +#include <asm/processor.h>
  51308. +#include "mvOs.h"
  51309. +
  51310. +static MV_U32 read_p15_c0 (void);
  51311. +
  51312. +/* defines */
  51313. +#define ARM_ID_REVISION_OFFS 0
  51314. +#define ARM_ID_REVISION_MASK (0xf << ARM_ID_REVISION_OFFS)
  51315. +
  51316. +#define ARM_ID_PART_NUM_OFFS 4
  51317. +#define ARM_ID_PART_NUM_MASK (0xfff << ARM_ID_PART_NUM_OFFS)
  51318. +
  51319. +#define ARM_ID_ARCH_OFFS 16
  51320. +#define ARM_ID_ARCH_MASK (0xf << ARM_ID_ARCH_OFFS)
  51321. +
  51322. +#define ARM_ID_VAR_OFFS 20
  51323. +#define ARM_ID_VAR_MASK (0xf << ARM_ID_VAR_OFFS)
  51324. +
  51325. +#define ARM_ID_ASCII_OFFS 24
  51326. +#define ARM_ID_ASCII_MASK (0xff << ARM_ID_ASCII_OFFS)
  51327. +
  51328. +
  51329. +
  51330. +void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,
  51331. + MV_U32 *memHandle)
  51332. +{
  51333. + void *p = kmalloc( size, GFP_KERNEL );
  51334. + *pPhyAddr = pci_map_single( osHandle, p, 0, PCI_DMA_BIDIRECTIONAL );
  51335. + return p;
  51336. +}
  51337. +void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,
  51338. + MV_U32 *memHandle)
  51339. +{
  51340. + return pci_alloc_consistent( osHandle, size, (dma_addr_t *)pPhyAddr );
  51341. +}
  51342. +
  51343. +void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,
  51344. + MV_U32 memHandle)
  51345. +{
  51346. + return pci_free_consistent( osHandle, size, pVirtAddr, (dma_addr_t)phyAddr );
  51347. +}
  51348. +
  51349. +void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,
  51350. + MV_U32 memHandle )
  51351. +{
  51352. + return kfree( pVirtAddr );
  51353. +}
  51354. +
  51355. +int mvOsRand(void)
  51356. +{
  51357. + int rand;
  51358. + get_random_bytes(&rand, sizeof(rand) );
  51359. + return rand;
  51360. +}
  51361. +
  51362. +/*******************************************************************************
  51363. +* mvOsCpuVerGet() -
  51364. +*
  51365. +* DESCRIPTION:
  51366. +*
  51367. +* INPUT:
  51368. +* None.
  51369. +*
  51370. +* OUTPUT:
  51371. +* None.
  51372. +*
  51373. +* RETURN:
  51374. +* 32bit CPU Revision
  51375. +*
  51376. +*******************************************************************************/
  51377. +MV_U32 mvOsCpuRevGet( MV_VOID )
  51378. +{
  51379. + return ((read_p15_c0() & ARM_ID_REVISION_MASK ) >> ARM_ID_REVISION_OFFS);
  51380. +}
  51381. +/*******************************************************************************
  51382. +* mvOsCpuPartGet() -
  51383. +*
  51384. +* DESCRIPTION:
  51385. +*
  51386. +* INPUT:
  51387. +* None.
  51388. +*
  51389. +* OUTPUT:
  51390. +* None.
  51391. +*
  51392. +* RETURN:
  51393. +* 32bit CPU Part number
  51394. +*
  51395. +*******************************************************************************/
  51396. +MV_U32 mvOsCpuPartGet( MV_VOID )
  51397. +{
  51398. + return ((read_p15_c0() & ARM_ID_PART_NUM_MASK ) >> ARM_ID_PART_NUM_OFFS);
  51399. +}
  51400. +/*******************************************************************************
  51401. +* mvOsCpuArchGet() -
  51402. +*
  51403. +* DESCRIPTION:
  51404. +*
  51405. +* INPUT:
  51406. +* None.
  51407. +*
  51408. +* OUTPUT:
  51409. +* None.
  51410. +*
  51411. +* RETURN:
  51412. +* 32bit CPU Architicture number
  51413. +*
  51414. +*******************************************************************************/
  51415. +MV_U32 mvOsCpuArchGet( MV_VOID )
  51416. +{
  51417. + return ((read_p15_c0() & ARM_ID_ARCH_MASK ) >> ARM_ID_ARCH_OFFS);
  51418. +}
  51419. +/*******************************************************************************
  51420. +* mvOsCpuVarGet() -
  51421. +*
  51422. +* DESCRIPTION:
  51423. +*
  51424. +* INPUT:
  51425. +* None.
  51426. +*
  51427. +* OUTPUT:
  51428. +* None.
  51429. +*
  51430. +* RETURN:
  51431. +* 32bit CPU Variant number
  51432. +*
  51433. +*******************************************************************************/
  51434. +MV_U32 mvOsCpuVarGet( MV_VOID )
  51435. +{
  51436. + return ((read_p15_c0() & ARM_ID_VAR_MASK ) >> ARM_ID_VAR_OFFS);
  51437. +}
  51438. +/*******************************************************************************
  51439. +* mvOsCpuAsciiGet() -
  51440. +*
  51441. +* DESCRIPTION:
  51442. +*
  51443. +* INPUT:
  51444. +* None.
  51445. +*
  51446. +* OUTPUT:
  51447. +* None.
  51448. +*
  51449. +* RETURN:
  51450. +* 32bit CPU Variant number
  51451. +*
  51452. +*******************************************************************************/
  51453. +MV_U32 mvOsCpuAsciiGet( MV_VOID )
  51454. +{
  51455. + return ((read_p15_c0() & ARM_ID_ASCII_MASK ) >> ARM_ID_ASCII_OFFS);
  51456. +}
  51457. +
  51458. +
  51459. +
  51460. +/*
  51461. +static unsigned long read_p15_c0 (void)
  51462. +*/
  51463. +/* read co-processor 15, register #0 (ID register) */
  51464. +static MV_U32 read_p15_c0 (void)
  51465. +{
  51466. + MV_U32 value;
  51467. +
  51468. + __asm__ __volatile__(
  51469. + "mrc p15, 0, %0, c0, c0, 0 @ read control reg\n"
  51470. + : "=r" (value)
  51471. + :
  51472. + : "memory");
  51473. +
  51474. + return value;
  51475. +}
  51476. +
  51477. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h
  51478. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h 1970-01-01 01:00:00.000000000 +0100
  51479. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h 2011-07-31 11:31:59.035915493 +0200
  51480. @@ -0,0 +1,423 @@
  51481. +/*******************************************************************************
  51482. +Copyright (C) Marvell International Ltd. and its affiliates
  51483. +
  51484. +This software file (the "File") is owned and distributed by Marvell
  51485. +International Ltd. and/or its affiliates ("Marvell") under the following
  51486. +alternative licensing terms. Once you have made an election to distribute the
  51487. +File under one of the following license alternatives, please (i) delete this
  51488. +introductory statement regarding license alternatives, (ii) delete the two
  51489. +license alternatives that you have not elected to use and (iii) preserve the
  51490. +Marvell copyright notice above.
  51491. +
  51492. +
  51493. +********************************************************************************
  51494. +Marvell GPL License Option
  51495. +
  51496. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51497. +modify this File in accordance with the terms and conditions of the General
  51498. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51499. +available along with the File in the license.txt file or by writing to the Free
  51500. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51501. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51502. +
  51503. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51504. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51505. +DISCLAIMED. The GPL License provides additional details about this warranty
  51506. +disclaimer.
  51507. +*******************************************************************************/
  51508. +#ifndef _MV_OS_LNX_H_
  51509. +#define _MV_OS_LNX_H_
  51510. +
  51511. +
  51512. +#ifdef __KERNEL__
  51513. +/* for kernel space */
  51514. +#include <linux/autoconf.h>
  51515. +#include <linux/interrupt.h>
  51516. +#include <linux/stddef.h>
  51517. +#include <linux/kernel.h>
  51518. +#include <linux/init.h>
  51519. +#include <linux/errno.h>
  51520. +#include <linux/reboot.h>
  51521. +#include <linux/pci.h>
  51522. +#include <linux/kdev_t.h>
  51523. +#include <linux/major.h>
  51524. +#include <linux/blkdev.h>
  51525. +#include <linux/console.h>
  51526. +#include <linux/delay.h>
  51527. +#include <linux/seq_file.h>
  51528. +#include <linux/string.h>
  51529. +#include <linux/slab.h>
  51530. +#include <linux/kernel.h>
  51531. +#include <linux/string.h>
  51532. +#include <linux/slab.h>
  51533. +#include <linux/mm.h>
  51534. +
  51535. +#include <asm/system.h>
  51536. +#include <asm/pgtable.h>
  51537. +#include <asm/page.h>
  51538. +#include <asm/hardirq.h>
  51539. +#include <asm/dma.h>
  51540. +#include <asm/io.h>
  51541. +
  51542. +#include <linux/random.h>
  51543. +
  51544. +#include "dbg-trace.h"
  51545. +
  51546. +extern void mv_early_printk(char *fmt,...);
  51547. +
  51548. +#define MV_ASM __asm__ __volatile__
  51549. +#define INLINE inline
  51550. +#define MV_TRC_REC TRC_REC
  51551. +#define mvOsPrintf printk
  51552. +#define mvOsEarlyPrintf mv_early_printk
  51553. +#define mvOsOutput printk
  51554. +#define mvOsSPrintf sprintf
  51555. +#define mvOsMalloc(_size_) kmalloc(_size_,GFP_ATOMIC)
  51556. +#define mvOsFree kfree
  51557. +#define mvOsMemcpy memcpy
  51558. +#define mvOsSleep(_mils_) mdelay(_mils_)
  51559. +#define mvOsTaskLock()
  51560. +#define mvOsTaskUnlock()
  51561. +#define strtol simple_strtoul
  51562. +#define mvOsDelay(x) mdelay(x)
  51563. +#define mvOsUDelay(x) udelay(x)
  51564. +#define mvCopyFromOs copy_from_user
  51565. +#define mvCopyToOs copy_to_user
  51566. +
  51567. +
  51568. +#include "mvTypes.h"
  51569. +#include "mvCommon.h"
  51570. +
  51571. +#ifdef MV_NDEBUG
  51572. +#define mvOsAssert(cond)
  51573. +#else
  51574. +#define mvOsAssert(cond) { do { if(!(cond)) { BUG(); } }while(0); }
  51575. +#endif /* MV_NDEBUG */
  51576. +
  51577. +#else /* __KERNEL__ */
  51578. +
  51579. +/* for user space applications */
  51580. +#include <stdlib.h>
  51581. +#include <stdio.h>
  51582. +#include <assert.h>
  51583. +#include <string.h>
  51584. +
  51585. +#define INLINE inline
  51586. +#define mvOsPrintf printf
  51587. +#define mvOsOutput printf
  51588. +#define mvOsMalloc(_size_) malloc(_size_)
  51589. +#define mvOsFree free
  51590. +#define mvOsAssert(cond) assert(cond)
  51591. +
  51592. +#endif /* __KERNEL__ */
  51593. +#define mvOsIoVirtToPhy(pDev, pVirtAddr) \
  51594. + pci_map_single( (pDev), (pVirtAddr), 0, PCI_DMA_BIDIRECTIONAL )
  51595. +
  51596. +#define mvOsCacheClear(pDev, p, size ) \
  51597. + pci_map_single( (pDev), (p), (size), PCI_DMA_BIDIRECTIONAL)
  51598. +
  51599. +#define mvOsCacheFlush(pDev, p, size ) \
  51600. + pci_map_single( (pDev), (p), (size), PCI_DMA_TODEVICE)
  51601. +
  51602. +#define mvOsCacheInvalidate(pDev, p, size) \
  51603. + pci_map_single( (pDev), (p), (size), PCI_DMA_FROMDEVICE )
  51604. +
  51605. +#define mvOsCacheUnmap(pDev, phys, size) \
  51606. + pci_unmap_single( (pDev), (dma_addr_t)(phys), (size), PCI_DMA_FROMDEVICE )
  51607. +
  51608. +
  51609. +#define CPU_PHY_MEM(x) (MV_U32)x
  51610. +#define CPU_MEMIO_CACHED_ADDR(x) (void*)x
  51611. +#define CPU_MEMIO_UNCACHED_ADDR(x) (void*)x
  51612. +
  51613. +
  51614. +/* CPU architecture dependent 32, 16, 8 bit read/write IO addresses */
  51615. +#define MV_MEMIO32_WRITE(addr, data) \
  51616. + ((*((volatile unsigned int*)(addr))) = ((unsigned int)(data)))
  51617. +
  51618. +#define MV_MEMIO32_READ(addr) \
  51619. + ((*((volatile unsigned int*)(addr))))
  51620. +
  51621. +#define MV_MEMIO16_WRITE(addr, data) \
  51622. + ((*((volatile unsigned short*)(addr))) = ((unsigned short)(data)))
  51623. +
  51624. +#define MV_MEMIO16_READ(addr) \
  51625. + ((*((volatile unsigned short*)(addr))))
  51626. +
  51627. +#define MV_MEMIO8_WRITE(addr, data) \
  51628. + ((*((volatile unsigned char*)(addr))) = ((unsigned char)(data)))
  51629. +
  51630. +#define MV_MEMIO8_READ(addr) \
  51631. + ((*((volatile unsigned char*)(addr))))
  51632. +
  51633. +
  51634. +/* No Fast Swap implementation (in assembler) for ARM */
  51635. +#define MV_32BIT_LE_FAST(val) MV_32BIT_LE(val)
  51636. +#define MV_16BIT_LE_FAST(val) MV_16BIT_LE(val)
  51637. +#define MV_32BIT_BE_FAST(val) MV_32BIT_BE(val)
  51638. +#define MV_16BIT_BE_FAST(val) MV_16BIT_BE(val)
  51639. +
  51640. +/* 32 and 16 bit read/write in big/little endian mode */
  51641. +
  51642. +/* 16bit write in little endian mode */
  51643. +#define MV_MEMIO_LE16_WRITE(addr, data) \
  51644. + MV_MEMIO16_WRITE(addr, MV_16BIT_LE_FAST(data))
  51645. +
  51646. +/* 16bit read in little endian mode */
  51647. +static __inline MV_U16 MV_MEMIO_LE16_READ(MV_U32 addr)
  51648. +{
  51649. + MV_U16 data;
  51650. +
  51651. + data= (MV_U16)MV_MEMIO16_READ(addr);
  51652. +
  51653. + return (MV_U16)MV_16BIT_LE_FAST(data);
  51654. +}
  51655. +
  51656. +/* 32bit write in little endian mode */
  51657. +#define MV_MEMIO_LE32_WRITE(addr, data) \
  51658. + MV_MEMIO32_WRITE(addr, MV_32BIT_LE_FAST(data))
  51659. +
  51660. +/* 32bit read in little endian mode */
  51661. +static __inline MV_U32 MV_MEMIO_LE32_READ(MV_U32 addr)
  51662. +{
  51663. + MV_U32 data;
  51664. +
  51665. + data= (MV_U32)MV_MEMIO32_READ(addr);
  51666. +
  51667. + return (MV_U32)MV_32BIT_LE_FAST(data);
  51668. +}
  51669. +
  51670. +static __inline void mvOsBCopy(char* srcAddr, char* dstAddr, int byteCount)
  51671. +{
  51672. + while(byteCount != 0)
  51673. + {
  51674. + *dstAddr = *srcAddr;
  51675. + dstAddr++;
  51676. + srcAddr++;
  51677. + byteCount--;
  51678. + }
  51679. +}
  51680. +
  51681. +static INLINE MV_U64 mvOsDivMod64(MV_U64 divided, MV_U64 divisor, MV_U64* modulu)
  51682. +{
  51683. + MV_U64 division = 0;
  51684. +
  51685. + if(divisor == 1)
  51686. + return divided;
  51687. +
  51688. + while(divided >= divisor)
  51689. + {
  51690. + division++;
  51691. + divided -= divisor;
  51692. + }
  51693. + if (modulu != NULL)
  51694. + *modulu = divided;
  51695. +
  51696. + return division;
  51697. +}
  51698. +
  51699. +#if defined(MV_BRIDGE_SYNC_REORDER)
  51700. +extern MV_U32 *mvUncachedParam;
  51701. +
  51702. +static __inline void mvOsBridgeReorderWA(void)
  51703. +{
  51704. + volatile MV_U32 val = 0;
  51705. +
  51706. + val = mvUncachedParam[0];
  51707. +}
  51708. +#endif
  51709. +
  51710. +
  51711. +/* Flash APIs */
  51712. +#define MV_FL_8_READ MV_MEMIO8_READ
  51713. +#define MV_FL_16_READ MV_MEMIO_LE16_READ
  51714. +#define MV_FL_32_READ MV_MEMIO_LE32_READ
  51715. +#define MV_FL_8_DATA_READ MV_MEMIO8_READ
  51716. +#define MV_FL_16_DATA_READ MV_MEMIO16_READ
  51717. +#define MV_FL_32_DATA_READ MV_MEMIO32_READ
  51718. +#define MV_FL_8_WRITE MV_MEMIO8_WRITE
  51719. +#define MV_FL_16_WRITE MV_MEMIO_LE16_WRITE
  51720. +#define MV_FL_32_WRITE MV_MEMIO_LE32_WRITE
  51721. +#define MV_FL_8_DATA_WRITE MV_MEMIO8_WRITE
  51722. +#define MV_FL_16_DATA_WRITE MV_MEMIO16_WRITE
  51723. +#define MV_FL_32_DATA_WRITE MV_MEMIO32_WRITE
  51724. +
  51725. +
  51726. +/* CPU cache information */
  51727. +#define CPU_I_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
  51728. +#define CPU_D_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
  51729. +
  51730. +#ifdef CONFIG_L2_CACHE_ENABLE
  51731. +/* Data cache flush one line */
  51732. +#define mvOsCacheLineFlushInv(handle, addr) \
  51733. +{ \
  51734. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\
  51735. + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c10, 1" : : "r" (addr));\
  51736. + __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4"); \
  51737. +}
  51738. +
  51739. +#else
  51740. +
  51741. +/* Data cache flush one line */
  51742. +#define mvOsCacheLineFlushInv(handle, addr) \
  51743. +{ \
  51744. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\
  51745. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \
  51746. +}
  51747. +#endif
  51748. +
  51749. +#ifdef CONFIG_L2_CACHE_ENABLE
  51750. +#define mvOsCacheLineInv(handle,addr) \
  51751. +{ \
  51752. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \
  51753. + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c11, 1" : : "r" (addr)); \
  51754. +}
  51755. +#else
  51756. +#define mvOsCacheLineInv(handle,addr) \
  51757. +{ \
  51758. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \
  51759. +}
  51760. +#endif
  51761. +
  51762. +#ifdef CONFIG_L2_CACHE_ENABLE
  51763. +/* Data cache flush one line */
  51764. +#define mvOsCacheLineFlush(handle, addr) \
  51765. +{ \
  51766. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\
  51767. + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c9, 1" : : "r" (addr));\
  51768. + __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4"); \
  51769. +}
  51770. +
  51771. +#else
  51772. +/* Data cache flush one line */
  51773. +#define mvOsCacheLineFlush(handle, addr) \
  51774. +{ \
  51775. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\
  51776. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \
  51777. +}
  51778. +#endif
  51779. +
  51780. +static __inline void mvOsPrefetch(const void *ptr)
  51781. +{
  51782. +#ifdef CONFIG_USE_DSP
  51783. + __asm__ __volatile__(
  51784. + "pld\t%0"
  51785. + :
  51786. + : "o" (*(char *)ptr)
  51787. + : "cc");
  51788. +#else
  51789. + return;
  51790. +#endif
  51791. +}
  51792. +
  51793. +
  51794. +/* Flush CPU pipe */
  51795. +#define CPU_PIPE_FLUSH
  51796. +
  51797. +
  51798. +
  51799. +
  51800. +
  51801. +/* register manipulations */
  51802. +
  51803. +/******************************************************************************
  51804. +* This debug function enable the write of each register that u-boot access to
  51805. +* to an array in the DRAM, the function record only MV_REG_WRITE access.
  51806. +* The function could not be operate when booting from flash.
  51807. +* In order to print the array we use the printreg command.
  51808. +******************************************************************************/
  51809. +/* #define REG_DEBUG */
  51810. +#if defined(REG_DEBUG)
  51811. +extern int reg_arry[2048][2];
  51812. +extern int reg_arry_index;
  51813. +#endif
  51814. +
  51815. +/* Marvell controller register read/write macros */
  51816. +#define MV_REG_VALUE(offset) \
  51817. + (MV_MEMIO32_READ((INTER_REGS_BASE | (offset))))
  51818. +
  51819. +#define MV_REG_READ(offset) \
  51820. + (MV_MEMIO_LE32_READ(INTER_REGS_BASE | (offset)))
  51821. +
  51822. +#if defined(REG_DEBUG)
  51823. +#define MV_REG_WRITE(offset, val) \
  51824. + MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val)); \
  51825. + { \
  51826. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  51827. + reg_arry[reg_arry_index][1] = (val);\
  51828. + reg_arry_index++;\
  51829. + }
  51830. +#else
  51831. +#define MV_REG_WRITE(offset, val) \
  51832. + MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val));
  51833. +#endif
  51834. +
  51835. +#define MV_REG_BYTE_READ(offset) \
  51836. + (MV_MEMIO8_READ((INTER_REGS_BASE | (offset))))
  51837. +
  51838. +#if defined(REG_DEBUG)
  51839. +#define MV_REG_BYTE_WRITE(offset, val) \
  51840. + MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val)); \
  51841. + { \
  51842. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  51843. + reg_arry[reg_arry_index][1] = (val);\
  51844. + reg_arry_index++;\
  51845. + }
  51846. +#else
  51847. +#define MV_REG_BYTE_WRITE(offset, val) \
  51848. + MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val))
  51849. +#endif
  51850. +
  51851. +#if defined(REG_DEBUG)
  51852. +#define MV_REG_BIT_SET(offset, bitMask) \
  51853. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  51854. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \
  51855. + MV_32BIT_LE_FAST(bitMask)))); \
  51856. + { \
  51857. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  51858. + reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\
  51859. + reg_arry_index++;\
  51860. + }
  51861. +#else
  51862. +#define MV_REG_BIT_SET(offset, bitMask) \
  51863. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  51864. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \
  51865. + MV_32BIT_LE_FAST(bitMask))))
  51866. +#endif
  51867. +
  51868. +#if defined(REG_DEBUG)
  51869. +#define MV_REG_BIT_RESET(offset,bitMask) \
  51870. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  51871. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \
  51872. + MV_32BIT_LE_FAST(~bitMask)))); \
  51873. + { \
  51874. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  51875. + reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\
  51876. + reg_arry_index++;\
  51877. + }
  51878. +#else
  51879. +#define MV_REG_BIT_RESET(offset,bitMask) \
  51880. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  51881. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \
  51882. + MV_32BIT_LE_FAST(~bitMask))))
  51883. +#endif
  51884. +
  51885. +
  51886. +
  51887. +/* ARM architecture APIs */
  51888. +MV_U32 mvOsCpuRevGet (MV_VOID);
  51889. +MV_U32 mvOsCpuPartGet (MV_VOID);
  51890. +MV_U32 mvOsCpuArchGet (MV_VOID);
  51891. +MV_U32 mvOsCpuVarGet (MV_VOID);
  51892. +MV_U32 mvOsCpuAsciiGet (MV_VOID);
  51893. +
  51894. +/* Other APIs */
  51895. +void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle);
  51896. +void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle );
  51897. +void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );
  51898. +void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );
  51899. +int mvOsRand(void);
  51900. +
  51901. +#endif /* _MV_OS_LNX_H_ */
  51902. +
  51903. +
  51904. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h
  51905. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h 1970-01-01 01:00:00.000000000 +0100
  51906. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h 2011-07-31 11:31:59.074148710 +0200
  51907. @@ -0,0 +1,158 @@
  51908. +/*******************************************************************************
  51909. +Copyright (C) Marvell International Ltd. and its affiliates
  51910. +
  51911. +This software file (the "File") is owned and distributed by Marvell
  51912. +International Ltd. and/or its affiliates ("Marvell") under the following
  51913. +alternative licensing terms. Once you have made an election to distribute the
  51914. +File under one of the following license alternatives, please (i) delete this
  51915. +introductory statement regarding license alternatives, (ii) delete the two
  51916. +license alternatives that you have not elected to use and (iii) preserve the
  51917. +Marvell copyright notice above.
  51918. +
  51919. +
  51920. +********************************************************************************
  51921. +Marvell GPL License Option
  51922. +
  51923. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51924. +modify this File in accordance with the terms and conditions of the General
  51925. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51926. +available along with the File in the license.txt file or by writing to the Free
  51927. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51928. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51929. +
  51930. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51931. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51932. +DISCLAIMED. The GPL License provides additional details about this warranty
  51933. +disclaimer.
  51934. +*******************************************************************************/
  51935. +/*******************************************************************************
  51936. +* mvOsLinux.h - O.S. interface header file for Linux
  51937. +*
  51938. +* DESCRIPTION:
  51939. +* This header file contains OS dependent definition under Linux
  51940. +*
  51941. +* DEPENDENCIES:
  51942. +* Linux kernel header files.
  51943. +*
  51944. +* FILE REVISION NUMBER:
  51945. +* $Revision: 1.1 $
  51946. +*******************************************************************************/
  51947. +
  51948. +#ifndef __INCmvOsLinuxh
  51949. +#define __INCmvOsLinuxh
  51950. +
  51951. +/* Includes */
  51952. +#include <linux/autoconf.h>
  51953. +#include <linux/module.h>
  51954. +#include <linux/types.h>
  51955. +#include <linux/string.h>
  51956. +#include <linux/kernel.h>
  51957. +#include <linux/timer.h>
  51958. +#include <linux/mm.h>
  51959. +#include <linux/interrupt.h>
  51960. +#include <linux/major.h>
  51961. +#include <linux/errno.h>
  51962. +#include <linux/genhd.h>
  51963. +#include <linux/slab.h>
  51964. +#include <linux/delay.h>
  51965. +#include <linux/ide.h>
  51966. +#include <linux/pci.h>
  51967. +
  51968. +#include <asm/byteorder.h>
  51969. +#include <asm/irq.h>
  51970. +#include <asm/uaccess.h>
  51971. +#include <asm/io.h>
  51972. +#include "mvOs.h"
  51973. +
  51974. +
  51975. +/* Definitions */
  51976. +#define MV_DEFAULT_QUEUE_DEPTH 2
  51977. +#define MV_SATA_SUPPORT_EDMA_SINGLE_DATA_REGION
  51978. +#define MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN
  51979. +
  51980. +#ifdef CONFIG_MV88F6082
  51981. + #define MV_SATA_OVERRIDE_SW_QUEUE_SIZE
  51982. + #define MV_SATA_REQUESTED_SW_QUEUE_SIZE 2
  51983. + #undef MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN
  51984. +#endif
  51985. +
  51986. +/* System dependent macro for flushing CPU write cache */
  51987. +#if defined (MV_BRIDGE_SYNC_REORDER)
  51988. +#define MV_CPU_WRITE_BUFFER_FLUSH() do { \
  51989. + wmb(); \
  51990. + mvOsBridgeReorderWA(); \
  51991. + } while (0)
  51992. +#else
  51993. +#define MV_CPU_WRITE_BUFFER_FLUSH() wmb()
  51994. +#endif /* CONFIG_MV78XX0 */
  51995. +
  51996. +/* System dependent little endian from / to CPU conversions */
  51997. +#define MV_CPU_TO_LE16(x) cpu_to_le16(x)
  51998. +#define MV_CPU_TO_LE32(x) cpu_to_le32(x)
  51999. +
  52000. +#define MV_LE16_TO_CPU(x) le16_to_cpu(x)
  52001. +#define MV_LE32_TO_CPU(x) le32_to_cpu(x)
  52002. +
  52003. +#ifdef __BIG_ENDIAN_BITFIELD
  52004. +#define MV_BIG_ENDIAN_BITFIELD
  52005. +#endif
  52006. +
  52007. +/* System dependent register read / write in byte/word/dword variants */
  52008. +#define MV_REG_WRITE_BYTE(base, offset, val) writeb(val, base + offset)
  52009. +#define MV_REG_WRITE_WORD(base, offset, val) writew(val, base + offset)
  52010. +#define MV_REG_WRITE_DWORD(base, offset, val) writel(val, base + offset)
  52011. +#define MV_REG_READ_BYTE(base, offset) readb(base + offset)
  52012. +#define MV_REG_READ_WORD(base, offset) readw(base + offset)
  52013. +#define MV_REG_READ_DWORD(base, offset) readl(base + offset)
  52014. +
  52015. +
  52016. +/* Typedefs */
  52017. +
  52018. +/* System dependant typedefs */
  52019. +typedef void *MV_VOID_PTR;
  52020. +typedef u32 *MV_U32_PTR;
  52021. +typedef u16 *MV_U16_PTR;
  52022. +typedef u8 *MV_U8_PTR;
  52023. +typedef char *MV_CHAR_PTR;
  52024. +typedef void *MV_BUS_ADDR_T;
  52025. +typedef unsigned long MV_CPU_FLAGS;
  52026. +
  52027. +
  52028. +/* Structures */
  52029. +/* System dependent structure */
  52030. +typedef struct mvOsSemaphore
  52031. +{
  52032. + int notUsed;
  52033. +} MV_OS_SEMAPHORE;
  52034. +
  52035. +
  52036. +/* Functions (User implemented)*/
  52037. +
  52038. +/* Semaphore init, take and release */
  52039. +#define mvOsSemInit(x) MV_TRUE
  52040. +#define mvOsSemTake(x)
  52041. +#define mvOsSemRelease(x)
  52042. +
  52043. +/* Interrupt masking and unmasking functions */
  52044. +MV_CPU_FLAGS mvOsSaveFlagsAndMaskCPUInterrupts(MV_VOID);
  52045. +MV_VOID mvOsRestoreFlags(MV_CPU_FLAGS);
  52046. +
  52047. +/* Delay function in micro seconds resolution */
  52048. +void mvMicroSecondsDelay(MV_VOID_PTR, MV_U32);
  52049. +
  52050. +/* Typedefs */
  52051. +typedef enum mvBoolean
  52052. +{
  52053. + MV_SFALSE, MV_STRUE
  52054. +} MV_BOOLEAN;
  52055. +
  52056. +/* System logging function */
  52057. +#include "mvLog.h"
  52058. +/* Enable READ/WRITE Long SCSI command only when driver is compiled for debugging */
  52059. +#ifdef MV_LOGGER
  52060. +#define MV_SATA_SUPPORT_READ_WRITE_LONG
  52061. +#endif
  52062. +
  52063. +#define MV_IAL_LOG_ID 3
  52064. +
  52065. +#endif /* __INCmvOsLinuxh */
  52066. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c
  52067. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c 1970-01-01 01:00:00.000000000 +0100
  52068. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c 2011-07-31 11:31:59.143416806 +0200
  52069. @@ -0,0 +1,376 @@
  52070. +/*******************************************************************************
  52071. +Copyright (C) Marvell International Ltd. and its affiliates
  52072. +
  52073. +This software file (the "File") is owned and distributed by Marvell
  52074. +International Ltd. and/or its affiliates ("Marvell") under the following
  52075. +alternative licensing terms. Once you have made an election to distribute the
  52076. +File under one of the following license alternatives, please (i) delete this
  52077. +introductory statement regarding license alternatives, (ii) delete the two
  52078. +license alternatives that you have not elected to use and (iii) preserve the
  52079. +Marvell copyright notice above.
  52080. +
  52081. +********************************************************************************
  52082. +Marvell Commercial License Option
  52083. +
  52084. +If you received this File from Marvell and you have entered into a commercial
  52085. +license agreement (a "Commercial License") with Marvell, the File is licensed
  52086. +to you under the terms of the applicable Commercial License.
  52087. +
  52088. +********************************************************************************
  52089. +Marvell GPL License Option
  52090. +
  52091. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52092. +modify this File in accordance with the terms and conditions of the General
  52093. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  52094. +available along with the File in the license.txt file or by writing to the Free
  52095. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  52096. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  52097. +
  52098. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  52099. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  52100. +DISCLAIMED. The GPL License provides additional details about this warranty
  52101. +disclaimer.
  52102. +********************************************************************************
  52103. +Marvell BSD License Option
  52104. +
  52105. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52106. +modify this File under the following licensing terms.
  52107. +Redistribution and use in source and binary forms, with or without modification,
  52108. +are permitted provided that the following conditions are met:
  52109. +
  52110. + * Redistributions of source code must retain the above copyright notice,
  52111. + this list of conditions and the following disclaimer.
  52112. +
  52113. + * Redistributions in binary form must reproduce the above copyright
  52114. + notice, this list of conditions and the following disclaimer in the
  52115. + documentation and/or other materials provided with the distribution.
  52116. +
  52117. + * Neither the name of Marvell nor the names of its contributors may be
  52118. + used to endorse or promote products derived from this software without
  52119. + specific prior written permission.
  52120. +
  52121. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  52122. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  52123. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  52124. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  52125. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  52126. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  52127. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  52128. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  52129. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  52130. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52131. +
  52132. +*******************************************************************************/
  52133. +
  52134. +#include "mvCntmr.h"
  52135. +#include "cpu/mvCpu.h"
  52136. +
  52137. +/* defines */
  52138. +#ifdef MV_DEBUG
  52139. + #define DB(x) x
  52140. +#else
  52141. + #define DB(x)
  52142. +#endif
  52143. +
  52144. +extern unsigned int whoAmI(void);
  52145. +
  52146. +/*******************************************************************************
  52147. +* mvCntmrLoad -
  52148. +*
  52149. +* DESCRIPTION:
  52150. +* Load an init Value to a given counter/timer
  52151. +*
  52152. +* INPUT:
  52153. +* countNum - counter number
  52154. +* value - value to be loaded
  52155. +*
  52156. +* OUTPUT:
  52157. +* None.
  52158. +*
  52159. +* RETURN:
  52160. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  52161. +*******************************************************************************/
  52162. +MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value)
  52163. +{
  52164. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  52165. + {
  52166. +
  52167. + mvOsPrintf(("mvCntmrLoad: Err. Illigal counter number \n"));
  52168. + return MV_BAD_PARAM;;
  52169. +
  52170. + }
  52171. +
  52172. + MV_REG_WRITE(CNTMR_RELOAD_REG(countNum),value);
  52173. + MV_REG_WRITE(CNTMR_VAL_REG(countNum),value);
  52174. +
  52175. + return MV_OK;
  52176. +}
  52177. +
  52178. +/*******************************************************************************
  52179. +* mvCntmrRead -
  52180. +*
  52181. +* DESCRIPTION:
  52182. +* Returns the value of the given Counter/Timer
  52183. +*
  52184. +* INPUT:
  52185. +* countNum - counter number
  52186. +*
  52187. +* OUTPUT:
  52188. +* None.
  52189. +*
  52190. +* RETURN:
  52191. +* MV_U32 counter value
  52192. +*******************************************************************************/
  52193. +MV_U32 mvCntmrRead(MV_U32 countNum)
  52194. +{
  52195. + return MV_REG_READ(CNTMR_VAL_REG(countNum));
  52196. +}
  52197. +
  52198. +/*******************************************************************************
  52199. +* mvCntmrWrite -
  52200. +*
  52201. +* DESCRIPTION:
  52202. +* Returns the value of the given Counter/Timer
  52203. +*
  52204. +* INPUT:
  52205. +* countNum - counter number
  52206. +* countVal - value to write
  52207. +*
  52208. +* OUTPUT:
  52209. +* None.
  52210. +*
  52211. +* RETURN:
  52212. +* None
  52213. +*******************************************************************************/
  52214. +void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal)
  52215. +{
  52216. + MV_REG_WRITE(CNTMR_VAL_REG(countNum),countVal);
  52217. +}
  52218. +
  52219. +/*******************************************************************************
  52220. +* mvCntmrCtrlSet -
  52221. +*
  52222. +* DESCRIPTION:
  52223. +* Set the Control to a given counter/timer
  52224. +*
  52225. +* INPUT:
  52226. +* countNum - counter number
  52227. +* pCtrl - pointer to MV_CNTMR_CTRL structure
  52228. +*
  52229. +* OUTPUT:
  52230. +* None.
  52231. +*
  52232. +* RETURN:
  52233. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  52234. +*******************************************************************************/
  52235. +MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)
  52236. +{
  52237. + MV_U32 cntmrCtrl;
  52238. +
  52239. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  52240. + {
  52241. +
  52242. + DB(mvOsPrintf(("mvCntmrCtrlSet: Err. Illigal counter number \n")));
  52243. + return MV_BAD_PARAM;;
  52244. +
  52245. + }
  52246. +
  52247. + /* read control register */
  52248. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  52249. +
  52250. +
  52251. + if (pCtrl->enable) /* enable counter\timer */
  52252. + {
  52253. + cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);
  52254. + }
  52255. + else /* disable counter\timer */
  52256. + {
  52257. + cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);
  52258. + }
  52259. +
  52260. + if ( pCtrl->autoEnable ) /* Auto mode */
  52261. + {
  52262. + cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(countNum);
  52263. +
  52264. + }
  52265. + else /* no auto mode */
  52266. + {
  52267. + cntmrCtrl &= ~CTCR_ARM_TIMER_AUTO_EN(countNum);
  52268. + }
  52269. +
  52270. + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
  52271. +
  52272. + return MV_OK;
  52273. +
  52274. +}
  52275. +
  52276. +/*******************************************************************************
  52277. +* mvCntmrCtrlGet -
  52278. +*
  52279. +* DESCRIPTION:
  52280. +* Get the Control value of a given counter/timer
  52281. +*
  52282. +* INPUT:
  52283. +* countNum - counter number
  52284. +* pCtrl - pointer to MV_CNTMR_CTRL structure
  52285. +*
  52286. +* OUTPUT:
  52287. +* Counter\Timer control value
  52288. +*
  52289. +* RETURN:
  52290. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  52291. +*******************************************************************************/
  52292. +MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)
  52293. +{
  52294. + MV_U32 cntmrCtrl;
  52295. +
  52296. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  52297. + {
  52298. + DB(mvOsPrintf(("mvCntmrCtrlGet: Err. Illigal counter number \n")));
  52299. + return MV_BAD_PARAM;;
  52300. + }
  52301. +
  52302. + /* read control register */
  52303. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  52304. +
  52305. + /* enable counter\timer */
  52306. + if (cntmrCtrl & CTCR_ARM_TIMER_EN(countNum))
  52307. + {
  52308. + pCtrl->enable = MV_TRUE;
  52309. + }
  52310. + else
  52311. + {
  52312. + pCtrl->enable = MV_FALSE;
  52313. + }
  52314. +
  52315. + /* counter mode */
  52316. + if (cntmrCtrl & CTCR_ARM_TIMER_AUTO_EN(countNum))
  52317. + {
  52318. + pCtrl->autoEnable = MV_TRUE;
  52319. + }
  52320. + else
  52321. + {
  52322. + pCtrl->autoEnable = MV_FALSE;
  52323. + }
  52324. +
  52325. + return MV_OK;
  52326. +}
  52327. +
  52328. +/*******************************************************************************
  52329. +* mvCntmrEnable -
  52330. +*
  52331. +* DESCRIPTION:
  52332. +* Set the Enable-Bit to logic '1' ==> starting the counter
  52333. +*
  52334. +* INPUT:
  52335. +* countNum - counter number
  52336. +*
  52337. +* OUTPUT:
  52338. +* None.
  52339. +*
  52340. +* RETURN:
  52341. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  52342. +*******************************************************************************/
  52343. +MV_STATUS mvCntmrEnable(MV_U32 countNum)
  52344. +{
  52345. + MV_U32 cntmrCtrl;
  52346. +
  52347. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  52348. + {
  52349. +
  52350. + DB(mvOsPrintf(("mvCntmrEnable: Err. Illigal counter number \n")));
  52351. + return MV_BAD_PARAM;;
  52352. +
  52353. + }
  52354. +
  52355. + /* read control register */
  52356. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  52357. +
  52358. + /* enable counter\timer */
  52359. + cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);
  52360. +
  52361. +
  52362. + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
  52363. +
  52364. + return MV_OK;
  52365. +}
  52366. +
  52367. +/*******************************************************************************
  52368. +* mvCntmrDisable -
  52369. +*
  52370. +* DESCRIPTION:
  52371. +* Stop the counter/timer running, and returns its Value
  52372. +*
  52373. +* INPUT:
  52374. +* countNum - counter number
  52375. +*
  52376. +* OUTPUT:
  52377. +* None.
  52378. +*
  52379. +* RETURN:
  52380. +* MV_U32 counter\timer value
  52381. +*******************************************************************************/
  52382. +MV_STATUS mvCntmrDisable(MV_U32 countNum)
  52383. +{
  52384. + MV_U32 cntmrCtrl;
  52385. +
  52386. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  52387. + {
  52388. +
  52389. + DB(mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n")));
  52390. + return MV_BAD_PARAM;;
  52391. +
  52392. + }
  52393. +
  52394. + /* read control register */
  52395. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  52396. +
  52397. + /* disable counter\timer */
  52398. + cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);
  52399. +
  52400. + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
  52401. +
  52402. + return MV_OK;
  52403. +}
  52404. +
  52405. +/*******************************************************************************
  52406. +* mvCntmrStart -
  52407. +*
  52408. +* DESCRIPTION:
  52409. +* Combined all the sub-operations above to one function: Load,setMode,Enable
  52410. +*
  52411. +* INPUT:
  52412. +* countNum - counter number
  52413. +* value - value of the counter\timer to be set
  52414. +* pCtrl - pointer to MV_CNTMR_CTRL structure
  52415. +*
  52416. +* OUTPUT:
  52417. +* None.
  52418. +*
  52419. +* RETURN:
  52420. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  52421. +*******************************************************************************/
  52422. +MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,
  52423. + MV_CNTMR_CTRL *pCtrl)
  52424. +{
  52425. +
  52426. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  52427. + {
  52428. +
  52429. + mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n"));
  52430. + return MV_BAD_PARAM;;
  52431. +
  52432. + }
  52433. +
  52434. + /* load value onto counter\timer */
  52435. + mvCntmrLoad(countNum,value);
  52436. +
  52437. + /* set the counter to load in the first time */
  52438. + mvCntmrWrite(countNum,value);
  52439. +
  52440. + /* set control for timer \ cunter and enable */
  52441. + mvCntmrCtrlSet(countNum,pCtrl);
  52442. +
  52443. + return MV_OK;
  52444. +}
  52445. +
  52446. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h
  52447. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h 1970-01-01 01:00:00.000000000 +0100
  52448. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h 2011-07-31 11:31:59.173417275 +0200
  52449. @@ -0,0 +1,121 @@
  52450. +/*******************************************************************************
  52451. +Copyright (C) Marvell International Ltd. and its affiliates
  52452. +
  52453. +This software file (the "File") is owned and distributed by Marvell
  52454. +International Ltd. and/or its affiliates ("Marvell") under the following
  52455. +alternative licensing terms. Once you have made an election to distribute the
  52456. +File under one of the following license alternatives, please (i) delete this
  52457. +introductory statement regarding license alternatives, (ii) delete the two
  52458. +license alternatives that you have not elected to use and (iii) preserve the
  52459. +Marvell copyright notice above.
  52460. +
  52461. +********************************************************************************
  52462. +Marvell Commercial License Option
  52463. +
  52464. +If you received this File from Marvell and you have entered into a commercial
  52465. +license agreement (a "Commercial License") with Marvell, the File is licensed
  52466. +to you under the terms of the applicable Commercial License.
  52467. +
  52468. +********************************************************************************
  52469. +Marvell GPL License Option
  52470. +
  52471. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52472. +modify this File in accordance with the terms and conditions of the General
  52473. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  52474. +available along with the File in the license.txt file or by writing to the Free
  52475. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  52476. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  52477. +
  52478. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  52479. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  52480. +DISCLAIMED. The GPL License provides additional details about this warranty
  52481. +disclaimer.
  52482. +********************************************************************************
  52483. +Marvell BSD License Option
  52484. +
  52485. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52486. +modify this File under the following licensing terms.
  52487. +Redistribution and use in source and binary forms, with or without modification,
  52488. +are permitted provided that the following conditions are met:
  52489. +
  52490. + * Redistributions of source code must retain the above copyright notice,
  52491. + this list of conditions and the following disclaimer.
  52492. +
  52493. + * Redistributions in binary form must reproduce the above copyright
  52494. + notice, this list of conditions and the following disclaimer in the
  52495. + documentation and/or other materials provided with the distribution.
  52496. +
  52497. + * Neither the name of Marvell nor the names of its contributors may be
  52498. + used to endorse or promote products derived from this software without
  52499. + specific prior written permission.
  52500. +
  52501. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  52502. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  52503. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  52504. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  52505. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  52506. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  52507. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  52508. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  52509. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  52510. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52511. +
  52512. +*******************************************************************************/
  52513. +
  52514. +#ifndef __INCmvTmrWtdgh
  52515. +#define __INCmvTmrWtdgh
  52516. +
  52517. +/* includes */
  52518. +#include "mvCommon.h"
  52519. +#include "mvOs.h"
  52520. +#include "cntmr/mvCntmrRegs.h"
  52521. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  52522. +
  52523. +
  52524. +/* This enumerator describe counters\watchdog numbers */
  52525. +typedef enum _mvCntmrID
  52526. +{
  52527. + TIMER0 = 0,
  52528. + TIMER1,
  52529. + WATCHDOG,
  52530. + TIMER2,
  52531. + TIMER3,
  52532. +}MV_CNTMR_ID;
  52533. +
  52534. +
  52535. +/* Counter / Timer control structure */
  52536. +typedef struct _mvCntmrCtrl
  52537. +{
  52538. + MV_BOOL enable; /* enable */
  52539. + MV_BOOL autoEnable; /* counter/Timer */
  52540. +}MV_CNTMR_CTRL;
  52541. +
  52542. +
  52543. +/* Functions */
  52544. +
  52545. +/* Load an init Value to a given counter/timer */
  52546. +MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value);
  52547. +
  52548. +/* Returns the value of the given Counter/Timer */
  52549. +MV_U32 mvCntmrRead(MV_U32 countNum);
  52550. +
  52551. +/* Write a value of the given Counter/Timer */
  52552. +void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal);
  52553. +
  52554. +/* Set the Control to a given counter/timer */
  52555. +MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);
  52556. +
  52557. +/* Get the value of a given counter/timer */
  52558. +MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);
  52559. +
  52560. +/* Set the Enable-Bit to logic '1' ==> starting the counter. */
  52561. +MV_STATUS mvCntmrEnable(MV_U32 countNum);
  52562. +
  52563. +/* Stop the counter/timer running, and returns its Value. */
  52564. +MV_STATUS mvCntmrDisable(MV_U32 countNum);
  52565. +
  52566. +/* Combined all the sub-operations above to one function: Load,setMode,Enable */
  52567. +MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,
  52568. + MV_CNTMR_CTRL *pCtrl);
  52569. +
  52570. +#endif /* __INCmvTmrWtdgh */
  52571. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h
  52572. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h 1970-01-01 01:00:00.000000000 +0100
  52573. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h 2011-07-31 11:31:59.233950381 +0200
  52574. @@ -0,0 +1,121 @@
  52575. +/*******************************************************************************
  52576. +Copyright (C) Marvell International Ltd. and its affiliates
  52577. +
  52578. +This software file (the "File") is owned and distributed by Marvell
  52579. +International Ltd. and/or its affiliates ("Marvell") under the following
  52580. +alternative licensing terms. Once you have made an election to distribute the
  52581. +File under one of the following license alternatives, please (i) delete this
  52582. +introductory statement regarding license alternatives, (ii) delete the two
  52583. +license alternatives that you have not elected to use and (iii) preserve the
  52584. +Marvell copyright notice above.
  52585. +
  52586. +********************************************************************************
  52587. +Marvell Commercial License Option
  52588. +
  52589. +If you received this File from Marvell and you have entered into a commercial
  52590. +license agreement (a "Commercial License") with Marvell, the File is licensed
  52591. +to you under the terms of the applicable Commercial License.
  52592. +
  52593. +********************************************************************************
  52594. +Marvell GPL License Option
  52595. +
  52596. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52597. +modify this File in accordance with the terms and conditions of the General
  52598. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  52599. +available along with the File in the license.txt file or by writing to the Free
  52600. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  52601. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  52602. +
  52603. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  52604. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  52605. +DISCLAIMED. The GPL License provides additional details about this warranty
  52606. +disclaimer.
  52607. +********************************************************************************
  52608. +Marvell BSD License Option
  52609. +
  52610. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52611. +modify this File under the following licensing terms.
  52612. +Redistribution and use in source and binary forms, with or without modification,
  52613. +are permitted provided that the following conditions are met:
  52614. +
  52615. + * Redistributions of source code must retain the above copyright notice,
  52616. + this list of conditions and the following disclaimer.
  52617. +
  52618. + * Redistributions in binary form must reproduce the above copyright
  52619. + notice, this list of conditions and the following disclaimer in the
  52620. + documentation and/or other materials provided with the distribution.
  52621. +
  52622. + * Neither the name of Marvell nor the names of its contributors may be
  52623. + used to endorse or promote products derived from this software without
  52624. + specific prior written permission.
  52625. +
  52626. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  52627. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  52628. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  52629. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  52630. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  52631. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  52632. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  52633. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  52634. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  52635. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52636. +
  52637. +*******************************************************************************/
  52638. +
  52639. +#ifndef __INCmvTmrwtdgRegsh
  52640. +#define __INCmvTmrwtdgRegsh
  52641. +
  52642. +/*******************************************/
  52643. +/* ARM Timers Registers Map */
  52644. +/*******************************************/
  52645. +
  52646. +#define CNTMR_RELOAD_REG(tmrNum) (CNTMR_BASE + 0x10 + (tmrNum)*8 + \
  52647. + (((tmrNum) <= 3)?0:8))
  52648. +#define CNTMR_VAL_REG(tmrNum) (CNTMR_BASE + 0x14 + (tmrNum)*8 + \
  52649. + (((tmrNum) <= 3)?0:8))
  52650. +#define CNTMR_CTRL_REG (CNTMR_BASE)
  52651. +
  52652. +/*For MV78XX0*/
  52653. +#define CNTMR_CAUSE_REG (CPU_AHB_MBUS_CAUSE_INT_REG(whoAmI()))
  52654. +#define CNTMR_MASK_REG (CPU_AHB_MBUS_MASK_INT_REG(whoAmI()))
  52655. +
  52656. +/* ARM Timers Registers Map */
  52657. +/*******************************************/
  52658. +
  52659. +
  52660. +/* ARM Timers Control Register */
  52661. +/* CPU_TIMERS_CTRL_REG (CTCR) */
  52662. +
  52663. +#define TIMER0_NUM 0
  52664. +#define TIMER1_NUM 1
  52665. +#define WATCHDOG_NUM 2
  52666. +#define TIMER2_NUM 3
  52667. +#define TIMER3_NUM 4
  52668. +
  52669. +#define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2)
  52670. +#define CTCR_ARM_TIMER_EN_MASK(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS)
  52671. +#define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr))
  52672. +#define CTCR_ARM_TIMER_DIS(cntr) (0 << CTCR_ARM_TIMER_EN_OFFS(cntr))
  52673. +
  52674. +#define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1)
  52675. +#define CTCR_ARM_TIMER_AUTO_MASK(cntr) BIT1
  52676. +#define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
  52677. +#define CTCR_ARM_TIMER_AUTO_DIS(cntr) (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
  52678. +
  52679. +
  52680. +/* ARM Timer\Watchdog Reload Register */
  52681. +/* CNTMR_RELOAD_REG (TRR) */
  52682. +
  52683. +#define TRG_ARM_TIMER_REL_OFFS 0
  52684. +#define TRG_ARM_TIMER_REL_MASK 0xffffffff
  52685. +
  52686. +/* ARM Timer\Watchdog Register */
  52687. +/* CNTMR_VAL_REG (TVRG) */
  52688. +
  52689. +#define TVR_ARM_TIMER_OFFS 0
  52690. +#define TVR_ARM_TIMER_MASK 0xffffffff
  52691. +#define TVR_ARM_TIMER_MAX 0xffffffff
  52692. +
  52693. +
  52694. +
  52695. +#endif /* __INCmvTmrwtdgRegsh */
  52696. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c
  52697. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c 1970-01-01 01:00:00.000000000 +0100
  52698. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c 2011-07-31 11:31:59.293423615 +0200
  52699. @@ -0,0 +1,207 @@
  52700. +/*
  52701. + * This program is free software; you can redistribute it and/or modify
  52702. + * it under the terms of the GNU General Public License as published by
  52703. + * the Free Software Foundation; either version 2 of the License, or
  52704. + * (at your option) any later version.
  52705. + *
  52706. + * This program is distributed in the hope that it will be useful,
  52707. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  52708. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  52709. + * GNU General Public License for more details.
  52710. + *
  52711. + * You should have received a copy of the GNU General Public License
  52712. + * along with this program; if not, write to the Free Software
  52713. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  52714. + */
  52715. +
  52716. +#include "mvOs.h"
  52717. +#include "mvCpuCntrs.h"
  52718. +
  52719. +
  52720. +const static MV_CPU_CNTRS_OPS mvCpuCntrsOpsTbl[MV_CPU_CNTRS_NUM][MV_CPU_CNTRS_OPS_NUM] =
  52721. +{
  52722. + /*0*/
  52723. + {
  52724. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_DCACHE_READ_HIT, MV_CPU_CNTRS_DCACHE_READ_MISS,
  52725. + MV_CPU_CNTRS_DCACHE_WRITE_HIT, MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_INSTRUCTIONS,
  52726. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  52727. + MV_CPU_CNTRS_MMU_READ_LATENCY, MV_CPU_CNTRS_ICACHE_READ_LATENCY, MV_CPU_CNTRS_WB_WRITE_LATENCY,
  52728. + MV_CPU_CNTRS_LDM_STM_HOLD, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  52729. + MV_CPU_CNTRS_DATA_WRITE_ACCESS, MV_CPU_CNTRS_DATA_READ_ACCESS, MV_CPU_CNTRS_INVALID,
  52730. + MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,
  52731. + },
  52732. + /*1*/
  52733. + {
  52734. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_ICACHE_READ_MISS, MV_CPU_CNTRS_DCACHE_READ_MISS,
  52735. + MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_ITLB_MISS, MV_CPU_CNTRS_SINGLE_ISSUE,
  52736. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_RETIRED, MV_CPU_CNTRS_INVALID,
  52737. + MV_CPU_CNTRS_MMU_READ_BEAT, MV_CPU_CNTRS_ICACHE_READ_LATENCY, MV_CPU_CNTRS_WB_WRITE_BEAT,
  52738. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_IS_HOLD, MV_CPU_CNTRS_DATA_READ_ACCESS,
  52739. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  52740. + MV_CPU_CNTRS_INVALID,
  52741. + },
  52742. + /*2*/
  52743. + {
  52744. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_ACCESS,
  52745. + MV_CPU_CNTRS_DTLB_MISS, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  52746. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_PREDICT_MISS, MV_CPU_CNTRS_WB_WRITE_BEAT,
  52747. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_READ_LATENCY, MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,
  52748. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BIU_SIMULT_ACCESS,
  52749. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  52750. + MV_CPU_CNTRS_INVALID,
  52751. + },
  52752. + /*3*/
  52753. + {
  52754. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_DCACHE_READ_MISS, MV_CPU_CNTRS_DCACHE_WRITE_MISS,
  52755. + MV_CPU_CNTRS_TLB_MISS, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  52756. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_TAKEN, MV_CPU_CNTRS_WB_FULL_CYCLES,
  52757. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_READ_BEAT, MV_CPU_CNTRS_DCACHE_WRITE_BEAT,
  52758. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BIU_ANY_ACCESS,
  52759. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DATA_WRITE_ACCESS,
  52760. + MV_CPU_CNTRS_INVALID,
  52761. + }
  52762. +};
  52763. +
  52764. +MV_CPU_CNTRS_ENTRY mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];
  52765. +
  52766. +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventTbl[128];
  52767. +
  52768. +void mvCpuCntrsReset(void)
  52769. +{
  52770. + MV_U32 reg = 0;
  52771. +
  52772. + MV_ASM ("mcr p15, 0, %0, c15, c13, 0" : : "r" (reg));
  52773. + MV_ASM ("mcr p15, 0, %0, c15, c13, 1" : : "r" (reg));
  52774. + MV_ASM ("mcr p15, 0, %0, c15, c13, 2" : : "r" (reg));
  52775. + MV_ASM ("mcr p15, 0, %0, c15, c13, 3" : : "r" (reg));
  52776. + MV_ASM ("mcr p15, 0, %0, c15, c13, 4" : : "r" (reg));
  52777. + MV_ASM ("mcr p15, 0, %0, c15, c13, 5" : : "r" (reg));
  52778. + MV_ASM ("mcr p15, 0, %0, c15, c13, 6" : : "r" (reg));
  52779. + MV_ASM ("mcr p15, 0, %0, c15, c13, 7" : : "r" (reg));
  52780. +}
  52781. +
  52782. +void program_counter(int counter, int op)
  52783. +{
  52784. + MV_U32 reg = (1 << op) | 0x1; /*enable*/
  52785. +
  52786. + switch(counter)
  52787. + {
  52788. + case 0:
  52789. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 0" : : "r" (reg));
  52790. + return;
  52791. +
  52792. + case 1:
  52793. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 1" : : "r" (reg));
  52794. + return;
  52795. +
  52796. + case 2:
  52797. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 2" : : "r" (reg));
  52798. + return;
  52799. +
  52800. + case 3:
  52801. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 3" : : "r" (reg));
  52802. + return;
  52803. +
  52804. + default:
  52805. + mvOsPrintf("error in program_counter: bad counter number (%d)\n", counter);
  52806. + }
  52807. + return;
  52808. +}
  52809. +
  52810. +void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent)
  52811. +{
  52812. + int i;
  52813. +
  52814. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  52815. + {
  52816. + pEvent->counters_sum[i] = 0;
  52817. + }
  52818. + pEvent->num_of_measurements = 0;
  52819. +}
  52820. +
  52821. +
  52822. +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold)
  52823. +{
  52824. + int i;
  52825. + MV_CPU_CNTRS_EVENT* event = mvOsMalloc(sizeof(MV_CPU_CNTRS_EVENT));
  52826. +
  52827. + if(event)
  52828. + {
  52829. + strncpy(event->name, name, sizeof(event->name));
  52830. + event->num_of_measurements = 0;
  52831. + event->avg_sample_count = print_threshold;
  52832. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  52833. + {
  52834. + event->counters_before[i] = 0;
  52835. + event->counters_after[i] = 0;
  52836. + event->counters_sum[i] = 0;
  52837. + }
  52838. + }
  52839. + return event;
  52840. +}
  52841. +
  52842. +void mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event)
  52843. +{
  52844. + if(event != NULL)
  52845. + mvOsFree(event);
  52846. +}
  52847. +
  52848. +
  52849. +MV_STATUS mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op,
  52850. + char* name, MV_U32 overhead)
  52851. +{
  52852. + int i;
  52853. +
  52854. + /* Find required operations */
  52855. + for(i=0; i<MV_CPU_CNTRS_OPS_NUM; i++)
  52856. + {
  52857. + if( mvCpuCntrsOpsTbl[counter][i] == op)
  52858. + {
  52859. + strncpy(mvCpuCntrsTbl[counter].name, name, sizeof(mvCpuCntrsTbl[counter].name));
  52860. + mvCpuCntrsTbl[counter].operation = op;
  52861. + mvCpuCntrsTbl[counter].opIdx = i+1;
  52862. + mvCpuCntrsTbl[counter].overhead = overhead;
  52863. + program_counter(counter, mvCpuCntrsTbl[counter].opIdx);
  52864. + mvOsPrintf("Counter=%d, opIdx=%d, overhead=%d\n",
  52865. + counter, mvCpuCntrsTbl[counter].opIdx, mvCpuCntrsTbl[counter].overhead);
  52866. + return MV_OK;
  52867. + }
  52868. + }
  52869. + return MV_NOT_FOUND;
  52870. +}
  52871. +
  52872. +void mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent)
  52873. +{
  52874. + int i;
  52875. + MV_U64 counters_avg;
  52876. +
  52877. + if(pEvent->num_of_measurements < pEvent->avg_sample_count)
  52878. + return;
  52879. +
  52880. + mvOsPrintf("%16s: ", pEvent->name);
  52881. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  52882. + {
  52883. + counters_avg = mvOsDivMod64(pEvent->counters_sum[i],
  52884. + pEvent->num_of_measurements, NULL);
  52885. + if(counters_avg >= mvCpuCntrsTbl[i].overhead)
  52886. + counters_avg -= mvCpuCntrsTbl[i].overhead;
  52887. + else
  52888. + counters_avg = 0;
  52889. +
  52890. + mvOsPrintf("%s=%5llu, ", mvCpuCntrsTbl[i].name, counters_avg);
  52891. + }
  52892. + mvOsPrintf("\n");
  52893. + mvCpuCntrsEventClear(pEvent);
  52894. + mvCpuCntrsReset();
  52895. +}
  52896. +
  52897. +void mvCpuCntrsStatus(void)
  52898. +{
  52899. + int i;
  52900. +
  52901. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  52902. + {
  52903. + mvOsPrintf("#%d: %s, overhead=%d\n",
  52904. + i, mvCpuCntrsTbl[i].name, mvCpuCntrsTbl[i].overhead);
  52905. + }
  52906. +}
  52907. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h
  52908. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h 1970-01-01 01:00:00.000000000 +0100
  52909. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h 2011-07-31 11:31:59.353421691 +0200
  52910. @@ -0,0 +1,213 @@
  52911. +/*******************************************************************************
  52912. +Copyright (C) Marvell International Ltd. and its affiliates
  52913. +
  52914. +This software file (the "File") is owned and distributed by Marvell
  52915. +International Ltd. and/or its affiliates ("Marvell") under the following
  52916. +alternative licensing terms. Once you have made an election to distribute the
  52917. +File under one of the following license alternatives, please (i) delete this
  52918. +introductory statement regarding license alternatives, (ii) delete the two
  52919. +license alternatives that you have not elected to use and (iii) preserve the
  52920. +Marvell copyright notice above.
  52921. +
  52922. +
  52923. +********************************************************************************
  52924. +Marvell GPL License Option
  52925. +
  52926. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52927. +modify this File in accordance with the terms and conditions of the General
  52928. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  52929. +available along with the File in the license.txt file or by writing to the Free
  52930. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  52931. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  52932. +
  52933. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  52934. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  52935. +DISCLAIMED. The GPL License provides additional details about this warranty
  52936. +disclaimer.
  52937. +*******************************************************************************/
  52938. +#ifndef __mvCpuCntrs_h__
  52939. +#define __mvCpuCntrs_h__
  52940. +
  52941. +#include "mvTypes.h"
  52942. +#include "mvOs.h"
  52943. +
  52944. +
  52945. +#define MV_CPU_CNTRS_NUM 4
  52946. +#define MV_CPU_CNTRS_OPS_NUM 32
  52947. +
  52948. +typedef enum
  52949. +{
  52950. + MV_CPU_CNTRS_INVALID = 0,
  52951. + MV_CPU_CNTRS_CYCLES,
  52952. + MV_CPU_CNTRS_ICACHE_READ_MISS,
  52953. + MV_CPU_CNTRS_DCACHE_ACCESS,
  52954. + MV_CPU_CNTRS_DCACHE_READ_MISS,
  52955. + MV_CPU_CNTRS_DCACHE_READ_HIT,
  52956. + MV_CPU_CNTRS_DCACHE_WRITE_MISS,
  52957. + MV_CPU_CNTRS_DCACHE_WRITE_HIT,
  52958. + MV_CPU_CNTRS_DTLB_MISS,
  52959. + MV_CPU_CNTRS_TLB_MISS,
  52960. + MV_CPU_CNTRS_ITLB_MISS,
  52961. + MV_CPU_CNTRS_INSTRUCTIONS,
  52962. + MV_CPU_CNTRS_SINGLE_ISSUE,
  52963. + MV_CPU_CNTRS_MMU_READ_LATENCY,
  52964. + MV_CPU_CNTRS_MMU_READ_BEAT,
  52965. + MV_CPU_CNTRS_BRANCH_RETIRED,
  52966. + MV_CPU_CNTRS_BRANCH_TAKEN,
  52967. + MV_CPU_CNTRS_BRANCH_PREDICT_MISS,
  52968. + MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,
  52969. + MV_CPU_CNTRS_WB_FULL_CYCLES,
  52970. + MV_CPU_CNTRS_WB_WRITE_LATENCY,
  52971. + MV_CPU_CNTRS_WB_WRITE_BEAT,
  52972. + MV_CPU_CNTRS_ICACHE_READ_LATENCY,
  52973. + MV_CPU_CNTRS_ICACHE_READ_BEAT,
  52974. + MV_CPU_CNTRS_DCACHE_READ_LATENCY,
  52975. + MV_CPU_CNTRS_DCACHE_READ_BEAT,
  52976. + MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,
  52977. + MV_CPU_CNTRS_DCACHE_WRITE_BEAT,
  52978. + MV_CPU_CNTRS_LDM_STM_HOLD,
  52979. + MV_CPU_CNTRS_IS_HOLD,
  52980. + MV_CPU_CNTRS_DATA_WRITE_ACCESS,
  52981. + MV_CPU_CNTRS_DATA_READ_ACCESS,
  52982. + MV_CPU_CNTRS_BIU_SIMULT_ACCESS,
  52983. + MV_CPU_CNTRS_BIU_ANY_ACCESS,
  52984. +
  52985. +} MV_CPU_CNTRS_OPS;
  52986. +
  52987. +typedef struct
  52988. +{
  52989. + char name[16];
  52990. + MV_CPU_CNTRS_OPS operation;
  52991. + int opIdx;
  52992. + MV_U32 overhead;
  52993. +
  52994. +} MV_CPU_CNTRS_ENTRY;
  52995. +
  52996. +
  52997. +typedef struct
  52998. +{
  52999. + char name[16];
  53000. + MV_U32 num_of_measurements;
  53001. + MV_U32 avg_sample_count;
  53002. + MV_U64 counters_before[MV_CPU_CNTRS_NUM];
  53003. + MV_U64 counters_after[MV_CPU_CNTRS_NUM];
  53004. + MV_U64 counters_sum[MV_CPU_CNTRS_NUM];
  53005. +
  53006. +} MV_CPU_CNTRS_EVENT;
  53007. +
  53008. +extern MV_CPU_CNTRS_ENTRY mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];
  53009. +
  53010. +
  53011. +MV_STATUS mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op,
  53012. + char* name, MV_U32 overhead);
  53013. +void mvCpuCntrsInit(void);
  53014. +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold);
  53015. +void mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event);
  53016. +void mvCpuCntrsReset(void);
  53017. +void mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent);
  53018. +void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent);
  53019. +
  53020. +/* internal */
  53021. +void program_counter(int counter, int op);
  53022. +
  53023. +static INLINE MV_U64 mvCpuCntrsRead(const int counter)
  53024. +{
  53025. + MV_U32 low = 0, high = 0;
  53026. + MV_U32 ll = 0;
  53027. +
  53028. + switch(counter)
  53029. + {
  53030. + case 0:
  53031. + MV_ASM ("mcr p15, 0, %0, c15, c12, 0" : : "r" (ll));
  53032. + MV_ASM ("mrc p15, 0, %0, c15, c13, 0" : "=r" (low));
  53033. + MV_ASM ("mrc p15, 0, %0, c15, c13, 1" : "=r" (high));
  53034. + break;
  53035. +
  53036. + case 1:
  53037. + MV_ASM ("mcr p15, 0, %0, c15, c12, 1" : : "r" (ll));
  53038. + MV_ASM ("mrc p15, 0, %0, c15, c13, 2" : "=r" (low));
  53039. + MV_ASM ("mrc p15, 0, %0, c15, c13, 3" : "=r" (high));
  53040. + break;
  53041. +
  53042. + case 2:
  53043. + MV_ASM ("mcr p15, 0, %0, c15, c12, 2" : : "r" (ll));
  53044. + MV_ASM ("mrc p15, 0, %0, c15, c13, 4" : "=r" (low));
  53045. + MV_ASM ("mrc p15, 0, %0, c15, c13, 5" : "=r" (high));
  53046. + break;
  53047. +
  53048. + case 3:
  53049. + MV_ASM ("mcr p15, 0, %0, c15, c12, 3" : : "r" (ll));
  53050. + MV_ASM ("mrc p15, 0, %0, c15, c13, 6" : "=r" (low));
  53051. + MV_ASM ("mrc p15, 0, %0, c15, c13, 7" : "=r" (high));
  53052. + break;
  53053. +
  53054. + default:
  53055. + mvOsPrintf("mv_cpu_cntrs_read: bad counter number (%d)\n", counter);
  53056. + }
  53057. + program_counter(counter, mvCpuCntrsTbl[counter].opIdx);
  53058. + return (((MV_U64)high << 32 ) | low);
  53059. +
  53060. +}
  53061. +
  53062. +
  53063. +static INLINE void mvCpuCntrsReadBefore(MV_CPU_CNTRS_EVENT* pEvent)
  53064. +{
  53065. +#if 0
  53066. + int i;
  53067. +
  53068. + /* order is important - we want to measure the cycle count last here! */
  53069. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  53070. + pEvent->counters_before[i] = mvCpuCntrsRead(i);
  53071. +#else
  53072. + pEvent->counters_before[1] = mvCpuCntrsRead(1);
  53073. + pEvent->counters_before[3] = mvCpuCntrsRead(3);
  53074. + pEvent->counters_before[0] = mvCpuCntrsRead(0);
  53075. + pEvent->counters_before[2] = mvCpuCntrsRead(2);
  53076. +#endif
  53077. +}
  53078. +
  53079. +static INLINE void mvCpuCntrsReadAfter(MV_CPU_CNTRS_EVENT* pEvent)
  53080. +{
  53081. + int i;
  53082. +
  53083. +#if 0
  53084. + /* order is important - we want to measure the cycle count first here! */
  53085. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  53086. + pEvent->counters_after[i] = mvCpuCntrsRead(i);
  53087. +#else
  53088. + pEvent->counters_after[2] = mvCpuCntrsRead(2);
  53089. + pEvent->counters_after[0] = mvCpuCntrsRead(0);
  53090. + pEvent->counters_after[3] = mvCpuCntrsRead(3);
  53091. + pEvent->counters_after[1] = mvCpuCntrsRead(1);
  53092. +#endif
  53093. +
  53094. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  53095. + {
  53096. + pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);
  53097. + }
  53098. + pEvent->num_of_measurements++;
  53099. +}
  53100. +
  53101. +
  53102. +#ifdef CONFIG_MV_CPU_PERF_CNTRS
  53103. +
  53104. +#define MV_CPU_CNTRS_READ(counter) mvCpuCntrsRead(counter)
  53105. +
  53106. +#define MV_CPU_CNTRS_START(event) mvCpuCntrsReadBefore(event)
  53107. +
  53108. +#define MV_CPU_CNTRS_STOP(event) mvCpuCntrsReadAfter(event)
  53109. +
  53110. +#define MV_CPU_CNTRS_SHOW(event) mvCpuCntrsShow(event)
  53111. +
  53112. +#else
  53113. +
  53114. +#define MV_CPU_CNTRS_READ(counter)
  53115. +#define MV_CPU_CNTRS_START(event)
  53116. +#define MV_CPU_CNTRS_STOP(event)
  53117. +#define MV_CPU_CNTRS_SHOW(event)
  53118. +
  53119. +#endif /* CONFIG_MV_CPU_PERF_CNTRS */
  53120. +
  53121. +
  53122. +#endif /* __mvCpuCntrs_h__ */
  53123. +
  53124. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c
  53125. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c 1970-01-01 01:00:00.000000000 +0100
  53126. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c 2011-07-31 11:31:59.453817640 +0200
  53127. @@ -0,0 +1,143 @@
  53128. +/*
  53129. + * This program is free software; you can redistribute it and/or modify
  53130. + * it under the terms of the GNU General Public License as published by
  53131. + * the Free Software Foundation; either version 2 of the License, or
  53132. + * (at your option) any later version.
  53133. + *
  53134. + * This program is distributed in the hope that it will be useful,
  53135. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  53136. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  53137. + * GNU General Public License for more details.
  53138. + *
  53139. + * You should have received a copy of the GNU General Public License
  53140. + * along with this program; if not, write to the Free Software
  53141. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  53142. + */
  53143. +
  53144. +#include "mvOs.h"
  53145. +#include "mvCpuL2Cntrs.h"
  53146. +
  53147. +
  53148. +
  53149. +MV_CPU_L2_CNTRS_ENTRY mvCpuL2CntrsTbl[MV_CPU_L2_CNTRS_NUM];
  53150. +
  53151. +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventTbl[128];
  53152. +
  53153. +void mvCpuL2CntrsReset(void)
  53154. +{
  53155. + MV_U32 reg = 0;
  53156. +
  53157. + MV_ASM ("mcr p15, 6, %0, c15, c13, 0" : : "r" (reg));
  53158. + MV_ASM ("mcr p15, 6, %0, c15, c13, 1" : : "r" (reg));
  53159. + MV_ASM ("mcr p15, 6, %0, c15, c13, 2" : : "r" (reg));
  53160. + MV_ASM ("mcr p15, 6, %0, c15, c13, 3" : : "r" (reg));
  53161. +}
  53162. +
  53163. +static void mvCpuL2CntrConfig(int counter, int op)
  53164. +{
  53165. + MV_U32 reg = (1 << op) | 0x1; /*enable*/
  53166. +
  53167. + switch(counter)
  53168. + {
  53169. + case 0:
  53170. + MV_ASM ("mcr p15, 6, %0, c15, c12, 0" : : "r" (reg));
  53171. + return;
  53172. +
  53173. + case 1:
  53174. + MV_ASM ("mcr p15, 6, %0, c15, c12, 1" : : "r" (reg));
  53175. + return;
  53176. +
  53177. + default:
  53178. + mvOsPrintf("mvCpuL2CntrConfig: bad counter number (%d)\n", counter);
  53179. + }
  53180. + return;
  53181. +}
  53182. +
  53183. +void mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent)
  53184. +{
  53185. + int i;
  53186. +
  53187. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  53188. + {
  53189. + pEvent->counters_sum[i] = 0;
  53190. + }
  53191. + pEvent->num_of_measurements = 0;
  53192. +}
  53193. +
  53194. +
  53195. +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold)
  53196. +{
  53197. + int i;
  53198. + MV_CPU_L2_CNTRS_EVENT* event = mvOsMalloc(sizeof(MV_CPU_L2_CNTRS_EVENT));
  53199. +
  53200. + if(event)
  53201. + {
  53202. + strncpy(event->name, name, sizeof(event->name));
  53203. + event->num_of_measurements = 0;
  53204. + event->avg_sample_count = print_threshold;
  53205. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  53206. + {
  53207. + event->counters_before[i] = 0;
  53208. + event->counters_after[i] = 0;
  53209. + event->counters_sum[i] = 0;
  53210. + }
  53211. + }
  53212. + return event;
  53213. +}
  53214. +
  53215. +void mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event)
  53216. +{
  53217. + if(event != NULL)
  53218. + mvOsFree(event);
  53219. +}
  53220. +
  53221. +
  53222. +MV_STATUS mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op,
  53223. + char* name, MV_U32 overhead)
  53224. +{
  53225. + strncpy(mvCpuL2CntrsTbl[counter].name, name, sizeof(mvCpuL2CntrsTbl[counter].name));
  53226. + mvCpuL2CntrsTbl[counter].operation = op;
  53227. + mvCpuL2CntrsTbl[counter].opIdx = op;
  53228. + mvCpuL2CntrsTbl[counter].overhead = overhead;
  53229. + mvCpuL2CntrConfig(counter, op);
  53230. + mvOsPrintf("CPU L2 Counter %d: operation=%d, overhead=%d\n",
  53231. + counter, op, overhead);
  53232. + return MV_OK;
  53233. +}
  53234. +
  53235. +void mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent)
  53236. +{
  53237. + int i;
  53238. + MV_U64 counters_avg;
  53239. +
  53240. + if(pEvent->num_of_measurements < pEvent->avg_sample_count)
  53241. + return;
  53242. +
  53243. + mvOsPrintf("%16s: ", pEvent->name);
  53244. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  53245. + {
  53246. + counters_avg = mvOsDivMod64(pEvent->counters_sum[i],
  53247. + pEvent->num_of_measurements, NULL);
  53248. +
  53249. + if(counters_avg >= mvCpuL2CntrsTbl[i].overhead)
  53250. + counters_avg -= mvCpuL2CntrsTbl[i].overhead;
  53251. + else
  53252. + counters_avg = 0;
  53253. +
  53254. + mvOsPrintf("%s=%5llu, ", mvCpuL2CntrsTbl[i].name, counters_avg);
  53255. + }
  53256. + mvOsPrintf("\n");
  53257. + mvCpuL2CntrsEventClear(pEvent);
  53258. + mvCpuL2CntrsReset();
  53259. +}
  53260. +
  53261. +void mvCpuL2CntrsStatus(void)
  53262. +{
  53263. + int i;
  53264. +
  53265. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  53266. + {
  53267. + mvOsPrintf("#%d: %s, overhead=%d\n",
  53268. + i, mvCpuL2CntrsTbl[i].name, mvCpuL2CntrsTbl[i].overhead);
  53269. + }
  53270. +}
  53271. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h
  53272. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h 1970-01-01 01:00:00.000000000 +0100
  53273. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h 2011-07-31 11:31:59.493426715 +0200
  53274. @@ -0,0 +1,151 @@
  53275. +/*******************************************************************************
  53276. +Copyright (C) Marvell International Ltd. and its affiliates
  53277. +
  53278. +This software file (the "File") is owned and distributed by Marvell
  53279. +International Ltd. and/or its affiliates ("Marvell") under the following
  53280. +alternative licensing terms. Once you have made an election to distribute the
  53281. +File under one of the following license alternatives, please (i) delete this
  53282. +introductory statement regarding license alternatives, (ii) delete the two
  53283. +license alternatives that you have not elected to use and (iii) preserve the
  53284. +Marvell copyright notice above.
  53285. +
  53286. +
  53287. +********************************************************************************
  53288. +Marvell GPL License Option
  53289. +
  53290. +If you received this File from Marvell, you may opt to use, redistribute and/or
  53291. +modify this File in accordance with the terms and conditions of the General
  53292. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  53293. +available along with the File in the license.txt file or by writing to the Free
  53294. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  53295. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  53296. +
  53297. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  53298. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  53299. +DISCLAIMED. The GPL License provides additional details about this warranty
  53300. +disclaimer.
  53301. +*******************************************************************************/
  53302. +#ifndef __mvCpuL2Cntrs_h__
  53303. +#define __mvCpuL2Cntrs_h__
  53304. +
  53305. +#include "mvTypes.h"
  53306. +#include "mvOs.h"
  53307. +
  53308. +
  53309. +#define MV_CPU_L2_CNTRS_NUM 2
  53310. +
  53311. +typedef enum
  53312. +{
  53313. + MV_CPU_L2_CNTRS_ENABLE = 0,
  53314. + MV_CPU_L2_CNTRS_DATA_REQ,
  53315. + MV_CPU_L2_CNTRS_DATA_MISS_REQ,
  53316. + MV_CPU_L2_CNTRS_INST_REQ,
  53317. + MV_CPU_L2_CNTRS_INST_MISS_REQ,
  53318. + MV_CPU_L2_CNTRS_DATA_READ_REQ,
  53319. + MV_CPU_L2_CNTRS_DATA_READ_MISS_REQ,
  53320. + MV_CPU_L2_CNTRS_DATA_WRITE_REQ,
  53321. + MV_CPU_L2_CNTRS_DATA_WRITE_MISS_REQ,
  53322. + MV_CPU_L2_CNTRS_RESERVED,
  53323. + MV_CPU_L2_CNTRS_DIRTY_EVICT_REQ,
  53324. + MV_CPU_L2_CNTRS_EVICT_BUFF_STALL,
  53325. + MV_CPU_L2_CNTRS_ACTIVE_CYCLES,
  53326. +
  53327. +} MV_CPU_L2_CNTRS_OPS;
  53328. +
  53329. +typedef struct
  53330. +{
  53331. + char name[16];
  53332. + MV_CPU_L2_CNTRS_OPS operation;
  53333. + int opIdx;
  53334. + MV_U32 overhead;
  53335. +
  53336. +} MV_CPU_L2_CNTRS_ENTRY;
  53337. +
  53338. +
  53339. +typedef struct
  53340. +{
  53341. + char name[16];
  53342. + MV_U32 num_of_measurements;
  53343. + MV_U32 avg_sample_count;
  53344. + MV_U64 counters_before[MV_CPU_L2_CNTRS_NUM];
  53345. + MV_U64 counters_after[MV_CPU_L2_CNTRS_NUM];
  53346. + MV_U64 counters_sum[MV_CPU_L2_CNTRS_NUM];
  53347. +
  53348. +} MV_CPU_L2_CNTRS_EVENT;
  53349. +
  53350. +
  53351. +MV_STATUS mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op,
  53352. + char* name, MV_U32 overhead);
  53353. +void mvCpuL2CntrsInit(void);
  53354. +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold);
  53355. +void mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event);
  53356. +void mvCpuL2CntrsReset(void);
  53357. +void mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent);
  53358. +void mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent);
  53359. +
  53360. +static INLINE MV_U64 mvCpuL2CntrsRead(const int counter)
  53361. +{
  53362. + MV_U32 low = 0, high = 0;
  53363. +
  53364. + switch(counter)
  53365. + {
  53366. + case 0:
  53367. + MV_ASM ("mrc p15, 6, %0, c15, c13, 0" : "=r" (low));
  53368. + MV_ASM ("mrc p15, 6, %0, c15, c13, 1" : "=r" (high));
  53369. + break;
  53370. +
  53371. + case 1:
  53372. + MV_ASM ("mrc p15, 6, %0, c15, c13, 2" : "=r" (low));
  53373. + MV_ASM ("mrc p15, 6, %0, c15, c13, 3" : "=r" (high));
  53374. + break;
  53375. +
  53376. + default:
  53377. + mvOsPrintf("mvCpuL2CntrsRead: bad counter number (%d)\n", counter);
  53378. + }
  53379. + return (((MV_U64)high << 32 ) | low);
  53380. +
  53381. +}
  53382. +
  53383. +static INLINE void mvCpuL2CntrsReadBefore(MV_CPU_L2_CNTRS_EVENT* pEvent)
  53384. +{
  53385. + int i;
  53386. +
  53387. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  53388. + pEvent->counters_before[i] = mvCpuL2CntrsRead(i);
  53389. +}
  53390. +
  53391. +static INLINE void mvCpuL2CntrsReadAfter(MV_CPU_L2_CNTRS_EVENT* pEvent)
  53392. +{
  53393. + int i;
  53394. +
  53395. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  53396. + {
  53397. + pEvent->counters_after[i] = mvCpuL2CntrsRead(i);
  53398. + pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);
  53399. + }
  53400. + pEvent->num_of_measurements++;
  53401. +}
  53402. +
  53403. +
  53404. +#ifdef CONFIG_MV_CPU_L2_PERF_CNTRS
  53405. +
  53406. +#define MV_CPU_L2_CNTRS_READ(counter) mvCpuL2CntrsRead(counter)
  53407. +
  53408. +#define MV_CPU_L2_CNTRS_START(event) mvCpuL2CntrsReadBefore(event)
  53409. +
  53410. +#define MV_CPU_L2_CNTRS_STOP(event) mvCpuL2CntrsReadAfter(event)
  53411. +
  53412. +#define MV_CPU_L2_CNTRS_SHOW(event) mvCpuL2CntrsShow(event)
  53413. +
  53414. +#else
  53415. +
  53416. +#define MV_CPU_L2_CNTRS_READ(counter)
  53417. +#define MV_CPU_L2_CNTRS_START(event)
  53418. +#define MV_CPU_L2_CNTRS_STOP(event)
  53419. +#define MV_CPU_L2_CNTRS_SHOW(event)
  53420. +
  53421. +#endif /* CONFIG_MV_CPU_L2_PERF_CNTRS */
  53422. +
  53423. +
  53424. +#endif /* __mvCpuL2Cntrs_h__ */
  53425. +
  53426. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c
  53427. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c 1970-01-01 01:00:00.000000000 +0100
  53428. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c 2011-07-31 11:31:59.523424060 +0200
  53429. @@ -0,0 +1,1479 @@
  53430. +/*******************************************************************************
  53431. +Copyright (C) Marvell International Ltd. and its affiliates
  53432. +
  53433. +This software file (the "File") is owned and distributed by Marvell
  53434. +International Ltd. and/or its affiliates ("Marvell") under the following
  53435. +alternative licensing terms. Once you have made an election to distribute the
  53436. +File under one of the following license alternatives, please (i) delete this
  53437. +introductory statement regarding license alternatives, (ii) delete the two
  53438. +license alternatives that you have not elected to use and (iii) preserve the
  53439. +Marvell copyright notice above.
  53440. +
  53441. +********************************************************************************
  53442. +Marvell Commercial License Option
  53443. +
  53444. +If you received this File from Marvell and you have entered into a commercial
  53445. +license agreement (a "Commercial License") with Marvell, the File is licensed
  53446. +to you under the terms of the applicable Commercial License.
  53447. +
  53448. +********************************************************************************
  53449. +Marvell GPL License Option
  53450. +
  53451. +If you received this File from Marvell, you may opt to use, redistribute and/or
  53452. +modify this File in accordance with the terms and conditions of the General
  53453. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  53454. +available along with the File in the license.txt file or by writing to the Free
  53455. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  53456. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  53457. +
  53458. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  53459. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  53460. +DISCLAIMED. The GPL License provides additional details about this warranty
  53461. +disclaimer.
  53462. +********************************************************************************
  53463. +Marvell BSD License Option
  53464. +
  53465. +If you received this File from Marvell, you may opt to use, redistribute and/or
  53466. +modify this File under the following licensing terms.
  53467. +Redistribution and use in source and binary forms, with or without modification,
  53468. +are permitted provided that the following conditions are met:
  53469. +
  53470. + * Redistributions of source code must retain the above copyright notice,
  53471. + this list of conditions and the following disclaimer.
  53472. +
  53473. + * Redistributions in binary form must reproduce the above copyright
  53474. + notice, this list of conditions and the following disclaimer in the
  53475. + documentation and/or other materials provided with the distribution.
  53476. +
  53477. + * Neither the name of Marvell nor the names of its contributors may be
  53478. + used to endorse or promote products derived from this software without
  53479. + specific prior written permission.
  53480. +
  53481. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  53482. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  53483. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  53484. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  53485. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  53486. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  53487. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  53488. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  53489. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  53490. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  53491. +
  53492. +*******************************************************************************/
  53493. +
  53494. +#include "ddr1_2/mvDram.h"
  53495. +#include "boardEnv/mvBoardEnvLib.h"
  53496. +
  53497. +#undef MV_DEBUG
  53498. +#ifdef MV_DEBUG
  53499. +#define DB(x) x
  53500. +#else
  53501. +#define DB(x)
  53502. +#endif
  53503. +
  53504. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  53505. + MV_DRAM_BANK_INFO *pBankInfo);
  53506. +static MV_U32 cas2ps(MV_U8 spd_byte);
  53507. +/*******************************************************************************
  53508. +* mvDramBankGet - Get the DRAM bank paramters.
  53509. +*
  53510. +* DESCRIPTION:
  53511. +* This function retrieves DRAM bank parameters as described in
  53512. +* DRAM_BANK_INFO struct to the controller DRAM unit. In case the board
  53513. +* has its DRAM on DIMMs it will use its EEPROM to extract SPD data
  53514. +* from it. Otherwise, if the DRAM is soldered on board, the function
  53515. +* should insert its bank information into MV_DRAM_BANK_INFO struct.
  53516. +*
  53517. +* INPUT:
  53518. +* bankNum - Board DRAM bank number.
  53519. +*
  53520. +* OUTPUT:
  53521. +* pBankInfo - DRAM bank information struct.
  53522. +*
  53523. +* RETURN:
  53524. +* MV_FAIL - Bank parameters could not be read.
  53525. +*
  53526. +*******************************************************************************/
  53527. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
  53528. +{
  53529. + MV_DIMM_INFO dimmInfo;
  53530. +
  53531. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
  53532. + /* zero pBankInfo structure */
  53533. + memset(pBankInfo, 0, sizeof(*pBankInfo));
  53534. +
  53535. + if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
  53536. + {
  53537. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  53538. + return MV_BAD_PARAM;
  53539. + }
  53540. + if( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
  53541. + {
  53542. + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
  53543. + return MV_FAIL;
  53544. + }
  53545. + if((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
  53546. + {
  53547. + DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
  53548. + return MV_FAIL;
  53549. + }
  53550. +
  53551. + /* convert Dimm info to Bank info */
  53552. + cpyDimm2BankInfo(&dimmInfo, pBankInfo);
  53553. +
  53554. + return MV_OK;
  53555. +}
  53556. +
  53557. +/*******************************************************************************
  53558. +* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
  53559. +*
  53560. +* DESCRIPTION:
  53561. +* Convert a Dimm info struct into a bank info struct.
  53562. +*
  53563. +* INPUT:
  53564. +* pDimmInfo - DIMM information structure.
  53565. +*
  53566. +* OUTPUT:
  53567. +* pBankInfo - DRAM bank information struct.
  53568. +*
  53569. +* RETURN:
  53570. +* None.
  53571. +*
  53572. +*******************************************************************************/
  53573. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  53574. + MV_DRAM_BANK_INFO *pBankInfo)
  53575. +{
  53576. + pBankInfo->memoryType = pDimmInfo->memoryType;
  53577. +
  53578. + /* DIMM dimensions */
  53579. + pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
  53580. + pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
  53581. + pBankInfo->dataWidth = pDimmInfo->dataWidth;
  53582. + pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
  53583. + pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
  53584. + pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
  53585. + pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
  53586. + pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
  53587. + pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
  53588. +
  53589. + /* DIMM timing parameters */
  53590. + pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
  53591. + pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  53592. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
  53593. + pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  53594. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
  53595. +
  53596. + pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
  53597. + pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
  53598. + pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
  53599. + pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
  53600. + pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
  53601. + pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
  53602. + pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
  53603. + pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
  53604. +
  53605. + /* Parameters calculated from the extracted DIMM information */
  53606. + pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
  53607. + pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
  53608. + pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
  53609. + pDimmInfo->numOfModuleBanks;
  53610. +
  53611. + /* DIMM attributes (MV_TRUE for yes) */
  53612. +
  53613. + if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
  53614. + (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
  53615. + {
  53616. + if (pDimmInfo->dimmAttributes & BIT1)
  53617. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  53618. + else
  53619. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  53620. + }
  53621. + else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
  53622. + {
  53623. + if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
  53624. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  53625. + else
  53626. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  53627. + }
  53628. +
  53629. + return;
  53630. +}
  53631. +
  53632. +/*******************************************************************************
  53633. +* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
  53634. +*
  53635. +* DESCRIPTION:
  53636. +* Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
  53637. +*
  53638. +* INPUT:
  53639. +* None.
  53640. +*
  53641. +* OUTPUT:
  53642. +* None.
  53643. +*
  53644. +* RETURN:
  53645. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  53646. +*
  53647. +*******************************************************************************/
  53648. +MV_STATUS dimmSpdCpy(MV_VOID)
  53649. +{
  53650. + MV_U32 i;
  53651. + MV_U32 spdChecksum;
  53652. +
  53653. + MV_TWSI_SLAVE twsiSlave;
  53654. + MV_U8 data[SPD_SIZE];
  53655. +
  53656. + /* zero dimmInfo structure */
  53657. + memset(data, 0, SPD_SIZE);
  53658. +
  53659. + /* read the dimm eeprom */
  53660. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  53661. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
  53662. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  53663. + twsiSlave.validOffset = MV_TRUE;
  53664. + twsiSlave.offset = 0;
  53665. + twsiSlave.moreThen256 = MV_FALSE;
  53666. +
  53667. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
  53668. + &twsiSlave, data, SPD_SIZE) )
  53669. + {
  53670. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
  53671. + return MV_FAIL;
  53672. + }
  53673. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  53674. +
  53675. + /* calculate SPD checksum */
  53676. + spdChecksum = 0;
  53677. +
  53678. + for(i = 0 ; i <= 62 ; i++)
  53679. + {
  53680. + spdChecksum += data[i];
  53681. + }
  53682. +
  53683. + if ((spdChecksum & 0xff) != data[63])
  53684. + {
  53685. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  53686. + (MV_U32)(spdChecksum & 0xff), data[63]));
  53687. + }
  53688. + else
  53689. + {
  53690. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  53691. + }
  53692. +
  53693. + /* copy the SPD content 1:1 into the DIMM 1 SPD */
  53694. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
  53695. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  53696. + twsiSlave.validOffset = MV_TRUE;
  53697. + twsiSlave.offset = 0;
  53698. + twsiSlave.moreThen256 = MV_FALSE;
  53699. +
  53700. + for(i = 0 ; i < SPD_SIZE ; i++)
  53701. + {
  53702. + twsiSlave.offset = i;
  53703. + if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL,
  53704. + &twsiSlave, &data[i], 1) )
  53705. + {
  53706. + mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
  53707. + return MV_FAIL;
  53708. + }
  53709. + mvOsDelay(5);
  53710. + }
  53711. +
  53712. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  53713. + return MV_OK;
  53714. +}
  53715. +
  53716. +/*******************************************************************************
  53717. +* dimmSpdGet - Get the SPD parameters.
  53718. +*
  53719. +* DESCRIPTION:
  53720. +* Read the DIMM SPD parameters into given struct parameter.
  53721. +*
  53722. +* INPUT:
  53723. +* dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
  53724. +*
  53725. +* OUTPUT:
  53726. +* pDimmInfo - DIMM information structure.
  53727. +*
  53728. +* RETURN:
  53729. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  53730. +*
  53731. +*******************************************************************************/
  53732. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
  53733. +{
  53734. + MV_U32 i;
  53735. + MV_U32 density = 1;
  53736. + MV_U32 spdChecksum;
  53737. +
  53738. + MV_TWSI_SLAVE twsiSlave;
  53739. + MV_U8 data[SPD_SIZE];
  53740. +
  53741. + if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
  53742. + {
  53743. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  53744. + return MV_BAD_PARAM;
  53745. + }
  53746. +
  53747. + /* zero dimmInfo structure */
  53748. + memset(data, 0, SPD_SIZE);
  53749. +
  53750. + /* read the dimm eeprom */
  53751. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  53752. + twsiSlave.slaveAddr.address = (dimmNum == 0) ?
  53753. + MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
  53754. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  53755. + twsiSlave.validOffset = MV_TRUE;
  53756. + twsiSlave.offset = 0;
  53757. + twsiSlave.moreThen256 = MV_FALSE;
  53758. +
  53759. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
  53760. + &twsiSlave, data, SPD_SIZE) )
  53761. + {
  53762. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
  53763. + return MV_FAIL;
  53764. + }
  53765. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  53766. +
  53767. + /* calculate SPD checksum */
  53768. + spdChecksum = 0;
  53769. +
  53770. + for(i = 0 ; i <= 62 ; i++)
  53771. + {
  53772. + spdChecksum += data[i];
  53773. + }
  53774. +
  53775. + if ((spdChecksum & 0xff) != data[63])
  53776. + {
  53777. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  53778. + (MV_U32)(spdChecksum & 0xff), data[63]));
  53779. + }
  53780. + else
  53781. + {
  53782. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  53783. + }
  53784. +
  53785. + /* copy the SPD content 1:1 into the dimmInfo structure*/
  53786. + for(i = 0 ; i < SPD_SIZE ; i++)
  53787. + {
  53788. + pDimmInfo->spdRawData[i] = data[i];
  53789. + DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
  53790. + }
  53791. +
  53792. + DB(mvOsPrintf("DRAM SPD Information:\n"));
  53793. +
  53794. + /* Memory type (DDR / SDRAM) */
  53795. + switch (data[DIMM_MEM_TYPE])
  53796. + {
  53797. + case (DIMM_MEM_TYPE_SDRAM):
  53798. + pDimmInfo->memoryType = MEM_TYPE_SDRAM;
  53799. + DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
  53800. + break;
  53801. + case (DIMM_MEM_TYPE_DDR1):
  53802. + pDimmInfo->memoryType = MEM_TYPE_DDR1;
  53803. + DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
  53804. + break;
  53805. + case (DIMM_MEM_TYPE_DDR2):
  53806. + pDimmInfo->memoryType = MEM_TYPE_DDR2;
  53807. + DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
  53808. + break;
  53809. + default:
  53810. + mvOsPrintf("ERROR: Undefined memory type!\n");
  53811. + return MV_ERROR;
  53812. + }
  53813. +
  53814. +
  53815. + /* Number Of Row Addresses */
  53816. + pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
  53817. + DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
  53818. +
  53819. + /* Number Of Column Addresses */
  53820. + pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
  53821. + DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
  53822. +
  53823. + /* Number Of Module Banks */
  53824. + pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
  53825. + DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
  53826. + pDimmInfo->numOfModuleBanks));
  53827. +
  53828. + /* Number of module banks encoded differently for DDR2 */
  53829. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  53830. + pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
  53831. +
  53832. + /* Data Width */
  53833. + pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
  53834. + DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
  53835. +
  53836. + /* Minimum Cycle Time At Max CasLatancy */
  53837. + pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
  53838. +
  53839. + /* Error Check Type */
  53840. + pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
  53841. + DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
  53842. + pDimmInfo->errorCheckType));
  53843. +
  53844. + /* Refresh Interval */
  53845. + pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
  53846. + DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
  53847. + pDimmInfo->refreshInterval));
  53848. +
  53849. + /* Sdram Width */
  53850. + pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
  53851. + DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
  53852. +
  53853. + /* Error Check Data Width */
  53854. + pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
  53855. + DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
  53856. + pDimmInfo->errorCheckDataWidth));
  53857. +
  53858. + /* Burst Length Supported */
  53859. + /* SDRAM/DDR1:
  53860. + *******-******-******-******-******-******-******-*******
  53861. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53862. + *******-******-******-******-******-******-******-*******
  53863. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  53864. + *********************************************************/
  53865. + /* DDR2:
  53866. + *******-******-******-******-******-******-******-*******
  53867. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53868. + *******-******-******-******-******-******-******-*******
  53869. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  53870. + *********************************************************/
  53871. +
  53872. + pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
  53873. + DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
  53874. + pDimmInfo->burstLengthSupported));
  53875. +
  53876. + /* Number Of Banks On Each Device */
  53877. + pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
  53878. + DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
  53879. + pDimmInfo->numOfBanksOnEachDevice));
  53880. +
  53881. + /* Suported Cas Latencies */
  53882. +
  53883. + /* SDRAM:
  53884. + *******-******-******-******-******-******-******-*******
  53885. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53886. + *******-******-******-******-******-******-******-*******
  53887. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  53888. + ********************************************************/
  53889. +
  53890. + /* DDR 1:
  53891. + *******-******-******-******-******-******-******-*******
  53892. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53893. + *******-******-******-******-******-******-******-*******
  53894. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  53895. + *********************************************************/
  53896. +
  53897. + /* DDR 2:
  53898. + *******-******-******-******-******-******-******-*******
  53899. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53900. + *******-******-******-******-******-******-******-*******
  53901. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  53902. + *********************************************************/
  53903. +
  53904. + pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
  53905. + DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
  53906. + pDimmInfo->suportedCasLatencies));
  53907. +
  53908. + /* For DDR2 only, get the DIMM type information */
  53909. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  53910. + {
  53911. + pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
  53912. + DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
  53913. + pDimmInfo->dimmTypeInfo));
  53914. + }
  53915. +
  53916. + /* SDRAM Modules Attributes */
  53917. + pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
  53918. + DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
  53919. + pDimmInfo->dimmAttributes));
  53920. +
  53921. + /* Minimum Cycle Time At Max CasLatancy Minus 1*/
  53922. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  53923. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
  53924. +
  53925. + /* Minimum Cycle Time At Max CasLatancy Minus 2*/
  53926. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  53927. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
  53928. +
  53929. + pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
  53930. + DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
  53931. + pDimmInfo->minRowPrechargeTime));
  53932. + pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
  53933. + DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
  53934. + pDimmInfo->minRowActiveToRowActive));
  53935. + pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
  53936. + DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
  53937. + pDimmInfo->minRasToCasDelay));
  53938. + pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
  53939. + DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
  53940. + pDimmInfo->minRasPulseWidth));
  53941. +
  53942. + /* DIMM Bank Density */
  53943. + pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
  53944. + DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
  53945. + pDimmInfo->dimmBankDensity));
  53946. +
  53947. + /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
  53948. + pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
  53949. + DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
  53950. + pDimmInfo->minWriteRecoveryTime));
  53951. +
  53952. + /* Only DDR2 includes Internal Write To Read Command Delay field. */
  53953. + pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
  53954. + DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
  53955. + pDimmInfo->minWriteToReadCmdDelay));
  53956. +
  53957. + /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
  53958. + pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
  53959. + DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
  53960. + pDimmInfo->minReadToPrechCmdDelay));
  53961. +
  53962. + /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
  53963. + pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
  53964. + DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
  53965. + pDimmInfo->minRefreshToActiveCmd));
  53966. +
  53967. + /* calculating the sdram density. Representing device density from */
  53968. + /* bit 20 to allow representation of 4GB and above. */
  53969. + /* For example, if density is 512Mbit 0x20000000, will be represent in */
  53970. + /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
  53971. + /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
  53972. + density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
  53973. + pDimmInfo->deviceDensity = density *
  53974. + pDimmInfo->numOfBanksOnEachDevice *
  53975. + pDimmInfo->sdramWidth;
  53976. + DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
  53977. +
  53978. + /* Number of devices includeing Error correction */
  53979. + pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
  53980. + pDimmInfo->numOfModuleBanks;
  53981. + DB(mvOsPrintf("DRAM numberOfDevices %d\n",
  53982. + pDimmInfo->numberOfDevices));
  53983. +
  53984. + pDimmInfo->size = 0;
  53985. +
  53986. + /* Note that pDimmInfo->size is in MB units */
  53987. + if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
  53988. + {
  53989. + if (pDimmInfo->dimmBankDensity & BIT0)
  53990. + pDimmInfo->size += 1024; /* Equal to 1GB */
  53991. + else if (pDimmInfo->dimmBankDensity & BIT1)
  53992. + pDimmInfo->size += 8; /* Equal to 8MB */
  53993. + else if (pDimmInfo->dimmBankDensity & BIT2)
  53994. + pDimmInfo->size += 16; /* Equal to 16MB */
  53995. + else if (pDimmInfo->dimmBankDensity & BIT3)
  53996. + pDimmInfo->size += 32; /* Equal to 32MB */
  53997. + else if (pDimmInfo->dimmBankDensity & BIT4)
  53998. + pDimmInfo->size += 64; /* Equal to 64MB */
  53999. + else if (pDimmInfo->dimmBankDensity & BIT5)
  54000. + pDimmInfo->size += 128; /* Equal to 128MB */
  54001. + else if (pDimmInfo->dimmBankDensity & BIT6)
  54002. + pDimmInfo->size += 256; /* Equal to 256MB */
  54003. + else if (pDimmInfo->dimmBankDensity & BIT7)
  54004. + pDimmInfo->size += 512; /* Equal to 512MB */
  54005. + }
  54006. + else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
  54007. + {
  54008. + if (pDimmInfo->dimmBankDensity & BIT0)
  54009. + pDimmInfo->size += 1024; /* Equal to 1GB */
  54010. + else if (pDimmInfo->dimmBankDensity & BIT1)
  54011. + pDimmInfo->size += 2048; /* Equal to 2GB */
  54012. + else if (pDimmInfo->dimmBankDensity & BIT2)
  54013. + pDimmInfo->size += 16; /* Equal to 16MB */
  54014. + else if (pDimmInfo->dimmBankDensity & BIT3)
  54015. + pDimmInfo->size += 32; /* Equal to 32MB */
  54016. + else if (pDimmInfo->dimmBankDensity & BIT4)
  54017. + pDimmInfo->size += 64; /* Equal to 64MB */
  54018. + else if (pDimmInfo->dimmBankDensity & BIT5)
  54019. + pDimmInfo->size += 128; /* Equal to 128MB */
  54020. + else if (pDimmInfo->dimmBankDensity & BIT6)
  54021. + pDimmInfo->size += 256; /* Equal to 256MB */
  54022. + else if (pDimmInfo->dimmBankDensity & BIT7)
  54023. + pDimmInfo->size += 512; /* Equal to 512MB */
  54024. + }
  54025. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  54026. + {
  54027. + if (pDimmInfo->dimmBankDensity & BIT0)
  54028. + pDimmInfo->size += 1024; /* Equal to 1GB */
  54029. + else if (pDimmInfo->dimmBankDensity & BIT1)
  54030. + pDimmInfo->size += 2048; /* Equal to 2GB */
  54031. + else if (pDimmInfo->dimmBankDensity & BIT2)
  54032. + pDimmInfo->size += 4096; /* Equal to 4GB */
  54033. + else if (pDimmInfo->dimmBankDensity & BIT3)
  54034. + pDimmInfo->size += 8192; /* Equal to 8GB */
  54035. + else if (pDimmInfo->dimmBankDensity & BIT4)
  54036. + pDimmInfo->size += 16384; /* Equal to 16GB */
  54037. + else if (pDimmInfo->dimmBankDensity & BIT5)
  54038. + pDimmInfo->size += 128; /* Equal to 128MB */
  54039. + else if (pDimmInfo->dimmBankDensity & BIT6)
  54040. + pDimmInfo->size += 256; /* Equal to 256MB */
  54041. + else if (pDimmInfo->dimmBankDensity & BIT7)
  54042. + pDimmInfo->size += 512; /* Equal to 512MB */
  54043. + }
  54044. +
  54045. + pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
  54046. +
  54047. + DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
  54048. +
  54049. + return MV_OK;
  54050. +}
  54051. +
  54052. +/*******************************************************************************
  54053. +* dimmSpdPrint - Print the SPD parameters.
  54054. +*
  54055. +* DESCRIPTION:
  54056. +* Print the Dimm SPD parameters.
  54057. +*
  54058. +* INPUT:
  54059. +* pDimmInfo - DIMM information structure.
  54060. +*
  54061. +* OUTPUT:
  54062. +* None.
  54063. +*
  54064. +* RETURN:
  54065. +* None.
  54066. +*
  54067. +*******************************************************************************/
  54068. +MV_VOID dimmSpdPrint(MV_U32 dimmNum)
  54069. +{
  54070. + MV_DIMM_INFO dimmInfo;
  54071. + MV_U32 i, temp = 0;
  54072. + MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
  54073. + MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
  54074. + MV_U32 busClkPs;
  54075. + MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
  54076. + temp_buf[40], *spdRawData;
  54077. +
  54078. + busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
  54079. +
  54080. + spdRawData = dimmInfo.spdRawData;
  54081. +
  54082. + if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
  54083. + {
  54084. + mvOsOutput("ERROR: Could not read SPD information!\n");
  54085. + return;
  54086. + }
  54087. +
  54088. + /* find Manufactura of Dimm Module */
  54089. + mvOsOutput("\nManufacturer's JEDEC ID Code: ");
  54090. + for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
  54091. + {
  54092. + mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
  54093. + }
  54094. + mvOsOutput("\n");
  54095. +
  54096. + /* Manufacturer's Specific Data */
  54097. + for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
  54098. + {
  54099. + temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
  54100. + }
  54101. + mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
  54102. +
  54103. + /* Module Part Number */
  54104. + for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
  54105. + {
  54106. + temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
  54107. + }
  54108. + mvOsOutput("Module Part Number: %s\n", temp_buf);
  54109. +
  54110. + /* Module Serial Number */
  54111. + for(i = 0; i < sizeof(MV_U32); i++)
  54112. + {
  54113. + temp |= spdRawData[95+i] << 8*i;
  54114. + }
  54115. + mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
  54116. + (long)temp);
  54117. +
  54118. + /* find Manufac-Data of Dimm Module */
  54119. + mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
  54120. + ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
  54121. + ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
  54122. + /* find modul_revision of Dimm Module */
  54123. + mvOsOutput("Module Revision: %d.%d\n",
  54124. + spdRawData[91], spdRawData[92]);
  54125. +
  54126. + /* find manufac_place of Dimm Module */
  54127. + mvOsOutput("manufac_place: %d\n", spdRawData[72]);
  54128. +
  54129. + /* go over the first 35 I2C data bytes */
  54130. + for(i = 2 ; i <= 35 ; i++)
  54131. + switch(i)
  54132. + {
  54133. + case 2: /* Memory type (DDR1/2 / SDRAM) */
  54134. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  54135. + mvOsOutput("Dram Type is: SDRAM\n");
  54136. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  54137. + mvOsOutput("Dram Type is: SDRAM DDR1\n");
  54138. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  54139. + mvOsOutput("Dram Type is: SDRAM DDR2\n");
  54140. + else
  54141. + mvOsOutput("Dram Type unknown\n");
  54142. + break;
  54143. +/*----------------------------------------------------------------------------*/
  54144. +
  54145. + case 3: /* Number Of Row Addresses */
  54146. + mvOsOutput("Module Number of row addresses: %d\n",
  54147. + dimmInfo.numOfRowAddr);
  54148. + break;
  54149. +/*----------------------------------------------------------------------------*/
  54150. +
  54151. + case 4: /* Number Of Column Addresses */
  54152. + mvOsOutput("Module Number of col addresses: %d\n",
  54153. + dimmInfo.numOfColAddr);
  54154. + break;
  54155. +/*----------------------------------------------------------------------------*/
  54156. +
  54157. + case 5: /* Number Of Module Banks */
  54158. + mvOsOutput("Number of Banks on Mod.: %d\n",
  54159. + dimmInfo.numOfModuleBanks);
  54160. + break;
  54161. +/*----------------------------------------------------------------------------*/
  54162. +
  54163. + case 6: /* Data Width */
  54164. + mvOsOutput("Module Data Width: %d bit\n",
  54165. + dimmInfo.dataWidth);
  54166. + break;
  54167. +/*----------------------------------------------------------------------------*/
  54168. +
  54169. + case 8: /* Voltage Interface */
  54170. + switch(spdRawData[i])
  54171. + {
  54172. + case 0x0:
  54173. + mvOsOutput("Module is TTL_5V_TOLERANT\n");
  54174. + break;
  54175. + case 0x1:
  54176. + mvOsOutput("Module is LVTTL\n");
  54177. + break;
  54178. + case 0x2:
  54179. + mvOsOutput("Module is HSTL_1_5V\n");
  54180. + break;
  54181. + case 0x3:
  54182. + mvOsOutput("Module is SSTL_3_3V\n");
  54183. + break;
  54184. + case 0x4:
  54185. + mvOsOutput("Module is SSTL_2_5V\n");
  54186. + break;
  54187. + case 0x5:
  54188. + if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
  54189. + {
  54190. + mvOsOutput("Module is SSTL_1_8V\n");
  54191. + break;
  54192. + }
  54193. + default:
  54194. + mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
  54195. + break;
  54196. + }
  54197. + break;
  54198. +/*----------------------------------------------------------------------------*/
  54199. +
  54200. + case 9: /* Minimum Cycle Time At Max CasLatancy */
  54201. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  54202. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  54203. +
  54204. + /* DDR2 addition of right of point */
  54205. + if ((spdRawData[i] & 0x0f) == 0xA)
  54206. + {
  54207. + rightOfPoint = 25;
  54208. + }
  54209. + if ((spdRawData[i] & 0x0f) == 0xB)
  54210. + {
  54211. + rightOfPoint = 33;
  54212. + }
  54213. + if ((spdRawData[i] & 0x0f) == 0xC)
  54214. + {
  54215. + rightOfPoint = 66;
  54216. + }
  54217. + if ((spdRawData[i] & 0x0f) == 0xD)
  54218. + {
  54219. + rightOfPoint = 75;
  54220. + }
  54221. + mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
  54222. + leftOfPoint, rightOfPoint);
  54223. + break;
  54224. +/*----------------------------------------------------------------------------*/
  54225. +
  54226. + case 10: /* Clock To Data Out */
  54227. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
  54228. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  54229. + ((spdRawData[i] & 0x0f));
  54230. + leftOfPoint = time_tmp / div;
  54231. + rightOfPoint = time_tmp % div;
  54232. + mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
  54233. + leftOfPoint, rightOfPoint);
  54234. + break;
  54235. +/*----------------------------------------------------------------------------*/
  54236. +
  54237. + case 11: /* Error Check Type */
  54238. + mvOsOutput("Error Check Type (0=NONE): %d\n",
  54239. + dimmInfo.errorCheckType);
  54240. + break;
  54241. +/*----------------------------------------------------------------------------*/
  54242. +
  54243. + case 12: /* Refresh Interval */
  54244. + mvOsOutput("Refresh Rate: %x\n",
  54245. + dimmInfo.refreshInterval);
  54246. + break;
  54247. +/*----------------------------------------------------------------------------*/
  54248. +
  54249. + case 13: /* Sdram Width */
  54250. + mvOsOutput("Sdram Width: %d bits\n",
  54251. + dimmInfo.sdramWidth);
  54252. + break;
  54253. +/*----------------------------------------------------------------------------*/
  54254. +
  54255. + case 14: /* Error Check Data Width */
  54256. + mvOsOutput("Error Check Data Width: %d bits\n",
  54257. + dimmInfo.errorCheckDataWidth);
  54258. + break;
  54259. +/*----------------------------------------------------------------------------*/
  54260. +
  54261. + case 15: /* Minimum Clock Delay is unsupported */
  54262. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  54263. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  54264. + {
  54265. + mvOsOutput("Minimum Clk Delay back to back: %d\n",
  54266. + spdRawData[i]);
  54267. + }
  54268. + break;
  54269. +/*----------------------------------------------------------------------------*/
  54270. +
  54271. + case 16: /* Burst Length Supported */
  54272. + /* SDRAM/DDR1:
  54273. + *******-******-******-******-******-******-******-*******
  54274. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54275. + *******-******-******-******-******-******-******-*******
  54276. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  54277. + *********************************************************/
  54278. + /* DDR2:
  54279. + *******-******-******-******-******-******-******-*******
  54280. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54281. + *******-******-******-******-******-******-******-*******
  54282. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  54283. + *********************************************************/
  54284. + mvOsOutput("Burst Length Supported: ");
  54285. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  54286. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  54287. + {
  54288. + if (dimmInfo.burstLengthSupported & BIT0)
  54289. + mvOsOutput("1, ");
  54290. + if (dimmInfo.burstLengthSupported & BIT1)
  54291. + mvOsOutput("2, ");
  54292. + }
  54293. + if (dimmInfo.burstLengthSupported & BIT2)
  54294. + mvOsOutput("4, ");
  54295. + if (dimmInfo.burstLengthSupported & BIT3)
  54296. + mvOsOutput("8, ");
  54297. +
  54298. + mvOsOutput(" Bit \n");
  54299. + break;
  54300. +/*----------------------------------------------------------------------------*/
  54301. +
  54302. + case 17: /* Number Of Banks On Each Device */
  54303. + mvOsOutput("Number Of Banks On Each Chip: %d\n",
  54304. + dimmInfo.numOfBanksOnEachDevice);
  54305. + break;
  54306. +/*----------------------------------------------------------------------------*/
  54307. +
  54308. + case 18: /* Suported Cas Latencies */
  54309. +
  54310. + /* SDRAM:
  54311. + *******-******-******-******-******-******-******-*******
  54312. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54313. + *******-******-******-******-******-******-******-*******
  54314. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  54315. + ********************************************************/
  54316. +
  54317. + /* DDR 1:
  54318. + *******-******-******-******-******-******-******-*******
  54319. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54320. + *******-******-******-******-******-******-******-*******
  54321. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  54322. + *********************************************************/
  54323. +
  54324. + /* DDR 2:
  54325. + *******-******-******-******-******-******-******-*******
  54326. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54327. + *******-******-******-******-******-******-******-*******
  54328. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  54329. + *********************************************************/
  54330. +
  54331. + mvOsOutput("Suported Cas Latencies: (CL) ");
  54332. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  54333. + {
  54334. + for (k = 0; k <=7; k++)
  54335. + {
  54336. + if (dimmInfo.suportedCasLatencies & (1 << k))
  54337. + mvOsOutput("%d, ", k+1);
  54338. + }
  54339. + }
  54340. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  54341. + {
  54342. + if (dimmInfo.suportedCasLatencies & BIT0)
  54343. + mvOsOutput("1, ");
  54344. + if (dimmInfo.suportedCasLatencies & BIT1)
  54345. + mvOsOutput("1.5, ");
  54346. + if (dimmInfo.suportedCasLatencies & BIT2)
  54347. + mvOsOutput("2, ");
  54348. + if (dimmInfo.suportedCasLatencies & BIT3)
  54349. + mvOsOutput("2.5, ");
  54350. + if (dimmInfo.suportedCasLatencies & BIT4)
  54351. + mvOsOutput("3, ");
  54352. + if (dimmInfo.suportedCasLatencies & BIT5)
  54353. + mvOsOutput("3.5, ");
  54354. + }
  54355. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  54356. + {
  54357. + if (dimmInfo.suportedCasLatencies & BIT2)
  54358. + mvOsOutput("2, ");
  54359. + if (dimmInfo.suportedCasLatencies & BIT3)
  54360. + mvOsOutput("3, ");
  54361. + if (dimmInfo.suportedCasLatencies & BIT4)
  54362. + mvOsOutput("4, ");
  54363. + if (dimmInfo.suportedCasLatencies & BIT5)
  54364. + mvOsOutput("5, ");
  54365. + }
  54366. + else
  54367. + mvOsOutput("?.?, ");
  54368. + mvOsOutput("\n");
  54369. + break;
  54370. +/*----------------------------------------------------------------------------*/
  54371. +
  54372. + case 20: /* DDR2 DIMM type info */
  54373. + if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  54374. + {
  54375. + if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
  54376. + mvOsOutput("Registered DIMM (RDIMM)\n");
  54377. + else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
  54378. + mvOsOutput("Unbuffered DIMM (UDIMM)\n");
  54379. + else
  54380. + mvOsOutput("Unknown DIMM type.\n");
  54381. + }
  54382. +
  54383. + break;
  54384. +/*----------------------------------------------------------------------------*/
  54385. +
  54386. + case 21: /* SDRAM Modules Attributes */
  54387. + mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
  54388. +
  54389. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  54390. + {
  54391. + if (dimmInfo.dimmAttributes & BIT0)
  54392. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  54393. + else
  54394. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  54395. +
  54396. + if (dimmInfo.dimmAttributes & BIT1)
  54397. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  54398. + else
  54399. + mvOsOutput(" Registered Addr/Control Input: No\n");
  54400. +
  54401. + if (dimmInfo.dimmAttributes & BIT2)
  54402. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  54403. + else
  54404. + mvOsOutput(" On-Card PLL (clock): No \n");
  54405. +
  54406. + if (dimmInfo.dimmAttributes & BIT3)
  54407. + mvOsOutput(" Bufferd DQMB Input: Yes \n");
  54408. + else
  54409. + mvOsOutput(" Bufferd DQMB Inputs: No \n");
  54410. +
  54411. + if (dimmInfo.dimmAttributes & BIT4)
  54412. + mvOsOutput(" Registered DQMB Inputs: Yes \n");
  54413. + else
  54414. + mvOsOutput(" Registered DQMB Inputs: No \n");
  54415. +
  54416. + if (dimmInfo.dimmAttributes & BIT5)
  54417. + mvOsOutput(" Differential Clock Input: Yes \n");
  54418. + else
  54419. + mvOsOutput(" Differential Clock Input: No \n");
  54420. +
  54421. + if (dimmInfo.dimmAttributes & BIT6)
  54422. + mvOsOutput(" redundant Row Addressing: Yes \n");
  54423. + else
  54424. + mvOsOutput(" redundant Row Addressing: No \n");
  54425. + }
  54426. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  54427. + {
  54428. + if (dimmInfo.dimmAttributes & BIT0)
  54429. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  54430. + else
  54431. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  54432. +
  54433. + if (dimmInfo.dimmAttributes & BIT1)
  54434. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  54435. + else
  54436. + mvOsOutput(" Registered Addr/Control Input: No\n");
  54437. +
  54438. + if (dimmInfo.dimmAttributes & BIT2)
  54439. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  54440. + else
  54441. + mvOsOutput(" On-Card PLL (clock): No \n");
  54442. +
  54443. + if (dimmInfo.dimmAttributes & BIT3)
  54444. + mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
  54445. + else
  54446. + mvOsOutput(" FET Switch On-Card Enabled: No \n");
  54447. +
  54448. + if (dimmInfo.dimmAttributes & BIT4)
  54449. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  54450. + else
  54451. + mvOsOutput(" FET Switch External Enabled: No \n");
  54452. +
  54453. + if (dimmInfo.dimmAttributes & BIT5)
  54454. + mvOsOutput(" Differential Clock Input: Yes \n");
  54455. + else
  54456. + mvOsOutput(" Differential Clock Input: No \n");
  54457. + }
  54458. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  54459. + {
  54460. + mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
  54461. + (dimmInfo.dimmAttributes & 0x3) + 1);
  54462. +
  54463. + mvOsOutput(" Number of PLLs on the DIMM: %d\n",
  54464. + ((dimmInfo.dimmAttributes) >> 2) & 0x3);
  54465. +
  54466. + if (dimmInfo.dimmAttributes & BIT4)
  54467. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  54468. + else
  54469. + mvOsOutput(" FET Switch External Enabled: No \n");
  54470. +
  54471. + if (dimmInfo.dimmAttributes & BIT6)
  54472. + mvOsOutput(" Analysis probe installed: Yes \n");
  54473. + else
  54474. + mvOsOutput(" Analysis probe installed: No \n");
  54475. + }
  54476. +
  54477. + break;
  54478. +/*----------------------------------------------------------------------------*/
  54479. +
  54480. + case 22: /* Suported AutoPreCharge */
  54481. + mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
  54482. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  54483. + {
  54484. + if ( spdRawData[i] & BIT0 )
  54485. + mvOsOutput(" Early Ras Precharge: Yes \n");
  54486. + else
  54487. + mvOsOutput(" Early Ras Precharge: No \n");
  54488. +
  54489. + if ( spdRawData[i] & BIT1 )
  54490. + mvOsOutput(" AutoPreCharge: Yes \n");
  54491. + else
  54492. + mvOsOutput(" AutoPreCharge: No \n");
  54493. +
  54494. + if ( spdRawData[i] & BIT2 )
  54495. + mvOsOutput(" Precharge All: Yes \n");
  54496. + else
  54497. + mvOsOutput(" Precharge All: No \n");
  54498. +
  54499. + if ( spdRawData[i] & BIT3 )
  54500. + mvOsOutput(" Write 1/ReadBurst: Yes \n");
  54501. + else
  54502. + mvOsOutput(" Write 1/ReadBurst: No \n");
  54503. +
  54504. + if ( spdRawData[i] & BIT4 )
  54505. + mvOsOutput(" lower VCC tolerance: 5%%\n");
  54506. + else
  54507. + mvOsOutput(" lower VCC tolerance: 10%%\n");
  54508. +
  54509. + if ( spdRawData[i] & BIT5 )
  54510. + mvOsOutput(" upper VCC tolerance: 5%%\n");
  54511. + else
  54512. + mvOsOutput(" upper VCC tolerance: 10%%\n");
  54513. + }
  54514. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  54515. + {
  54516. + if ( spdRawData[i] & BIT0 )
  54517. + mvOsOutput(" Supports Weak Driver: Yes \n");
  54518. + else
  54519. + mvOsOutput(" Supports Weak Driver: No \n");
  54520. +
  54521. + if ( !(spdRawData[i] & BIT4) )
  54522. + mvOsOutput(" lower VCC tolerance: 0.2V\n");
  54523. +
  54524. + if ( !(spdRawData[i] & BIT5) )
  54525. + mvOsOutput(" upper VCC tolerance: 0.2V\n");
  54526. +
  54527. + if ( spdRawData[i] & BIT6 )
  54528. + mvOsOutput(" Concurrent Auto Preharge: Yes \n");
  54529. + else
  54530. + mvOsOutput(" Concurrent Auto Preharge: No \n");
  54531. +
  54532. + if ( spdRawData[i] & BIT7 )
  54533. + mvOsOutput(" Supports Fast AP: Yes \n");
  54534. + else
  54535. + mvOsOutput(" Supports Fast AP: No \n");
  54536. + }
  54537. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  54538. + {
  54539. + if ( spdRawData[i] & BIT0 )
  54540. + mvOsOutput(" Supports Weak Driver: Yes \n");
  54541. + else
  54542. + mvOsOutput(" Supports Weak Driver: No \n");
  54543. + }
  54544. + break;
  54545. +/*----------------------------------------------------------------------------*/
  54546. +
  54547. + case 23:
  54548. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
  54549. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  54550. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  54551. +
  54552. + /* DDR2 addition of right of point */
  54553. + if ((spdRawData[i] & 0x0f) == 0xA)
  54554. + {
  54555. + rightOfPoint = 25;
  54556. + }
  54557. + if ((spdRawData[i] & 0x0f) == 0xB)
  54558. + {
  54559. + rightOfPoint = 33;
  54560. + }
  54561. + if ((spdRawData[i] & 0x0f) == 0xC)
  54562. + {
  54563. + rightOfPoint = 66;
  54564. + }
  54565. + if ((spdRawData[i] & 0x0f) == 0xD)
  54566. + {
  54567. + rightOfPoint = 75;
  54568. + }
  54569. +
  54570. + mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
  54571. + "(0 = Not supported): %d.%d [ns]\n",
  54572. + leftOfPoint, rightOfPoint );
  54573. + break;
  54574. +/*----------------------------------------------------------------------------*/
  54575. +
  54576. + case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
  54577. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
  54578. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  54579. + ((spdRawData[i] & 0x0f));
  54580. + leftOfPoint = time_tmp / div;
  54581. + rightOfPoint = time_tmp % div;
  54582. + mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
  54583. + leftOfPoint, rightOfPoint);
  54584. + break;
  54585. +/*----------------------------------------------------------------------------*/
  54586. +
  54587. + case 25:
  54588. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
  54589. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  54590. + {
  54591. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  54592. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  54593. + }
  54594. + else /* DDR1 or DDR2 */
  54595. + {
  54596. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  54597. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  54598. +
  54599. + /* DDR2 addition of right of point */
  54600. + if ((spdRawData[i] & 0x0f) == 0xA)
  54601. + {
  54602. + rightOfPoint = 25;
  54603. + }
  54604. + if ((spdRawData[i] & 0x0f) == 0xB)
  54605. + {
  54606. + rightOfPoint = 33;
  54607. + }
  54608. + if ((spdRawData[i] & 0x0f) == 0xC)
  54609. + {
  54610. + rightOfPoint = 66;
  54611. + }
  54612. + if ((spdRawData[i] & 0x0f) == 0xD)
  54613. + {
  54614. + rightOfPoint = 75;
  54615. + }
  54616. + }
  54617. + mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
  54618. + "(0 = Not supported): %d.%d [ns]\n",
  54619. + leftOfPoint, rightOfPoint );
  54620. + break;
  54621. +/*----------------------------------------------------------------------------*/
  54622. +
  54623. + case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
  54624. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  54625. + {
  54626. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  54627. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  54628. + }
  54629. + else /* DDR1 or DDR2 */
  54630. + {
  54631. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  54632. + ((spdRawData[i] & 0x0f));
  54633. + leftOfPoint = 0;
  54634. + rightOfPoint = time_tmp;
  54635. + }
  54636. + mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
  54637. + leftOfPoint, rightOfPoint );
  54638. + break;
  54639. +/*----------------------------------------------------------------------------*/
  54640. +
  54641. + case 27: /* Minimum Row Precharge Time */
  54642. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  54643. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  54644. + 0xff : 0xfc;
  54645. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  54646. + 0x00 : 0x03;
  54647. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  54648. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  54649. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
  54650. + trp_clocks = (temp + (busClkPs-1)) / busClkPs;
  54651. + mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
  54652. + "in Clk cycles %d\n",
  54653. + leftOfPoint, rightOfPoint, trp_clocks);
  54654. + break;
  54655. +/*----------------------------------------------------------------------------*/
  54656. +
  54657. + case 28: /* Minimum Row Active to Row Active Time */
  54658. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  54659. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  54660. + 0xff : 0xfc;
  54661. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  54662. + 0x00 : 0x03;
  54663. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  54664. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  54665. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  54666. + trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
  54667. + mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
  54668. + "%d.%d = in Clk cycles %d\n",
  54669. + leftOfPoint, rightOfPoint, trp_clocks);
  54670. + break;
  54671. +/*----------------------------------------------------------------------------*/
  54672. +
  54673. + case 29: /* Minimum Ras-To-Cas Delay */
  54674. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  54675. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  54676. + 0xff : 0xfc;
  54677. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  54678. + 0x00 : 0x03;
  54679. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  54680. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  54681. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  54682. + trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
  54683. + mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
  54684. + "in Clk cycles %d\n",
  54685. + leftOfPoint, rightOfPoint, trp_clocks);
  54686. + break;
  54687. +/*----------------------------------------------------------------------------*/
  54688. +
  54689. + case 30: /* Minimum Ras Pulse Width */
  54690. + tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
  54691. + mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
  54692. + "in Clk cycles %d\n", spdRawData[i], tras_clocks);
  54693. + break;
  54694. +/*----------------------------------------------------------------------------*/
  54695. +
  54696. + case 31: /* Module Bank Density */
  54697. + mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
  54698. +
  54699. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  54700. + {
  54701. + if (dimmInfo.dimmBankDensity & BIT0)
  54702. + mvOsOutput("1GB, ");
  54703. + if (dimmInfo.dimmBankDensity & BIT1)
  54704. + mvOsOutput("8MB, ");
  54705. + if (dimmInfo.dimmBankDensity & BIT2)
  54706. + mvOsOutput("16MB, ");
  54707. + if (dimmInfo.dimmBankDensity & BIT3)
  54708. + mvOsOutput("32MB, ");
  54709. + if (dimmInfo.dimmBankDensity & BIT4)
  54710. + mvOsOutput("64MB, ");
  54711. + if (dimmInfo.dimmBankDensity & BIT5)
  54712. + mvOsOutput("128MB, ");
  54713. + if (dimmInfo.dimmBankDensity & BIT6)
  54714. + mvOsOutput("256MB, ");
  54715. + if (dimmInfo.dimmBankDensity & BIT7)
  54716. + mvOsOutput("512MB, ");
  54717. + }
  54718. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  54719. + {
  54720. + if (dimmInfo.dimmBankDensity & BIT0)
  54721. + mvOsOutput("1GB, ");
  54722. + if (dimmInfo.dimmBankDensity & BIT1)
  54723. + mvOsOutput("2GB, ");
  54724. + if (dimmInfo.dimmBankDensity & BIT2)
  54725. + mvOsOutput("16MB, ");
  54726. + if (dimmInfo.dimmBankDensity & BIT3)
  54727. + mvOsOutput("32MB, ");
  54728. + if (dimmInfo.dimmBankDensity & BIT4)
  54729. + mvOsOutput("64MB, ");
  54730. + if (dimmInfo.dimmBankDensity & BIT5)
  54731. + mvOsOutput("128MB, ");
  54732. + if (dimmInfo.dimmBankDensity & BIT6)
  54733. + mvOsOutput("256MB, ");
  54734. + if (dimmInfo.dimmBankDensity & BIT7)
  54735. + mvOsOutput("512MB, ");
  54736. + }
  54737. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  54738. + {
  54739. + if (dimmInfo.dimmBankDensity & BIT0)
  54740. + mvOsOutput("1GB, ");
  54741. + if (dimmInfo.dimmBankDensity & BIT1)
  54742. + mvOsOutput("2GB, ");
  54743. + if (dimmInfo.dimmBankDensity & BIT2)
  54744. + mvOsOutput("4GB, ");
  54745. + if (dimmInfo.dimmBankDensity & BIT3)
  54746. + mvOsOutput("8GB, ");
  54747. + if (dimmInfo.dimmBankDensity & BIT4)
  54748. + mvOsOutput("16GB, ");
  54749. + if (dimmInfo.dimmBankDensity & BIT5)
  54750. + mvOsOutput("128MB, ");
  54751. + if (dimmInfo.dimmBankDensity & BIT6)
  54752. + mvOsOutput("256MB, ");
  54753. + if (dimmInfo.dimmBankDensity & BIT7)
  54754. + mvOsOutput("512MB, ");
  54755. + }
  54756. + mvOsOutput("\n");
  54757. + break;
  54758. +/*----------------------------------------------------------------------------*/
  54759. +
  54760. + case 32: /* Address And Command Setup Time (measured in ns/1000) */
  54761. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  54762. + {
  54763. + rightOfPoint = (spdRawData[i] & 0x0f);
  54764. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  54765. + if(leftOfPoint > 7)
  54766. + {
  54767. + leftOfPoint *= -1;
  54768. + }
  54769. + }
  54770. + else /* DDR1 or DDR2 */
  54771. + {
  54772. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  54773. + ((spdRawData[i] & 0x0f));
  54774. + leftOfPoint = time_tmp / 100;
  54775. + rightOfPoint = time_tmp % 100;
  54776. + }
  54777. + mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
  54778. + leftOfPoint, rightOfPoint);
  54779. + break;
  54780. +/*----------------------------------------------------------------------------*/
  54781. +
  54782. + case 33: /* Address And Command Hold Time */
  54783. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  54784. + {
  54785. + rightOfPoint = (spdRawData[i] & 0x0f);
  54786. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  54787. + if(leftOfPoint > 7)
  54788. + {
  54789. + leftOfPoint *= -1;
  54790. + }
  54791. + }
  54792. + else /* DDR1 or DDR2 */
  54793. + {
  54794. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  54795. + ((spdRawData[i] & 0x0f));
  54796. + leftOfPoint = time_tmp / 100;
  54797. + rightOfPoint = time_tmp % 100;
  54798. + }
  54799. + mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
  54800. + leftOfPoint, rightOfPoint);
  54801. + break;
  54802. +/*----------------------------------------------------------------------------*/
  54803. +
  54804. + case 34: /* Data Input Setup Time */
  54805. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  54806. + {
  54807. + rightOfPoint = (spdRawData[i] & 0x0f);
  54808. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  54809. + if(leftOfPoint > 7)
  54810. + {
  54811. + leftOfPoint *= -1;
  54812. + }
  54813. + }
  54814. + else /* DDR1 or DDR2 */
  54815. + {
  54816. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  54817. + ((spdRawData[i] & 0x0f));
  54818. + leftOfPoint = time_tmp / 100;
  54819. + rightOfPoint = time_tmp % 100;
  54820. + }
  54821. + mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
  54822. + leftOfPoint, rightOfPoint);
  54823. + break;
  54824. +/*----------------------------------------------------------------------------*/
  54825. +
  54826. + case 35: /* Data Input Hold Time */
  54827. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  54828. + {
  54829. + rightOfPoint = (spdRawData[i] & 0x0f);
  54830. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  54831. + if(leftOfPoint > 7)
  54832. + {
  54833. + leftOfPoint *= -1;
  54834. + }
  54835. + }
  54836. + else /* DDR1 or DDR2 */
  54837. + {
  54838. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  54839. + ((spdRawData[i] & 0x0f));
  54840. + leftOfPoint = time_tmp / 100;
  54841. + rightOfPoint = time_tmp % 100;
  54842. + }
  54843. + mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
  54844. + leftOfPoint, rightOfPoint);
  54845. + break;
  54846. +/*----------------------------------------------------------------------------*/
  54847. +
  54848. + case 36: /* Relevant for DDR2 only: Write Recovery Time */
  54849. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
  54850. + rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
  54851. + mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
  54852. + leftOfPoint, rightOfPoint);
  54853. + break;
  54854. +/*----------------------------------------------------------------------------*/
  54855. + }
  54856. +
  54857. +}
  54858. +
  54859. +
  54860. +/*
  54861. + * translate ns.ns/10 coding of SPD timing values
  54862. + * into ps unit values
  54863. + */
  54864. +/*******************************************************************************
  54865. +* cas2ps - Translate x.y ns parameter to pico-seconds values
  54866. +*
  54867. +* DESCRIPTION:
  54868. +* This function translates x.y nano seconds to its value in pico seconds.
  54869. +* For example 3.75ns will return 3750.
  54870. +*
  54871. +* INPUT:
  54872. +* spd_byte - DIMM SPD byte.
  54873. +*
  54874. +* OUTPUT:
  54875. +* None.
  54876. +*
  54877. +* RETURN:
  54878. +* value in pico seconds.
  54879. +*
  54880. +*******************************************************************************/
  54881. +static MV_U32 cas2ps(MV_U8 spd_byte)
  54882. +{
  54883. + MV_U32 ns, ns10;
  54884. +
  54885. + /* isolate upper nibble */
  54886. + ns = (spd_byte >> 4) & 0x0F;
  54887. + /* isolate lower nibble */
  54888. + ns10 = (spd_byte & 0x0F);
  54889. +
  54890. + if( ns10 < 10 ) {
  54891. + ns10 *= 10;
  54892. + }
  54893. + else if( ns10 == 10 )
  54894. + ns10 = 25;
  54895. + else if( ns10 == 11 )
  54896. + ns10 = 33;
  54897. + else if( ns10 == 12 )
  54898. + ns10 = 66;
  54899. + else if( ns10 == 13 )
  54900. + ns10 = 75;
  54901. + else
  54902. + {
  54903. + mvOsOutput("cas2ps Err. unsupported cycle time.\n");
  54904. + }
  54905. +
  54906. + return (ns*1000 + ns10*10);
  54907. +}
  54908. +
  54909. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h
  54910. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h 1970-01-01 01:00:00.000000000 +0100
  54911. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h 2011-07-31 11:31:59.563522806 +0200
  54912. @@ -0,0 +1,191 @@
  54913. +/*******************************************************************************
  54914. +Copyright (C) Marvell International Ltd. and its affiliates
  54915. +
  54916. +This software file (the "File") is owned and distributed by Marvell
  54917. +International Ltd. and/or its affiliates ("Marvell") under the following
  54918. +alternative licensing terms. Once you have made an election to distribute the
  54919. +File under one of the following license alternatives, please (i) delete this
  54920. +introductory statement regarding license alternatives, (ii) delete the two
  54921. +license alternatives that you have not elected to use and (iii) preserve the
  54922. +Marvell copyright notice above.
  54923. +
  54924. +********************************************************************************
  54925. +Marvell Commercial License Option
  54926. +
  54927. +If you received this File from Marvell and you have entered into a commercial
  54928. +license agreement (a "Commercial License") with Marvell, the File is licensed
  54929. +to you under the terms of the applicable Commercial License.
  54930. +
  54931. +********************************************************************************
  54932. +Marvell GPL License Option
  54933. +
  54934. +If you received this File from Marvell, you may opt to use, redistribute and/or
  54935. +modify this File in accordance with the terms and conditions of the General
  54936. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  54937. +available along with the File in the license.txt file or by writing to the Free
  54938. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  54939. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  54940. +
  54941. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  54942. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  54943. +DISCLAIMED. The GPL License provides additional details about this warranty
  54944. +disclaimer.
  54945. +********************************************************************************
  54946. +Marvell BSD License Option
  54947. +
  54948. +If you received this File from Marvell, you may opt to use, redistribute and/or
  54949. +modify this File under the following licensing terms.
  54950. +Redistribution and use in source and binary forms, with or without modification,
  54951. +are permitted provided that the following conditions are met:
  54952. +
  54953. + * Redistributions of source code must retain the above copyright notice,
  54954. + this list of conditions and the following disclaimer.
  54955. +
  54956. + * Redistributions in binary form must reproduce the above copyright
  54957. + notice, this list of conditions and the following disclaimer in the
  54958. + documentation and/or other materials provided with the distribution.
  54959. +
  54960. + * Neither the name of Marvell nor the names of its contributors may be
  54961. + used to endorse or promote products derived from this software without
  54962. + specific prior written permission.
  54963. +
  54964. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  54965. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  54966. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  54967. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  54968. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  54969. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  54970. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  54971. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  54972. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  54973. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  54974. +
  54975. +*******************************************************************************/
  54976. +
  54977. +#ifndef __INCmvDram
  54978. +#define __INCmvDram
  54979. +
  54980. +#include "ddr1_2/mvDramIf.h"
  54981. +#include "twsi/mvTwsi.h"
  54982. +
  54983. +#define MAX_DIMM_NUM 2
  54984. +#define SPD_SIZE 128
  54985. +
  54986. +/* Dimm spd offsets */
  54987. +#define DIMM_MEM_TYPE 2
  54988. +#define DIMM_ROW_NUM 3
  54989. +#define DIMM_COL_NUM 4
  54990. +#define DIMM_MODULE_BANK_NUM 5
  54991. +#define DIMM_DATA_WIDTH 6
  54992. +#define DIMM_VOLT_IF 8
  54993. +#define DIMM_MIN_CC_AT_MAX_CAS 9
  54994. +#define DIMM_ERR_CHECK_TYPE 11
  54995. +#define DIMM_REFRESH_INTERVAL 12
  54996. +#define DIMM_SDRAM_WIDTH 13
  54997. +#define DIMM_ERR_CHECK_DATA_WIDTH 14
  54998. +#define DIMM_MIN_CLK_DEL 15
  54999. +#define DIMM_BURST_LEN_SUP 16
  55000. +#define DIMM_DEV_BANK_NUM 17
  55001. +#define DIMM_SUP_CAL 18
  55002. +#define DIMM_DDR2_TYPE_INFORMATION 20 /* DDR2 only */
  55003. +#define DIMM_BUF_ADDR_CONT_IN 21
  55004. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1 23
  55005. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2 25
  55006. +#define DIMM_MIN_ROW_PRECHARGE_TIME 27
  55007. +#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE 28
  55008. +#define DIMM_MIN_RAS_TO_CAS_DELAY 29
  55009. +#define DIMM_MIN_RAS_PULSE_WIDTH 30
  55010. +#define DIMM_BANK_DENSITY 31
  55011. +#define DIMM_MIN_WRITE_RECOVERY_TIME 36
  55012. +#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY 37
  55013. +#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY 38
  55014. +#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD 42
  55015. +
  55016. +/* Dimm Memory Type values */
  55017. +#define DIMM_MEM_TYPE_SDRAM 0x4
  55018. +#define DIMM_MEM_TYPE_DDR1 0x7
  55019. +#define DIMM_MEM_TYPE_DDR2 0x8
  55020. +
  55021. +#define DIMM_MODULE_MANU_OFFS 64
  55022. +#define DIMM_MODULE_MANU_SIZE 8
  55023. +#define DIMM_MODULE_VEN_OFFS 73
  55024. +#define DIMM_MODULE_VEN_SIZE 25
  55025. +#define DIMM_MODULE_ID_OFFS 99
  55026. +#define DIMM_MODULE_ID_SIZE 18
  55027. +
  55028. +/* enumeration for voltage levels. */
  55029. +typedef enum _mvDimmVoltageIf
  55030. +{
  55031. + TTL_5V_TOLERANT,
  55032. + LVTTL,
  55033. + HSTL_1_5V,
  55034. + SSTL_3_3V,
  55035. + SSTL_2_5V,
  55036. + VOLTAGE_UNKNOWN,
  55037. +} MV_DIMM_VOLTAGE_IF;
  55038. +
  55039. +
  55040. +/* enumaration for SDRAM CAS Latencies. */
  55041. +typedef enum _mvDimmSdramCas
  55042. +{
  55043. + SD_CL_1 =1,
  55044. + SD_CL_2,
  55045. + SD_CL_3,
  55046. + SD_CL_4,
  55047. + SD_CL_5,
  55048. + SD_CL_6,
  55049. + SD_CL_7,
  55050. + SD_FAULT
  55051. +}MV_DIMM_SDRAM_CAS;
  55052. +
  55053. +
  55054. +/* DIMM information structure */
  55055. +typedef struct _mvDimmInfo
  55056. +{
  55057. + MV_MEMORY_TYPE memoryType; /* DDR or SDRAM */
  55058. +
  55059. + MV_U8 spdRawData[SPD_SIZE]; /* Content of SPD-EEPROM copied 1:1 */
  55060. +
  55061. + /* DIMM dimensions */
  55062. + MV_U32 numOfRowAddr;
  55063. + MV_U32 numOfColAddr;
  55064. + MV_U32 numOfModuleBanks;
  55065. + MV_U32 dataWidth;
  55066. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  55067. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  55068. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  55069. + MV_U32 burstLengthSupported;
  55070. + MV_U32 numOfBanksOnEachDevice;
  55071. + MV_U32 suportedCasLatencies;
  55072. + MV_U32 refreshInterval;
  55073. + MV_U32 dimmBankDensity;
  55074. + MV_U32 dimmTypeInfo; /* DDR2 only */
  55075. + MV_U32 dimmAttributes;
  55076. +
  55077. + /* DIMM timing parameters */
  55078. + MV_U32 minCycleTimeAtMaxCasLatPs;
  55079. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  55080. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  55081. + MV_U32 minRowPrechargeTime;
  55082. + MV_U32 minRowActiveToRowActive;
  55083. + MV_U32 minRasToCasDelay;
  55084. + MV_U32 minRasPulseWidth;
  55085. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  55086. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  55087. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  55088. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  55089. +
  55090. + /* Parameters calculated from the extracted DIMM information */
  55091. + MV_U32 size; /* 16,64,128,256 or 512 MByte in MB units */
  55092. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit in MB units */
  55093. + MV_U32 numberOfDevices;
  55094. +
  55095. +} MV_DIMM_INFO;
  55096. +
  55097. +
  55098. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);
  55099. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);
  55100. +MV_VOID dimmSpdPrint(MV_U32 dimmNum);
  55101. +MV_STATUS dimmSpdCpy(MV_VOID);
  55102. +
  55103. +#endif /* __INCmvDram */
  55104. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c
  55105. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c 1970-01-01 01:00:00.000000000 +0100
  55106. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c 2011-07-31 11:31:59.603900955 +0200
  55107. @@ -0,0 +1,1599 @@
  55108. +/*******************************************************************************
  55109. +Copyright (C) Marvell International Ltd. and its affiliates
  55110. +
  55111. +This software file (the "File") is owned and distributed by Marvell
  55112. +International Ltd. and/or its affiliates ("Marvell") under the following
  55113. +alternative licensing terms. Once you have made an election to distribute the
  55114. +File under one of the following license alternatives, please (i) delete this
  55115. +introductory statement regarding license alternatives, (ii) delete the two
  55116. +license alternatives that you have not elected to use and (iii) preserve the
  55117. +Marvell copyright notice above.
  55118. +
  55119. +********************************************************************************
  55120. +Marvell Commercial License Option
  55121. +
  55122. +If you received this File from Marvell and you have entered into a commercial
  55123. +license agreement (a "Commercial License") with Marvell, the File is licensed
  55124. +to you under the terms of the applicable Commercial License.
  55125. +
  55126. +********************************************************************************
  55127. +Marvell GPL License Option
  55128. +
  55129. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55130. +modify this File in accordance with the terms and conditions of the General
  55131. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  55132. +available along with the File in the license.txt file or by writing to the Free
  55133. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  55134. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  55135. +
  55136. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  55137. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  55138. +DISCLAIMED. The GPL License provides additional details about this warranty
  55139. +disclaimer.
  55140. +********************************************************************************
  55141. +Marvell BSD License Option
  55142. +
  55143. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55144. +modify this File under the following licensing terms.
  55145. +Redistribution and use in source and binary forms, with or without modification,
  55146. +are permitted provided that the following conditions are met:
  55147. +
  55148. + * Redistributions of source code must retain the above copyright notice,
  55149. + this list of conditions and the following disclaimer.
  55150. +
  55151. + * Redistributions in binary form must reproduce the above copyright
  55152. + notice, this list of conditions and the following disclaimer in the
  55153. + documentation and/or other materials provided with the distribution.
  55154. +
  55155. + * Neither the name of Marvell nor the names of its contributors may be
  55156. + used to endorse or promote products derived from this software without
  55157. + specific prior written permission.
  55158. +
  55159. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  55160. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  55161. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  55162. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  55163. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  55164. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  55165. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  55166. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  55167. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  55168. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  55169. +
  55170. +*******************************************************************************/
  55171. +
  55172. +
  55173. +/* includes */
  55174. +#include "ddr1_2/mvDramIf.h"
  55175. +#include "ctrlEnv/sys/mvCpuIf.h"
  55176. +
  55177. +
  55178. +
  55179. +#ifdef MV_DEBUG
  55180. +#define DB(x) x
  55181. +#else
  55182. +#define DB(x)
  55183. +#endif
  55184. +
  55185. +/* DRAM bank presence encoding */
  55186. +#define BANK_PRESENT_CS0 0x1
  55187. +#define BANK_PRESENT_CS0_CS1 0x3
  55188. +#define BANK_PRESENT_CS0_CS2 0x5
  55189. +#define BANK_PRESENT_CS0_CS1_CS2 0x7
  55190. +#define BANK_PRESENT_CS0_CS2_CS3 0xd
  55191. +#define BANK_PRESENT_CS0_CS2_CS3_CS4 0xf
  55192. +
  55193. +/* locals */
  55194. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
  55195. +#if defined(MV_INC_BOARD_DDIM)
  55196. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
  55197. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas);
  55198. +static MV_U32 sdramModeRegCalc(MV_U32 minCas);
  55199. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
  55200. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
  55201. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  55202. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk,
  55203. + MV_U32 forcedCl);
  55204. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  55205. + MV_U32 minCas, MV_U32 busClk);
  55206. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  55207. + MV_U32 busClk);
  55208. +
  55209. +/*******************************************************************************
  55210. +* mvDramIfDetect - Prepare DRAM interface configuration values.
  55211. +*
  55212. +* DESCRIPTION:
  55213. +* This function implements the full DRAM detection and timing
  55214. +* configuration for best system performance.
  55215. +* Since this routine runs from a ROM device (Boot Flash), its stack
  55216. +* resides on RAM, that might be the system DRAM. Changing DRAM
  55217. +* configuration values while keeping vital data in DRAM is risky. That
  55218. +* is why the function does not preform the configuration setting but
  55219. +* prepare those in predefined 32bit registers (in this case IDMA
  55220. +* registers are used) for other routine to perform the settings.
  55221. +* The function will call for board DRAM SPD information for each DRAM
  55222. +* chip select. The function will then analyze those SPD parameters of
  55223. +* all DRAM banks in order to decide on DRAM configuration compatible
  55224. +* for all DRAM banks.
  55225. +* The function will set the CPU DRAM address decode registers.
  55226. +* Note: This routine prepares values that will overide configuration of
  55227. +* mvDramBasicAsmInit().
  55228. +*
  55229. +* INPUT:
  55230. +* forcedCl - Forced CAL Latency. If equal to zero, do not force.
  55231. +*
  55232. +* OUTPUT:
  55233. +* None.
  55234. +*
  55235. +* RETURN:
  55236. +* None.
  55237. +*
  55238. +*******************************************************************************/
  55239. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl)
  55240. +{
  55241. + MV_U32 retVal = MV_OK; /* return value */
  55242. + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
  55243. + MV_U32 busClk, size, base = 0, i, temp, deviceW, dimmW;
  55244. + MV_U8 minCas;
  55245. + MV_DRAM_DEC_WIN dramDecWin;
  55246. +
  55247. + dramDecWin.addrWin.baseHigh = 0;
  55248. +
  55249. + busClk = mvBoardSysClkGet();
  55250. +
  55251. + if (0 == busClk)
  55252. + {
  55253. + mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
  55254. + return MV_ERROR;
  55255. + }
  55256. +
  55257. + /* Close DRAM banks except bank 0 (in case code is excecuting from it...) */
  55258. +#if defined(MV_INCLUDE_SDRAM_CS1)
  55259. + for(i= SDRAM_CS1; i < MV_DRAM_MAX_CS; i++)
  55260. + mvCpuIfTargetWinEnable(i, MV_FALSE);
  55261. +#endif
  55262. +
  55263. + /* we will use bank 0 as the representative of the all the DRAM banks, */
  55264. + /* since bank 0 must exist. */
  55265. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  55266. + {
  55267. + /* if Bank exist */
  55268. + if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
  55269. + {
  55270. + /* check it isn't SDRAM */
  55271. + if(bankInfo[i].memoryType == MEM_TYPE_SDRAM)
  55272. + {
  55273. + mvOsPrintf("Dram: ERR. SDRAM type not supported !!!\n");
  55274. + return MV_ERROR;
  55275. + }
  55276. + /* All banks must support registry in order to activate it */
  55277. + if(bankInfo[i].registeredAddrAndControlInputs !=
  55278. + bankInfo[0].registeredAddrAndControlInputs)
  55279. + {
  55280. + mvOsPrintf("Dram: ERR. different Registered settings !!!\n");
  55281. + return MV_ERROR;
  55282. + }
  55283. +
  55284. + /* Init the CPU window decode */
  55285. + /* Note that the size in Bank info is in MB units */
  55286. + /* Note that the Dimm width might be different then the device DRAM width */
  55287. + temp = MV_REG_READ(SDRAM_CONFIG_REG);
  55288. +
  55289. + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_16BIT )? 16 : 32;
  55290. + dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
  55291. + size = ((bankInfo[i].size << 20) / (dimmW/deviceW));
  55292. +
  55293. + /* We can not change DRAM window settings while excecuting */
  55294. + /* code from it. That is why we skip the DRAM CS[0], saving */
  55295. + /* it to the ROM configuration routine */
  55296. + if(i == SDRAM_CS0)
  55297. + {
  55298. + MV_U32 sizeToReg;
  55299. +
  55300. + /* Translate the given window size to register format */
  55301. + sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
  55302. +
  55303. + /* Size parameter validity check. */
  55304. + if (-1 == sizeToReg)
  55305. + {
  55306. + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
  55307. + ,i);
  55308. + return MV_BAD_PARAM;
  55309. + }
  55310. +
  55311. + /* Size is located at upper 16 bits */
  55312. + sizeToReg <<= SCSR_SIZE_OFFS;
  55313. +
  55314. + /* enable it */
  55315. + sizeToReg |= SCSR_WIN_EN;
  55316. +
  55317. + MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
  55318. + }
  55319. + else
  55320. + {
  55321. + dramDecWin.addrWin.baseLow = base;
  55322. + dramDecWin.addrWin.size = size;
  55323. + dramDecWin.enable = MV_TRUE;
  55324. +
  55325. + if (MV_OK != mvDramIfWinSet(SDRAM_CS0 + i, &dramDecWin))
  55326. + {
  55327. + mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n",
  55328. + SDRAM_CS0 + i);
  55329. + return MV_ERROR;
  55330. + }
  55331. + }
  55332. +
  55333. + base += size;
  55334. +
  55335. + /* update the suportedCasLatencies mask */
  55336. + bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
  55337. +
  55338. + }
  55339. + else
  55340. + {
  55341. + if( i == 0 ) /* bank 0 doesn't exist */
  55342. + {
  55343. + mvOsPrintf("Dram: ERR. Fail to detect bank 0 !!!\n");
  55344. + return MV_ERROR;
  55345. + }
  55346. + else
  55347. + {
  55348. + DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
  55349. + bankInfo[i].size = 0; /* Mark this bank as non exist */
  55350. + }
  55351. + }
  55352. + }
  55353. +
  55354. + /* calculate minimum CAS */
  55355. + minCas = minCasCalc(&bankInfo[0], busClk, forcedCl);
  55356. + if (0 == minCas)
  55357. + {
  55358. + mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
  55359. + (busClk / 1000000));
  55360. +
  55361. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  55362. + {
  55363. + minCas = DDR2_CL_4; /* Continue with this CAS */
  55364. + mvOsPrintf("Set default CAS latency 4\n");
  55365. + }
  55366. + else
  55367. + {
  55368. + minCas = DDR1_CL_3; /* Continue with this CAS */
  55369. + mvOsPrintf("Set default CAS latency 3\n");
  55370. + }
  55371. + }
  55372. +
  55373. + /* calc SDRAM_CONFIG_REG and save it to temp register */
  55374. + temp = sdramConfigRegCalc(&bankInfo[0], busClk);
  55375. + if(-1 == temp)
  55376. + {
  55377. + mvOsPrintf("Dram: ERR. sdramConfigRegCalc failed !!!\n");
  55378. + return MV_ERROR;
  55379. + }
  55380. + MV_REG_WRITE(DRAM_BUF_REG1, temp);
  55381. +
  55382. + /* calc SDRAM_MODE_REG and save it to temp register */
  55383. + temp = sdramModeRegCalc(minCas);
  55384. + if(-1 == temp)
  55385. + {
  55386. + mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
  55387. + return MV_ERROR;
  55388. + }
  55389. + MV_REG_WRITE(DRAM_BUF_REG2, temp);
  55390. +
  55391. + /* calc SDRAM_EXTENDED_MODE_REG and save it to temp register */
  55392. + temp = sdramExtModeRegCalc(&bankInfo[0]);
  55393. + if(-1 == temp)
  55394. + {
  55395. + mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
  55396. + return MV_ERROR;
  55397. + }
  55398. + MV_REG_WRITE(DRAM_BUF_REG10, temp);
  55399. +
  55400. + /* calc D_UNIT_CONTROL_LOW and save it to temp register */
  55401. + temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas);
  55402. + if(-1 == temp)
  55403. + {
  55404. + mvOsPrintf("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
  55405. + return MV_ERROR;
  55406. + }
  55407. + MV_REG_WRITE(DRAM_BUF_REG3, temp);
  55408. +
  55409. + /* calc SDRAM_ADDR_CTRL_REG and save it to temp register */
  55410. + temp = sdramAddrCtrlRegCalc(&bankInfo[0]);
  55411. + if(-1 == temp)
  55412. + {
  55413. + mvOsPrintf("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
  55414. + return MV_ERROR;
  55415. + }
  55416. + MV_REG_WRITE(DRAM_BUF_REG4, temp);
  55417. +
  55418. + /* calc SDRAM_TIMING_CTRL_LOW_REG and save it to temp register */
  55419. + temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
  55420. + if(-1 == temp)
  55421. + {
  55422. + mvOsPrintf("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
  55423. + return MV_ERROR;
  55424. + }
  55425. + MV_REG_WRITE(DRAM_BUF_REG5, temp);
  55426. +
  55427. + /* calc SDRAM_TIMING_CTRL_HIGH_REG and save it to temp register */
  55428. + temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
  55429. + if(-1 == temp)
  55430. + {
  55431. + mvOsPrintf("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
  55432. + return MV_ERROR;
  55433. + }
  55434. + MV_REG_WRITE(DRAM_BUF_REG6, temp);
  55435. +
  55436. + /* Config DDR2 On Die Termination (ODT) registers */
  55437. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  55438. + {
  55439. + sdramDDr2OdtConfig(bankInfo);
  55440. + }
  55441. +
  55442. + /* Note that DDR SDRAM Address/Control and Data pad calibration */
  55443. + /* settings is done in mvSdramIfConfig.s */
  55444. +
  55445. + return retVal;
  55446. +}
  55447. +
  55448. +/*******************************************************************************
  55449. +* minCasCalc - Calculate the Minimum CAS latency which can be used.
  55450. +*
  55451. +* DESCRIPTION:
  55452. +* Calculate the minimum CAS latency that can be used, base on the DRAM
  55453. +* parameters and the SDRAM bus Clock freq.
  55454. +*
  55455. +* INPUT:
  55456. +* busClk - the DRAM bus Clock.
  55457. +* pBankInfo - bank info parameters.
  55458. +*
  55459. +* OUTPUT:
  55460. +* None
  55461. +*
  55462. +* RETURN:
  55463. +* The minimum CAS Latency. The function returns 0 if max CAS latency
  55464. +* supported by banks is incompatible with system bus clock frequancy.
  55465. +*
  55466. +*******************************************************************************/
  55467. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk,
  55468. + MV_U32 forcedCl)
  55469. +{
  55470. + MV_U32 count = 1, j;
  55471. + MV_U32 busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
  55472. + MV_U32 startBit, stopBit;
  55473. +
  55474. + /* DDR 1:
  55475. + *******-******-******-******-******-******-******-*******
  55476. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  55477. + *******-******-******-******-******-******-******-*******
  55478. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  55479. + *********************************************************/
  55480. +
  55481. + /* DDR 2:
  55482. + *******-******-******-******-******-******-******-*******
  55483. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  55484. + *******-******-******-******-******-******-******-*******
  55485. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  55486. + *********************************************************/
  55487. +
  55488. +
  55489. + /* If we are asked to use the forced CAL */
  55490. + if (forcedCl)
  55491. + {
  55492. + mvOsPrintf("DRAM: Using forced CL %d.%d\n", (forcedCl / 10),
  55493. + (forcedCl % 10));
  55494. +
  55495. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  55496. + {
  55497. + if (forcedCl == 30)
  55498. + pBankInfo->suportedCasLatencies = 0x08;
  55499. + else if (forcedCl == 40)
  55500. + pBankInfo->suportedCasLatencies = 0x10;
  55501. + else
  55502. + {
  55503. + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n",
  55504. + (forcedCl / 10), (forcedCl % 10));
  55505. + pBankInfo->suportedCasLatencies = 0x10;
  55506. + }
  55507. + }
  55508. + else
  55509. + {
  55510. + if (forcedCl == 15)
  55511. + pBankInfo->suportedCasLatencies = 0x02;
  55512. + else if (forcedCl == 20)
  55513. + pBankInfo->suportedCasLatencies = 0x04;
  55514. + else if (forcedCl == 25)
  55515. + pBankInfo->suportedCasLatencies = 0x08;
  55516. + else if (forcedCl == 30)
  55517. + pBankInfo->suportedCasLatencies = 0x10;
  55518. + else if (forcedCl == 40)
  55519. + pBankInfo->suportedCasLatencies = 0x40;
  55520. + else
  55521. + {
  55522. + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 3\n",
  55523. + (forcedCl / 10), (forcedCl % 10));
  55524. + pBankInfo->suportedCasLatencies = 0x10;
  55525. + }
  55526. + }
  55527. +
  55528. + return pBankInfo->suportedCasLatencies;
  55529. + }
  55530. +
  55531. + /* go over the supported cas mask from Max Cas down and check if the */
  55532. + /* SysClk stands in its time requirments. */
  55533. +
  55534. +
  55535. + DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
  55536. + pBankInfo->suportedCasLatencies,busClkPs ));
  55537. + for(j = 7; j > 0; j--)
  55538. + {
  55539. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  55540. + {
  55541. + /* Reset the bits for CL incompatible for the sysClk */
  55542. + switch (count)
  55543. + {
  55544. + case 1:
  55545. + if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs)
  55546. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  55547. + count++;
  55548. + break;
  55549. + case 2:
  55550. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
  55551. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  55552. + count++;
  55553. + break;
  55554. + case 3:
  55555. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
  55556. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  55557. + count++;
  55558. + break;
  55559. + default:
  55560. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  55561. + break;
  55562. + }
  55563. + }
  55564. + }
  55565. +
  55566. + DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
  55567. + pBankInfo->suportedCasLatencies ));
  55568. +
  55569. + /* SDRAM DDR1 controller supports CL 1.5 to 3.5 */
  55570. + /* SDRAM DDR2 controller supports CL 3 to 5 */
  55571. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  55572. + {
  55573. + startBit = 3; /* DDR2 support CL start with CL3 (bit 3) */
  55574. + stopBit = 5; /* DDR2 support CL stops with CL5 (bit 5) */
  55575. + }
  55576. + else
  55577. + {
  55578. + startBit = 1; /* DDR1 support CL start with CL1.5 (bit 3) */
  55579. + stopBit = 4; /* DDR1 support CL stops with CL3 (bit 4) */
  55580. + }
  55581. +
  55582. + for(j = startBit; j <= stopBit ; j++)
  55583. + {
  55584. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  55585. + {
  55586. + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
  55587. + return (BIT0 << j);
  55588. + }
  55589. + }
  55590. +
  55591. + return 0;
  55592. +}
  55593. +
  55594. +/*******************************************************************************
  55595. +* sdramConfigRegCalc - Calculate sdram config register
  55596. +*
  55597. +* DESCRIPTION: Calculate sdram config register optimized value based
  55598. +* on the bank info parameters.
  55599. +*
  55600. +* INPUT:
  55601. +* pBankInfo - sdram bank parameters
  55602. +*
  55603. +* OUTPUT:
  55604. +* None
  55605. +*
  55606. +* RETURN:
  55607. +* sdram config reg value.
  55608. +*
  55609. +*******************************************************************************/
  55610. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  55611. +{
  55612. + MV_U32 sdramConfig = 0;
  55613. + MV_U32 refreshPeriod;
  55614. +
  55615. + busClk /= 1000000; /* we work with busClk in MHz */
  55616. +
  55617. + sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
  55618. +
  55619. + /* figure out the memory refresh internal */
  55620. + switch (pBankInfo->refreshInterval & 0xf)
  55621. + {
  55622. + case 0x0: /* refresh period is 15.625 usec */
  55623. + refreshPeriod = 15625;
  55624. + break;
  55625. + case 0x1: /* refresh period is 3.9 usec */
  55626. + refreshPeriod = 3900;
  55627. + break;
  55628. + case 0x2: /* refresh period is 7.8 usec */
  55629. + refreshPeriod = 7800;
  55630. + break;
  55631. + case 0x3: /* refresh period is 31.3 usec */
  55632. + refreshPeriod = 31300;
  55633. + break;
  55634. + case 0x4: /* refresh period is 62.5 usec */
  55635. + refreshPeriod = 62500;
  55636. + break;
  55637. + case 0x5: /* refresh period is 125 usec */
  55638. + refreshPeriod = 125000;
  55639. + break;
  55640. + default: /* refresh period undefined */
  55641. + mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
  55642. + return -1;
  55643. + }
  55644. +
  55645. + /* Now the refreshPeriod is in register format value */
  55646. + refreshPeriod = (busClk * refreshPeriod) / 1000;
  55647. +
  55648. + DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n",
  55649. + refreshPeriod));
  55650. +
  55651. + /* make sure the refresh value is only 14 bits */
  55652. + if(refreshPeriod > SDRAM_REFRESH_MAX)
  55653. + {
  55654. + refreshPeriod = SDRAM_REFRESH_MAX;
  55655. + DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n",
  55656. + refreshPeriod));
  55657. + }
  55658. +
  55659. + /* Clear the refresh field */
  55660. + sdramConfig &= ~SDRAM_REFRESH_MASK;
  55661. +
  55662. + /* Set new value to refresh field */
  55663. + sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
  55664. +
  55665. + /* registered DRAM ? */
  55666. + if ( pBankInfo->registeredAddrAndControlInputs )
  55667. + {
  55668. + /* it's registered DRAM, so set the reg. DRAM bit */
  55669. + sdramConfig |= SDRAM_REGISTERED;
  55670. + mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");
  55671. + }
  55672. +
  55673. + /* set DDR SDRAM devices configuration */
  55674. + sdramConfig &= ~SDRAM_DCFG_MASK; /* Clear Dcfg field */
  55675. +
  55676. + switch (pBankInfo->sdramWidth)
  55677. + {
  55678. + case 8: /* memory is x8 */
  55679. + sdramConfig |= SDRAM_DCFG_X8_DEV;
  55680. + DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x8\n"));
  55681. + break;
  55682. + case 16:
  55683. + sdramConfig |= SDRAM_DCFG_X16_DEV;
  55684. + DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x16\n"));
  55685. + break;
  55686. + default: /* memory width unsupported */
  55687. + mvOsPrintf("Dram: ERR. DRAM chip width is unknown!\n");
  55688. + return -1;
  55689. + }
  55690. +
  55691. + /* Set static default settings */
  55692. + sdramConfig |= SDRAM_CONFIG_DV;
  55693. +
  55694. + DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
  55695. + sdramConfig));
  55696. +
  55697. + return sdramConfig;
  55698. +}
  55699. +
  55700. +/*******************************************************************************
  55701. +* sdramModeRegCalc - Calculate sdram mode register
  55702. +*
  55703. +* DESCRIPTION: Calculate sdram mode register optimized value based
  55704. +* on the bank info parameters and the minCas.
  55705. +*
  55706. +* INPUT:
  55707. +* minCas - minimum CAS supported.
  55708. +*
  55709. +* OUTPUT:
  55710. +* None
  55711. +*
  55712. +* RETURN:
  55713. +* sdram mode reg value.
  55714. +*
  55715. +*******************************************************************************/
  55716. +static MV_U32 sdramModeRegCalc(MV_U32 minCas)
  55717. +{
  55718. + MV_U32 sdramMode;
  55719. +
  55720. + sdramMode = MV_REG_READ(SDRAM_MODE_REG);
  55721. +
  55722. + /* Clear CAS Latency field */
  55723. + sdramMode &= ~SDRAM_CL_MASK;
  55724. +
  55725. + mvOsPrintf("DRAM CAS Latency ");
  55726. +
  55727. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  55728. + {
  55729. + switch (minCas)
  55730. + {
  55731. + case DDR2_CL_3:
  55732. + sdramMode |= SDRAM_DDR2_CL_3;
  55733. + mvOsPrintf("3.\n");
  55734. + break;
  55735. + case DDR2_CL_4:
  55736. + sdramMode |= SDRAM_DDR2_CL_4;
  55737. + mvOsPrintf("4.\n");
  55738. + break;
  55739. + case DDR2_CL_5:
  55740. + sdramMode |= SDRAM_DDR2_CL_5;
  55741. + mvOsPrintf("5.\n");
  55742. + break;
  55743. + default:
  55744. + mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
  55745. + return -1;
  55746. + }
  55747. + sdramMode |= DDR2_MODE_REG_DV;
  55748. + }
  55749. + else /* DDR1 */
  55750. + {
  55751. + switch (minCas)
  55752. + {
  55753. + case DDR1_CL_1_5:
  55754. + sdramMode |= SDRAM_DDR1_CL_1_5;
  55755. + mvOsPrintf("1.5\n");
  55756. + break;
  55757. + case DDR1_CL_2:
  55758. + sdramMode |= SDRAM_DDR1_CL_2;
  55759. + mvOsPrintf("2\n");
  55760. + break;
  55761. + case DDR1_CL_2_5:
  55762. + sdramMode |= SDRAM_DDR1_CL_2_5;
  55763. + mvOsPrintf("2.5\n");
  55764. + break;
  55765. + case DDR1_CL_3:
  55766. + sdramMode |= SDRAM_DDR1_CL_3;
  55767. + mvOsPrintf("3\n");
  55768. + break;
  55769. + case DDR1_CL_4:
  55770. + sdramMode |= SDRAM_DDR1_CL_4;
  55771. + mvOsPrintf("4\n");
  55772. + break;
  55773. + default:
  55774. + mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
  55775. + return -1;
  55776. + }
  55777. + sdramMode |= DDR1_MODE_REG_DV;
  55778. + }
  55779. +
  55780. + DB(mvOsPrintf("nsdramModeRegCalc register 0x%x\n", sdramMode ));
  55781. +
  55782. + return sdramMode;
  55783. +}
  55784. +
  55785. +/*******************************************************************************
  55786. +* sdramExtModeRegCalc - Calculate sdram Extended mode register
  55787. +*
  55788. +* DESCRIPTION:
  55789. +* Return sdram Extended mode register value based
  55790. +* on the bank info parameters and bank presence.
  55791. +*
  55792. +* INPUT:
  55793. +* pBankInfo - sdram bank parameters
  55794. +*
  55795. +* OUTPUT:
  55796. +* None
  55797. +*
  55798. +* RETURN:
  55799. +* sdram Extended mode reg value.
  55800. +*
  55801. +*******************************************************************************/
  55802. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
  55803. +{
  55804. + MV_U32 populateBanks = 0;
  55805. + int bankNum;
  55806. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  55807. + {
  55808. + /* Represent the populate banks in binary form */
  55809. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  55810. + {
  55811. + if (0 != pBankInfo[bankNum].size)
  55812. + {
  55813. + populateBanks |= (1 << bankNum);
  55814. + }
  55815. + }
  55816. +
  55817. + switch(populateBanks)
  55818. + {
  55819. + case(BANK_PRESENT_CS0):
  55820. + return DDR_SDRAM_EXT_MODE_CS0_DV;
  55821. +
  55822. + case(BANK_PRESENT_CS0_CS1):
  55823. + return DDR_SDRAM_EXT_MODE_CS0_DV;
  55824. +
  55825. + case(BANK_PRESENT_CS0_CS2):
  55826. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  55827. +
  55828. + case(BANK_PRESENT_CS0_CS1_CS2):
  55829. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  55830. +
  55831. + case(BANK_PRESENT_CS0_CS2_CS3):
  55832. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  55833. +
  55834. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  55835. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  55836. +
  55837. + default:
  55838. + mvOsPrintf("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
  55839. + return -1;
  55840. + }
  55841. + }
  55842. + return 0;
  55843. +}
  55844. +
  55845. +/*******************************************************************************
  55846. +* dunitCtrlLowRegCalc - Calculate sdram dunit control low register
  55847. +*
  55848. +* DESCRIPTION: Calculate sdram dunit control low register optimized value based
  55849. +* on the bank info parameters and the minCas.
  55850. +*
  55851. +* INPUT:
  55852. +* pBankInfo - sdram bank parameters
  55853. +* minCas - minimum CAS supported.
  55854. +*
  55855. +* OUTPUT:
  55856. +* None
  55857. +*
  55858. +* RETURN:
  55859. +* sdram dunit control low reg value.
  55860. +*
  55861. +*******************************************************************************/
  55862. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas)
  55863. +{
  55864. + MV_U32 dunitCtrlLow;
  55865. +
  55866. + dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
  55867. +
  55868. + /* Clear StBurstDel field */
  55869. + dunitCtrlLow &= ~SDRAM_ST_BURST_DEL_MASK;
  55870. +
  55871. +#ifdef MV_88W8660
  55872. + /* Clear address/control output timing field */
  55873. + dunitCtrlLow &= ~SDRAM_CTRL_POS_RISE;
  55874. +#endif /* MV_88W8660 */
  55875. +
  55876. + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
  55877. +
  55878. + /* For proper sample of read data set the Dunit Control register's */
  55879. + /* stBurstDel bits [27:24] */
  55880. + /********-********-********-********-********-*********
  55881. + * CL=1.5 | CL=2 | CL=2.5 | CL=3 | CL=4 | CL=5 *
  55882. + *********-********-********-********-********-*********
  55883. +Not Reg. * 0011 | 0011 | 0100 | 0100 | 0101 | TBD *
  55884. + *********-********-********-********-********-*********
  55885. +Registered * 0100 | 0100 | 0101 | 0101 | 0110 | TBD *
  55886. + *********-********-********-********-********-*********/
  55887. +
  55888. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  55889. + {
  55890. + switch (minCas)
  55891. + {
  55892. + case DDR2_CL_3:
  55893. + /* registerd DDR SDRAM? */
  55894. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  55895. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  55896. + else
  55897. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  55898. + break;
  55899. + case DDR2_CL_4:
  55900. + /* registerd DDR SDRAM? */
  55901. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  55902. + dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
  55903. + else
  55904. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  55905. + break;
  55906. + default:
  55907. + mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n",
  55908. + minCas);
  55909. + return -1;
  55910. + }
  55911. + }
  55912. + else /* DDR1 */
  55913. + {
  55914. + switch (minCas)
  55915. + {
  55916. + case DDR1_CL_1_5:
  55917. + /* registerd DDR SDRAM? */
  55918. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  55919. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  55920. + else
  55921. + dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
  55922. + break;
  55923. + case DDR1_CL_2:
  55924. + /* registerd DDR SDRAM? */
  55925. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  55926. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  55927. + else
  55928. + dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
  55929. + break;
  55930. + case DDR1_CL_2_5:
  55931. + /* registerd DDR SDRAM? */
  55932. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  55933. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  55934. + else
  55935. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  55936. + break;
  55937. + case DDR1_CL_3:
  55938. + /* registerd DDR SDRAM? */
  55939. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  55940. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  55941. + else
  55942. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  55943. + break;
  55944. + case DDR1_CL_4:
  55945. + /* registerd DDR SDRAM? */
  55946. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  55947. + dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
  55948. + else
  55949. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  55950. + break;
  55951. + default:
  55952. + mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n",
  55953. + minCas);
  55954. + return -1;
  55955. + }
  55956. +
  55957. + }
  55958. + DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
  55959. +
  55960. + return dunitCtrlLow;
  55961. +}
  55962. +
  55963. +/*******************************************************************************
  55964. +* sdramAddrCtrlRegCalc - Calculate sdram address control register
  55965. +*
  55966. +* DESCRIPTION: Calculate sdram address control register optimized value based
  55967. +* on the bank info parameters and the minCas.
  55968. +*
  55969. +* INPUT:
  55970. +* pBankInfo - sdram bank parameters
  55971. +*
  55972. +* OUTPUT:
  55973. +* None
  55974. +*
  55975. +* RETURN:
  55976. +* sdram address control reg value.
  55977. +*
  55978. +*******************************************************************************/
  55979. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
  55980. +{
  55981. + MV_U32 addrCtrl = 0;
  55982. +
  55983. + /* Set Address Control register static configuration bits */
  55984. + addrCtrl = MV_REG_READ(SDRAM_ADDR_CTRL_REG);
  55985. +
  55986. + /* Set address control default value */
  55987. + addrCtrl |= SDRAM_ADDR_CTRL_DV;
  55988. +
  55989. + /* Clear DSize field */
  55990. + addrCtrl &= ~SDRAM_DSIZE_MASK;
  55991. +
  55992. + /* Note that density is in MB units */
  55993. + switch (pBankInfo->deviceDensity)
  55994. + {
  55995. + case 128: /* 128 Mbit */
  55996. + DB(mvOsPrintf("DRAM Device Density 128Mbit\n"));
  55997. + addrCtrl |= SDRAM_DSIZE_128Mb;
  55998. + break;
  55999. + case 256: /* 256 Mbit */
  56000. + DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
  56001. + addrCtrl |= SDRAM_DSIZE_256Mb;
  56002. + break;
  56003. + case 512: /* 512 Mbit */
  56004. + DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
  56005. + addrCtrl |= SDRAM_DSIZE_512Mb;
  56006. + break;
  56007. + default:
  56008. + mvOsPrintf("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
  56009. + pBankInfo->deviceDensity);
  56010. + return -1;
  56011. + }
  56012. +
  56013. + /* SDRAM address control */
  56014. + DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
  56015. +
  56016. + return addrCtrl;
  56017. +}
  56018. +
  56019. +/*******************************************************************************
  56020. +* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
  56021. +*
  56022. +* DESCRIPTION:
  56023. +* This function calculates sdram timing control low register
  56024. +* optimized value based on the bank info parameters and the minCas.
  56025. +*
  56026. +* INPUT:
  56027. +* pBankInfo - sdram bank parameters
  56028. +* busClk - Bus clock
  56029. +*
  56030. +* OUTPUT:
  56031. +* None
  56032. +*
  56033. +* RETURN:
  56034. +* sdram timinf control low reg value.
  56035. +*
  56036. +*******************************************************************************/
  56037. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  56038. + MV_U32 minCas, MV_U32 busClk)
  56039. +{
  56040. + MV_U32 tRp = 0;
  56041. + MV_U32 tRrd = 0;
  56042. + MV_U32 tRcd = 0;
  56043. + MV_U32 tRas = 0;
  56044. + MV_U32 tWr = 0;
  56045. + MV_U32 tWtr = 0;
  56046. + MV_U32 tRtp = 0;
  56047. +
  56048. + MV_U32 bankNum;
  56049. +
  56050. + busClk = busClk / 1000000; /* In MHz */
  56051. +
  56052. + /* Scan all DRAM banks to find maximum timing values */
  56053. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  56054. + {
  56055. + tRp = MV_MAX(tRp, pBankInfo[bankNum].minRowPrechargeTime);
  56056. + tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
  56057. + tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
  56058. + tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
  56059. + }
  56060. +
  56061. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns part. */
  56062. + /* by shifting the data two bits right. */
  56063. + tRp = tRp >> 2; /* For example 0x50 -> 20ns */
  56064. + tRrd = tRrd >> 2;
  56065. + tRcd = tRcd >> 2;
  56066. +
  56067. + /* Extract clock cycles from time parameter. We need to round up */
  56068. + tRp = ((busClk * tRp) / 1000) + (((busClk * tRp) % 1000) ? 1 : 0);
  56069. + /* Micron work around for 133MHz */
  56070. + if (busClk == 133)
  56071. + tRp += 1;
  56072. + DB(mvOsPrintf("Dram Timing Low: tRp = %d ", tRp));
  56073. + tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
  56074. + /* JEDEC min reqeirments tRrd = 2 */
  56075. + if (tRrd < 2)
  56076. + tRrd = 2;
  56077. + DB(mvOsPrintf("tRrd = %d ", tRrd));
  56078. + tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
  56079. + DB(mvOsPrintf("tRcd = %d ", tRcd));
  56080. + tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
  56081. + DB(mvOsPrintf("tRas = %d ", tRas));
  56082. +
  56083. + /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2 */
  56084. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  56085. + {
  56086. + /* Scan all DRAM banks to find maximum timing values */
  56087. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  56088. + {
  56089. + tWr = MV_MAX(tWr, pBankInfo[bankNum].minWriteRecoveryTime);
  56090. + tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
  56091. + tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
  56092. + }
  56093. +
  56094. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns */
  56095. + /* part by shifting the data two bits right. */
  56096. + tWr = tWr >> 2; /* For example 0x50 -> 20ns */
  56097. + tWtr = tWtr >> 2;
  56098. + tRtp = tRtp >> 2;
  56099. +
  56100. + /* Extract clock cycles from time parameter. We need to round up */
  56101. + tWr = ((busClk * tWr) / 1000) + (((busClk * tWr) % 1000) ? 1 : 0);
  56102. + DB(mvOsPrintf("tWr = %d ", tWr));
  56103. + tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
  56104. + /* JEDEC min reqeirments tWtr = 2 */
  56105. + if (tWtr < 2)
  56106. + tWtr = 2;
  56107. + DB(mvOsPrintf("tWtr = %d ", tWtr));
  56108. + tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
  56109. + /* JEDEC min reqeirments tRtp = 2 */
  56110. + if (tRtp < 2)
  56111. + tRtp = 2;
  56112. + DB(mvOsPrintf("tRtp = %d ", tRtp));
  56113. + }
  56114. + else
  56115. + {
  56116. + tWr = ((busClk*SDRAM_TWR) / 1000) + (((busClk*SDRAM_TWR) % 1000)?1:0);
  56117. +
  56118. + if ((200 == busClk) || ((100 == busClk) && (DDR1_CL_1_5 == minCas)))
  56119. + {
  56120. + tWtr = 2;
  56121. + }
  56122. + else
  56123. + {
  56124. + tWtr = 1;
  56125. + }
  56126. +
  56127. + tRtp = 2; /* Must be set to 0x1 (two cycles) when using DDR1 */
  56128. + }
  56129. +
  56130. + DB(mvOsPrintf("tWtr = %d\n", tWtr));
  56131. +
  56132. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  56133. + return (((tRp - 1) << SDRAM_TRP_OFFS) |
  56134. + ((tRrd - 1) << SDRAM_TRRD_OFFS) |
  56135. + ((tRcd - 1) << SDRAM_TRCD_OFFS) |
  56136. + ((tRas - 1) << SDRAM_TRAS_OFFS) |
  56137. + ((tWr - 1) << SDRAM_TWR_OFFS) |
  56138. + ((tWtr - 1) << SDRAM_TWTR_OFFS) |
  56139. + ((tRtp - 1) << SDRAM_TRTP_OFFS));
  56140. +}
  56141. +
  56142. +/*******************************************************************************
  56143. +* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
  56144. +*
  56145. +* DESCRIPTION:
  56146. +* This function calculates sdram timing control high register
  56147. +* optimized value based on the bank info parameters and the bus clock.
  56148. +*
  56149. +* INPUT:
  56150. +* pBankInfo - sdram bank parameters
  56151. +* busClk - Bus clock
  56152. +*
  56153. +* OUTPUT:
  56154. +* None
  56155. +*
  56156. +* RETURN:
  56157. +* sdram timinf control high reg value.
  56158. +*
  56159. +*******************************************************************************/
  56160. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  56161. + MV_U32 busClk)
  56162. +{
  56163. + MV_U32 tRfc;
  56164. + MV_U32 timeNs = 0;
  56165. + int bankNum;
  56166. + MV_U32 sdramTw2wCyc = 0;
  56167. +
  56168. + busClk = busClk / 1000000; /* In MHz */
  56169. +
  56170. + /* tRfc is different for DDR1 and DDR2. */
  56171. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  56172. + {
  56173. + MV_U32 bankNum;
  56174. +
  56175. + /* Scan all DRAM banks to find maximum timing values */
  56176. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  56177. + timeNs = MV_MAX(timeNs, pBankInfo[bankNum].minRefreshToActiveCmd);
  56178. + }
  56179. + else
  56180. + {
  56181. + if (pBankInfo[0].deviceDensity == _1G)
  56182. + {
  56183. + timeNs = SDRAM_TRFC_1G;
  56184. + }
  56185. + else
  56186. + {
  56187. + if (200 == busClk)
  56188. + {
  56189. + timeNs = SDRAM_TRFC_64_512M_AT_200MHZ;
  56190. + }
  56191. + else
  56192. + {
  56193. + timeNs = SDRAM_TRFC_64_512M;
  56194. + }
  56195. + }
  56196. + }
  56197. +
  56198. + tRfc = ((busClk * timeNs) / 1000) + (((busClk * timeNs) % 1000) ? 1 : 0);
  56199. +
  56200. + DB(mvOsPrintf("Dram Timing High: tRfc = %d\n", tRfc));
  56201. +
  56202. +
  56203. + /* Represent the populate banks in binary form */
  56204. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  56205. + {
  56206. + if (0 != pBankInfo[bankNum].size)
  56207. + sdramTw2wCyc++;
  56208. + }
  56209. +
  56210. + /* If we have more the 1 bank then we need the TW2W in 1 for ODT switch */
  56211. + if (sdramTw2wCyc > 1)
  56212. + sdramTw2wCyc = 1;
  56213. + else
  56214. + sdramTw2wCyc = 0;
  56215. +
  56216. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  56217. + return ((((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS) |
  56218. + ((SDRAM_TR2R_CYC - 1) << SDRAM_TR2R_OFFS) |
  56219. + ((SDRAM_TR2WW2R_CYC - 1) << SDRAM_TR2W_W2R_OFFS) |
  56220. + (((tRfc - 1) >> 4) << SDRAM_TRFC_EXT_OFFS) |
  56221. + (sdramTw2wCyc << SDRAM_TW2W_OFFS));
  56222. +
  56223. +}
  56224. +
  56225. +/*******************************************************************************
  56226. +* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
  56227. +*
  56228. +* DESCRIPTION:
  56229. +* This function config DDR2 On Die Termination (ODT) registers.
  56230. +* ODT configuration is done according to DIMM presence:
  56231. +*
  56232. +* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode
  56233. +* CS0 0x84210000 0x00000000 0x0000780F 0x00000440
  56234. +* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440
  56235. +* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404
  56236. +* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404
  56237. +* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404
  56238. +* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404
  56239. +*
  56240. +* INPUT:
  56241. +* pBankInfo - bank info parameters.
  56242. +*
  56243. +* OUTPUT:
  56244. +* None
  56245. +*
  56246. +* RETURN:
  56247. +* None
  56248. +*******************************************************************************/
  56249. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
  56250. +{
  56251. + MV_U32 populateBanks = 0;
  56252. + MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
  56253. + int bankNum;
  56254. +
  56255. + /* Represent the populate banks in binary form */
  56256. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  56257. + {
  56258. + if (0 != pBankInfo[bankNum].size)
  56259. + {
  56260. + populateBanks |= (1 << bankNum);
  56261. + }
  56262. + }
  56263. +
  56264. + switch(populateBanks)
  56265. + {
  56266. + case(BANK_PRESENT_CS0):
  56267. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_DV;
  56268. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_DV;
  56269. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
  56270. + break;
  56271. + case(BANK_PRESENT_CS0_CS1):
  56272. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_DV;
  56273. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_DV;
  56274. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
  56275. + break;
  56276. + case(BANK_PRESENT_CS0_CS2):
  56277. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  56278. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  56279. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  56280. + break;
  56281. + case(BANK_PRESENT_CS0_CS1_CS2):
  56282. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  56283. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  56284. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  56285. + break;
  56286. + case(BANK_PRESENT_CS0_CS2_CS3):
  56287. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  56288. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  56289. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  56290. + break;
  56291. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  56292. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  56293. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  56294. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  56295. + break;
  56296. + default:
  56297. + mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n");
  56298. + return;
  56299. + }
  56300. + MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
  56301. + MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
  56302. + MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
  56303. + return;
  56304. +}
  56305. +#endif /* defined(MV_INC_BOARD_DDIM) */
  56306. +
  56307. +/*******************************************************************************
  56308. +* mvDramIfWinSet - Set DRAM interface address decode window
  56309. +*
  56310. +* DESCRIPTION:
  56311. +* This function sets DRAM interface address decode window.
  56312. +*
  56313. +* INPUT:
  56314. +* target - System target. Use only SDRAM targets.
  56315. +* pAddrDecWin - SDRAM address window structure.
  56316. +*
  56317. +* OUTPUT:
  56318. +* None
  56319. +*
  56320. +* RETURN:
  56321. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  56322. +* otherwise.
  56323. +*******************************************************************************/
  56324. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  56325. +{
  56326. + MV_U32 baseReg=0,sizeReg=0;
  56327. + MV_U32 baseToReg=0 , sizeToReg=0;
  56328. +
  56329. + /* Check parameters */
  56330. + if (!MV_TARGET_IS_DRAM(target))
  56331. + {
  56332. + mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
  56333. + return MV_BAD_PARAM;
  56334. + }
  56335. +
  56336. + /* Check if the requested window overlaps with current enabled windows */
  56337. + if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
  56338. + {
  56339. + mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
  56340. + return MV_BAD_PARAM;
  56341. + }
  56342. +
  56343. + /* check if address is aligned to the size */
  56344. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  56345. + {
  56346. + mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
  56347. + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
  56348. + target,
  56349. + pAddrDecWin->addrWin.baseLow,
  56350. + pAddrDecWin->addrWin.size);
  56351. + return MV_ERROR;
  56352. + }
  56353. +
  56354. + /* read base register*/
  56355. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
  56356. +
  56357. + /* read size register */
  56358. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
  56359. +
  56360. + /* BaseLow[31:16] => base register [31:16] */
  56361. + baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;
  56362. +
  56363. + /* Write to address decode Base Address Register */
  56364. + baseReg &= ~SCBAR_BASE_MASK;
  56365. + baseReg |= baseToReg;
  56366. +
  56367. + /* Translate the given window size to register format */
  56368. + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);
  56369. +
  56370. + /* Size parameter validity check. */
  56371. + if (-1 == sizeToReg)
  56372. + {
  56373. + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
  56374. + return MV_BAD_PARAM;
  56375. + }
  56376. +
  56377. + /* set size */
  56378. + sizeReg &= ~SCSR_SIZE_MASK;
  56379. + /* Size is located at upper 16 bits */
  56380. + sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);
  56381. +
  56382. + /* enable/Disable */
  56383. + if (MV_TRUE == pAddrDecWin->enable)
  56384. + {
  56385. + sizeReg |= SCSR_WIN_EN;
  56386. + }
  56387. + else
  56388. + {
  56389. + sizeReg &= ~SCSR_WIN_EN;
  56390. + }
  56391. +
  56392. + /* 3) Write to address decode Base Address Register */
  56393. + MV_REG_WRITE(SDRAM_BASE_ADDR_REG(target), baseReg);
  56394. +
  56395. + /* Write to address decode Size Register */
  56396. + MV_REG_WRITE(SDRAM_SIZE_REG(target), sizeReg);
  56397. +
  56398. + return MV_OK;
  56399. +}
  56400. +/*******************************************************************************
  56401. +* mvDramIfWinGet - Get DRAM interface address decode window
  56402. +*
  56403. +* DESCRIPTION:
  56404. +* This function gets DRAM interface address decode window.
  56405. +*
  56406. +* INPUT:
  56407. +* target - System target. Use only SDRAM targets.
  56408. +*
  56409. +* OUTPUT:
  56410. +* pAddrDecWin - SDRAM address window structure.
  56411. +*
  56412. +* RETURN:
  56413. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  56414. +* otherwise.
  56415. +*******************************************************************************/
  56416. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  56417. +{
  56418. + MV_U32 baseReg,sizeReg;
  56419. + MV_U32 sizeRegVal;
  56420. +
  56421. + /* Check parameters */
  56422. + if (!MV_TARGET_IS_DRAM(target))
  56423. + {
  56424. + mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);
  56425. + return MV_ERROR;
  56426. + }
  56427. +
  56428. + /* Read base and size registers */
  56429. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
  56430. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
  56431. +
  56432. + sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;
  56433. +
  56434. + pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,
  56435. + SCSR_SIZE_ALIGNMENT);
  56436. +
  56437. + /* Check if ctrlRegToSize returned OK */
  56438. + if (-1 == pAddrDecWin->addrWin.size)
  56439. + {
  56440. + mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);
  56441. + return MV_ERROR;
  56442. + }
  56443. +
  56444. + /* Extract base address */
  56445. + /* Base register [31:16] ==> baseLow[31:16] */
  56446. + pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;
  56447. +
  56448. + pAddrDecWin->addrWin.baseHigh = 0;
  56449. +
  56450. +
  56451. + if (sizeReg & SCSR_WIN_EN)
  56452. + {
  56453. + pAddrDecWin->enable = MV_TRUE;
  56454. + }
  56455. + else
  56456. + {
  56457. + pAddrDecWin->enable = MV_FALSE;
  56458. + }
  56459. +
  56460. + return MV_OK;
  56461. +}
  56462. +/*******************************************************************************
  56463. +* mvDramIfWinEnable - Enable/Disable SDRAM address decode window
  56464. +*
  56465. +* DESCRIPTION:
  56466. +* This function enable/Disable SDRAM address decode window.
  56467. +*
  56468. +* INPUT:
  56469. +* target - System target. Use only SDRAM targets.
  56470. +*
  56471. +* OUTPUT:
  56472. +* None.
  56473. +*
  56474. +* RETURN:
  56475. +* MV_ERROR in case function parameter are invalid, MV_OK otherewise.
  56476. +*
  56477. +*******************************************************************************/
  56478. +MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable)
  56479. +{
  56480. + MV_DRAM_DEC_WIN addrDecWin;
  56481. +
  56482. + /* Check parameters */
  56483. + if (!MV_TARGET_IS_DRAM(target))
  56484. + {
  56485. + mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
  56486. + return MV_ERROR;
  56487. + }
  56488. +
  56489. + if (enable == MV_TRUE)
  56490. + { /* First check for overlap with other enabled windows */
  56491. + if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
  56492. + {
  56493. + mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n",
  56494. + target);
  56495. + return MV_ERROR;
  56496. + }
  56497. + /* Check for overlapping */
  56498. + if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
  56499. + {
  56500. + /* No Overlap. Enable address decode winNum window */
  56501. + MV_REG_BIT_SET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
  56502. + }
  56503. + else
  56504. + { /* Overlap detected */
  56505. + mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
  56506. + target);
  56507. + return MV_ERROR;
  56508. + }
  56509. + }
  56510. + else
  56511. + { /* Disable address decode winNum window */
  56512. + MV_REG_BIT_RESET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
  56513. + }
  56514. +
  56515. + return MV_OK;
  56516. +}
  56517. +
  56518. +/*******************************************************************************
  56519. +* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window
  56520. +*
  56521. +* DESCRIPTION:
  56522. +* This function scan each SDRAM address decode window to test if it
  56523. +* overlapps the given address windoow
  56524. +*
  56525. +* INPUT:
  56526. +* target - SDRAM target where the function skips checking.
  56527. +* pAddrDecWin - The tested address window for overlapping with
  56528. +* SDRAM windows.
  56529. +*
  56530. +* OUTPUT:
  56531. +* None.
  56532. +*
  56533. +* RETURN:
  56534. +* MV_TRUE if the given address window overlaps any enabled address
  56535. +* decode map, MV_FALSE otherwise.
  56536. +*
  56537. +*******************************************************************************/
  56538. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
  56539. +{
  56540. + MV_TARGET targetNum;
  56541. + MV_DRAM_DEC_WIN addrDecWin;
  56542. +
  56543. + for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)
  56544. + {
  56545. + /* don't check our winNum or illegal targets */
  56546. + if (targetNum == target)
  56547. + {
  56548. + continue;
  56549. + }
  56550. +
  56551. + /* Get window parameters */
  56552. + if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))
  56553. + {
  56554. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  56555. + return MV_ERROR;
  56556. + }
  56557. +
  56558. + /* Do not check disabled windows */
  56559. + if (MV_FALSE == addrDecWin.enable)
  56560. + {
  56561. + continue;
  56562. + }
  56563. +
  56564. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  56565. + {
  56566. + mvOsPrintf(
  56567. + "sdramIfWinOverlap: Required target %d overlap winNum %d\n",
  56568. + target, targetNum);
  56569. + return MV_TRUE;
  56570. + }
  56571. + }
  56572. +
  56573. + return MV_FALSE;
  56574. +}
  56575. +
  56576. +/*******************************************************************************
  56577. +* mvDramIfBankSizeGet - Get DRAM interface bank size.
  56578. +*
  56579. +* DESCRIPTION:
  56580. +* This function returns the size of a given DRAM bank.
  56581. +*
  56582. +* INPUT:
  56583. +* bankNum - Bank number.
  56584. +*
  56585. +* OUTPUT:
  56586. +* None.
  56587. +*
  56588. +* RETURN:
  56589. +* DRAM bank size. If bank is disabled the function return '0'. In case
  56590. +* or paramter is invalid, the function returns -1.
  56591. +*
  56592. +*******************************************************************************/
  56593. +MV_32 mvDramIfBankSizeGet(MV_U32 bankNum)
  56594. +{
  56595. + MV_DRAM_DEC_WIN addrDecWin;
  56596. +
  56597. + /* Check parameters */
  56598. + if (!MV_TARGET_IS_DRAM(bankNum))
  56599. + {
  56600. + mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
  56601. + return -1;
  56602. + }
  56603. + /* Get window parameters */
  56604. + if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
  56605. + {
  56606. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  56607. + return -1;
  56608. + }
  56609. +
  56610. + if (MV_TRUE == addrDecWin.enable)
  56611. + {
  56612. + return addrDecWin.addrWin.size;
  56613. + }
  56614. + else
  56615. + {
  56616. + return 0;
  56617. + }
  56618. +}
  56619. +
  56620. +
  56621. +/*******************************************************************************
  56622. +* mvDramIfSizeGet - Get DRAM interface total size.
  56623. +*
  56624. +* DESCRIPTION:
  56625. +* This function get the DRAM total size.
  56626. +*
  56627. +* INPUT:
  56628. +* None.
  56629. +*
  56630. +* OUTPUT:
  56631. +* None.
  56632. +*
  56633. +* RETURN:
  56634. +* DRAM total size. In case or paramter is invalid, the function
  56635. +* returns -1.
  56636. +*
  56637. +*******************************************************************************/
  56638. +MV_32 mvDramIfSizeGet(MV_VOID)
  56639. +{
  56640. + MV_U32 totalSize = 0, bankSize = 0, bankNum;
  56641. +
  56642. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  56643. + {
  56644. + bankSize = mvDramIfBankSizeGet(bankNum);
  56645. +
  56646. + if (-1 == bankSize)
  56647. + {
  56648. + mvOsPrintf("Dram: mvDramIfSizeGet error with bank %d \n",bankNum);
  56649. + return -1;
  56650. + }
  56651. + else
  56652. + {
  56653. + totalSize += bankSize;
  56654. + }
  56655. + }
  56656. +
  56657. + DB(mvOsPrintf("Dram: Total DRAM size is 0x%x \n",totalSize));
  56658. +
  56659. + return totalSize;
  56660. +}
  56661. +
  56662. +/*******************************************************************************
  56663. +* mvDramIfBankBaseGet - Get DRAM interface bank base.
  56664. +*
  56665. +* DESCRIPTION:
  56666. +* This function returns the 32 bit base address of a given DRAM bank.
  56667. +*
  56668. +* INPUT:
  56669. +* bankNum - Bank number.
  56670. +*
  56671. +* OUTPUT:
  56672. +* None.
  56673. +*
  56674. +* RETURN:
  56675. +* DRAM bank size. If bank is disabled or paramter is invalid, the
  56676. +* function returns -1.
  56677. +*
  56678. +*******************************************************************************/
  56679. +MV_32 mvDramIfBankBaseGet(MV_U32 bankNum)
  56680. +{
  56681. + MV_DRAM_DEC_WIN addrDecWin;
  56682. +
  56683. + /* Check parameters */
  56684. + if (!MV_TARGET_IS_DRAM(bankNum))
  56685. + {
  56686. + mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
  56687. + return -1;
  56688. + }
  56689. + /* Get window parameters */
  56690. + if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
  56691. + {
  56692. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  56693. + return -1;
  56694. + }
  56695. +
  56696. + if (MV_TRUE == addrDecWin.enable)
  56697. + {
  56698. + return addrDecWin.addrWin.baseLow;
  56699. + }
  56700. + else
  56701. + {
  56702. + return -1;
  56703. + }
  56704. +}
  56705. +
  56706. +
  56707. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h
  56708. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h 1970-01-01 01:00:00.000000000 +0100
  56709. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h 2011-07-31 11:31:59.643947098 +0200
  56710. @@ -0,0 +1,192 @@
  56711. +/*******************************************************************************
  56712. +Copyright (C) Marvell International Ltd. and its affiliates
  56713. +
  56714. +This software file (the "File") is owned and distributed by Marvell
  56715. +International Ltd. and/or its affiliates ("Marvell") under the following
  56716. +alternative licensing terms. Once you have made an election to distribute the
  56717. +File under one of the following license alternatives, please (i) delete this
  56718. +introductory statement regarding license alternatives, (ii) delete the two
  56719. +license alternatives that you have not elected to use and (iii) preserve the
  56720. +Marvell copyright notice above.
  56721. +
  56722. +********************************************************************************
  56723. +Marvell Commercial License Option
  56724. +
  56725. +If you received this File from Marvell and you have entered into a commercial
  56726. +license agreement (a "Commercial License") with Marvell, the File is licensed
  56727. +to you under the terms of the applicable Commercial License.
  56728. +
  56729. +********************************************************************************
  56730. +Marvell GPL License Option
  56731. +
  56732. +If you received this File from Marvell, you may opt to use, redistribute and/or
  56733. +modify this File in accordance with the terms and conditions of the General
  56734. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  56735. +available along with the File in the license.txt file or by writing to the Free
  56736. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  56737. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  56738. +
  56739. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  56740. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  56741. +DISCLAIMED. The GPL License provides additional details about this warranty
  56742. +disclaimer.
  56743. +********************************************************************************
  56744. +Marvell BSD License Option
  56745. +
  56746. +If you received this File from Marvell, you may opt to use, redistribute and/or
  56747. +modify this File under the following licensing terms.
  56748. +Redistribution and use in source and binary forms, with or without modification,
  56749. +are permitted provided that the following conditions are met:
  56750. +
  56751. + * Redistributions of source code must retain the above copyright notice,
  56752. + this list of conditions and the following disclaimer.
  56753. +
  56754. + * Redistributions in binary form must reproduce the above copyright
  56755. + notice, this list of conditions and the following disclaimer in the
  56756. + documentation and/or other materials provided with the distribution.
  56757. +
  56758. + * Neither the name of Marvell nor the names of its contributors may be
  56759. + used to endorse or promote products derived from this software without
  56760. + specific prior written permission.
  56761. +
  56762. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  56763. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  56764. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  56765. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  56766. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  56767. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  56768. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  56769. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  56770. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  56771. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  56772. +
  56773. +*******************************************************************************/
  56774. +
  56775. +
  56776. +#ifndef __INCmvDramIfConfigh
  56777. +#define __INCmvDramIfConfigh
  56778. +
  56779. +/* includes */
  56780. +
  56781. +/* defines */
  56782. +
  56783. +/* registers defaults values */
  56784. +
  56785. +#define SDRAM_CONFIG_DV \
  56786. + (SDRAM_PERR_WRITE | \
  56787. + SDRAM_SRMODE | \
  56788. + SDRAM_SRCLK_GATED)
  56789. +
  56790. +#define SDRAM_DUNIT_CTRL_LOW_DV \
  56791. + (SDRAM_CTRL_POS_RISE | \
  56792. + SDRAM_CLK1DRV_NORMAL | \
  56793. + SDRAM_LOCKEN_ENABLE)
  56794. +
  56795. +#define SDRAM_ADDR_CTRL_DV 0
  56796. +
  56797. +#define SDRAM_TIMING_CTRL_LOW_REG_DV \
  56798. + ((0x2 << SDRAM_TRCD_OFFS) | \
  56799. + (0x2 << SDRAM_TRP_OFFS) | \
  56800. + (0x1 << SDRAM_TWR_OFFS) | \
  56801. + (0x0 << SDRAM_TWTR_OFFS) | \
  56802. + (0x5 << SDRAM_TRAS_OFFS) | \
  56803. + (0x1 << SDRAM_TRRD_OFFS))
  56804. +/* TRFC 0x27, TW2W 0x1 */
  56805. +#define SDRAM_TIMING_CTRL_HIGH_REG_DV (( 0x7 << SDRAM_TRFC_OFFS ) |\
  56806. + ( 0x2 << SDRAM_TRFC_EXT_OFFS) |\
  56807. + ( 0x1 << SDRAM_TW2W_OFFS))
  56808. +
  56809. +#define SDRAM_OPEN_PAGES_CTRL_REG_DV SDRAM_OPEN_PAGE_EN
  56810. +
  56811. +/* DDR2 ODT default register values */
  56812. +
  56813. +/* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode */
  56814. +/* CS0 0x84210000 0x00000000 0x0000780F 0x00000440 */
  56815. +/* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440 */
  56816. +/* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  56817. +/* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  56818. +/* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  56819. +/* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  56820. +
  56821. +#define DDR2_ODT_CTRL_LOW_CS0_DV 0x84210000
  56822. +#define DDR2_ODT_CTRL_HIGH_CS0_DV 0x00000000
  56823. +#define DDR2_DUNIT_ODT_CTRL_CS0_DV 0x0000780F
  56824. +#define DDR_SDRAM_EXT_MODE_CS0_DV 0x00000440
  56825. +
  56826. +#define DDR2_ODT_CTRL_LOW_CS0_CS2_DV 0x030C030C
  56827. +#define DDR2_ODT_CTRL_HIGH_CS0_CS2_DV 0x00000000
  56828. +#define DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV 0x0000740F
  56829. +#define DDR_SDRAM_EXT_MODE_CS0_CS2_DV 0x00000404
  56830. +
  56831. +
  56832. +/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */
  56833. +#define DDR1_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
  56834. + (1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  56835. +#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
  56836. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  56837. +
  56838. +
  56839. +#define DDR1_DATA_PAD_STRENGTH_TYPICAL_DV \
  56840. + (1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  56841. +#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV \
  56842. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  56843. +
  56844. +/* DDR SDRAM Mode Register default value */
  56845. +#define DDR1_MODE_REG_DV 0x00000000
  56846. +#define DDR2_MODE_REG_DV 0x00000400
  56847. +
  56848. +/* DDR SDRAM Timing parameter default values */
  56849. +#define DDR1_TIMING_LOW_DV 0x11602220
  56850. +#define DDR1_TIMING_HIGH_DV 0x0000000d
  56851. +
  56852. +#define DDR2_TIMING_LOW_DV 0x11812220
  56853. +#define DDR2_TIMING_HIGH_DV 0x0000030f
  56854. +
  56855. +/* For Guideline (GL# MEM-4) DQS Reference Delay Tuning */
  56856. +#define FTDLL_DDR1_166MHZ ((0x1 << 0) | \
  56857. + (0x7F<< 12) | \
  56858. + (0x1 << 22))
  56859. +
  56860. +#define FTDLL_DDR1_133MHZ FTDLL_DDR1_166MHZ
  56861. +
  56862. +#define FTDLL_DDR1_200MHZ ((0x1 << 0) | \
  56863. + (0x1 << 12) | \
  56864. + (0x3 << 14) | \
  56865. + (0x1 << 18) | \
  56866. + (0x1 << 22))
  56867. +
  56868. +
  56869. +#define FTDLL_DDR2_166MHZ ((0x1 << 0) | \
  56870. + (0x1 << 12) | \
  56871. + (0x1 << 14) | \
  56872. + (0x1 << 16) | \
  56873. + (0x1 << 19) | \
  56874. + (0xF << 20))
  56875. +
  56876. +#define FTDLL_DDR2_133MHZ FTDLL_DDR2_166MHZ
  56877. +
  56878. +#define FTDLL_DDR2_200MHZ ((0x1 << 0) | \
  56879. + (0x1 << 12) | \
  56880. + (0x1 << 14) | \
  56881. + (0x1 << 16) | \
  56882. + (0x1 << 19) | \
  56883. + (0xF << 20))
  56884. +
  56885. +#define FTDLL_DDR2_250MHZ 0x445001
  56886. +
  56887. +/* Orion 1 B1 and above */
  56888. +#define FTDLL_DDR1_166MHZ_5181_B1 0x45D001
  56889. +
  56890. +/* Orion nas */
  56891. +#define FTDLL_DDR2_166MHZ_5182 0x597001
  56892. +
  56893. +/* Orion 2 D0 and above */
  56894. +#define FTDLL_DDR1_166MHZ_5281_D0 0x8D0001
  56895. +#define FTDLL_DDR1_200MHZ_5281_D0 0x8D0001
  56896. +#define FTDLL_DDR2_166MHZ_5281_D0 0x485001
  56897. +#define FTDLL_DDR2_200MHZ_5281_D0 0x485001
  56898. +#define FTDLL_DDR2_250MHZ_5281_D0 0x445001
  56899. +#define FTDLL_DDR2_200MHZ_5281_D1 0x995001
  56900. +#define FTDLL_DDR2_250MHZ_5281_D1 0x984801
  56901. +
  56902. +#endif /* __INCmvDramIfh */
  56903. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h
  56904. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h 1970-01-01 01:00:00.000000000 +0100
  56905. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h 2011-07-31 11:31:59.674122418 +0200
  56906. @@ -0,0 +1,179 @@
  56907. +/*******************************************************************************
  56908. +Copyright (C) Marvell International Ltd. and its affiliates
  56909. +
  56910. +This software file (the "File") is owned and distributed by Marvell
  56911. +International Ltd. and/or its affiliates ("Marvell") under the following
  56912. +alternative licensing terms. Once you have made an election to distribute the
  56913. +File under one of the following license alternatives, please (i) delete this
  56914. +introductory statement regarding license alternatives, (ii) delete the two
  56915. +license alternatives that you have not elected to use and (iii) preserve the
  56916. +Marvell copyright notice above.
  56917. +
  56918. +********************************************************************************
  56919. +Marvell Commercial License Option
  56920. +
  56921. +If you received this File from Marvell and you have entered into a commercial
  56922. +license agreement (a "Commercial License") with Marvell, the File is licensed
  56923. +to you under the terms of the applicable Commercial License.
  56924. +
  56925. +********************************************************************************
  56926. +Marvell GPL License Option
  56927. +
  56928. +If you received this File from Marvell, you may opt to use, redistribute and/or
  56929. +modify this File in accordance with the terms and conditions of the General
  56930. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  56931. +available along with the File in the license.txt file or by writing to the Free
  56932. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  56933. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  56934. +
  56935. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  56936. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  56937. +DISCLAIMED. The GPL License provides additional details about this warranty
  56938. +disclaimer.
  56939. +********************************************************************************
  56940. +Marvell BSD License Option
  56941. +
  56942. +If you received this File from Marvell, you may opt to use, redistribute and/or
  56943. +modify this File under the following licensing terms.
  56944. +Redistribution and use in source and binary forms, with or without modification,
  56945. +are permitted provided that the following conditions are met:
  56946. +
  56947. + * Redistributions of source code must retain the above copyright notice,
  56948. + this list of conditions and the following disclaimer.
  56949. +
  56950. + * Redistributions in binary form must reproduce the above copyright
  56951. + notice, this list of conditions and the following disclaimer in the
  56952. + documentation and/or other materials provided with the distribution.
  56953. +
  56954. + * Neither the name of Marvell nor the names of its contributors may be
  56955. + used to endorse or promote products derived from this software without
  56956. + specific prior written permission.
  56957. +
  56958. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  56959. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  56960. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  56961. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  56962. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  56963. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  56964. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  56965. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  56966. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  56967. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  56968. +
  56969. +*******************************************************************************/
  56970. +
  56971. +
  56972. +#ifndef __INCmvDramIfh
  56973. +#define __INCmvDramIfh
  56974. +
  56975. +/* includes */
  56976. +#include "ddr1_2/mvDramIfRegs.h"
  56977. +#include "ddr1_2/mvDramIfConfig.h"
  56978. +#include "ctrlEnv/mvCtrlEnvLib.h"
  56979. +
  56980. +/* defines */
  56981. +/* DRAM Timing parameters */
  56982. +#define SDRAM_TWR 15 /* ns tWr */
  56983. +#define SDRAM_TRFC_64_512M_AT_200MHZ 70 /* ns tRfc for dens 64-512 @ 200MHz */
  56984. +#define SDRAM_TRFC_64_512M 75 /* ns tRfc for dens 64-512 */
  56985. +#define SDRAM_TRFC_1G 120 /* ns tRfc for dens 1GB */
  56986. +#define SDRAM_TR2R_CYC 1 /* cycle for tR2r */
  56987. +#define SDRAM_TR2WW2R_CYC 1 /* cycle for tR2wW2r */
  56988. +
  56989. +/* typedefs */
  56990. +
  56991. +/* enumeration for memory types */
  56992. +typedef enum _mvMemoryType
  56993. +{
  56994. + MEM_TYPE_SDRAM,
  56995. + MEM_TYPE_DDR1,
  56996. + MEM_TYPE_DDR2
  56997. +}MV_MEMORY_TYPE;
  56998. +
  56999. +/* enumeration for DDR1 supported CAS Latencies */
  57000. +typedef enum _mvDimmDdr1Cas
  57001. +{
  57002. + DDR1_CL_1_5 = 0x02,
  57003. + DDR1_CL_2 = 0x04,
  57004. + DDR1_CL_2_5 = 0x08,
  57005. + DDR1_CL_3 = 0x10,
  57006. + DDR1_CL_4 = 0x40,
  57007. + DDR1_CL_FAULT
  57008. +} MV_DIMM_DDR1_CAS;
  57009. +
  57010. +/* enumeration for DDR2 supported CAS Latencies */
  57011. +typedef enum _mvDimmDdr2Cas
  57012. +{
  57013. + DDR2_CL_3 = 0x08,
  57014. + DDR2_CL_4 = 0x10,
  57015. + DDR2_CL_5 = 0x20,
  57016. + DDR2_CL_FAULT
  57017. +} MV_DIMM_DDR2_CAS;
  57018. +
  57019. +
  57020. +typedef struct _mvDramBankInfo
  57021. +{
  57022. + MV_MEMORY_TYPE memoryType; /* DDR1, DDR2 or SDRAM */
  57023. +
  57024. + /* DIMM dimensions */
  57025. + MV_U32 numOfRowAddr;
  57026. + MV_U32 numOfColAddr;
  57027. + MV_U32 dataWidth;
  57028. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  57029. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  57030. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  57031. + MV_U32 burstLengthSupported;
  57032. + MV_U32 numOfBanksOnEachDevice;
  57033. + MV_U32 suportedCasLatencies;
  57034. + MV_U32 refreshInterval;
  57035. +
  57036. + /* DIMM timing parameters */
  57037. + MV_U32 minCycleTimeAtMaxCasLatPs;
  57038. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  57039. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  57040. + MV_U32 minRowPrechargeTime;
  57041. + MV_U32 minRowActiveToRowActive;
  57042. + MV_U32 minRasToCasDelay;
  57043. + MV_U32 minRasPulseWidth;
  57044. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  57045. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  57046. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  57047. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  57048. +
  57049. + /* Parameters calculated from the extracted DIMM information */
  57050. + MV_U32 size;
  57051. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit */
  57052. + MV_U32 numberOfDevices;
  57053. +
  57054. + /* DIMM attributes (MV_TRUE for yes) */
  57055. + MV_BOOL registeredAddrAndControlInputs;
  57056. +
  57057. +}MV_DRAM_BANK_INFO;
  57058. +
  57059. +/* This structure describes CPU interface address decode window */
  57060. +typedef struct _mvDramIfDecWin
  57061. +{
  57062. + MV_ADDR_WIN addrWin; /* An address window*/
  57063. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  57064. +}MV_DRAM_DEC_WIN;
  57065. +
  57066. +#include "ddr1_2/mvDram.h"
  57067. +
  57068. +/* mvDramIf.h API list */
  57069. +MV_VOID mvDramIfBasicAsmInit(MV_VOID);
  57070. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl);
  57071. +MV_VOID _mvDramIfConfig(MV_VOID);
  57072. +
  57073. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  57074. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  57075. +MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable);
  57076. +MV_32 mvDramIfBankSizeGet(MV_U32 bankNum);
  57077. +MV_32 mvDramIfBankBaseGet(MV_U32 bankNum);
  57078. +MV_32 mvDramIfSizeGet(MV_VOID);
  57079. +
  57080. +#if 0
  57081. +MV_STATUS mvDramIfMbusCtrlSet(MV_XBAR_TARGET *pPizzaArbArray);
  57082. +MV_STATUS mvDramIfMbusToutSet(MV_U32 timeout, MV_BOOL enable);
  57083. +#endif
  57084. +
  57085. +#endif /* __INCmvDramIfh */
  57086. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h
  57087. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  57088. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h 2011-07-31 11:31:59.713944140 +0200
  57089. @@ -0,0 +1,306 @@
  57090. +/*******************************************************************************
  57091. +Copyright (C) Marvell International Ltd. and its affiliates
  57092. +
  57093. +This software file (the "File") is owned and distributed by Marvell
  57094. +International Ltd. and/or its affiliates ("Marvell") under the following
  57095. +alternative licensing terms. Once you have made an election to distribute the
  57096. +File under one of the following license alternatives, please (i) delete this
  57097. +introductory statement regarding license alternatives, (ii) delete the two
  57098. +license alternatives that you have not elected to use and (iii) preserve the
  57099. +Marvell copyright notice above.
  57100. +
  57101. +********************************************************************************
  57102. +Marvell Commercial License Option
  57103. +
  57104. +If you received this File from Marvell and you have entered into a commercial
  57105. +license agreement (a "Commercial License") with Marvell, the File is licensed
  57106. +to you under the terms of the applicable Commercial License.
  57107. +
  57108. +********************************************************************************
  57109. +Marvell GPL License Option
  57110. +
  57111. +If you received this File from Marvell, you may opt to use, redistribute and/or
  57112. +modify this File in accordance with the terms and conditions of the General
  57113. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  57114. +available along with the File in the license.txt file or by writing to the Free
  57115. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  57116. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  57117. +
  57118. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  57119. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  57120. +DISCLAIMED. The GPL License provides additional details about this warranty
  57121. +disclaimer.
  57122. +********************************************************************************
  57123. +Marvell BSD License Option
  57124. +
  57125. +If you received this File from Marvell, you may opt to use, redistribute and/or
  57126. +modify this File under the following licensing terms.
  57127. +Redistribution and use in source and binary forms, with or without modification,
  57128. +are permitted provided that the following conditions are met:
  57129. +
  57130. + * Redistributions of source code must retain the above copyright notice,
  57131. + this list of conditions and the following disclaimer.
  57132. +
  57133. + * Redistributions in binary form must reproduce the above copyright
  57134. + notice, this list of conditions and the following disclaimer in the
  57135. + documentation and/or other materials provided with the distribution.
  57136. +
  57137. + * Neither the name of Marvell nor the names of its contributors may be
  57138. + used to endorse or promote products derived from this software without
  57139. + specific prior written permission.
  57140. +
  57141. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  57142. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  57143. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  57144. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  57145. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  57146. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  57147. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  57148. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  57149. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  57150. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  57151. +
  57152. +*******************************************************************************/
  57153. +
  57154. +#ifndef __INCmvDramIfRegsh
  57155. +#define __INCmvDramIfRegsh
  57156. +
  57157. +
  57158. +/* DDR SDRAM Controller Address Decode Registers */
  57159. +/* SDRAM CSn Base Address Register (SCBAR) */
  57160. +#define SDRAM_BASE_ADDR_REG(csNum) (0x1500 + (csNum * 8))
  57161. +#define SCBAR_BASE_OFFS 16
  57162. +#define SCBAR_BASE_MASK (0xffff << SCBAR_BASE_OFFS)
  57163. +#define SCBAR_BASE_ALIGNMENT 0x10000
  57164. +
  57165. +/* SDRAM CSn Size Register (SCSR) */
  57166. +#define SDRAM_SIZE_REG(csNum) (0x1504 + (csNum * 8))
  57167. +#define SCSR_WIN_EN BIT0
  57168. +#define SCSR_SIZE_OFFS 16
  57169. +#define SCSR_SIZE_MASK (0xffff << SCSR_SIZE_OFFS)
  57170. +#define SCSR_SIZE_ALIGNMENT 0x10000
  57171. +
  57172. +/* configuration register */
  57173. +#define SDRAM_CONFIG_REG 0x1400
  57174. +#define SDRAM_REFRESH_OFFS 0
  57175. +#define SDRAM_REFRESH_MAX 0x3000
  57176. +#define SDRAM_REFRESH_MASK (SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)
  57177. +#define SDRAM_DWIDTH_OFFS 14
  57178. +#define SDRAM_DWIDTH_MASK (3 << SDRAM_DWIDTH_OFFS)
  57179. +#define SDRAM_DWIDTH_16BIT (1 << SDRAM_DWIDTH_OFFS)
  57180. +#define SDRAM_DWIDTH_32BIT (2 << SDRAM_DWIDTH_OFFS)
  57181. +#define SDRAM_DTYPE_OFFS 16
  57182. +#define SDRAM_DTYPE_MASK (1 << SDRAM_DTYPE_OFFS)
  57183. +#define SDRAM_DTYPE_DDR1 (0 << SDRAM_DTYPE_OFFS)
  57184. +#define SDRAM_DTYPE_DDR2 (1 << SDRAM_DTYPE_OFFS)
  57185. +#define SDRAM_REGISTERED (1 << 17)
  57186. +#define SDRAM_PERR_OFFS 18
  57187. +#define SDRAM_PERR_MASK (1 << SDRAM_PERR_OFFS)
  57188. +#define SDRAM_PERR_NO_WRITE (0 << SDRAM_PERR_OFFS)
  57189. +#define SDRAM_PERR_WRITE (1 << SDRAM_PERR_OFFS)
  57190. +#define SDRAM_DCFG_OFFS 20
  57191. +#define SDRAM_DCFG_MASK (0x3 << SDRAM_DCFG_OFFS)
  57192. +#define SDRAM_DCFG_X16_DEV (1 << SDRAM_DCFG_OFFS)
  57193. +#define SDRAM_DCFG_X8_DEV (2 << SDRAM_DCFG_OFFS)
  57194. +#define SDRAM_SRMODE (1 << 24)
  57195. +#define SDRAM_SRCLK_OFFS 25
  57196. +#define SDRAM_SRCLK_MASK (1 << SDRAM_SRCLK_OFFS)
  57197. +#define SDRAM_SRCLK_KEPT (0 << SDRAM_SRCLK_OFFS)
  57198. +#define SDRAM_SRCLK_GATED (1 << SDRAM_SRCLK_OFFS)
  57199. +#define SDRAM_CATTH_OFFS 26
  57200. +#define SDRAM_CATTHR_EN (1 << SDRAM_CATTH_OFFS)
  57201. +
  57202. +
  57203. +/* dunit control register */
  57204. +#define SDRAM_DUNIT_CTRL_REG 0x1404
  57205. +#define SDRAM_CTRL_POS_OFFS 6
  57206. +#define SDRAM_CTRL_POS_FALL (0 << SDRAM_CTRL_POS_OFFS)
  57207. +#define SDRAM_CTRL_POS_RISE (1 << SDRAM_CTRL_POS_OFFS)
  57208. +#define SDRAM_CLK1DRV_OFFS 12
  57209. +#define SDRAM_CLK1DRV_MASK (1 << SDRAM_CLK1DRV_OFFS)
  57210. +#define SDRAM_CLK1DRV_HIGH_Z (0 << SDRAM_CLK1DRV_OFFS)
  57211. +#define SDRAM_CLK1DRV_NORMAL (1 << SDRAM_CLK1DRV_OFFS)
  57212. +#define SDRAM_LOCKEN_OFFS 18
  57213. +#define SDRAM_LOCKEN_MASK (1 << SDRAM_LOCKEN_OFFS)
  57214. +#define SDRAM_LOCKEN_DISABLE (0 << SDRAM_LOCKEN_OFFS)
  57215. +#define SDRAM_LOCKEN_ENABLE (1 << SDRAM_LOCKEN_OFFS)
  57216. +#define SDRAM_ST_BURST_DEL_OFFS 24
  57217. +#define SDRAM_ST_BURST_DEL_MAX 0xf
  57218. +#define SDRAM_ST_BURST_DEL_MASK (SDRAM_ST_BURST_DEL_MAX<<SDRAM_ST_BURST_DEL_OFFS)
  57219. +
  57220. +/* sdram timing control low register */
  57221. +#define SDRAM_TIMING_CTRL_LOW_REG 0x1408
  57222. +#define SDRAM_TRCD_OFFS 4
  57223. +#define SDRAM_TRCD_MASK (0xF << SDRAM_TRCD_OFFS)
  57224. +#define SDRAM_TRP_OFFS 8
  57225. +#define SDRAM_TRP_MASK (0xF << SDRAM_TRP_OFFS)
  57226. +#define SDRAM_TWR_OFFS 12
  57227. +#define SDRAM_TWR_MASK (0xF << SDRAM_TWR_OFFS)
  57228. +#define SDRAM_TWTR_OFFS 16
  57229. +#define SDRAM_TWTR_MASK (0xF << SDRAM_TWTR_OFFS)
  57230. +#define SDRAM_TRAS_OFFS 20
  57231. +#define SDRAM_TRAS_MASK (0xF << SDRAM_TRAS_OFFS)
  57232. +#define SDRAM_TRRD_OFFS 24
  57233. +#define SDRAM_TRRD_MASK (0xF << SDRAM_TRRD_OFFS)
  57234. +#define SDRAM_TRTP_OFFS 28
  57235. +#define SDRAM_TRTP_MASK (0xF << SDRAM_TRTP_OFFS)
  57236. +
  57237. +/* sdram timing control high register */
  57238. +#define SDRAM_TIMING_CTRL_HIGH_REG 0x140c
  57239. +#define SDRAM_TRFC_OFFS 0
  57240. +#define SDRAM_TRFC_MASK (0xF << SDRAM_TRFC_OFFS)
  57241. +#define SDRAM_TR2R_OFFS 4
  57242. +#define SDRAM_TR2R_MASK (0x3 << SDRAM_TR2R_OFFS)
  57243. +#define SDRAM_TR2W_W2R_OFFS 6
  57244. +#define SDRAM_TR2W_W2R_MASK (0x3 << SDRAM_TR2W_W2R_OFFS)
  57245. +#define SDRAM_TRFC_EXT_OFFS 8
  57246. +#define SDRAM_TRFC_EXT_MASK (0x1 << SDRAM_TRFC_EXT_OFFS)
  57247. +#define SDRAM_TW2W_OFFS 10
  57248. +#define SDRAM_TW2W_MASK (0x1 << SDRAM_TW2W_OFFS)
  57249. +
  57250. +/* address control register */
  57251. +#define SDRAM_ADDR_CTRL_REG 0x1410
  57252. +#define SDRAM_DSIZE_OFFS 4
  57253. +#define SDRAM_DSIZE_MASK (0x3 << SDRAM_DSIZE_OFFS)
  57254. +#define SDRAM_DSIZE_128Mb (0x0 << SDRAM_DSIZE_OFFS)
  57255. +#define SDRAM_DSIZE_256Mb (0x1 << SDRAM_DSIZE_OFFS)
  57256. +#define SDRAM_DSIZE_512Mb (0x2 << SDRAM_DSIZE_OFFS)
  57257. +
  57258. +/* SDRAM Open Pages Control registers */
  57259. +#define SDRAM_OPEN_PAGE_CTRL_REG 0x1414
  57260. +#define SDRAM_OPEN_PAGE_EN (0 << 0)
  57261. +#define SDRAM_OPEN_PAGE_DIS (1 << 0)
  57262. +
  57263. +/* sdram opertion register */
  57264. +#define SDRAM_OPERATION_REG 0x1418
  57265. +#define SDRAM_CMD_OFFS 0
  57266. +#define SDRAM_CMD_MASK (0x7 << SDRAM_CMD_OFFS)
  57267. +#define SDRAM_CMD_NORMAL (0x0 << SDRAM_CMD_OFFS)
  57268. +#define SDRAM_CMD_PRECHARGE_ALL (0x1 << SDRAM_CMD_OFFS)
  57269. +#define SDRAM_CMD_REFRESH_ALL (0x2 << SDRAM_CMD_OFFS)
  57270. +#define SDRAM_CMD_REG_SET_CMD (0x3 << SDRAM_CMD_OFFS)
  57271. +#define SDRAM_CMD_EXT_MODE_SET (0x4 << SDRAM_CMD_OFFS)
  57272. +#define SDRAM_CMD_NOP (0x5 << SDRAM_CMD_OFFS)
  57273. +#define SDRAM_CMD_SLF_RFRSH (0x7 << SDRAM_CMD_OFFS)
  57274. +#define SDRAM_CMD_EMRS2_CMD (0x8 << SDRAM_CMD_OFFS)
  57275. +#define SDRAM_CMD_EMRS3_CMD (0x9 << SDRAM_CMD_OFFS)
  57276. +
  57277. +/* sdram mode register */
  57278. +#define SDRAM_MODE_REG 0x141c
  57279. +#define SDRAM_BURST_LEN_OFFS 0
  57280. +#define SDRAM_BURST_LEN_MASK (0x7 << SDRAM_BURST_LEN_OFFS)
  57281. +#define SDRAM_BURST_LEN_4 (0x2 << SDRAM_BURST_LEN_OFFS)
  57282. +#define SDRAM_CL_OFFS 4
  57283. +#define SDRAM_CL_MASK (0x7 << SDRAM_CL_OFFS)
  57284. +#define SDRAM_DDR1_CL_2 (0x2 << SDRAM_CL_OFFS)
  57285. +#define SDRAM_DDR1_CL_3 (0x3 << SDRAM_CL_OFFS)
  57286. +#define SDRAM_DDR1_CL_4 (0x4 << SDRAM_CL_OFFS)
  57287. +#define SDRAM_DDR1_CL_1_5 (0x5 << SDRAM_CL_OFFS)
  57288. +#define SDRAM_DDR1_CL_2_5 (0x6 << SDRAM_CL_OFFS)
  57289. +#define SDRAM_DDR2_CL_3 (0x3 << SDRAM_CL_OFFS)
  57290. +#define SDRAM_DDR2_CL_4 (0x4 << SDRAM_CL_OFFS)
  57291. +#define SDRAM_DDR2_CL_5 (0x5 << SDRAM_CL_OFFS)
  57292. +#define SDRAM_TM_OFFS 7
  57293. +#define SDRAM_TM_MASK (1 << SDRAM_TM_OFFS)
  57294. +#define SDRAM_TM_NORMAL (0 << SDRAM_TM_OFFS)
  57295. +#define SDRAM_TM_TEST_MODE (1 << SDRAM_TM_OFFS)
  57296. +#define SDRAM_DLL_OFFS 8
  57297. +#define SDRAM_DLL_MASK (1 << SDRAM_DLL_OFFS)
  57298. +#define SDRAM_DLL_NORMAL (0 << SDRAM_DLL_OFFS)
  57299. +#define SDRAM_DLL_RESET (1 << SDRAM_DLL_OFFS)
  57300. +#define SDRAM_WR_OFFS 11
  57301. +#define SDRAM_WR_MAX 7
  57302. +#define SDRAM_WR_MASK (SDRAM_WR_MAX << SDRAM_WR_OFFS)
  57303. +#define SDRAM_PD_OFFS 12
  57304. +#define SDRAM_PD_MASK (1 << SDRAM_PD_OFFS)
  57305. +#define SDRAM_PD_FAST_EXIT (0 << SDRAM_PD_OFFS)
  57306. +#define SDRAM_PD_SLOW_EXIT (1 << SDRAM_PD_OFFS)
  57307. +
  57308. +/* DDR SDRAM Extended Mode register (DSEMR) */
  57309. +#define SDRAM_EXTENDED_MODE_REG 0x1420
  57310. +#define DSEMR_DLL_ENABLE (1 << 0)
  57311. +#define DSEMR_DS_OFFS 1
  57312. +#define DSEMR_DS_MASK (1 << DSEMR_DS_OFFS)
  57313. +#define DSEMR_DS_NORMAL (0 << DSEMR_DS_OFFS)
  57314. +#define DSEMR_DS_REDUCED (1 << DSEMR_DS_OFFS)
  57315. +#define DSEMR_RTT0_OFFS 2
  57316. +#define DSEMR_RTT1_OFFS 6
  57317. +#define DSEMR_RTT_ODT_DISABLE ((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  57318. +#define DSEMR_RTT_ODT_75_OHM ((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  57319. +#define DSEMR_RTT_ODT_150_OHM ((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
  57320. +#define DSEMR_OCD_OFFS 7
  57321. +#define DSEMR_OCD_MASK (0x7 << DSEMR_OCD_OFFS)
  57322. +#define DSEMR_OCD_EXIT_CALIB (0 << DSEMR_OCD_OFFS)
  57323. +#define DSEMR_OCD_DRIVE1 (1 << DSEMR_OCD_OFFS)
  57324. +#define DSEMR_OCD_DRIVE0 (2 << DSEMR_OCD_OFFS)
  57325. +#define DSEMR_OCD_ADJUST_MODE (4 << DSEMR_OCD_OFFS)
  57326. +#define DSEMR_OCD_CALIB_DEFAULT (7 << DSEMR_OCD_OFFS)
  57327. +#define DSEMR_DQS_OFFS 10
  57328. +#define DSEMR_DQS_MASK (1 << DSEMR_DQS_OFFS)
  57329. +#define DSEMR_DQS_DIFFERENTIAL (0 << DSEMR_DQS_OFFS)
  57330. +#define DSEMR_DQS_SINGLE_ENDED (0 << DSEMR_DQS_OFFS)
  57331. +#define DSEMR_RDQS_ENABLE (1 << 11)
  57332. +#define DSEMR_QOFF_OUTPUT_BUFF_EN (1 << 12)
  57333. +
  57334. +/* DDR SDRAM Operation Control Register */
  57335. +#define SDRAM_OPERATION_CTRL_REG 0x142c
  57336. +
  57337. +/* Dunit FTDLL Configuration Register */
  57338. +#define SDRAM_FTDLL_CONFIG_REG 0x1484
  57339. +
  57340. +/* Pads Calibration register */
  57341. +#define SDRAM_ADDR_CTRL_PADS_CAL_REG 0x14c0
  57342. +#define SDRAM_DATA_PADS_CAL_REG 0x14c4
  57343. +#define SDRAM_DRVN_OFFS 0
  57344. +#define SDRAM_DRVN_MASK (0x3F << SDRAM_DRVN_OFFS)
  57345. +#define SDRAM_DRVP_OFFS 6
  57346. +#define SDRAM_DRVP_MASK (0x3F << SDRAM_DRVP_OFFS)
  57347. +#define SDRAM_PRE_DRIVER_STRENGTH_OFFS 12
  57348. +#define SDRAM_PRE_DRIVER_STRENGTH_MASK (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  57349. +#define SDRAM_TUNE_EN BIT16
  57350. +#define SDRAM_LOCK_OFFS 17
  57351. +#define SDRAM_LOCK_MAKS (0x1F << SDRAM_LOCK_OFFS)
  57352. +#define SDRAM_LOCKN_OFFS 17
  57353. +#define SDRAM_LOCKN_MAKS (0x3F << SDRAM_LOCKN_OFFS)
  57354. +#define SDRAM_LOCKP_OFFS 23
  57355. +#define SDRAM_LOCKP_MAKS (0x3F << SDRAM_LOCKP_OFFS)
  57356. +#define SDRAM_WR_EN (1 << 31)
  57357. +
  57358. +/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */
  57359. +#define DDR2_SDRAM_ODT_CTRL_LOW_REG 0x1494
  57360. +#define DSOCLR_ODT_RD_OFFS(odtNum) (odtNum * 4)
  57361. +#define DSOCLR_ODT_RD_MASK(odtNum) (0xf << DSOCLR_ODT_RD_OFFS(odtNum))
  57362. +#define DSOCLR_ODT_RD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))
  57363. +#define DSOCLR_ODT_WR_OFFS(odtNum) (16 + (odtNum * 4))
  57364. +#define DSOCLR_ODT_WR_MASK(odtNum) (0xf << DSOCLR_ODT_WR_OFFS(odtNum))
  57365. +#define DSOCLR_ODT_WD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))
  57366. +
  57367. +/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */
  57368. +#define DDR2_SDRAM_ODT_CTRL_HIGH_REG 0x1498
  57369. +/* Optional control values to DSOCHR_ODT_EN macro */
  57370. +#define DDR2_ODT_CTRL_DUNIT 0
  57371. +#define DDR2_ODT_CTRL_NEVER 1
  57372. +#define DDR2_ODT_CTRL_ALWAYS 3
  57373. +#define DSOCHR_ODT_EN_OFFS(odtNum) (odtNum * 2)
  57374. +#define DSOCHR_ODT_EN_MASK(odtNum) (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))
  57375. +#define DSOCHR_ODT_EN(odtNum, ctrl) ((1 << ctrl) << DSOCHR_ODT_RD_OFFS(odtNum))
  57376. +
  57377. +/* DDR2 Dunit ODT Control Register (DDOCR)*/
  57378. +#define DDR2_DUNIT_ODT_CONTROL_REG 0x149c
  57379. +#define DDOCR_ODT_RD_OFFS 0
  57380. +#define DDOCR_ODT_RD_MASK (0xf << DDOCR_ODT_RD_OFFS)
  57381. +#define DDOCR_ODT_RD(bank) ((1 << bank) << DDOCR_ODT_RD_OFFS)
  57382. +#define DDOCR_ODT_WR_OFFS 4
  57383. +#define DDOCR_ODT_WR_MASK (0xf << DDOCR_ODT_WR_OFFS)
  57384. +#define DDOCR_ODT_WR(bank) ((1 << bank) << DDOCR_ODT_WR_OFFS)
  57385. +#define DSOCR_ODT_EN_OFFS 8
  57386. +#define DSOCR_ODT_EN_MASK (0x3 << DSOCR_ODT_EN_OFFS)
  57387. +#define DSOCR_ODT_EN(ctrl) ((1 << ctrl) << DSOCR_ODT_EN_OFFS)
  57388. +#define DSOCR_ODT_SEL_OFFS 10
  57389. +#define DSOCR_ODT_SEL_MASK (0x3 << DSOCR_ODT_SEL_OFFS)
  57390. +
  57391. +/* DDR SDRAM Initialization Control Register (DSICR) */
  57392. +#define DDR_SDRAM_INIT_CTRL_REG 0x1480
  57393. +#define DSICR_INIT_EN (1 << 0)
  57394. +
  57395. +#endif /* __INCmvDramIfRegsh */
  57396. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c
  57397. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c 1970-01-01 01:00:00.000000000 +0100
  57398. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c 2011-07-31 11:31:59.757175391 +0200
  57399. @@ -0,0 +1,1855 @@
  57400. +/*******************************************************************************
  57401. +Copyright (C) Marvell International Ltd. and its affiliates
  57402. +
  57403. +This software file (the "File") is owned and distributed by Marvell
  57404. +International Ltd. and/or its affiliates ("Marvell") under the following
  57405. +alternative licensing terms. Once you have made an election to distribute the
  57406. +File under one of the following license alternatives, please (i) delete this
  57407. +introductory statement regarding license alternatives, (ii) delete the two
  57408. +license alternatives that you have not elected to use and (iii) preserve the
  57409. +Marvell copyright notice above.
  57410. +
  57411. +********************************************************************************
  57412. +Marvell Commercial License Option
  57413. +
  57414. +If you received this File from Marvell and you have entered into a commercial
  57415. +license agreement (a "Commercial License") with Marvell, the File is licensed
  57416. +to you under the terms of the applicable Commercial License.
  57417. +
  57418. +********************************************************************************
  57419. +Marvell GPL License Option
  57420. +
  57421. +If you received this File from Marvell, you may opt to use, redistribute and/or
  57422. +modify this File in accordance with the terms and conditions of the General
  57423. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  57424. +available along with the File in the license.txt file or by writing to the Free
  57425. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  57426. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  57427. +
  57428. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  57429. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  57430. +DISCLAIMED. The GPL License provides additional details about this warranty
  57431. +disclaimer.
  57432. +********************************************************************************
  57433. +Marvell BSD License Option
  57434. +
  57435. +If you received this File from Marvell, you may opt to use, redistribute and/or
  57436. +modify this File under the following licensing terms.
  57437. +Redistribution and use in source and binary forms, with or without modification,
  57438. +are permitted provided that the following conditions are met:
  57439. +
  57440. + * Redistributions of source code must retain the above copyright notice,
  57441. + this list of conditions and the following disclaimer.
  57442. +
  57443. + * Redistributions in binary form must reproduce the above copyright
  57444. + notice, this list of conditions and the following disclaimer in the
  57445. + documentation and/or other materials provided with the distribution.
  57446. +
  57447. + * Neither the name of Marvell nor the names of its contributors may be
  57448. + used to endorse or promote products derived from this software without
  57449. + specific prior written permission.
  57450. +
  57451. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  57452. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  57453. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  57454. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  57455. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  57456. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  57457. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  57458. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  57459. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  57460. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  57461. +
  57462. +*******************************************************************************/
  57463. +
  57464. +
  57465. +/* includes */
  57466. +#include "ddr2/mvDramIf.h"
  57467. +#include "ctrlEnv/sys/mvCpuIf.h"
  57468. +
  57469. +#include "ddr2/mvDramIfStaticInit.h"
  57470. +
  57471. +/* #define MV_DEBUG */
  57472. +#ifdef MV_DEBUG
  57473. +#define DB(x) x
  57474. +#else
  57475. +#define DB(x)
  57476. +#endif
  57477. +
  57478. +/* DRAM bank presence encoding */
  57479. +#define BANK_PRESENT_CS0 0x1
  57480. +#define BANK_PRESENT_CS0_CS1 0x3
  57481. +#define BANK_PRESENT_CS0_CS2 0x5
  57482. +#define BANK_PRESENT_CS0_CS1_CS2 0x7
  57483. +#define BANK_PRESENT_CS0_CS2_CS3 0xd
  57484. +#define BANK_PRESENT_CS0_CS2_CS3_CS4 0xf
  57485. +
  57486. +/* locals */
  57487. +#ifndef MV_STATIC_DRAM_ON_BOARD
  57488. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
  57489. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk, MV_STATUS TTmode );
  57490. +static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  57491. +static MV_U32 sdramModeRegCalc(MV_U32 minCas);
  57492. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  57493. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1);
  57494. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk);
  57495. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl);
  57496. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk);
  57497. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  57498. +static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas);
  57499. +static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas);
  57500. +#endif
  57501. +MV_32 DRAM_CS_Order[MV_DRAM_MAX_CS] = {N_A
  57502. +
  57503. +#ifdef MV_INCLUDE_SDRAM_CS1
  57504. + ,N_A
  57505. +#endif
  57506. +#ifdef MV_INCLUDE_SDRAM_CS2
  57507. + ,N_A
  57508. +#endif
  57509. +#ifdef MV_INCLUDE_SDRAM_CS3
  57510. + ,N_A
  57511. +#endif
  57512. + };
  57513. +/* Get DRAM size of CS num */
  57514. +MV_U32 mvDramCsSizeGet(MV_U32 csNum)
  57515. +{
  57516. + MV_DRAM_BANK_INFO bankInfo;
  57517. + MV_U32 size, deviceW, dimmW;
  57518. +#ifdef MV78XX0
  57519. + MV_U32 temp;
  57520. +#endif
  57521. +
  57522. + if(MV_OK == mvDramBankInfoGet(csNum, &bankInfo))
  57523. + {
  57524. + if (0 == bankInfo.size)
  57525. + return 0;
  57526. +
  57527. + /* Note that the Dimm width might be different then the device DRAM width */
  57528. +#ifdef MV78XX0
  57529. + temp = MV_REG_READ(SDRAM_CONFIG_REG);
  57530. + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
  57531. +#else
  57532. + deviceW = 16 /* KW family */;
  57533. +#endif
  57534. + dimmW = bankInfo.dataWidth - (bankInfo.dataWidth % 16);
  57535. + size = ((bankInfo.size << 20) / (dimmW/deviceW));
  57536. + return size;
  57537. + }
  57538. + else
  57539. + return 0;
  57540. +}
  57541. +/*******************************************************************************
  57542. +* mvDramIfDetect - Prepare DRAM interface configuration values.
  57543. +*
  57544. +* DESCRIPTION:
  57545. +* This function implements the full DRAM detection and timing
  57546. +* configuration for best system performance.
  57547. +* Since this routine runs from a ROM device (Boot Flash), its stack
  57548. +* resides on RAM, that might be the system DRAM. Changing DRAM
  57549. +* configuration values while keeping vital data in DRAM is risky. That
  57550. +* is why the function does not preform the configuration setting but
  57551. +* prepare those in predefined 32bit registers (in this case IDMA
  57552. +* registers are used) for other routine to perform the settings.
  57553. +* The function will call for board DRAM SPD information for each DRAM
  57554. +* chip select. The function will then analyze those SPD parameters of
  57555. +* all DRAM banks in order to decide on DRAM configuration compatible
  57556. +* for all DRAM banks.
  57557. +* The function will set the CPU DRAM address decode registers.
  57558. +* Note: This routine prepares values that will overide configuration of
  57559. +* mvDramBasicAsmInit().
  57560. +*
  57561. +* INPUT:
  57562. +* forcedCl - Forced CAL Latency. If equal to zero, do not force.
  57563. +* eccDisable - Force down the ECC.
  57564. +*
  57565. +* OUTPUT:
  57566. +* None.
  57567. +*
  57568. +* RETURN:
  57569. +* None.
  57570. +*
  57571. +*******************************************************************************/
  57572. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable)
  57573. +{
  57574. + MV_32 MV_DRAM_CS_order[MV_DRAM_MAX_CS] = {
  57575. + SDRAM_CS0
  57576. +#ifdef MV_INCLUDE_SDRAM_CS1
  57577. + ,SDRAM_CS1
  57578. +#endif
  57579. +#ifdef MV_INCLUDE_SDRAM_CS2
  57580. + ,SDRAM_CS2
  57581. +#endif
  57582. +#ifdef MV_INCLUDE_SDRAM_CS3
  57583. + ,SDRAM_CS3
  57584. +#endif
  57585. + };
  57586. + MV_U32 busClk, deviceW, dimmW;
  57587. + MV_U32 numOfAllDevices = 0;
  57588. + MV_STATUS TTMode;
  57589. +#ifndef MV_STATIC_DRAM_ON_BOARD
  57590. + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
  57591. + MV_U32 size, base = 0, i, j, temp, busClkPs;
  57592. + MV_U8 minCas;
  57593. + MV_CPU_DEC_WIN dramDecWin;
  57594. + dramDecWin.addrWin.baseHigh = 0;
  57595. +#endif
  57596. +
  57597. + busClk = mvBoardSysClkGet();
  57598. +
  57599. + if (0 == busClk)
  57600. + {
  57601. + mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
  57602. + return MV_ERROR;
  57603. + }
  57604. +
  57605. +#ifndef MV_STATIC_DRAM_ON_BOARD
  57606. +
  57607. + busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
  57608. + /* we will use bank 0 as the representative of the all the DRAM banks, */
  57609. + /* since bank 0 must exist. */
  57610. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  57611. + {
  57612. + /* if Bank exist */
  57613. + if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
  57614. + {
  57615. + DB(mvOsPrintf("Dram: Find bank %d\n", i));
  57616. + /* check it isn't SDRAM */
  57617. + if(bankInfo[i].memoryType != MEM_TYPE_DDR2)
  57618. + {
  57619. + mvOsOutput("Dram: ERR. SDRAM type not supported !!!\n");
  57620. + return MV_ERROR;
  57621. + }
  57622. +
  57623. + /* All banks must support the Mclk freqency */
  57624. + if(bankInfo[i].minCycleTimeAtMaxCasLatPs > busClkPs)
  57625. + {
  57626. + mvOsOutput("Dram: ERR. Bank %d doesn't support memory clock!!!\n", i);
  57627. + return MV_ERROR;
  57628. + }
  57629. +
  57630. + /* All banks must support registry in order to activate it */
  57631. + if(bankInfo[i].registeredAddrAndControlInputs !=
  57632. + bankInfo[0].registeredAddrAndControlInputs)
  57633. + {
  57634. + mvOsOutput("Dram: ERR. different Registered settings !!!\n");
  57635. + return MV_ERROR;
  57636. + }
  57637. +
  57638. + /* All banks must support same ECC mode */
  57639. + if(bankInfo[i].errorCheckType !=
  57640. + bankInfo[0].errorCheckType)
  57641. + {
  57642. + mvOsOutput("Dram: ERR. different ECC settings !!!\n");
  57643. + return MV_ERROR;
  57644. + }
  57645. +
  57646. + }
  57647. + else
  57648. + {
  57649. + if( i == 0 ) /* bank 0 doesn't exist */
  57650. + {
  57651. + mvOsOutput("Dram: ERR. Fail to detect bank 0 !!!\n");
  57652. + return MV_ERROR;
  57653. + }
  57654. + else
  57655. + {
  57656. + DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
  57657. + bankInfo[i].size = 0; /* Mark this bank as non exist */
  57658. + }
  57659. + }
  57660. + }
  57661. +
  57662. +#ifdef MV_INCLUDE_SDRAM_CS2
  57663. + if (bankInfo[SDRAM_CS0].size < bankInfo[SDRAM_CS2].size)
  57664. + {
  57665. + MV_DRAM_CS_order[0] = SDRAM_CS2;
  57666. + MV_DRAM_CS_order[1] = SDRAM_CS3;
  57667. + MV_DRAM_CS_order[2] = SDRAM_CS0;
  57668. + MV_DRAM_CS_order[3] = SDRAM_CS1;
  57669. + DRAM_CS_Order[0] = SDRAM_CS2;
  57670. + DRAM_CS_Order[1] = SDRAM_CS3;
  57671. + DRAM_CS_Order[2] = SDRAM_CS0;
  57672. + DRAM_CS_Order[3] = SDRAM_CS1;
  57673. +
  57674. + }
  57675. + else
  57676. +#endif
  57677. + {
  57678. + MV_DRAM_CS_order[0] = SDRAM_CS0;
  57679. + MV_DRAM_CS_order[1] = SDRAM_CS1;
  57680. + DRAM_CS_Order[0] = SDRAM_CS0;
  57681. + DRAM_CS_Order[1] = SDRAM_CS1;
  57682. +#ifdef MV_INCLUDE_SDRAM_CS2
  57683. + MV_DRAM_CS_order[2] = SDRAM_CS2;
  57684. + MV_DRAM_CS_order[3] = SDRAM_CS3;
  57685. + DRAM_CS_Order[2] = SDRAM_CS2;
  57686. + DRAM_CS_Order[3] = SDRAM_CS3;
  57687. +#endif
  57688. + }
  57689. +
  57690. + for(j = 0; j < MV_DRAM_MAX_CS; j++)
  57691. + {
  57692. + i = MV_DRAM_CS_order[j];
  57693. +
  57694. + if (0 == bankInfo[i].size)
  57695. + continue;
  57696. +
  57697. + /* Init the CPU window decode */
  57698. + /* Note that the Dimm width might be different then the device DRAM width */
  57699. +#ifdef MV78XX0
  57700. + temp = MV_REG_READ(SDRAM_CONFIG_REG);
  57701. + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
  57702. +#else
  57703. + deviceW = 16 /* KW family */;
  57704. +#endif
  57705. + dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
  57706. + size = ((bankInfo[i].size << 20) / (dimmW/deviceW));
  57707. +
  57708. + /* We can not change DRAM window settings while excecuting */
  57709. + /* code from it. That is why we skip the DRAM CS[0], saving */
  57710. + /* it to the ROM configuration routine */
  57711. +
  57712. + numOfAllDevices += bankInfo[i].numberOfDevices;
  57713. + if (i == MV_DRAM_CS_order[0])
  57714. + {
  57715. + MV_U32 sizeToReg;
  57716. + /* Translate the given window size to register format */
  57717. + sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
  57718. + /* Size parameter validity check. */
  57719. + if (-1 == sizeToReg)
  57720. + {
  57721. + mvOsOutput("DRAM: mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
  57722. + ,i);
  57723. + return MV_BAD_PARAM;
  57724. + }
  57725. +
  57726. + DB(mvOsPrintf("Dram: Bank 0 Size - %x\n",sizeToReg);)
  57727. + sizeToReg = (sizeToReg << SCSR_SIZE_OFFS);
  57728. + sizeToReg |= SCSR_WIN_EN;
  57729. + MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
  57730. + }
  57731. + else
  57732. + {
  57733. + dramDecWin.addrWin.baseLow = base;
  57734. + dramDecWin.addrWin.size = size;
  57735. + dramDecWin.enable = MV_TRUE;
  57736. + DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
  57737. +
  57738. + /* Check if the DRAM size is more then 3GByte */
  57739. + if (base < 0xC0000000)
  57740. + {
  57741. + DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
  57742. + if (MV_OK != mvCpuIfTargetWinSet(i, &dramDecWin))
  57743. + {
  57744. + mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n", SDRAM_CS0 + i);
  57745. + return MV_ERROR;
  57746. + }
  57747. + }
  57748. + }
  57749. +
  57750. + base += size;
  57751. +
  57752. + /* update the suportedCasLatencies mask */
  57753. + bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
  57754. + }
  57755. +
  57756. + /* calculate minimum CAS */
  57757. + minCas = minCasCalc(&bankInfo[0], &bankInfo[2], busClk, forcedCl);
  57758. + if (0 == minCas)
  57759. + {
  57760. + mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
  57761. + (busClk / 1000000));
  57762. +
  57763. + minCas = DDR2_CL_4; /* Continue with this CAS */
  57764. + mvOsOutput("Set default CAS latency 4\n");
  57765. + }
  57766. +
  57767. + /* calc SDRAM_CONFIG_REG and save it to temp register */
  57768. + temp = sdramConfigRegCalc(&bankInfo[0],&bankInfo[2], busClk);
  57769. + if(-1 == temp)
  57770. + {
  57771. + mvOsOutput("Dram: ERR. sdramConfigRegCalc failed !!!\n");
  57772. + return MV_ERROR;
  57773. + }
  57774. +
  57775. + /* check if ECC is enabled by the user */
  57776. + if(eccDisable)
  57777. + {
  57778. + /* turn off ECC*/
  57779. + temp &= ~BIT18;
  57780. + }
  57781. + DB(mvOsPrintf("Dram: sdramConfigRegCalc - %x\n",temp);)
  57782. + MV_REG_WRITE(DRAM_BUF_REG1, temp);
  57783. +
  57784. + /* calc SDRAM_MODE_REG and save it to temp register */
  57785. + temp = sdramModeRegCalc(minCas);
  57786. + if(-1 == temp)
  57787. + {
  57788. + mvOsOutput("Dram: ERR. sdramModeRegCalc failed !!!\n");
  57789. + return MV_ERROR;
  57790. + }
  57791. + DB(mvOsPrintf("Dram: sdramModeRegCalc - %x\n",temp);)
  57792. + MV_REG_WRITE(DRAM_BUF_REG2, temp);
  57793. +
  57794. + /* calc SDRAM_EXTENDED_MODE_REG and save it to temp register */
  57795. + temp = sdramExtModeRegCalc(&bankInfo[0], busClk);
  57796. + if(-1 == temp)
  57797. + {
  57798. + mvOsOutput("Dram: ERR. sdramExtModeRegCalc failed !!!\n");
  57799. + return MV_ERROR;
  57800. + }
  57801. + DB(mvOsPrintf("Dram: sdramExtModeRegCalc - %x\n",temp);)
  57802. + MV_REG_WRITE(DRAM_BUF_REG10, temp);
  57803. +
  57804. + /* calc D_UNIT_CONTROL_LOW and save it to temp register */
  57805. + TTMode = MV_FALSE;
  57806. + DB(mvOsPrintf("Dram: numOfAllDevices = %x\n",numOfAllDevices);)
  57807. + if( (numOfAllDevices > 9) && (bankInfo[0].registeredAddrAndControlInputs == MV_FALSE) )
  57808. + {
  57809. + if ( ( (numOfAllDevices > 9) && (busClk > MV_BOARD_SYSCLK_200MHZ) ) ||
  57810. + (numOfAllDevices > 18) )
  57811. + {
  57812. + mvOsOutput("Enable 2T ");
  57813. + TTMode = MV_TRUE;
  57814. + }
  57815. + }
  57816. +
  57817. + temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas, busClk, TTMode );
  57818. + if(-1 == temp)
  57819. + {
  57820. + mvOsOutput("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
  57821. + return MV_ERROR;
  57822. + }
  57823. + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc - %x\n",temp);)
  57824. + MV_REG_WRITE(DRAM_BUF_REG3, temp);
  57825. +
  57826. + /* calc D_UNIT_CONTROL_HIGH and save it to temp register */
  57827. + temp = dunitCtrlHighRegCalc(&bankInfo[0], busClk);
  57828. + if(-1 == temp)
  57829. + {
  57830. + mvOsOutput("Dram: ERR. dunitCtrlHighRegCalc failed !!!\n");
  57831. + return MV_ERROR;
  57832. + }
  57833. + DB(mvOsPrintf("Dram: dunitCtrlHighRegCalc - %x\n",temp);)
  57834. + /* check if ECC is enabled by the user */
  57835. + if(eccDisable)
  57836. + {
  57837. + /* turn off sample stage if no ecc */
  57838. + temp &= ~SDRAM__D2P_EN;;
  57839. + }
  57840. + MV_REG_WRITE(DRAM_BUF_REG13, temp);
  57841. +
  57842. + /* calc SDRAM_ADDR_CTRL_REG and save it to temp register */
  57843. + temp = sdramAddrCtrlRegCalc(&bankInfo[0],&bankInfo[2]);
  57844. + if(-1 == temp)
  57845. + {
  57846. + mvOsOutput("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
  57847. + return MV_ERROR;
  57848. + }
  57849. + DB(mvOsPrintf("Dram: sdramAddrCtrlRegCalc - %x\n",temp);)
  57850. + MV_REG_WRITE(DRAM_BUF_REG4, temp);
  57851. +
  57852. + /* calc SDRAM_TIMING_CTRL_LOW_REG and save it to temp register */
  57853. + temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
  57854. + if(-1 == temp)
  57855. + {
  57856. + mvOsOutput("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
  57857. + return MV_ERROR;
  57858. + }
  57859. + DB(mvOsPrintf("Dram: sdramTimeCtrlLowRegCalc - %x\n",temp);)
  57860. + MV_REG_WRITE(DRAM_BUF_REG5, temp);
  57861. +
  57862. + /* calc SDRAM_TIMING_CTRL_HIGH_REG and save it to temp register */
  57863. + temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
  57864. + if(-1 == temp)
  57865. + {
  57866. + mvOsOutput("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
  57867. + return MV_ERROR;
  57868. + }
  57869. + DB(mvOsPrintf("Dram: sdramTimeCtrlHighRegCalc - %x\n",temp);)
  57870. + MV_REG_WRITE(DRAM_BUF_REG6, temp);
  57871. +
  57872. + sdramDDr2OdtConfig(bankInfo);
  57873. +
  57874. + /* calc DDR2_SDRAM_TIMING_LOW_REG and save it to temp register */
  57875. + temp = sdramDdr2TimeLoRegCalc(minCas);
  57876. + if(-1 == temp)
  57877. + {
  57878. + mvOsOutput("Dram: ERR. sdramDdr2TimeLoRegCalc failed !!!\n");
  57879. + return MV_ERROR;
  57880. + }
  57881. + DB(mvOsPrintf("Dram: sdramDdr2TimeLoRegCalc - %x\n",temp);)
  57882. + MV_REG_WRITE(DRAM_BUF_REG11, temp);
  57883. +
  57884. + /* calc DDR2_SDRAM_TIMING_HIGH_REG and save it to temp register */
  57885. + temp = sdramDdr2TimeHiRegCalc(minCas);
  57886. + if(-1 == temp)
  57887. + {
  57888. + mvOsOutput("Dram: ERR. sdramDdr2TimeHiRegCalc failed !!!\n");
  57889. + return MV_ERROR;
  57890. + }
  57891. + DB(mvOsPrintf("Dram: sdramDdr2TimeHiRegCalc - %x\n",temp);)
  57892. + MV_REG_WRITE(DRAM_BUF_REG12, temp);
  57893. +#endif
  57894. +
  57895. + /* Note that DDR SDRAM Address/Control and Data pad calibration */
  57896. + /* settings is done in mvSdramIfConfig.s */
  57897. +
  57898. + return MV_OK;
  57899. +}
  57900. +
  57901. +
  57902. +/*******************************************************************************
  57903. +* mvDramIfBankBaseGet - Get DRAM interface bank base.
  57904. +*
  57905. +* DESCRIPTION:
  57906. +* This function returns the 32 bit base address of a given DRAM bank.
  57907. +*
  57908. +* INPUT:
  57909. +* bankNum - Bank number.
  57910. +*
  57911. +* OUTPUT:
  57912. +* None.
  57913. +*
  57914. +* RETURN:
  57915. +* DRAM bank size. If bank is disabled or paramter is invalid, the
  57916. +* function returns -1.
  57917. +*
  57918. +*******************************************************************************/
  57919. +MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum)
  57920. +{
  57921. + DB(mvOsPrintf("Dram: mvDramIfBankBaseGet Bank %d base addr is %x \n",
  57922. + bankNum, mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum)));
  57923. + return mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum);
  57924. +}
  57925. +
  57926. +/*******************************************************************************
  57927. +* mvDramIfBankSizeGet - Get DRAM interface bank size.
  57928. +*
  57929. +* DESCRIPTION:
  57930. +* This function returns the size of a given DRAM bank.
  57931. +*
  57932. +* INPUT:
  57933. +* bankNum - Bank number.
  57934. +*
  57935. +* OUTPUT:
  57936. +* None.
  57937. +*
  57938. +* RETURN:
  57939. +* DRAM bank size. If bank is disabled the function return '0'. In case
  57940. +* or paramter is invalid, the function returns -1.
  57941. +*
  57942. +*******************************************************************************/
  57943. +MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum)
  57944. +{
  57945. + DB(mvOsPrintf("Dram: mvDramIfBankSizeGet Bank %d size is %x \n",
  57946. + bankNum, mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum)));
  57947. + return mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum);
  57948. +}
  57949. +
  57950. +
  57951. +/*******************************************************************************
  57952. +* mvDramIfSizeGet - Get DRAM interface total size.
  57953. +*
  57954. +* DESCRIPTION:
  57955. +* This function get the DRAM total size.
  57956. +*
  57957. +* INPUT:
  57958. +* None.
  57959. +*
  57960. +* OUTPUT:
  57961. +* None.
  57962. +*
  57963. +* RETURN:
  57964. +* DRAM total size. In case or paramter is invalid, the function
  57965. +* returns -1.
  57966. +*
  57967. +*******************************************************************************/
  57968. +MV_U32 mvDramIfSizeGet(MV_VOID)
  57969. +{
  57970. + MV_U32 size = 0, i;
  57971. +
  57972. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  57973. + size += mvDramIfBankSizeGet(i);
  57974. +
  57975. + DB(mvOsPrintf("Dram: mvDramIfSizeGet size is %x \n",size));
  57976. + return size;
  57977. +}
  57978. +
  57979. +/*******************************************************************************
  57980. +* mvDramIfSingleBitErrThresholdSet - Set single bit ECC threshold.
  57981. +*
  57982. +* DESCRIPTION:
  57983. +* The ECC single bit error threshold is the number of single bit
  57984. +* errors to happen before the Dunit generates an interrupt.
  57985. +* This function set single bit ECC threshold.
  57986. +*
  57987. +* INPUT:
  57988. +* threshold - threshold.
  57989. +*
  57990. +* OUTPUT:
  57991. +* None.
  57992. +*
  57993. +* RETURN:
  57994. +* MV_BAD_PARAM if threshold is to big, MV_OK otherwise.
  57995. +*
  57996. +*******************************************************************************/
  57997. +MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold)
  57998. +{
  57999. + MV_U32 regVal;
  58000. +
  58001. + if (threshold > SECR_THRECC_MAX)
  58002. + {
  58003. + return MV_BAD_PARAM;
  58004. + }
  58005. +
  58006. + regVal = MV_REG_READ(SDRAM_ECC_CONTROL_REG);
  58007. + regVal &= ~SECR_THRECC_MASK;
  58008. + regVal |= ((SECR_THRECC(threshold) & SECR_THRECC_MASK));
  58009. + MV_REG_WRITE(SDRAM_ECC_CONTROL_REG, regVal);
  58010. +
  58011. + return MV_OK;
  58012. +}
  58013. +
  58014. +#ifndef MV_STATIC_DRAM_ON_BOARD
  58015. +/*******************************************************************************
  58016. +* minCasCalc - Calculate the Minimum CAS latency which can be used.
  58017. +*
  58018. +* DESCRIPTION:
  58019. +* Calculate the minimum CAS latency that can be used, base on the DRAM
  58020. +* parameters and the SDRAM bus Clock freq.
  58021. +*
  58022. +* INPUT:
  58023. +* busClk - the DRAM bus Clock.
  58024. +* pBankInfo - bank info parameters.
  58025. +* forcedCl - Forced CAS Latency multiplied by 10. If equal to zero, do not force.
  58026. +*
  58027. +* OUTPUT:
  58028. +* None
  58029. +*
  58030. +* RETURN:
  58031. +* The minimum CAS Latency. The function returns 0 if max CAS latency
  58032. +* supported by banks is incompatible with system bus clock frequancy.
  58033. +*
  58034. +*******************************************************************************/
  58035. +
  58036. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl)
  58037. +{
  58038. + MV_U32 count = 1, j;
  58039. + MV_U32 busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
  58040. + MV_U32 startBit, stopBit;
  58041. + MV_U32 minCas0 = 0, minCas2 = 0;
  58042. +
  58043. +
  58044. + /* DDR 2:
  58045. + *******-******-******-******-******-******-******-*******
  58046. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  58047. + *******-******-******-******-******-******-******-*******
  58048. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  58049. + Disco VI= * TBD | TBD | 5 | 4 | 3 | TBD | TBD | TBD *
  58050. + Disco Duo= * TBD | 6 | 5 | 4 | 3 | TBD | TBD | TBD *
  58051. + *********************************************************/
  58052. +
  58053. +
  58054. + /* If we are asked to use the forced CAL we change the suported CAL to be forcedCl only */
  58055. + if (forcedCl)
  58056. + {
  58057. + mvOsOutput("DRAM: Using forced CL %d.%d\n", (forcedCl / 10), (forcedCl % 10));
  58058. +
  58059. + if (forcedCl == 30)
  58060. + pBankInfo->suportedCasLatencies = 0x08;
  58061. + else if (forcedCl == 40)
  58062. + pBankInfo->suportedCasLatencies = 0x10;
  58063. + else if (forcedCl == 50)
  58064. + pBankInfo->suportedCasLatencies = 0x20;
  58065. + else if (forcedCl == 60)
  58066. + pBankInfo->suportedCasLatencies = 0x40;
  58067. + else
  58068. + {
  58069. + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n",
  58070. + (forcedCl / 10), (forcedCl % 10));
  58071. + pBankInfo->suportedCasLatencies = 0x10;
  58072. + }
  58073. +
  58074. + return pBankInfo->suportedCasLatencies;
  58075. + }
  58076. +
  58077. + /* go over the supported cas mask from Max Cas down and check if the */
  58078. + /* SysClk stands in its time requirments. */
  58079. +
  58080. + DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
  58081. + pBankInfo->suportedCasLatencies,busClkPs ));
  58082. + count = 1;
  58083. + for(j = 7; j > 0; j--)
  58084. + {
  58085. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  58086. + {
  58087. + /* Reset the bits for CL incompatible for the sysClk */
  58088. + switch (count)
  58089. + {
  58090. + case 1:
  58091. + if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs)
  58092. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  58093. + count++;
  58094. + break;
  58095. + case 2:
  58096. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
  58097. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  58098. + count++;
  58099. + break;
  58100. + case 3:
  58101. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
  58102. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  58103. + count++;
  58104. + break;
  58105. + default:
  58106. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  58107. + break;
  58108. + }
  58109. + }
  58110. + }
  58111. +
  58112. + DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
  58113. + pBankInfo->suportedCasLatencies ));
  58114. +
  58115. + count = 1;
  58116. + DB(mvOsPrintf("Dram2: minCasCalc supported mask = %x busClkPs = %x \n",
  58117. + pBankInfo2->suportedCasLatencies,busClkPs ));
  58118. + for(j = 7; j > 0; j--)
  58119. + {
  58120. + if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
  58121. + {
  58122. + /* Reset the bits for CL incompatible for the sysClk */
  58123. + switch (count)
  58124. + {
  58125. + case 1:
  58126. + if (pBankInfo2->minCycleTimeAtMaxCasLatPs > busClkPs)
  58127. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  58128. + count++;
  58129. + break;
  58130. + case 2:
  58131. + if (pBankInfo2->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
  58132. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  58133. + count++;
  58134. + break;
  58135. + case 3:
  58136. + if (pBankInfo2->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
  58137. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  58138. + count++;
  58139. + break;
  58140. + default:
  58141. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  58142. + break;
  58143. + }
  58144. + }
  58145. + }
  58146. +
  58147. + DB(mvOsPrintf("Dram2: minCasCalc support = %x (after SysCC calc)\n",
  58148. + pBankInfo2->suportedCasLatencies ));
  58149. +
  58150. + startBit = 3; /* DDR2 support CL start with CL3 (bit 3) */
  58151. + stopBit = 6; /* DDR2 support CL stops with CL6 (bit 6) */
  58152. +
  58153. + for(j = startBit; j <= stopBit ; j++)
  58154. + {
  58155. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  58156. + {
  58157. + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
  58158. + minCas0 = (BIT0 << j);
  58159. + break;
  58160. + }
  58161. + }
  58162. +
  58163. + for(j = startBit; j <= stopBit ; j++)
  58164. + {
  58165. + if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
  58166. + {
  58167. + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
  58168. + minCas2 = (BIT0 << j);
  58169. + break;
  58170. + }
  58171. + }
  58172. +
  58173. + if (minCas2 > minCas0)
  58174. + return minCas2;
  58175. + else
  58176. + return minCas0;
  58177. +
  58178. + return 0;
  58179. +}
  58180. +
  58181. +/*******************************************************************************
  58182. +* sdramConfigRegCalc - Calculate sdram config register
  58183. +*
  58184. +* DESCRIPTION: Calculate sdram config register optimized value based
  58185. +* on the bank info parameters.
  58186. +*
  58187. +* INPUT:
  58188. +* busClk - the DRAM bus Clock.
  58189. +* pBankInfo - sdram bank parameters
  58190. +*
  58191. +* OUTPUT:
  58192. +* None
  58193. +*
  58194. +* RETURN:
  58195. +* sdram config reg value.
  58196. +*
  58197. +*******************************************************************************/
  58198. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk)
  58199. +{
  58200. + MV_U32 sdramConfig = 0;
  58201. + MV_U32 refreshPeriod;
  58202. +
  58203. + busClk /= 1000000; /* we work with busClk in MHz */
  58204. +
  58205. + sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
  58206. +
  58207. + /* figure out the memory refresh internal */
  58208. + switch (pBankInfo->refreshInterval & 0xf)
  58209. + {
  58210. + case 0x0: /* refresh period is 15.625 usec */
  58211. + refreshPeriod = 15625;
  58212. + break;
  58213. + case 0x1: /* refresh period is 3.9 usec */
  58214. + refreshPeriod = 3900;
  58215. + break;
  58216. + case 0x2: /* refresh period is 7.8 usec */
  58217. + refreshPeriod = 7800;
  58218. + break;
  58219. + case 0x3: /* refresh period is 31.3 usec */
  58220. + refreshPeriod = 31300;
  58221. + break;
  58222. + case 0x4: /* refresh period is 62.5 usec */
  58223. + refreshPeriod = 62500;
  58224. + break;
  58225. + case 0x5: /* refresh period is 125 usec */
  58226. + refreshPeriod = 125000;
  58227. + break;
  58228. + default: /* refresh period undefined */
  58229. + mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
  58230. + return -1;
  58231. + }
  58232. +
  58233. + /* Now the refreshPeriod is in register format value */
  58234. + refreshPeriod = (busClk * refreshPeriod) / 1000;
  58235. +
  58236. + DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n",
  58237. + refreshPeriod));
  58238. +
  58239. + /* make sure the refresh value is only 14 bits */
  58240. + if(refreshPeriod > SDRAM_REFRESH_MAX)
  58241. + {
  58242. + refreshPeriod = SDRAM_REFRESH_MAX;
  58243. + DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n",
  58244. + refreshPeriod));
  58245. + }
  58246. +
  58247. + /* Clear the refresh field */
  58248. + sdramConfig &= ~SDRAM_REFRESH_MASK;
  58249. +
  58250. + /* Set new value to refresh field */
  58251. + sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
  58252. +
  58253. + /* registered DRAM ? */
  58254. + if ( pBankInfo->registeredAddrAndControlInputs )
  58255. + {
  58256. + /* it's registered DRAM, so set the reg. DRAM bit */
  58257. + sdramConfig |= SDRAM_REGISTERED;
  58258. + DB(mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");)
  58259. + }
  58260. +
  58261. + /* ECC and IERR support */
  58262. + sdramConfig &= ~SDRAM_ECC_MASK; /* Clear ECC field */
  58263. + sdramConfig &= ~SDRAM_IERR_MASK; /* Clear IErr field */
  58264. +
  58265. + if ( pBankInfo->errorCheckType )
  58266. + {
  58267. + sdramConfig |= SDRAM_ECC_EN;
  58268. + sdramConfig |= SDRAM_IERR_REPORTE;
  58269. + DB(mvOsPrintf("Dram: mvDramIfDetect Enabling ECC\n"));
  58270. + }
  58271. + else
  58272. + {
  58273. + sdramConfig |= SDRAM_ECC_DIS;
  58274. + sdramConfig |= SDRAM_IERR_IGNORE;
  58275. + DB(mvOsPrintf("Dram: mvDramIfDetect Disabling ECC!\n"));
  58276. + }
  58277. + /* Set static default settings */
  58278. + sdramConfig |= SDRAM_CONFIG_DV;
  58279. +
  58280. + DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
  58281. + sdramConfig));
  58282. +
  58283. + return sdramConfig;
  58284. +}
  58285. +
  58286. +/*******************************************************************************
  58287. +* sdramModeRegCalc - Calculate sdram mode register
  58288. +*
  58289. +* DESCRIPTION: Calculate sdram mode register optimized value based
  58290. +* on the bank info parameters and the minCas.
  58291. +*
  58292. +* INPUT:
  58293. +* minCas - minimum CAS supported.
  58294. +*
  58295. +* OUTPUT:
  58296. +* None
  58297. +*
  58298. +* RETURN:
  58299. +* sdram mode reg value.
  58300. +*
  58301. +*******************************************************************************/
  58302. +static MV_U32 sdramModeRegCalc(MV_U32 minCas)
  58303. +{
  58304. + MV_U32 sdramMode;
  58305. +
  58306. + sdramMode = MV_REG_READ(SDRAM_MODE_REG);
  58307. +
  58308. + /* Clear CAS Latency field */
  58309. + sdramMode &= ~SDRAM_CL_MASK;
  58310. +
  58311. + DB(mvOsPrintf("DRAM CAS Latency ");)
  58312. +
  58313. + switch (minCas)
  58314. + {
  58315. + case DDR2_CL_3:
  58316. + sdramMode |= SDRAM_DDR2_CL_3;
  58317. + DB(mvOsPrintf("3.\n");)
  58318. + break;
  58319. + case DDR2_CL_4:
  58320. + sdramMode |= SDRAM_DDR2_CL_4;
  58321. + DB(mvOsPrintf("4.\n");)
  58322. + break;
  58323. + case DDR2_CL_5:
  58324. + sdramMode |= SDRAM_DDR2_CL_5;
  58325. + DB(mvOsPrintf("5.\n");)
  58326. + break;
  58327. + case DDR2_CL_6:
  58328. + sdramMode |= SDRAM_DDR2_CL_6;
  58329. + DB(mvOsPrintf("6.\n");)
  58330. + break;
  58331. + default:
  58332. + mvOsOutput("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
  58333. + return -1;
  58334. + }
  58335. +
  58336. + DB(mvOsPrintf("\nsdramModeRegCalc register 0x%x\n", sdramMode ));
  58337. +
  58338. + return sdramMode;
  58339. +}
  58340. +/*******************************************************************************
  58341. +* sdramExtModeRegCalc - Calculate sdram Extended mode register
  58342. +*
  58343. +* DESCRIPTION:
  58344. +* Return sdram Extended mode register value based
  58345. +* on the bank info parameters and bank presence.
  58346. +*
  58347. +* INPUT:
  58348. +* pBankInfo - sdram bank parameters
  58349. +* busClk - DRAM frequency
  58350. +*
  58351. +* OUTPUT:
  58352. +* None
  58353. +*
  58354. +* RETURN:
  58355. +* sdram Extended mode reg value.
  58356. +*
  58357. +*******************************************************************************/
  58358. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  58359. +{
  58360. + MV_U32 populateBanks = 0;
  58361. + int bankNum;
  58362. +
  58363. + /* Represent the populate banks in binary form */
  58364. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  58365. + {
  58366. + if (0 != pBankInfo[bankNum].size)
  58367. + {
  58368. + populateBanks |= (1 << bankNum);
  58369. + }
  58370. + }
  58371. +
  58372. + switch(populateBanks)
  58373. + {
  58374. + case(BANK_PRESENT_CS0):
  58375. + case(BANK_PRESENT_CS0_CS1):
  58376. + return DDR_SDRAM_EXT_MODE_CS0_CS1_DV;
  58377. +
  58378. + case(BANK_PRESENT_CS0_CS2):
  58379. + case(BANK_PRESENT_CS0_CS1_CS2):
  58380. + case(BANK_PRESENT_CS0_CS2_CS3):
  58381. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  58382. + if (busClk >= MV_BOARD_SYSCLK_267MHZ)
  58383. + return DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV;
  58384. + else
  58385. + return DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV;
  58386. +
  58387. + default:
  58388. + mvOsOutput("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
  58389. + return -1;
  58390. + }
  58391. + return 0;
  58392. +}
  58393. +
  58394. +/*******************************************************************************
  58395. +* dunitCtrlLowRegCalc - Calculate sdram dunit control low register
  58396. +*
  58397. +* DESCRIPTION: Calculate sdram dunit control low register optimized value based
  58398. +* on the bank info parameters and the minCas.
  58399. +*
  58400. +* INPUT:
  58401. +* pBankInfo - sdram bank parameters
  58402. +* minCas - minimum CAS supported.
  58403. +*
  58404. +* OUTPUT:
  58405. +* None
  58406. +*
  58407. +* RETURN:
  58408. +* sdram dunit control low reg value.
  58409. +*
  58410. +*******************************************************************************/
  58411. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk, MV_STATUS TTMode)
  58412. +{
  58413. + MV_U32 dunitCtrlLow, cl;
  58414. + MV_U32 sbOutR[4]={3,5,7,9} ;
  58415. + MV_U32 sbOutU[4]={1,3,5,7} ;
  58416. +
  58417. + dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
  58418. +
  58419. + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
  58420. +
  58421. + /* Clear StBurstOutDel field */
  58422. + dunitCtrlLow &= ~SDRAM_SB_OUT_MASK;
  58423. +
  58424. + /* Clear StBurstInDel field */
  58425. + dunitCtrlLow &= ~SDRAM_SB_IN_MASK;
  58426. +
  58427. + /* Clear CtrlPos field */
  58428. + dunitCtrlLow &= ~SDRAM_CTRL_POS_MASK;
  58429. +
  58430. + /* Clear 2T field */
  58431. + dunitCtrlLow &= ~SDRAM_2T_MASK;
  58432. + if (TTMode == MV_TRUE)
  58433. + {
  58434. + dunitCtrlLow |= SDRAM_2T_MODE;
  58435. + }
  58436. +
  58437. + /* For proper sample of read data set the Dunit Control register's */
  58438. + /* stBurstInDel bits [27:24] */
  58439. + /* 200MHz - 267MHz None reg = CL + 1 */
  58440. + /* 200MHz - 267MHz reg = CL + 2 */
  58441. + /* > 267MHz None reg = CL + 2 */
  58442. + /* > 267MHz reg = CL + 3 */
  58443. +
  58444. + /* For proper sample of read data set the Dunit Control register's */
  58445. + /* stBurstOutDel bits [23:20] */
  58446. + /********-********-********-********-
  58447. + * CL=3 | CL=4 | CL=5 | CL=6 |
  58448. + *********-********-********-********-
  58449. + Not Reg. * 0001 | 0011 | 0101 | 0111 |
  58450. + *********-********-********-********-
  58451. + Registered * 0011 | 0101 | 0111 | 1001 |
  58452. + *********-********-********-********/
  58453. +
  58454. + /* Set Dunit Control low default value */
  58455. + dunitCtrlLow |= SDRAM_DUNIT_CTRL_LOW_DDR2_DV;
  58456. +
  58457. + switch (minCas)
  58458. + {
  58459. + case DDR2_CL_3: cl = 3; break;
  58460. + case DDR2_CL_4: cl = 4; break;
  58461. + case DDR2_CL_5: cl = 5; break;
  58462. + case DDR2_CL_6: cl = 6; break;
  58463. + default:
  58464. + mvOsOutput("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n", minCas);
  58465. + return -1;
  58466. + }
  58467. +
  58468. + /* registerd DDR SDRAM? */
  58469. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  58470. + {
  58471. + dunitCtrlLow |= (sbOutR[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
  58472. + }
  58473. + else
  58474. + {
  58475. + dunitCtrlLow |= (sbOutU[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
  58476. + }
  58477. +
  58478. + DB(mvOsPrintf("\n\ndunitCtrlLowRegCalc: CL = %d, frequencies=%d\n", cl, busClk));
  58479. +
  58480. + if (busClk <= MV_BOARD_SYSCLK_267MHZ)
  58481. + {
  58482. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  58483. + cl = cl + 2;
  58484. + else
  58485. + cl = cl + 1;
  58486. + }
  58487. + else
  58488. + {
  58489. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  58490. + cl = cl + 3;
  58491. + else
  58492. + cl = cl + 2;
  58493. + }
  58494. +
  58495. + DB(mvOsPrintf("dunitCtrlLowRegCalc: SDRAM_SB_IN_DEL_OFFS = %d \n", cl));
  58496. + dunitCtrlLow |= cl << SDRAM_SB_IN_DEL_OFFS;
  58497. +
  58498. + DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
  58499. +
  58500. + return dunitCtrlLow;
  58501. +}
  58502. +
  58503. +/*******************************************************************************
  58504. +* dunitCtrlHighRegCalc - Calculate sdram dunit control high register
  58505. +*
  58506. +* DESCRIPTION: Calculate sdram dunit control high register optimized value based
  58507. +* on the bus clock.
  58508. +*
  58509. +* INPUT:
  58510. +* busClk - DRAM frequency.
  58511. +*
  58512. +* OUTPUT:
  58513. +* None
  58514. +*
  58515. +* RETURN:
  58516. +* sdram dunit control high reg value.
  58517. +*
  58518. +*******************************************************************************/
  58519. +static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  58520. +{
  58521. + MV_U32 dunitCtrlHigh;
  58522. + dunitCtrlHigh = MV_REG_READ(SDRAM_DUNIT_CTRL_HI_REG);
  58523. + if(busClk > MV_BOARD_SYSCLK_300MHZ)
  58524. + dunitCtrlHigh |= SDRAM__P2D_EN;
  58525. + else
  58526. + dunitCtrlHigh &= ~SDRAM__P2D_EN;
  58527. +
  58528. + if(busClk > MV_BOARD_SYSCLK_267MHZ)
  58529. + dunitCtrlHigh |= (SDRAM__WR_MESH_DELAY_EN | SDRAM__PUP_ZERO_SKEW_EN | SDRAM__ADD_HALF_FCC_EN);
  58530. +
  58531. + /* If ECC support we turn on D2P sample */
  58532. + dunitCtrlHigh &= ~SDRAM__D2P_EN; /* Clear D2P bit */
  58533. + if (( pBankInfo->errorCheckType ) && (busClk > MV_BOARD_SYSCLK_267MHZ))
  58534. + dunitCtrlHigh |= SDRAM__D2P_EN;
  58535. +
  58536. + return dunitCtrlHigh;
  58537. +}
  58538. +
  58539. +/*******************************************************************************
  58540. +* sdramAddrCtrlRegCalc - Calculate sdram address control register
  58541. +*
  58542. +* DESCRIPTION: Calculate sdram address control register optimized value based
  58543. +* on the bank info parameters and the minCas.
  58544. +*
  58545. +* INPUT:
  58546. +* pBankInfo - sdram bank parameters
  58547. +*
  58548. +* OUTPUT:
  58549. +* None
  58550. +*
  58551. +* RETURN:
  58552. +* sdram address control reg value.
  58553. +*
  58554. +*******************************************************************************/
  58555. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1)
  58556. +{
  58557. + MV_U32 addrCtrl = 0;
  58558. +
  58559. + if (pBankInfoDIMM1->size)
  58560. + {
  58561. + switch (pBankInfoDIMM1->sdramWidth)
  58562. + {
  58563. + case 4: /* memory is x4 */
  58564. + mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
  58565. + return -1;
  58566. + break;
  58567. + case 8: /* memory is x8 */
  58568. + addrCtrl |= SDRAM_ADDRSEL_X8(2) | SDRAM_ADDRSEL_X8(3);
  58569. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x8\n"));
  58570. + break;
  58571. + case 16:
  58572. + addrCtrl |= SDRAM_ADDRSEL_X16(2) | SDRAM_ADDRSEL_X16(3);
  58573. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x16\n"));
  58574. + break;
  58575. + default: /* memory width unsupported */
  58576. + mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
  58577. + return -1;
  58578. + }
  58579. + }
  58580. +
  58581. + switch (pBankInfo->sdramWidth)
  58582. + {
  58583. + case 4: /* memory is x4 */
  58584. + mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
  58585. + return -1;
  58586. + break;
  58587. + case 8: /* memory is x8 */
  58588. + addrCtrl |= SDRAM_ADDRSEL_X8(0) | SDRAM_ADDRSEL_X8(1);
  58589. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x8\n"));
  58590. + break;
  58591. + case 16:
  58592. + addrCtrl |= SDRAM_ADDRSEL_X16(0) | SDRAM_ADDRSEL_X16(1);
  58593. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x16\n"));
  58594. + break;
  58595. + default: /* memory width unsupported */
  58596. + mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
  58597. + return -1;
  58598. + }
  58599. +
  58600. + /* Note that density is in MB units */
  58601. + switch (pBankInfo->deviceDensity)
  58602. + {
  58603. + case 256: /* 256 Mbit */
  58604. + DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
  58605. + addrCtrl |= SDRAM_DSIZE_256Mb(0) | SDRAM_DSIZE_256Mb(1);
  58606. + break;
  58607. + case 512: /* 512 Mbit */
  58608. + DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
  58609. + addrCtrl |= SDRAM_DSIZE_512Mb(0) | SDRAM_DSIZE_512Mb(1);
  58610. + break;
  58611. + case 1024: /* 1 Gbit */
  58612. + DB(mvOsPrintf("DRAM Device Density 1Gbit\n"));
  58613. + addrCtrl |= SDRAM_DSIZE_1Gb(0) | SDRAM_DSIZE_1Gb(1);
  58614. + break;
  58615. + case 2048: /* 2 Gbit */
  58616. + DB(mvOsPrintf("DRAM Device Density 2Gbit\n"));
  58617. + addrCtrl |= SDRAM_DSIZE_2Gb(0) | SDRAM_DSIZE_2Gb(1);
  58618. + break;
  58619. + default:
  58620. + mvOsOutput("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
  58621. + pBankInfo->deviceDensity);
  58622. + return -1;
  58623. + }
  58624. +
  58625. + if (pBankInfoDIMM1->size)
  58626. + {
  58627. + switch (pBankInfoDIMM1->deviceDensity)
  58628. + {
  58629. + case 256: /* 256 Mbit */
  58630. + DB(mvOsPrintf("DIMM2: DRAM Device Density 256Mbit\n"));
  58631. + addrCtrl |= SDRAM_DSIZE_256Mb(2) | SDRAM_DSIZE_256Mb(3);
  58632. + break;
  58633. + case 512: /* 512 Mbit */
  58634. + DB(mvOsPrintf("DIMM2: DRAM Device Density 512Mbit\n"));
  58635. + addrCtrl |= SDRAM_DSIZE_512Mb(2) | SDRAM_DSIZE_512Mb(3);
  58636. + break;
  58637. + case 1024: /* 1 Gbit */
  58638. + DB(mvOsPrintf("DIMM2: DRAM Device Density 1Gbit\n"));
  58639. + addrCtrl |= SDRAM_DSIZE_1Gb(2) | SDRAM_DSIZE_1Gb(3);
  58640. + break;
  58641. + case 2048: /* 2 Gbit */
  58642. + DB(mvOsPrintf("DIMM2: DRAM Device Density 2Gbit\n"));
  58643. + addrCtrl |= SDRAM_DSIZE_2Gb(2) | SDRAM_DSIZE_2Gb(3);
  58644. + break;
  58645. + default:
  58646. + mvOsOutput("DIMM2: Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
  58647. + pBankInfoDIMM1->deviceDensity);
  58648. + return -1;
  58649. + }
  58650. + }
  58651. + /* SDRAM address control */
  58652. + DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
  58653. +
  58654. + return addrCtrl;
  58655. +}
  58656. +
  58657. +/*******************************************************************************
  58658. +* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
  58659. +*
  58660. +* DESCRIPTION:
  58661. +* This function calculates sdram timing control low register
  58662. +* optimized value based on the bank info parameters and the minCas.
  58663. +*
  58664. +* INPUT:
  58665. +* pBankInfo - sdram bank parameters
  58666. +* minCas - minimum CAS supported.
  58667. +* busClk - Bus clock
  58668. +*
  58669. +* OUTPUT:
  58670. +* None
  58671. +*
  58672. +* RETURN:
  58673. +* sdram timing control low reg value.
  58674. +*
  58675. +*******************************************************************************/
  58676. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk)
  58677. +{
  58678. + MV_U32 tRp = 0;
  58679. + MV_U32 tRrd = 0;
  58680. + MV_U32 tRcd = 0;
  58681. + MV_U32 tRas = 0;
  58682. + MV_U32 tWr = 0;
  58683. + MV_U32 tWtr = 0;
  58684. + MV_U32 tRtp = 0;
  58685. + MV_U32 timeCtrlLow = 0;
  58686. +
  58687. + MV_U32 bankNum;
  58688. +
  58689. + busClk = busClk / 1000000; /* In MHz */
  58690. +
  58691. + /* Scan all DRAM banks to find maximum timing values */
  58692. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  58693. + {
  58694. + tRp = MV_MAX(tRp, pBankInfo[bankNum].minRowPrechargeTime);
  58695. + tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
  58696. + tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
  58697. + tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
  58698. + }
  58699. +
  58700. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns part. */
  58701. + /* by shifting the data two bits right. */
  58702. + tRp = tRp >> 2; /* For example 0x50 -> 20ns */
  58703. + tRrd = tRrd >> 2;
  58704. + tRcd = tRcd >> 2;
  58705. +
  58706. + /* Extract clock cycles from time parameter. We need to round up */
  58707. + tRp = ((busClk * tRp) / 1000) + (((busClk * tRp) % 1000) ? 1 : 0);
  58708. + DB(mvOsPrintf("Dram Timing Low: tRp = %d ", tRp));
  58709. + tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
  58710. + /* JEDEC min reqeirments tRrd = 2 */
  58711. + if (tRrd < 2)
  58712. + tRrd = 2;
  58713. + DB(mvOsPrintf("tRrd = %d ", tRrd));
  58714. + tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
  58715. + DB(mvOsPrintf("tRcd = %d ", tRcd));
  58716. + tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
  58717. + DB(mvOsPrintf("tRas = %d ", tRas));
  58718. +
  58719. + /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2 */
  58720. + /* Scan all DRAM banks to find maximum timing values */
  58721. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  58722. + {
  58723. + tWr = MV_MAX(tWr, pBankInfo[bankNum].minWriteRecoveryTime);
  58724. + tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
  58725. + tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
  58726. + }
  58727. +
  58728. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns */
  58729. + /* part by shifting the data two bits right. */
  58730. + tWr = tWr >> 2; /* For example 0x50 -> 20ns */
  58731. + tWtr = tWtr >> 2;
  58732. + tRtp = tRtp >> 2;
  58733. + /* Extract clock cycles from time parameter. We need to round up */
  58734. + tWr = ((busClk * tWr) / 1000) + (((busClk * tWr) % 1000) ? 1 : 0);
  58735. + DB(mvOsPrintf("tWr = %d ", tWr));
  58736. + tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
  58737. + /* JEDEC min reqeirments tWtr = 2 */
  58738. + if (tWtr < 2)
  58739. + tWtr = 2;
  58740. + DB(mvOsPrintf("tWtr = %d ", tWtr));
  58741. + tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
  58742. + /* JEDEC min reqeirments tRtp = 2 */
  58743. + if (tRtp < 2)
  58744. + tRtp = 2;
  58745. + DB(mvOsPrintf("tRtp = %d ", tRtp));
  58746. +
  58747. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  58748. + timeCtrlLow = (((tRp - 1) << SDRAM_TRP_OFFS) |
  58749. + ((tRrd - 1) << SDRAM_TRRD_OFFS) |
  58750. + ((tRcd - 1) << SDRAM_TRCD_OFFS) |
  58751. + (((tRas - 1) << SDRAM_TRAS_OFFS) & SDRAM_TRAS_MASK)|
  58752. + ((tWr - 1) << SDRAM_TWR_OFFS) |
  58753. + ((tWtr - 1) << SDRAM_TWTR_OFFS) |
  58754. + ((tRtp - 1) << SDRAM_TRTP_OFFS));
  58755. +
  58756. + /* Check extended tRas bit */
  58757. + if ((tRas - 1) & BIT4)
  58758. + timeCtrlLow |= (1 << SDRAM_EXT_TRAS_OFFS);
  58759. +
  58760. + return timeCtrlLow;
  58761. +}
  58762. +
  58763. +/*******************************************************************************
  58764. +* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
  58765. +*
  58766. +* DESCRIPTION:
  58767. +* This function calculates sdram timing control high register
  58768. +* optimized value based on the bank info parameters and the bus clock.
  58769. +*
  58770. +* INPUT:
  58771. +* pBankInfo - sdram bank parameters
  58772. +* busClk - Bus clock
  58773. +*
  58774. +* OUTPUT:
  58775. +* None
  58776. +*
  58777. +* RETURN:
  58778. +* sdram timing control high reg value.
  58779. +*
  58780. +*******************************************************************************/
  58781. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  58782. +{
  58783. + MV_U32 tRfc;
  58784. + MV_U32 timingHigh;
  58785. + MV_U32 timeNs = 0;
  58786. + MV_U32 bankNum;
  58787. +
  58788. + busClk = busClk / 1000000; /* In MHz */
  58789. +
  58790. + /* Set DDR timing high register static configuration bits */
  58791. + timingHigh = MV_REG_READ(SDRAM_TIMING_CTRL_HIGH_REG);
  58792. +
  58793. + /* Set DDR timing high register default value */
  58794. + timingHigh |= SDRAM_TIMING_CTRL_HIGH_REG_DV;
  58795. +
  58796. + /* Clear tRfc field */
  58797. + timingHigh &= ~SDRAM_TRFC_MASK;
  58798. +
  58799. + /* Scan all DRAM banks to find maximum timing values */
  58800. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  58801. + {
  58802. + timeNs = MV_MAX(timeNs, pBankInfo[bankNum].minRefreshToActiveCmd);
  58803. + DB(mvOsPrintf("Dram: Timing High: minRefreshToActiveCmd = %d\n",
  58804. + pBankInfo[bankNum].minRefreshToActiveCmd));
  58805. + }
  58806. + if(busClk >= 333 && mvCtrlModelGet() == MV_78XX0_A1_REV)
  58807. + {
  58808. + timingHigh |= 0x1 << SDRAM_TR2W_W2R_OFFS;
  58809. + }
  58810. +
  58811. + tRfc = ((busClk * timeNs) / 1000) + (((busClk * timeNs) % 1000) ? 1 : 0);
  58812. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  58813. + DB(mvOsPrintf("Dram: Timing High: tRfc = %d\n", tRfc));
  58814. + timingHigh |= (((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS);
  58815. + DB(mvOsPrintf("Dram: Timing High: tRfc = %d\n", tRfc));
  58816. +
  58817. + /* SDRAM timing high */
  58818. + DB(mvOsPrintf("Dram: setting timing high with: %x \n", timingHigh));
  58819. +
  58820. + return timingHigh;
  58821. +}
  58822. +/*******************************************************************************
  58823. +* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
  58824. +*
  58825. +* DESCRIPTION:
  58826. +* This function config DDR2 On Die Termination (ODT) registers.
  58827. +*
  58828. +* INPUT:
  58829. +* pBankInfo - bank info parameters.
  58830. +*
  58831. +* OUTPUT:
  58832. +* None
  58833. +*
  58834. +* RETURN:
  58835. +* None
  58836. +*******************************************************************************/
  58837. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
  58838. +{
  58839. + MV_U32 populateBanks = 0;
  58840. + MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
  58841. + int bankNum;
  58842. +
  58843. + /* Represent the populate banks in binary form */
  58844. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  58845. + {
  58846. + if (0 != pBankInfo[bankNum].size)
  58847. + {
  58848. + populateBanks |= (1 << bankNum);
  58849. + }
  58850. + }
  58851. +
  58852. + switch(populateBanks)
  58853. + {
  58854. + case(BANK_PRESENT_CS0):
  58855. + case(BANK_PRESENT_CS0_CS1):
  58856. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS1_DV;
  58857. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS1_DV;
  58858. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV;
  58859. + break;
  58860. + case(BANK_PRESENT_CS0_CS2):
  58861. + case(BANK_PRESENT_CS0_CS1_CS2):
  58862. + case(BANK_PRESENT_CS0_CS2_CS3):
  58863. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  58864. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV;
  58865. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV;
  58866. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV;
  58867. + break;
  58868. + default:
  58869. + DB(mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n"));
  58870. + return;
  58871. + }
  58872. + /* DDR2 SDRAM ODT ctrl low */
  58873. + DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl low with: %x \n", odtCtrlLow));
  58874. + MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
  58875. +
  58876. + /* DDR2 SDRAM ODT ctrl high */
  58877. + DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl high with: %x \n", odtCtrlHigh));
  58878. + MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
  58879. +
  58880. + /* DDR2 DUNIT ODT ctrl */
  58881. + if ( ((mvCtrlModelGet() == MV_78XX0_DEV_ID) && (mvCtrlRevGet() == MV_78XX0_Y0_REV)) ||
  58882. + (mvCtrlModelGet() == MV_76100_DEV_ID) ||
  58883. + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
  58884. + (mvCtrlModelGet() == MV_78200_DEV_ID) )
  58885. + dunitOdtCtrl &= ~(BIT9|BIT8); /* Clear ODT always on */
  58886. +
  58887. + DB(mvOsPrintf("DUNIT: DDR2 setting ODT ctrl with: %x \n", dunitOdtCtrl));
  58888. + MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
  58889. + return;
  58890. +}
  58891. +/*******************************************************************************
  58892. +* sdramDdr2TimeLoRegCalc - Set DDR2 DRAM Timing Low registers.
  58893. +*
  58894. +* DESCRIPTION:
  58895. +* This function config DDR2 DRAM Timing low registers.
  58896. +*
  58897. +* INPUT:
  58898. +* minCas - minimum CAS supported.
  58899. +*
  58900. +* OUTPUT:
  58901. +* None
  58902. +*
  58903. +* RETURN:
  58904. +* DDR2 sdram timing low reg value.
  58905. +*******************************************************************************/
  58906. +static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas)
  58907. +{
  58908. + MV_U8 cl = -1;
  58909. + MV_U32 ddr2TimeLoReg;
  58910. +
  58911. + /* read and clear the feilds we are going to set */
  58912. + ddr2TimeLoReg = MV_REG_READ(SDRAM_DDR2_TIMING_LO_REG);
  58913. + ddr2TimeLoReg &= ~(SD2TLR_TODT_ON_RD_MASK |
  58914. + SD2TLR_TODT_OFF_RD_MASK |
  58915. + SD2TLR_TODT_ON_CTRL_RD_MASK |
  58916. + SD2TLR_TODT_OFF_CTRL_RD_MASK);
  58917. +
  58918. + if( minCas == DDR2_CL_3 )
  58919. + {
  58920. + cl = 3;
  58921. + }
  58922. + else if( minCas == DDR2_CL_4 )
  58923. + {
  58924. + cl = 4;
  58925. + }
  58926. + else if( minCas == DDR2_CL_5 )
  58927. + {
  58928. + cl = 5;
  58929. + }
  58930. + else if( minCas == DDR2_CL_6 )
  58931. + {
  58932. + cl = 6;
  58933. + }
  58934. + else
  58935. + {
  58936. + DB(mvOsPrintf("sdramDdr2TimeLoRegCalc: CAS latency %d unsupported. using CAS latency 4\n",
  58937. + minCas));
  58938. + cl = 4;
  58939. + }
  58940. +
  58941. + ddr2TimeLoReg |= ((cl-3) << SD2TLR_TODT_ON_RD_OFFS);
  58942. + ddr2TimeLoReg |= ( cl << SD2TLR_TODT_OFF_RD_OFFS);
  58943. + ddr2TimeLoReg |= ( cl << SD2TLR_TODT_ON_CTRL_RD_OFFS);
  58944. + ddr2TimeLoReg |= ((cl+3) << SD2TLR_TODT_OFF_CTRL_RD_OFFS);
  58945. +
  58946. + /* DDR2 SDRAM timing low */
  58947. + DB(mvOsPrintf("Dram: DDR2 setting timing low with: %x \n", ddr2TimeLoReg));
  58948. +
  58949. + return ddr2TimeLoReg;
  58950. +}
  58951. +
  58952. +/*******************************************************************************
  58953. +* sdramDdr2TimeHiRegCalc - Set DDR2 DRAM Timing High registers.
  58954. +*
  58955. +* DESCRIPTION:
  58956. +* This function config DDR2 DRAM Timing high registers.
  58957. +*
  58958. +* INPUT:
  58959. +* minCas - minimum CAS supported.
  58960. +*
  58961. +* OUTPUT:
  58962. +* None
  58963. +*
  58964. +* RETURN:
  58965. +* DDR2 sdram timing high reg value.
  58966. +*******************************************************************************/
  58967. +static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas)
  58968. +{
  58969. + MV_U8 cl = -1;
  58970. + MV_U32 ddr2TimeHiReg;
  58971. +
  58972. + /* read and clear the feilds we are going to set */
  58973. + ddr2TimeHiReg = MV_REG_READ(SDRAM_DDR2_TIMING_HI_REG);
  58974. + ddr2TimeHiReg &= ~(SD2THR_TODT_ON_WR_MASK |
  58975. + SD2THR_TODT_OFF_WR_MASK |
  58976. + SD2THR_TODT_ON_CTRL_WR_MASK |
  58977. + SD2THR_TODT_OFF_CTRL_WR_MASK);
  58978. +
  58979. + if( minCas == DDR2_CL_3 )
  58980. + {
  58981. + cl = 3;
  58982. + }
  58983. + else if( minCas == DDR2_CL_4 )
  58984. + {
  58985. + cl = 4;
  58986. + }
  58987. + else if( minCas == DDR2_CL_5 )
  58988. + {
  58989. + cl = 5;
  58990. + }
  58991. + else if( minCas == DDR2_CL_6 )
  58992. + {
  58993. + cl = 6;
  58994. + }
  58995. + else
  58996. + {
  58997. + mvOsOutput("sdramDdr2TimeHiRegCalc: CAS latency %d unsupported. using CAS latency 4\n",
  58998. + minCas);
  58999. + cl = 4;
  59000. + }
  59001. +
  59002. + ddr2TimeHiReg |= ((cl-3) << SD2THR_TODT_ON_WR_OFFS);
  59003. + ddr2TimeHiReg |= ( cl << SD2THR_TODT_OFF_WR_OFFS);
  59004. + ddr2TimeHiReg |= ( cl << SD2THR_TODT_ON_CTRL_WR_OFFS);
  59005. + ddr2TimeHiReg |= ((cl+3) << SD2THR_TODT_OFF_CTRL_WR_OFFS);
  59006. +
  59007. + /* DDR2 SDRAM timin high */
  59008. + DB(mvOsPrintf("Dram: DDR2 setting timing high with: %x \n", ddr2TimeHiReg));
  59009. +
  59010. + return ddr2TimeHiReg;
  59011. +}
  59012. +#endif
  59013. +
  59014. +/*******************************************************************************
  59015. +* mvDramIfCalGet - Get CAS Latency
  59016. +*
  59017. +* DESCRIPTION:
  59018. +* This function get the CAS Latency.
  59019. +*
  59020. +* INPUT:
  59021. +* None
  59022. +*
  59023. +* OUTPUT:
  59024. +* None
  59025. +*
  59026. +* RETURN:
  59027. +* CAS latency times 10 (to avoid using floating point).
  59028. +*
  59029. +*******************************************************************************/
  59030. +MV_U32 mvDramIfCalGet(void)
  59031. +{
  59032. + MV_U32 sdramCasLat, casLatMask;
  59033. +
  59034. + casLatMask = (MV_REG_READ(SDRAM_MODE_REG) & SDRAM_CL_MASK);
  59035. +
  59036. + switch (casLatMask)
  59037. + {
  59038. + case SDRAM_DDR2_CL_3:
  59039. + sdramCasLat = 30;
  59040. + break;
  59041. + case SDRAM_DDR2_CL_4:
  59042. + sdramCasLat = 40;
  59043. + break;
  59044. + case SDRAM_DDR2_CL_5:
  59045. + sdramCasLat = 50;
  59046. + break;
  59047. + case SDRAM_DDR2_CL_6:
  59048. + sdramCasLat = 60;
  59049. + break;
  59050. + default:
  59051. + mvOsOutput("mvDramIfCalGet: Err, unknown DDR2 CAL\n");
  59052. + return -1;
  59053. + }
  59054. +
  59055. + return sdramCasLat;
  59056. +}
  59057. +
  59058. +
  59059. +/*******************************************************************************
  59060. +* mvDramIfSelfRefreshSet - Put the dram in self refresh mode -
  59061. +*
  59062. +* DESCRIPTION:
  59063. +* add support in power management.
  59064. +*
  59065. +*
  59066. +* INPUT:
  59067. +* None
  59068. +*
  59069. +* OUTPUT:
  59070. +* None
  59071. +*
  59072. +* RETURN:
  59073. +* None
  59074. +*
  59075. +*******************************************************************************/
  59076. +
  59077. +MV_VOID mvDramIfSelfRefreshSet()
  59078. +{
  59079. + MV_U32 operReg;
  59080. +
  59081. + operReg = MV_REG_READ(SDRAM_OPERATION_REG);
  59082. + MV_REG_WRITE(SDRAM_OPERATION_REG ,operReg |SDRAM_CMD_SLF_RFRSH);
  59083. + /* Read until register is reset to 0 */
  59084. + while(MV_REG_READ(SDRAM_OPERATION_REG));
  59085. +}
  59086. +/*******************************************************************************
  59087. +* mvDramIfDimGetSPDversion - return DIMM SPD version.
  59088. +*
  59089. +* DESCRIPTION:
  59090. +* This function prints the DRAM controller information.
  59091. +*
  59092. +* INPUT:
  59093. +* None.
  59094. +*
  59095. +* OUTPUT:
  59096. +* None.
  59097. +*
  59098. +* RETURN:
  59099. +* None.
  59100. +*
  59101. +*******************************************************************************/
  59102. +static void mvDramIfDimGetSPDversion(MV_U32 *pMajor, MV_U32 *pMinor, MV_U32 bankNum)
  59103. +{
  59104. + MV_DIMM_INFO dimmInfo;
  59105. + if (bankNum >= MV_DRAM_MAX_CS )
  59106. + {
  59107. + DB(mvOsPrintf("Dram: mvDramIfDimGetSPDversion bad params \n"));
  59108. + return ;
  59109. + }
  59110. + memset(&dimmInfo,0,sizeof(dimmInfo));
  59111. + if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
  59112. + {
  59113. + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
  59114. + return ;
  59115. + }
  59116. + *pMajor = dimmInfo.spdRawData[DIMM_SPD_VERSION]/10;
  59117. + *pMinor = dimmInfo.spdRawData[DIMM_SPD_VERSION]%10;
  59118. +}
  59119. +/*******************************************************************************
  59120. +* mvDramIfShow - Show DRAM controller information.
  59121. +*
  59122. +* DESCRIPTION:
  59123. +* This function prints the DRAM controller information.
  59124. +*
  59125. +* INPUT:
  59126. +* None.
  59127. +*
  59128. +* OUTPUT:
  59129. +* None.
  59130. +*
  59131. +* RETURN:
  59132. +* None.
  59133. +*
  59134. +*******************************************************************************/
  59135. +void mvDramIfShow(void)
  59136. +{
  59137. + int i, sdramCasLat, sdramCsSize;
  59138. + MV_U32 Major=0, Minor=0;
  59139. +
  59140. + mvOsOutput("DRAM Controller info:\n");
  59141. +
  59142. + mvOsOutput("Total DRAM ");
  59143. + mvSizePrint(mvDramIfSizeGet());
  59144. + mvOsOutput("\n");
  59145. +
  59146. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  59147. + {
  59148. + sdramCsSize = mvDramIfBankSizeGet(i);
  59149. + if (sdramCsSize)
  59150. + {
  59151. + if (0 == (i & 1))
  59152. + {
  59153. + mvDramIfDimGetSPDversion(&Major, &Minor,i);
  59154. + mvOsOutput("DIMM %d version %d.%d\n", i/2, Major, Minor);
  59155. + }
  59156. + mvOsOutput("\tDRAM CS[%d] ", i);
  59157. + mvSizePrint(sdramCsSize);
  59158. + mvOsOutput("\n");
  59159. + }
  59160. + }
  59161. + sdramCasLat = mvDramIfCalGet();
  59162. +
  59163. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_ECC_EN)
  59164. + {
  59165. + mvOsOutput("ECC enabled, ");
  59166. + }
  59167. + else
  59168. + {
  59169. + mvOsOutput("ECC Disabled, ");
  59170. + }
  59171. +
  59172. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_REGISTERED)
  59173. + {
  59174. + mvOsOutput("Registered DIMM\n");
  59175. + }
  59176. + else
  59177. + {
  59178. + mvOsOutput("Non registered DIMM\n");
  59179. + }
  59180. +
  59181. + mvOsOutput("Configured CAS Latency %d.%d\n", sdramCasLat/10, sdramCasLat%10);
  59182. +}
  59183. +/*******************************************************************************
  59184. +* mvDramIfGetFirstCS - find the DRAM bank on the lower address
  59185. +*
  59186. +*
  59187. +* DESCRIPTION:
  59188. +* This function return the fisrt CS on address 0
  59189. +*
  59190. +* INPUT:
  59191. +* None.
  59192. +*
  59193. +* OUTPUT:
  59194. +* None.
  59195. +*
  59196. +* RETURN:
  59197. +* SDRAM_CS0 or SDRAM_CS2
  59198. +*
  59199. +*******************************************************************************/
  59200. +MV_U32 mvDramIfGetFirstCS(void)
  59201. +{
  59202. + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
  59203. +
  59204. + if (DRAM_CS_Order[0] == N_A)
  59205. + {
  59206. + mvDramBankInfoGet(SDRAM_CS0, &bankInfo[SDRAM_CS0]);
  59207. +#ifdef MV_INCLUDE_SDRAM_CS2
  59208. + mvDramBankInfoGet(SDRAM_CS2, &bankInfo[SDRAM_CS2]);
  59209. +#endif
  59210. +
  59211. +#ifdef MV_INCLUDE_SDRAM_CS2
  59212. + if (bankInfo[SDRAM_CS0].size < bankInfo[SDRAM_CS2].size)
  59213. + {
  59214. + DRAM_CS_Order[0] = SDRAM_CS2;
  59215. + DRAM_CS_Order[1] = SDRAM_CS3;
  59216. + DRAM_CS_Order[2] = SDRAM_CS0;
  59217. + DRAM_CS_Order[3] = SDRAM_CS1;
  59218. +
  59219. + return SDRAM_CS2;
  59220. + }
  59221. +#endif
  59222. + DRAM_CS_Order[0] = SDRAM_CS0;
  59223. + DRAM_CS_Order[1] = SDRAM_CS1;
  59224. +#ifdef MV_INCLUDE_SDRAM_CS2
  59225. + DRAM_CS_Order[2] = SDRAM_CS2;
  59226. + DRAM_CS_Order[3] = SDRAM_CS3;
  59227. +#endif
  59228. + return SDRAM_CS0;
  59229. + }
  59230. + return DRAM_CS_Order[0];
  59231. +}
  59232. +/*******************************************************************************
  59233. +* mvDramIfGetCSorder -
  59234. +*
  59235. +*
  59236. +* DESCRIPTION:
  59237. +* This function return the fisrt CS on address 0
  59238. +*
  59239. +* INPUT:
  59240. +* CS number.
  59241. +*
  59242. +* OUTPUT:
  59243. +* CS order.
  59244. +*
  59245. +* RETURN:
  59246. +* SDRAM_CS0 or SDRAM_CS2
  59247. +*
  59248. +* NOTE: mvDramIfGetFirstCS must be caled before this subroutine
  59249. +*******************************************************************************/
  59250. +MV_U32 mvDramIfGetCSorder(MV_U32 csOrder )
  59251. +{
  59252. + return DRAM_CS_Order[csOrder];
  59253. +}
  59254. +
  59255. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h
  59256. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h 1970-01-01 01:00:00.000000000 +0100
  59257. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h 2011-07-31 11:31:59.793596608 +0200
  59258. @@ -0,0 +1,157 @@
  59259. +/*******************************************************************************
  59260. +Copyright (C) Marvell International Ltd. and its affiliates
  59261. +
  59262. +This software file (the "File") is owned and distributed by Marvell
  59263. +International Ltd. and/or its affiliates ("Marvell") under the following
  59264. +alternative licensing terms. Once you have made an election to distribute the
  59265. +File under one of the following license alternatives, please (i) delete this
  59266. +introductory statement regarding license alternatives, (ii) delete the two
  59267. +license alternatives that you have not elected to use and (iii) preserve the
  59268. +Marvell copyright notice above.
  59269. +
  59270. +********************************************************************************
  59271. +Marvell Commercial License Option
  59272. +
  59273. +If you received this File from Marvell and you have entered into a commercial
  59274. +license agreement (a "Commercial License") with Marvell, the File is licensed
  59275. +to you under the terms of the applicable Commercial License.
  59276. +
  59277. +********************************************************************************
  59278. +Marvell GPL License Option
  59279. +
  59280. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59281. +modify this File in accordance with the terms and conditions of the General
  59282. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  59283. +available along with the File in the license.txt file or by writing to the Free
  59284. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  59285. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  59286. +
  59287. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  59288. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  59289. +DISCLAIMED. The GPL License provides additional details about this warranty
  59290. +disclaimer.
  59291. +********************************************************************************
  59292. +Marvell BSD License Option
  59293. +
  59294. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59295. +modify this File under the following licensing terms.
  59296. +Redistribution and use in source and binary forms, with or without modification,
  59297. +are permitted provided that the following conditions are met:
  59298. +
  59299. + * Redistributions of source code must retain the above copyright notice,
  59300. + this list of conditions and the following disclaimer.
  59301. +
  59302. + * Redistributions in binary form must reproduce the above copyright
  59303. + notice, this list of conditions and the following disclaimer in the
  59304. + documentation and/or other materials provided with the distribution.
  59305. +
  59306. + * Neither the name of Marvell nor the names of its contributors may be
  59307. + used to endorse or promote products derived from this software without
  59308. + specific prior written permission.
  59309. +
  59310. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  59311. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  59312. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  59313. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  59314. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  59315. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  59316. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  59317. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  59318. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  59319. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59320. +
  59321. +*******************************************************************************/
  59322. +
  59323. +
  59324. +#ifndef __INCmvDramIfConfigh
  59325. +#define __INCmvDramIfConfigh
  59326. +
  59327. +#ifdef __cplusplus
  59328. +extern "C" {
  59329. +#endif /* __cplusplus */
  59330. +
  59331. +/* includes */
  59332. +
  59333. +/* defines */
  59334. +
  59335. +/* registers defaults values */
  59336. +
  59337. +#define SDRAM_CONFIG_DV (SDRAM_SRMODE_DRAM | BIT25 | BIT30)
  59338. +
  59339. +#define SDRAM_DUNIT_CTRL_LOW_DDR2_DV \
  59340. + (SDRAM_SRCLK_KEPT | \
  59341. + SDRAM_CLK1DRV_NORMAL | \
  59342. + (BIT28 | BIT29))
  59343. +
  59344. +#define SDRAM_ADDR_CTRL_DV 2
  59345. +
  59346. +#define SDRAM_TIMING_CTRL_LOW_REG_DV \
  59347. + ((0x2 << SDRAM_TRCD_OFFS) | \
  59348. + (0x2 << SDRAM_TRP_OFFS) | \
  59349. + (0x1 << SDRAM_TWR_OFFS) | \
  59350. + (0x0 << SDRAM_TWTR_OFFS) | \
  59351. + (0x5 << SDRAM_TRAS_OFFS) | \
  59352. + (0x1 << SDRAM_TRRD_OFFS))
  59353. +
  59354. +/* Note: value of 0 in register means one cycle, 1 means two and so on */
  59355. +#define SDRAM_TIMING_CTRL_HIGH_REG_DV \
  59356. + ((0x0 << SDRAM_TR2R_OFFS) | \
  59357. + (0x0 << SDRAM_TR2W_W2R_OFFS) | \
  59358. + (0x1 << SDRAM_TW2W_OFFS))
  59359. +
  59360. +#define SDRAM_OPEN_PAGES_CTRL_REG_DV SDRAM_OPEN_PAGE_EN
  59361. +
  59362. +/* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode */
  59363. +/* CS0 0x84210000 0x00000000 0x0000780F 0x00000440 */
  59364. +/* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440 */
  59365. +/* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  59366. +/* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  59367. +/* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  59368. +/* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  59369. +
  59370. +#define DDR2_ODT_CTRL_LOW_CS0_CS1_DV 0x84210000
  59371. +#define DDR2_ODT_CTRL_HIGH_CS0_CS1_DV 0x00000000
  59372. +#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV 0x0000E80F
  59373. +#ifdef MV78XX0
  59374. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV 0x00000040
  59375. +#else
  59376. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV 0x00000440
  59377. +#endif
  59378. +
  59379. +#define DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV 0x030C030C
  59380. +#define DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV 0x00000000
  59381. +#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV 0x0000F40F
  59382. +#ifdef MV78XX0
  59383. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV 0x00000004
  59384. +#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV 0x00000044
  59385. +#else
  59386. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV 0x00000404
  59387. +#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV 0x00000444
  59388. +#endif
  59389. +
  59390. +/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */
  59391. +#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
  59392. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  59393. +
  59394. +#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV \
  59395. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  59396. +
  59397. +/* DDR SDRAM Mode Register default value */
  59398. +#define DDR2_MODE_REG_DV (SDRAM_BURST_LEN_4 | SDRAM_WR_3_CYC)
  59399. +/* DDR SDRAM Timing parameter default values */
  59400. +#define SDRAM_TIMING_CTRL_LOW_REG_DEFAULT 0x33136552
  59401. +#define SDRAM_TRFC_DEFAULT_VALUE 0x34
  59402. +#define SDRAM_TRFC_DEFAULT SDRAM_TRFC_DEFAULT_VALUE
  59403. +#define SDRAM_TW2W_DEFALT (0x1 << SDRAM_TW2W_OFFS)
  59404. +
  59405. +#define SDRAM_TIMING_CTRL_HIGH_REG_DEFAULT (SDRAM_TRFC_DEFAULT | SDRAM_TW2W_DEFALT)
  59406. +
  59407. +#define SDRAM_FTDLL_REG_DEFAULT_LEFT 0x88C800
  59408. +#define SDRAM_FTDLL_REG_DEFAULT_RIGHT 0x88C800
  59409. +#define SDRAM_FTDLL_REG_DEFAULT_UP 0x88C800
  59410. +
  59411. +#ifdef __cplusplus
  59412. +}
  59413. +#endif /* __cplusplus */
  59414. +
  59415. +#endif /* __INCmvDramIfh */
  59416. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h
  59417. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h 1970-01-01 01:00:00.000000000 +0100
  59418. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h 2011-07-31 11:31:59.834833008 +0200
  59419. @@ -0,0 +1,172 @@
  59420. +/*******************************************************************************
  59421. +Copyright (C) Marvell International Ltd. and its affiliates
  59422. +
  59423. +This software file (the "File") is owned and distributed by Marvell
  59424. +International Ltd. and/or its affiliates ("Marvell") under the following
  59425. +alternative licensing terms. Once you have made an election to distribute the
  59426. +File under one of the following license alternatives, please (i) delete this
  59427. +introductory statement regarding license alternatives, (ii) delete the two
  59428. +license alternatives that you have not elected to use and (iii) preserve the
  59429. +Marvell copyright notice above.
  59430. +
  59431. +********************************************************************************
  59432. +Marvell Commercial License Option
  59433. +
  59434. +If you received this File from Marvell and you have entered into a commercial
  59435. +license agreement (a "Commercial License") with Marvell, the File is licensed
  59436. +to you under the terms of the applicable Commercial License.
  59437. +
  59438. +********************************************************************************
  59439. +Marvell GPL License Option
  59440. +
  59441. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59442. +modify this File in accordance with the terms and conditions of the General
  59443. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  59444. +available along with the File in the license.txt file or by writing to the Free
  59445. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  59446. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  59447. +
  59448. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  59449. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  59450. +DISCLAIMED. The GPL License provides additional details about this warranty
  59451. +disclaimer.
  59452. +********************************************************************************
  59453. +Marvell BSD License Option
  59454. +
  59455. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59456. +modify this File under the following licensing terms.
  59457. +Redistribution and use in source and binary forms, with or without modification,
  59458. +are permitted provided that the following conditions are met:
  59459. +
  59460. + * Redistributions of source code must retain the above copyright notice,
  59461. + this list of conditions and the following disclaimer.
  59462. +
  59463. + * Redistributions in binary form must reproduce the above copyright
  59464. + notice, this list of conditions and the following disclaimer in the
  59465. + documentation and/or other materials provided with the distribution.
  59466. +
  59467. + * Neither the name of Marvell nor the names of its contributors may be
  59468. + used to endorse or promote products derived from this software without
  59469. + specific prior written permission.
  59470. +
  59471. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  59472. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  59473. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  59474. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  59475. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  59476. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  59477. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  59478. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  59479. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  59480. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59481. +
  59482. +*******************************************************************************/
  59483. +
  59484. +
  59485. +#ifndef __INCmvDramIfh
  59486. +#define __INCmvDramIfh
  59487. +
  59488. +#ifdef __cplusplus
  59489. +extern "C" {
  59490. +#endif /* __cplusplus */
  59491. +
  59492. +/* includes */
  59493. +#include "ddr2/mvDramIfRegs.h"
  59494. +#include "ddr2/mvDramIfConfig.h"
  59495. +#include "ctrlEnv/mvCtrlEnvLib.h"
  59496. +
  59497. +/* defines */
  59498. +/* DRAM Timing parameters */
  59499. +#define SDRAM_TWR 15 /* ns tWr */
  59500. +#define SDRAM_TRFC_64_512M_AT_200MHZ 70 /* ns tRfc for dens 64-512 @ 200MHz */
  59501. +#define SDRAM_TRFC_64_512M 75 /* ns tRfc for dens 64-512 */
  59502. +#define SDRAM_TRFC_1G 120 /* ns tRfc for dens 1GB */
  59503. +#define SDRAM_TR2R_CYC 1 /* cycle for tR2r */
  59504. +
  59505. +#define CAL_AUTO_DETECT 0 /* Do not force CAS latancy (mvDramIfDetect) */
  59506. +#define ECC_DISABLE 1 /* Force ECC to Disable */
  59507. +#define ECC_ENABLE 0 /* Force ECC to ENABLE */
  59508. +/* typedefs */
  59509. +
  59510. +/* enumeration for memory types */
  59511. +typedef enum _mvMemoryType
  59512. +{
  59513. + MEM_TYPE_SDRAM,
  59514. + MEM_TYPE_DDR1,
  59515. + MEM_TYPE_DDR2
  59516. +}MV_MEMORY_TYPE;
  59517. +
  59518. +/* enumeration for DDR2 supported CAS Latencies */
  59519. +typedef enum _mvDimmDdr2Cas
  59520. +{
  59521. + DDR2_CL_3 = 0x08,
  59522. + DDR2_CL_4 = 0x10,
  59523. + DDR2_CL_5 = 0x20,
  59524. + DDR2_CL_6 = 0x40,
  59525. + DDR2_CL_FAULT
  59526. +} MV_DIMM_DDR2_CAS;
  59527. +
  59528. +
  59529. +typedef struct _mvDramBankInfo
  59530. +{
  59531. + MV_MEMORY_TYPE memoryType; /* DDR1, DDR2 or SDRAM */
  59532. +
  59533. + /* DIMM dimensions */
  59534. + MV_U32 numOfRowAddr;
  59535. + MV_U32 numOfColAddr;
  59536. + MV_U32 dataWidth;
  59537. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  59538. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  59539. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  59540. + MV_U32 burstLengthSupported;
  59541. + MV_U32 numOfBanksOnEachDevice;
  59542. + MV_U32 suportedCasLatencies;
  59543. + MV_U32 refreshInterval;
  59544. +
  59545. + /* DIMM timing parameters */
  59546. + MV_U32 minCycleTimeAtMaxCasLatPs;
  59547. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  59548. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  59549. + MV_U32 minRowPrechargeTime;
  59550. + MV_U32 minRowActiveToRowActive;
  59551. + MV_U32 minRasToCasDelay;
  59552. + MV_U32 minRasPulseWidth;
  59553. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  59554. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  59555. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  59556. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  59557. +
  59558. + /* Parameters calculated from the extracted DIMM information */
  59559. + MV_U32 size;
  59560. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit */
  59561. + MV_U32 numberOfDevices;
  59562. +
  59563. + /* DIMM attributes (MV_TRUE for yes) */
  59564. + MV_BOOL registeredAddrAndControlInputs;
  59565. + MV_BOOL registeredDQMBinputs;
  59566. +
  59567. +}MV_DRAM_BANK_INFO;
  59568. +
  59569. +#include "ddr2/spd/mvSpd.h"
  59570. +
  59571. +/* mvDramIf.h API list */
  59572. +MV_VOID mvDramIfBasicAsmInit(MV_VOID);
  59573. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable);
  59574. +MV_VOID _mvDramIfConfig(int entryNum);
  59575. +
  59576. +MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum);
  59577. +MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum);
  59578. +MV_U32 mvDramIfSizeGet(MV_VOID);
  59579. +MV_U32 mvDramIfCalGet(void);
  59580. +MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold);
  59581. +MV_VOID mvDramIfSelfRefreshSet(void);
  59582. +void mvDramIfShow(void);
  59583. +MV_U32 mvDramIfGetFirstCS(void);
  59584. +MV_U32 mvDramIfGetCSorder(MV_U32 csOrder );
  59585. +MV_U32 mvDramCsSizeGet(MV_U32 csNum);
  59586. +
  59587. +#ifdef __cplusplus
  59588. +}
  59589. +#endif /* __cplusplus */
  59590. +
  59591. +#endif /* __INCmvDramIfh */
  59592. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h
  59593. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  59594. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h 2011-07-31 11:31:59.893679319 +0200
  59595. @@ -0,0 +1,423 @@
  59596. +/*******************************************************************************
  59597. +Copyright (C) Marvell International Ltd. and its affiliates
  59598. +
  59599. +This software file (the "File") is owned and distributed by Marvell
  59600. +International Ltd. and/or its affiliates ("Marvell") under the following
  59601. +alternative licensing terms. Once you have made an election to distribute the
  59602. +File under one of the following license alternatives, please (i) delete this
  59603. +introductory statement regarding license alternatives, (ii) delete the two
  59604. +license alternatives that you have not elected to use and (iii) preserve the
  59605. +Marvell copyright notice above.
  59606. +
  59607. +********************************************************************************
  59608. +Marvell Commercial License Option
  59609. +
  59610. +If you received this File from Marvell and you have entered into a commercial
  59611. +license agreement (a "Commercial License") with Marvell, the File is licensed
  59612. +to you under the terms of the applicable Commercial License.
  59613. +
  59614. +********************************************************************************
  59615. +Marvell GPL License Option
  59616. +
  59617. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59618. +modify this File in accordance with the terms and conditions of the General
  59619. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  59620. +available along with the File in the license.txt file or by writing to the Free
  59621. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  59622. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  59623. +
  59624. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  59625. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  59626. +DISCLAIMED. The GPL License provides additional details about this warranty
  59627. +disclaimer.
  59628. +********************************************************************************
  59629. +Marvell BSD License Option
  59630. +
  59631. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59632. +modify this File under the following licensing terms.
  59633. +Redistribution and use in source and binary forms, with or without modification,
  59634. +are permitted provided that the following conditions are met:
  59635. +
  59636. + * Redistributions of source code must retain the above copyright notice,
  59637. + this list of conditions and the following disclaimer.
  59638. +
  59639. + * Redistributions in binary form must reproduce the above copyright
  59640. + notice, this list of conditions and the following disclaimer in the
  59641. + documentation and/or other materials provided with the distribution.
  59642. +
  59643. + * Neither the name of Marvell nor the names of its contributors may be
  59644. + used to endorse or promote products derived from this software without
  59645. + specific prior written permission.
  59646. +
  59647. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  59648. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  59649. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  59650. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  59651. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  59652. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  59653. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  59654. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  59655. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  59656. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59657. +
  59658. +*******************************************************************************/
  59659. +
  59660. +#ifndef __INCmvDramIfRegsh
  59661. +#define __INCmvDramIfRegsh
  59662. +
  59663. +#ifdef __cplusplus
  59664. +extern "C" {
  59665. +#endif /* __cplusplus */
  59666. +
  59667. +/* DDR SDRAM Controller Address Decode Registers */
  59668. + /* SDRAM CSn Base Address Register (SCBAR) */
  59669. +#define SDRAM_BASE_ADDR_REG(cpu,csNum) (0x1500 + ((csNum) * 8) + ((cpu) * 0x70))
  59670. +#define SCBAR_BASE_OFFS 16
  59671. +#define SCBAR_BASE_MASK (0xffff << SCBAR_BASE_OFFS)
  59672. +#define SCBAR_BASE_ALIGNMENT 0x10000
  59673. +
  59674. +/* SDRAM CSn Size Register (SCSR) */
  59675. +#define SDRAM_SIZE_REG(cpu,csNum) (0x1504 + ((csNum) * 8) + ((cpu) * 0x70))
  59676. +#define SCSR_SIZE_OFFS 24
  59677. +#define SCSR_SIZE_MASK (0xff << SCSR_SIZE_OFFS)
  59678. +#define SCSR_SIZE_ALIGNMENT 0x1000000
  59679. +#define SCSR_WIN_EN BIT0
  59680. +
  59681. +/* configuration register */
  59682. +#define SDRAM_CONFIG_REG (DRAM_BASE + 0x1400)
  59683. +#define SDRAM_REFRESH_OFFS 0
  59684. +#define SDRAM_REFRESH_MAX 0x3FFF
  59685. +#define SDRAM_REFRESH_MASK (SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)
  59686. +#define SDRAM_DWIDTH_OFFS 15
  59687. +#define SDRAM_DWIDTH_MASK (1 << SDRAM_DWIDTH_OFFS)
  59688. +#define SDRAM_DWIDTH_32BIT (0 << SDRAM_DWIDTH_OFFS)
  59689. +#define SDRAM_DWIDTH_64BIT (1 << SDRAM_DWIDTH_OFFS)
  59690. +#define SDRAM_REGISTERED (1 << 17)
  59691. +#define SDRAM_ECC_OFFS 18
  59692. +#define SDRAM_ECC_MASK (1 << SDRAM_ECC_OFFS)
  59693. +#define SDRAM_ECC_DIS (0 << SDRAM_ECC_OFFS)
  59694. +#define SDRAM_ECC_EN (1 << SDRAM_ECC_OFFS)
  59695. +#define SDRAM_IERR_OFFS 19
  59696. +#define SDRAM_IERR_MASK (1 << SDRAM_IERR_OFFS)
  59697. +#define SDRAM_IERR_REPORTE (0 << SDRAM_IERR_OFFS)
  59698. +#define SDRAM_IERR_IGNORE (1 << SDRAM_IERR_OFFS)
  59699. +#define SDRAM_SRMODE_OFFS 24
  59700. +#define SDRAM_SRMODE_MASK (1 << SDRAM_SRMODE_OFFS)
  59701. +#define SDRAM_SRMODE_POWER (0 << SDRAM_SRMODE_OFFS)
  59702. +#define SDRAM_SRMODE_DRAM (1 << SDRAM_SRMODE_OFFS)
  59703. +
  59704. +/* dunit control low register */
  59705. +#define SDRAM_DUNIT_CTRL_REG (DRAM_BASE + 0x1404)
  59706. +#define SDRAM_2T_OFFS 4
  59707. +#define SDRAM_2T_MASK (1 << SDRAM_2T_OFFS)
  59708. +#define SDRAM_2T_MODE (1 << SDRAM_2T_OFFS)
  59709. +
  59710. +#define SDRAM_SRCLK_OFFS 5
  59711. +#define SDRAM_SRCLK_MASK (1 << SDRAM_SRCLK_OFFS)
  59712. +#define SDRAM_SRCLK_KEPT (0 << SDRAM_SRCLK_OFFS)
  59713. +#define SDRAM_SRCLK_GATED (1 << SDRAM_SRCLK_OFFS)
  59714. +#define SDRAM_CTRL_POS_OFFS 6
  59715. +#define SDRAM_CTRL_POS_MASK (1 << SDRAM_CTRL_POS_OFFS)
  59716. +#define SDRAM_CTRL_POS_FALL (0 << SDRAM_CTRL_POS_OFFS)
  59717. +#define SDRAM_CTRL_POS_RISE (1 << SDRAM_CTRL_POS_OFFS)
  59718. +#define SDRAM_CLK1DRV_OFFS 12
  59719. +#define SDRAM_CLK1DRV_MASK (1 << SDRAM_CLK1DRV_OFFS)
  59720. +#define SDRAM_CLK1DRV_HIGH_Z (0 << SDRAM_CLK1DRV_OFFS)
  59721. +#define SDRAM_CLK1DRV_NORMAL (1 << SDRAM_CLK1DRV_OFFS)
  59722. +#define SDRAM_CLK2DRV_OFFS 13
  59723. +#define SDRAM_CLK2DRV_MASK (1 << SDRAM_CLK2DRV_OFFS)
  59724. +#define SDRAM_CLK2DRV_HIGH_Z (0 << SDRAM_CLK2DRV_OFFS)
  59725. +#define SDRAM_CLK2DRV_NORMAL (1 << SDRAM_CLK2DRV_OFFS)
  59726. +#define SDRAM_SB_OUT_DEL_OFFS 20
  59727. +#define SDRAM_SB_OUT_DEL_MAX 0xf
  59728. +#define SDRAM_SB_OUT_MASK (SDRAM_SB_OUT_DEL_MAX<<SDRAM_SB_OUT_DEL_OFFS)
  59729. +#define SDRAM_SB_IN_DEL_OFFS 24
  59730. +#define SDRAM_SB_IN_DEL_MAX 0xf
  59731. +#define SDRAM_SB_IN_MASK (SDRAM_SB_IN_DEL_MAX<<SDRAM_SB_IN_DEL_OFFS)
  59732. +
  59733. +/* dunit control hight register */
  59734. +#define SDRAM_DUNIT_CTRL_HI_REG (DRAM_BASE + 0x1424)
  59735. +#define SDRAM__D2P_OFFS 7
  59736. +#define SDRAM__D2P_EN (1 << SDRAM__D2P_OFFS)
  59737. +#define SDRAM__P2D_OFFS 8
  59738. +#define SDRAM__P2D_EN (1 << SDRAM__P2D_OFFS)
  59739. +#define SDRAM__ADD_HALF_FCC_OFFS 9
  59740. +#define SDRAM__ADD_HALF_FCC_EN (1 << SDRAM__ADD_HALF_FCC_OFFS)
  59741. +#define SDRAM__PUP_ZERO_SKEW_OFFS 10
  59742. +#define SDRAM__PUP_ZERO_SKEW_EN (1 << SDRAM__PUP_ZERO_SKEW_OFFS)
  59743. +#define SDRAM__WR_MESH_DELAY_OFFS 11
  59744. +#define SDRAM__WR_MESH_DELAY_EN (1 << SDRAM__WR_MESH_DELAY_OFFS)
  59745. +
  59746. +/* sdram timing control low register */
  59747. +#define SDRAM_TIMING_CTRL_LOW_REG (DRAM_BASE + 0x1408)
  59748. +#define SDRAM_TRCD_OFFS 4
  59749. +#define SDRAM_TRCD_MASK (0xF << SDRAM_TRCD_OFFS)
  59750. +#define SDRAM_TRP_OFFS 8
  59751. +#define SDRAM_TRP_MASK (0xF << SDRAM_TRP_OFFS)
  59752. +#define SDRAM_TWR_OFFS 12
  59753. +#define SDRAM_TWR_MASK (0xF << SDRAM_TWR_OFFS)
  59754. +#define SDRAM_TWTR_OFFS 16
  59755. +#define SDRAM_TWTR_MASK (0xF << SDRAM_TWTR_OFFS)
  59756. +#define SDRAM_TRAS_OFFS 0
  59757. +#define SDRAM_TRAS_MASK (0xF << SDRAM_TRAS_OFFS)
  59758. +#define SDRAM_EXT_TRAS_OFFS 20
  59759. +#define SDRAM_EXT_TRAS_MASK (0x1 << SDRAM_EXT_TRAS_OFFS)
  59760. +#define SDRAM_TRRD_OFFS 24
  59761. +#define SDRAM_TRRD_MASK (0xF << SDRAM_TRRD_OFFS)
  59762. +#define SDRAM_TRTP_OFFS 28
  59763. +#define SDRAM_TRTP_MASK (0xF << SDRAM_TRTP_OFFS)
  59764. +#define SDRAM_TRTP_DDR1 (0x1 << SDRAM_TRTP_OFFS)
  59765. +
  59766. +/* sdram timing control high register */
  59767. +#define SDRAM_TIMING_CTRL_HIGH_REG (DRAM_BASE + 0x140c)
  59768. +#define SDRAM_TRFC_OFFS 0
  59769. +#define SDRAM_TRFC_MASK (0x3F << SDRAM_TRFC_OFFS)
  59770. +#define SDRAM_TR2R_OFFS 7
  59771. +#define SDRAM_TR2R_MASK (0x3 << SDRAM_TR2R_OFFS)
  59772. +#define SDRAM_TR2W_W2R_OFFS 9
  59773. +#define SDRAM_TR2W_W2R_MASK (0x3 << SDRAM_TR2W_W2R_OFFS)
  59774. +#define SDRAM_TW2W_OFFS 11
  59775. +#define SDRAM_TW2W_MASK (0x3 << SDRAM_TW2W_OFFS)
  59776. +
  59777. +/* sdram DDR2 timing low register (SD2TLR) */
  59778. +#define SDRAM_DDR2_TIMING_LO_REG (DRAM_BASE + 0x1428)
  59779. +#define SD2TLR_TODT_ON_RD_OFFS 4
  59780. +#define SD2TLR_TODT_ON_RD_MASK (0xF << SD2TLR_TODT_ON_RD_OFFS)
  59781. +#define SD2TLR_TODT_OFF_RD_OFFS 8
  59782. +#define SD2TLR_TODT_OFF_RD_MASK (0xF << SD2TLR_TODT_OFF_RD_OFFS)
  59783. +#define SD2TLR_TODT_ON_CTRL_RD_OFFS 12
  59784. +#define SD2TLR_TODT_ON_CTRL_RD_MASK (0xF << SD2TLR_TODT_ON_CTRL_RD_OFFS)
  59785. +#define SD2TLR_TODT_OFF_CTRL_RD_OFFS 16
  59786. +#define SD2TLR_TODT_OFF_CTRL_RD_MASK (0xF << SD2TLR_TODT_OFF_CTRL_RD_OFFS)
  59787. +
  59788. +/* sdram DDR2 timing high register (SD2TLR) */
  59789. +#define SDRAM_DDR2_TIMING_HI_REG (DRAM_BASE + 0x147C)
  59790. +#define SD2THR_TODT_ON_WR_OFFS 0
  59791. +#define SD2THR_TODT_ON_WR_MASK (0xF << SD2THR_TODT_ON_WR_OFFS)
  59792. +#define SD2THR_TODT_OFF_WR_OFFS 4
  59793. +#define SD2THR_TODT_OFF_WR_MASK (0xF << SD2THR_TODT_OFF_WR_OFFS)
  59794. +#define SD2THR_TODT_ON_CTRL_WR_OFFS 8
  59795. +#define SD2THR_TODT_ON_CTRL_WR_MASK (0xF << SD2THR_TODT_ON_CTRL_WR_OFFS)
  59796. +#define SD2THR_TODT_OFF_CTRL_WR_OFFS 12
  59797. +#define SD2THR_TODT_OFF_CTRL_WR_MASK (0xF << SD2THR_TODT_OFF_CTRL_WR_OFFS)
  59798. +
  59799. +/* address control register */
  59800. +#define SDRAM_ADDR_CTRL_REG (DRAM_BASE + 0x1410)
  59801. +#define SDRAM_ADDRSEL_OFFS(cs) (4 * (cs))
  59802. +#define SDRAM_ADDRSEL_MASK(cs) (0x3 << SDRAM_ADDRSEL_OFFS(cs))
  59803. +#define SDRAM_ADDRSEL_X8(cs) (0x0 << SDRAM_ADDRSEL_OFFS(cs))
  59804. +#define SDRAM_ADDRSEL_X16(cs) (0x1 << SDRAM_ADDRSEL_OFFS(cs))
  59805. +#define SDRAM_DSIZE_OFFS(cs) (2 + 4 * (cs))
  59806. +#define SDRAM_DSIZE_MASK(cs) (0x3 << SDRAM_DSIZE_OFFS(cs))
  59807. +#define SDRAM_DSIZE_256Mb(cs) (0x1 << SDRAM_DSIZE_OFFS(cs))
  59808. +#define SDRAM_DSIZE_512Mb(cs) (0x2 << SDRAM_DSIZE_OFFS(cs))
  59809. +#define SDRAM_DSIZE_1Gb(cs) (0x3 << SDRAM_DSIZE_OFFS(cs))
  59810. +#define SDRAM_DSIZE_2Gb(cs) (0x0 << SDRAM_DSIZE_OFFS(cs))
  59811. +
  59812. +/* SDRAM Open Pages Control registers */
  59813. +#define SDRAM_OPEN_PAGE_CTRL_REG (DRAM_BASE + 0x1414)
  59814. +#define SDRAM_OPEN_PAGE_EN (0 << 0)
  59815. +#define SDRAM_OPEN_PAGE_DIS (1 << 0)
  59816. +
  59817. +/* sdram opertion register */
  59818. +#define SDRAM_OPERATION_REG (DRAM_BASE + 0x1418)
  59819. +#define SDRAM_CMD_OFFS 0
  59820. +#define SDRAM_CMD_MASK (0xF << SDRAM_CMD_OFFS)
  59821. +#define SDRAM_CMD_NORMAL (0x0 << SDRAM_CMD_OFFS)
  59822. +#define SDRAM_CMD_PRECHARGE_ALL (0x1 << SDRAM_CMD_OFFS)
  59823. +#define SDRAM_CMD_REFRESH_ALL (0x2 << SDRAM_CMD_OFFS)
  59824. +#define SDRAM_CMD_REG_SET_CMD (0x3 << SDRAM_CMD_OFFS)
  59825. +#define SDRAM_CMD_EXT_MODE_SET (0x4 << SDRAM_CMD_OFFS)
  59826. +#define SDRAM_CMD_NOP (0x5 << SDRAM_CMD_OFFS)
  59827. +#define SDRAM_CMD_SLF_RFRSH (0x7 << SDRAM_CMD_OFFS)
  59828. +#define SDRAM_CMD_EMRS2_CMD (0x8 << SDRAM_CMD_OFFS)
  59829. +#define SDRAM_CMD_EMRS3_CMD (0x9 << SDRAM_CMD_OFFS)
  59830. +
  59831. +/* sdram mode register */
  59832. +#define SDRAM_MODE_REG (DRAM_BASE + 0x141c)
  59833. +#define SDRAM_BURST_LEN_OFFS 0
  59834. +#define SDRAM_BURST_LEN_MASK (0x7 << SDRAM_BURST_LEN_OFFS)
  59835. +#define SDRAM_BURST_LEN_4 (0x2 << SDRAM_BURST_LEN_OFFS)
  59836. +#define SDRAM_CL_OFFS 4
  59837. +#define SDRAM_CL_MASK (0x7 << SDRAM_CL_OFFS)
  59838. +#define SDRAM_DDR2_CL_3 (0x3 << SDRAM_CL_OFFS)
  59839. +#define SDRAM_DDR2_CL_4 (0x4 << SDRAM_CL_OFFS)
  59840. +#define SDRAM_DDR2_CL_5 (0x5 << SDRAM_CL_OFFS)
  59841. +#define SDRAM_DDR2_CL_6 (0x6 << SDRAM_CL_OFFS)
  59842. +
  59843. +#define SDRAM_TM_OFFS 7
  59844. +#define SDRAM_TM_MASK (1 << SDRAM_TM_OFFS)
  59845. +#define SDRAM_TM_NORMAL (0 << SDRAM_TM_OFFS)
  59846. +#define SDRAM_TM_TEST_MODE (1 << SDRAM_TM_OFFS)
  59847. +#define SDRAM_DLL_OFFS 8
  59848. +#define SDRAM_DLL_MASK (1 << SDRAM_DLL_OFFS)
  59849. +#define SDRAM_DLL_NORMAL (0 << SDRAM_DLL_OFFS)
  59850. +#define SDRAM_DLL_RESET (1 << SDRAM_DLL_OFFS)
  59851. +#define SDRAM_WR_OFFS 9
  59852. +#define SDRAM_WR_MAX 7
  59853. +#define SDRAM_WR_MASK (SDRAM_WR_MAX << SDRAM_WR_OFFS)
  59854. +#define SDRAM_WR_2_CYC (1 << SDRAM_WR_OFFS)
  59855. +#define SDRAM_WR_3_CYC (2 << SDRAM_WR_OFFS)
  59856. +#define SDRAM_WR_4_CYC (3 << SDRAM_WR_OFFS)
  59857. +#define SDRAM_WR_5_CYC (4 << SDRAM_WR_OFFS)
  59858. +#define SDRAM_WR_6_CYC (5 << SDRAM_WR_OFFS)
  59859. +#define SDRAM_PD_OFFS 12
  59860. +#define SDRAM_PD_MASK (1 << SDRAM_PD_OFFS)
  59861. +#define SDRAM_PD_FAST_EXIT (0 << SDRAM_PD_OFFS)
  59862. +#define SDRAM_PD_SLOW_EXIT (1 << SDRAM_PD_OFFS)
  59863. +
  59864. +/* DDR SDRAM Extended Mode register (DSEMR) */
  59865. +#define SDRAM_EXTENDED_MODE_REG (DRAM_BASE + 0x1420)
  59866. +#define DSEMR_DLL_ENABLE 0
  59867. +#define DSEMR_DLL_DISABLE 1
  59868. +#define DSEMR_DS_OFFS 1
  59869. +#define DSEMR_DS_MASK (1 << DSEMR_DS_OFFS)
  59870. +#define DSEMR_DS_NORMAL (0 << DSEMR_DS_OFFS)
  59871. +#define DSEMR_DS_REDUCED (1 << DSEMR_DS_OFFS)
  59872. +#define DSEMR_QOFF_OUTPUT_BUFF_EN (0 << 12)
  59873. +#define DSEMR_RTT0_OFFS 2
  59874. +#define DSEMR_RTT1_OFFS 6
  59875. +#define DSEMR_RTT_ODT_DISABLE ((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  59876. +#define DSEMR_RTT_ODT_75_OHM ((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  59877. +#define DSEMR_RTT_ODT_150_OHM ((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
  59878. +#define DSEMR_RTT_ODT_50_OHM ((1 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
  59879. +#define DSEMR_DQS_OFFS 10
  59880. +#define DSEMR_DQS_MASK (1 << DSEMR_DQS_OFFS)
  59881. +#define DSEMR_DQS_DIFFERENTIAL (0 << DSEMR_DQS_OFFS)
  59882. +#define DSEMR_DQS_SINGLE_ENDED (1 << DSEMR_DQS_OFFS)
  59883. +#define DSEMR_RDQS_ENABLE (1 << 11)
  59884. +#define DSEMR_QOFF_OUTPUT_BUFF_EN (0 << 12)
  59885. +#define DSEMR_QOFF_OUTPUT_BUFF_DIS (1 << 12)
  59886. +
  59887. +/* DDR SDRAM Operation Control Register */
  59888. +#define SDRAM_OPERATION_CTRL_REG (DRAM_BASE + 0x142c)
  59889. +
  59890. +/* Dunit FTDLL Configuration Register */
  59891. +#define SDRAM_FTDLL_CONFIG_LEFT_REG (DRAM_BASE + 0x1484)
  59892. +#define SDRAM_FTDLL_CONFIG_RIGHT_REG (DRAM_BASE + 0x161C)
  59893. +#define SDRAM_FTDLL_CONFIG_UP_REG (DRAM_BASE + 0x1620)
  59894. +
  59895. +/* Pads Calibration register */
  59896. +#define SDRAM_ADDR_CTRL_PADS_CAL_REG (DRAM_BASE + 0x14c0)
  59897. +#define SDRAM_DATA_PADS_CAL_REG (DRAM_BASE + 0x14c4)
  59898. +#define SDRAM_DRVN_OFFS 0
  59899. +#define SDRAM_DRVN_MASK (0x3F << SDRAM_DRVN_OFFS)
  59900. +#define SDRAM_DRVP_OFFS 6
  59901. +#define SDRAM_DRVP_MASK (0x3F << SDRAM_DRVP_OFFS)
  59902. +#define SDRAM_PRE_DRIVER_STRENGTH_OFFS 12
  59903. +#define SDRAM_PRE_DRIVER_STRENGTH_MASK (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  59904. +#define SDRAM_TUNE_EN BIT16
  59905. +#define SDRAM_LOCKN_OFFS 17
  59906. +#define SDRAM_LOCKN_MAKS (0x3F << SDRAM_LOCKN_OFFS)
  59907. +#define SDRAM_LOCKP_OFFS 23
  59908. +#define SDRAM_LOCKP_MAKS (0x3F << SDRAM_LOCKP_OFFS)
  59909. +#define SDRAM_WR_EN (1 << 31)
  59910. +
  59911. +/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */
  59912. +#define DDR2_SDRAM_ODT_CTRL_LOW_REG (DRAM_BASE + 0x1494)
  59913. +#define DSOCLR_ODT_RD_OFFS(odtNum) (odtNum * 4)
  59914. +#define DSOCLR_ODT_RD_MASK(odtNum) (0xf << DSOCLR_ODT_RD_OFFS(odtNum))
  59915. +#define DSOCLR_ODT_RD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))
  59916. +#define DSOCLR_ODT_WR_OFFS(odtNum) (16 + (odtNum * 4))
  59917. +#define DSOCLR_ODT_WR_MASK(odtNum) (0xf << DSOCLR_ODT_WR_OFFS(odtNum))
  59918. +#define DSOCLR_ODT_WR(odtNum, bank) ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))
  59919. +
  59920. +/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */
  59921. +#define DDR2_SDRAM_ODT_CTRL_HIGH_REG (DRAM_BASE + 0x1498)
  59922. +/* Optional control values to DSOCHR_ODT_EN macro */
  59923. +#define DDR2_ODT_CTRL_DUNIT 0
  59924. +#define DDR2_ODT_CTRL_NEVER 1
  59925. +#define DDR2_ODT_CTRL_ALWAYS 3
  59926. +#define DSOCHR_ODT_EN_OFFS(odtNum) (odtNum * 2)
  59927. +#define DSOCHR_ODT_EN_MASK(odtNum) (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))
  59928. +#define DSOCHR_ODT_EN(odtNum, ctrl) (ctrl << DSOCHR_ODT_EN_OFFS(odtNum))
  59929. +
  59930. +/* DDR2 Dunit ODT Control Register (DDOCR)*/
  59931. +#define DDR2_DUNIT_ODT_CONTROL_REG (DRAM_BASE + 0x149c)
  59932. +#define DDOCR_ODT_RD_OFFS 0
  59933. +#define DDOCR_ODT_RD_MASK (0xf << DDOCR_ODT_RD_OFFS)
  59934. +#define DDOCR_ODT_RD(bank) ((1 << bank) << DDOCR_ODT_RD_OFFS)
  59935. +#define DDOCR_ODT_WR_OFFS 4
  59936. +#define DDOCR_ODT_WR_MASK (0xf << DDOCR_ODT_WR_OFFS)
  59937. +#define DDOCR_ODT_WR(bank) ((1 << bank) << DDOCR_ODT_WR_OFFS)
  59938. +#define DSOCR_ODT_EN_OFFS 8
  59939. +#define DSOCR_ODT_EN_MASK (0x3 << DSOCR_ODT_EN_OFFS)
  59940. +/* For ctrl parameters see DDR2 SDRAM ODT Control (High) Register (0x1498) above. */
  59941. +#define DSOCR_ODT_EN(ctrl) (ctrl << DSOCR_ODT_EN_OFFS)
  59942. +#define DSOCR_ODT_SEL_DISABLE 0
  59943. +#define DSOCR_ODT_SEL_75_OHM 2
  59944. +#define DSOCR_ODT_SEL_150_OHM 1
  59945. +#define DSOCR_ODT_SEL_50_OHM 3
  59946. +#define DSOCR_DQ_ODT_SEL_OFFS 10
  59947. +#define DSOCR_DQ_ODT_SEL_MASK (0x3 << DSOCR_DQ_ODT_SEL_OFFS)
  59948. +#define DSOCR_DQ_ODT_SEL(odtSel) (odtSel << DSOCR_DQ_ODT_SEL_OFFS)
  59949. +#define DSOCR_ST_ODT_SEL_OFFS 12
  59950. +#define DSOCR_ST_ODT_SEL_MASK (0x3 << DSOCR_ST_ODT_SEL_OFFS)
  59951. +#define DSOCR_ST_ODT_SEL(odtSel) (odtSel << DSOCR_ST_ODT_SEL_OFFS)
  59952. +#define DSOCR_ST_ODT_EN (1 << 14)
  59953. +
  59954. +/* DDR SDRAM Initialization Control Register (DSICR) */
  59955. +#define DDR_SDRAM_INIT_CTRL_REG (DRAM_BASE + 0x1480)
  59956. +#define DSICR_INIT_EN (1 << 0)
  59957. +#define DSICR_T200_SET (1 << 8)
  59958. +
  59959. +/* sdram extended mode2 register (SEM2R) */
  59960. +#define SDRAM_EXTENDED_MODE2_REG (DRAM_BASE + 0x148C)
  59961. +#define SEM2R_EMRS2_DDR2_OFFS 0
  59962. +#define SEM2R_EMRS2_DDR2_MASK (0x7FFF << SEM2R_EMRS2_DDR2_OFFS)
  59963. +
  59964. +/* sdram extended mode3 register (SEM3R) */
  59965. +#define SDRAM_EXTENDED_MODE3_REG (DRAM_BASE + 0x1490)
  59966. +#define SEM3R_EMRS3_DDR2_OFFS 0
  59967. +#define SEM3R_EMRS3_DDR2_MASK (0x7FFF << SEM3R_EMRS3_DDR2_OFFS)
  59968. +
  59969. +/* sdram error registers */
  59970. +#define SDRAM_ERROR_CAUSE_REG (DRAM_BASE + 0x14d0)
  59971. +#define SDRAM_ERROR_MASK_REG (DRAM_BASE + 0x14d4)
  59972. +#define SDRAM_ERROR_DATA_LOW_REG (DRAM_BASE + 0x1444)
  59973. +#define SDRAM_ERROR_DATA_HIGH_REG (DRAM_BASE + 0x1440)
  59974. +#define SDRAM_ERROR_ADDR_REG (DRAM_BASE + 0x1450)
  59975. +#define SDRAM_ERROR_ECC_REG (DRAM_BASE + 0x1448)
  59976. +#define SDRAM_CALC_ECC_REG (DRAM_BASE + 0x144c)
  59977. +#define SDRAM_ECC_CONTROL_REG (DRAM_BASE + 0x1454)
  59978. +#define SDRAM_SINGLE_BIT_ERR_CNTR_REG (DRAM_BASE + 0x1458)
  59979. +#define SDRAM_DOUBLE_BIT_ERR_CNTR_REG (DRAM_BASE + 0x145c)
  59980. +
  59981. +/* SDRAM Error Cause Register (SECR) */
  59982. +#define SECR_SINGLE_BIT_ERR BIT0
  59983. +#define SECR_DOUBLE_BIT_ERR BIT1
  59984. +#define SECR_DATA_PATH_PARITY_ERR BIT2
  59985. +/* SDRAM Error Address Register (SEAR) */
  59986. +#define SEAR_ERR_TYPE_OFFS 0
  59987. +#define SEAR_ERR_TYPE_MASK (1 << SEAR_ERR_TYPE_OFFS)
  59988. +#define SEAR_ERR_TYPE_SINGLE 0
  59989. +#define SEAR_ERR_TYPE_DOUBLE (1 << SEAR_ERR_TYPE_OFFS)
  59990. +#define SEAR_ERR_CS_OFFS 1
  59991. +#define SEAR_ERR_CS_MASK (3 << SEAR_ERR_CS_OFFS)
  59992. +#define SEAR_ERR_CS(csNum) (csNum << SEAR_ERR_CS_OFFS)
  59993. +#define SEAR_ERR_ADDR_OFFS 3
  59994. +#define SEAR_ERR_ADDR_MASK (0x1FFFFFFF << SEAR_ERR_ADDR_OFFS)
  59995. +
  59996. +/* SDRAM ECC Control Register (SECR) */
  59997. +#define SECR_FORCEECC_OFFS 0
  59998. +#define SECR_FORCEECC_MASK (0xFF << SECR_FORCEECC_OFFS)
  59999. +#define SECR_FORCEEN_OFFS 8
  60000. +#define SECR_FORCEEN_MASK (1 << SECR_FORCEEN_OFFS)
  60001. +#define SECR_ECC_CALC_MASK (0 << SECR_FORCEEN_OFFS)
  60002. +#define SECR_ECC_USER_MASK (1 << SECR_FORCEEN_OFFS)
  60003. +#define SECR_PERRPROP_EN BIT9
  60004. +#define SECR_CNTMODE_OFFS 10
  60005. +#define SECR_CNTMODE_MASK (1 << SECR_CNTMODE_OFFS)
  60006. +#define SECR_ALL_IN_CS0 (0 << SECR_CNTMODE_OFFS)
  60007. +#define SECR_NORMAL_COUNTER (1 << SECR_CNTMODE_OFFS)
  60008. +#define SECR_THRECC_OFFS 16
  60009. +#define SECR_THRECC_MAX 0xFF
  60010. +#define SECR_THRECC_MASK (SECR_THRECC_MAX << SECR_THRECC_OFFS)
  60011. +#define SECR_THRECC(threshold) (threshold << SECR_THRECC_OFFS)
  60012. +
  60013. +
  60014. +#ifdef __cplusplus
  60015. +}
  60016. +#endif /* __cplusplus */
  60017. +
  60018. +#endif /* __INCmvDramIfRegsh */
  60019. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h
  60020. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h 1970-01-01 01:00:00.000000000 +0100
  60021. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h 2011-07-31 11:31:59.943416960 +0200
  60022. @@ -0,0 +1,179 @@
  60023. +/*******************************************************************************
  60024. +Copyright (C) Marvell International Ltd. and its affiliates
  60025. +
  60026. +This software file (the "File") is owned and distributed by Marvell
  60027. +International Ltd. and/or its affiliates ("Marvell") under the following
  60028. +alternative licensing terms. Once you have made an election to distribute the
  60029. +File under one of the following license alternatives, please (i) delete this
  60030. +introductory statement regarding license alternatives, (ii) delete the two
  60031. +license alternatives that you have not elected to use and (iii) preserve the
  60032. +Marvell copyright notice above.
  60033. +
  60034. +********************************************************************************
  60035. +Marvell Commercial License Option
  60036. +
  60037. +If you received this File from Marvell and you have entered into a commercial
  60038. +license agreement (a "Commercial License") with Marvell, the File is licensed
  60039. +to you under the terms of the applicable Commercial License.
  60040. +
  60041. +********************************************************************************
  60042. +Marvell GPL License Option
  60043. +
  60044. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60045. +modify this File in accordance with the terms and conditions of the General
  60046. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  60047. +available along with the File in the license.txt file or by writing to the Free
  60048. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  60049. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  60050. +
  60051. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  60052. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  60053. +DISCLAIMED. The GPL License provides additional details about this warranty
  60054. +disclaimer.
  60055. +********************************************************************************
  60056. +Marvell BSD License Option
  60057. +
  60058. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60059. +modify this File under the following licensing terms.
  60060. +Redistribution and use in source and binary forms, with or without modification,
  60061. +are permitted provided that the following conditions are met:
  60062. +
  60063. + * Redistributions of source code must retain the above copyright notice,
  60064. + this list of conditions and the following disclaimer.
  60065. +
  60066. + * Redistributions in binary form must reproduce the above copyright
  60067. + notice, this list of conditions and the following disclaimer in the
  60068. + documentation and/or other materials provided with the distribution.
  60069. +
  60070. + * Neither the name of Marvell nor the names of its contributors may be
  60071. + used to endorse or promote products derived from this software without
  60072. + specific prior written permission.
  60073. +
  60074. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  60075. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  60076. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  60077. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  60078. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  60079. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  60080. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  60081. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  60082. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  60083. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60084. +
  60085. +*******************************************************************************/
  60086. +
  60087. +
  60088. +#ifndef __INCmvDramIfStaticInith
  60089. +#define __INCmvDramIfStaticInith
  60090. +
  60091. +#ifdef MV_STATIC_DRAM_ON_BOARD
  60092. +#define STATIC_DRAM_BANK_1
  60093. +#undef STATIC_DRAM_BANK_2
  60094. +#undef STATIC_DRAM_BANK_3
  60095. +#undef STATIC_DRAM_BANK_4
  60096. +
  60097. +
  60098. +#ifdef MV_DIMM_TS256MLQ72V5U
  60099. +#define STATIC_DRAM_BANK_2
  60100. +#define STATIC_DRAM_BANK_3
  60101. +#undef STATIC_DRAM_BANK_4
  60102. +
  60103. +#define STATIC_SDRAM_CONFIG_REG 0x4724481A /* offset 0x1400 - DMA reg-0xf1000814 */
  60104. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0x37707450 /* offset 0x1404 - DMA reg-0xf100081c */
  60105. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11A13330 /* offset 0x1408 - DMA reg-0xf1000824 */
  60106. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000601 /* offset 0x140c - DMA reg-0xf1000828 */
  60107. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00001CB2 /* offset 0x1410 - DMA reg-0xf1000820 */
  60108. +#define STATIC_SDRAM_MODE_REG 0x00000642 /* offset 0x141c - DMA reg-0xf1000818 */
  60109. +#define STATIC_SDRAM_ODT_CTRL_LOW 0x030C030C /* 0x1494 */
  60110. +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000 /* 0x1498 */
  60111. +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000740F /* 0x149c */
  60112. +#define STATIC_SDRAM_EXT_MODE 0x00000404 /* 0x1420 */
  60113. +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00074410 /* 0x1428 */
  60114. +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00007441 /* 0x147C */
  60115. +
  60116. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x3FFF /* size bank0 dimm0 - DMA reg-0xf1000810 */
  60117. +#define STATIC_SDRAM_RANK1_SIZE_DIMM0 0x3FFF /* size bank1 dimm0 */
  60118. +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x3FFF /* size bank0 dimm1 */
  60119. +#define STATIC_SDRAM_RANK1_SIZE_DIMM1 0x0 /* size bank1 dimm1 */
  60120. +
  60121. +#endif /* TS256MLQ72V5U */
  60122. +
  60123. +
  60124. +#ifdef MV_MT9VDDT3272AG
  60125. +/* one DIMM 256M */
  60126. +#define STATIC_SDRAM_CONFIG_REG 0x5820040d /* offset 0x1400 - DMA reg-0xf1000814 */
  60127. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xC4000540 /* offset 0x1404 - DMA reg-0xf100081c */
  60128. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x01602220 /* offset 0x1408 - DMA reg-0xf1000824 */
  60129. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x0000000b /* offset 0x140c - DMA reg-0xf1000828 */
  60130. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000012 /* offset 0x1410 - DMA reg-0xf1000820 */
  60131. +#define STATIC_SDRAM_MODE_REG 0x00000062 /* offset 0x141c - DMA reg-0xf1000818 */
  60132. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x0fff /* size bank0 dimm0 - DMA reg-0xf1000810 */
  60133. +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x0 /* size bank0 dimm1 */
  60134. +
  60135. +#endif /* MV_MT9VDDT3272AG */
  60136. +
  60137. +
  60138. +
  60139. +#ifdef MV_D27RB12P
  60140. +/*
  60141. +Two DIMM 512M + ECC enabled, Registered DIMM CAS Latency 2.5
  60142. +*/
  60143. +
  60144. +#define STATIC_SDRAM_CONFIG_REG 0x6826081E /* offset 0x1400 - DMA reg-0xf1000814 */
  60145. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xC5000540 /* offset 0x1404 - DMA reg-0xf100081c */
  60146. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x01501220 /* offset 0x1408 - DMA reg-0xf1000824 */
  60147. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000009 /* offset 0x140c - DMA reg-0xf1000828 */
  60148. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000012 /* offset 0x1410 - DMA reg-0xf1000820 */
  60149. +#define STATIC_SDRAM_MODE_REG 0x00000062 /* offset 0x141c - DMA reg-0xf1000818 */
  60150. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x0FFF /* size bank0 dimm0 - DMA reg-0xf1000810 */
  60151. +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x0FFF /* size bank0 dimm1 */
  60152. +
  60153. +#define STATIC_DRAM_BANK_2
  60154. +
  60155. +#define STATIC_DRAM_BANK_3
  60156. +#define STATIC_DRAM_BANK_4
  60157. +
  60158. +#endif /* mv_D27RB12P */
  60159. +
  60160. +#ifdef RD_MV645XX
  60161. +
  60162. +#define STATIC_MEM_TYPE MEM_TYPE_DDR2
  60163. +#define STATIC_DIMM_INFO_BANK0_SIZE 256
  60164. +/* DDR2 boards 256 MB*/
  60165. +
  60166. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x00000fff /* size bank0 dimm0 - DMA reg-0xf1000810 */
  60167. +#define STATIC_SDRAM_CONFIG_REG 0x07190618
  60168. +#define STATIC_SDRAM_MODE_REG 0x00000432
  60169. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xf4a03440
  60170. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000022
  60171. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11712220
  60172. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000504
  60173. +#define STATIC_SDRAM_ODT_CTRL_LOW 0x84210000
  60174. +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000
  60175. +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000780f
  60176. +#define STATIC_SDRAM_EXT_MODE 0x00000440
  60177. +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00063300
  60178. +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00006330
  60179. +#endif /* RD_MV645XX */
  60180. +
  60181. +#if MV_DIMM_M3783354CZ3_CE6
  60182. +
  60183. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x00000FFF /* 0x2010 size bank0 dimm0 - DMA reg-0xf1000810 */
  60184. +#define STATIC_SDRAM_CONFIG_REG 0x07190618 /* 0x1400 */
  60185. +#define STATIC_SDRAM_MODE_REG 0x00000432 /* 0x141c */
  60186. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xf4a03440 /* 0x1404 */
  60187. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000022 /* 0x1410 */
  60188. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11712220 /* 0x1408 */
  60189. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000504 /* 0x140c */
  60190. +#define STATIC_SDRAM_ODT_CTRL_LOW 0x84210000 /* 0x1494 */
  60191. +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000 /* 0x1498 */
  60192. +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000780f /* 0x149c */
  60193. +#define STATIC_SDRAM_EXT_MODE 0x00000440 /* 0x1420 */
  60194. +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00063300 /* 0x1428 */
  60195. +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00006330 /* 0x147C */
  60196. +
  60197. +#endif /* MV_DIMM_M3783354CZ3_CE6 */
  60198. +
  60199. +#endif /* MV_STATIC_DRAM_ON_BOARD */
  60200. +#endif /* __INCmvDramIfStaticInith */
  60201. +
  60202. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c
  60203. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c 1970-01-01 01:00:00.000000000 +0100
  60204. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c 2011-07-31 11:32:00.023420475 +0200
  60205. @@ -0,0 +1,1474 @@
  60206. +/*******************************************************************************
  60207. +Copyright (C) Marvell International Ltd. and its affiliates
  60208. +
  60209. +This software file (the "File") is owned and distributed by Marvell
  60210. +International Ltd. and/or its affiliates ("Marvell") under the following
  60211. +alternative licensing terms. Once you have made an election to distribute the
  60212. +File under one of the following license alternatives, please (i) delete this
  60213. +introductory statement regarding license alternatives, (ii) delete the two
  60214. +license alternatives that you have not elected to use and (iii) preserve the
  60215. +Marvell copyright notice above.
  60216. +
  60217. +********************************************************************************
  60218. +Marvell Commercial License Option
  60219. +
  60220. +If you received this File from Marvell and you have entered into a commercial
  60221. +license agreement (a "Commercial License") with Marvell, the File is licensed
  60222. +to you under the terms of the applicable Commercial License.
  60223. +
  60224. +********************************************************************************
  60225. +Marvell GPL License Option
  60226. +
  60227. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60228. +modify this File in accordance with the terms and conditions of the General
  60229. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  60230. +available along with the File in the license.txt file or by writing to the Free
  60231. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  60232. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  60233. +
  60234. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  60235. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  60236. +DISCLAIMED. The GPL License provides additional details about this warranty
  60237. +disclaimer.
  60238. +********************************************************************************
  60239. +Marvell BSD License Option
  60240. +
  60241. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60242. +modify this File under the following licensing terms.
  60243. +Redistribution and use in source and binary forms, with or without modification,
  60244. +are permitted provided that the following conditions are met:
  60245. +
  60246. + * Redistributions of source code must retain the above copyright notice,
  60247. + this list of conditions and the following disclaimer.
  60248. +
  60249. + * Redistributions in binary form must reproduce the above copyright
  60250. + notice, this list of conditions and the following disclaimer in the
  60251. + documentation and/or other materials provided with the distribution.
  60252. +
  60253. + * Neither the name of Marvell nor the names of its contributors may be
  60254. + used to endorse or promote products derived from this software without
  60255. + specific prior written permission.
  60256. +
  60257. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  60258. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  60259. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  60260. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  60261. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  60262. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  60263. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  60264. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  60265. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  60266. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60267. +
  60268. +*******************************************************************************/
  60269. +
  60270. +#include "ddr2/spd/mvSpd.h"
  60271. +#include "boardEnv/mvBoardEnvLib.h"
  60272. +
  60273. +/* #define MV_DEBUG */
  60274. +#ifdef MV_DEBUG
  60275. +#define DB(x) x
  60276. +#else
  60277. +#define DB(x)
  60278. +#endif
  60279. +
  60280. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  60281. + MV_DRAM_BANK_INFO *pBankInfo);
  60282. +static MV_U32 cas2ps(MV_U8 spd_byte);
  60283. +/*******************************************************************************
  60284. +* mvDramBankGet - Get the DRAM bank paramters.
  60285. +*
  60286. +* DESCRIPTION:
  60287. +* This function retrieves DRAM bank parameters as described in
  60288. +* DRAM_BANK_INFO struct to the controller DRAM unit. In case the board
  60289. +* has its DRAM on DIMMs it will use its EEPROM to extract SPD data
  60290. +* from it. Otherwise, if the DRAM is soldered on board, the function
  60291. +* should insert its bank information into MV_DRAM_BANK_INFO struct.
  60292. +*
  60293. +* INPUT:
  60294. +* bankNum - Board DRAM bank number.
  60295. +*
  60296. +* OUTPUT:
  60297. +* pBankInfo - DRAM bank information struct.
  60298. +*
  60299. +* RETURN:
  60300. +* MV_FAIL - Bank parameters could not be read.
  60301. +*
  60302. +*******************************************************************************/
  60303. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
  60304. +{
  60305. + MV_DIMM_INFO dimmInfo;
  60306. +
  60307. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
  60308. + /* zero pBankInfo structure */
  60309. +
  60310. + if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
  60311. + {
  60312. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  60313. + return MV_BAD_PARAM;
  60314. + }
  60315. + memset(pBankInfo, 0, sizeof(*pBankInfo));
  60316. +
  60317. + if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
  60318. + {
  60319. + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
  60320. + return MV_FAIL;
  60321. + }
  60322. + if ((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
  60323. + {
  60324. + DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
  60325. + return MV_FAIL;
  60326. + }
  60327. + /* convert Dimm info to Bank info */
  60328. + cpyDimm2BankInfo(&dimmInfo, pBankInfo);
  60329. + return MV_OK;
  60330. +}
  60331. +
  60332. +/*******************************************************************************
  60333. +* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
  60334. +*
  60335. +* DESCRIPTION:
  60336. +* Convert a Dimm info struct into a bank info struct.
  60337. +*
  60338. +* INPUT:
  60339. +* pDimmInfo - DIMM information structure.
  60340. +*
  60341. +* OUTPUT:
  60342. +* pBankInfo - DRAM bank information struct.
  60343. +*
  60344. +* RETURN:
  60345. +* None.
  60346. +*
  60347. +*******************************************************************************/
  60348. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  60349. + MV_DRAM_BANK_INFO *pBankInfo)
  60350. +{
  60351. + pBankInfo->memoryType = pDimmInfo->memoryType;
  60352. +
  60353. + /* DIMM dimensions */
  60354. + pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
  60355. + pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
  60356. + pBankInfo->dataWidth = pDimmInfo->dataWidth;
  60357. + pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
  60358. + pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
  60359. + pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
  60360. + pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
  60361. + pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
  60362. + pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
  60363. +
  60364. + /* DIMM timing parameters */
  60365. + pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
  60366. + pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  60367. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
  60368. + pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  60369. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
  60370. +
  60371. + pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
  60372. + pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
  60373. + pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
  60374. + pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
  60375. + pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
  60376. + pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
  60377. + pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
  60378. + pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
  60379. +
  60380. + /* Parameters calculated from the extracted DIMM information */
  60381. + pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
  60382. + pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
  60383. + pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
  60384. + pDimmInfo->numOfModuleBanks;
  60385. +
  60386. + /* DIMM attributes (MV_TRUE for yes) */
  60387. +
  60388. + if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
  60389. + (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
  60390. + {
  60391. + if (pDimmInfo->dimmAttributes & BIT1)
  60392. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  60393. + else
  60394. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  60395. + }
  60396. + else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
  60397. + {
  60398. + if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
  60399. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  60400. + else
  60401. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  60402. + }
  60403. +
  60404. + return;
  60405. +}
  60406. +/*******************************************************************************
  60407. +* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
  60408. +*
  60409. +* DESCRIPTION:
  60410. +* Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
  60411. +*
  60412. +* INPUT:
  60413. +* None.
  60414. +*
  60415. +* OUTPUT:
  60416. +* None.
  60417. +*
  60418. +* RETURN:
  60419. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  60420. +*
  60421. +*******************************************************************************/
  60422. +MV_STATUS dimmSpdCpy(MV_VOID)
  60423. +{
  60424. + MV_U32 i;
  60425. + MV_U32 spdChecksum;
  60426. +
  60427. + MV_TWSI_SLAVE twsiSlave;
  60428. + MV_U8 data[SPD_SIZE];
  60429. +
  60430. + /* zero dimmInfo structure */
  60431. + memset(data, 0, SPD_SIZE);
  60432. +
  60433. + /* read the dimm eeprom */
  60434. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  60435. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
  60436. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  60437. + twsiSlave.validOffset = MV_TRUE;
  60438. + twsiSlave.offset = 0;
  60439. + twsiSlave.moreThen256 = MV_FALSE;
  60440. +
  60441. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
  60442. + {
  60443. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
  60444. + return MV_FAIL;
  60445. + }
  60446. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  60447. +
  60448. + /* calculate SPD checksum */
  60449. + spdChecksum = 0;
  60450. +
  60451. + for(i = 0 ; i <= 62 ; i++)
  60452. + {
  60453. + spdChecksum += data[i];
  60454. + }
  60455. +
  60456. + if ((spdChecksum & 0xff) != data[63])
  60457. + {
  60458. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  60459. + (MV_U32)(spdChecksum & 0xff), data[63]));
  60460. + }
  60461. + else
  60462. + {
  60463. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  60464. + }
  60465. +
  60466. + /* copy the SPD content 1:1 into the DIMM 1 SPD */
  60467. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
  60468. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  60469. + twsiSlave.validOffset = MV_TRUE;
  60470. + twsiSlave.offset = 0;
  60471. + twsiSlave.moreThen256 = MV_FALSE;
  60472. +
  60473. + for(i = 0 ; i < SPD_SIZE ; i++)
  60474. + {
  60475. + twsiSlave.offset = i;
  60476. + if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, &data[i], 1) )
  60477. + {
  60478. + mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
  60479. + return MV_FAIL;
  60480. + }
  60481. + mvOsDelay(5);
  60482. + }
  60483. +
  60484. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  60485. + return MV_OK;
  60486. +}
  60487. +
  60488. +/*******************************************************************************
  60489. +* dimmSpdGet - Get the SPD parameters.
  60490. +*
  60491. +* DESCRIPTION:
  60492. +* Read the DIMM SPD parameters into given struct parameter.
  60493. +*
  60494. +* INPUT:
  60495. +* dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
  60496. +*
  60497. +* OUTPUT:
  60498. +* pDimmInfo - DIMM information structure.
  60499. +*
  60500. +* RETURN:
  60501. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  60502. +*
  60503. +*******************************************************************************/
  60504. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
  60505. +{
  60506. + MV_U32 i;
  60507. + MV_U32 density = 1;
  60508. + MV_U32 spdChecksum;
  60509. +
  60510. + MV_TWSI_SLAVE twsiSlave;
  60511. + MV_U8 data[SPD_SIZE];
  60512. +
  60513. + if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
  60514. + {
  60515. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  60516. + return MV_BAD_PARAM;
  60517. + }
  60518. +
  60519. + /* zero dimmInfo structure */
  60520. + memset(data, 0, SPD_SIZE);
  60521. +
  60522. + /* read the dimm eeprom */
  60523. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  60524. + twsiSlave.slaveAddr.address = (dimmNum == 0) ?
  60525. + MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
  60526. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  60527. + twsiSlave.validOffset = MV_TRUE;
  60528. + twsiSlave.offset = 0;
  60529. + twsiSlave.moreThen256 = MV_FALSE;
  60530. +
  60531. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
  60532. + {
  60533. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
  60534. + return MV_FAIL;
  60535. + }
  60536. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  60537. +
  60538. + /* calculate SPD checksum */
  60539. + spdChecksum = 0;
  60540. +
  60541. + for(i = 0 ; i <= 62 ; i++)
  60542. + {
  60543. + spdChecksum += data[i];
  60544. + }
  60545. +
  60546. + if ((spdChecksum & 0xff) != data[63])
  60547. + {
  60548. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  60549. + (MV_U32)(spdChecksum & 0xff), data[63]));
  60550. + }
  60551. + else
  60552. + {
  60553. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  60554. + }
  60555. +
  60556. + /* copy the SPD content 1:1 into the dimmInfo structure*/
  60557. + for(i = 0 ; i < SPD_SIZE ; i++)
  60558. + {
  60559. + pDimmInfo->spdRawData[i] = data[i];
  60560. + DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
  60561. + }
  60562. +
  60563. + DB(mvOsPrintf("DRAM SPD Information:\n"));
  60564. +
  60565. + /* Memory type (DDR / SDRAM) */
  60566. + switch (data[DIMM_MEM_TYPE])
  60567. + {
  60568. + case (DIMM_MEM_TYPE_SDRAM):
  60569. + pDimmInfo->memoryType = MEM_TYPE_SDRAM;
  60570. + DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
  60571. + break;
  60572. + case (DIMM_MEM_TYPE_DDR1):
  60573. + pDimmInfo->memoryType = MEM_TYPE_DDR1;
  60574. + DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
  60575. + break;
  60576. + case (DIMM_MEM_TYPE_DDR2):
  60577. + pDimmInfo->memoryType = MEM_TYPE_DDR2;
  60578. + DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
  60579. + break;
  60580. + default:
  60581. + mvOsPrintf("ERROR: Undefined memory type!\n");
  60582. + return MV_ERROR;
  60583. + }
  60584. +
  60585. +
  60586. + /* Number Of Row Addresses */
  60587. + pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
  60588. + DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
  60589. +
  60590. + /* Number Of Column Addresses */
  60591. + pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
  60592. + DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
  60593. +
  60594. + /* Number Of Module Banks */
  60595. + pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
  60596. + DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
  60597. + pDimmInfo->numOfModuleBanks));
  60598. +
  60599. + /* Number of module banks encoded differently for DDR2 */
  60600. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  60601. + pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
  60602. +
  60603. + /* Data Width */
  60604. + pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
  60605. + DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
  60606. +
  60607. + /* Minimum Cycle Time At Max CasLatancy */
  60608. + pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
  60609. +
  60610. + /* Error Check Type */
  60611. + pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
  60612. + DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
  60613. + pDimmInfo->errorCheckType));
  60614. +
  60615. + /* Refresh Interval */
  60616. + pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
  60617. + DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
  60618. + pDimmInfo->refreshInterval));
  60619. +
  60620. + /* Sdram Width */
  60621. + pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
  60622. + DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
  60623. +
  60624. + /* Error Check Data Width */
  60625. + pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
  60626. + DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
  60627. + pDimmInfo->errorCheckDataWidth));
  60628. +
  60629. + /* Burst Length Supported */
  60630. + /* SDRAM/DDR1:
  60631. + *******-******-******-******-******-******-******-*******
  60632. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60633. + *******-******-******-******-******-******-******-*******
  60634. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  60635. + *********************************************************/
  60636. + /* DDR2:
  60637. + *******-******-******-******-******-******-******-*******
  60638. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60639. + *******-******-******-******-******-******-******-*******
  60640. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  60641. + *********************************************************/
  60642. +
  60643. + pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
  60644. + DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
  60645. + pDimmInfo->burstLengthSupported));
  60646. +
  60647. + /* Number Of Banks On Each Device */
  60648. + pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
  60649. + DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
  60650. + pDimmInfo->numOfBanksOnEachDevice));
  60651. +
  60652. + /* Suported Cas Latencies */
  60653. +
  60654. + /* SDRAM:
  60655. + *******-******-******-******-******-******-******-*******
  60656. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60657. + *******-******-******-******-******-******-******-*******
  60658. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  60659. + ********************************************************/
  60660. +
  60661. + /* DDR 1:
  60662. + *******-******-******-******-******-******-******-*******
  60663. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60664. + *******-******-******-******-******-******-******-*******
  60665. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  60666. + *********************************************************/
  60667. +
  60668. + /* DDR 2:
  60669. + *******-******-******-******-******-******-******-*******
  60670. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60671. + *******-******-******-******-******-******-******-*******
  60672. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  60673. + *********************************************************/
  60674. +
  60675. + pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
  60676. + DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
  60677. + pDimmInfo->suportedCasLatencies));
  60678. +
  60679. + /* For DDR2 only, get the DIMM type information */
  60680. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  60681. + {
  60682. + pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
  60683. + DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
  60684. + pDimmInfo->dimmTypeInfo));
  60685. + }
  60686. +
  60687. + /* SDRAM Modules Attributes */
  60688. + pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
  60689. + DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
  60690. + pDimmInfo->dimmAttributes));
  60691. +
  60692. + /* Minimum Cycle Time At Max CasLatancy Minus 1*/
  60693. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  60694. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
  60695. +
  60696. + /* Minimum Cycle Time At Max CasLatancy Minus 2*/
  60697. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  60698. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
  60699. +
  60700. + pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
  60701. + DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
  60702. + pDimmInfo->minRowPrechargeTime));
  60703. + pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
  60704. + DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
  60705. + pDimmInfo->minRowActiveToRowActive));
  60706. + pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
  60707. + DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
  60708. + pDimmInfo->minRasToCasDelay));
  60709. + pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
  60710. + DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
  60711. + pDimmInfo->minRasPulseWidth));
  60712. +
  60713. + /* DIMM Bank Density */
  60714. + pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
  60715. + DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
  60716. + pDimmInfo->dimmBankDensity));
  60717. +
  60718. + /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
  60719. + pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
  60720. + DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
  60721. + pDimmInfo->minWriteRecoveryTime));
  60722. +
  60723. + /* Only DDR2 includes Internal Write To Read Command Delay field. */
  60724. + pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
  60725. + DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
  60726. + pDimmInfo->minWriteToReadCmdDelay));
  60727. +
  60728. + /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
  60729. + pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
  60730. + DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
  60731. + pDimmInfo->minReadToPrechCmdDelay));
  60732. +
  60733. + /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
  60734. + pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
  60735. + DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
  60736. + pDimmInfo->minRefreshToActiveCmd));
  60737. +
  60738. + /* calculating the sdram density. Representing device density from */
  60739. + /* bit 20 to allow representation of 4GB and above. */
  60740. + /* For example, if density is 512Mbit 0x20000000, will be represent in */
  60741. + /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
  60742. + /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
  60743. + density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
  60744. + pDimmInfo->deviceDensity = density *
  60745. + pDimmInfo->numOfBanksOnEachDevice *
  60746. + pDimmInfo->sdramWidth;
  60747. + DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
  60748. +
  60749. + /* Number of devices includeing Error correction */
  60750. + pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
  60751. + pDimmInfo->numOfModuleBanks;
  60752. + DB(mvOsPrintf("DRAM numberOfDevices %d\n",
  60753. + pDimmInfo->numberOfDevices));
  60754. +
  60755. + pDimmInfo->size = 0;
  60756. +
  60757. + /* Note that pDimmInfo->size is in MB units */
  60758. + if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
  60759. + {
  60760. + if (pDimmInfo->dimmBankDensity & BIT0)
  60761. + pDimmInfo->size += 1024; /* Equal to 1GB */
  60762. + else if (pDimmInfo->dimmBankDensity & BIT1)
  60763. + pDimmInfo->size += 8; /* Equal to 8MB */
  60764. + else if (pDimmInfo->dimmBankDensity & BIT2)
  60765. + pDimmInfo->size += 16; /* Equal to 16MB */
  60766. + else if (pDimmInfo->dimmBankDensity & BIT3)
  60767. + pDimmInfo->size += 32; /* Equal to 32MB */
  60768. + else if (pDimmInfo->dimmBankDensity & BIT4)
  60769. + pDimmInfo->size += 64; /* Equal to 64MB */
  60770. + else if (pDimmInfo->dimmBankDensity & BIT5)
  60771. + pDimmInfo->size += 128; /* Equal to 128MB */
  60772. + else if (pDimmInfo->dimmBankDensity & BIT6)
  60773. + pDimmInfo->size += 256; /* Equal to 256MB */
  60774. + else if (pDimmInfo->dimmBankDensity & BIT7)
  60775. + pDimmInfo->size += 512; /* Equal to 512MB */
  60776. + }
  60777. + else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
  60778. + {
  60779. + if (pDimmInfo->dimmBankDensity & BIT0)
  60780. + pDimmInfo->size += 1024; /* Equal to 1GB */
  60781. + else if (pDimmInfo->dimmBankDensity & BIT1)
  60782. + pDimmInfo->size += 2048; /* Equal to 2GB */
  60783. + else if (pDimmInfo->dimmBankDensity & BIT2)
  60784. + pDimmInfo->size += 16; /* Equal to 16MB */
  60785. + else if (pDimmInfo->dimmBankDensity & BIT3)
  60786. + pDimmInfo->size += 32; /* Equal to 32MB */
  60787. + else if (pDimmInfo->dimmBankDensity & BIT4)
  60788. + pDimmInfo->size += 64; /* Equal to 64MB */
  60789. + else if (pDimmInfo->dimmBankDensity & BIT5)
  60790. + pDimmInfo->size += 128; /* Equal to 128MB */
  60791. + else if (pDimmInfo->dimmBankDensity & BIT6)
  60792. + pDimmInfo->size += 256; /* Equal to 256MB */
  60793. + else if (pDimmInfo->dimmBankDensity & BIT7)
  60794. + pDimmInfo->size += 512; /* Equal to 512MB */
  60795. + }
  60796. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  60797. + {
  60798. + if (pDimmInfo->dimmBankDensity & BIT0)
  60799. + pDimmInfo->size += 1024; /* Equal to 1GB */
  60800. + else if (pDimmInfo->dimmBankDensity & BIT1)
  60801. + pDimmInfo->size += 2048; /* Equal to 2GB */
  60802. + else if (pDimmInfo->dimmBankDensity & BIT2)
  60803. + pDimmInfo->size += 4096; /* Equal to 4GB */
  60804. + else if (pDimmInfo->dimmBankDensity & BIT3)
  60805. + pDimmInfo->size += 8192; /* Equal to 8GB */
  60806. + else if (pDimmInfo->dimmBankDensity & BIT4)
  60807. + pDimmInfo->size += 16384; /* Equal to 16GB */
  60808. + else if (pDimmInfo->dimmBankDensity & BIT5)
  60809. + pDimmInfo->size += 128; /* Equal to 128MB */
  60810. + else if (pDimmInfo->dimmBankDensity & BIT6)
  60811. + pDimmInfo->size += 256; /* Equal to 256MB */
  60812. + else if (pDimmInfo->dimmBankDensity & BIT7)
  60813. + pDimmInfo->size += 512; /* Equal to 512MB */
  60814. + }
  60815. +
  60816. + pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
  60817. +
  60818. + DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
  60819. +
  60820. + return MV_OK;
  60821. +}
  60822. +
  60823. +/*******************************************************************************
  60824. +* dimmSpdPrint - Print the SPD parameters.
  60825. +*
  60826. +* DESCRIPTION:
  60827. +* Print the Dimm SPD parameters.
  60828. +*
  60829. +* INPUT:
  60830. +* pDimmInfo - DIMM information structure.
  60831. +*
  60832. +* OUTPUT:
  60833. +* None.
  60834. +*
  60835. +* RETURN:
  60836. +* None.
  60837. +*
  60838. +*******************************************************************************/
  60839. +MV_VOID dimmSpdPrint(MV_U32 dimmNum)
  60840. +{
  60841. + MV_DIMM_INFO dimmInfo;
  60842. + MV_U32 i, temp = 0;
  60843. + MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
  60844. + MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
  60845. + MV_U32 busClkPs;
  60846. + MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
  60847. + temp_buf[40], *spdRawData;
  60848. +
  60849. + busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
  60850. +
  60851. + spdRawData = dimmInfo.spdRawData;
  60852. +
  60853. + if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
  60854. + {
  60855. + mvOsOutput("ERROR: Could not read SPD information!\n");
  60856. + return;
  60857. + }
  60858. +
  60859. + /* find Manufactura of Dimm Module */
  60860. + mvOsOutput("\nManufacturer's JEDEC ID Code: ");
  60861. + for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
  60862. + {
  60863. + mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
  60864. + }
  60865. + mvOsOutput("\n");
  60866. +
  60867. + /* Manufacturer's Specific Data */
  60868. + for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
  60869. + {
  60870. + temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
  60871. + }
  60872. + mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
  60873. +
  60874. + /* Module Part Number */
  60875. + for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
  60876. + {
  60877. + temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
  60878. + }
  60879. + mvOsOutput("Module Part Number: %s\n", temp_buf);
  60880. +
  60881. + /* Module Serial Number */
  60882. + for(i = 0; i < sizeof(MV_U32); i++)
  60883. + {
  60884. + temp |= spdRawData[95+i] << 8*i;
  60885. + }
  60886. + mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
  60887. + (long)temp);
  60888. +
  60889. + /* find Manufac-Data of Dimm Module */
  60890. + mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
  60891. + ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
  60892. + ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
  60893. + /* find modul_revision of Dimm Module */
  60894. + mvOsOutput("Module Revision: %d.%d\n",
  60895. + spdRawData[62]/10, spdRawData[62]%10);
  60896. +
  60897. + /* find manufac_place of Dimm Module */
  60898. + mvOsOutput("manufac_place: %d\n", spdRawData[72]);
  60899. +
  60900. + /* go over the first 35 I2C data bytes */
  60901. + for(i = 2 ; i <= 35 ; i++)
  60902. + switch(i)
  60903. + {
  60904. + case 2: /* Memory type (DDR1/2 / SDRAM) */
  60905. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60906. + mvOsOutput("Dram Type is: SDRAM\n");
  60907. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  60908. + mvOsOutput("Dram Type is: SDRAM DDR1\n");
  60909. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  60910. + mvOsOutput("Dram Type is: SDRAM DDR2\n");
  60911. + else
  60912. + mvOsOutput("Dram Type unknown\n");
  60913. + break;
  60914. +/*----------------------------------------------------------------------------*/
  60915. +
  60916. + case 3: /* Number Of Row Addresses */
  60917. + mvOsOutput("Module Number of row addresses: %d\n",
  60918. + dimmInfo.numOfRowAddr);
  60919. + break;
  60920. +/*----------------------------------------------------------------------------*/
  60921. +
  60922. + case 4: /* Number Of Column Addresses */
  60923. + mvOsOutput("Module Number of col addresses: %d\n",
  60924. + dimmInfo.numOfColAddr);
  60925. + break;
  60926. +/*----------------------------------------------------------------------------*/
  60927. +
  60928. + case 5: /* Number Of Module Banks */
  60929. + mvOsOutput("Number of Banks on Mod.: %d\n",
  60930. + dimmInfo.numOfModuleBanks);
  60931. + break;
  60932. +/*----------------------------------------------------------------------------*/
  60933. +
  60934. + case 6: /* Data Width */
  60935. + mvOsOutput("Module Data Width: %d bit\n",
  60936. + dimmInfo.dataWidth);
  60937. + break;
  60938. +/*----------------------------------------------------------------------------*/
  60939. +
  60940. + case 8: /* Voltage Interface */
  60941. + switch(spdRawData[i])
  60942. + {
  60943. + case 0x0:
  60944. + mvOsOutput("Module is TTL_5V_TOLERANT\n");
  60945. + break;
  60946. + case 0x1:
  60947. + mvOsOutput("Module is LVTTL\n");
  60948. + break;
  60949. + case 0x2:
  60950. + mvOsOutput("Module is HSTL_1_5V\n");
  60951. + break;
  60952. + case 0x3:
  60953. + mvOsOutput("Module is SSTL_3_3V\n");
  60954. + break;
  60955. + case 0x4:
  60956. + mvOsOutput("Module is SSTL_2_5V\n");
  60957. + break;
  60958. + case 0x5:
  60959. + if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
  60960. + {
  60961. + mvOsOutput("Module is SSTL_1_8V\n");
  60962. + break;
  60963. + }
  60964. + default:
  60965. + mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
  60966. + break;
  60967. + }
  60968. + break;
  60969. +/*----------------------------------------------------------------------------*/
  60970. +
  60971. + case 9: /* Minimum Cycle Time At Max CasLatancy */
  60972. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60973. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  60974. +
  60975. + /* DDR2 addition of right of point */
  60976. + if ((spdRawData[i] & 0x0f) == 0xA)
  60977. + {
  60978. + rightOfPoint = 25;
  60979. + }
  60980. + if ((spdRawData[i] & 0x0f) == 0xB)
  60981. + {
  60982. + rightOfPoint = 33;
  60983. + }
  60984. + if ((spdRawData[i] & 0x0f) == 0xC)
  60985. + {
  60986. + rightOfPoint = 66;
  60987. + }
  60988. + if ((spdRawData[i] & 0x0f) == 0xD)
  60989. + {
  60990. + rightOfPoint = 75;
  60991. + }
  60992. + mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
  60993. + leftOfPoint, rightOfPoint);
  60994. + break;
  60995. +/*----------------------------------------------------------------------------*/
  60996. +
  60997. + case 10: /* Clock To Data Out */
  60998. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
  60999. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  61000. + ((spdRawData[i] & 0x0f));
  61001. + leftOfPoint = time_tmp / div;
  61002. + rightOfPoint = time_tmp % div;
  61003. + mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
  61004. + leftOfPoint, rightOfPoint);
  61005. + break;
  61006. +/*----------------------------------------------------------------------------*/
  61007. +
  61008. + case 11: /* Error Check Type */
  61009. + mvOsOutput("Error Check Type (0=NONE): %d\n",
  61010. + dimmInfo.errorCheckType);
  61011. + break;
  61012. +/*----------------------------------------------------------------------------*/
  61013. +
  61014. + case 12: /* Refresh Interval */
  61015. + mvOsOutput("Refresh Rate: %x\n",
  61016. + dimmInfo.refreshInterval);
  61017. + break;
  61018. +/*----------------------------------------------------------------------------*/
  61019. +
  61020. + case 13: /* Sdram Width */
  61021. + mvOsOutput("Sdram Width: %d bits\n",
  61022. + dimmInfo.sdramWidth);
  61023. + break;
  61024. +/*----------------------------------------------------------------------------*/
  61025. +
  61026. + case 14: /* Error Check Data Width */
  61027. + mvOsOutput("Error Check Data Width: %d bits\n",
  61028. + dimmInfo.errorCheckDataWidth);
  61029. + break;
  61030. +/*----------------------------------------------------------------------------*/
  61031. +
  61032. + case 15: /* Minimum Clock Delay is unsupported */
  61033. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  61034. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  61035. + {
  61036. + mvOsOutput("Minimum Clk Delay back to back: %d\n",
  61037. + spdRawData[i]);
  61038. + }
  61039. + break;
  61040. +/*----------------------------------------------------------------------------*/
  61041. +
  61042. + case 16: /* Burst Length Supported */
  61043. + /* SDRAM/DDR1:
  61044. + *******-******-******-******-******-******-******-*******
  61045. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61046. + *******-******-******-******-******-******-******-*******
  61047. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  61048. + *********************************************************/
  61049. + /* DDR2:
  61050. + *******-******-******-******-******-******-******-*******
  61051. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61052. + *******-******-******-******-******-******-******-*******
  61053. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  61054. + *********************************************************/
  61055. + mvOsOutput("Burst Length Supported: ");
  61056. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  61057. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  61058. + {
  61059. + if (dimmInfo.burstLengthSupported & BIT0)
  61060. + mvOsOutput("1, ");
  61061. + if (dimmInfo.burstLengthSupported & BIT1)
  61062. + mvOsOutput("2, ");
  61063. + }
  61064. + if (dimmInfo.burstLengthSupported & BIT2)
  61065. + mvOsOutput("4, ");
  61066. + if (dimmInfo.burstLengthSupported & BIT3)
  61067. + mvOsOutput("8, ");
  61068. +
  61069. + mvOsOutput(" Bit \n");
  61070. + break;
  61071. +/*----------------------------------------------------------------------------*/
  61072. +
  61073. + case 17: /* Number Of Banks On Each Device */
  61074. + mvOsOutput("Number Of Banks On Each Chip: %d\n",
  61075. + dimmInfo.numOfBanksOnEachDevice);
  61076. + break;
  61077. +/*----------------------------------------------------------------------------*/
  61078. +
  61079. + case 18: /* Suported Cas Latencies */
  61080. +
  61081. + /* SDRAM:
  61082. + *******-******-******-******-******-******-******-*******
  61083. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61084. + *******-******-******-******-******-******-******-*******
  61085. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  61086. + ********************************************************/
  61087. +
  61088. + /* DDR 1:
  61089. + *******-******-******-******-******-******-******-*******
  61090. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61091. + *******-******-******-******-******-******-******-*******
  61092. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  61093. + *********************************************************/
  61094. +
  61095. + /* DDR 2:
  61096. + *******-******-******-******-******-******-******-*******
  61097. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61098. + *******-******-******-******-******-******-******-*******
  61099. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  61100. + *********************************************************/
  61101. +
  61102. + mvOsOutput("Suported Cas Latencies: (CL) ");
  61103. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61104. + {
  61105. + for (k = 0; k <=7; k++)
  61106. + {
  61107. + if (dimmInfo.suportedCasLatencies & (1 << k))
  61108. + mvOsOutput("%d, ", k+1);
  61109. + }
  61110. + }
  61111. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  61112. + {
  61113. + if (dimmInfo.suportedCasLatencies & BIT0)
  61114. + mvOsOutput("1, ");
  61115. + if (dimmInfo.suportedCasLatencies & BIT1)
  61116. + mvOsOutput("1.5, ");
  61117. + if (dimmInfo.suportedCasLatencies & BIT2)
  61118. + mvOsOutput("2, ");
  61119. + if (dimmInfo.suportedCasLatencies & BIT3)
  61120. + mvOsOutput("2.5, ");
  61121. + if (dimmInfo.suportedCasLatencies & BIT4)
  61122. + mvOsOutput("3, ");
  61123. + if (dimmInfo.suportedCasLatencies & BIT5)
  61124. + mvOsOutput("3.5, ");
  61125. + }
  61126. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  61127. + {
  61128. + if (dimmInfo.suportedCasLatencies & BIT2)
  61129. + mvOsOutput("2, ");
  61130. + if (dimmInfo.suportedCasLatencies & BIT3)
  61131. + mvOsOutput("3, ");
  61132. + if (dimmInfo.suportedCasLatencies & BIT4)
  61133. + mvOsOutput("4, ");
  61134. + if (dimmInfo.suportedCasLatencies & BIT5)
  61135. + mvOsOutput("5, ");
  61136. + }
  61137. + else
  61138. + mvOsOutput("?.?, ");
  61139. + mvOsOutput("\n");
  61140. + break;
  61141. +/*----------------------------------------------------------------------------*/
  61142. +
  61143. + case 20: /* DDR2 DIMM type info */
  61144. + if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  61145. + {
  61146. + if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
  61147. + mvOsOutput("Registered DIMM (RDIMM)\n");
  61148. + else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
  61149. + mvOsOutput("Unbuffered DIMM (UDIMM)\n");
  61150. + else
  61151. + mvOsOutput("Unknown DIMM type.\n");
  61152. + }
  61153. +
  61154. + break;
  61155. +/*----------------------------------------------------------------------------*/
  61156. +
  61157. + case 21: /* SDRAM Modules Attributes */
  61158. + mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
  61159. +
  61160. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61161. + {
  61162. + if (dimmInfo.dimmAttributes & BIT0)
  61163. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  61164. + else
  61165. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  61166. +
  61167. + if (dimmInfo.dimmAttributes & BIT1)
  61168. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  61169. + else
  61170. + mvOsOutput(" Registered Addr/Control Input: No\n");
  61171. +
  61172. + if (dimmInfo.dimmAttributes & BIT2)
  61173. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  61174. + else
  61175. + mvOsOutput(" On-Card PLL (clock): No \n");
  61176. +
  61177. + if (dimmInfo.dimmAttributes & BIT3)
  61178. + mvOsOutput(" Bufferd DQMB Input: Yes \n");
  61179. + else
  61180. + mvOsOutput(" Bufferd DQMB Inputs: No \n");
  61181. +
  61182. + if (dimmInfo.dimmAttributes & BIT4)
  61183. + mvOsOutput(" Registered DQMB Inputs: Yes \n");
  61184. + else
  61185. + mvOsOutput(" Registered DQMB Inputs: No \n");
  61186. +
  61187. + if (dimmInfo.dimmAttributes & BIT5)
  61188. + mvOsOutput(" Differential Clock Input: Yes \n");
  61189. + else
  61190. + mvOsOutput(" Differential Clock Input: No \n");
  61191. +
  61192. + if (dimmInfo.dimmAttributes & BIT6)
  61193. + mvOsOutput(" redundant Row Addressing: Yes \n");
  61194. + else
  61195. + mvOsOutput(" redundant Row Addressing: No \n");
  61196. + }
  61197. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  61198. + {
  61199. + if (dimmInfo.dimmAttributes & BIT0)
  61200. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  61201. + else
  61202. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  61203. +
  61204. + if (dimmInfo.dimmAttributes & BIT1)
  61205. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  61206. + else
  61207. + mvOsOutput(" Registered Addr/Control Input: No\n");
  61208. +
  61209. + if (dimmInfo.dimmAttributes & BIT2)
  61210. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  61211. + else
  61212. + mvOsOutput(" On-Card PLL (clock): No \n");
  61213. +
  61214. + if (dimmInfo.dimmAttributes & BIT3)
  61215. + mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
  61216. + else
  61217. + mvOsOutput(" FET Switch On-Card Enabled: No \n");
  61218. +
  61219. + if (dimmInfo.dimmAttributes & BIT4)
  61220. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  61221. + else
  61222. + mvOsOutput(" FET Switch External Enabled: No \n");
  61223. +
  61224. + if (dimmInfo.dimmAttributes & BIT5)
  61225. + mvOsOutput(" Differential Clock Input: Yes \n");
  61226. + else
  61227. + mvOsOutput(" Differential Clock Input: No \n");
  61228. + }
  61229. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  61230. + {
  61231. + mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
  61232. + (dimmInfo.dimmAttributes & 0x3) + 1);
  61233. +
  61234. + mvOsOutput(" Number of PLLs on the DIMM: %d\n",
  61235. + ((dimmInfo.dimmAttributes) >> 2) & 0x3);
  61236. +
  61237. + if (dimmInfo.dimmAttributes & BIT4)
  61238. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  61239. + else
  61240. + mvOsOutput(" FET Switch External Enabled: No \n");
  61241. +
  61242. + if (dimmInfo.dimmAttributes & BIT6)
  61243. + mvOsOutput(" Analysis probe installed: Yes \n");
  61244. + else
  61245. + mvOsOutput(" Analysis probe installed: No \n");
  61246. + }
  61247. +
  61248. + break;
  61249. +/*----------------------------------------------------------------------------*/
  61250. +
  61251. + case 22: /* Suported AutoPreCharge */
  61252. + mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
  61253. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61254. + {
  61255. + if ( spdRawData[i] & BIT0 )
  61256. + mvOsOutput(" Early Ras Precharge: Yes \n");
  61257. + else
  61258. + mvOsOutput(" Early Ras Precharge: No \n");
  61259. +
  61260. + if ( spdRawData[i] & BIT1 )
  61261. + mvOsOutput(" AutoPreCharge: Yes \n");
  61262. + else
  61263. + mvOsOutput(" AutoPreCharge: No \n");
  61264. +
  61265. + if ( spdRawData[i] & BIT2 )
  61266. + mvOsOutput(" Precharge All: Yes \n");
  61267. + else
  61268. + mvOsOutput(" Precharge All: No \n");
  61269. +
  61270. + if ( spdRawData[i] & BIT3 )
  61271. + mvOsOutput(" Write 1/ReadBurst: Yes \n");
  61272. + else
  61273. + mvOsOutput(" Write 1/ReadBurst: No \n");
  61274. +
  61275. + if ( spdRawData[i] & BIT4 )
  61276. + mvOsOutput(" lower VCC tolerance: 5%%\n");
  61277. + else
  61278. + mvOsOutput(" lower VCC tolerance: 10%%\n");
  61279. +
  61280. + if ( spdRawData[i] & BIT5 )
  61281. + mvOsOutput(" upper VCC tolerance: 5%%\n");
  61282. + else
  61283. + mvOsOutput(" upper VCC tolerance: 10%%\n");
  61284. + }
  61285. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  61286. + {
  61287. + if ( spdRawData[i] & BIT0 )
  61288. + mvOsOutput(" Supports Weak Driver: Yes \n");
  61289. + else
  61290. + mvOsOutput(" Supports Weak Driver: No \n");
  61291. +
  61292. + if ( !(spdRawData[i] & BIT4) )
  61293. + mvOsOutput(" lower VCC tolerance: 0.2V\n");
  61294. +
  61295. + if ( !(spdRawData[i] & BIT5) )
  61296. + mvOsOutput(" upper VCC tolerance: 0.2V\n");
  61297. +
  61298. + if ( spdRawData[i] & BIT6 )
  61299. + mvOsOutput(" Concurrent Auto Preharge: Yes \n");
  61300. + else
  61301. + mvOsOutput(" Concurrent Auto Preharge: No \n");
  61302. +
  61303. + if ( spdRawData[i] & BIT7 )
  61304. + mvOsOutput(" Supports Fast AP: Yes \n");
  61305. + else
  61306. + mvOsOutput(" Supports Fast AP: No \n");
  61307. + }
  61308. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  61309. + {
  61310. + if ( spdRawData[i] & BIT0 )
  61311. + mvOsOutput(" Supports Weak Driver: Yes \n");
  61312. + else
  61313. + mvOsOutput(" Supports Weak Driver: No \n");
  61314. + }
  61315. + break;
  61316. +/*----------------------------------------------------------------------------*/
  61317. +
  61318. + case 23:
  61319. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
  61320. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  61321. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  61322. +
  61323. + /* DDR2 addition of right of point */
  61324. + if ((spdRawData[i] & 0x0f) == 0xA)
  61325. + {
  61326. + rightOfPoint = 25;
  61327. + }
  61328. + if ((spdRawData[i] & 0x0f) == 0xB)
  61329. + {
  61330. + rightOfPoint = 33;
  61331. + }
  61332. + if ((spdRawData[i] & 0x0f) == 0xC)
  61333. + {
  61334. + rightOfPoint = 66;
  61335. + }
  61336. + if ((spdRawData[i] & 0x0f) == 0xD)
  61337. + {
  61338. + rightOfPoint = 75;
  61339. + }
  61340. +
  61341. + mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
  61342. + "(0 = Not supported): %d.%d [ns]\n",
  61343. + leftOfPoint, rightOfPoint );
  61344. + break;
  61345. +/*----------------------------------------------------------------------------*/
  61346. +
  61347. + case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
  61348. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
  61349. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  61350. + ((spdRawData[i] & 0x0f));
  61351. + leftOfPoint = time_tmp / div;
  61352. + rightOfPoint = time_tmp % div;
  61353. + mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
  61354. + leftOfPoint, rightOfPoint);
  61355. + break;
  61356. +/*----------------------------------------------------------------------------*/
  61357. +
  61358. + case 25:
  61359. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
  61360. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61361. + {
  61362. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  61363. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  61364. + }
  61365. + else /* DDR1 or DDR2 */
  61366. + {
  61367. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  61368. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  61369. +
  61370. + /* DDR2 addition of right of point */
  61371. + if ((spdRawData[i] & 0x0f) == 0xA)
  61372. + {
  61373. + rightOfPoint = 25;
  61374. + }
  61375. + if ((spdRawData[i] & 0x0f) == 0xB)
  61376. + {
  61377. + rightOfPoint = 33;
  61378. + }
  61379. + if ((spdRawData[i] & 0x0f) == 0xC)
  61380. + {
  61381. + rightOfPoint = 66;
  61382. + }
  61383. + if ((spdRawData[i] & 0x0f) == 0xD)
  61384. + {
  61385. + rightOfPoint = 75;
  61386. + }
  61387. + }
  61388. + mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
  61389. + "(0 = Not supported): %d.%d [ns]\n",
  61390. + leftOfPoint, rightOfPoint );
  61391. + break;
  61392. +/*----------------------------------------------------------------------------*/
  61393. +
  61394. + case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
  61395. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61396. + {
  61397. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  61398. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  61399. + }
  61400. + else /* DDR1 or DDR2 */
  61401. + {
  61402. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  61403. + ((spdRawData[i] & 0x0f));
  61404. + leftOfPoint = 0;
  61405. + rightOfPoint = time_tmp;
  61406. + }
  61407. + mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
  61408. + leftOfPoint, rightOfPoint );
  61409. + break;
  61410. +/*----------------------------------------------------------------------------*/
  61411. +
  61412. + case 27: /* Minimum Row Precharge Time */
  61413. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  61414. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  61415. + 0xff : 0xfc;
  61416. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  61417. + 0x00 : 0x03;
  61418. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  61419. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  61420. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
  61421. + trp_clocks = (temp + (busClkPs-1)) / busClkPs;
  61422. + mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
  61423. + "in Clk cycles %d\n",
  61424. + leftOfPoint, rightOfPoint, trp_clocks);
  61425. + break;
  61426. +/*----------------------------------------------------------------------------*/
  61427. +
  61428. + case 28: /* Minimum Row Active to Row Active Time */
  61429. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  61430. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  61431. + 0xff : 0xfc;
  61432. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  61433. + 0x00 : 0x03;
  61434. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  61435. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  61436. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  61437. + trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
  61438. + mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
  61439. + "%d.%d = in Clk cycles %d\n",
  61440. + leftOfPoint, rightOfPoint, trp_clocks);
  61441. + break;
  61442. +/*----------------------------------------------------------------------------*/
  61443. +
  61444. + case 29: /* Minimum Ras-To-Cas Delay */
  61445. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  61446. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  61447. + 0xff : 0xfc;
  61448. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  61449. + 0x00 : 0x03;
  61450. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  61451. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  61452. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  61453. + trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
  61454. + mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
  61455. + "in Clk cycles %d\n",
  61456. + leftOfPoint, rightOfPoint, trp_clocks);
  61457. + break;
  61458. +/*----------------------------------------------------------------------------*/
  61459. +
  61460. + case 30: /* Minimum Ras Pulse Width */
  61461. + tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
  61462. + mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
  61463. + "in Clk cycles %d\n", spdRawData[i], tras_clocks);
  61464. + break;
  61465. +/*----------------------------------------------------------------------------*/
  61466. +
  61467. + case 31: /* Module Bank Density */
  61468. + mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
  61469. +
  61470. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61471. + {
  61472. + if (dimmInfo.dimmBankDensity & BIT0)
  61473. + mvOsOutput("1GB, ");
  61474. + if (dimmInfo.dimmBankDensity & BIT1)
  61475. + mvOsOutput("8MB, ");
  61476. + if (dimmInfo.dimmBankDensity & BIT2)
  61477. + mvOsOutput("16MB, ");
  61478. + if (dimmInfo.dimmBankDensity & BIT3)
  61479. + mvOsOutput("32MB, ");
  61480. + if (dimmInfo.dimmBankDensity & BIT4)
  61481. + mvOsOutput("64MB, ");
  61482. + if (dimmInfo.dimmBankDensity & BIT5)
  61483. + mvOsOutput("128MB, ");
  61484. + if (dimmInfo.dimmBankDensity & BIT6)
  61485. + mvOsOutput("256MB, ");
  61486. + if (dimmInfo.dimmBankDensity & BIT7)
  61487. + mvOsOutput("512MB, ");
  61488. + }
  61489. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  61490. + {
  61491. + if (dimmInfo.dimmBankDensity & BIT0)
  61492. + mvOsOutput("1GB, ");
  61493. + if (dimmInfo.dimmBankDensity & BIT1)
  61494. + mvOsOutput("2GB, ");
  61495. + if (dimmInfo.dimmBankDensity & BIT2)
  61496. + mvOsOutput("16MB, ");
  61497. + if (dimmInfo.dimmBankDensity & BIT3)
  61498. + mvOsOutput("32MB, ");
  61499. + if (dimmInfo.dimmBankDensity & BIT4)
  61500. + mvOsOutput("64MB, ");
  61501. + if (dimmInfo.dimmBankDensity & BIT5)
  61502. + mvOsOutput("128MB, ");
  61503. + if (dimmInfo.dimmBankDensity & BIT6)
  61504. + mvOsOutput("256MB, ");
  61505. + if (dimmInfo.dimmBankDensity & BIT7)
  61506. + mvOsOutput("512MB, ");
  61507. + }
  61508. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  61509. + {
  61510. + if (dimmInfo.dimmBankDensity & BIT0)
  61511. + mvOsOutput("1GB, ");
  61512. + if (dimmInfo.dimmBankDensity & BIT1)
  61513. + mvOsOutput("2GB, ");
  61514. + if (dimmInfo.dimmBankDensity & BIT2)
  61515. + mvOsOutput("4GB, ");
  61516. + if (dimmInfo.dimmBankDensity & BIT3)
  61517. + mvOsOutput("8GB, ");
  61518. + if (dimmInfo.dimmBankDensity & BIT4)
  61519. + mvOsOutput("16GB, ");
  61520. + if (dimmInfo.dimmBankDensity & BIT5)
  61521. + mvOsOutput("128MB, ");
  61522. + if (dimmInfo.dimmBankDensity & BIT6)
  61523. + mvOsOutput("256MB, ");
  61524. + if (dimmInfo.dimmBankDensity & BIT7)
  61525. + mvOsOutput("512MB, ");
  61526. + }
  61527. + mvOsOutput("\n");
  61528. + break;
  61529. +/*----------------------------------------------------------------------------*/
  61530. +
  61531. + case 32: /* Address And Command Setup Time (measured in ns/1000) */
  61532. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61533. + {
  61534. + rightOfPoint = (spdRawData[i] & 0x0f);
  61535. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  61536. + if(leftOfPoint > 7)
  61537. + {
  61538. + leftOfPoint *= -1;
  61539. + }
  61540. + }
  61541. + else /* DDR1 or DDR2 */
  61542. + {
  61543. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  61544. + ((spdRawData[i] & 0x0f));
  61545. + leftOfPoint = time_tmp / 100;
  61546. + rightOfPoint = time_tmp % 100;
  61547. + }
  61548. + mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
  61549. + leftOfPoint, rightOfPoint);
  61550. + break;
  61551. +/*----------------------------------------------------------------------------*/
  61552. +
  61553. + case 33: /* Address And Command Hold Time */
  61554. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61555. + {
  61556. + rightOfPoint = (spdRawData[i] & 0x0f);
  61557. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  61558. + if(leftOfPoint > 7)
  61559. + {
  61560. + leftOfPoint *= -1;
  61561. + }
  61562. + }
  61563. + else /* DDR1 or DDR2 */
  61564. + {
  61565. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  61566. + ((spdRawData[i] & 0x0f));
  61567. + leftOfPoint = time_tmp / 100;
  61568. + rightOfPoint = time_tmp % 100;
  61569. + }
  61570. + mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
  61571. + leftOfPoint, rightOfPoint);
  61572. + break;
  61573. +/*----------------------------------------------------------------------------*/
  61574. +
  61575. + case 34: /* Data Input Setup Time */
  61576. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61577. + {
  61578. + rightOfPoint = (spdRawData[i] & 0x0f);
  61579. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  61580. + if(leftOfPoint > 7)
  61581. + {
  61582. + leftOfPoint *= -1;
  61583. + }
  61584. + }
  61585. + else /* DDR1 or DDR2 */
  61586. + {
  61587. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  61588. + ((spdRawData[i] & 0x0f));
  61589. + leftOfPoint = time_tmp / 100;
  61590. + rightOfPoint = time_tmp % 100;
  61591. + }
  61592. + mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
  61593. + leftOfPoint, rightOfPoint);
  61594. + break;
  61595. +/*----------------------------------------------------------------------------*/
  61596. +
  61597. + case 35: /* Data Input Hold Time */
  61598. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61599. + {
  61600. + rightOfPoint = (spdRawData[i] & 0x0f);
  61601. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  61602. + if(leftOfPoint > 7)
  61603. + {
  61604. + leftOfPoint *= -1;
  61605. + }
  61606. + }
  61607. + else /* DDR1 or DDR2 */
  61608. + {
  61609. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  61610. + ((spdRawData[i] & 0x0f));
  61611. + leftOfPoint = time_tmp / 100;
  61612. + rightOfPoint = time_tmp % 100;
  61613. + }
  61614. + mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
  61615. + leftOfPoint, rightOfPoint);
  61616. + break;
  61617. +/*----------------------------------------------------------------------------*/
  61618. +
  61619. + case 36: /* Relevant for DDR2 only: Write Recovery Time */
  61620. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
  61621. + rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
  61622. + mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
  61623. + leftOfPoint, rightOfPoint);
  61624. + break;
  61625. +/*----------------------------------------------------------------------------*/
  61626. + }
  61627. +
  61628. +}
  61629. +
  61630. +
  61631. +/*
  61632. + * translate ns.ns/10 coding of SPD timing values
  61633. + * into ps unit values
  61634. + */
  61635. +/*******************************************************************************
  61636. +* cas2ps - Translate x.y ns parameter to pico-seconds values
  61637. +*
  61638. +* DESCRIPTION:
  61639. +* This function translates x.y nano seconds to its value in pico seconds.
  61640. +* For example 3.75ns will return 3750.
  61641. +*
  61642. +* INPUT:
  61643. +* spd_byte - DIMM SPD byte.
  61644. +*
  61645. +* OUTPUT:
  61646. +* None.
  61647. +*
  61648. +* RETURN:
  61649. +* value in pico seconds.
  61650. +*
  61651. +*******************************************************************************/
  61652. +static MV_U32 cas2ps(MV_U8 spd_byte)
  61653. +{
  61654. + MV_U32 ns, ns10;
  61655. +
  61656. + /* isolate upper nibble */
  61657. + ns = (spd_byte >> 4) & 0x0F;
  61658. + /* isolate lower nibble */
  61659. + ns10 = (spd_byte & 0x0F);
  61660. +
  61661. + if( ns10 < 10 ) {
  61662. + ns10 *= 10;
  61663. + }
  61664. + else if( ns10 == 10 )
  61665. + ns10 = 25;
  61666. + else if( ns10 == 11 )
  61667. + ns10 = 33;
  61668. + else if( ns10 == 12 )
  61669. + ns10 = 66;
  61670. + else if( ns10 == 13 )
  61671. + ns10 = 75;
  61672. + else
  61673. + {
  61674. + mvOsOutput("cas2ps Err. unsupported cycle time.\n");
  61675. + }
  61676. +
  61677. + return (ns*1000 + ns10*10);
  61678. +}
  61679. +
  61680. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h
  61681. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h 1970-01-01 01:00:00.000000000 +0100
  61682. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h 2011-07-31 11:32:00.073415544 +0200
  61683. @@ -0,0 +1,192 @@
  61684. +/*******************************************************************************
  61685. +Copyright (C) Marvell International Ltd. and its affiliates
  61686. +
  61687. +This software file (the "File") is owned and distributed by Marvell
  61688. +International Ltd. and/or its affiliates ("Marvell") under the following
  61689. +alternative licensing terms. Once you have made an election to distribute the
  61690. +File under one of the following license alternatives, please (i) delete this
  61691. +introductory statement regarding license alternatives, (ii) delete the two
  61692. +license alternatives that you have not elected to use and (iii) preserve the
  61693. +Marvell copyright notice above.
  61694. +
  61695. +********************************************************************************
  61696. +Marvell Commercial License Option
  61697. +
  61698. +If you received this File from Marvell and you have entered into a commercial
  61699. +license agreement (a "Commercial License") with Marvell, the File is licensed
  61700. +to you under the terms of the applicable Commercial License.
  61701. +
  61702. +********************************************************************************
  61703. +Marvell GPL License Option
  61704. +
  61705. +If you received this File from Marvell, you may opt to use, redistribute and/or
  61706. +modify this File in accordance with the terms and conditions of the General
  61707. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  61708. +available along with the File in the license.txt file or by writing to the Free
  61709. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  61710. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  61711. +
  61712. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  61713. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  61714. +DISCLAIMED. The GPL License provides additional details about this warranty
  61715. +disclaimer.
  61716. +********************************************************************************
  61717. +Marvell BSD License Option
  61718. +
  61719. +If you received this File from Marvell, you may opt to use, redistribute and/or
  61720. +modify this File under the following licensing terms.
  61721. +Redistribution and use in source and binary forms, with or without modification,
  61722. +are permitted provided that the following conditions are met:
  61723. +
  61724. + * Redistributions of source code must retain the above copyright notice,
  61725. + this list of conditions and the following disclaimer.
  61726. +
  61727. + * Redistributions in binary form must reproduce the above copyright
  61728. + notice, this list of conditions and the following disclaimer in the
  61729. + documentation and/or other materials provided with the distribution.
  61730. +
  61731. + * Neither the name of Marvell nor the names of its contributors may be
  61732. + used to endorse or promote products derived from this software without
  61733. + specific prior written permission.
  61734. +
  61735. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  61736. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  61737. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  61738. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  61739. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  61740. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  61741. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  61742. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  61743. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  61744. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  61745. +
  61746. +*******************************************************************************/
  61747. +
  61748. +#ifndef __INCmvDram
  61749. +#define __INCmvDram
  61750. +
  61751. +#include "ddr2/mvDramIf.h"
  61752. +#include "twsi/mvTwsi.h"
  61753. +
  61754. +#define MAX_DIMM_NUM 2
  61755. +#define SPD_SIZE 128
  61756. +
  61757. +/* Dimm spd offsets */
  61758. +#define DIMM_MEM_TYPE 2
  61759. +#define DIMM_ROW_NUM 3
  61760. +#define DIMM_COL_NUM 4
  61761. +#define DIMM_MODULE_BANK_NUM 5
  61762. +#define DIMM_DATA_WIDTH 6
  61763. +#define DIMM_VOLT_IF 8
  61764. +#define DIMM_MIN_CC_AT_MAX_CAS 9
  61765. +#define DIMM_ERR_CHECK_TYPE 11
  61766. +#define DIMM_REFRESH_INTERVAL 12
  61767. +#define DIMM_SDRAM_WIDTH 13
  61768. +#define DIMM_ERR_CHECK_DATA_WIDTH 14
  61769. +#define DIMM_MIN_CLK_DEL 15
  61770. +#define DIMM_BURST_LEN_SUP 16
  61771. +#define DIMM_DEV_BANK_NUM 17
  61772. +#define DIMM_SUP_CAL 18
  61773. +#define DIMM_DDR2_TYPE_INFORMATION 20 /* DDR2 only */
  61774. +#define DIMM_BUF_ADDR_CONT_IN 21
  61775. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1 23
  61776. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2 25
  61777. +#define DIMM_MIN_ROW_PRECHARGE_TIME 27
  61778. +#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE 28
  61779. +#define DIMM_MIN_RAS_TO_CAS_DELAY 29
  61780. +#define DIMM_MIN_RAS_PULSE_WIDTH 30
  61781. +#define DIMM_BANK_DENSITY 31
  61782. +#define DIMM_MIN_WRITE_RECOVERY_TIME 36
  61783. +#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY 37
  61784. +#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY 38
  61785. +#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD 42
  61786. +#define DIMM_SPD_VERSION 62
  61787. +
  61788. +/* Dimm Memory Type values */
  61789. +#define DIMM_MEM_TYPE_SDRAM 0x4
  61790. +#define DIMM_MEM_TYPE_DDR1 0x7
  61791. +#define DIMM_MEM_TYPE_DDR2 0x8
  61792. +
  61793. +#define DIMM_MODULE_MANU_OFFS 64
  61794. +#define DIMM_MODULE_MANU_SIZE 8
  61795. +#define DIMM_MODULE_VEN_OFFS 73
  61796. +#define DIMM_MODULE_VEN_SIZE 25
  61797. +#define DIMM_MODULE_ID_OFFS 99
  61798. +#define DIMM_MODULE_ID_SIZE 18
  61799. +
  61800. +/* enumeration for voltage levels. */
  61801. +typedef enum _mvDimmVoltageIf
  61802. +{
  61803. + TTL_5V_TOLERANT,
  61804. + LVTTL,
  61805. + HSTL_1_5V,
  61806. + SSTL_3_3V,
  61807. + SSTL_2_5V,
  61808. + VOLTAGE_UNKNOWN,
  61809. +} MV_DIMM_VOLTAGE_IF;
  61810. +
  61811. +
  61812. +/* enumaration for SDRAM CAS Latencies. */
  61813. +typedef enum _mvDimmSdramCas
  61814. +{
  61815. + SD_CL_1 =1,
  61816. + SD_CL_2,
  61817. + SD_CL_3,
  61818. + SD_CL_4,
  61819. + SD_CL_5,
  61820. + SD_CL_6,
  61821. + SD_CL_7,
  61822. + SD_FAULT
  61823. +}MV_DIMM_SDRAM_CAS;
  61824. +
  61825. +
  61826. +/* DIMM information structure */
  61827. +typedef struct _mvDimmInfo
  61828. +{
  61829. + MV_MEMORY_TYPE memoryType; /* DDR or SDRAM */
  61830. +
  61831. + MV_U8 spdRawData[SPD_SIZE]; /* Content of SPD-EEPROM copied 1:1 */
  61832. +
  61833. + /* DIMM dimensions */
  61834. + MV_U32 numOfRowAddr;
  61835. + MV_U32 numOfColAddr;
  61836. + MV_U32 numOfModuleBanks;
  61837. + MV_U32 dataWidth;
  61838. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  61839. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  61840. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  61841. + MV_U32 burstLengthSupported;
  61842. + MV_U32 numOfBanksOnEachDevice;
  61843. + MV_U32 suportedCasLatencies;
  61844. + MV_U32 refreshInterval;
  61845. + MV_U32 dimmBankDensity;
  61846. + MV_U32 dimmTypeInfo; /* DDR2 only */
  61847. + MV_U32 dimmAttributes;
  61848. +
  61849. + /* DIMM timing parameters */
  61850. + MV_U32 minCycleTimeAtMaxCasLatPs;
  61851. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  61852. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  61853. + MV_U32 minRowPrechargeTime;
  61854. + MV_U32 minRowActiveToRowActive;
  61855. + MV_U32 minRasToCasDelay;
  61856. + MV_U32 minRasPulseWidth;
  61857. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  61858. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  61859. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  61860. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  61861. +
  61862. + /* Parameters calculated from the extracted DIMM information */
  61863. + MV_U32 size; /* 16,64,128,256 or 512 MByte in MB units */
  61864. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit in MB units */
  61865. + MV_U32 numberOfDevices;
  61866. +
  61867. +} MV_DIMM_INFO;
  61868. +
  61869. +
  61870. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);
  61871. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);
  61872. +MV_VOID dimmSpdPrint(MV_U32 dimmNum);
  61873. +MV_STATUS dimmSpdCpy(MV_VOID);
  61874. +
  61875. +#endif /* __INCmvDram */
  61876. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c
  61877. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c 1970-01-01 01:00:00.000000000 +0100
  61878. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c 2011-07-31 11:32:00.094444907 +0200
  61879. @@ -0,0 +1,2952 @@
  61880. +/*******************************************************************************
  61881. +Copyright (C) Marvell International Ltd. and its affiliates
  61882. +
  61883. +This software file (the "File") is owned and distributed by Marvell
  61884. +International Ltd. and/or its affiliates ("Marvell") under the following
  61885. +alternative licensing terms. Once you have made an election to distribute the
  61886. +File under one of the following license alternatives, please (i) delete this
  61887. +introductory statement regarding license alternatives, (ii) delete the two
  61888. +license alternatives that you have not elected to use and (iii) preserve the
  61889. +Marvell copyright notice above.
  61890. +
  61891. +********************************************************************************
  61892. +Marvell Commercial License Option
  61893. +
  61894. +If you received this File from Marvell and you have entered into a commercial
  61895. +license agreement (a "Commercial License") with Marvell, the File is licensed
  61896. +to you under the terms of the applicable Commercial License.
  61897. +
  61898. +********************************************************************************
  61899. +Marvell GPL License Option
  61900. +
  61901. +If you received this File from Marvell, you may opt to use, redistribute and/or
  61902. +modify this File in accordance with the terms and conditions of the General
  61903. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  61904. +available along with the File in the license.txt file or by writing to the Free
  61905. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  61906. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  61907. +
  61908. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  61909. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  61910. +DISCLAIMED. The GPL License provides additional details about this warranty
  61911. +disclaimer.
  61912. +********************************************************************************
  61913. +Marvell BSD License Option
  61914. +
  61915. +If you received this File from Marvell, you may opt to use, redistribute and/or
  61916. +modify this File under the following licensing terms.
  61917. +Redistribution and use in source and binary forms, with or without modification,
  61918. +are permitted provided that the following conditions are met:
  61919. +
  61920. + * Redistributions of source code must retain the above copyright notice,
  61921. + this list of conditions and the following disclaimer.
  61922. +
  61923. + * Redistributions in binary form must reproduce the above copyright
  61924. + notice, this list of conditions and the following disclaimer in the
  61925. + documentation and/or other materials provided with the distribution.
  61926. +
  61927. + * Neither the name of Marvell nor the names of its contributors may be
  61928. + used to endorse or promote products derived from this software without
  61929. + specific prior written permission.
  61930. +
  61931. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  61932. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  61933. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  61934. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  61935. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  61936. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  61937. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  61938. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  61939. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  61940. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  61941. +
  61942. +*******************************************************************************/
  61943. +
  61944. +/*******************************************************************************
  61945. +* mvEth.c - Marvell's Gigabit Ethernet controller low level driver
  61946. +*
  61947. +* DESCRIPTION:
  61948. +* This file introduce OS independent APIs to Marvell's Gigabit Ethernet
  61949. +* controller. This Gigabit Ethernet Controller driver API controls
  61950. +* 1) Operations (i.e. port Init, Finish, Up, Down, PhyReset etc').
  61951. +* 2) Data flow (i.e. port Send, Receive etc').
  61952. +* 3) MAC Filtering functions (ethSetMcastAddr, ethSetRxFilterMode, etc.)
  61953. +* 4) MIB counters support (ethReadMibCounter)
  61954. +* 5) Debug functions (ethPortRegs, ethPortCounters, ethPortQueues, etc.)
  61955. +* Each Gigabit Ethernet port is controlled via ETH_PORT_CTRL struct.
  61956. +* This struct includes configuration information as well as driver
  61957. +* internal data needed for its operations.
  61958. +*
  61959. +* Supported Features:
  61960. +* - OS independent. All required OS services are implemented via external
  61961. +* OS dependent components (like osLayer or ethOsg)
  61962. +* - The user is free from Rx/Tx queue managing.
  61963. +* - Simple Gigabit Ethernet port operation API.
  61964. +* - Simple Gigabit Ethernet port data flow API.
  61965. +* - Data flow and operation API support per queue functionality.
  61966. +* - Support cached descriptors for better performance.
  61967. +* - PHY access and control API.
  61968. +* - Port Configuration API.
  61969. +* - Full control over Special and Other Multicast MAC tables.
  61970. +*
  61971. +*******************************************************************************/
  61972. +/* includes */
  61973. +#include "mvTypes.h"
  61974. +#include "mv802_3.h"
  61975. +#include "mvDebug.h"
  61976. +#include "mvCommon.h"
  61977. +#include "mvOs.h"
  61978. +#include "ctrlEnv/mvCtrlEnvLib.h"
  61979. +#include "eth-phy/mvEthPhy.h"
  61980. +#include "eth/mvEth.h"
  61981. +#include "eth/gbe/mvEthGbe.h"
  61982. +#include "cpu/mvCpu.h"
  61983. +
  61984. +#ifdef INCLUDE_SYNC_BARR
  61985. +#include "sys/mvCpuIf.h"
  61986. +#endif
  61987. +
  61988. +#ifdef MV_RT_DEBUG
  61989. +# define ETH_DEBUG
  61990. +#endif
  61991. +
  61992. +
  61993. +/* locals */
  61994. +MV_BOOL ethDescInSram;
  61995. +MV_BOOL ethDescSwCoher;
  61996. +
  61997. +/* This array holds the control structure of each port */
  61998. +ETH_PORT_CTRL* ethPortCtrl[MV_ETH_MAX_PORTS];
  61999. +
  62000. +/* Ethernet Port Local routines */
  62001. +
  62002. +static void ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);
  62003. +
  62004. +static void ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);
  62005. +
  62006. +static void ethSetUcastTable(int portNo, int queue);
  62007. +
  62008. +static MV_BOOL ethSetUcastAddr (int ethPortNum, MV_U8 lastNibble, int queue);
  62009. +static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue);
  62010. +static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue);
  62011. +
  62012. +static void ethFreeDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, MV_BUF_INFO* pDescBuf);
  62013. +static MV_U8* ethAllocDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, int size,
  62014. + MV_ULONG* pPhysAddr, MV_U32 *memHandle);
  62015. +
  62016. +static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize);
  62017. +
  62018. +static void mvEthPortSgmiiConfig(int port);
  62019. +
  62020. +
  62021. +
  62022. +/******************************************************************************/
  62023. +/* EthDrv Initialization functions */
  62024. +/******************************************************************************/
  62025. +
  62026. +/*******************************************************************************
  62027. +* mvEthHalInit - Initialize the Giga Ethernet unit
  62028. +*
  62029. +* DESCRIPTION:
  62030. +* This function initialize the Giga Ethernet unit.
  62031. +* 1) Configure Address decode windows of the unit
  62032. +* 2) Set registers to HW default values.
  62033. +* 3) Clear and Disable interrupts
  62034. +*
  62035. +* INPUT: NONE
  62036. +*
  62037. +* RETURN: NONE
  62038. +*
  62039. +* NOTE: this function is called once in the boot process.
  62040. +*******************************************************************************/
  62041. +void mvEthHalInit(void)
  62042. +{
  62043. + int port;
  62044. +
  62045. + /* Init static data structures */
  62046. + for (port=0; port<MV_ETH_MAX_PORTS; port++)
  62047. + {
  62048. + ethPortCtrl[port] = NULL;
  62049. + }
  62050. + /* Power down all existing ports */
  62051. + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
  62052. + {
  62053. +
  62054. +#if defined (MV78200)
  62055. + /* Skip ports mapped to another CPU*/
  62056. + if (MV_FALSE == mvSocUnitIsMappedToThisCpu(GIGA0+port))
  62057. + {
  62058. + continue;
  62059. + }
  62060. +#endif
  62061. +
  62062. + /* Skip power down ports */
  62063. + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;
  62064. +
  62065. + /* Disable Giga Ethernet Unit interrupts */
  62066. + MV_REG_WRITE(ETH_UNIT_INTR_MASK_REG(port), 0);
  62067. +
  62068. + /* Clear ETH_UNIT_INTR_CAUSE_REG register */
  62069. + MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);
  62070. +
  62071. + }
  62072. +
  62073. + mvEthMemAttrGet(&ethDescInSram, &ethDescSwCoher);
  62074. +
  62075. +#if defined(ETH_DESCR_IN_SRAM)
  62076. + if(ethDescInSram == MV_FALSE)
  62077. + {
  62078. + mvOsPrintf("ethDrv: WARNING! Descriptors will be allocated in DRAM instead of SRAM.\n");
  62079. + }
  62080. +#endif /* ETH_DESCR_IN_SRAM */
  62081. +}
  62082. +
  62083. +/*******************************************************************************
  62084. +* mvEthMemAttrGet - Define properties (SRAM/DRAM, SW_COHER / HW_COHER / UNCACHED)
  62085. +* of of memory location for RX and TX descriptors.
  62086. +*
  62087. +* DESCRIPTION:
  62088. +* This function allocates memory for RX and TX descriptors.
  62089. +* - If ETH_DESCR_IN_SRAM defined, allocate from SRAM memory.
  62090. +* - If ETH_DESCR_IN_SDRAM defined, allocate from SDRAM memory.
  62091. +*
  62092. +* INPUT:
  62093. +* MV_BOOL* pIsSram - place of descriptors:
  62094. +* MV_TRUE - in SRAM
  62095. +* MV_FALSE - in DRAM
  62096. +* MV_BOOL* pIsSwCoher - cache coherency of descriptors:
  62097. +* MV_TRUE - driver is responsible for cache coherency
  62098. +* MV_FALSE - driver is not responsible for cache coherency
  62099. +*
  62100. +* RETURN:
  62101. +*
  62102. +*******************************************************************************/
  62103. +void mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher)
  62104. +{
  62105. + MV_BOOL isSram, isSwCoher;
  62106. +
  62107. + isSram = MV_FALSE;
  62108. +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW)
  62109. + isSwCoher = MV_TRUE;
  62110. +#else
  62111. + isSwCoher = MV_FALSE;
  62112. +#endif
  62113. +
  62114. +#if defined(ETH_DESCR_IN_SRAM)
  62115. + if( mvCtrlSramSizeGet() > 0)
  62116. + {
  62117. + isSram = MV_TRUE;
  62118. + #if (INTEG_SRAM_COHER == MV_CACHE_COHER_SW)
  62119. + isSwCoher = MV_TRUE;
  62120. + #else
  62121. + isSwCoher = MV_FALSE;
  62122. + #endif
  62123. + }
  62124. +#endif /* ETH_DESCR_IN_SRAM */
  62125. +
  62126. + if(pIsSram != NULL)
  62127. + *pIsSram = isSram;
  62128. +
  62129. + if(pIsSwCoher != NULL)
  62130. + *pIsSwCoher = isSwCoher;
  62131. +}
  62132. +
  62133. +
  62134. +
  62135. +/******************************************************************************/
  62136. +/* Port Initialization functions */
  62137. +/******************************************************************************/
  62138. +
  62139. +/*******************************************************************************
  62140. +* mvEthPortInit - Initialize the Ethernet port driver
  62141. +*
  62142. +* DESCRIPTION:
  62143. +* This function initialize the ethernet port.
  62144. +* 1) Allocate and initialize internal port Control structure.
  62145. +* 2) Create RX and TX descriptor rings for default RX and TX queues
  62146. +* 3) Disable RX and TX operations, clear cause registers and
  62147. +* mask all interrupts.
  62148. +* 4) Set all registers to default values and clean all MAC tables.
  62149. +*
  62150. +* INPUT:
  62151. +* int portNo - Ethernet port number
  62152. +* ETH_PORT_INIT *pEthPortInit - Ethernet port init structure
  62153. +*
  62154. +* RETURN:
  62155. +* void* - ethernet port handler, that should be passed to the most other
  62156. +* functions dealing with this port.
  62157. +*
  62158. +* NOTE: This function is called once per port when loading the eth module.
  62159. +*******************************************************************************/
  62160. +void* mvEthPortInit(int portNo, MV_ETH_PORT_INIT *pEthPortInit)
  62161. +{
  62162. + int queue, descSize;
  62163. + ETH_PORT_CTRL* pPortCtrl;
  62164. +
  62165. + /* Check validity of parameters */
  62166. + if( (portNo >= (int)mvCtrlEthMaxPortGet()) ||
  62167. + (pEthPortInit->rxDefQ >= MV_ETH_RX_Q_NUM) ||
  62168. + (pEthPortInit->maxRxPktSize < 1518) )
  62169. + {
  62170. + mvOsPrintf("EthPort #%d: Bad initialization parameters\n", portNo);
  62171. + return NULL;
  62172. + }
  62173. + if( (pEthPortInit->rxDescrNum[pEthPortInit->rxDefQ]) == 0)
  62174. + {
  62175. + mvOsPrintf("EthPort #%d: rxDefQ (%d) must be created\n",
  62176. + portNo, pEthPortInit->rxDefQ);
  62177. + return NULL;
  62178. + }
  62179. +
  62180. + pPortCtrl = (ETH_PORT_CTRL*)mvOsMalloc( sizeof(ETH_PORT_CTRL) );
  62181. + if(pPortCtrl == NULL)
  62182. + {
  62183. + mvOsPrintf("EthDrv: Can't allocate %dB for port #%d control structure!\n",
  62184. + (int)sizeof(ETH_PORT_CTRL), portNo);
  62185. + return NULL;
  62186. + }
  62187. +
  62188. + memset(pPortCtrl, 0, sizeof(ETH_PORT_CTRL) );
  62189. + ethPortCtrl[portNo] = pPortCtrl;
  62190. +
  62191. + pPortCtrl->portState = MV_UNDEFINED_STATE;
  62192. +
  62193. + pPortCtrl->portNo = portNo;
  62194. +
  62195. + pPortCtrl->osHandle = pEthPortInit->osHandle;
  62196. +
  62197. + /* Copy Configuration parameters */
  62198. + pPortCtrl->portConfig.maxRxPktSize = pEthPortInit->maxRxPktSize;
  62199. + pPortCtrl->portConfig.rxDefQ = pEthPortInit->rxDefQ;
  62200. + pPortCtrl->portConfig.ejpMode = 0;
  62201. +
  62202. + for( queue=0; queue<MV_ETH_RX_Q_NUM; queue++ )
  62203. + {
  62204. + pPortCtrl->rxQueueConfig[queue].descrNum = pEthPortInit->rxDescrNum[queue];
  62205. + }
  62206. + for( queue=0; queue<MV_ETH_TX_Q_NUM; queue++ )
  62207. + {
  62208. + pPortCtrl->txQueueConfig[queue].descrNum = pEthPortInit->txDescrNum[queue];
  62209. + }
  62210. +
  62211. + mvEthPortDisable(pPortCtrl);
  62212. +
  62213. + /* Set the board information regarding PHY address */
  62214. + mvEthPhyAddrSet(pPortCtrl, mvBoardPhyAddrGet(portNo) );
  62215. +
  62216. + /* Create all requested RX queues */
  62217. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  62218. + {
  62219. + if(pPortCtrl->rxQueueConfig[queue].descrNum == 0)
  62220. + continue;
  62221. +
  62222. + /* Allocate memory for RX descriptors */
  62223. + descSize = ((pPortCtrl->rxQueueConfig[queue].descrNum * ETH_RX_DESC_ALIGNED_SIZE) +
  62224. + CPU_D_CACHE_LINE_SIZE);
  62225. +
  62226. + pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr =
  62227. + ethAllocDescrMemory(pPortCtrl, descSize,
  62228. + &pPortCtrl->rxQueue[queue].descBuf.bufPhysAddr,
  62229. + &pPortCtrl->rxQueue[queue].descBuf.memHandle);
  62230. + pPortCtrl->rxQueue[queue].descBuf.bufSize = descSize;
  62231. + if(pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr == NULL)
  62232. + {
  62233. + mvOsPrintf("EthPort #%d, rxQ=%d: Can't allocate %d bytes in %s for %d RX descr\n",
  62234. + pPortCtrl->portNo, queue, descSize,
  62235. + ethDescInSram ? "SRAM" : "DRAM",
  62236. + pPortCtrl->rxQueueConfig[queue].descrNum);
  62237. + return NULL;
  62238. + }
  62239. +
  62240. + ethInitRxDescRing(pPortCtrl, queue);
  62241. + }
  62242. + /* Create TX queues */
  62243. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  62244. + {
  62245. + if(pPortCtrl->txQueueConfig[queue].descrNum == 0)
  62246. + continue;
  62247. +
  62248. + /* Allocate memory for TX descriptors */
  62249. + descSize = ((pPortCtrl->txQueueConfig[queue].descrNum * ETH_TX_DESC_ALIGNED_SIZE) +
  62250. + CPU_D_CACHE_LINE_SIZE);
  62251. +
  62252. + pPortCtrl->txQueue[queue].descBuf.bufVirtPtr =
  62253. + ethAllocDescrMemory(pPortCtrl, descSize,
  62254. + &pPortCtrl->txQueue[queue].descBuf.bufPhysAddr,
  62255. + &pPortCtrl->txQueue[queue].descBuf.memHandle);
  62256. + pPortCtrl->txQueue[queue].descBuf.bufSize = descSize;
  62257. + if(pPortCtrl->txQueue[queue].descBuf.bufVirtPtr == NULL)
  62258. + {
  62259. + mvOsPrintf("EthPort #%d, txQ=%d: Can't allocate %d bytes in %s for %d TX descr\n",
  62260. + pPortCtrl->portNo, queue, descSize, ethDescInSram ? "SRAM" : "DRAM",
  62261. + pPortCtrl->txQueueConfig[queue].descrNum);
  62262. + return NULL;
  62263. + }
  62264. +
  62265. + ethInitTxDescRing(pPortCtrl, queue);
  62266. + }
  62267. + mvEthDefaultsSet(pPortCtrl);
  62268. +
  62269. + pPortCtrl->portState = MV_IDLE;
  62270. + return pPortCtrl;
  62271. +}
  62272. +
  62273. +/*******************************************************************************
  62274. +* ethPortFinish - Finish the Ethernet port driver
  62275. +*
  62276. +* DESCRIPTION:
  62277. +* This function finish the ethernet port.
  62278. +* 1) Down ethernet port if needed.
  62279. +* 2) Delete RX and TX descriptor rings for all created RX and TX queues
  62280. +* 3) Free internal port Control structure.
  62281. +*
  62282. +* INPUT:
  62283. +* void* pEthPortHndl - Ethernet port handler
  62284. +*
  62285. +* RETURN: NONE.
  62286. +*
  62287. +*******************************************************************************/
  62288. +void mvEthPortFinish(void* pPortHndl)
  62289. +{
  62290. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62291. + int queue, portNo = pPortCtrl->portNo;
  62292. +
  62293. + if(pPortCtrl->portState == MV_ACTIVE)
  62294. + {
  62295. + mvOsPrintf("ethPort #%d: Warning !!! Finish port in Active state\n",
  62296. + portNo);
  62297. + mvEthPortDisable(pPortHndl);
  62298. + }
  62299. +
  62300. + /* Free all allocated RX queues */
  62301. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  62302. + {
  62303. + ethFreeDescrMemory(pPortCtrl, &pPortCtrl->rxQueue[queue].descBuf);
  62304. + }
  62305. +
  62306. + /* Free all allocated TX queues */
  62307. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  62308. + {
  62309. + ethFreeDescrMemory(pPortCtrl, &pPortCtrl->txQueue[queue].descBuf);
  62310. + }
  62311. +
  62312. + /* Free port control structure */
  62313. + mvOsFree(pPortCtrl);
  62314. +
  62315. + ethPortCtrl[portNo] = NULL;
  62316. +}
  62317. +
  62318. +/*******************************************************************************
  62319. +* mvEthDefaultsSet - Set defaults to the ethernet port
  62320. +*
  62321. +* DESCRIPTION:
  62322. +* This function set default values to the ethernet port.
  62323. +* 1) Clear Cause registers and Mask all interrupts
  62324. +* 2) Clear all MAC tables
  62325. +* 3) Set defaults to all registers
  62326. +* 4) Reset all created RX and TX descriptors ring
  62327. +* 5) Reset PHY
  62328. +*
  62329. +* INPUT:
  62330. +* void* pEthPortHndl - Ethernet port handler
  62331. +*
  62332. +* RETURN: MV_STATUS
  62333. +* MV_OK - Success, Others - Failure
  62334. +* NOTE:
  62335. +* This function update all the port configuration except those set
  62336. +* Initialy by the OsGlue by MV_ETH_PORT_INIT.
  62337. +* This function can be called after portDown to return the port setting
  62338. +* to defaults.
  62339. +*******************************************************************************/
  62340. +MV_STATUS mvEthDefaultsSet(void* pPortHndl)
  62341. +{
  62342. + int ethPortNo, queue;
  62343. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62344. + ETH_QUEUE_CTRL* pQueueCtrl;
  62345. + MV_U32 txPrio;
  62346. + MV_U32 portCfgReg, portCfgExtReg, portSerialCtrlReg, portSerialCtrl1Reg, portSdmaCfgReg;
  62347. + MV_BOARD_MAC_SPEED boardMacCfg;
  62348. +
  62349. + ethPortNo = pPortCtrl->portNo;
  62350. +
  62351. + /* Clear Cause registers */
  62352. + MV_REG_WRITE(ETH_INTR_CAUSE_REG(ethPortNo),0);
  62353. + MV_REG_WRITE(ETH_INTR_CAUSE_EXT_REG(ethPortNo),0);
  62354. +
  62355. + /* Mask all interrupts */
  62356. + MV_REG_WRITE(ETH_INTR_MASK_REG(ethPortNo),0);
  62357. + MV_REG_WRITE(ETH_INTR_MASK_EXT_REG(ethPortNo),0);
  62358. +
  62359. + portCfgReg = PORT_CONFIG_VALUE;
  62360. + portCfgExtReg = PORT_CONFIG_EXTEND_VALUE;
  62361. +
  62362. + boardMacCfg = mvBoardMacSpeedGet(ethPortNo);
  62363. +
  62364. + if(boardMacCfg == BOARD_MAC_SPEED_100M)
  62365. + {
  62366. + portSerialCtrlReg = PORT_SERIAL_CONTROL_100MB_FORCE_VALUE;
  62367. + }
  62368. + else if(boardMacCfg == BOARD_MAC_SPEED_1000M)
  62369. + {
  62370. + portSerialCtrlReg = PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE;
  62371. + }
  62372. + else
  62373. + {
  62374. + portSerialCtrlReg = PORT_SERIAL_CONTROL_VALUE;
  62375. + }
  62376. +
  62377. + /* build PORT_SDMA_CONFIG_REG */
  62378. + portSdmaCfgReg = ETH_TX_INTR_COAL_MASK(0);
  62379. + portSdmaCfgReg |= ETH_TX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);
  62380. +
  62381. +#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB) || \
  62382. + (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT) )
  62383. + /* some devices have restricted RX burst size when using HW coherency */
  62384. + portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_4_64BIT_VALUE);
  62385. +#else
  62386. + portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);
  62387. +#endif
  62388. +
  62389. +#if defined(MV_CPU_BE)
  62390. + /* big endian */
  62391. +# if defined(MV_ARM)
  62392. + portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK |
  62393. + ETH_TX_NO_DATA_SWAP_MASK |
  62394. + ETH_DESC_SWAP_MASK);
  62395. +# elif defined(MV_PPC)
  62396. + portSdmaCfgReg |= (ETH_RX_DATA_SWAP_MASK |
  62397. + ETH_TX_DATA_SWAP_MASK |
  62398. + ETH_NO_DESC_SWAP_MASK);
  62399. +# else
  62400. +# error "Giga Ethernet Swap policy is not defined for the CPU_ARCH"
  62401. +# endif /* MV_ARM / MV_PPC */
  62402. +
  62403. +#else /* MV_CPU_LE */
  62404. + /* little endian */
  62405. + portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK |
  62406. + ETH_TX_NO_DATA_SWAP_MASK |
  62407. + ETH_NO_DESC_SWAP_MASK);
  62408. +#endif /* MV_CPU_BE / MV_CPU_LE */
  62409. +
  62410. + pPortCtrl->portRxQueueCmdReg = 0;
  62411. + pPortCtrl->portTxQueueCmdReg = 0;
  62412. +
  62413. +#if (MV_ETH_VERSION >= 4)
  62414. + if(pPortCtrl->portConfig.ejpMode == MV_TRUE)
  62415. + {
  62416. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), ETH_TX_EJP_ENABLE_MASK);
  62417. + }
  62418. + else
  62419. + {
  62420. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), 0)
  62421. + }
  62422. +#endif /* (MV_ETH_VERSION >= 4) */
  62423. +
  62424. + ethSetUcastTable(ethPortNo, -1);
  62425. + mvEthSetSpecialMcastTable(ethPortNo, -1);
  62426. + mvEthSetOtherMcastTable(ethPortNo, -1);
  62427. +
  62428. + portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;
  62429. +
  62430. + portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);
  62431. +
  62432. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);
  62433. +
  62434. + /* Update value of PortConfig register accordingly with all RxQueue types */
  62435. + pPortCtrl->portConfig.rxArpQ = pPortCtrl->portConfig.rxDefQ;
  62436. + pPortCtrl->portConfig.rxBpduQ = pPortCtrl->portConfig.rxDefQ;
  62437. + pPortCtrl->portConfig.rxTcpQ = pPortCtrl->portConfig.rxDefQ;
  62438. + pPortCtrl->portConfig.rxUdpQ = pPortCtrl->portConfig.rxDefQ;
  62439. +
  62440. + portCfgReg &= ~ETH_DEF_RX_QUEUE_ALL_MASK;
  62441. + portCfgReg |= ETH_DEF_RX_QUEUE_MASK(pPortCtrl->portConfig.rxDefQ);
  62442. +
  62443. + portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;
  62444. + portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ);
  62445. +
  62446. + portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;
  62447. + portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);
  62448. +
  62449. + portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;
  62450. + portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);
  62451. +
  62452. + portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;
  62453. + portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);
  62454. +
  62455. + /* Assignment of Tx CTRP of given queue */
  62456. + txPrio = 0;
  62457. +
  62458. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  62459. + {
  62460. + pQueueCtrl = &pPortCtrl->txQueue[queue];
  62461. +
  62462. + if(pQueueCtrl->pFirstDescr != NULL)
  62463. + {
  62464. + ethResetTxDescRing(pPortCtrl, queue);
  62465. +
  62466. + MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue),
  62467. + 0x3fffffff);
  62468. + MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue),
  62469. + 0x03ffffff);
  62470. + }
  62471. + else
  62472. + {
  62473. + MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue), 0x0);
  62474. + MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue), 0x0);
  62475. + }
  62476. + }
  62477. +
  62478. + /* Assignment of Rx CRDP of given queue */
  62479. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  62480. + {
  62481. + ethResetRxDescRing(pPortCtrl, queue);
  62482. + }
  62483. +
  62484. + /* Allow receiving packes with odd number of preamble nibbles */
  62485. + portSerialCtrl1Reg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo));
  62486. + portSerialCtrl1Reg |= ETH_EN_MII_ODD_PRE_MASK;
  62487. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo), portSerialCtrl1Reg);
  62488. +
  62489. + /* Assign port configuration and command. */
  62490. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(ethPortNo), portCfgReg);
  62491. +
  62492. + MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(ethPortNo), portCfgExtReg);
  62493. +
  62494. + /* Assign port SDMA configuration */
  62495. + MV_REG_WRITE(ETH_SDMA_CONFIG_REG(ethPortNo), portSdmaCfgReg);
  62496. +
  62497. + /* Turn off the port/queue bandwidth limitation */
  62498. + MV_REG_WRITE(ETH_MAX_TRANSMIT_UNIT_REG(ethPortNo), 0x0);
  62499. +
  62500. + return MV_OK;
  62501. +}
  62502. +
  62503. +/*******************************************************************************
  62504. +* ethPortUp - Start the Ethernet port RX and TX activity.
  62505. +*
  62506. +* DESCRIPTION:
  62507. +* This routine start Rx and Tx activity:
  62508. +*
  62509. +* Note: Each Rx and Tx queue descriptor's list must be initialized prior
  62510. +* to calling this function (use etherInitTxDescRing for Tx queues and
  62511. +* etherInitRxDescRing for Rx queues).
  62512. +*
  62513. +* INPUT:
  62514. +* void* pEthPortHndl - Ethernet port handler
  62515. +*
  62516. +* RETURN: MV_STATUS
  62517. +* MV_OK - Success, Others - Failure.
  62518. +*
  62519. +* NOTE : used for port link up.
  62520. +*******************************************************************************/
  62521. +MV_STATUS mvEthPortUp(void* pEthPortHndl)
  62522. +{
  62523. + int ethPortNo;
  62524. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  62525. +
  62526. + ethPortNo = pPortCtrl->portNo;
  62527. +
  62528. + if( (pPortCtrl->portState != MV_ACTIVE) &&
  62529. + (pPortCtrl->portState != MV_PAUSED) )
  62530. + {
  62531. + mvOsPrintf("ethDrv port%d: Unexpected port state %d\n",
  62532. + ethPortNo, pPortCtrl->portState);
  62533. + return MV_BAD_STATE;
  62534. + }
  62535. +
  62536. + ethPortNo = pPortCtrl->portNo;
  62537. +
  62538. + /* Enable port RX. */
  62539. + MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNo), pPortCtrl->portRxQueueCmdReg);
  62540. +
  62541. + /* Enable port TX. */
  62542. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(ethPortNo)) = pPortCtrl->portTxQueueCmdReg;
  62543. +
  62544. + pPortCtrl->portState = MV_ACTIVE;
  62545. +
  62546. + return MV_OK;
  62547. +}
  62548. +
  62549. +/*******************************************************************************
  62550. +* ethPortDown - Stop the Ethernet port activity.
  62551. +*
  62552. +* DESCRIPTION:
  62553. +*
  62554. +* INPUT:
  62555. +* void* pEthPortHndl - Ethernet port handler
  62556. +*
  62557. +* RETURN: MV_STATUS
  62558. +* MV_OK - Success, Others - Failure.
  62559. +*
  62560. +* NOTE : used for port link down.
  62561. +*******************************************************************************/
  62562. +MV_STATUS mvEthPortDown(void* pEthPortHndl)
  62563. +{
  62564. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  62565. + int ethPortNum = pPortCtrl->portNo;
  62566. + unsigned int regData;
  62567. + volatile int uDelay, mDelay;
  62568. +
  62569. + /* Stop Rx port activity. Check port Rx activity. */
  62570. + regData = (MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_RXQ_ENABLE_MASK;
  62571. + if(regData != 0)
  62572. + {
  62573. + /* Issue stop command for active channels only */
  62574. + MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNum), (regData << ETH_RXQ_DISABLE_OFFSET));
  62575. + }
  62576. +
  62577. + /* Stop Tx port activity. Check port Tx activity. */
  62578. + regData = (MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_TXQ_ENABLE_MASK;
  62579. + if(regData != 0)
  62580. + {
  62581. + /* Issue stop command for active channels only */
  62582. + MV_REG_WRITE(ETH_TX_QUEUE_COMMAND_REG(ethPortNum),
  62583. + (regData << ETH_TXQ_DISABLE_OFFSET) );
  62584. + }
  62585. +
  62586. + /* Force link down */
  62587. +/*
  62588. + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
  62589. + regData &= ~(ETH_DO_NOT_FORCE_LINK_FAIL_MASK);
  62590. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
  62591. +*/
  62592. + /* Wait for all Rx activity to terminate. */
  62593. + mDelay = 0;
  62594. + do
  62595. + {
  62596. + if(mDelay >= RX_DISABLE_TIMEOUT_MSEC)
  62597. + {
  62598. + mvOsPrintf("ethPort_%d: TIMEOUT for RX stopped !!! rxQueueCmd - 0x08%x\n",
  62599. + ethPortNum, regData);
  62600. + break;
  62601. + }
  62602. + mvOsDelay(1);
  62603. + mDelay++;
  62604. +
  62605. + /* Check port RX Command register that all Rx queues are stopped */
  62606. + regData = MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum));
  62607. + }
  62608. + while(regData & 0xFF);
  62609. +
  62610. + /* Wait for all Tx activity to terminate. */
  62611. + mDelay = 0;
  62612. + do
  62613. + {
  62614. + if(mDelay >= TX_DISABLE_TIMEOUT_MSEC)
  62615. + {
  62616. + mvOsPrintf("ethPort_%d: TIMEOUT for TX stoped !!! txQueueCmd - 0x08%x\n",
  62617. + ethPortNum, regData);
  62618. + break;
  62619. + }
  62620. + mvOsDelay(1);
  62621. + mDelay++;
  62622. +
  62623. + /* Check port TX Command register that all Tx queues are stopped */
  62624. + regData = MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum));
  62625. + }
  62626. + while(regData & 0xFF);
  62627. +
  62628. + /* Double check to Verify that TX FIFO is Empty */
  62629. + mDelay = 0;
  62630. + while(MV_TRUE)
  62631. + {
  62632. + do
  62633. + {
  62634. + if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)
  62635. + {
  62636. + mvOsPrintf("\n ethPort_%d: TIMEOUT for TX FIFO empty !!! portStatus - 0x08%x\n",
  62637. + ethPortNum, regData);
  62638. + break;
  62639. + }
  62640. + mvOsDelay(1);
  62641. + mDelay++;
  62642. +
  62643. + regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));
  62644. + }
  62645. + while( ((regData & ETH_TX_FIFO_EMPTY_MASK) == 0) ||
  62646. + ((regData & ETH_TX_IN_PROGRESS_MASK) != 0) );
  62647. +
  62648. + if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)
  62649. + break;
  62650. +
  62651. + /* Double check */
  62652. + regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));
  62653. + if( ((regData & ETH_TX_FIFO_EMPTY_MASK) != 0) &&
  62654. + ((regData & ETH_TX_IN_PROGRESS_MASK) == 0) )
  62655. + {
  62656. + break;
  62657. + }
  62658. + else
  62659. + mvOsPrintf("ethPort_%d: TX FIFO Empty double check failed. %d msec, portStatus=0x%x\n",
  62660. + ethPortNum, mDelay, regData);
  62661. + }
  62662. +
  62663. + /* Do NOT force link down */
  62664. +/*
  62665. + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
  62666. + regData |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK);
  62667. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
  62668. +*/
  62669. + /* Wait about 2500 tclk cycles */
  62670. + uDelay = (PORT_DISABLE_WAIT_TCLOCKS/(mvBoardTclkGet()/1000000));
  62671. + mvOsUDelay(uDelay);
  62672. +
  62673. + pPortCtrl->portState = MV_PAUSED;
  62674. +
  62675. + return MV_OK;
  62676. +}
  62677. +
  62678. +
  62679. +/*******************************************************************************
  62680. +* ethPortEnable - Enable the Ethernet port and Start RX and TX.
  62681. +*
  62682. +* DESCRIPTION:
  62683. +* This routine enable the Ethernet port and Rx and Tx activity:
  62684. +*
  62685. +* Note: Each Rx and Tx queue descriptor's list must be initialized prior
  62686. +* to calling this function (use etherInitTxDescRing for Tx queues and
  62687. +* etherInitRxDescRing for Rx queues).
  62688. +*
  62689. +* INPUT:
  62690. +* void* pEthPortHndl - Ethernet port handler
  62691. +*
  62692. +* RETURN: MV_STATUS
  62693. +* MV_OK - Success, Others - Failure.
  62694. +*
  62695. +* NOTE: main usage is to enable the port after ifconfig up.
  62696. +*******************************************************************************/
  62697. +MV_STATUS mvEthPortEnable(void* pEthPortHndl)
  62698. +{
  62699. + int ethPortNo;
  62700. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  62701. + MV_U32 portSerialCtrlReg;
  62702. +
  62703. + ethPortNo = pPortCtrl->portNo;
  62704. +
  62705. + /* Enable port */
  62706. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNo));
  62707. + portSerialCtrlReg |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK | ETH_PORT_ENABLE_MASK);
  62708. +
  62709. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);
  62710. +
  62711. + mvEthMibCountersClear(pEthPortHndl);
  62712. +
  62713. + pPortCtrl->portState = MV_PAUSED;
  62714. +
  62715. + /* If Link is UP, Start RX and TX traffic */
  62716. + if( MV_REG_READ( ETH_PORT_STATUS_REG(ethPortNo) ) & ETH_LINK_UP_MASK)
  62717. + return( mvEthPortUp(pEthPortHndl) );
  62718. +
  62719. + return MV_NOT_READY;
  62720. +}
  62721. +
  62722. +
  62723. +/*******************************************************************************
  62724. +* mvEthPortDisable - Stop RX and TX activities and Disable the Ethernet port.
  62725. +*
  62726. +* DESCRIPTION:
  62727. +*
  62728. +* INPUT:
  62729. +* void* pEthPortHndl - Ethernet port handler
  62730. +*
  62731. +* RETURN: MV_STATUS
  62732. +* MV_OK - Success, Others - Failure.
  62733. +*
  62734. +* NOTE: main usage is to disable the port after ifconfig down.
  62735. +*******************************************************************************/
  62736. +MV_STATUS mvEthPortDisable(void* pEthPortHndl)
  62737. +{
  62738. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  62739. + int ethPortNum = pPortCtrl->portNo;
  62740. + unsigned int regData;
  62741. + volatile int mvDelay;
  62742. +
  62743. + if(pPortCtrl->portState == MV_ACTIVE)
  62744. + {
  62745. + /* Stop RX and TX activities */
  62746. + mvEthPortDown(pEthPortHndl);
  62747. + }
  62748. +
  62749. + /* Reset the Enable bit in the Serial Control Register */
  62750. + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
  62751. + regData &= ~(ETH_PORT_ENABLE_MASK);
  62752. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
  62753. +
  62754. + /* Wait about 2500 tclk cycles */
  62755. + mvDelay = (PORT_DISABLE_WAIT_TCLOCKS*(mvCpuPclkGet()/mvBoardTclkGet()));
  62756. + for(mvDelay; mvDelay>0; mvDelay--);
  62757. +
  62758. + pPortCtrl->portState = MV_IDLE;
  62759. + return MV_OK;
  62760. +}
  62761. +
  62762. +/*******************************************************************************
  62763. +* mvEthPortForceTxDone - Get next buffer from TX queue in spite of buffer ownership.
  62764. +*
  62765. +* DESCRIPTION:
  62766. +* This routine used to free buffers attached to the Tx ring and should
  62767. +* be called only when Giga Ethernet port is Down
  62768. +*
  62769. +* INPUT:
  62770. +* void* pEthPortHndl - Ethernet Port handler.
  62771. +* int txQueue - Number of TX queue.
  62772. +*
  62773. +* OUTPUT:
  62774. +* MV_PKT_INFO *pPktInfo - Pointer to packet was sent.
  62775. +*
  62776. +* RETURN:
  62777. +* MV_EMPTY - There is no more buffers in this queue.
  62778. +* MV_OK - Buffer detached from the queue and pPktInfo structure
  62779. +* filled with relevant information.
  62780. +*
  62781. +*******************************************************************************/
  62782. +MV_PKT_INFO* mvEthPortForceTxDone(void* pEthPortHndl, int txQueue)
  62783. +{
  62784. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  62785. + ETH_QUEUE_CTRL* pQueueCtrl;
  62786. + MV_PKT_INFO* pPktInfo;
  62787. + ETH_TX_DESC* pTxDesc;
  62788. + int port = pPortCtrl->portNo;
  62789. +
  62790. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  62791. +
  62792. + while( (pQueueCtrl->pUsedDescr != pQueueCtrl->pCurrentDescr) ||
  62793. + (pQueueCtrl->resource == 0) )
  62794. + {
  62795. + /* Free next descriptor */
  62796. + pQueueCtrl->resource++;
  62797. + pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pUsedDescr;
  62798. +
  62799. + /* pPktInfo is available only in descriptors which are last descriptors */
  62800. + pPktInfo = (MV_PKT_INFO*)pTxDesc->returnInfo;
  62801. + if (pPktInfo)
  62802. + pPktInfo->status = pTxDesc->cmdSts;
  62803. +
  62804. + pTxDesc->cmdSts = 0x0;
  62805. + pTxDesc->returnInfo = 0x0;
  62806. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);
  62807. +
  62808. + pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);
  62809. +
  62810. + if (pPktInfo)
  62811. + if (pPktInfo->status & ETH_TX_LAST_DESC_MASK)
  62812. + return pPktInfo;
  62813. + }
  62814. + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(port, txQueue),
  62815. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  62816. + return NULL;
  62817. +}
  62818. +
  62819. +
  62820. +
  62821. +/*******************************************************************************
  62822. +* mvEthPortForceRx - Get next buffer from RX queue in spite of buffer ownership.
  62823. +*
  62824. +* DESCRIPTION:
  62825. +* This routine used to free buffers attached to the Rx ring and should
  62826. +* be called only when Giga Ethernet port is Down
  62827. +*
  62828. +* INPUT:
  62829. +* void* pEthPortHndl - Ethernet Port handler.
  62830. +* int rxQueue - Number of Rx queue.
  62831. +*
  62832. +* OUTPUT:
  62833. +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
  62834. +*
  62835. +* RETURN:
  62836. +* MV_EMPTY - There is no more buffers in this queue.
  62837. +* MV_OK - Buffer detached from the queue and pBufInfo structure
  62838. +* filled with relevant information.
  62839. +*
  62840. +*******************************************************************************/
  62841. +MV_PKT_INFO* mvEthPortForceRx(void* pEthPortHndl, int rxQueue)
  62842. +{
  62843. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  62844. + ETH_QUEUE_CTRL* pQueueCtrl;
  62845. + ETH_RX_DESC* pRxDesc;
  62846. + MV_PKT_INFO* pPktInfo;
  62847. + int port = pPortCtrl->portNo;
  62848. +
  62849. + pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
  62850. +
  62851. + if(pQueueCtrl->resource == 0)
  62852. + {
  62853. + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue),
  62854. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  62855. +
  62856. + return NULL;
  62857. + }
  62858. + /* Free next descriptor */
  62859. + pQueueCtrl->resource--;
  62860. + pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pCurrentDescr;
  62861. + pPktInfo = (MV_PKT_INFO*)pRxDesc->returnInfo;
  62862. +
  62863. + pPktInfo->status = pRxDesc->cmdSts;
  62864. + pRxDesc->cmdSts = 0x0;
  62865. + pRxDesc->returnInfo = 0x0;
  62866. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);
  62867. +
  62868. + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);
  62869. + return pPktInfo;
  62870. +}
  62871. +
  62872. +
  62873. +/******************************************************************************/
  62874. +/* Port Configuration functions */
  62875. +/******************************************************************************/
  62876. +/*******************************************************************************
  62877. +* mvEthMruGet - Get MRU configuration for Max Rx packet size.
  62878. +*
  62879. +* INPUT:
  62880. +* MV_U32 maxRxPktSize - max packet size.
  62881. +*
  62882. +* RETURN: MV_U32 - MRU configuration.
  62883. +*
  62884. +*******************************************************************************/
  62885. +static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize)
  62886. +{
  62887. + MV_U32 portSerialCtrlReg = 0;
  62888. +
  62889. + if(maxRxPktSize > 9192)
  62890. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9700BYTE;
  62891. + else if(maxRxPktSize > 9022)
  62892. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9192BYTE;
  62893. + else if(maxRxPktSize > 1552)
  62894. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9022BYTE;
  62895. + else if(maxRxPktSize > 1522)
  62896. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1552BYTE;
  62897. + else if(maxRxPktSize > 1518)
  62898. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1522BYTE;
  62899. + else
  62900. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1518BYTE;
  62901. +
  62902. + return portSerialCtrlReg;
  62903. +}
  62904. +
  62905. +/*******************************************************************************
  62906. +* mvEthRxCoalSet - Sets coalescing interrupt mechanism on RX path
  62907. +*
  62908. +* DESCRIPTION:
  62909. +* This routine sets the RX coalescing interrupt mechanism parameter.
  62910. +* This parameter is a timeout counter, that counts in 64 tClk
  62911. +* chunks, that when timeout event occurs a maskable interrupt occurs.
  62912. +* The parameter is calculated using the tCLK frequency of the
  62913. +* MV-64xxx chip, and the required number is in micro seconds.
  62914. +*
  62915. +* INPUT:
  62916. +* void* pPortHndl - Ethernet Port handler.
  62917. +* MV_U32 uSec - Number of micro seconds between
  62918. +* RX interrupts
  62919. +*
  62920. +* RETURN:
  62921. +* None.
  62922. +*
  62923. +* COMMENT:
  62924. +* 1 sec - TCLK_RATE clocks
  62925. +* 1 uSec - TCLK_RATE / 1,000,000 clocks
  62926. +*
  62927. +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
  62928. +*
  62929. +* RETURN:
  62930. +* None.
  62931. +*
  62932. +*******************************************************************************/
  62933. +MV_U32 mvEthRxCoalSet (void* pPortHndl, MV_U32 uSec)
  62934. +{
  62935. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62936. + MV_U32 coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);
  62937. + MV_U32 portSdmaCfgReg;
  62938. +
  62939. + portSdmaCfgReg = MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));
  62940. + portSdmaCfgReg &= ~ETH_RX_INTR_COAL_ALL_MASK;
  62941. +
  62942. + portSdmaCfgReg |= ETH_RX_INTR_COAL_MASK(coal);
  62943. +
  62944. +#if (MV_ETH_VERSION >= 2)
  62945. + /* Set additional bit if needed ETH_RX_INTR_COAL_MSB_BIT (25) */
  62946. + if(ETH_RX_INTR_COAL_MASK(coal) > ETH_RX_INTR_COAL_ALL_MASK)
  62947. + portSdmaCfgReg |= ETH_RX_INTR_COAL_MSB_MASK;
  62948. +#endif /* MV_ETH_VERSION >= 2 */
  62949. +
  62950. + MV_REG_WRITE (ETH_SDMA_CONFIG_REG(pPortCtrl->portNo), portSdmaCfgReg);
  62951. + return coal;
  62952. +}
  62953. +
  62954. +/*******************************************************************************
  62955. +* mvEthTxCoalSet - Sets coalescing interrupt mechanism on TX path
  62956. +*
  62957. +* DESCRIPTION:
  62958. +* This routine sets the TX coalescing interrupt mechanism parameter.
  62959. +* This parameter is a timeout counter, that counts in 64 tClk
  62960. +* chunks, that when timeout event occurs a maskable interrupt
  62961. +* occurs.
  62962. +* The parameter is calculated using the tCLK frequency of the
  62963. +* MV-64xxx chip, and the required number is in micro seconds.
  62964. +*
  62965. +* INPUT:
  62966. +* void* pPortHndl - Ethernet Port handler.
  62967. +* MV_U32 uSec - Number of micro seconds between
  62968. +* RX interrupts
  62969. +*
  62970. +* RETURN:
  62971. +* None.
  62972. +*
  62973. +* COMMENT:
  62974. +* 1 sec - TCLK_RATE clocks
  62975. +* 1 uSec - TCLK_RATE / 1,000,000 clocks
  62976. +*
  62977. +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
  62978. +*
  62979. +*******************************************************************************/
  62980. +MV_U32 mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec)
  62981. +{
  62982. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62983. + MV_U32 coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);
  62984. + MV_U32 regVal;
  62985. +
  62986. + regVal = MV_REG_READ(ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));
  62987. + regVal &= ~ETH_TX_INTR_COAL_ALL_MASK;
  62988. + regVal |= ETH_TX_INTR_COAL_MASK(coal);
  62989. +
  62990. + /* Set TX Coalescing mechanism */
  62991. + MV_REG_WRITE (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo), regVal);
  62992. + return coal;
  62993. +}
  62994. +
  62995. +/*******************************************************************************
  62996. +* mvEthCoalGet - Gets RX and TX coalescing values in micro seconds
  62997. +*
  62998. +* DESCRIPTION:
  62999. +* This routine gets the RX and TX coalescing interrupt values.
  63000. +* The parameter is calculated using the tCLK frequency of the
  63001. +* MV-64xxx chip, and the returned numbers are in micro seconds.
  63002. +*
  63003. +* INPUTs:
  63004. +* void* pPortHndl - Ethernet Port handler.
  63005. +*
  63006. +* OUTPUTs:
  63007. +* MV_U32* pRxCoal - Number of micro seconds between RX interrupts
  63008. +* MV_U32* pTxCoal - Number of micro seconds between TX interrupts
  63009. +*
  63010. +* RETURN:
  63011. +* MV_STATUS MV_OK - success
  63012. +* Others - failure.
  63013. +*
  63014. +* COMMENT:
  63015. +* 1 sec - TCLK_RATE clocks
  63016. +* 1 uSec - TCLK_RATE / 1,000,000 clocks
  63017. +*
  63018. +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
  63019. +*
  63020. +*******************************************************************************/
  63021. +MV_STATUS mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal)
  63022. +{
  63023. + MV_U32 regVal, coal, usec;
  63024. +
  63025. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63026. +
  63027. + /* get TX Coalescing */
  63028. + regVal = MV_REG_READ (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));
  63029. + coal = ((regVal & ETH_TX_INTR_COAL_ALL_MASK) >> ETH_TX_INTR_COAL_OFFSET);
  63030. +
  63031. + usec = (coal * 64) / (mvBoardTclkGet() / 1000000);
  63032. + if(pTxCoal != NULL)
  63033. + *pTxCoal = usec;
  63034. +
  63035. + /* Get RX Coalescing */
  63036. + regVal = MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));
  63037. + coal = ((regVal & ETH_RX_INTR_COAL_ALL_MASK) >> ETH_RX_INTR_COAL_OFFSET);
  63038. +
  63039. +#if (MV_ETH_VERSION >= 2)
  63040. + if(regVal & ETH_RX_INTR_COAL_MSB_MASK)
  63041. + {
  63042. + /* Add MSB */
  63043. + coal |= (ETH_RX_INTR_COAL_ALL_MASK + 1);
  63044. + }
  63045. +#endif /* MV_ETH_VERSION >= 2 */
  63046. +
  63047. + usec = (coal * 64) / (mvBoardTclkGet() / 1000000);
  63048. + if(pRxCoal != NULL)
  63049. + *pRxCoal = usec;
  63050. +
  63051. + return MV_OK;
  63052. +}
  63053. +
  63054. +/*******************************************************************************
  63055. +* mvEthMaxRxSizeSet -
  63056. +*
  63057. +* DESCRIPTION:
  63058. +* Change maximum receive size of the port. This configuration will take place
  63059. +* after next call of ethPortSetDefaults() function.
  63060. +*
  63061. +* INPUT:
  63062. +*
  63063. +* RETURN:
  63064. +*******************************************************************************/
  63065. +MV_STATUS mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize)
  63066. +{
  63067. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63068. + MV_U32 portSerialCtrlReg;
  63069. +
  63070. + if((maxRxSize < 1518) || (maxRxSize & ~ETH_RX_BUFFER_MASK))
  63071. + return MV_BAD_PARAM;
  63072. +
  63073. + pPortCtrl->portConfig.maxRxPktSize = maxRxSize;
  63074. +
  63075. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo));
  63076. + portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;
  63077. + portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);
  63078. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo), portSerialCtrlReg);
  63079. +
  63080. + return MV_OK;
  63081. +}
  63082. +
  63083. +
  63084. +/******************************************************************************/
  63085. +/* MAC Filtering functions */
  63086. +/******************************************************************************/
  63087. +
  63088. +/*******************************************************************************
  63089. +* mvEthRxFilterModeSet - Configure Fitering mode of Ethernet port
  63090. +*
  63091. +* DESCRIPTION:
  63092. +* This routine used to free buffers attached to the Rx ring and should
  63093. +* be called only when Giga Ethernet port is Down
  63094. +*
  63095. +* INPUT:
  63096. +* void* pEthPortHndl - Ethernet Port handler.
  63097. +* MV_BOOL isPromisc - Promiscous mode
  63098. +* MV_TRUE - accept all Broadcast, Multicast
  63099. +* and Unicast packets
  63100. +* MV_FALSE - accept all Broadcast,
  63101. +* specially added Multicast and
  63102. +* single Unicast packets
  63103. +*
  63104. +* RETURN: MV_STATUS MV_OK - Success, Other - Failure
  63105. +*
  63106. +*******************************************************************************/
  63107. +MV_STATUS mvEthRxFilterModeSet(void* pEthPortHndl, MV_BOOL isPromisc)
  63108. +{
  63109. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  63110. + int queue;
  63111. + MV_U32 portCfgReg;
  63112. +
  63113. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  63114. + /* Set / Clear UPM bit in port configuration register */
  63115. + if(isPromisc)
  63116. + {
  63117. + /* Accept all multicast packets to RX default queue */
  63118. + queue = pPortCtrl->portConfig.rxDefQ;
  63119. + portCfgReg |= ETH_UNICAST_PROMISCUOUS_MODE_MASK;
  63120. + memset(pPortCtrl->mcastCount, 1, sizeof(pPortCtrl->mcastCount));
  63121. + MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo),0xFFFF);
  63122. + MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo),0xFFFFFFFF);
  63123. + }
  63124. + else
  63125. + {
  63126. + /* Reject all Multicast addresses */
  63127. + queue = -1;
  63128. + portCfgReg &= ~ETH_UNICAST_PROMISCUOUS_MODE_MASK;
  63129. + /* Clear all mcastCount */
  63130. + memset(pPortCtrl->mcastCount, 0, sizeof(pPortCtrl->mcastCount));
  63131. + }
  63132. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  63133. +
  63134. + /* Set Special Multicast and Other Multicast tables */
  63135. + mvEthSetSpecialMcastTable(pPortCtrl->portNo, queue);
  63136. + mvEthSetOtherMcastTable(pPortCtrl->portNo, queue);
  63137. + ethSetUcastTable(pPortCtrl->portNo, queue);
  63138. +
  63139. + return MV_OK;
  63140. +}
  63141. +
  63142. +/*******************************************************************************
  63143. +* mvEthMacAddrSet - This function Set the port Unicast address.
  63144. +*
  63145. +* DESCRIPTION:
  63146. +* This function Set the port Ethernet MAC address. This address
  63147. +* will be used to send Pause frames if enabled. Packets with this
  63148. +* address will be accepted and dispatched to default RX queue
  63149. +*
  63150. +* INPUT:
  63151. +* void* pEthPortHndl - Ethernet port handler.
  63152. +* char* pAddr - Address to be set
  63153. +*
  63154. +* RETURN: MV_STATUS
  63155. +* MV_OK - Success, Other - Faulure
  63156. +*
  63157. +*******************************************************************************/
  63158. +MV_STATUS mvEthMacAddrSet(void* pPortHndl, unsigned char *pAddr, int queue)
  63159. +{
  63160. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63161. + unsigned int macH;
  63162. + unsigned int macL;
  63163. +
  63164. + if(queue >= MV_ETH_RX_Q_NUM)
  63165. + {
  63166. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", queue);
  63167. + return MV_BAD_PARAM;
  63168. + }
  63169. +
  63170. + if(queue != -1)
  63171. + {
  63172. + macL = (pAddr[4] << 8) | (pAddr[5]);
  63173. + macH = (pAddr[0] << 24)| (pAddr[1] << 16) |
  63174. + (pAddr[2] << 8) | (pAddr[3] << 0);
  63175. +
  63176. + MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo), macL);
  63177. + MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo), macH);
  63178. + }
  63179. +
  63180. + /* Accept frames of this address */
  63181. + ethSetUcastAddr(pPortCtrl->portNo, pAddr[5], queue);
  63182. +
  63183. + return MV_OK;
  63184. +}
  63185. +
  63186. +/*******************************************************************************
  63187. +* mvEthMacAddrGet - This function returns the port Unicast address.
  63188. +*
  63189. +* DESCRIPTION:
  63190. +* This function returns the port Ethernet MAC address.
  63191. +*
  63192. +* INPUT:
  63193. +* int portNo - Ethernet port number.
  63194. +* char* pAddr - Pointer where address will be written to
  63195. +*
  63196. +* RETURN: MV_STATUS
  63197. +* MV_OK - Success, Other - Faulure
  63198. +*
  63199. +*******************************************************************************/
  63200. +MV_STATUS mvEthMacAddrGet(int portNo, unsigned char *pAddr)
  63201. +{
  63202. + unsigned int macH;
  63203. + unsigned int macL;
  63204. +
  63205. + if(pAddr == NULL)
  63206. + {
  63207. + mvOsPrintf("mvEthMacAddrGet: NULL pointer.\n");
  63208. + return MV_BAD_PARAM;
  63209. + }
  63210. +
  63211. + macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(portNo));
  63212. + macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(portNo));
  63213. + pAddr[0] = (macH >> 24) & 0xff;
  63214. + pAddr[1] = (macH >> 16) & 0xff;
  63215. + pAddr[2] = (macH >> 8) & 0xff;
  63216. + pAddr[3] = macH & 0xff;
  63217. + pAddr[4] = (macL >> 8) & 0xff;
  63218. + pAddr[5] = macL & 0xff;
  63219. +
  63220. + return MV_OK;
  63221. +}
  63222. +
  63223. +/*******************************************************************************
  63224. +* mvEthMcastCrc8Get - Calculate CRC8 of MAC address.
  63225. +*
  63226. +* DESCRIPTION:
  63227. +*
  63228. +* INPUT:
  63229. +* MV_U8* pAddr - Address to calculate CRC-8
  63230. +*
  63231. +* RETURN: MV_U8 - CRC-8 of this MAC address
  63232. +*
  63233. +*******************************************************************************/
  63234. +MV_U8 mvEthMcastCrc8Get(MV_U8* pAddr)
  63235. +{
  63236. + unsigned int macH;
  63237. + unsigned int macL;
  63238. + int macArray[48];
  63239. + int crc[8];
  63240. + int i;
  63241. + unsigned char crcResult = 0;
  63242. +
  63243. + /* Calculate CRC-8 out of the given address */
  63244. + macH = (pAddr[0] << 8) | (pAddr[1]);
  63245. + macL = (pAddr[2] << 24)| (pAddr[3] << 16) |
  63246. + (pAddr[4] << 8) | (pAddr[5] << 0);
  63247. +
  63248. + for(i=0; i<32; i++)
  63249. + macArray[i] = (macL >> i) & 0x1;
  63250. +
  63251. + for(i=32; i<48; i++)
  63252. + macArray[i] = (macH >> (i - 32)) & 0x1;
  63253. +
  63254. + crc[0] = macArray[45] ^ macArray[43] ^ macArray[40] ^ macArray[39] ^
  63255. + macArray[35] ^ macArray[34] ^ macArray[31] ^ macArray[30] ^
  63256. + macArray[28] ^ macArray[23] ^ macArray[21] ^ macArray[19] ^
  63257. + macArray[18] ^ macArray[16] ^ macArray[14] ^ macArray[12] ^
  63258. + macArray[8] ^ macArray[7] ^ macArray[6] ^ macArray[0];
  63259. +
  63260. + crc[1] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^
  63261. + macArray[41] ^ macArray[39] ^ macArray[36] ^ macArray[34] ^
  63262. + macArray[32] ^ macArray[30] ^ macArray[29] ^ macArray[28] ^
  63263. + macArray[24] ^ macArray[23] ^ macArray[22] ^ macArray[21] ^
  63264. + macArray[20] ^ macArray[18] ^ macArray[17] ^ macArray[16] ^
  63265. + macArray[15] ^ macArray[14] ^ macArray[13] ^ macArray[12] ^
  63266. + macArray[9] ^ macArray[6] ^ macArray[1] ^ macArray[0];
  63267. +
  63268. + crc[2] = macArray[47] ^ macArray[46] ^ macArray[44] ^ macArray[43] ^
  63269. + macArray[42] ^ macArray[39] ^ macArray[37] ^ macArray[34] ^
  63270. + macArray[33] ^ macArray[29] ^ macArray[28] ^ macArray[25] ^
  63271. + macArray[24] ^ macArray[22] ^ macArray[17] ^ macArray[15] ^
  63272. + macArray[13] ^ macArray[12] ^ macArray[10] ^ macArray[8] ^
  63273. + macArray[6] ^ macArray[2] ^ macArray[1] ^ macArray[0];
  63274. +
  63275. + crc[3] = macArray[47] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^
  63276. + macArray[40] ^ macArray[38] ^ macArray[35] ^ macArray[34] ^
  63277. + macArray[30] ^ macArray[29] ^ macArray[26] ^ macArray[25] ^
  63278. + macArray[23] ^ macArray[18] ^ macArray[16] ^ macArray[14] ^
  63279. + macArray[13] ^ macArray[11] ^ macArray[9] ^ macArray[7] ^
  63280. + macArray[3] ^ macArray[2] ^ macArray[1];
  63281. +
  63282. + crc[4] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[41] ^
  63283. + macArray[39] ^ macArray[36] ^ macArray[35] ^ macArray[31] ^
  63284. + macArray[30] ^ macArray[27] ^ macArray[26] ^ macArray[24] ^
  63285. + macArray[19] ^ macArray[17] ^ macArray[15] ^ macArray[14] ^
  63286. + macArray[12] ^ macArray[10] ^ macArray[8] ^ macArray[4] ^
  63287. + macArray[3] ^ macArray[2];
  63288. +
  63289. + crc[5] = macArray[47] ^ macArray[46] ^ macArray[45] ^ macArray[42] ^
  63290. + macArray[40] ^ macArray[37] ^ macArray[36] ^ macArray[32] ^
  63291. + macArray[31] ^ macArray[28] ^ macArray[27] ^ macArray[25] ^
  63292. + macArray[20] ^ macArray[18] ^ macArray[16] ^ macArray[15] ^
  63293. + macArray[13] ^ macArray[11] ^ macArray[9] ^ macArray[5] ^
  63294. + macArray[4] ^ macArray[3];
  63295. +
  63296. + crc[6] = macArray[47] ^ macArray[46] ^ macArray[43] ^ macArray[41] ^
  63297. + macArray[38] ^ macArray[37] ^ macArray[33] ^ macArray[32] ^
  63298. + macArray[29] ^ macArray[28] ^ macArray[26] ^ macArray[21] ^
  63299. + macArray[19] ^ macArray[17] ^ macArray[16] ^ macArray[14] ^
  63300. + macArray[12] ^ macArray[10] ^ macArray[6] ^ macArray[5] ^
  63301. + macArray[4];
  63302. +
  63303. + crc[7] = macArray[47] ^ macArray[44] ^ macArray[42] ^ macArray[39] ^
  63304. + macArray[38] ^ macArray[34] ^ macArray[33] ^ macArray[30] ^
  63305. + macArray[29] ^ macArray[27] ^ macArray[22] ^ macArray[20] ^
  63306. + macArray[18] ^ macArray[17] ^ macArray[15] ^ macArray[13] ^
  63307. + macArray[11] ^ macArray[7] ^ macArray[6] ^ macArray[5];
  63308. +
  63309. + for(i=0; i<8; i++)
  63310. + crcResult = crcResult | (crc[i] << i);
  63311. +
  63312. + return crcResult;
  63313. +}
  63314. +/*******************************************************************************
  63315. +* mvEthMcastAddrSet - Multicast address settings.
  63316. +*
  63317. +* DESCRIPTION:
  63318. +* This API controls the MV device MAC multicast support.
  63319. +* The MV device supports multicast using two tables:
  63320. +* 1) Special Multicast Table for MAC addresses of the form
  63321. +* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
  63322. +* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
  63323. +* Table entries in the DA-Filter table.
  63324. +* In this case, the function calls ethPortSmcAddr() routine to set the
  63325. +* Special Multicast Table.
  63326. +* 2) Other Multicast Table for multicast of another type. A CRC-8bit
  63327. +* is used as an index to the Other Multicast Table entries in the
  63328. +* DA-Filter table.
  63329. +* In this case, the function calculates the CRC-8bit value and calls
  63330. +* ethPortOmcAddr() routine to set the Other Multicast Table.
  63331. +*
  63332. +* INPUT:
  63333. +* void* pEthPortHndl - Ethernet port handler.
  63334. +* MV_U8* pAddr - Address to be set
  63335. +* int queue - RX queue to capture all packets with this
  63336. +* Multicast MAC address.
  63337. +* -1 means delete this Multicast address.
  63338. +*
  63339. +* RETURN: MV_STATUS
  63340. +* MV_TRUE - Success, Other - Failure
  63341. +*
  63342. +*******************************************************************************/
  63343. +MV_STATUS mvEthMcastAddrSet(void* pPortHndl, MV_U8 *pAddr, int queue)
  63344. +{
  63345. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63346. + unsigned char crcResult = 0;
  63347. +
  63348. + if(queue >= MV_ETH_RX_Q_NUM)
  63349. + {
  63350. + mvOsPrintf("ethPort %d: RX queue #%d is out of range\n",
  63351. + pPortCtrl->portNo, queue);
  63352. + return MV_BAD_PARAM;
  63353. + }
  63354. +
  63355. + if((pAddr[0] == 0x01) &&
  63356. + (pAddr[1] == 0x00) &&
  63357. + (pAddr[2] == 0x5E) &&
  63358. + (pAddr[3] == 0x00) &&
  63359. + (pAddr[4] == 0x00))
  63360. + {
  63361. + ethSetSpecialMcastAddr(pPortCtrl->portNo, pAddr[5], queue);
  63362. + }
  63363. + else
  63364. + {
  63365. + crcResult = mvEthMcastCrc8Get(pAddr);
  63366. +
  63367. + /* Check Add counter for this CRC value */
  63368. + if(queue == -1)
  63369. + {
  63370. + if(pPortCtrl->mcastCount[crcResult] == 0)
  63371. + {
  63372. + mvOsPrintf("ethPort #%d: No valid Mcast for crc8=0x%02x\n",
  63373. + pPortCtrl->portNo, (unsigned)crcResult);
  63374. + return MV_NO_SUCH;
  63375. + }
  63376. +
  63377. + pPortCtrl->mcastCount[crcResult]--;
  63378. + if(pPortCtrl->mcastCount[crcResult] != 0)
  63379. + {
  63380. + mvOsPrintf("ethPort #%d: After delete there are %d valid Mcast for crc8=0x%02x\n",
  63381. + pPortCtrl->portNo, pPortCtrl->mcastCount[crcResult],
  63382. + (unsigned)crcResult);
  63383. + return MV_NO_CHANGE;
  63384. + }
  63385. + }
  63386. + else
  63387. + {
  63388. + pPortCtrl->mcastCount[crcResult]++;
  63389. + if(pPortCtrl->mcastCount[crcResult] > 1)
  63390. + {
  63391. + mvOsPrintf("ethPort #%d: Valid Mcast for crc8=0x%02x already exists\n",
  63392. + pPortCtrl->portNo, (unsigned)crcResult);
  63393. + return MV_NO_CHANGE;
  63394. + }
  63395. + }
  63396. + ethSetOtherMcastAddr(pPortCtrl->portNo, crcResult, queue);
  63397. + }
  63398. + return MV_OK;
  63399. +}
  63400. +
  63401. +/*******************************************************************************
  63402. +* ethSetUcastTable - Unicast address settings.
  63403. +*
  63404. +* DESCRIPTION:
  63405. +* Set all entries in the Unicast MAC Table queue==-1 means reject all
  63406. +* INPUT:
  63407. +*
  63408. +* RETURN:
  63409. +*
  63410. +*******************************************************************************/
  63411. +static void ethSetUcastTable(int portNo, int queue)
  63412. +{
  63413. + int offset;
  63414. + MV_U32 regValue;
  63415. +
  63416. + if(queue == -1)
  63417. + {
  63418. + regValue = 0;
  63419. + }
  63420. + else
  63421. + {
  63422. + regValue = (((0x01 | (queue<<1)) << 0) |
  63423. + ((0x01 | (queue<<1)) << 8) |
  63424. + ((0x01 | (queue<<1)) << 16) |
  63425. + ((0x01 | (queue<<1)) << 24));
  63426. + }
  63427. +
  63428. + for (offset=0; offset<=0xC; offset+=4)
  63429. + MV_REG_WRITE((ETH_DA_FILTER_UCAST_BASE(portNo) + offset), regValue);
  63430. +}
  63431. +
  63432. +/*******************************************************************************
  63433. +* mvEthSetSpecialMcastTable - Special Multicast address settings.
  63434. +*
  63435. +* DESCRIPTION:
  63436. +* Set all entries to the Special Multicast MAC Table. queue==-1 means reject all
  63437. +* INPUT:
  63438. +*
  63439. +* RETURN:
  63440. +*
  63441. +*******************************************************************************/
  63442. +MV_VOID mvEthSetSpecialMcastTable(int portNo, int queue)
  63443. +{
  63444. + int offset;
  63445. + MV_U32 regValue;
  63446. +
  63447. + if(queue == -1)
  63448. + {
  63449. + regValue = 0;
  63450. + }
  63451. + else
  63452. + {
  63453. + regValue = (((0x01 | (queue<<1)) << 0) |
  63454. + ((0x01 | (queue<<1)) << 8) |
  63455. + ((0x01 | (queue<<1)) << 16) |
  63456. + ((0x01 | (queue<<1)) << 24));
  63457. + }
  63458. +
  63459. + for (offset=0; offset<=0xFC; offset+=4)
  63460. + {
  63461. + MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(portNo) +
  63462. + offset), regValue);
  63463. + }
  63464. +}
  63465. +
  63466. +/*******************************************************************************
  63467. +* mvEthSetOtherMcastTable - Other Multicast address settings.
  63468. +*
  63469. +* DESCRIPTION:
  63470. +* Set all entries to the Other Multicast MAC Table. queue==-1 means reject all
  63471. +* INPUT:
  63472. +*
  63473. +* RETURN:
  63474. +*
  63475. +*******************************************************************************/
  63476. +MV_VOID mvEthSetOtherMcastTable(int portNo, int queue)
  63477. +{
  63478. + int offset;
  63479. + MV_U32 regValue;
  63480. +
  63481. + if(queue == -1)
  63482. + {
  63483. + regValue = 0;
  63484. + }
  63485. + else
  63486. + {
  63487. + regValue = (((0x01 | (queue<<1)) << 0) |
  63488. + ((0x01 | (queue<<1)) << 8) |
  63489. + ((0x01 | (queue<<1)) << 16) |
  63490. + ((0x01 | (queue<<1)) << 24));
  63491. + }
  63492. +
  63493. + for (offset=0; offset<=0xFC; offset+=4)
  63494. + {
  63495. + MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(portNo) +
  63496. + offset), regValue);
  63497. + }
  63498. +}
  63499. +
  63500. +/*******************************************************************************
  63501. +* ethSetUcastAddr - This function Set the port unicast address table
  63502. +*
  63503. +* DESCRIPTION:
  63504. +* This function locates the proper entry in the Unicast table for the
  63505. +* specified MAC nibble and sets its properties according to function
  63506. +* parameters.
  63507. +*
  63508. +* INPUT:
  63509. +* int ethPortNum - Port number.
  63510. +* MV_U8 lastNibble - Unicast MAC Address last nibble.
  63511. +* int queue - Rx queue number for this MAC address.
  63512. +* value "-1" means remove address
  63513. +*
  63514. +* OUTPUT:
  63515. +* This function add/removes MAC addresses from the port unicast address
  63516. +* table.
  63517. +*
  63518. +* RETURN:
  63519. +* MV_TRUE is output succeeded.
  63520. +* MV_FALSE if option parameter is invalid.
  63521. +*
  63522. +*******************************************************************************/
  63523. +static MV_BOOL ethSetUcastAddr(int portNo, MV_U8 lastNibble, int queue)
  63524. +{
  63525. + unsigned int unicastReg;
  63526. + unsigned int tblOffset;
  63527. + unsigned int regOffset;
  63528. +
  63529. + /* Locate the Unicast table entry */
  63530. + lastNibble = (0xf & lastNibble);
  63531. + tblOffset = (lastNibble / 4) * 4; /* Register offset from unicast table base*/
  63532. + regOffset = lastNibble % 4; /* Entry offset within the above register */
  63533. +
  63534. +
  63535. + unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(portNo) +
  63536. + tblOffset));
  63537. +
  63538. +
  63539. + if(queue == -1)
  63540. + {
  63541. + /* Clear accepts frame bit at specified unicast DA table entry */
  63542. + unicastReg &= ~(0xFF << (8*regOffset));
  63543. + }
  63544. + else
  63545. + {
  63546. + unicastReg &= ~(0xFF << (8*regOffset));
  63547. + unicastReg |= ((0x01 | (queue<<1)) << (8*regOffset));
  63548. + }
  63549. + MV_REG_WRITE( (ETH_DA_FILTER_UCAST_BASE(portNo) + tblOffset),
  63550. + unicastReg);
  63551. +
  63552. + return MV_TRUE;
  63553. +}
  63554. +
  63555. +/*******************************************************************************
  63556. +* ethSetSpecialMcastAddr - Special Multicast address settings.
  63557. +*
  63558. +* DESCRIPTION:
  63559. +* This routine controls the MV device special MAC multicast support.
  63560. +* The Special Multicast Table for MAC addresses supports MAC of the form
  63561. +* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
  63562. +* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
  63563. +* Table entries in the DA-Filter table.
  63564. +* This function set the Special Multicast Table appropriate entry
  63565. +* according to the argument given.
  63566. +*
  63567. +* INPUT:
  63568. +* int ethPortNum Port number.
  63569. +* unsigned char mcByte Multicast addr last byte (MAC DA[7:0] bits).
  63570. +* int queue Rx queue number for this MAC address.
  63571. +* int option 0 = Add, 1 = remove address.
  63572. +*
  63573. +* OUTPUT:
  63574. +* See description.
  63575. +*
  63576. +* RETURN:
  63577. +* MV_TRUE is output succeeded.
  63578. +* MV_FALSE if option parameter is invalid.
  63579. +*
  63580. +*******************************************************************************/
  63581. +static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue)
  63582. +{
  63583. + unsigned int smcTableReg;
  63584. + unsigned int tblOffset;
  63585. + unsigned int regOffset;
  63586. +
  63587. + /* Locate the SMC table entry */
  63588. + tblOffset = (lastByte / 4); /* Register offset from SMC table base */
  63589. + regOffset = lastByte % 4; /* Entry offset within the above register */
  63590. +
  63591. + smcTableReg = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) + tblOffset*4));
  63592. +
  63593. + if(queue == -1)
  63594. + {
  63595. + /* Clear accepts frame bit at specified Special DA table entry */
  63596. + smcTableReg &= ~(0xFF << (8 * regOffset));
  63597. + }
  63598. + else
  63599. + {
  63600. + smcTableReg &= ~(0xFF << (8 * regOffset));
  63601. + smcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));
  63602. + }
  63603. + MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) +
  63604. + tblOffset*4), smcTableReg);
  63605. +
  63606. + return MV_TRUE;
  63607. +}
  63608. +
  63609. +/*******************************************************************************
  63610. +* ethSetOtherMcastAddr - Multicast address settings.
  63611. +*
  63612. +* DESCRIPTION:
  63613. +* This routine controls the MV device Other MAC multicast support.
  63614. +* The Other Multicast Table is used for multicast of another type.
  63615. +* A CRC-8bit is used as an index to the Other Multicast Table entries
  63616. +* in the DA-Filter table.
  63617. +* The function gets the CRC-8bit value from the calling routine and
  63618. +* set the Other Multicast Table appropriate entry according to the
  63619. +* CRC-8 argument given.
  63620. +*
  63621. +* INPUT:
  63622. +* int ethPortNum Port number.
  63623. +* MV_U8 crc8 A CRC-8bit (Polynomial: x^8+x^2+x^1+1).
  63624. +* int queue Rx queue number for this MAC address.
  63625. +*
  63626. +* OUTPUT:
  63627. +* See description.
  63628. +*
  63629. +* RETURN:
  63630. +* MV_TRUE is output succeeded.
  63631. +* MV_FALSE if option parameter is invalid.
  63632. +*
  63633. +*******************************************************************************/
  63634. +static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue)
  63635. +{
  63636. + unsigned int omcTableReg;
  63637. + unsigned int tblOffset;
  63638. + unsigned int regOffset;
  63639. +
  63640. + /* Locate the OMC table entry */
  63641. + tblOffset = (crc8 / 4) * 4; /* Register offset from OMC table base */
  63642. + regOffset = crc8 % 4; /* Entry offset within the above register */
  63643. +
  63644. + omcTableReg = MV_REG_READ(
  63645. + (ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset));
  63646. +
  63647. + if(queue == -1)
  63648. + {
  63649. + /* Clear accepts frame bit at specified Other DA table entry */
  63650. + omcTableReg &= ~(0xFF << (8 * regOffset));
  63651. + }
  63652. + else
  63653. + {
  63654. + omcTableReg &= ~(0xFF << (8 * regOffset));
  63655. + omcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));
  63656. + }
  63657. +
  63658. + MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset),
  63659. + omcTableReg);
  63660. +
  63661. + return MV_TRUE;
  63662. +}
  63663. +
  63664. +
  63665. +/******************************************************************************/
  63666. +/* MIB Counters functions */
  63667. +/******************************************************************************/
  63668. +
  63669. +
  63670. +/*******************************************************************************
  63671. +* mvEthMibCounterRead - Read a MIB counter
  63672. +*
  63673. +* DESCRIPTION:
  63674. +* This function reads a MIB counter of a specific ethernet port.
  63675. +* NOTE - Read from ETH_MIB_GOOD_OCTETS_RECEIVED_LOW or
  63676. +* ETH_MIB_GOOD_OCTETS_SENT_LOW counters will return 64 bits value,
  63677. +* so pHigh32 pointer should not be NULL in this case.
  63678. +*
  63679. +* INPUT:
  63680. +* int ethPortNum - Ethernet Port number.
  63681. +* unsigned int mibOffset - MIB counter offset.
  63682. +*
  63683. +* OUTPUT:
  63684. +* MV_U32* pHigh32 - pointer to place where 32 most significant bits
  63685. +* of the counter will be stored.
  63686. +*
  63687. +* RETURN:
  63688. +* 32 low sgnificant bits of MIB counter value.
  63689. +*
  63690. +*******************************************************************************/
  63691. +MV_U32 mvEthMibCounterRead(void* pPortHandle, unsigned int mibOffset,
  63692. + MV_U32* pHigh32)
  63693. +{
  63694. + int portNo;
  63695. + MV_U32 valLow32, valHigh32;
  63696. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63697. +
  63698. + portNo = pPortCtrl->portNo;
  63699. +
  63700. + valLow32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset);
  63701. +
  63702. + /* Implement FEr ETH. Erroneous Value when Reading the Upper 32-bits */
  63703. + /* of a 64-bit MIB Counter. */
  63704. + if( (mibOffset == ETH_MIB_GOOD_OCTETS_RECEIVED_LOW) ||
  63705. + (mibOffset == ETH_MIB_GOOD_OCTETS_SENT_LOW) )
  63706. + {
  63707. + valHigh32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset + 4);
  63708. + if(pHigh32 != NULL)
  63709. + *pHigh32 = valHigh32;
  63710. + }
  63711. + return valLow32;
  63712. +}
  63713. +
  63714. +/*******************************************************************************
  63715. +* mvEthMibCountersClear - Clear all MIB counters
  63716. +*
  63717. +* DESCRIPTION:
  63718. +* This function clears all MIB counters
  63719. +*
  63720. +* INPUT:
  63721. +* int ethPortNum - Ethernet Port number.
  63722. +*
  63723. +*
  63724. +* RETURN: void
  63725. +*
  63726. +*******************************************************************************/
  63727. +void mvEthMibCountersClear(void* pPortHandle)
  63728. +{
  63729. + int i, portNo;
  63730. + unsigned int dummy;
  63731. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63732. +
  63733. + portNo = pPortCtrl->portNo;
  63734. +
  63735. + /* Perform dummy reads from MIB counters */
  63736. + for(i=ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i<ETH_MIB_LATE_COLLISION; i+=4)
  63737. + dummy = MV_REG_READ((ETH_MIB_COUNTERS_BASE(portNo) + i));
  63738. +}
  63739. +
  63740. +
  63741. +/******************************************************************************/
  63742. +/* RX Dispatching configuration routines */
  63743. +/******************************************************************************/
  63744. +
  63745. +int mvEthTosToRxqGet(void* pPortHandle, int tos)
  63746. +{
  63747. + MV_U32 regValue;
  63748. + int regIdx, regOffs, rxq;
  63749. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63750. +
  63751. + if(tos > 0xFF)
  63752. + {
  63753. + mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);
  63754. + return -1;
  63755. + }
  63756. + regIdx = mvOsDivide(tos>>2, 10);
  63757. + regOffs = mvOsReminder(tos>>2, 10);
  63758. +
  63759. + regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );
  63760. + rxq = (regValue >> (regOffs*3));
  63761. + rxq &= 0x7;
  63762. +
  63763. + return rxq;
  63764. +}
  63765. +
  63766. +/*******************************************************************************
  63767. +* mvEthTosToRxqSet - Map packets with special TOS value to special RX queue
  63768. +*
  63769. +* DESCRIPTION:
  63770. +*
  63771. +* INPUT:
  63772. +* void* pPortHandle - Pointer to port specific handler;
  63773. +* int tos - TOS value in the IP header of the packet
  63774. +* int rxq - RX Queue for packets with the configured TOS value
  63775. +* Negative value (-1) means no special processing for these packets,
  63776. +* so they will be processed as regular packets.
  63777. +*
  63778. +* RETURN: MV_STATUS
  63779. +*******************************************************************************/
  63780. +MV_STATUS mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq)
  63781. +{
  63782. + MV_U32 regValue;
  63783. + int regIdx, regOffs;
  63784. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63785. +
  63786. + if( (rxq < 0) || (rxq >= MV_ETH_RX_Q_NUM) )
  63787. + {
  63788. + mvOsPrintf("eth_%d: RX queue #%d is out of range\n", pPortCtrl->portNo, rxq);
  63789. + return MV_BAD_PARAM;
  63790. + }
  63791. + if(tos > 0xFF)
  63792. + {
  63793. + mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);
  63794. + return MV_BAD_PARAM;
  63795. + }
  63796. + regIdx = mvOsDivide(tos>>2, 10);
  63797. + regOffs = mvOsReminder(tos>>2, 10);
  63798. +
  63799. + regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );
  63800. + regValue &= ~(0x7 << (regOffs*3));
  63801. + regValue |= (rxq << (regOffs*3));
  63802. +
  63803. + MV_REG_WRITE(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx), regValue);
  63804. + return MV_OK;
  63805. +}
  63806. +
  63807. +/*******************************************************************************
  63808. +* mvEthVlanPrioRxQueue - Configure RX queue to capture VLAN tagged packets with
  63809. +* special priority bits [0-2]
  63810. +*
  63811. +* DESCRIPTION:
  63812. +*
  63813. +* INPUT:
  63814. +* void* pPortHandle - Pointer to port specific handler;
  63815. +* int bpduQueue - Special queue to capture VLAN tagged packets with special
  63816. +* priority.
  63817. +* Negative value (-1) means no special processing for these packets,
  63818. +* so they will be processed as regular packets.
  63819. +*
  63820. +* RETURN: MV_STATUS
  63821. +* MV_OK - Success
  63822. +* MV_FAIL - Failed.
  63823. +*
  63824. +*******************************************************************************/
  63825. +MV_STATUS mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue)
  63826. +{
  63827. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63828. + MV_U32 vlanPrioReg;
  63829. +
  63830. + if(vlanPrioQueue >= MV_ETH_RX_Q_NUM)
  63831. + {
  63832. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", vlanPrioQueue);
  63833. + return MV_BAD_PARAM;
  63834. + }
  63835. + if(vlanPrio >= 8)
  63836. + {
  63837. + mvOsPrintf("ethDrv: vlanPrio=%d is out of range\n", vlanPrio);
  63838. + return MV_BAD_PARAM;
  63839. + }
  63840. +
  63841. + vlanPrioReg = MV_REG_READ(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo));
  63842. + vlanPrioReg &= ~(0x7 << (vlanPrio*3));
  63843. + vlanPrioReg |= (vlanPrioQueue << (vlanPrio*3));
  63844. + MV_REG_WRITE(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo), vlanPrioReg);
  63845. +
  63846. + return MV_OK;
  63847. +}
  63848. +
  63849. +
  63850. +/*******************************************************************************
  63851. +* mvEthBpduRxQueue - Configure RX queue to capture BPDU packets.
  63852. +*
  63853. +* DESCRIPTION:
  63854. +* This function defines processing of BPDU packets.
  63855. +* BPDU packets can be accepted and captured to one of RX queues
  63856. +* or can be processing as regular Multicast packets.
  63857. +*
  63858. +* INPUT:
  63859. +* void* pPortHandle - Pointer to port specific handler;
  63860. +* int bpduQueue - Special queue to capture BPDU packets (DA is equal to
  63861. +* 01-80-C2-00-00-00 through 01-80-C2-00-00-FF,
  63862. +* except for the Flow-Control Pause packets).
  63863. +* Negative value (-1) means no special processing for BPDU,
  63864. +* packets so they will be processed as regular Multicast packets.
  63865. +*
  63866. +* RETURN: MV_STATUS
  63867. +* MV_OK - Success
  63868. +* MV_FAIL - Failed.
  63869. +*
  63870. +*******************************************************************************/
  63871. +MV_STATUS mvEthBpduRxQueue(void* pPortHandle, int bpduQueue)
  63872. +{
  63873. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63874. + MV_U32 portCfgReg;
  63875. + MV_U32 portCfgExtReg;
  63876. +
  63877. + if(bpduQueue >= MV_ETH_RX_Q_NUM)
  63878. + {
  63879. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", bpduQueue);
  63880. + return MV_BAD_PARAM;
  63881. + }
  63882. +
  63883. + portCfgExtReg = MV_REG_READ(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo));
  63884. +
  63885. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  63886. + if(bpduQueue >= 0)
  63887. + {
  63888. + pPortCtrl->portConfig.rxBpduQ = bpduQueue;
  63889. +
  63890. + portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;
  63891. + portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);
  63892. +
  63893. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  63894. +
  63895. + portCfgExtReg |= ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK;
  63896. + }
  63897. + else
  63898. + {
  63899. + pPortCtrl->portConfig.rxBpduQ = -1;
  63900. + /* no special processing for BPDU packets */
  63901. + portCfgExtReg &= (~ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK);
  63902. + }
  63903. +
  63904. + MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo), portCfgExtReg);
  63905. +
  63906. + return MV_OK;
  63907. +}
  63908. +
  63909. +
  63910. +/*******************************************************************************
  63911. +* mvEthArpRxQueue - Configure RX queue to capture ARP packets.
  63912. +*
  63913. +* DESCRIPTION:
  63914. +* This function defines processing of ARP (type=0x0806) packets.
  63915. +* ARP packets can be accepted and captured to one of RX queues
  63916. +* or can be processed as other Broadcast packets.
  63917. +*
  63918. +* INPUT:
  63919. +* void* pPortHandle - Pointer to port specific handler;
  63920. +* int arpQueue - Special queue to capture ARP packets (type=0x806).
  63921. +* Negative value (-1) means discard ARP packets
  63922. +*
  63923. +* RETURN: MV_STATUS
  63924. +* MV_OK - Success
  63925. +* MV_FAIL - Failed.
  63926. +*
  63927. +*******************************************************************************/
  63928. +MV_STATUS mvEthArpRxQueue(void* pPortHandle, int arpQueue)
  63929. +{
  63930. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63931. + MV_U32 portCfgReg;
  63932. +
  63933. + if(arpQueue >= MV_ETH_RX_Q_NUM)
  63934. + {
  63935. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", arpQueue);
  63936. + return MV_BAD_PARAM;
  63937. + }
  63938. +
  63939. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  63940. +
  63941. + if(arpQueue >= 0)
  63942. + {
  63943. + pPortCtrl->portConfig.rxArpQ = arpQueue;
  63944. + portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;
  63945. + portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ);
  63946. +
  63947. + portCfgReg &= (~ETH_REJECT_ARP_BCAST_MASK);
  63948. + }
  63949. + else
  63950. + {
  63951. + pPortCtrl->portConfig.rxArpQ = -1;
  63952. + portCfgReg |= ETH_REJECT_ARP_BCAST_MASK;
  63953. + }
  63954. +
  63955. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  63956. +
  63957. + return MV_OK;
  63958. +}
  63959. +
  63960. +
  63961. +/*******************************************************************************
  63962. +* mvEthTcpRxQueue - Configure RX queue to capture TCP packets.
  63963. +*
  63964. +* DESCRIPTION:
  63965. +* This function defines processing of TCP packets.
  63966. +* TCP packets can be accepted and captured to one of RX queues
  63967. +* or can be processed as regular Unicast packets.
  63968. +*
  63969. +* INPUT:
  63970. +* void* pPortHandle - Pointer to port specific handler;
  63971. +* int tcpQueue - Special queue to capture TCP packets. Value "-1"
  63972. +* means no special processing for TCP packets,
  63973. +* so they will be processed as regular
  63974. +*
  63975. +* RETURN: MV_STATUS
  63976. +* MV_OK - Success
  63977. +* MV_FAIL - Failed.
  63978. +*
  63979. +*******************************************************************************/
  63980. +MV_STATUS mvEthTcpRxQueue(void* pPortHandle, int tcpQueue)
  63981. +{
  63982. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63983. + MV_U32 portCfgReg;
  63984. +
  63985. + if(tcpQueue >= MV_ETH_RX_Q_NUM)
  63986. + {
  63987. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", tcpQueue);
  63988. + return MV_BAD_PARAM;
  63989. + }
  63990. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  63991. +
  63992. + if(tcpQueue >= 0)
  63993. + {
  63994. + pPortCtrl->portConfig.rxTcpQ = tcpQueue;
  63995. + portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;
  63996. + portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);
  63997. +
  63998. + portCfgReg |= ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK;
  63999. + }
  64000. + else
  64001. + {
  64002. + pPortCtrl->portConfig.rxTcpQ = -1;
  64003. + portCfgReg &= (~ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK);
  64004. + }
  64005. +
  64006. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  64007. +
  64008. + return MV_OK;
  64009. +}
  64010. +
  64011. +
  64012. +/*******************************************************************************
  64013. +* mvEthUdpRxQueue - Configure RX queue to capture UDP packets.
  64014. +*
  64015. +* DESCRIPTION:
  64016. +* This function defines processing of UDP packets.
  64017. +* TCP packets can be accepted and captured to one of RX queues
  64018. +* or can be processed as regular Unicast packets.
  64019. +*
  64020. +* INPUT:
  64021. +* void* pPortHandle - Pointer to port specific handler;
  64022. +* int udpQueue - Special queue to capture UDP packets. Value "-1"
  64023. +* means no special processing for UDP packets,
  64024. +* so they will be processed as regular
  64025. +*
  64026. +* RETURN: MV_STATUS
  64027. +* MV_OK - Success
  64028. +* MV_FAIL - Failed.
  64029. +*
  64030. +*******************************************************************************/
  64031. +MV_STATUS mvEthUdpRxQueue(void* pPortHandle, int udpQueue)
  64032. +{
  64033. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64034. + MV_U32 portCfgReg;
  64035. +
  64036. + if(udpQueue >= MV_ETH_RX_Q_NUM)
  64037. + {
  64038. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", udpQueue);
  64039. + return MV_BAD_PARAM;
  64040. + }
  64041. +
  64042. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  64043. +
  64044. + if(udpQueue >= 0)
  64045. + {
  64046. + pPortCtrl->portConfig.rxUdpQ = udpQueue;
  64047. + portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;
  64048. + portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);
  64049. +
  64050. + portCfgReg |= ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;
  64051. + }
  64052. + else
  64053. + {
  64054. + pPortCtrl->portConfig.rxUdpQ = -1;
  64055. + portCfgReg &= ~ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;
  64056. + }
  64057. +
  64058. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  64059. +
  64060. + return MV_OK;
  64061. +}
  64062. +
  64063. +
  64064. +/******************************************************************************/
  64065. +/* Speed, Duplex, FlowControl routines */
  64066. +/******************************************************************************/
  64067. +
  64068. +/*******************************************************************************
  64069. +* mvEthSpeedDuplexSet - Set Speed and Duplex of the port.
  64070. +*
  64071. +* DESCRIPTION:
  64072. +* This function configure the port to work with desirable Duplex and Speed.
  64073. +* Changing of these parameters are allowed only when port is disabled.
  64074. +* This function disable the port if was enabled, change duplex and speed
  64075. +* and, enable the port back if needed.
  64076. +*
  64077. +* INPUT:
  64078. +* void* pPortHandle - Pointer to port specific handler;
  64079. +* ETH_PORT_SPEED speed - Speed of the port.
  64080. +* ETH_PORT_SPEED duplex - Duplex of the port.
  64081. +*
  64082. +* RETURN: MV_STATUS
  64083. +* MV_OK - Success
  64084. +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
  64085. +* MV_NOT_FOUND - Failed. Port is not initialized.
  64086. +* MV_BAD_PARAM - Input parameters (speed/duplex) in conflict.
  64087. +* MV_BAD_VALUE - Value of one of input parameters (speed, duplex)
  64088. +* is not valid
  64089. +*
  64090. +*******************************************************************************/
  64091. +MV_STATUS mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed,
  64092. + MV_ETH_PORT_DUPLEX duplex)
  64093. +{
  64094. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64095. + int port = pPortCtrl->portNo;
  64096. + MV_U32 portSerialCtrlReg;
  64097. +
  64098. + if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet()) )
  64099. + return MV_OUT_OF_RANGE;
  64100. +
  64101. + pPortCtrl = ethPortCtrl[port];
  64102. + if(pPortCtrl == NULL)
  64103. + return MV_NOT_FOUND;
  64104. +
  64105. + /* Check validity */
  64106. + if( (speed == MV_ETH_SPEED_1000) && (duplex == MV_ETH_DUPLEX_HALF) )
  64107. + return MV_BAD_PARAM;
  64108. +
  64109. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
  64110. + /* Set Speed */
  64111. + switch(speed)
  64112. + {
  64113. + case MV_ETH_SPEED_AN:
  64114. + portSerialCtrlReg &= ~ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  64115. + break;
  64116. +
  64117. + case MV_ETH_SPEED_10:
  64118. + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  64119. + portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;
  64120. + portSerialCtrlReg &= ~ETH_SET_MII_SPEED_100_MASK;
  64121. + break;
  64122. +
  64123. + case MV_ETH_SPEED_100:
  64124. + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  64125. + portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;
  64126. + portSerialCtrlReg |= ETH_SET_MII_SPEED_100_MASK;
  64127. + break;
  64128. +
  64129. + case MV_ETH_SPEED_1000:
  64130. + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  64131. + portSerialCtrlReg |= ETH_SET_GMII_SPEED_1000_MASK;
  64132. + break;
  64133. +
  64134. + default:
  64135. + mvOsPrintf("ethDrv: Unexpected Speed value %d\n", speed);
  64136. + return MV_BAD_VALUE;
  64137. + }
  64138. + /* Set duplex */
  64139. + switch(duplex)
  64140. + {
  64141. + case MV_ETH_DUPLEX_AN:
  64142. + portSerialCtrlReg &= ~ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
  64143. + break;
  64144. +
  64145. + case MV_ETH_DUPLEX_HALF:
  64146. + portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
  64147. + portSerialCtrlReg &= ~ETH_SET_FULL_DUPLEX_MASK;
  64148. + break;
  64149. +
  64150. + case MV_ETH_DUPLEX_FULL:
  64151. + portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
  64152. + portSerialCtrlReg |= ETH_SET_FULL_DUPLEX_MASK;
  64153. + break;
  64154. +
  64155. + default:
  64156. + mvOsPrintf("ethDrv: Unexpected Duplex value %d\n", duplex);
  64157. + return MV_BAD_VALUE;
  64158. + }
  64159. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);
  64160. +
  64161. + return MV_OK;
  64162. +}
  64163. +
  64164. +/*******************************************************************************
  64165. +* mvEthFlowCtrlSet - Set Flow Control of the port.
  64166. +*
  64167. +* DESCRIPTION:
  64168. +* This function configure the port to work with desirable Duplex and
  64169. +* Speed. Changing of these parameters are allowed only when port is
  64170. +* disabled. This function disable the port if was enabled, change
  64171. +* duplex and speed and, enable the port back if needed.
  64172. +*
  64173. +* INPUT:
  64174. +* void* pPortHandle - Pointer to port specific handler;
  64175. +* MV_ETH_PORT_FC flowControl - Flow control of the port.
  64176. +*
  64177. +* RETURN: MV_STATUS
  64178. +* MV_OK - Success
  64179. +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
  64180. +* MV_NOT_FOUND - Failed. Port is not initialized.
  64181. +* MV_BAD_VALUE - Value flowControl parameters is not valid
  64182. +*
  64183. +*******************************************************************************/
  64184. +MV_STATUS mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl)
  64185. +{
  64186. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64187. + int port = pPortCtrl->portNo;
  64188. + MV_U32 portSerialCtrlReg;
  64189. +
  64190. + if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet() ) )
  64191. + return MV_OUT_OF_RANGE;
  64192. +
  64193. + pPortCtrl = ethPortCtrl[port];
  64194. + if(pPortCtrl == NULL)
  64195. + return MV_NOT_FOUND;
  64196. +
  64197. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
  64198. + switch(flowControl)
  64199. + {
  64200. + case MV_ETH_FC_AN_ADV_DIS:
  64201. + portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;
  64202. + portSerialCtrlReg &= ~ETH_ADVERTISE_SYM_FC_MASK;
  64203. + break;
  64204. +
  64205. + case MV_ETH_FC_AN_ADV_SYM:
  64206. + portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;
  64207. + portSerialCtrlReg |= ETH_ADVERTISE_SYM_FC_MASK;
  64208. + break;
  64209. +
  64210. + case MV_ETH_FC_DISABLE:
  64211. + portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;
  64212. + portSerialCtrlReg &= ~ETH_SET_FLOW_CTRL_MASK;
  64213. + break;
  64214. +
  64215. + case MV_ETH_FC_ENABLE:
  64216. + portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;
  64217. + portSerialCtrlReg |= ETH_SET_FLOW_CTRL_MASK;
  64218. + break;
  64219. +
  64220. + default:
  64221. + mvOsPrintf("ethDrv: Unexpected FlowControl value %d\n", flowControl);
  64222. + return MV_BAD_VALUE;
  64223. + }
  64224. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);
  64225. +
  64226. + return MV_OK;
  64227. +}
  64228. +
  64229. +/*******************************************************************************
  64230. +* mvEthHeaderModeSet - Set port header mode.
  64231. +*
  64232. +* DESCRIPTION:
  64233. +* This function configures the port to work in Marvell-Header mode.
  64234. +*
  64235. +* INPUT:
  64236. +* void* pPortHandle - Pointer to port specific handler;
  64237. +* MV_ETH_HEADER_MODE headerMode - The header mode to set the port in.
  64238. +*
  64239. +* RETURN: MV_STATUS
  64240. +* MV_OK - Success
  64241. +* MV_NOT_SUPPORTED- Feature not supported.
  64242. +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
  64243. +* MV_NOT_FOUND - Failed. Port is not initialized.
  64244. +* MV_BAD_VALUE - Value of headerMode or numRxQueue parameter is not valid.
  64245. +*
  64246. +*******************************************************************************/
  64247. +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode)
  64248. +{
  64249. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64250. + int port = pPortCtrl->portNo;
  64251. + MV_U32 mvHeaderReg;
  64252. + MV_U32 numRxQ = MV_ETH_RX_Q_NUM;
  64253. +
  64254. + if((port < 0) || (port >= mvCtrlEthMaxPortGet()))
  64255. + return MV_OUT_OF_RANGE;
  64256. +
  64257. + pPortCtrl = ethPortCtrl[port];
  64258. + if(pPortCtrl == NULL)
  64259. + return MV_NOT_FOUND;
  64260. +
  64261. + mvHeaderReg = MV_REG_READ(ETH_PORT_MARVELL_HEADER_REG(port));
  64262. + /* Disable header mode. */
  64263. + mvHeaderReg &= ~ETH_MVHDR_EN_MASK;
  64264. +
  64265. + if(headerMode != MV_ETH_DISABLE_HEADER_MODE)
  64266. + {
  64267. + /* Enable Header mode. */
  64268. + mvHeaderReg |= ETH_MVHDR_EN_MASK;
  64269. +
  64270. + /* Clear DA-Prefix & MHMask fields.*/
  64271. + mvHeaderReg &= ~(ETH_MVHDR_DAPREFIX_MASK | ETH_MVHDR_MHMASK_MASK);
  64272. +
  64273. + if(numRxQ > 1)
  64274. + {
  64275. + switch (headerMode)
  64276. + {
  64277. + case(MV_ETH_ENABLE_HEADER_MODE_PRI_2_1):
  64278. + mvHeaderReg |= ETH_MVHDR_DAPREFIX_PRI_1_2;
  64279. + break;
  64280. + case(MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM):
  64281. + mvHeaderReg |= ETH_MVHDR_DAPREFIX_DBNUM_PRI;
  64282. + break;
  64283. + case(MV_ETH_ENABLE_HEADER_MODE_PRI_SPID):
  64284. + mvHeaderReg |= ETH_MVHDR_DAPREFIX_SPID_PRI;
  64285. + break;
  64286. + default:
  64287. + break;
  64288. + }
  64289. +
  64290. + switch (numRxQ)
  64291. + {
  64292. + case (4):
  64293. + mvHeaderReg |= ETH_MVHDR_MHMASK_4_QUEUE;
  64294. + break;
  64295. + case (8):
  64296. + mvHeaderReg |= ETH_MVHDR_MHMASK_8_QUEUE;
  64297. + break;
  64298. + default:
  64299. + break;
  64300. + }
  64301. + }
  64302. + }
  64303. +
  64304. + MV_REG_WRITE(ETH_PORT_MARVELL_HEADER_REG(port), mvHeaderReg);
  64305. +
  64306. + return MV_OK;
  64307. +}
  64308. +
  64309. +#if (MV_ETH_VERSION >= 4)
  64310. +/*******************************************************************************
  64311. +* mvEthEjpModeSet - Enable / Disable EJP policy for TX.
  64312. +*
  64313. +* DESCRIPTION:
  64314. +* This function
  64315. +*
  64316. +* INPUT:
  64317. +* void* pPortHandle - Pointer to port specific handler;
  64318. +* MV_BOOL TRUE - enable EJP mode
  64319. +* FALSE - disable EJP mode
  64320. +*
  64321. +* OUTPUT: MV_STATUS
  64322. +* MV_OK - Success
  64323. +* Other - Failure
  64324. +*
  64325. +* RETURN: None.
  64326. +*
  64327. +*******************************************************************************/
  64328. +MV_STATUS mvEthEjpModeSet(void* pPortHandle, int mode)
  64329. +{
  64330. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64331. + int port = pPortCtrl->portNo;
  64332. +
  64333. + if((port < 0) || (port >= mvCtrlEthMaxPortGet()))
  64334. + return MV_OUT_OF_RANGE;
  64335. +
  64336. + pPortCtrl = ethPortCtrl[port];
  64337. + if(pPortCtrl == NULL)
  64338. + return MV_NOT_FOUND;
  64339. +
  64340. + pPortCtrl->portConfig.ejpMode = mode;
  64341. + if(mode)
  64342. + {
  64343. + /* EJP enabled */
  64344. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), ETH_TX_EJP_ENABLE_MASK);
  64345. + }
  64346. + else
  64347. + {
  64348. + /* EJP disabled */
  64349. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), 0);
  64350. + }
  64351. + mvOsPrintf("eth_%d: EJP %s - ETH_TXQ_CMD_1_REG: 0x%x = 0x%08x\n",
  64352. + port, mode ? "Enabled" : "Disabled", ETH_TXQ_CMD_1_REG(port),
  64353. + MV_REG_READ(ETH_TXQ_CMD_1_REG(port)));
  64354. +
  64355. + return MV_OK;
  64356. +}
  64357. +#endif /* MV_ETH_VERSION >= 4 */
  64358. +
  64359. +/*******************************************************************************
  64360. +* mvEthStatusGet - Get major properties of the port .
  64361. +*
  64362. +* DESCRIPTION:
  64363. +* This function get major properties of the port (link, speed, duplex,
  64364. +* flowControl, etc) and return them using the single structure.
  64365. +*
  64366. +* INPUT:
  64367. +* void* pPortHandle - Pointer to port specific handler;
  64368. +*
  64369. +* OUTPUT:
  64370. +* MV_ETH_PORT_STATUS* pStatus - Pointer to structure, were port status
  64371. +* will be placed.
  64372. +*
  64373. +* RETURN: None.
  64374. +*
  64375. +*******************************************************************************/
  64376. +void mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus)
  64377. +{
  64378. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64379. + int port = pPortCtrl->portNo;
  64380. +
  64381. + MV_U32 regValue;
  64382. +
  64383. + regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );
  64384. +
  64385. + if(regValue & ETH_GMII_SPEED_1000_MASK)
  64386. + pStatus->speed = MV_ETH_SPEED_1000;
  64387. + else if(regValue & ETH_MII_SPEED_100_MASK)
  64388. + pStatus->speed = MV_ETH_SPEED_100;
  64389. + else
  64390. + pStatus->speed = MV_ETH_SPEED_10;
  64391. +
  64392. + if(regValue & ETH_LINK_UP_MASK)
  64393. + pStatus->isLinkUp = MV_TRUE;
  64394. + else
  64395. + pStatus->isLinkUp = MV_FALSE;
  64396. +
  64397. + if(regValue & ETH_FULL_DUPLEX_MASK)
  64398. + pStatus->duplex = MV_ETH_DUPLEX_FULL;
  64399. + else
  64400. + pStatus->duplex = MV_ETH_DUPLEX_HALF;
  64401. +
  64402. +
  64403. + if(regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK)
  64404. + pStatus->flowControl = MV_ETH_FC_ENABLE;
  64405. + else
  64406. + pStatus->flowControl = MV_ETH_FC_DISABLE;
  64407. +}
  64408. +
  64409. +
  64410. +/******************************************************************************/
  64411. +/* PHY Control Functions */
  64412. +/******************************************************************************/
  64413. +
  64414. +
  64415. +/*******************************************************************************
  64416. +* mvEthPhyAddrSet - Set the ethernet port PHY address.
  64417. +*
  64418. +* DESCRIPTION:
  64419. +* This routine set the ethernet port PHY address according to given
  64420. +* parameter.
  64421. +*
  64422. +* INPUT:
  64423. +* void* pPortHandle - Pointer to port specific handler;
  64424. +* int phyAddr - PHY address
  64425. +*
  64426. +* RETURN:
  64427. +* None.
  64428. +*
  64429. +*******************************************************************************/
  64430. +void mvEthPhyAddrSet(void* pPortHandle, int phyAddr)
  64431. +{
  64432. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64433. + int port = pPortCtrl->portNo;
  64434. + unsigned int regData;
  64435. +
  64436. + regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));
  64437. +
  64438. + regData &= ~ETH_PHY_ADDR_MASK;
  64439. + regData |= phyAddr;
  64440. +
  64441. + MV_REG_WRITE(ETH_PHY_ADDR_REG(port), regData);
  64442. +
  64443. + return;
  64444. +}
  64445. +
  64446. +/*******************************************************************************
  64447. +* mvEthPhyAddrGet - Get the ethernet port PHY address.
  64448. +*
  64449. +* DESCRIPTION:
  64450. +* This routine returns the given ethernet port PHY address.
  64451. +*
  64452. +* INPUT:
  64453. +* void* pPortHandle - Pointer to port specific handler;
  64454. +*
  64455. +*
  64456. +* RETURN: int - PHY address.
  64457. +*
  64458. +*******************************************************************************/
  64459. +int mvEthPhyAddrGet(void* pPortHandle)
  64460. +{
  64461. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64462. + int port = pPortCtrl->portNo;
  64463. + unsigned int regData;
  64464. +
  64465. + regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));
  64466. +
  64467. + return ((regData >> (5 * port)) & 0x1f);
  64468. +}
  64469. +
  64470. +/******************************************************************************/
  64471. +/* Descriptor handling Functions */
  64472. +/******************************************************************************/
  64473. +
  64474. +/*******************************************************************************
  64475. +* etherInitRxDescRing - Curve a Rx chain desc list and buffer in memory.
  64476. +*
  64477. +* DESCRIPTION:
  64478. +* This function prepares a Rx chained list of descriptors and packet
  64479. +* buffers in a form of a ring. The routine must be called after port
  64480. +* initialization routine and before port start routine.
  64481. +* The Ethernet SDMA engine uses CPU bus addresses to access the various
  64482. +* devices in the system (i.e. DRAM). This function uses the ethernet
  64483. +* struct 'virtual to physical' routine (set by the user) to set the ring
  64484. +* with physical addresses.
  64485. +*
  64486. +* INPUT:
  64487. +* ETH_QUEUE_CTRL *pEthPortCtrl Ethernet Port Control srtuct.
  64488. +* int rxQueue Number of Rx queue.
  64489. +* int rxDescNum Number of Rx descriptors
  64490. +* MV_U8* rxDescBaseAddr Rx descriptors memory area base addr.
  64491. +*
  64492. +* OUTPUT:
  64493. +* The routine updates the Ethernet port control struct with information
  64494. +* regarding the Rx descriptors and buffers.
  64495. +*
  64496. +* RETURN: None
  64497. +*
  64498. +*******************************************************************************/
  64499. +static void ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)
  64500. +{
  64501. + ETH_RX_DESC *pRxDescBase, *pRxDesc, *pRxPrevDesc;
  64502. + int ix, rxDescNum = pPortCtrl->rxQueueConfig[queue].descrNum;
  64503. + ETH_QUEUE_CTRL *pQueueCtrl = &pPortCtrl->rxQueue[queue];
  64504. +
  64505. + /* Make sure descriptor address is cache line size aligned */
  64506. + pRxDescBase = (ETH_RX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr,
  64507. + CPU_D_CACHE_LINE_SIZE);
  64508. +
  64509. + pRxDesc = (ETH_RX_DESC*)pRxDescBase;
  64510. + pRxPrevDesc = pRxDesc;
  64511. +
  64512. + /* initialize the Rx descriptors ring */
  64513. + for (ix=0; ix<rxDescNum; ix++)
  64514. + {
  64515. + pRxDesc->bufSize = 0x0;
  64516. + pRxDesc->byteCnt = 0x0;
  64517. + pRxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  64518. + pRxDesc->bufPtr = 0x0;
  64519. + pRxDesc->returnInfo = 0x0;
  64520. + pRxPrevDesc = pRxDesc;
  64521. + if(ix == (rxDescNum-1))
  64522. + {
  64523. + /* Closing Rx descriptors ring */
  64524. + pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDescBase);
  64525. + }
  64526. + else
  64527. + {
  64528. + pRxDesc = (ETH_RX_DESC*)((MV_ULONG)pRxDesc + ETH_RX_DESC_ALIGNED_SIZE);
  64529. + pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDesc);
  64530. + }
  64531. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxPrevDesc);
  64532. + }
  64533. +
  64534. + pQueueCtrl->pCurrentDescr = pRxDescBase;
  64535. + pQueueCtrl->pUsedDescr = pRxDescBase;
  64536. +
  64537. + pQueueCtrl->pFirstDescr = pRxDescBase;
  64538. + pQueueCtrl->pLastDescr = pRxDesc;
  64539. + pQueueCtrl->resource = 0;
  64540. +}
  64541. +
  64542. +void ethResetRxDescRing(void* pPortHndl, int queue)
  64543. +{
  64544. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  64545. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[queue];
  64546. + ETH_RX_DESC* pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;
  64547. +
  64548. + pQueueCtrl->resource = 0;
  64549. + if(pQueueCtrl->pFirstDescr != NULL)
  64550. + {
  64551. + while(MV_TRUE)
  64552. + {
  64553. + pRxDesc->bufSize = 0x0;
  64554. + pRxDesc->byteCnt = 0x0;
  64555. + pRxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  64556. + pRxDesc->bufPtr = 0x0;
  64557. + pRxDesc->returnInfo = 0x0;
  64558. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);
  64559. + if( (void*)pRxDesc == pQueueCtrl->pLastDescr)
  64560. + break;
  64561. + pRxDesc = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);
  64562. + }
  64563. + pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;
  64564. + pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;
  64565. +
  64566. + /* Update RX Command register */
  64567. + pPortCtrl->portRxQueueCmdReg |= (1 << queue);
  64568. +
  64569. + /* update HW */
  64570. + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),
  64571. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  64572. + }
  64573. + else
  64574. + {
  64575. + /* Update RX Command register */
  64576. + pPortCtrl->portRxQueueCmdReg &= ~(1 << queue);
  64577. +
  64578. + /* update HW */
  64579. + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0);
  64580. + }
  64581. +}
  64582. +
  64583. +/*******************************************************************************
  64584. +* etherInitTxDescRing - Curve a Tx chain desc list and buffer in memory.
  64585. +*
  64586. +* DESCRIPTION:
  64587. +* This function prepares a Tx chained list of descriptors and packet
  64588. +* buffers in a form of a ring. The routine must be called after port
  64589. +* initialization routine and before port start routine.
  64590. +* The Ethernet SDMA engine uses CPU bus addresses to access the various
  64591. +* devices in the system (i.e. DRAM). This function uses the ethernet
  64592. +* struct 'virtual to physical' routine (set by the user) to set the ring
  64593. +* with physical addresses.
  64594. +*
  64595. +* INPUT:
  64596. +* ETH_PORT_CTRL *pEthPortCtrl Ethernet Port Control srtuct.
  64597. +* int txQueue Number of Tx queue.
  64598. +* int txDescNum Number of Tx descriptors
  64599. +* int txBuffSize Size of Tx buffer
  64600. +* MV_U8* pTxDescBase Tx descriptors memory area base addr.
  64601. +*
  64602. +* OUTPUT:
  64603. +* The routine updates the Ethernet port control struct with information
  64604. +* regarding the Tx descriptors and buffers.
  64605. +*
  64606. +* RETURN: None.
  64607. +*
  64608. +*******************************************************************************/
  64609. +static void ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)
  64610. +{
  64611. + ETH_TX_DESC *pTxDescBase, *pTxDesc, *pTxPrevDesc;
  64612. + int ix, txDescNum = pPortCtrl->txQueueConfig[queue].descrNum;
  64613. + ETH_QUEUE_CTRL *pQueueCtrl = &pPortCtrl->txQueue[queue];
  64614. +
  64615. + /* Make sure descriptor address is cache line size aligned */
  64616. + pTxDescBase = (ETH_TX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr,
  64617. + CPU_D_CACHE_LINE_SIZE);
  64618. +
  64619. + pTxDesc = (ETH_TX_DESC*)pTxDescBase;
  64620. + pTxPrevDesc = pTxDesc;
  64621. +
  64622. + /* initialize the Tx descriptors ring */
  64623. + for (ix=0; ix<txDescNum; ix++)
  64624. + {
  64625. + pTxDesc->byteCnt = 0x0000;
  64626. + pTxDesc->L4iChk = 0x0000;
  64627. + pTxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  64628. + pTxDesc->bufPtr = 0x0;
  64629. + pTxDesc->returnInfo = 0x0;
  64630. +
  64631. + pTxPrevDesc = pTxDesc;
  64632. +
  64633. + if(ix == (txDescNum-1))
  64634. + {
  64635. + /* Closing Tx descriptors ring */
  64636. + pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDescBase);
  64637. + }
  64638. + else
  64639. + {
  64640. + pTxDesc = (ETH_TX_DESC*)((MV_ULONG)pTxDesc + ETH_TX_DESC_ALIGNED_SIZE);
  64641. + pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDesc);
  64642. + }
  64643. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxPrevDesc);
  64644. + }
  64645. +
  64646. + pQueueCtrl->pCurrentDescr = pTxDescBase;
  64647. + pQueueCtrl->pUsedDescr = pTxDescBase;
  64648. +
  64649. + pQueueCtrl->pFirstDescr = pTxDescBase;
  64650. + pQueueCtrl->pLastDescr = pTxDesc;
  64651. + /* Leave one TX descriptor out of use */
  64652. + pQueueCtrl->resource = txDescNum - 1;
  64653. +}
  64654. +
  64655. +void ethResetTxDescRing(void* pPortHndl, int queue)
  64656. +{
  64657. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  64658. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[queue];
  64659. + ETH_TX_DESC* pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;
  64660. +
  64661. + pQueueCtrl->resource = 0;
  64662. + if(pQueueCtrl->pFirstDescr != NULL)
  64663. + {
  64664. + while(MV_TRUE)
  64665. + {
  64666. + pTxDesc->byteCnt = 0x0000;
  64667. + pTxDesc->L4iChk = 0x0000;
  64668. + pTxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  64669. + pTxDesc->bufPtr = 0x0;
  64670. + pTxDesc->returnInfo = 0x0;
  64671. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);
  64672. + pQueueCtrl->resource++;
  64673. + if( (void*)pTxDesc == pQueueCtrl->pLastDescr)
  64674. + break;
  64675. + pTxDesc = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);
  64676. + }
  64677. + /* Leave one TX descriptor out of use */
  64678. + pQueueCtrl->resource--;
  64679. + pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;
  64680. + pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;
  64681. +
  64682. + /* Update TX Command register */
  64683. + pPortCtrl->portTxQueueCmdReg |= MV_32BIT_LE_FAST(1 << queue);
  64684. + /* update HW */
  64685. + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),
  64686. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  64687. + }
  64688. + else
  64689. + {
  64690. + /* Update TX Command register */
  64691. + pPortCtrl->portTxQueueCmdReg &= MV_32BIT_LE_FAST(~(1 << queue));
  64692. + /* update HW */
  64693. + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0 );
  64694. + }
  64695. +}
  64696. +
  64697. +/*******************************************************************************
  64698. +* ethAllocDescrMemory - Free memory allocated for RX and TX descriptors.
  64699. +*
  64700. +* DESCRIPTION:
  64701. +* This function allocates memory for RX and TX descriptors.
  64702. +* - If ETH_DESCR_IN_SRAM defined, allocate memory from SRAM.
  64703. +* - If ETH_DESCR_IN_SDRAM defined, allocate memory in SDRAM.
  64704. +*
  64705. +* INPUT:
  64706. +* int size - size of memory should be allocated.
  64707. +*
  64708. +* RETURN: None
  64709. +*
  64710. +*******************************************************************************/
  64711. +static MV_U8* ethAllocDescrMemory(ETH_PORT_CTRL* pPortCtrl, int descSize,
  64712. + MV_ULONG* pPhysAddr, MV_U32 *memHandle)
  64713. +{
  64714. + MV_U8* pVirt;
  64715. +
  64716. +#if defined(ETH_DESCR_IN_SRAM)
  64717. + if(ethDescInSram == MV_TRUE)
  64718. + pVirt = (char*)mvSramMalloc(descSize, pPhysAddr);
  64719. + else
  64720. +#endif /* ETH_DESCR_IN_SRAM */
  64721. + {
  64722. +#ifdef ETH_DESCR_UNCACHED
  64723. + pVirt = (MV_U8*)mvOsIoUncachedMalloc(pPortCtrl->osHandle, descSize,
  64724. + pPhysAddr,memHandle);
  64725. +#else
  64726. + pVirt = (MV_U8*)mvOsIoCachedMalloc(pPortCtrl->osHandle, descSize,
  64727. + pPhysAddr, memHandle);
  64728. +#endif /* ETH_DESCR_UNCACHED */
  64729. + }
  64730. + memset(pVirt, 0, descSize);
  64731. +
  64732. + return pVirt;
  64733. +}
  64734. +
  64735. +/*******************************************************************************
  64736. +* ethFreeDescrMemory - Free memory allocated for RX and TX descriptors.
  64737. +*
  64738. +* DESCRIPTION:
  64739. +* This function frees memory allocated for RX and TX descriptors.
  64740. +* - If ETH_DESCR_IN_SRAM defined, free memory using gtSramFree() function.
  64741. +* - If ETH_DESCR_IN_SDRAM defined, free memory using mvOsFree() function.
  64742. +*
  64743. +* INPUT:
  64744. +* void* pVirtAddr - virtual pointer to memory allocated for RX and TX
  64745. +* desriptors.
  64746. +*
  64747. +* RETURN: None
  64748. +*
  64749. +*******************************************************************************/
  64750. +void ethFreeDescrMemory(ETH_PORT_CTRL* pPortCtrl, MV_BUF_INFO* pDescBuf)
  64751. +{
  64752. + if( (pDescBuf == NULL) || (pDescBuf->bufVirtPtr == NULL) )
  64753. + return;
  64754. +
  64755. +#if defined(ETH_DESCR_IN_SRAM)
  64756. + if( ethDescInSram )
  64757. + {
  64758. + mvSramFree(pDescBuf->bufSize, pDescBuf->bufPhysAddr, pDescBuf->bufVirtPtr);
  64759. + return;
  64760. + }
  64761. +#endif /* ETH_DESCR_IN_SRAM */
  64762. +
  64763. +#ifdef ETH_DESCR_UNCACHED
  64764. + mvOsIoUncachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr,
  64765. + pDescBuf->bufVirtPtr,pDescBuf->memHandle);
  64766. +#else
  64767. + mvOsIoCachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr,
  64768. + pDescBuf->bufVirtPtr,pDescBuf->memHandle);
  64769. +#endif /* ETH_DESCR_UNCACHED */
  64770. +}
  64771. +
  64772. +/******************************************************************************/
  64773. +/* Other Functions */
  64774. +/******************************************************************************/
  64775. +
  64776. +void mvEthPortPowerUp(int port)
  64777. +{
  64778. + MV_U32 regVal;
  64779. +
  64780. + /* MAC Cause register should be cleared */
  64781. + MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);
  64782. +
  64783. + if (mvBoardIsPortInSgmii(port))
  64784. + mvEthPortSgmiiConfig(port);
  64785. +
  64786. + /* Cancel Port Reset */
  64787. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
  64788. + regVal &= (~ETH_PORT_RESET_MASK);
  64789. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);
  64790. + while( (MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) != 0);
  64791. +}
  64792. +
  64793. +void mvEthPortPowerDown(int port)
  64794. +{
  64795. + MV_U32 regVal;
  64796. +
  64797. + /* Port must be DISABLED */
  64798. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
  64799. + if( (regVal & ETH_PORT_ENABLE_MASK) != 0)
  64800. + {
  64801. + mvOsPrintf("ethPort #%d: PowerDown - port must be Disabled (PSC=0x%x)\n",
  64802. + port, regVal);
  64803. + return;
  64804. + }
  64805. +
  64806. + /* Port Reset (Read after write the register as a precaution) */
  64807. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
  64808. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal | ETH_PORT_RESET_MASK);
  64809. + while((MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) == 0);
  64810. +}
  64811. +
  64812. +static void mvEthPortSgmiiConfig(int port)
  64813. +{
  64814. + MV_U32 regVal;
  64815. +
  64816. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
  64817. +
  64818. + regVal |= (ETH_SGMII_MODE_MASK /*| ETH_INBAND_AUTO_NEG_ENABLE_MASK */);
  64819. + regVal &= (~ETH_INBAND_AUTO_NEG_BYPASS_MASK);
  64820. +
  64821. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);
  64822. +}
  64823. +
  64824. +
  64825. +
  64826. +
  64827. +
  64828. +
  64829. +
  64830. +
  64831. +
  64832. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c
  64833. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c 1970-01-01 01:00:00.000000000 +0100
  64834. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c 2011-07-31 11:32:00.143449361 +0200
  64835. @@ -0,0 +1,748 @@
  64836. +/*******************************************************************************
  64837. +Copyright (C) Marvell International Ltd. and its affiliates
  64838. +
  64839. +This software file (the "File") is owned and distributed by Marvell
  64840. +International Ltd. and/or its affiliates ("Marvell") under the following
  64841. +alternative licensing terms. Once you have made an election to distribute the
  64842. +File under one of the following license alternatives, please (i) delete this
  64843. +introductory statement regarding license alternatives, (ii) delete the two
  64844. +license alternatives that you have not elected to use and (iii) preserve the
  64845. +Marvell copyright notice above.
  64846. +
  64847. +********************************************************************************
  64848. +Marvell Commercial License Option
  64849. +
  64850. +If you received this File from Marvell and you have entered into a commercial
  64851. +license agreement (a "Commercial License") with Marvell, the File is licensed
  64852. +to you under the terms of the applicable Commercial License.
  64853. +
  64854. +********************************************************************************
  64855. +Marvell GPL License Option
  64856. +
  64857. +If you received this File from Marvell, you may opt to use, redistribute and/or
  64858. +modify this File in accordance with the terms and conditions of the General
  64859. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  64860. +available along with the File in the license.txt file or by writing to the Free
  64861. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  64862. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  64863. +
  64864. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  64865. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  64866. +DISCLAIMED. The GPL License provides additional details about this warranty
  64867. +disclaimer.
  64868. +********************************************************************************
  64869. +Marvell BSD License Option
  64870. +
  64871. +If you received this File from Marvell, you may opt to use, redistribute and/or
  64872. +modify this File under the following licensing terms.
  64873. +Redistribution and use in source and binary forms, with or without modification,
  64874. +are permitted provided that the following conditions are met:
  64875. +
  64876. + * Redistributions of source code must retain the above copyright notice,
  64877. + this list of conditions and the following disclaimer.
  64878. +
  64879. + * Redistributions in binary form must reproduce the above copyright
  64880. + notice, this list of conditions and the following disclaimer in the
  64881. + documentation and/or other materials provided with the distribution.
  64882. +
  64883. + * Neither the name of Marvell nor the names of its contributors may be
  64884. + used to endorse or promote products derived from this software without
  64885. + specific prior written permission.
  64886. +
  64887. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  64888. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  64889. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  64890. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  64891. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  64892. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  64893. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  64894. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  64895. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  64896. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  64897. +
  64898. +*******************************************************************************/
  64899. +
  64900. +/*******************************************************************************
  64901. +* mvEthDebug.c - Source file for user friendly debug functions
  64902. +*
  64903. +* DESCRIPTION:
  64904. +*
  64905. +* DEPENDENCIES:
  64906. +* None.
  64907. +*
  64908. +*******************************************************************************/
  64909. +
  64910. +#include "mvOs.h"
  64911. +#include "mvCommon.h"
  64912. +#include "mvTypes.h"
  64913. +#include "mv802_3.h"
  64914. +#include "mvDebug.h"
  64915. +#include "ctrlEnv/mvCtrlEnvLib.h"
  64916. +#include "eth-phy/mvEthPhy.h"
  64917. +#include "eth/mvEth.h"
  64918. +#include "eth/gbe/mvEthDebug.h"
  64919. +
  64920. +/* #define mvOsPrintf printf */
  64921. +
  64922. +void mvEthPortShow(void* pHndl);
  64923. +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);
  64924. +
  64925. +/******************************************************************************/
  64926. +/* Debug functions */
  64927. +/******************************************************************************/
  64928. +void ethRxCoal(int port, int usec)
  64929. +{
  64930. + void* pHndl;
  64931. +
  64932. + pHndl = mvEthPortHndlGet(port);
  64933. + if(pHndl != NULL)
  64934. + {
  64935. + mvEthRxCoalSet(pHndl, usec);
  64936. + }
  64937. +}
  64938. +
  64939. +void ethTxCoal(int port, int usec)
  64940. +{
  64941. + void* pHndl;
  64942. +
  64943. + pHndl = mvEthPortHndlGet(port);
  64944. + if(pHndl != NULL)
  64945. + {
  64946. + mvEthTxCoalSet(pHndl, usec);
  64947. + }
  64948. +}
  64949. +
  64950. +#if (MV_ETH_VERSION >= 4)
  64951. +void ethEjpModeSet(int port, int mode)
  64952. +{
  64953. + void* pHndl;
  64954. +
  64955. + pHndl = mvEthPortHndlGet(port);
  64956. + if(pHndl != NULL)
  64957. + {
  64958. + mvEthEjpModeSet(pHndl, mode);
  64959. + }
  64960. +}
  64961. +#endif /* (MV_ETH_VERSION >= 4) */
  64962. +
  64963. +void ethBpduRxQ(int port, int bpduQueue)
  64964. +{
  64965. + void* pHndl;
  64966. +
  64967. + pHndl = mvEthPortHndlGet(port);
  64968. + if(pHndl != NULL)
  64969. + {
  64970. + mvEthBpduRxQueue(pHndl, bpduQueue);
  64971. + }
  64972. +}
  64973. +
  64974. +void ethArpRxQ(int port, int arpQueue)
  64975. +{
  64976. + void* pHndl;
  64977. +
  64978. + pHndl = mvEthPortHndlGet(port);
  64979. + if(pHndl != NULL)
  64980. + {
  64981. + mvEthArpRxQueue(pHndl, arpQueue);
  64982. + }
  64983. +}
  64984. +
  64985. +void ethTcpRxQ(int port, int tcpQueue)
  64986. +{
  64987. + void* pHndl;
  64988. +
  64989. + pHndl = mvEthPortHndlGet(port);
  64990. + if(pHndl != NULL)
  64991. + {
  64992. + mvEthTcpRxQueue(pHndl, tcpQueue);
  64993. + }
  64994. +}
  64995. +
  64996. +void ethUdpRxQ(int port, int udpQueue)
  64997. +{
  64998. + void* pHndl;
  64999. +
  65000. + pHndl = mvEthPortHndlGet(port);
  65001. + if(pHndl != NULL)
  65002. + {
  65003. + mvEthUdpRxQueue(pHndl, udpQueue);
  65004. + }
  65005. +}
  65006. +
  65007. +void ethTxPolicyRegs(int port)
  65008. +{
  65009. + int queue;
  65010. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)mvEthPortHndlGet(port);
  65011. +
  65012. + if(pPortCtrl == NULL)
  65013. + {
  65014. + return;
  65015. + }
  65016. + mvOsPrintf("Port #%d TX Policy: EJP=%d, TXQs: ",
  65017. + port, pPortCtrl->portConfig.ejpMode);
  65018. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  65019. + {
  65020. + if(pPortCtrl->txQueueConfig[queue].descrNum > 0)
  65021. + mvOsPrintf("%d, ", queue);
  65022. + }
  65023. + mvOsPrintf("\n");
  65024. +
  65025. + mvOsPrintf("\n\t TX policy Port #%d configuration registers\n", port);
  65026. +
  65027. + mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
  65028. + ETH_TX_QUEUE_COMMAND_REG(port),
  65029. + MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );
  65030. +
  65031. + mvOsPrintf("ETH_TX_FIXED_PRIO_CFG_REG : 0x%X = 0x%08x\n",
  65032. + ETH_TX_FIXED_PRIO_CFG_REG(port),
  65033. + MV_REG_READ( ETH_TX_FIXED_PRIO_CFG_REG(port) ) );
  65034. +
  65035. + mvOsPrintf("ETH_TX_TOKEN_RATE_CFG_REG : 0x%X = 0x%08x\n",
  65036. + ETH_TX_TOKEN_RATE_CFG_REG(port),
  65037. + MV_REG_READ( ETH_TX_TOKEN_RATE_CFG_REG(port) ) );
  65038. +
  65039. + mvOsPrintf("ETH_MAX_TRANSMIT_UNIT_REG : 0x%X = 0x%08x\n",
  65040. + ETH_MAX_TRANSMIT_UNIT_REG(port),
  65041. + MV_REG_READ( ETH_MAX_TRANSMIT_UNIT_REG(port) ) );
  65042. +
  65043. + mvOsPrintf("ETH_TX_TOKEN_BUCKET_SIZE_REG : 0x%X = 0x%08x\n",
  65044. + ETH_TX_TOKEN_BUCKET_SIZE_REG(port),
  65045. + MV_REG_READ( ETH_TX_TOKEN_BUCKET_SIZE_REG(port) ) );
  65046. +
  65047. + mvOsPrintf("ETH_TX_TOKEN_BUCKET_COUNT_REG : 0x%X = 0x%08x\n",
  65048. + ETH_TX_TOKEN_BUCKET_COUNT_REG(port),
  65049. + MV_REG_READ( ETH_TX_TOKEN_BUCKET_COUNT_REG(port) ) );
  65050. +
  65051. + for(queue=0; queue<MV_ETH_MAX_TXQ; queue++)
  65052. + {
  65053. + mvOsPrintf("\n\t TX policy Port #%d, Queue #%d configuration registers\n", port, queue);
  65054. +
  65055. + mvOsPrintf("ETH_TXQ_TOKEN_COUNT_REG : 0x%X = 0x%08x\n",
  65056. + ETH_TXQ_TOKEN_COUNT_REG(port, queue),
  65057. + MV_REG_READ( ETH_TXQ_TOKEN_COUNT_REG(port, queue) ) );
  65058. +
  65059. + mvOsPrintf("ETH_TXQ_TOKEN_CFG_REG : 0x%X = 0x%08x\n",
  65060. + ETH_TXQ_TOKEN_CFG_REG(port, queue),
  65061. + MV_REG_READ( ETH_TXQ_TOKEN_CFG_REG(port, queue) ) );
  65062. +
  65063. + mvOsPrintf("ETH_TXQ_ARBITER_CFG_REG : 0x%X = 0x%08x\n",
  65064. + ETH_TXQ_ARBITER_CFG_REG(port, queue),
  65065. + MV_REG_READ( ETH_TXQ_ARBITER_CFG_REG(port, queue) ) );
  65066. + }
  65067. + mvOsPrintf("\n");
  65068. +}
  65069. +
  65070. +/* Print important registers of Ethernet port */
  65071. +void ethPortRegs(int port)
  65072. +{
  65073. + mvOsPrintf("\n\t ethGiga #%d port Registers:\n", port);
  65074. +
  65075. + mvOsPrintf("ETH_PORT_STATUS_REG : 0x%X = 0x%08x\n",
  65076. + ETH_PORT_STATUS_REG(port),
  65077. + MV_REG_READ( ETH_PORT_STATUS_REG(port) ) );
  65078. +
  65079. + mvOsPrintf("ETH_PORT_SERIAL_CTRL_REG : 0x%X = 0x%08x\n",
  65080. + ETH_PORT_SERIAL_CTRL_REG(port),
  65081. + MV_REG_READ( ETH_PORT_SERIAL_CTRL_REG(port) ) );
  65082. +
  65083. + mvOsPrintf("ETH_PORT_CONFIG_REG : 0x%X = 0x%08x\n",
  65084. + ETH_PORT_CONFIG_REG(port),
  65085. + MV_REG_READ( ETH_PORT_CONFIG_REG(port) ) );
  65086. +
  65087. + mvOsPrintf("ETH_PORT_CONFIG_EXTEND_REG : 0x%X = 0x%08x\n",
  65088. + ETH_PORT_CONFIG_EXTEND_REG(port),
  65089. + MV_REG_READ( ETH_PORT_CONFIG_EXTEND_REG(port) ) );
  65090. +
  65091. + mvOsPrintf("ETH_SDMA_CONFIG_REG : 0x%X = 0x%08x\n",
  65092. + ETH_SDMA_CONFIG_REG(port),
  65093. + MV_REG_READ( ETH_SDMA_CONFIG_REG(port) ) );
  65094. +
  65095. + mvOsPrintf("ETH_TX_FIFO_URGENT_THRESH_REG : 0x%X = 0x%08x\n",
  65096. + ETH_TX_FIFO_URGENT_THRESH_REG(port),
  65097. + MV_REG_READ( ETH_TX_FIFO_URGENT_THRESH_REG(port) ) );
  65098. +
  65099. + mvOsPrintf("ETH_RX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
  65100. + ETH_RX_QUEUE_COMMAND_REG(port),
  65101. + MV_REG_READ( ETH_RX_QUEUE_COMMAND_REG(port) ) );
  65102. +
  65103. + mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
  65104. + ETH_TX_QUEUE_COMMAND_REG(port),
  65105. + MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );
  65106. +
  65107. + mvOsPrintf("ETH_INTR_CAUSE_REG : 0x%X = 0x%08x\n",
  65108. + ETH_INTR_CAUSE_REG(port),
  65109. + MV_REG_READ( ETH_INTR_CAUSE_REG(port) ) );
  65110. +
  65111. + mvOsPrintf("ETH_INTR_EXTEND_CAUSE_REG : 0x%X = 0x%08x\n",
  65112. + ETH_INTR_CAUSE_EXT_REG(port),
  65113. + MV_REG_READ( ETH_INTR_CAUSE_EXT_REG(port) ) );
  65114. +
  65115. + mvOsPrintf("ETH_INTR_MASK_REG : 0x%X = 0x%08x\n",
  65116. + ETH_INTR_MASK_REG(port),
  65117. + MV_REG_READ( ETH_INTR_MASK_REG(port) ) );
  65118. +
  65119. + mvOsPrintf("ETH_INTR_EXTEND_MASK_REG : 0x%X = 0x%08x\n",
  65120. + ETH_INTR_MASK_EXT_REG(port),
  65121. + MV_REG_READ( ETH_INTR_MASK_EXT_REG(port) ) );
  65122. +
  65123. + mvOsPrintf("ETH_RX_DESCR_STAT_CMD_REG : 0x%X = 0x%08x\n",
  65124. + ETH_RX_DESCR_STAT_CMD_REG(port, 0),
  65125. + MV_REG_READ( ETH_RX_DESCR_STAT_CMD_REG(port, 0) ) );
  65126. +
  65127. + mvOsPrintf("ETH_RX_BYTE_COUNT_REG : 0x%X = 0x%08x\n",
  65128. + ETH_RX_BYTE_COUNT_REG(port, 0),
  65129. + MV_REG_READ( ETH_RX_BYTE_COUNT_REG(port, 0) ) );
  65130. +
  65131. + mvOsPrintf("ETH_RX_BUF_PTR_REG : 0x%X = 0x%08x\n",
  65132. + ETH_RX_BUF_PTR_REG(port, 0),
  65133. + MV_REG_READ( ETH_RX_BUF_PTR_REG(port, 0) ) );
  65134. +
  65135. + mvOsPrintf("ETH_RX_CUR_DESC_PTR_REG : 0x%X = 0x%08x\n",
  65136. + ETH_RX_CUR_DESC_PTR_REG(port, 0),
  65137. + MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, 0) ) );
  65138. +}
  65139. +
  65140. +
  65141. +/* Print Giga Ethernet UNIT registers */
  65142. +void ethRegs(int port)
  65143. +{
  65144. + mvOsPrintf("ETH_PHY_ADDR_REG : 0x%X = 0x%08x\n",
  65145. + ETH_PHY_ADDR_REG(port),
  65146. + MV_REG_READ(ETH_PHY_ADDR_REG(port)) );
  65147. +
  65148. + mvOsPrintf("ETH_UNIT_INTR_CAUSE_REG : 0x%X = 0x%08x\n",
  65149. + ETH_UNIT_INTR_CAUSE_REG(port),
  65150. + MV_REG_READ( ETH_UNIT_INTR_CAUSE_REG(port)) );
  65151. +
  65152. + mvOsPrintf("ETH_UNIT_INTR_MASK_REG : 0x%X = 0x%08x\n",
  65153. + ETH_UNIT_INTR_MASK_REG(port),
  65154. + MV_REG_READ( ETH_UNIT_INTR_MASK_REG(port)) );
  65155. +
  65156. + mvOsPrintf("ETH_UNIT_ERROR_ADDR_REG : 0x%X = 0x%08x\n",
  65157. + ETH_UNIT_ERROR_ADDR_REG(port),
  65158. + MV_REG_READ(ETH_UNIT_ERROR_ADDR_REG(port)) );
  65159. +
  65160. + mvOsPrintf("ETH_UNIT_INT_ADDR_ERROR_REG : 0x%X = 0x%08x\n",
  65161. + ETH_UNIT_INT_ADDR_ERROR_REG(port),
  65162. + MV_REG_READ(ETH_UNIT_INT_ADDR_ERROR_REG(port)) );
  65163. +
  65164. +}
  65165. +
  65166. +/******************************************************************************/
  65167. +/* MIB Counters functions */
  65168. +/******************************************************************************/
  65169. +
  65170. +/*******************************************************************************
  65171. +* ethClearMibCounters - Clear all MIB counters
  65172. +*
  65173. +* DESCRIPTION:
  65174. +* This function clears all MIB counters of a specific ethernet port.
  65175. +* A read from the MIB counter will reset the counter.
  65176. +*
  65177. +* INPUT:
  65178. +* int port - Ethernet Port number.
  65179. +*
  65180. +* RETURN: None
  65181. +*
  65182. +*******************************************************************************/
  65183. +void ethClearCounters(int port)
  65184. +{
  65185. + void* pHndl;
  65186. +
  65187. + pHndl = mvEthPortHndlGet(port);
  65188. + if(pHndl != NULL)
  65189. + mvEthMibCountersClear(pHndl);
  65190. +
  65191. + return;
  65192. +}
  65193. +
  65194. +
  65195. +/* Print counters of the Ethernet port */
  65196. +void ethPortCounters(int port)
  65197. +{
  65198. + MV_U32 regValue, regValHigh;
  65199. + void* pHndl;
  65200. +
  65201. + pHndl = mvEthPortHndlGet(port);
  65202. + if(pHndl == NULL)
  65203. + return;
  65204. +
  65205. + mvOsPrintf("\n\t Port #%d MIB Counters\n\n", port);
  65206. +
  65207. + mvOsPrintf("GoodFramesReceived = %u\n",
  65208. + mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_RECEIVED, NULL));
  65209. + mvOsPrintf("BadFramesReceived = %u\n",
  65210. + mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FRAMES_RECEIVED, NULL));
  65211. + mvOsPrintf("BroadcastFramesReceived = %u\n",
  65212. + mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_RECEIVED, NULL));
  65213. + mvOsPrintf("MulticastFramesReceived = %u\n",
  65214. + mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_RECEIVED, NULL));
  65215. +
  65216. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW,
  65217. + &regValHigh);
  65218. + mvOsPrintf("GoodOctetsReceived = 0x%08x%08x\n",
  65219. + regValHigh, regValue);
  65220. +
  65221. + mvOsPrintf("\n");
  65222. + mvOsPrintf("GoodFramesSent = %u\n",
  65223. + mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_SENT, NULL));
  65224. + mvOsPrintf("BroadcastFramesSent = %u\n",
  65225. + mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_SENT, NULL));
  65226. + mvOsPrintf("MulticastFramesSent = %u\n",
  65227. + mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_SENT, NULL));
  65228. +
  65229. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_SENT_LOW,
  65230. + &regValHigh);
  65231. + mvOsPrintf("GoodOctetsSent = 0x%08x%08x\n", regValHigh, regValue);
  65232. +
  65233. +
  65234. + mvOsPrintf("\n\t FC Control Counters\n");
  65235. +
  65236. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNREC_MAC_CONTROL_RECEIVED, NULL);
  65237. + mvOsPrintf("UnrecogMacControlReceived = %u\n", regValue);
  65238. +
  65239. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FC_RECEIVED, NULL);
  65240. + mvOsPrintf("GoodFCFramesReceived = %u\n", regValue);
  65241. +
  65242. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FC_RECEIVED, NULL);
  65243. + mvOsPrintf("BadFCFramesReceived = %u\n", regValue);
  65244. +
  65245. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FC_SENT, NULL);
  65246. + mvOsPrintf("FCFramesSent = %u\n", regValue);
  65247. +
  65248. +
  65249. + mvOsPrintf("\n\t RX Errors\n");
  65250. +
  65251. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_OCTETS_RECEIVED, NULL);
  65252. + mvOsPrintf("BadOctetsReceived = %u\n", regValue);
  65253. +
  65254. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNDERSIZE_RECEIVED, NULL);
  65255. + mvOsPrintf("UndersizeFramesReceived = %u\n", regValue);
  65256. +
  65257. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FRAGMENTS_RECEIVED, NULL);
  65258. + mvOsPrintf("FragmentsReceived = %u\n", regValue);
  65259. +
  65260. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_OVERSIZE_RECEIVED, NULL);
  65261. + mvOsPrintf("OversizeFramesReceived = %u\n", regValue);
  65262. +
  65263. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_JABBER_RECEIVED, NULL);
  65264. + mvOsPrintf("JabbersReceived = %u\n", regValue);
  65265. +
  65266. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_MAC_RECEIVE_ERROR, NULL);
  65267. + mvOsPrintf("MacReceiveErrors = %u\n", regValue);
  65268. +
  65269. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_CRC_EVENT, NULL);
  65270. + mvOsPrintf("BadCrcReceived = %u\n", regValue);
  65271. +
  65272. + mvOsPrintf("\n\t TX Errors\n");
  65273. +
  65274. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR, NULL);
  65275. + mvOsPrintf("TxMacErrors = %u\n", regValue);
  65276. +
  65277. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_EXCESSIVE_COLLISION, NULL);
  65278. + mvOsPrintf("TxExcessiveCollisions = %u\n", regValue);
  65279. +
  65280. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_COLLISION, NULL);
  65281. + mvOsPrintf("TxCollisions = %u\n", regValue);
  65282. +
  65283. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_LATE_COLLISION, NULL);
  65284. + mvOsPrintf("TxLateCollisions = %u\n", regValue);
  65285. +
  65286. +
  65287. + mvOsPrintf("\n");
  65288. + regValue = MV_REG_READ( ETH_RX_DISCARD_PKTS_CNTR_REG(port));
  65289. + mvOsPrintf("Rx Discard packets counter = %u\n", regValue);
  65290. +
  65291. + regValue = MV_REG_READ(ETH_RX_OVERRUN_PKTS_CNTR_REG(port));
  65292. + mvOsPrintf("Rx Overrun packets counter = %u\n", regValue);
  65293. +}
  65294. +
  65295. +/* Print RMON counters of the Ethernet port */
  65296. +void ethPortRmonCounters(int port)
  65297. +{
  65298. + void* pHndl;
  65299. +
  65300. + pHndl = mvEthPortHndlGet(port);
  65301. + if(pHndl == NULL)
  65302. + return;
  65303. +
  65304. + mvOsPrintf("\n\t Port #%d RMON MIB Counters\n\n", port);
  65305. +
  65306. + mvOsPrintf("64 ByteFramesReceived = %u\n",
  65307. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_64_OCTETS, NULL));
  65308. + mvOsPrintf("65...127 ByteFramesReceived = %u\n",
  65309. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_65_TO_127_OCTETS, NULL));
  65310. + mvOsPrintf("128...255 ByteFramesReceived = %u\n",
  65311. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_128_TO_255_OCTETS, NULL));
  65312. + mvOsPrintf("256...511 ByteFramesReceived = %u\n",
  65313. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_256_TO_511_OCTETS, NULL));
  65314. + mvOsPrintf("512...1023 ByteFramesReceived = %u\n",
  65315. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_512_TO_1023_OCTETS, NULL));
  65316. + mvOsPrintf("1024...Max ByteFramesReceived = %u\n",
  65317. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_1024_TO_MAX_OCTETS, NULL));
  65318. +}
  65319. +
  65320. +/* Print port information */
  65321. +void ethPortStatus(int port)
  65322. +{
  65323. + void* pHndl;
  65324. +
  65325. + pHndl = mvEthPortHndlGet(port);
  65326. + if(pHndl != NULL)
  65327. + {
  65328. + mvEthPortShow(pHndl);
  65329. + }
  65330. +}
  65331. +
  65332. +/* Print port queues information */
  65333. +void ethPortQueues(int port, int rxQueue, int txQueue, int mode)
  65334. +{
  65335. + void* pHndl;
  65336. +
  65337. + pHndl = mvEthPortHndlGet(port);
  65338. + if(pHndl != NULL)
  65339. + {
  65340. + mvEthQueuesShow(pHndl, rxQueue, txQueue, mode);
  65341. + }
  65342. +}
  65343. +
  65344. +void ethUcastSet(int port, char* macStr, int queue)
  65345. +{
  65346. + void* pHndl;
  65347. + MV_U8 macAddr[MV_MAC_ADDR_SIZE];
  65348. +
  65349. + pHndl = mvEthPortHndlGet(port);
  65350. + if(pHndl != NULL)
  65351. + {
  65352. + mvMacStrToHex(macStr, macAddr);
  65353. + mvEthMacAddrSet(pHndl, macAddr, queue);
  65354. + }
  65355. +}
  65356. +
  65357. +
  65358. +void ethPortUcastShow(int port)
  65359. +{
  65360. + MV_U32 unicastReg, macL, macH;
  65361. + int i, j;
  65362. +
  65363. + macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(port));
  65364. + macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(port));
  65365. +
  65366. + mvOsPrintf("\n\t Port #%d Unicast MAC table: %02x:%02x:%02x:%02x:%02x:%02x\n\n",
  65367. + port, ((macH >> 24) & 0xff), ((macH >> 16) & 0xff),
  65368. + ((macH >> 8) & 0xff), (macH & 0xff),
  65369. + ((macL >> 8) & 0xff), (macL & 0xff) );
  65370. +
  65371. + for (i=0; i<4; i++)
  65372. + {
  65373. + unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(port) + i*4));
  65374. + for(j=0; j<4; j++)
  65375. + {
  65376. + MV_U8 macEntry = (unicastReg >> (8*j)) & 0xFF;
  65377. +
  65378. + mvOsPrintf("%X: %8s, Q = %d\n", i*4+j,
  65379. + (macEntry & BIT0) ? "Accept" : "Reject", (macEntry >> 1) & 0x7);
  65380. + }
  65381. + }
  65382. +}
  65383. +
  65384. +void ethMcastAdd(int port, char* macStr, int queue)
  65385. +{
  65386. + void* pHndl;
  65387. + MV_U8 macAddr[MV_MAC_ADDR_SIZE];
  65388. +
  65389. + pHndl = mvEthPortHndlGet(port);
  65390. + if(pHndl != NULL)
  65391. + {
  65392. + mvMacStrToHex(macStr, macAddr);
  65393. + mvEthMcastAddrSet(pHndl, macAddr, queue);
  65394. + }
  65395. +}
  65396. +
  65397. +void ethPortMcast(int port)
  65398. +{
  65399. + int tblIdx, regIdx;
  65400. + MV_U32 regVal;
  65401. +
  65402. + mvOsPrintf("\n\t Port #%d Special (IP) Multicast table: 01:00:5E:00:00:XX\n\n",
  65403. + port);
  65404. +
  65405. + for(tblIdx=0; tblIdx<(256/4); tblIdx++)
  65406. + {
  65407. + regVal = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(port) + tblIdx*4));
  65408. + for(regIdx=0; regIdx<4; regIdx++)
  65409. + {
  65410. + if((regVal & (0x01 << (regIdx*8))) != 0)
  65411. + {
  65412. + mvOsPrintf("0x%02X: Accepted, rxQ = %d\n",
  65413. + tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));
  65414. + }
  65415. + }
  65416. + }
  65417. + mvOsPrintf("\n\t Port #%d Other Multicast table\n\n", port);
  65418. + for(tblIdx=0; tblIdx<(256/4); tblIdx++)
  65419. + {
  65420. + regVal = MV_REG_READ((ETH_DA_FILTER_OTH_MCAST_BASE(port) + tblIdx*4));
  65421. + for(regIdx=0; regIdx<4; regIdx++)
  65422. + {
  65423. + if((regVal & (0x01 << (regIdx*8))) != 0)
  65424. + {
  65425. + mvOsPrintf("Crc8=0x%02X: Accepted, rxQ = %d\n",
  65426. + tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));
  65427. + }
  65428. + }
  65429. + }
  65430. +}
  65431. +
  65432. +
  65433. +/* Print status of Ethernet port */
  65434. +void mvEthPortShow(void* pHndl)
  65435. +{
  65436. + MV_U32 regValue, rxCoal, txCoal;
  65437. + int speed, queue, port;
  65438. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pHndl;
  65439. +
  65440. + port = pPortCtrl->portNo;
  65441. +
  65442. + regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );
  65443. +
  65444. + mvOsPrintf("\n\t ethGiga #%d port Status: 0x%04x = 0x%08x\n\n",
  65445. + port, ETH_PORT_STATUS_REG(port), regValue);
  65446. +
  65447. + mvOsPrintf("descInSram=%d, descSwCoher=%d\n",
  65448. + ethDescInSram, ethDescSwCoher);
  65449. +
  65450. + if(regValue & ETH_GMII_SPEED_1000_MASK)
  65451. + speed = 1000;
  65452. + else if(regValue & ETH_MII_SPEED_100_MASK)
  65453. + speed = 100;
  65454. + else
  65455. + speed = 10;
  65456. +
  65457. + mvEthCoalGet(pPortCtrl, &rxCoal, &txCoal);
  65458. +
  65459. + /* Link, Speed, Duplex, FlowControl */
  65460. + mvOsPrintf("Link=%s, Speed=%d, Duplex=%s, RxFlowControl=%s",
  65461. + (regValue & ETH_LINK_UP_MASK) ? "UP" : "DOWN",
  65462. + speed,
  65463. + (regValue & ETH_FULL_DUPLEX_MASK) ? "FULL" : "HALF",
  65464. + (regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK) ? "ENABLE" : "DISABLE");
  65465. +
  65466. + mvOsPrintf("\n");
  65467. +
  65468. + mvOsPrintf("RxCoal = %d usec, TxCoal = %d usec\n",
  65469. + rxCoal, txCoal);
  65470. +
  65471. + mvOsPrintf("rxDefQ=%d, arpQ=%d, bpduQ=%d, tcpQ=%d, udpQ=%d\n\n",
  65472. + pPortCtrl->portConfig.rxDefQ, pPortCtrl->portConfig.rxArpQ,
  65473. + pPortCtrl->portConfig.rxBpduQ,
  65474. + pPortCtrl->portConfig.rxTcpQ, pPortCtrl->portConfig.rxUdpQ);
  65475. +
  65476. + /* Print all RX and TX queues */
  65477. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  65478. + {
  65479. + mvOsPrintf("RX Queue #%d: base=0x%lx, free=%d\n",
  65480. + queue, (MV_ULONG)pPortCtrl->rxQueue[queue].pFirstDescr,
  65481. + mvEthRxResourceGet(pPortCtrl, queue) );
  65482. + }
  65483. + mvOsPrintf("\n");
  65484. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  65485. + {
  65486. + mvOsPrintf("TX Queue #%d: base=0x%lx, free=%d\n",
  65487. + queue, (MV_ULONG)pPortCtrl->txQueue[queue].pFirstDescr,
  65488. + mvEthTxResourceGet(pPortCtrl, queue) );
  65489. + }
  65490. +}
  65491. +
  65492. +/* Print RX and TX queue of the Ethernet port */
  65493. +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode)
  65494. +{
  65495. + ETH_PORT_CTRL *pPortCtrl = (ETH_PORT_CTRL*)pHndl;
  65496. + ETH_QUEUE_CTRL *pQueueCtrl;
  65497. + MV_U32 regValue;
  65498. + ETH_RX_DESC *pRxDescr;
  65499. + ETH_TX_DESC *pTxDescr;
  65500. + int i, port = pPortCtrl->portNo;
  65501. +
  65502. + if( (rxQueue >=0) && (rxQueue < MV_ETH_RX_Q_NUM) )
  65503. + {
  65504. + pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);
  65505. + mvOsPrintf("Port #%d, RX Queue #%d\n\n", port, rxQueue);
  65506. +
  65507. + mvOsPrintf("CURR_RX_DESC_PTR : 0x%X = 0x%08x\n",
  65508. + ETH_RX_CUR_DESC_PTR_REG(port, rxQueue),
  65509. + MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue)));
  65510. +
  65511. +
  65512. + if(pQueueCtrl->pFirstDescr != NULL)
  65513. + {
  65514. + mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",
  65515. + (MV_ULONG)pQueueCtrl->pFirstDescr, (MV_ULONG)pQueueCtrl->pLastDescr,
  65516. + pQueueCtrl->resource);
  65517. + mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",
  65518. + (MV_ULONG)pQueueCtrl->pCurrentDescr,
  65519. + (MV_ULONG)pQueueCtrl->pUsedDescr);
  65520. +
  65521. + if(mode == 1)
  65522. + {
  65523. + pRxDescr = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;
  65524. + i = 0;
  65525. + do
  65526. + {
  65527. + mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%4d, buf=%08x, pkt=%lx, os=%lx\n",
  65528. + i, (MV_U32)pRxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pRxDescr),
  65529. + pRxDescr->cmdSts, pRxDescr->byteCnt, (MV_U32)pRxDescr->bufSize,
  65530. + (unsigned int)pRxDescr->bufPtr, (MV_ULONG)pRxDescr->returnInfo,
  65531. + ((MV_PKT_INFO*)pRxDescr->returnInfo)->osInfo);
  65532. +
  65533. + ETH_DESCR_INV(pPortCtrl, pRxDescr);
  65534. + pRxDescr = RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl);
  65535. + i++;
  65536. + } while (pRxDescr != pQueueCtrl->pFirstDescr);
  65537. + }
  65538. + }
  65539. + else
  65540. + mvOsPrintf("RX Queue #%d is NOT CREATED\n", rxQueue);
  65541. + }
  65542. +
  65543. + if( (txQueue >=0) && (txQueue < MV_ETH_TX_Q_NUM) )
  65544. + {
  65545. + pQueueCtrl = &(pPortCtrl->txQueue[txQueue]);
  65546. + mvOsPrintf("Port #%d, TX Queue #%d\n\n", port, txQueue);
  65547. +
  65548. + regValue = MV_REG_READ( ETH_TX_CUR_DESC_PTR_REG(port, txQueue));
  65549. + mvOsPrintf("CURR_TX_DESC_PTR : 0x%X = 0x%08x\n",
  65550. + ETH_TX_CUR_DESC_PTR_REG(port, txQueue), regValue);
  65551. +
  65552. + if(pQueueCtrl->pFirstDescr != NULL)
  65553. + {
  65554. + mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",
  65555. + (MV_ULONG)pQueueCtrl->pFirstDescr,
  65556. + (MV_ULONG)pQueueCtrl->pLastDescr,
  65557. + pQueueCtrl->resource);
  65558. + mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",
  65559. + (MV_ULONG)pQueueCtrl->pCurrentDescr,
  65560. + (MV_ULONG)pQueueCtrl->pUsedDescr);
  65561. +
  65562. + if(mode == 1)
  65563. + {
  65564. + pTxDescr = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;
  65565. + i = 0;
  65566. + do
  65567. + {
  65568. + mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%08x, pkt=%lx, os=%lx\n",
  65569. + i, (MV_U32)pTxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxDescr),
  65570. + pTxDescr->cmdSts, pTxDescr->byteCnt,
  65571. + (MV_U32)pTxDescr->bufPtr, (MV_ULONG)pTxDescr->returnInfo,
  65572. + pTxDescr->returnInfo ? (((MV_PKT_INFO*)pTxDescr->returnInfo)->osInfo) : 0x0);
  65573. +
  65574. + ETH_DESCR_INV(pPortCtrl, pTxDescr);
  65575. + pTxDescr = TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl);
  65576. + i++;
  65577. + } while (pTxDescr != pQueueCtrl->pFirstDescr);
  65578. + }
  65579. + }
  65580. + else
  65581. + mvOsPrintf("TX Queue #%d is NOT CREATED\n", txQueue);
  65582. + }
  65583. +}
  65584. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h
  65585. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h 1970-01-01 01:00:00.000000000 +0100
  65586. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h 2011-07-31 11:32:00.203425336 +0200
  65587. @@ -0,0 +1,146 @@
  65588. +/*******************************************************************************
  65589. +Copyright (C) Marvell International Ltd. and its affiliates
  65590. +
  65591. +This software file (the "File") is owned and distributed by Marvell
  65592. +International Ltd. and/or its affiliates ("Marvell") under the following
  65593. +alternative licensing terms. Once you have made an election to distribute the
  65594. +File under one of the following license alternatives, please (i) delete this
  65595. +introductory statement regarding license alternatives, (ii) delete the two
  65596. +license alternatives that you have not elected to use and (iii) preserve the
  65597. +Marvell copyright notice above.
  65598. +
  65599. +********************************************************************************
  65600. +Marvell Commercial License Option
  65601. +
  65602. +If you received this File from Marvell and you have entered into a commercial
  65603. +license agreement (a "Commercial License") with Marvell, the File is licensed
  65604. +to you under the terms of the applicable Commercial License.
  65605. +
  65606. +********************************************************************************
  65607. +Marvell GPL License Option
  65608. +
  65609. +If you received this File from Marvell, you may opt to use, redistribute and/or
  65610. +modify this File in accordance with the terms and conditions of the General
  65611. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  65612. +available along with the File in the license.txt file or by writing to the Free
  65613. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  65614. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  65615. +
  65616. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  65617. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  65618. +DISCLAIMED. The GPL License provides additional details about this warranty
  65619. +disclaimer.
  65620. +********************************************************************************
  65621. +Marvell BSD License Option
  65622. +
  65623. +If you received this File from Marvell, you may opt to use, redistribute and/or
  65624. +modify this File under the following licensing terms.
  65625. +Redistribution and use in source and binary forms, with or without modification,
  65626. +are permitted provided that the following conditions are met:
  65627. +
  65628. + * Redistributions of source code must retain the above copyright notice,
  65629. + this list of conditions and the following disclaimer.
  65630. +
  65631. + * Redistributions in binary form must reproduce the above copyright
  65632. + notice, this list of conditions and the following disclaimer in the
  65633. + documentation and/or other materials provided with the distribution.
  65634. +
  65635. + * Neither the name of Marvell nor the names of its contributors may be
  65636. + used to endorse or promote products derived from this software without
  65637. + specific prior written permission.
  65638. +
  65639. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  65640. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  65641. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  65642. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  65643. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  65644. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  65645. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  65646. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  65647. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  65648. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  65649. +
  65650. +*******************************************************************************/
  65651. +#ifndef __MV_ETH_DEBUG_H__
  65652. +#define __MV_ETH_DEBUG_H__
  65653. +
  65654. +#if 0
  65655. +/*
  65656. + ** Externs
  65657. + */
  65658. +void ethBpduRxQ(int port, int bpduQueue);
  65659. +void ethArpRxQ(int port, int bpduQueue);
  65660. +void ethTcpRxQ(int port, int bpduQueue);
  65661. +void ethUdpRxQ(int port, int bpduQueue);
  65662. +void ethMcastAdd(int port, char* macStr, int queue);
  65663. +
  65664. +#ifdef INCLUDE_MULTI_QUEUE
  65665. +void ethRxPolicy( int port);
  65666. +void ethTxPolicy( int port);
  65667. +void ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);
  65668. +void ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);
  65669. +void ethRxPolQ(int port, int rxQueue, int rxQuota);
  65670. +#endif /* INCLUDE_MULTI_QUEUE */
  65671. +
  65672. +void print_egiga_stat(void *sc, unsigned int port);
  65673. +void ethPortStatus (int port);
  65674. +void ethPortQueues( int port, int rxQueue, int txQueue, int mode);
  65675. +void ethPortMcast(int port);
  65676. +void ethPortRegs(int port);
  65677. +void ethPortCounters(int port);
  65678. +void ethPortRmonCounters(int port);
  65679. +void ethRxCoal(int port, int usec);
  65680. +void ethTxCoal(int port, int usec);
  65681. +
  65682. +void ethRegs(int port);
  65683. +void ethClearCounters(int port);
  65684. +void ethUcastSet(int port, char* macStr, int queue);
  65685. +void ethPortUcastShow(int port);
  65686. +
  65687. +#ifdef CONFIG_MV_ETH_HEADER
  65688. +void run_com_header(const char *buffer);
  65689. +#endif
  65690. +
  65691. +#ifdef INCLUDE_MULTI_QUEUE
  65692. +void ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);
  65693. +void ethRxPolQ(int port, int queue, int quota);
  65694. +void ethRxPolicy(int port);
  65695. +void ethTxPolDef(int port, int txQ, char* headerHexStr);
  65696. +void ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);
  65697. +void ethTxPolicy(int port);
  65698. +#endif /* INCLUDE_MULTI_QUEUE */
  65699. +
  65700. +#if (MV_ETH_VERSION >= 4)
  65701. +void ethEjpModeSet(int port, int mode)
  65702. +#endif
  65703. +#endif /* 0 */
  65704. +
  65705. +
  65706. +
  65707. +
  65708. +void ethRxCoal(int port, int usec);
  65709. +void ethTxCoal(int port, int usec);
  65710. +#if (MV_ETH_VERSION >= 4)
  65711. +void ethEjpModeSet(int port, int mode);
  65712. +#endif /* (MV_ETH_VERSION >= 4) */
  65713. +
  65714. +void ethBpduRxQ(int port, int bpduQueue);
  65715. +void ethArpRxQ(int port, int arpQueue);
  65716. +void ethTcpRxQ(int port, int tcpQueue);
  65717. +void ethUdpRxQ(int port, int udpQueue);
  65718. +void ethTxPolicyRegs(int port);
  65719. +void ethPortRegs(int port);
  65720. +void ethRegs(int port);
  65721. +void ethClearCounters(int port);
  65722. +void ethPortCounters(int port);
  65723. +void ethPortRmonCounters(int port);
  65724. +void ethPortStatus(int port);
  65725. +void ethPortQueues(int port, int rxQueue, int txQueue, int mode);
  65726. +void ethUcastSet(int port, char* macStr, int queue);
  65727. +void ethPortUcastShow(int port);
  65728. +void ethMcastAdd(int port, char* macStr, int queue);
  65729. +void ethPortMcast(int port);
  65730. +void mvEthPortShow(void* pHndl);
  65731. +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);
  65732. +
  65733. +#endif
  65734. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h
  65735. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h 1970-01-01 01:00:00.000000000 +0100
  65736. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h 2011-07-31 11:32:00.283831547 +0200
  65737. @@ -0,0 +1,751 @@
  65738. +/*******************************************************************************
  65739. +Copyright (C) Marvell International Ltd. and its affiliates
  65740. +
  65741. +This software file (the "File") is owned and distributed by Marvell
  65742. +International Ltd. and/or its affiliates ("Marvell") under the following
  65743. +alternative licensing terms. Once you have made an election to distribute the
  65744. +File under one of the following license alternatives, please (i) delete this
  65745. +introductory statement regarding license alternatives, (ii) delete the two
  65746. +license alternatives that you have not elected to use and (iii) preserve the
  65747. +Marvell copyright notice above.
  65748. +
  65749. +********************************************************************************
  65750. +Marvell Commercial License Option
  65751. +
  65752. +If you received this File from Marvell and you have entered into a commercial
  65753. +license agreement (a "Commercial License") with Marvell, the File is licensed
  65754. +to you under the terms of the applicable Commercial License.
  65755. +
  65756. +********************************************************************************
  65757. +Marvell GPL License Option
  65758. +
  65759. +If you received this File from Marvell, you may opt to use, redistribute and/or
  65760. +modify this File in accordance with the terms and conditions of the General
  65761. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  65762. +available along with the File in the license.txt file or by writing to the Free
  65763. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  65764. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  65765. +
  65766. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  65767. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  65768. +DISCLAIMED. The GPL License provides additional details about this warranty
  65769. +disclaimer.
  65770. +********************************************************************************
  65771. +Marvell BSD License Option
  65772. +
  65773. +If you received this File from Marvell, you may opt to use, redistribute and/or
  65774. +modify this File under the following licensing terms.
  65775. +Redistribution and use in source and binary forms, with or without modification,
  65776. +are permitted provided that the following conditions are met:
  65777. +
  65778. + * Redistributions of source code must retain the above copyright notice,
  65779. + this list of conditions and the following disclaimer.
  65780. +
  65781. + * Redistributions in binary form must reproduce the above copyright
  65782. + notice, this list of conditions and the following disclaimer in the
  65783. + documentation and/or other materials provided with the distribution.
  65784. +
  65785. + * Neither the name of Marvell nor the names of its contributors may be
  65786. + used to endorse or promote products derived from this software without
  65787. + specific prior written permission.
  65788. +
  65789. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  65790. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  65791. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  65792. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  65793. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  65794. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  65795. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  65796. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  65797. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  65798. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  65799. +
  65800. +*******************************************************************************/
  65801. +
  65802. +/*******************************************************************************
  65803. +* mvEth.h - Header File for : Marvell Gigabit Ethernet Controller
  65804. +*
  65805. +* DESCRIPTION:
  65806. +* This header file contains macros typedefs and function declaration specific to
  65807. +* the Marvell Gigabit Ethernet Controller.
  65808. +*
  65809. +* DEPENDENCIES:
  65810. +* None.
  65811. +*
  65812. +*******************************************************************************/
  65813. +
  65814. +#ifndef __mvEthGbe_h__
  65815. +#define __mvEthGbe_h__
  65816. +
  65817. +extern MV_BOOL ethDescInSram;
  65818. +extern MV_BOOL ethDescSwCoher;
  65819. +extern ETH_PORT_CTRL* ethPortCtrl[];
  65820. +
  65821. +static INLINE MV_ULONG ethDescVirtToPhy(ETH_QUEUE_CTRL* pQueueCtrl, MV_U8* pDesc)
  65822. +{
  65823. +#if defined (ETH_DESCR_IN_SRAM)
  65824. + if( ethDescInSram )
  65825. + return mvSramVirtToPhy(pDesc);
  65826. + else
  65827. +#endif /* ETH_DESCR_IN_SRAM */
  65828. + return (pQueueCtrl->descBuf.bufPhysAddr + (pDesc - pQueueCtrl->descBuf.bufVirtPtr));
  65829. +}
  65830. +/* Return port handler */
  65831. +#define mvEthPortHndlGet(port) ethPortCtrl[port]
  65832. +
  65833. +/* Used as WA for HW/SW race on TX */
  65834. +static INLINE int mvEthPortTxEnable(void* pPortHndl, int queue, int max_deep)
  65835. +{
  65836. + int deep = 0;
  65837. + MV_U32 txCurrReg, txEnReg;
  65838. + ETH_TX_DESC* pTxLastDesc;
  65839. + ETH_QUEUE_CTRL* pQueueCtrl;
  65840. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65841. +
  65842. + txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));
  65843. + if( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) == 0)
  65844. + {
  65845. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
  65846. + return 0;
  65847. + }
  65848. +
  65849. + pQueueCtrl = &pPortCtrl->txQueue[queue];
  65850. + pTxLastDesc = pQueueCtrl->pCurrentDescr;
  65851. + txCurrReg = MV_REG_READ(ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue));
  65852. + if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)
  65853. + {
  65854. + /* All descriptors are processed, no chance for race */
  65855. + return 0;
  65856. + }
  65857. +
  65858. + /* Check distance betwee HW and SW location: */
  65859. + /* If distance between HW and SW pointers is less than max_deep descriptors */
  65860. + /* Race condition is possible, so wait end of TX and restart TXQ */
  65861. + while(deep < max_deep)
  65862. + {
  65863. + pTxLastDesc = TX_PREV_DESC_PTR(pTxLastDesc, pQueueCtrl);
  65864. + if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)
  65865. + {
  65866. + int count = 0;
  65867. +
  65868. + while( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) != 0)
  65869. + {
  65870. + count++;
  65871. + if(count > 10000)
  65872. + {
  65873. + mvOsPrintf("mvEthPortTxEnable: timeout - TXQ_CMD=0x%08x\n",
  65874. + MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) );
  65875. + break;
  65876. + }
  65877. + txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));
  65878. + }
  65879. +
  65880. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
  65881. + return count;
  65882. + }
  65883. + deep++;
  65884. + }
  65885. + /* Distance between HW and SW pointers is more than max_deep descriptors, */
  65886. + /* So NO race condition - do nothing */
  65887. + return -1;
  65888. +}
  65889. +
  65890. +
  65891. +/* defines */
  65892. +#define ETH_CSUM_MIN_BYTE_COUNT 72
  65893. +
  65894. +/* Tailgate and Kirwood have only 2K TX FIFO */
  65895. +#if (MV_ETH_VERSION == 2) || (MV_ETH_VERSION == 4)
  65896. +#define ETH_CSUM_MAX_BYTE_COUNT 1600
  65897. +#else
  65898. +#define ETH_CSUM_MAX_BYTE_COUNT 9*1024
  65899. +#endif /* MV_ETH_VERSION */
  65900. +
  65901. +#define ETH_MV_HEADER_SIZE 2
  65902. +#define ETH_MV_TX_EN
  65903. +
  65904. +/* An offest in Tx descriptors to store data for buffers less than 8 Bytes */
  65905. +#define MIN_TX_BUFF_LOAD 8
  65906. +#define TX_BUF_OFFSET_IN_DESC (ETH_TX_DESC_ALIGNED_SIZE - MIN_TX_BUFF_LOAD)
  65907. +
  65908. +/* Default port configuration value */
  65909. +#define PORT_CONFIG_VALUE \
  65910. + ETH_DEF_RX_QUEUE_MASK(0) | \
  65911. + ETH_DEF_RX_ARP_QUEUE_MASK(0) | \
  65912. + ETH_DEF_RX_TCP_QUEUE_MASK(0) | \
  65913. + ETH_DEF_RX_UDP_QUEUE_MASK(0) | \
  65914. + ETH_DEF_RX_BPDU_QUEUE_MASK(0) | \
  65915. + ETH_RX_CHECKSUM_WITH_PSEUDO_HDR
  65916. +
  65917. +/* Default port extend configuration value */
  65918. +#define PORT_CONFIG_EXTEND_VALUE 0
  65919. +
  65920. +#define PORT_SERIAL_CONTROL_VALUE \
  65921. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  65922. + BIT9 | \
  65923. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  65924. + ETH_MAX_RX_PACKET_1552BYTE | \
  65925. + ETH_SET_FULL_DUPLEX_MASK
  65926. +
  65927. +#define PORT_SERIAL_CONTROL_100MB_FORCE_VALUE \
  65928. + ETH_FORCE_LINK_PASS_MASK | \
  65929. + ETH_DISABLE_DUPLEX_AUTO_NEG_MASK | \
  65930. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  65931. + BIT9 | \
  65932. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  65933. + ETH_DISABLE_SPEED_AUTO_NEG_MASK | \
  65934. + ETH_SET_FULL_DUPLEX_MASK | \
  65935. + ETH_SET_MII_SPEED_100_MASK | \
  65936. + ETH_MAX_RX_PACKET_1552BYTE
  65937. +
  65938. +
  65939. +#define PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE \
  65940. + ETH_FORCE_LINK_PASS_MASK | \
  65941. + ETH_DISABLE_DUPLEX_AUTO_NEG_MASK | \
  65942. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  65943. + BIT9 | \
  65944. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  65945. + ETH_DISABLE_SPEED_AUTO_NEG_MASK | \
  65946. + ETH_SET_FULL_DUPLEX_MASK | \
  65947. + ETH_SET_GMII_SPEED_1000_MASK | \
  65948. + ETH_MAX_RX_PACKET_1552BYTE
  65949. +
  65950. +#define PORT_SERIAL_CONTROL_SGMII_IBAN_VALUE \
  65951. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  65952. + BIT9 | \
  65953. + ETH_IN_BAND_AN_EN_MASK | \
  65954. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  65955. + ETH_MAX_RX_PACKET_1552BYTE
  65956. +
  65957. +/* Function headers: */
  65958. +MV_VOID mvEthSetSpecialMcastTable(int portNo, int queue);
  65959. +MV_STATUS mvEthArpRxQueue(void* pPortHandle, int arpQueue);
  65960. +MV_STATUS mvEthUdpRxQueue(void* pPortHandle, int udpQueue);
  65961. +MV_STATUS mvEthTcpRxQueue(void* pPortHandle, int tcpQueue);
  65962. +MV_STATUS mvEthMacAddrGet(int portNo, unsigned char *pAddr);
  65963. +MV_VOID mvEthSetOtherMcastTable(int portNo, int queue);
  65964. +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);
  65965. +/* Interrupt Coalesting functions */
  65966. +MV_U32 mvEthRxCoalSet(void* pPortHndl, MV_U32 uSec);
  65967. +MV_U32 mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec);
  65968. +MV_STATUS mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal);
  65969. +
  65970. +/******************************************************************************/
  65971. +/* Data Flow functions */
  65972. +/******************************************************************************/
  65973. +static INLINE void mvEthPortTxRestart(void* pPortHndl)
  65974. +{
  65975. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65976. +
  65977. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
  65978. +}
  65979. +
  65980. +/* Get number of Free resources in specific TX queue */
  65981. +static INLINE int mvEthTxResourceGet(void* pPortHndl, int txQueue)
  65982. +{
  65983. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65984. +
  65985. + return (pPortCtrl->txQueue[txQueue].resource);
  65986. +}
  65987. +
  65988. +/* Get number of Free resources in specific RX queue */
  65989. +static INLINE int mvEthRxResourceGet(void* pPortHndl, int rxQueue)
  65990. +{
  65991. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65992. +
  65993. + return (pPortCtrl->rxQueue[rxQueue].resource);
  65994. +}
  65995. +
  65996. +static INLINE int mvEthTxQueueIsFull(void* pPortHndl, int txQueue)
  65997. +{
  65998. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65999. +
  66000. + if(pPortCtrl->txQueue[txQueue].resource == 0)
  66001. + return MV_TRUE;
  66002. +
  66003. + return MV_FALSE;
  66004. +}
  66005. +
  66006. +/* Get number of Free resources in specific RX queue */
  66007. +static INLINE int mvEthRxQueueIsFull(void* pPortHndl, int rxQueue)
  66008. +{
  66009. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  66010. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
  66011. +
  66012. + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
  66013. + (pQueueCtrl->resource != 0) )
  66014. + return MV_TRUE;
  66015. +
  66016. + return MV_FALSE;
  66017. +}
  66018. +
  66019. +static INLINE int mvEthTxQueueIsEmpty(void* pPortHndl, int txQueue)
  66020. +{
  66021. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  66022. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  66023. +
  66024. + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
  66025. + (pQueueCtrl->resource != 0) )
  66026. + {
  66027. + return MV_TRUE;
  66028. + }
  66029. + return MV_FALSE;
  66030. +}
  66031. +
  66032. +/* Get number of Free resources in specific RX queue */
  66033. +static INLINE int mvEthRxQueueIsEmpty(void* pPortHndl, int rxQueue)
  66034. +{
  66035. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  66036. +
  66037. + if(pPortCtrl->rxQueue[rxQueue].resource == 0)
  66038. + return MV_TRUE;
  66039. +
  66040. + return MV_FALSE;
  66041. +}
  66042. +
  66043. +/*******************************************************************************
  66044. +* mvEthPortTx - Send an Ethernet packet
  66045. +*
  66046. +* DESCRIPTION:
  66047. +* This routine send a given packet described by pPktInfo parameter.
  66048. +* Single buffer only.
  66049. +*
  66050. +* INPUT:
  66051. +* void* pEthPortHndl - Ethernet Port handler.
  66052. +* int txQueue - Number of Tx queue.
  66053. +* MV_PKT_INFO *pPktInfo - User packet to send.
  66054. +*
  66055. +* RETURN:
  66056. +* MV_NO_RESOURCE - No enough resources to send this packet.
  66057. +* MV_ERROR - Unexpected Fatal error.
  66058. +* MV_OK - Packet send successfully.
  66059. +*
  66060. +*******************************************************************************/
  66061. +static INLINE MV_STATUS mvEthPortTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)
  66062. +{
  66063. + ETH_TX_DESC* pTxCurrDesc;
  66064. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  66065. + ETH_QUEUE_CTRL* pQueueCtrl;
  66066. + int portNo;
  66067. + MV_BUF_INFO* pBufInfo = pPktInfo->pFrags;
  66068. +
  66069. +#ifdef ETH_DEBUG
  66070. + if(pPortCtrl->portState != MV_ACTIVE)
  66071. + return MV_BAD_STATE;
  66072. +#endif /* ETH_DEBUG */
  66073. +
  66074. + portNo = pPortCtrl->portNo;
  66075. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  66076. +
  66077. + /* Get the Tx Desc ring indexes */
  66078. + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
  66079. +
  66080. + /* Check if there is enough resources to send the packet */
  66081. + if(pQueueCtrl->resource == 0)
  66082. + return MV_NO_RESOURCE;
  66083. +
  66084. + pTxCurrDesc->byteCnt = pBufInfo->dataSize;
  66085. +
  66086. + /* Flash Buffer */
  66087. + if(pPktInfo->pktSize != 0)
  66088. + {
  66089. +#ifdef MV_NETBSD
  66090. + pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;
  66091. + ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);
  66092. +#else
  66093. + pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);
  66094. +#endif
  66095. + pPktInfo->pktSize = 0;
  66096. + }
  66097. + else
  66098. + pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;
  66099. +
  66100. + pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;
  66101. +
  66102. + /* There is only one buffer in the packet */
  66103. + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
  66104. + pTxCurrDesc->cmdSts = pPktInfo->status |
  66105. + ETH_BUFFER_OWNED_BY_DMA |
  66106. + ETH_TX_GENERATE_CRC_MASK |
  66107. + ETH_TX_ENABLE_INTERRUPT_MASK |
  66108. + ETH_TX_ZERO_PADDING_MASK |
  66109. + ETH_TX_FIRST_DESC_MASK |
  66110. + ETH_TX_LAST_DESC_MASK;
  66111. +
  66112. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  66113. +
  66114. + pQueueCtrl->resource--;
  66115. + pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
  66116. +
  66117. + /* Apply send command */
  66118. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;
  66119. +
  66120. + return MV_OK;
  66121. +}
  66122. +
  66123. +
  66124. +/*******************************************************************************
  66125. +* mvEthPortSgTx - Send an Ethernet packet
  66126. +*
  66127. +* DESCRIPTION:
  66128. +* This routine send a given packet described by pBufInfo parameter. It
  66129. +* supports transmitting of a packet spaned over multiple buffers.
  66130. +*
  66131. +* INPUT:
  66132. +* void* pEthPortHndl - Ethernet Port handler.
  66133. +* int txQueue - Number of Tx queue.
  66134. +* MV_PKT_INFO *pPktInfo - User packet to send.
  66135. +*
  66136. +* RETURN:
  66137. +* MV_NO_RESOURCE - No enough resources to send this packet.
  66138. +* MV_ERROR - Unexpected Fatal error.
  66139. +* MV_OK - Packet send successfully.
  66140. +*
  66141. +*******************************************************************************/
  66142. +static INLINE MV_STATUS mvEthPortSgTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)
  66143. +{
  66144. + ETH_TX_DESC* pTxFirstDesc;
  66145. + ETH_TX_DESC* pTxCurrDesc;
  66146. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  66147. + ETH_QUEUE_CTRL* pQueueCtrl;
  66148. + int portNo, bufCount;
  66149. + MV_BUF_INFO* pBufInfo = pPktInfo->pFrags;
  66150. + MV_U8* pTxBuf;
  66151. +
  66152. +#ifdef ETH_DEBUG
  66153. + if(pPortCtrl->portState != MV_ACTIVE)
  66154. + return MV_BAD_STATE;
  66155. +#endif /* ETH_DEBUG */
  66156. +
  66157. + portNo = pPortCtrl->portNo;
  66158. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  66159. +
  66160. + /* Get the Tx Desc ring indexes */
  66161. + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
  66162. +
  66163. + /* Check if there is enough resources to send the packet */
  66164. + if(pQueueCtrl->resource < pPktInfo->numFrags)
  66165. + return MV_NO_RESOURCE;
  66166. +
  66167. + /* Remember first desc */
  66168. + pTxFirstDesc = pTxCurrDesc;
  66169. +
  66170. + bufCount = 0;
  66171. + while(MV_TRUE)
  66172. + {
  66173. + if(pBufInfo[bufCount].dataSize <= MIN_TX_BUFF_LOAD)
  66174. + {
  66175. + /* Buffers with a payload smaller than MIN_TX_BUFF_LOAD (8 bytes) must be aligned */
  66176. + /* to 64-bit boundary. Two options here: */
  66177. + /* 1) Usually, copy the payload to the reserved 8 bytes inside descriptor. */
  66178. + /* 2) In the Half duplex workaround, the reserved 8 bytes inside descriptor are used */
  66179. + /* as a pointer to the aligned buffer, copy the small payload to this buffer. */
  66180. + pTxBuf = ((MV_U8*)pTxCurrDesc)+TX_BUF_OFFSET_IN_DESC;
  66181. + mvOsBCopy(pBufInfo[bufCount].bufVirtPtr, pTxBuf, pBufInfo[bufCount].dataSize);
  66182. + pTxCurrDesc->bufPtr = ethDescVirtToPhy(pQueueCtrl, pTxBuf);
  66183. + }
  66184. + else
  66185. + {
  66186. + /* Flash Buffer */
  66187. +#ifdef MV_NETBSD
  66188. + pTxCurrDesc->bufPtr = pBufInfo[bufCount].bufPhysAddr;
  66189. + ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);
  66190. +#else
  66191. + pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);
  66192. +#endif
  66193. + }
  66194. +
  66195. + pTxCurrDesc->byteCnt = pBufInfo[bufCount].dataSize;
  66196. + bufCount++;
  66197. +
  66198. + if(bufCount >= pPktInfo->numFrags)
  66199. + break;
  66200. +
  66201. + if(bufCount > 1)
  66202. + {
  66203. + /* There is middle buffer of the packet Not First and Not Last */
  66204. + pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA;
  66205. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  66206. + }
  66207. + /* Go to next descriptor and next buffer */
  66208. + pTxCurrDesc = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
  66209. + }
  66210. + /* Set last desc with DMA ownership and interrupt enable. */
  66211. + pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;
  66212. + if(bufCount == 1)
  66213. + {
  66214. + /* There is only one buffer in the packet */
  66215. + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
  66216. + pTxCurrDesc->cmdSts = pPktInfo->status |
  66217. + ETH_BUFFER_OWNED_BY_DMA |
  66218. + ETH_TX_GENERATE_CRC_MASK |
  66219. + ETH_TX_ENABLE_INTERRUPT_MASK |
  66220. + ETH_TX_ZERO_PADDING_MASK |
  66221. + ETH_TX_FIRST_DESC_MASK |
  66222. + ETH_TX_LAST_DESC_MASK;
  66223. +
  66224. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  66225. + }
  66226. + else
  66227. + {
  66228. + /* Last but not First */
  66229. + pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA |
  66230. + ETH_TX_ENABLE_INTERRUPT_MASK |
  66231. + ETH_TX_ZERO_PADDING_MASK |
  66232. + ETH_TX_LAST_DESC_MASK;
  66233. +
  66234. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  66235. +
  66236. + /* Update First when more than one buffer in the packet */
  66237. + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
  66238. + pTxFirstDesc->cmdSts = pPktInfo->status |
  66239. + ETH_BUFFER_OWNED_BY_DMA |
  66240. + ETH_TX_GENERATE_CRC_MASK |
  66241. + ETH_TX_FIRST_DESC_MASK;
  66242. +
  66243. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxFirstDesc);
  66244. + }
  66245. + /* Update txQueue state */
  66246. + pQueueCtrl->resource -= bufCount;
  66247. + pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
  66248. +
  66249. + /* Apply send command */
  66250. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;
  66251. +
  66252. + return MV_OK;
  66253. +}
  66254. +
  66255. +/*******************************************************************************
  66256. +* mvEthPortTxDone - Free all used Tx descriptors and mBlks.
  66257. +*
  66258. +* DESCRIPTION:
  66259. +* This routine returns the transmitted packet information to the caller.
  66260. +*
  66261. +* INPUT:
  66262. +* void* pEthPortHndl - Ethernet Port handler.
  66263. +* int txQueue - Number of Tx queue.
  66264. +*
  66265. +* OUTPUT:
  66266. +* MV_PKT_INFO *pPktInfo - Pointer to packet was sent.
  66267. +*
  66268. +* RETURN:
  66269. +* MV_NOT_FOUND - No transmitted packets to return. Transmit in progress.
  66270. +* MV_EMPTY - No transmitted packets to return. TX Queue is empty.
  66271. +* MV_ERROR - Unexpected Fatal error.
  66272. +* MV_OK - There is transmitted packet in the queue,
  66273. +* 'pPktInfo' filled with relevant information.
  66274. +*
  66275. +*******************************************************************************/
  66276. +static INLINE MV_PKT_INFO* mvEthPortTxDone(void* pEthPortHndl, int txQueue)
  66277. +{
  66278. + ETH_TX_DESC* pTxCurrDesc;
  66279. + ETH_TX_DESC* pTxUsedDesc;
  66280. + ETH_QUEUE_CTRL* pQueueCtrl;
  66281. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  66282. + MV_PKT_INFO* pPktInfo;
  66283. + MV_U32 commandStatus;
  66284. +
  66285. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  66286. +
  66287. + pTxUsedDesc = pQueueCtrl->pUsedDescr;
  66288. + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
  66289. +
  66290. + while(MV_TRUE)
  66291. + {
  66292. + /* No more used descriptors */
  66293. + commandStatus = pTxUsedDesc->cmdSts;
  66294. + if (commandStatus & (ETH_BUFFER_OWNED_BY_DMA))
  66295. + {
  66296. + ETH_DESCR_INV(pPortCtrl, pTxUsedDesc);
  66297. + return NULL;
  66298. + }
  66299. + if( (pTxUsedDesc == pTxCurrDesc) &&
  66300. + (pQueueCtrl->resource != 0) )
  66301. + {
  66302. + return NULL;
  66303. + }
  66304. + pQueueCtrl->resource++;
  66305. + pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxUsedDesc, pQueueCtrl);
  66306. + if(commandStatus & (ETH_TX_LAST_DESC_MASK))
  66307. + {
  66308. + pPktInfo = (MV_PKT_INFO*)pTxUsedDesc->returnInfo;
  66309. + pPktInfo->status = commandStatus;
  66310. + return pPktInfo;
  66311. + }
  66312. + pTxUsedDesc = pQueueCtrl->pUsedDescr;
  66313. + }
  66314. +}
  66315. +
  66316. +/*******************************************************************************
  66317. +* mvEthPortRx - Get new received packets from Rx queue.
  66318. +*
  66319. +* DESCRIPTION:
  66320. +* This routine returns the received data to the caller. There is no
  66321. +* data copying during routine operation. All information is returned
  66322. +* using pointer to packet information struct passed from the caller.
  66323. +*
  66324. +* INPUT:
  66325. +* void* pEthPortHndl - Ethernet Port handler.
  66326. +* int rxQueue - Number of Rx queue.
  66327. +*
  66328. +* OUTPUT:
  66329. +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
  66330. +*
  66331. +* RETURN:
  66332. +* MV_NO_RESOURCE - No free resources in RX queue.
  66333. +* MV_ERROR - Unexpected Fatal error.
  66334. +* MV_OK - New packet received and 'pBufInfo' structure filled
  66335. +* with relevant information.
  66336. +*
  66337. +*******************************************************************************/
  66338. +static INLINE MV_PKT_INFO* mvEthPortRx(void* pEthPortHndl, int rxQueue)
  66339. +{
  66340. + ETH_RX_DESC *pRxCurrDesc;
  66341. + MV_U32 commandStatus;
  66342. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  66343. + ETH_QUEUE_CTRL* pQueueCtrl;
  66344. + MV_PKT_INFO* pPktInfo;
  66345. +
  66346. + pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);
  66347. +
  66348. + /* Check resources */
  66349. + if(pQueueCtrl->resource == 0)
  66350. + {
  66351. + mvOsPrintf("ethPortRx: no more resources\n");
  66352. + return NULL;
  66353. + }
  66354. + while(MV_TRUE)
  66355. + {
  66356. + /* Get the Rx Desc ring 'curr and 'used' indexes */
  66357. + pRxCurrDesc = pQueueCtrl->pCurrentDescr;
  66358. +
  66359. + commandStatus = pRxCurrDesc->cmdSts;
  66360. + if (commandStatus & (ETH_BUFFER_OWNED_BY_DMA))
  66361. + {
  66362. + /* Nothing to receive... */
  66363. + ETH_DESCR_INV(pPortCtrl, pRxCurrDesc);
  66364. + return NULL;
  66365. + }
  66366. +
  66367. + /* Valid RX only if FIRST and LAST bits are set */
  66368. + if( (commandStatus & (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK)) ==
  66369. + (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK) )
  66370. + {
  66371. + pPktInfo = (MV_PKT_INFO*)pRxCurrDesc->returnInfo;
  66372. + pPktInfo->pFrags->dataSize = pRxCurrDesc->byteCnt - 4;
  66373. + pPktInfo->status = commandStatus;
  66374. + pPktInfo->fragIP = pRxCurrDesc->bufSize & ETH_RX_IP_FRAGMENTED_FRAME_MASK;
  66375. +
  66376. + pQueueCtrl->resource--;
  66377. + /* Update 'curr' in data structure */
  66378. + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);
  66379. +
  66380. +#ifdef INCLUDE_SYNC_BARR
  66381. + mvCpuIfSyncBarr(DRAM_TARGET);
  66382. +#endif
  66383. + return pPktInfo;
  66384. + }
  66385. + else
  66386. + {
  66387. + ETH_RX_DESC* pRxUsedDesc = pQueueCtrl->pUsedDescr;
  66388. +
  66389. +#ifdef ETH_DEBUG
  66390. + mvOsPrintf("ethDrv: Unexpected Jumbo frame: "
  66391. + "status=0x%08x, byteCnt=%d, pData=0x%x\n",
  66392. + commandStatus, pRxCurrDesc->byteCnt, pRxCurrDesc->bufPtr);
  66393. +#endif /* ETH_DEBUG */
  66394. +
  66395. + /* move buffer from pCurrentDescr position to pUsedDescr position */
  66396. + pRxUsedDesc->bufPtr = pRxCurrDesc->bufPtr;
  66397. + pRxUsedDesc->returnInfo = pRxCurrDesc->returnInfo;
  66398. + pRxUsedDesc->bufSize = pRxCurrDesc->bufSize & ETH_RX_BUFFER_MASK;
  66399. +
  66400. + /* Return the descriptor to DMA ownership */
  66401. + pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA |
  66402. + ETH_RX_ENABLE_INTERRUPT_MASK;
  66403. +
  66404. + /* Flush descriptor and CPU pipe */
  66405. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);
  66406. +
  66407. + /* Move the used descriptor pointer to the next descriptor */
  66408. + pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);
  66409. + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);
  66410. + }
  66411. + }
  66412. +}
  66413. +
  66414. +/*******************************************************************************
  66415. +* mvEthPortRxDone - Returns a Rx buffer back to the Rx ring.
  66416. +*
  66417. +* DESCRIPTION:
  66418. +* This routine returns a Rx buffer back to the Rx ring.
  66419. +*
  66420. +* INPUT:
  66421. +* void* pEthPortHndl - Ethernet Port handler.
  66422. +* int rxQueue - Number of Rx queue.
  66423. +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
  66424. +*
  66425. +* RETURN:
  66426. +* MV_ERROR - Unexpected Fatal error.
  66427. +* MV_OUT_OF_RANGE - RX queue is already FULL, so this buffer can't be
  66428. +* returned to this queue.
  66429. +* MV_FULL - Buffer returned successfully and RX queue became full.
  66430. +* More buffers should not be returned at the time.
  66431. +* MV_OK - Buffer returned successfully and there are more free
  66432. +* places in the queue.
  66433. +*
  66434. +*******************************************************************************/
  66435. +static INLINE MV_STATUS mvEthPortRxDone(void* pEthPortHndl, int rxQueue, MV_PKT_INFO *pPktInfo)
  66436. +{
  66437. + ETH_RX_DESC* pRxUsedDesc;
  66438. + ETH_QUEUE_CTRL* pQueueCtrl;
  66439. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  66440. +
  66441. + pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
  66442. +
  66443. + /* Get 'used' Rx descriptor */
  66444. + pRxUsedDesc = pQueueCtrl->pUsedDescr;
  66445. +
  66446. + /* Check that ring is not FULL */
  66447. + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
  66448. + (pQueueCtrl->resource != 0) )
  66449. + {
  66450. + mvOsPrintf("%s %d: out of range Error resource=%d, curr=%p, used=%p\n",
  66451. + __FUNCTION__, pPortCtrl->portNo, pQueueCtrl->resource,
  66452. + pQueueCtrl->pCurrentDescr, pQueueCtrl->pUsedDescr);
  66453. + return MV_OUT_OF_RANGE;
  66454. + }
  66455. +
  66456. + pRxUsedDesc->bufPtr = pPktInfo->pFrags->bufPhysAddr;
  66457. + pRxUsedDesc->returnInfo = (MV_ULONG)pPktInfo;
  66458. + pRxUsedDesc->bufSize = pPktInfo->pFrags->bufSize & ETH_RX_BUFFER_MASK;
  66459. +
  66460. + /* Invalidate data buffer accordingly with pktSize */
  66461. + if(pPktInfo->pktSize != 0)
  66462. + {
  66463. + ETH_PACKET_CACHE_INVALIDATE(pPktInfo->pFrags->bufVirtPtr, pPktInfo->pktSize);
  66464. + pPktInfo->pktSize = 0;
  66465. + }
  66466. +
  66467. + /* Return the descriptor to DMA ownership */
  66468. + pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT_MASK;
  66469. +
  66470. + /* Flush descriptor and CPU pipe */
  66471. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);
  66472. +
  66473. + pQueueCtrl->resource++;
  66474. +
  66475. + /* Move the used descriptor pointer to the next descriptor */
  66476. + pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);
  66477. +
  66478. + /* If ring became Full return MV_FULL */
  66479. + if(pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr)
  66480. + return MV_FULL;
  66481. +
  66482. + return MV_OK;
  66483. +}
  66484. +
  66485. +
  66486. +#endif /* __mvEthGbe_h__ */
  66487. +
  66488. +
  66489. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h
  66490. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h 1970-01-01 01:00:00.000000000 +0100
  66491. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h 2011-07-31 11:32:00.344567101 +0200
  66492. @@ -0,0 +1,700 @@
  66493. +/*******************************************************************************
  66494. +Copyright (C) Marvell International Ltd. and its affiliates
  66495. +
  66496. +This software file (the "File") is owned and distributed by Marvell
  66497. +International Ltd. and/or its affiliates ("Marvell") under the following
  66498. +alternative licensing terms. Once you have made an election to distribute the
  66499. +File under one of the following license alternatives, please (i) delete this
  66500. +introductory statement regarding license alternatives, (ii) delete the two
  66501. +license alternatives that you have not elected to use and (iii) preserve the
  66502. +Marvell copyright notice above.
  66503. +
  66504. +********************************************************************************
  66505. +Marvell Commercial License Option
  66506. +
  66507. +If you received this File from Marvell and you have entered into a commercial
  66508. +license agreement (a "Commercial License") with Marvell, the File is licensed
  66509. +to you under the terms of the applicable Commercial License.
  66510. +
  66511. +********************************************************************************
  66512. +Marvell GPL License Option
  66513. +
  66514. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66515. +modify this File in accordance with the terms and conditions of the General
  66516. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  66517. +available along with the File in the license.txt file or by writing to the Free
  66518. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  66519. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  66520. +
  66521. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  66522. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  66523. +DISCLAIMED. The GPL License provides additional details about this warranty
  66524. +disclaimer.
  66525. +********************************************************************************
  66526. +Marvell BSD License Option
  66527. +
  66528. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66529. +modify this File under the following licensing terms.
  66530. +Redistribution and use in source and binary forms, with or without modification,
  66531. +are permitted provided that the following conditions are met:
  66532. +
  66533. + * Redistributions of source code must retain the above copyright notice,
  66534. + this list of conditions and the following disclaimer.
  66535. +
  66536. + * Redistributions in binary form must reproduce the above copyright
  66537. + notice, this list of conditions and the following disclaimer in the
  66538. + documentation and/or other materials provided with the distribution.
  66539. +
  66540. + * Neither the name of Marvell nor the names of its contributors may be
  66541. + used to endorse or promote products derived from this software without
  66542. + specific prior written permission.
  66543. +
  66544. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  66545. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  66546. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  66547. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  66548. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  66549. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  66550. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  66551. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  66552. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  66553. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  66554. +
  66555. +*******************************************************************************/
  66556. +
  66557. +
  66558. +#ifndef __INCmvEthRegsh
  66559. +#define __INCmvEthRegsh
  66560. +
  66561. +#ifdef __cplusplus
  66562. +extern "C" {
  66563. +#endif /* __cplusplus */
  66564. +
  66565. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  66566. +
  66567. +/****************************************/
  66568. +/* Ethernet Unit Registers */
  66569. +/****************************************/
  66570. +#define ETH_REG_BASE MV_ETH_REG_BASE
  66571. +
  66572. +#define ETH_PHY_ADDR_REG(port) (ETH_REG_BASE(port) + 0x000)
  66573. +#define ETH_SMI_REG(port) (ETH_REG_BASE(port) + 0x004)
  66574. +#define ETH_UNIT_DEF_ADDR_REG(port) (ETH_REG_BASE(port) + 0x008)
  66575. +#define ETH_UNIT_DEF_ID_REG(port) (ETH_REG_BASE(port) + 0x00c)
  66576. +#define ETH_UNIT_RESERVED(port) (ETH_REG_BASE(port) + 0x014)
  66577. +#define ETH_UNIT_INTR_CAUSE_REG(port) (ETH_REG_BASE(port) + 0x080)
  66578. +#define ETH_UNIT_INTR_MASK_REG(port) (ETH_REG_BASE(port) + 0x084)
  66579. +
  66580. +
  66581. +#define ETH_UNIT_ERROR_ADDR_REG(port) (ETH_REG_BASE(port) + 0x094)
  66582. +#define ETH_UNIT_INT_ADDR_ERROR_REG(port) (ETH_REG_BASE(port) + 0x098)
  66583. +#define ETH_UNIT_CONTROL_REG(port) (ETH_REG_BASE(port) + 0x0B0)
  66584. +
  66585. +#define ETH_PORT_CONFIG_REG(port) (ETH_REG_BASE(port) + 0x400)
  66586. +#define ETH_PORT_CONFIG_EXTEND_REG(port) (ETH_REG_BASE(port) + 0x404)
  66587. +#define ETH_MII_SERIAL_PARAM_REG(port) (ETH_REG_BASE(port) + 0x408)
  66588. +#define ETH_GMII_SERIAL_PARAM_REG(port) (ETH_REG_BASE(port) + 0x40c)
  66589. +#define ETH_VLAN_ETHER_TYPE_REG(port) (ETH_REG_BASE(port) + 0x410)
  66590. +#define ETH_MAC_ADDR_LOW_REG(port) (ETH_REG_BASE(port) + 0x414)
  66591. +#define ETH_MAC_ADDR_HIGH_REG(port) (ETH_REG_BASE(port) + 0x418)
  66592. +#define ETH_SDMA_CONFIG_REG(port) (ETH_REG_BASE(port) + 0x41c)
  66593. +#define ETH_DIFF_SERV_PRIO_REG(port, code) (ETH_REG_BASE(port) + 0x420 + ((code)<<2))
  66594. +#define ETH_PORT_SERIAL_CTRL_REG(port) (ETH_REG_BASE(port) + 0x43c)
  66595. +#define ETH_VLAN_TAG_TO_PRIO_REG(port) (ETH_REG_BASE(port) + 0x440)
  66596. +#define ETH_PORT_STATUS_REG(port) (ETH_REG_BASE(port) + 0x444)
  66597. +
  66598. +#define ETH_RX_QUEUE_COMMAND_REG(port) (ETH_REG_BASE(port) + 0x680)
  66599. +#define ETH_TX_QUEUE_COMMAND_REG(port) (ETH_REG_BASE(port) + 0x448)
  66600. +
  66601. +#define ETH_PORT_SERIAL_CTRL_1_REG(port) (ETH_REG_BASE(port) + 0x44c)
  66602. +#define ETH_PORT_STATUS_1_REG(port) (ETH_REG_BASE(port) + 0x450)
  66603. +#define ETH_PORT_MARVELL_HEADER_REG(port) (ETH_REG_BASE(port) + 0x454)
  66604. +#define ETH_PORT_FIFO_PARAMS_REG(port) (ETH_REG_BASE(port) + 0x458)
  66605. +#define ETH_MAX_TOKEN_BUCKET_SIZE_REG(port) (ETH_REG_BASE(port) + 0x45c)
  66606. +#define ETH_INTR_CAUSE_REG(port) (ETH_REG_BASE(port) + 0x460)
  66607. +#define ETH_INTR_CAUSE_EXT_REG(port) (ETH_REG_BASE(port) + 0x464)
  66608. +#define ETH_INTR_MASK_REG(port) (ETH_REG_BASE(port) + 0x468)
  66609. +#define ETH_INTR_MASK_EXT_REG(port) (ETH_REG_BASE(port) + 0x46c)
  66610. +#define ETH_TX_FIFO_URGENT_THRESH_REG(port) (ETH_REG_BASE(port) + 0x474)
  66611. +#define ETH_RX_MINIMAL_FRAME_SIZE_REG(port) (ETH_REG_BASE(port) + 0x47c)
  66612. +#define ETH_RX_DISCARD_PKTS_CNTR_REG(port) (ETH_REG_BASE(port) + 0x484)
  66613. +#define ETH_RX_OVERRUN_PKTS_CNTR_REG(port) (ETH_REG_BASE(port) + 0x488)
  66614. +#define ETH_INTERNAL_ADDR_ERROR_REG(port) (ETH_REG_BASE(port) + 0x494)
  66615. +#define ETH_TX_FIXED_PRIO_CFG_REG(port) (ETH_REG_BASE(port) + 0x4dc)
  66616. +#define ETH_TX_TOKEN_RATE_CFG_REG(port) (ETH_REG_BASE(port) + 0x4e0)
  66617. +#define ETH_TX_QUEUE_COMMAND1_REG(port) (ETH_REG_BASE(port) + 0x4e4)
  66618. +#define ETH_MAX_TRANSMIT_UNIT_REG(port) (ETH_REG_BASE(port) + 0x4e8)
  66619. +#define ETH_TX_TOKEN_BUCKET_SIZE_REG(port) (ETH_REG_BASE(port) + 0x4ec)
  66620. +#define ETH_TX_TOKEN_BUCKET_COUNT_REG(port) (ETH_REG_BASE(port) + 0x780)
  66621. +#define ETH_RX_DESCR_STAT_CMD_REG(port, q) (ETH_REG_BASE(port) + 0x600 + ((q)<<4))
  66622. +#define ETH_RX_BYTE_COUNT_REG(port, q) (ETH_REG_BASE(port) + 0x604 + ((q)<<4))
  66623. +#define ETH_RX_BUF_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x608 + ((q)<<4))
  66624. +#define ETH_RX_CUR_DESC_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x60c + ((q)<<4))
  66625. +#define ETH_TX_CUR_DESC_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x6c0 + ((q)<<2))
  66626. +
  66627. +#define ETH_TXQ_TOKEN_COUNT_REG(port, q) (ETH_REG_BASE(port) + 0x700 + ((q)<<4))
  66628. +#define ETH_TXQ_TOKEN_CFG_REG(port, q) (ETH_REG_BASE(port) + 0x704 + ((q)<<4))
  66629. +#define ETH_TXQ_ARBITER_CFG_REG(port, q) (ETH_REG_BASE(port) + 0x708 + ((q)<<4))
  66630. +
  66631. +#if (MV_ETH_VERSION >= 4)
  66632. +#define ETH_TXQ_CMD_1_REG(port) (ETH_REG_BASE(port) + 0x4E4)
  66633. +#define ETH_EJP_TX_HI_IPG_REG(port) (ETH_REG_BASE(port) + 0x7A8)
  66634. +#define ETH_EJP_TX_LO_IPG_REG(port) (ETH_REG_BASE(port) + 0x7B8)
  66635. +#define ETH_EJP_HI_TKN_LO_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C0)
  66636. +#define ETH_EJP_HI_TKN_ASYNC_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C4)
  66637. +#define ETH_EJP_LO_TKN_ASYNC_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C8)
  66638. +#define ETH_EJP_TX_SPEED_REG(port) (ETH_REG_BASE(port) + 0x7D0)
  66639. +#endif /* MV_ETH_VERSION >= 4 */
  66640. +
  66641. +#define ETH_MIB_COUNTERS_BASE(port) (ETH_REG_BASE(port) + 0x1000)
  66642. +#define ETH_DA_FILTER_SPEC_MCAST_BASE(port) (ETH_REG_BASE(port) + 0x1400)
  66643. +#define ETH_DA_FILTER_OTH_MCAST_BASE(port) (ETH_REG_BASE(port) + 0x1500)
  66644. +#define ETH_DA_FILTER_UCAST_BASE(port) (ETH_REG_BASE(port) + 0x1600)
  66645. +
  66646. +/* Phy address register definitions */
  66647. +#define ETH_PHY_ADDR_OFFS 0
  66648. +#define ETH_PHY_ADDR_MASK (0x1f <<ETH_PHY_ADDR_OFFS)
  66649. +
  66650. +/* MIB Counters register definitions */
  66651. +#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW 0x0
  66652. +#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH 0x4
  66653. +#define ETH_MIB_BAD_OCTETS_RECEIVED 0x8
  66654. +#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR 0xc
  66655. +#define ETH_MIB_GOOD_FRAMES_RECEIVED 0x10
  66656. +#define ETH_MIB_BAD_FRAMES_RECEIVED 0x14
  66657. +#define ETH_MIB_BROADCAST_FRAMES_RECEIVED 0x18
  66658. +#define ETH_MIB_MULTICAST_FRAMES_RECEIVED 0x1c
  66659. +#define ETH_MIB_FRAMES_64_OCTETS 0x20
  66660. +#define ETH_MIB_FRAMES_65_TO_127_OCTETS 0x24
  66661. +#define ETH_MIB_FRAMES_128_TO_255_OCTETS 0x28
  66662. +#define ETH_MIB_FRAMES_256_TO_511_OCTETS 0x2c
  66663. +#define ETH_MIB_FRAMES_512_TO_1023_OCTETS 0x30
  66664. +#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS 0x34
  66665. +#define ETH_MIB_GOOD_OCTETS_SENT_LOW 0x38
  66666. +#define ETH_MIB_GOOD_OCTETS_SENT_HIGH 0x3c
  66667. +#define ETH_MIB_GOOD_FRAMES_SENT 0x40
  66668. +#define ETH_MIB_EXCESSIVE_COLLISION 0x44
  66669. +#define ETH_MIB_MULTICAST_FRAMES_SENT 0x48
  66670. +#define ETH_MIB_BROADCAST_FRAMES_SENT 0x4c
  66671. +#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED 0x50
  66672. +#define ETH_MIB_FC_SENT 0x54
  66673. +#define ETH_MIB_GOOD_FC_RECEIVED 0x58
  66674. +#define ETH_MIB_BAD_FC_RECEIVED 0x5c
  66675. +#define ETH_MIB_UNDERSIZE_RECEIVED 0x60
  66676. +#define ETH_MIB_FRAGMENTS_RECEIVED 0x64
  66677. +#define ETH_MIB_OVERSIZE_RECEIVED 0x68
  66678. +#define ETH_MIB_JABBER_RECEIVED 0x6c
  66679. +#define ETH_MIB_MAC_RECEIVE_ERROR 0x70
  66680. +#define ETH_MIB_BAD_CRC_EVENT 0x74
  66681. +#define ETH_MIB_COLLISION 0x78
  66682. +#define ETH_MIB_LATE_COLLISION 0x7c
  66683. +
  66684. +
  66685. +/****************************************/
  66686. +/* Ethernet Unit Register BITs */
  66687. +/****************************************/
  66688. +
  66689. +#define ETH_RXQ_ENABLE_OFFSET 0
  66690. +#define ETH_RXQ_ENABLE_MASK (0x000000FF << ETH_RXQ_ENABLE_OFFSET)
  66691. +
  66692. +#define ETH_RXQ_DISABLE_OFFSET 8
  66693. +#define ETH_RXQ_DISABLE_MASK (0x000000FF << ETH_RXQ_DISABLE_OFFSET)
  66694. +
  66695. +/***** BITs of Transmit Queue Command (TQC) register *****/
  66696. +#define ETH_TXQ_ENABLE_OFFSET 0
  66697. +#define ETH_TXQ_ENABLE_MASK (0x000000FF << ETH_TXQ_ENABLE_OFFSET)
  66698. +
  66699. +#define ETH_TXQ_DISABLE_OFFSET 8
  66700. +#define ETH_TXQ_DISABLE_MASK (0x000000FF << ETH_TXQ_DISABLE_OFFSET)
  66701. +
  66702. +#if (MV_ETH_VERSION >= 4)
  66703. +#define ETH_TX_EJP_RESET_BIT 0
  66704. +#define ETH_TX_EJP_RESET_MASK (1 << ETH_TX_EJP_RESET_BIT)
  66705. +
  66706. +#define ETH_TX_EJP_ENABLE_BIT 2
  66707. +#define ETH_TX_EJP_ENABLE_MASK (1 << ETH_TX_EJP_ENABLE_BIT)
  66708. +
  66709. +#define ETH_TX_LEGACY_WRR_BIT 3
  66710. +#define ETH_TX_LEGACY_WRR_MASK (1 << ETH_TX_LEGACY_WRR_BIT)
  66711. +#endif /* (MV_ETH_VERSION >= 4) */
  66712. +
  66713. +/***** BITs of Ethernet Port Status reg (PSR) *****/
  66714. +#define ETH_LINK_UP_BIT 1
  66715. +#define ETH_LINK_UP_MASK (1<<ETH_LINK_UP_BIT)
  66716. +
  66717. +#define ETH_FULL_DUPLEX_BIT 2
  66718. +#define ETH_FULL_DUPLEX_MASK (1<<ETH_FULL_DUPLEX_BIT)
  66719. +
  66720. +#define ETH_ENABLE_RCV_FLOW_CTRL_BIT 3
  66721. +#define ETH_ENABLE_RCV_FLOW_CTRL_MASK (1<<ETH_ENABLE_RCV_FLOW_CTRL_BIT)
  66722. +
  66723. +#define ETH_GMII_SPEED_1000_BIT 4
  66724. +#define ETH_GMII_SPEED_1000_MASK (1<<ETH_GMII_SPEED_1000_BIT)
  66725. +
  66726. +#define ETH_MII_SPEED_100_BIT 5
  66727. +#define ETH_MII_SPEED_100_MASK (1<<ETH_MII_SPEED_100_BIT)
  66728. +
  66729. +#define ETH_TX_IN_PROGRESS_BIT 7
  66730. +#define ETH_TX_IN_PROGRESS_MASK (1<<ETH_TX_IN_PROGRESS_BIT)
  66731. +
  66732. +#define ETH_TX_FIFO_EMPTY_BIT 10
  66733. +#define ETH_TX_FIFO_EMPTY_MASK (1<<ETH_TX_FIFO_EMPTY_BIT)
  66734. +
  66735. +/***** BITs of Ethernet Port Status 1 reg (PS1R) *****/
  66736. +#define ETH_AUTO_NEG_DONE_BIT 4
  66737. +#define ETH_AUTO_NEG_DONE_MASK (1<<ETH_AUTO_NEG_DONE_BIT)
  66738. +
  66739. +#define ETH_SERDES_PLL_LOCKED_BIT 6
  66740. +#define ETH_SERDES_PLL_LOCKED_MASK (1<<ETH_SERDES_PLL_LOCKED_BIT)
  66741. +
  66742. +/***** BITs of Port Configuration reg (PxCR) *****/
  66743. +#define ETH_UNICAST_PROMISCUOUS_MODE_BIT 0
  66744. +#define ETH_UNICAST_PROMISCUOUS_MODE_MASK (1<<ETH_UNICAST_PROMISCUOUS_MODE_BIT)
  66745. +
  66746. +#define ETH_DEF_RX_QUEUE_OFFSET 1
  66747. +#define ETH_DEF_RX_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_QUEUE_OFFSET)
  66748. +#define ETH_DEF_RX_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_QUEUE_OFFSET)
  66749. +
  66750. +#define ETH_DEF_RX_ARP_QUEUE_OFFSET 4
  66751. +#define ETH_DEF_RX_ARP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_ARP_QUEUE_OFFSET)
  66752. +#define ETH_DEF_RX_ARP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_ARP_QUEUE_OFFSET)
  66753. +
  66754. +#define ETH_REJECT_NOT_IP_ARP_BCAST_BIT 7
  66755. +#define ETH_REJECT_NOT_IP_ARP_BCAST_MASK (1<<ETH_REJECT_NOT_IP_ARP_BCAST_BIT)
  66756. +
  66757. +#define ETH_REJECT_IP_BCAST_BIT 8
  66758. +#define ETH_REJECT_IP_BCAST_MASK (1<<ETH_REJECT_IP_BCAST_BIT)
  66759. +
  66760. +#define ETH_REJECT_ARP_BCAST_BIT 9
  66761. +#define ETH_REJECT_ARP_BCAST_MASK (1<<ETH_REJECT_ARP_BCAST_BIT)
  66762. +
  66763. +#define ETH_TX_NO_SET_ERROR_SUMMARY_BIT 12
  66764. +#define ETH_TX_NO_SET_ERROR_SUMMARY_MASK (1<<ETH_TX_NO_SET_ERROR_SUMMARY_BIT)
  66765. +
  66766. +#define ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT 14
  66767. +#define ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK (1<<ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT)
  66768. +
  66769. +#define ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT 15
  66770. +#define ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK (1<<ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT)
  66771. +
  66772. +#define ETH_DEF_RX_TCP_QUEUE_OFFSET 16
  66773. +#define ETH_DEF_RX_TCP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_TCP_QUEUE_OFFSET)
  66774. +#define ETH_DEF_RX_TCP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_TCP_QUEUE_OFFSET)
  66775. +
  66776. +#define ETH_DEF_RX_UDP_QUEUE_OFFSET 19
  66777. +#define ETH_DEF_RX_UDP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_UDP_QUEUE_OFFSET)
  66778. +#define ETH_DEF_RX_UDP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_UDP_QUEUE_OFFSET)
  66779. +
  66780. +#define ETH_DEF_RX_BPDU_QUEUE_OFFSET 22
  66781. +#define ETH_DEF_RX_BPDU_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)
  66782. +#define ETH_DEF_RX_BPDU_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)
  66783. +
  66784. +#define ETH_RX_CHECKSUM_MODE_OFFSET 25
  66785. +#define ETH_RX_CHECKSUM_NO_PSEUDO_HDR (0<<ETH_RX_CHECKSUM_MODE_OFFSET)
  66786. +#define ETH_RX_CHECKSUM_WITH_PSEUDO_HDR (1<<ETH_RX_CHECKSUM_MODE_OFFSET)
  66787. +
  66788. +/***** BITs of Port Configuration Extend reg (PxCXR) *****/
  66789. +#define ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT 1
  66790. +#define ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK (1<<ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT)
  66791. +
  66792. +#define ETH_TX_DISABLE_GEN_CRC_BIT 3
  66793. +#define ETH_TX_DISABLE_GEN_CRC_MASK (1<<ETH_TX_DISABLE_GEN_CRC_BIT)
  66794. +
  66795. +/***** BITs of Tx/Rx queue command reg (RQCR/TQCR) *****/
  66796. +#define ETH_QUEUE_ENABLE_OFFSET 0
  66797. +#define ETH_QUEUE_ENABLE_ALL_MASK (0xFF<<ETH_QUEUE_ENABLE_OFFSET)
  66798. +#define ETH_QUEUE_ENABLE_MASK(queue) (1<<((queue)+ETH_QUEUE_ENABLE_OFFSET))
  66799. +
  66800. +#define ETH_QUEUE_DISABLE_OFFSET 8
  66801. +#define ETH_QUEUE_DISABLE_ALL_MASK (0xFF<<ETH_QUEUE_DISABLE_OFFSET)
  66802. +#define ETH_QUEUE_DISABLE_MASK(queue) (1<<((queue)+ETH_QUEUE_DISABLE_OFFSET))
  66803. +
  66804. +
  66805. +/***** BITs of Port Sdma Configuration reg (SDCR) *****/
  66806. +#define ETH_RX_FRAME_INTERRUPT_BIT 0
  66807. +#define ETH_RX_FRAME_INTERRUPT_MASK (1<<ETH_RX_FRAME_INTERRUPT_BIT)
  66808. +
  66809. +#define ETH_BURST_SIZE_1_64BIT_VALUE 0
  66810. +#define ETH_BURST_SIZE_2_64BIT_VALUE 1
  66811. +#define ETH_BURST_SIZE_4_64BIT_VALUE 2
  66812. +#define ETH_BURST_SIZE_8_64BIT_VALUE 3
  66813. +#define ETH_BURST_SIZE_16_64BIT_VALUE 4
  66814. +
  66815. +#define ETH_RX_BURST_SIZE_OFFSET 1
  66816. +#define ETH_RX_BURST_SIZE_ALL_MASK (0x7<<ETH_RX_BURST_SIZE_OFFSET)
  66817. +#define ETH_RX_BURST_SIZE_MASK(burst) ((burst)<<ETH_RX_BURST_SIZE_OFFSET)
  66818. +
  66819. +#define ETH_RX_NO_DATA_SWAP_BIT 4
  66820. +#define ETH_RX_NO_DATA_SWAP_MASK (1<<ETH_RX_NO_DATA_SWAP_BIT)
  66821. +#define ETH_RX_DATA_SWAP_MASK (0<<ETH_RX_NO_DATA_SWAP_BIT)
  66822. +
  66823. +#define ETH_TX_NO_DATA_SWAP_BIT 5
  66824. +#define ETH_TX_NO_DATA_SWAP_MASK (1<<ETH_TX_NO_DATA_SWAP_BIT)
  66825. +#define ETH_TX_DATA_SWAP_MASK (0<<ETH_TX_NO_DATA_SWAP_BIT)
  66826. +
  66827. +#define ETH_DESC_SWAP_BIT 6
  66828. +#define ETH_DESC_SWAP_MASK (1<<ETH_DESC_SWAP_BIT)
  66829. +#define ETH_NO_DESC_SWAP_MASK (0<<ETH_DESC_SWAP_BIT)
  66830. +
  66831. +#define ETH_RX_INTR_COAL_OFFSET 7
  66832. +#define ETH_RX_INTR_COAL_ALL_MASK (0x3fff<<ETH_RX_INTR_COAL_OFFSET)
  66833. +#define ETH_RX_INTR_COAL_MASK(value) (((value)<<ETH_RX_INTR_COAL_OFFSET) \
  66834. + & ETH_RX_INTR_COAL_ALL_MASK)
  66835. +
  66836. +#define ETH_TX_BURST_SIZE_OFFSET 22
  66837. +#define ETH_TX_BURST_SIZE_ALL_MASK (0x7<<ETH_TX_BURST_SIZE_OFFSET)
  66838. +#define ETH_TX_BURST_SIZE_MASK(burst) ((burst)<<ETH_TX_BURST_SIZE_OFFSET)
  66839. +
  66840. +#define ETH_RX_INTR_COAL_MSB_BIT 25
  66841. +#define ETH_RX_INTR_COAL_MSB_MASK (1<<ETH_RX_INTR_COAL_MSB_BIT)
  66842. +
  66843. +/* BITs Port #x Tx FIFO Urgent Threshold (PxTFUT) */
  66844. +#define ETH_TX_INTR_COAL_OFFSET 4
  66845. +#define ETH_TX_INTR_COAL_ALL_MASK (0x3fff << ETH_TX_INTR_COAL_OFFSET)
  66846. +#define ETH_TX_INTR_COAL_MASK(value) (((value) << ETH_TX_INTR_COAL_OFFSET) \
  66847. + & ETH_TX_INTR_COAL_ALL_MASK)
  66848. +
  66849. +/* BITs of Port Serial Control reg (PSCR) */
  66850. +#define ETH_PORT_ENABLE_BIT 0
  66851. +#define ETH_PORT_ENABLE_MASK (1<<ETH_PORT_ENABLE_BIT)
  66852. +
  66853. +#define ETH_FORCE_LINK_PASS_BIT 1
  66854. +#define ETH_FORCE_LINK_PASS_MASK (1<<ETH_FORCE_LINK_PASS_BIT)
  66855. +
  66856. +#define ETH_DISABLE_DUPLEX_AUTO_NEG_BIT 2
  66857. +#define ETH_DISABLE_DUPLEX_AUTO_NEG_MASK (1<<ETH_DISABLE_DUPLEX_AUTO_NEG_BIT)
  66858. +
  66859. +#define ETH_DISABLE_FC_AUTO_NEG_BIT 3
  66860. +#define ETH_DISABLE_FC_AUTO_NEG_MASK (1<<ETH_DISABLE_FC_AUTO_NEG_BIT)
  66861. +
  66862. +#define ETH_ADVERTISE_SYM_FC_BIT 4
  66863. +#define ETH_ADVERTISE_SYM_FC_MASK (1<<ETH_ADVERTISE_SYM_FC_BIT)
  66864. +
  66865. +#define ETH_TX_FC_MODE_OFFSET 5
  66866. +#define ETH_TX_FC_MODE_MASK (3<<ETH_TX_FC_MODE_OFFSET)
  66867. +#define ETH_TX_FC_NO_PAUSE (0<<ETH_TX_FC_MODE_OFFSET)
  66868. +#define ETH_TX_FC_SEND_PAUSE (1<<ETH_TX_FC_MODE_OFFSET)
  66869. +
  66870. +#define ETH_TX_BP_MODE_OFFSET 7
  66871. +#define ETH_TX_BP_MODE_MASK (3<<ETH_TX_BP_MODE_OFFSET)
  66872. +#define ETH_TX_BP_NO_JAM (0<<ETH_TX_BP_MODE_OFFSET)
  66873. +#define ETH_TX_BP_SEND_JAM (1<<ETH_TX_BP_MODE_OFFSET)
  66874. +
  66875. +#define ETH_DO_NOT_FORCE_LINK_FAIL_BIT 10
  66876. +#define ETH_DO_NOT_FORCE_LINK_FAIL_MASK (1<<ETH_DO_NOT_FORCE_LINK_FAIL_BIT)
  66877. +
  66878. +#define ETH_RETRANSMIT_FOREVER_BIT 11
  66879. +#define ETH_RETRANSMIT_FOREVER_MASK (1<<ETH_RETRANSMIT_FOREVER_BIT)
  66880. +
  66881. +#define ETH_DISABLE_SPEED_AUTO_NEG_BIT 13
  66882. +#define ETH_DISABLE_SPEED_AUTO_NEG_MASK (1<<ETH_DISABLE_SPEED_AUTO_NEG_BIT)
  66883. +
  66884. +#define ETH_DTE_ADVERT_BIT 14
  66885. +#define ETH_DTE_ADVERT_MASK (1<<ETH_DTE_ADVERT_BIT)
  66886. +
  66887. +#define ETH_MII_PHY_MODE_BIT 15
  66888. +#define ETH_MII_PHY_MODE_MAC (0<<ETH_MII_PHY_MODE_BIT)
  66889. +#define ETH_MII_PHY_MODE_PHY (1<<ETH_MII_PHY_MODE_BIT)
  66890. +
  66891. +#define ETH_MII_SOURCE_SYNCH_BIT 16
  66892. +#define ETH_MII_STANDARD_SYNCH (0<<ETH_MII_SOURCE_SYNCH_BIT)
  66893. +#define ETH_MII_400Mbps_SYNCH (1<<ETH_MII_SOURCE_CLK_BIT)
  66894. +
  66895. +#define ETH_MAX_RX_PACKET_SIZE_OFFSET 17
  66896. +#define ETH_MAX_RX_PACKET_SIZE_MASK (7<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  66897. +#define ETH_MAX_RX_PACKET_1518BYTE (0<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  66898. +#define ETH_MAX_RX_PACKET_1522BYTE (1<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  66899. +#define ETH_MAX_RX_PACKET_1552BYTE (2<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  66900. +#define ETH_MAX_RX_PACKET_9022BYTE (3<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  66901. +#define ETH_MAX_RX_PACKET_9192BYTE (4<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  66902. +#define ETH_MAX_RX_PACKET_9700BYTE (5<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  66903. +
  66904. +#define ETH_SET_FULL_DUPLEX_BIT 21
  66905. +#define ETH_SET_FULL_DUPLEX_MASK (1<<ETH_SET_FULL_DUPLEX_BIT)
  66906. +
  66907. +#define ETH_SET_FLOW_CTRL_BIT 22
  66908. +#define ETH_SET_FLOW_CTRL_MASK (1<<ETH_SET_FLOW_CTRL_BIT)
  66909. +
  66910. +#define ETH_SET_GMII_SPEED_1000_BIT 23
  66911. +#define ETH_SET_GMII_SPEED_1000_MASK (1<<ETH_SET_GMII_SPEED_1000_BIT)
  66912. +
  66913. +#define ETH_SET_MII_SPEED_100_BIT 24
  66914. +#define ETH_SET_MII_SPEED_100_MASK (1<<ETH_SET_MII_SPEED_100_BIT)
  66915. +
  66916. +/* BITs of Port Serial Control 1 reg (PSC1R) */
  66917. +#define ETH_PSC_ENABLE_BIT 2
  66918. +#define ETH_PSC_ENABLE_MASK (1<<ETH_PSC_ENABLE_BIT)
  66919. +
  66920. +#define ETH_RGMII_ENABLE_BIT 3
  66921. +#define ETH_RGMII_ENABLE_MASK (1<<ETH_RGMII_ENABLE_BIT)
  66922. +
  66923. +#define ETH_PORT_RESET_BIT 4
  66924. +#define ETH_PORT_RESET_MASK (1<<ETH_PORT_RESET_BIT)
  66925. +
  66926. +#define ETH_INBAND_AUTO_NEG_ENABLE_BIT 6
  66927. +#define ETH_INBAND_AUTO_NEG_ENABLE_MASK (1<<ETH_INBAND_AUTO_NEG_ENABLE_BIT)
  66928. +
  66929. +#define ETH_INBAND_AUTO_NEG_BYPASS_BIT 7
  66930. +#define ETH_INBAND_AUTO_NEG_BYPASS_MASK (1<<ETH_INBAND_AUTO_NEG_BYPASS_BIT)
  66931. +
  66932. +#define ETH_INBAND_AUTO_NEG_START_BIT 8
  66933. +#define ETH_INBAND_AUTO_NEG_START_MASK (1<<ETH_INBAND_AUTO_NEG_START_BIT)
  66934. +
  66935. +#define ETH_PORT_TYPE_BIT 11
  66936. +#define ETH_PORT_TYPE_1000BasedX_MASK (1<<ETH_PORT_TYPE_BIT)
  66937. +
  66938. +#define ETH_SGMII_MODE_BIT 12
  66939. +#define ETH_1000BaseX_MODE_MASK (0<<ETH_SGMII_MODE_BIT)
  66940. +#define ETH_SGMII_MODE_MASK (1<<ETH_SGMII_MODE_BIT)
  66941. +
  66942. +#define ETH_MGMII_MODE_BIT 13
  66943. +
  66944. +#define ETH_EN_MII_ODD_PRE_BIT 22
  66945. +#define ETH_EN_MII_ODD_PRE_MASK (1<<ETH_EN_MII_ODD_PRE_BIT)
  66946. +
  66947. +/* BITs of SDMA Descriptor Command/Status field */
  66948. +#if defined(MV_CPU_BE)
  66949. +typedef struct _ethRxDesc
  66950. +{
  66951. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  66952. + MV_U16 bufSize ; /* Buffer size */
  66953. + MV_U32 cmdSts ; /* Descriptor command status */
  66954. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  66955. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  66956. + MV_ULONG returnInfo ; /* User resource return information */
  66957. +} ETH_RX_DESC;
  66958. +
  66959. +typedef struct _ethTxDesc
  66960. +{
  66961. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  66962. + MV_U16 L4iChk ; /* CPU provided TCP Checksum */
  66963. + MV_U32 cmdSts ; /* Descriptor command status */
  66964. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  66965. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  66966. + MV_ULONG returnInfo ; /* User resource return information */
  66967. + MV_U8* alignBufPtr; /* Pointer to 8 byte aligned buffer */
  66968. +} ETH_TX_DESC;
  66969. +
  66970. +#elif defined(MV_CPU_LE)
  66971. +
  66972. +typedef struct _ethRxDesc
  66973. +{
  66974. + MV_U32 cmdSts ; /* Descriptor command status */
  66975. + MV_U16 bufSize ; /* Buffer size */
  66976. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  66977. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  66978. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  66979. + MV_ULONG returnInfo ; /* User resource return information */
  66980. +} ETH_RX_DESC;
  66981. +
  66982. +typedef struct _ethTxDesc
  66983. +{
  66984. + MV_U32 cmdSts ; /* Descriptor command status */
  66985. + MV_U16 L4iChk ; /* CPU provided TCP Checksum */
  66986. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  66987. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  66988. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  66989. + MV_ULONG returnInfo ; /* User resource return information */
  66990. + MV_U8* alignBufPtr; /* Pointer to 32 byte aligned buffer */
  66991. +} ETH_TX_DESC;
  66992. +
  66993. +#else
  66994. +#error "MV_CPU_BE or MV_CPU_LE must be defined"
  66995. +#endif /* MV_CPU_BE || MV_CPU_LE */
  66996. +
  66997. +/* Buffer offset from buffer pointer */
  66998. +#define ETH_RX_BUF_OFFSET 0x2
  66999. +
  67000. +
  67001. +/* Tx & Rx descriptor bits */
  67002. +#define ETH_ERROR_SUMMARY_BIT 0
  67003. +#define ETH_ERROR_SUMMARY_MASK (1<<ETH_ERROR_SUMMARY_BIT)
  67004. +
  67005. +#define ETH_BUFFER_OWNER_BIT 31
  67006. +#define ETH_BUFFER_OWNED_BY_DMA (1<<ETH_BUFFER_OWNER_BIT)
  67007. +#define ETH_BUFFER_OWNED_BY_HOST (0<<ETH_BUFFER_OWNER_BIT)
  67008. +
  67009. +/* Tx descriptor bits */
  67010. +#define ETH_TX_ERROR_CODE_OFFSET 1
  67011. +#define ETH_TX_ERROR_CODE_MASK (3<<ETH_TX_ERROR_CODE_OFFSET)
  67012. +#define ETH_TX_LATE_COLLISION_ERROR (0<<ETH_TX_ERROR_CODE_OFFSET)
  67013. +#define ETH_TX_UNDERRUN_ERROR (1<<ETH_TX_ERROR_CODE_OFFSET)
  67014. +#define ETH_TX_EXCESSIVE_COLLISION_ERROR (2<<ETH_TX_ERROR_CODE_OFFSET)
  67015. +
  67016. +#define ETH_TX_LLC_SNAP_FORMAT_BIT 9
  67017. +#define ETH_TX_LLC_SNAP_FORMAT_MASK (1<<ETH_TX_LLC_SNAP_FORMAT_BIT)
  67018. +
  67019. +#define ETH_TX_IP_FRAG_BIT 10
  67020. +#define ETH_TX_IP_FRAG_MASK (1<<ETH_TX_IP_FRAG_BIT)
  67021. +#define ETH_TX_IP_FRAG (0<<ETH_TX_IP_FRAG_BIT)
  67022. +#define ETH_TX_IP_NO_FRAG (1<<ETH_TX_IP_FRAG_BIT)
  67023. +
  67024. +#define ETH_TX_IP_HEADER_LEN_OFFSET 11
  67025. +#define ETH_TX_IP_HEADER_LEN_ALL_MASK (0xF<<ETH_TX_IP_HEADER_LEN_OFFSET)
  67026. +#define ETH_TX_IP_HEADER_LEN_MASK(len) ((len)<<ETH_TX_IP_HEADER_LEN_OFFSET)
  67027. +
  67028. +#define ETH_TX_VLAN_TAGGED_FRAME_BIT 15
  67029. +#define ETH_TX_VLAN_TAGGED_FRAME_MASK (1<<ETH_TX_VLAN_TAGGED_FRAME_BIT)
  67030. +
  67031. +#define ETH_TX_L4_TYPE_BIT 16
  67032. +#define ETH_TX_L4_TCP_TYPE (0<<ETH_TX_L4_TYPE_BIT)
  67033. +#define ETH_TX_L4_UDP_TYPE (1<<ETH_TX_L4_TYPE_BIT)
  67034. +
  67035. +#define ETH_TX_GENERATE_L4_CHKSUM_BIT 17
  67036. +#define ETH_TX_GENERATE_L4_CHKSUM_MASK (1<<ETH_TX_GENERATE_L4_CHKSUM_BIT)
  67037. +
  67038. +#define ETH_TX_GENERATE_IP_CHKSUM_BIT 18
  67039. +#define ETH_TX_GENERATE_IP_CHKSUM_MASK (1<<ETH_TX_GENERATE_IP_CHKSUM_BIT)
  67040. +
  67041. +#define ETH_TX_ZERO_PADDING_BIT 19
  67042. +#define ETH_TX_ZERO_PADDING_MASK (1<<ETH_TX_ZERO_PADDING_BIT)
  67043. +
  67044. +#define ETH_TX_LAST_DESC_BIT 20
  67045. +#define ETH_TX_LAST_DESC_MASK (1<<ETH_TX_LAST_DESC_BIT)
  67046. +
  67047. +#define ETH_TX_FIRST_DESC_BIT 21
  67048. +#define ETH_TX_FIRST_DESC_MASK (1<<ETH_TX_FIRST_DESC_BIT)
  67049. +
  67050. +#define ETH_TX_GENERATE_CRC_BIT 22
  67051. +#define ETH_TX_GENERATE_CRC_MASK (1<<ETH_TX_GENERATE_CRC_BIT)
  67052. +
  67053. +#define ETH_TX_ENABLE_INTERRUPT_BIT 23
  67054. +#define ETH_TX_ENABLE_INTERRUPT_MASK (1<<ETH_TX_ENABLE_INTERRUPT_BIT)
  67055. +
  67056. +#define ETH_TX_AUTO_MODE_BIT 30
  67057. +#define ETH_TX_AUTO_MODE_MASK (1<<ETH_TX_AUTO_MODE_BIT)
  67058. +
  67059. +
  67060. +/* Rx descriptor bits */
  67061. +#define ETH_RX_ERROR_CODE_OFFSET 1
  67062. +#define ETH_RX_ERROR_CODE_MASK (3<<ETH_RX_ERROR_CODE_OFFSET)
  67063. +#define ETH_RX_CRC_ERROR (0<<ETH_RX_ERROR_CODE_OFFSET)
  67064. +#define ETH_RX_OVERRUN_ERROR (1<<ETH_RX_ERROR_CODE_OFFSET)
  67065. +#define ETH_RX_MAX_FRAME_LEN_ERROR (2<<ETH_RX_ERROR_CODE_OFFSET)
  67066. +#define ETH_RX_RESOURCE_ERROR (3<<ETH_RX_ERROR_CODE_OFFSET)
  67067. +
  67068. +#define ETH_RX_L4_CHECKSUM_OFFSET 3
  67069. +#define ETH_RX_L4_CHECKSUM_MASK (0xffff<<ETH_RX_L4_CHECKSUM_OFFSET)
  67070. +
  67071. +#define ETH_RX_VLAN_TAGGED_FRAME_BIT 19
  67072. +#define ETH_RX_VLAN_TAGGED_FRAME_MASK (1<<ETH_RX_VLAN_TAGGED_FRAME_BIT)
  67073. +
  67074. +#define ETH_RX_BPDU_FRAME_BIT 20
  67075. +#define ETH_RX_BPDU_FRAME_MASK (1<<ETH_RX_BPDU_FRAME_BIT)
  67076. +
  67077. +#define ETH_RX_L4_TYPE_OFFSET 21
  67078. +#define ETH_RX_L4_TYPE_MASK (3<<ETH_RX_L4_TYPE_OFFSET)
  67079. +#define ETH_RX_L4_TCP_TYPE (0<<ETH_RX_L4_TYPE_OFFSET)
  67080. +#define ETH_RX_L4_UDP_TYPE (1<<ETH_RX_L4_TYPE_OFFSET)
  67081. +#define ETH_RX_L4_OTHER_TYPE (2<<ETH_RX_L4_TYPE_OFFSET)
  67082. +
  67083. +#define ETH_RX_NOT_LLC_SNAP_FORMAT_BIT 23
  67084. +#define ETH_RX_NOT_LLC_SNAP_FORMAT_MASK (1<<ETH_RX_NOT_LLC_SNAP_FORMAT_BIT)
  67085. +
  67086. +#define ETH_RX_IP_FRAME_TYPE_BIT 24
  67087. +#define ETH_RX_IP_FRAME_TYPE_MASK (1<<ETH_RX_IP_FRAME_TYPE_BIT)
  67088. +
  67089. +#define ETH_RX_IP_HEADER_OK_BIT 25
  67090. +#define ETH_RX_IP_HEADER_OK_MASK (1<<ETH_RX_IP_HEADER_OK_BIT)
  67091. +
  67092. +#define ETH_RX_LAST_DESC_BIT 26
  67093. +#define ETH_RX_LAST_DESC_MASK (1<<ETH_RX_LAST_DESC_BIT)
  67094. +
  67095. +#define ETH_RX_FIRST_DESC_BIT 27
  67096. +#define ETH_RX_FIRST_DESC_MASK (1<<ETH_RX_FIRST_DESC_BIT)
  67097. +
  67098. +#define ETH_RX_UNKNOWN_DA_BIT 28
  67099. +#define ETH_RX_UNKNOWN_DA_MASK (1<<ETH_RX_UNKNOWN_DA_BIT)
  67100. +
  67101. +#define ETH_RX_ENABLE_INTERRUPT_BIT 29
  67102. +#define ETH_RX_ENABLE_INTERRUPT_MASK (1<<ETH_RX_ENABLE_INTERRUPT_BIT)
  67103. +
  67104. +#define ETH_RX_L4_CHECKSUM_OK_BIT 30
  67105. +#define ETH_RX_L4_CHECKSUM_OK_MASK (1<<ETH_RX_L4_CHECKSUM_OK_BIT)
  67106. +
  67107. +/* Rx descriptor bufSize field */
  67108. +#define ETH_RX_IP_FRAGMENTED_FRAME_BIT 2
  67109. +#define ETH_RX_IP_FRAGMENTED_FRAME_MASK (1<<ETH_RX_IP_FRAGMENTED_FRAME_BIT)
  67110. +
  67111. +#define ETH_RX_BUFFER_MASK 0xFFF8
  67112. +
  67113. +
  67114. +/* Ethernet Cause Register BITs */
  67115. +#define ETH_CAUSE_RX_READY_SUM_BIT 0
  67116. +#define ETH_CAUSE_EXTEND_BIT 1
  67117. +
  67118. +#define ETH_CAUSE_RX_READY_OFFSET 2
  67119. +#define ETH_CAUSE_RX_READY_BIT(queue) (ETH_CAUSE_RX_READY_OFFSET + (queue))
  67120. +#define ETH_CAUSE_RX_READY_MASK(queue) (1 << (ETH_CAUSE_RX_READY_BIT(queue)))
  67121. +
  67122. +#define ETH_CAUSE_RX_ERROR_SUM_BIT 10
  67123. +#define ETH_CAUSE_RX_ERROR_OFFSET 11
  67124. +#define ETH_CAUSE_RX_ERROR_BIT(queue) (ETH_CAUSE_RX_ERROR_OFFSET + (queue))
  67125. +#define ETH_CAUSE_RX_ERROR_MASK(queue) (1 << (ETH_CAUSE_RX_ERROR_BIT(queue)))
  67126. +
  67127. +#define ETH_CAUSE_TX_END_BIT 19
  67128. +#define ETH_CAUSE_SUM_BIT 31
  67129. +
  67130. +/* Ethernet Cause Extended Register BITs */
  67131. +#define ETH_CAUSE_TX_BUF_OFFSET 0
  67132. +#define ETH_CAUSE_TX_BUF_BIT(queue) (ETH_CAUSE_TX_BUF_OFFSET + (queue))
  67133. +#define ETH_CAUSE_TX_BUF_MASK(queue) (1 << (ETH_CAUSE_TX_BUF_BIT(queue)))
  67134. +
  67135. +#define ETH_CAUSE_TX_ERROR_OFFSET 8
  67136. +#define ETH_CAUSE_TX_ERROR_BIT(queue) (ETH_CAUSE_TX_ERROR_OFFSET + (queue))
  67137. +#define ETH_CAUSE_TX_ERROR_MASK(queue) (1 << (ETH_CAUSE_TX_ERROR_BIT(queue)))
  67138. +
  67139. +#define ETH_CAUSE_PHY_STATUS_CHANGE_BIT 16
  67140. +#define ETH_CAUSE_RX_OVERRUN_BIT 18
  67141. +#define ETH_CAUSE_TX_UNDERRUN_BIT 19
  67142. +#define ETH_CAUSE_LINK_STATE_CHANGE_BIT 20
  67143. +#define ETH_CAUSE_INTERNAL_ADDR_ERR_BIT 23
  67144. +#define ETH_CAUSE_EXTEND_SUM_BIT 31
  67145. +
  67146. +/* Marvell Header Register */
  67147. +/* Marvell Header register bits */
  67148. +#define ETH_MVHDR_EN_BIT 0
  67149. +#define ETH_MVHDR_EN_MASK (1 << ETH_MVHDR_EN_BIT)
  67150. +
  67151. +#define ETH_MVHDR_DAPREFIX_BIT 1
  67152. +#define ETH_MVHDR_DAPREFIX_MASK (0x3 << ETH_MVHDR_DAPREFIX_BIT)
  67153. +#define ETH_MVHDR_DAPREFIX_PRI_1_2 (0x1 << ETH_MVHDR_DAPREFIX_BIT)
  67154. +#define ETH_MVHDR_DAPREFIX_DBNUM_PRI (0x2 << ETH_MVHDR_DAPREFIX_BIT)
  67155. +#define ETH_MVHDR_DAPREFIX_SPID_PRI (0x3 << ETH_MVHDR_DAPREFIX_BIT)
  67156. +
  67157. +#define ETH_MVHDR_MHMASK_BIT 8
  67158. +#define ETH_MVHDR_MHMASK_MASK (0x3 << ETH_MVHDR_MHMASK_BIT)
  67159. +#define ETH_MVHDR_MHMASK_8_QUEUE (0x0 << ETH_MVHDR_MHMASK_BIT)
  67160. +#define ETH_MVHDR_MHMASK_4_QUEUE (0x1 << ETH_MVHDR_MHMASK_BIT)
  67161. +#define ETH_MVHDR_MHMASK_2_QUEUE (0x3 << ETH_MVHDR_MHMASK_BIT)
  67162. +
  67163. +
  67164. +/* Relevant for 6183 ONLY */
  67165. +#define ETH_UNIT_PORTS_PADS_CALIB_0_REG (MV_ETH_REG_BASE(0) + 0x0A0)
  67166. +#define ETH_UNIT_PORTS_PADS_CALIB_1_REG (MV_ETH_REG_BASE(0) + 0x0A4)
  67167. +#define ETH_UNIT_PORTS_PADS_CALIB_2_REG (MV_ETH_REG_BASE(0) + 0x0A8)
  67168. +/* Ethernet Unit Ports Pads Calibration_REG (ETH_UNIT_PORTS_PADS_CALIB_x_REG) */
  67169. +#define ETH_ETHERNET_PAD_CLIB_DRVN_OFFS 0
  67170. +#define ETH_ETHERNET_PAD_CLIB_DRVN_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_DRVN_OFFS)
  67171. +
  67172. +#define ETH_ETHERNET_PAD_CLIB_DRVP_OFFS 5
  67173. +#define ETH_ETHERNET_PAD_CLIB_DRVP_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_DRVP_OFFS)
  67174. +
  67175. +#define ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS 16
  67176. +#define ETH_ETHERNET_PAD_CLIB_TUNEEN_MASK (0x1 << ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS)
  67177. +
  67178. +#define ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS 17
  67179. +#define ETH_ETHERNET_PAD_CLIB_LOCKN_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS)
  67180. +
  67181. +#define ETH_ETHERNET_PAD_CLIB_OFFST_OFFS 24
  67182. +#define ETH_ETHERNET_PAD_CLIB_OFFST_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_OFFST_OFFS)
  67183. +
  67184. +#define ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS 31
  67185. +#define ETH_ETHERNET_PAD_CLIB_WR_EN_MASK (0x1 << ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS)
  67186. +
  67187. +
  67188. +#ifdef __cplusplus
  67189. +}
  67190. +#endif /* __cplusplus */
  67191. +
  67192. +#endif /* __INCmvEthRegsh */
  67193. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h
  67194. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h 1970-01-01 01:00:00.000000000 +0100
  67195. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h 2011-07-31 11:32:00.384198160 +0200
  67196. @@ -0,0 +1,356 @@
  67197. +/*******************************************************************************
  67198. +Copyright (C) Marvell International Ltd. and its affiliates
  67199. +
  67200. +This software file (the "File") is owned and distributed by Marvell
  67201. +International Ltd. and/or its affiliates ("Marvell") under the following
  67202. +alternative licensing terms. Once you have made an election to distribute the
  67203. +File under one of the following license alternatives, please (i) delete this
  67204. +introductory statement regarding license alternatives, (ii) delete the two
  67205. +license alternatives that you have not elected to use and (iii) preserve the
  67206. +Marvell copyright notice above.
  67207. +
  67208. +********************************************************************************
  67209. +Marvell Commercial License Option
  67210. +
  67211. +If you received this File from Marvell and you have entered into a commercial
  67212. +license agreement (a "Commercial License") with Marvell, the File is licensed
  67213. +to you under the terms of the applicable Commercial License.
  67214. +
  67215. +********************************************************************************
  67216. +Marvell GPL License Option
  67217. +
  67218. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67219. +modify this File in accordance with the terms and conditions of the General
  67220. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  67221. +available along with the File in the license.txt file or by writing to the Free
  67222. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  67223. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  67224. +
  67225. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  67226. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  67227. +DISCLAIMED. The GPL License provides additional details about this warranty
  67228. +disclaimer.
  67229. +********************************************************************************
  67230. +Marvell BSD License Option
  67231. +
  67232. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67233. +modify this File under the following licensing terms.
  67234. +Redistribution and use in source and binary forms, with or without modification,
  67235. +are permitted provided that the following conditions are met:
  67236. +
  67237. + * Redistributions of source code must retain the above copyright notice,
  67238. + this list of conditions and the following disclaimer.
  67239. +
  67240. + * Redistributions in binary form must reproduce the above copyright
  67241. + notice, this list of conditions and the following disclaimer in the
  67242. + documentation and/or other materials provided with the distribution.
  67243. +
  67244. + * Neither the name of Marvell nor the names of its contributors may be
  67245. + used to endorse or promote products derived from this software without
  67246. + specific prior written permission.
  67247. +
  67248. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  67249. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  67250. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  67251. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  67252. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  67253. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  67254. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  67255. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  67256. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  67257. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  67258. +
  67259. +*******************************************************************************/
  67260. +
  67261. +/*******************************************************************************
  67262. +* mvEth.h - Header File for : Ethernet Controller
  67263. +*
  67264. +* DESCRIPTION:
  67265. +* This header file contains macros typedefs and function declaration for
  67266. +* Marvell Gigabit Ethernet Controllers.
  67267. +*
  67268. +* DEPENDENCIES:
  67269. +* None.
  67270. +*
  67271. +*******************************************************************************/
  67272. +
  67273. +#ifndef __mvEth_h__
  67274. +#define __mvEth_h__
  67275. +
  67276. +/* includes */
  67277. +#include "mvTypes.h"
  67278. +#include "mv802_3.h"
  67279. +#include "ctrlEnv/mvCtrlEnvLib.h"
  67280. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  67281. +#include "eth/gbe/mvEthRegs.h"
  67282. +#include "mvSysHwConfig.h"
  67283. +
  67284. +/* defines */
  67285. +
  67286. +#define MV_ETH_EXTRA_FRAGS_NUM 2
  67287. +
  67288. +
  67289. +typedef enum
  67290. +{
  67291. + MV_ETH_SPEED_AN,
  67292. + MV_ETH_SPEED_10,
  67293. + MV_ETH_SPEED_100,
  67294. + MV_ETH_SPEED_1000
  67295. +
  67296. +} MV_ETH_PORT_SPEED;
  67297. +
  67298. +typedef enum
  67299. +{
  67300. + MV_ETH_DUPLEX_AN,
  67301. + MV_ETH_DUPLEX_HALF,
  67302. + MV_ETH_DUPLEX_FULL
  67303. +
  67304. +} MV_ETH_PORT_DUPLEX;
  67305. +
  67306. +typedef enum
  67307. +{
  67308. + MV_ETH_FC_AN_ADV_DIS,
  67309. + MV_ETH_FC_AN_ADV_SYM,
  67310. + MV_ETH_FC_DISABLE,
  67311. + MV_ETH_FC_ENABLE
  67312. +
  67313. +} MV_ETH_PORT_FC;
  67314. +
  67315. +typedef enum
  67316. +{
  67317. + MV_ETH_PRIO_FIXED = 0, /* Fixed priority mode */
  67318. + MV_ETH_PRIO_WRR = 1 /* Weighted round robin priority mode */
  67319. +} MV_ETH_PRIO_MODE;
  67320. +
  67321. +/* Ethernet port specific infomation */
  67322. +typedef struct
  67323. +{
  67324. + int maxRxPktSize;
  67325. + int rxDefQ;
  67326. + int rxBpduQ;
  67327. + int rxArpQ;
  67328. + int rxTcpQ;
  67329. + int rxUdpQ;
  67330. + int ejpMode;
  67331. +} MV_ETH_PORT_CFG;
  67332. +
  67333. +typedef struct
  67334. +{
  67335. + int descrNum;
  67336. +} MV_ETH_RX_Q_CFG;
  67337. +
  67338. +typedef struct
  67339. +{
  67340. + int descrNum;
  67341. + MV_ETH_PRIO_MODE prioMode;
  67342. + int quota;
  67343. +} MV_ETH_TX_Q_CFG;
  67344. +
  67345. +typedef struct
  67346. +{
  67347. + int maxRxPktSize;
  67348. + int rxDefQ;
  67349. + int txDescrNum[MV_ETH_TX_Q_NUM];
  67350. + int rxDescrNum[MV_ETH_RX_Q_NUM];
  67351. + void *osHandle;
  67352. +} MV_ETH_PORT_INIT;
  67353. +
  67354. +typedef struct
  67355. +{
  67356. + MV_BOOL isLinkUp;
  67357. + MV_ETH_PORT_SPEED speed;
  67358. + MV_ETH_PORT_DUPLEX duplex;
  67359. + MV_ETH_PORT_FC flowControl;
  67360. +
  67361. +} MV_ETH_PORT_STATUS;
  67362. +
  67363. +typedef enum
  67364. +{
  67365. + MV_ETH_DISABLE_HEADER_MODE = 0,
  67366. + MV_ETH_ENABLE_HEADER_MODE_PRI_2_1 = 1,
  67367. + MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM = 2,
  67368. + MV_ETH_ENABLE_HEADER_MODE_PRI_SPID = 3
  67369. +} MV_ETH_HEADER_MODE;
  67370. +
  67371. +
  67372. +/* ethernet.h API list */
  67373. +void mvEthHalInit(void);
  67374. +void mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher);
  67375. +
  67376. +/* Port Initalization routines */
  67377. +void* mvEthPortInit (int port, MV_ETH_PORT_INIT *pPortInit);
  67378. +void ethResetTxDescRing(void* pPortHndl, int queue);
  67379. +void ethResetRxDescRing(void* pPortHndl, int queue);
  67380. +
  67381. +void* mvEthPortHndlGet(int port);
  67382. +
  67383. +void mvEthPortFinish(void* pEthPortHndl);
  67384. +MV_STATUS mvEthPortDown(void* pEthPortHndl);
  67385. +MV_STATUS mvEthPortDisable(void* pEthPortHndl);
  67386. +MV_STATUS mvEthPortUp(void* pEthPortHndl);
  67387. +MV_STATUS mvEthPortEnable(void* pEthPortHndl);
  67388. +
  67389. +/* Port data flow routines */
  67390. +MV_PKT_INFO *mvEthPortForceTxDone(void* pEthPortHndl, int txQueue);
  67391. +MV_PKT_INFO *mvEthPortForceRx(void* pEthPortHndl, int rxQueue);
  67392. +
  67393. +/* Port Configuration routines */
  67394. +MV_STATUS mvEthDefaultsSet(void* pEthPortHndl);
  67395. +MV_STATUS mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize);
  67396. +
  67397. +/* Port RX MAC Filtering control routines */
  67398. +MV_U8 mvEthMcastCrc8Get(MV_U8* pAddr);
  67399. +MV_STATUS mvEthRxFilterModeSet(void* pPortHndl, MV_BOOL isPromisc);
  67400. +MV_STATUS mvEthMacAddrSet(void* pPortHandle, MV_U8* pMacAddr, int queue);
  67401. +MV_STATUS mvEthMcastAddrSet(void* pPortHandle, MV_U8 *pAddr, int queue);
  67402. +
  67403. +/* MIB Counters APIs */
  67404. +MV_U32 mvEthMibCounterRead(void* pPortHndl, unsigned int mibOffset,
  67405. + MV_U32* pHigh32);
  67406. +void mvEthMibCountersClear(void* pPortHandle);
  67407. +
  67408. +/* TX Scheduling configuration routines */
  67409. +MV_STATUS mvEthTxQueueConfig(void* pPortHandle, int txQueue,
  67410. + MV_ETH_PRIO_MODE txPrioMode, int txQuota);
  67411. +
  67412. +/* RX Dispatching configuration routines */
  67413. +MV_STATUS mvEthBpduRxQueue(void* pPortHandle, int bpduQueue);
  67414. +MV_STATUS mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue);
  67415. +MV_STATUS mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq);
  67416. +int mvEthTosToRxqGet(void* pPortHandle, int tos);
  67417. +
  67418. +/* Speed, Duplex, FlowControl routines */
  67419. +MV_STATUS mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed,
  67420. + MV_ETH_PORT_DUPLEX duplex);
  67421. +
  67422. +MV_STATUS mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl);
  67423. +
  67424. +#if (MV_ETH_VERSION >= 4)
  67425. +MV_STATUS mvEthEjpModeSet(void* pPortHandle, int mode);
  67426. +#endif /* (MV_ETH_VERSION >= 4) */
  67427. +
  67428. +void mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus);
  67429. +
  67430. +/* Marvell Header control */
  67431. +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);
  67432. +
  67433. +/* PHY routines */
  67434. +void mvEthPhyAddrSet(void* pPortHandle, int phyAddr);
  67435. +int mvEthPhyAddrGet(void* pPortHandle);
  67436. +
  67437. +/* Power management routines */
  67438. +void mvEthPortPowerDown(int port);
  67439. +void mvEthPortPowerUp(int port);
  67440. +
  67441. +/******************** ETH PRIVATE ************************/
  67442. +
  67443. +/*#define UNCACHED_TX_BUFFERS*/
  67444. +/*#define UNCACHED_RX_BUFFERS*/
  67445. +
  67446. +
  67447. +/* Port attributes */
  67448. +/* Size of a Tx/Rx descriptor used in chain list data structure */
  67449. +#define ETH_RX_DESC_ALIGNED_SIZE 32
  67450. +#define ETH_TX_DESC_ALIGNED_SIZE 32
  67451. +
  67452. +#define TX_DISABLE_TIMEOUT_MSEC 1000
  67453. +#define RX_DISABLE_TIMEOUT_MSEC 1000
  67454. +#define TX_FIFO_EMPTY_TIMEOUT_MSEC 10000
  67455. +#define PORT_DISABLE_WAIT_TCLOCKS 5000
  67456. +
  67457. +/* Macros that save access to desc in order to find next desc pointer */
  67458. +#define RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl) \
  67459. + ((pRxDescr) == (pQueueCtrl)->pLastDescr) ? \
  67460. + (ETH_RX_DESC*)((pQueueCtrl)->pFirstDescr) : \
  67461. + (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) + ETH_RX_DESC_ALIGNED_SIZE)
  67462. +
  67463. +#define TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl) \
  67464. + ((pTxDescr) == (pQueueCtrl)->pLastDescr) ? \
  67465. + (ETH_TX_DESC*)((pQueueCtrl)->pFirstDescr) : \
  67466. + (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) + ETH_TX_DESC_ALIGNED_SIZE)
  67467. +
  67468. +#define RX_PREV_DESC_PTR(pRxDescr, pQueueCtrl) \
  67469. + ((pRxDescr) == (pQueueCtrl)->pFirstDescr) ? \
  67470. + (ETH_RX_DESC*)((pQueueCtrl)->pLastDescr) : \
  67471. + (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) - ETH_RX_DESC_ALIGNED_SIZE)
  67472. +
  67473. +#define TX_PREV_DESC_PTR(pTxDescr, pQueueCtrl) \
  67474. + ((pTxDescr) == (pQueueCtrl)->pFirstDescr) ? \
  67475. + (ETH_TX_DESC*)((pQueueCtrl)->pLastDescr) : \
  67476. + (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) - ETH_TX_DESC_ALIGNED_SIZE)
  67477. +
  67478. +
  67479. +/* Queue specific information */
  67480. +typedef struct
  67481. +{
  67482. + void* pFirstDescr;
  67483. + void* pLastDescr;
  67484. + void* pCurrentDescr;
  67485. + void* pUsedDescr;
  67486. + int resource;
  67487. + MV_BUF_INFO descBuf;
  67488. +} ETH_QUEUE_CTRL;
  67489. +
  67490. +
  67491. +/* Ethernet port specific infomation */
  67492. +typedef struct _ethPortCtrl
  67493. +{
  67494. + int portNo;
  67495. + ETH_QUEUE_CTRL rxQueue[MV_ETH_RX_Q_NUM]; /* Rx ring resource */
  67496. + ETH_QUEUE_CTRL txQueue[MV_ETH_TX_Q_NUM]; /* Tx ring resource */
  67497. +
  67498. + MV_ETH_PORT_CFG portConfig;
  67499. + MV_ETH_RX_Q_CFG rxQueueConfig[MV_ETH_RX_Q_NUM];
  67500. + MV_ETH_TX_Q_CFG txQueueConfig[MV_ETH_TX_Q_NUM];
  67501. +
  67502. + /* Register images - For DP */
  67503. + MV_U32 portTxQueueCmdReg; /* Port active Tx queues summary */
  67504. + MV_U32 portRxQueueCmdReg; /* Port active Rx queues summary */
  67505. +
  67506. + MV_STATE portState;
  67507. +
  67508. + MV_U8 mcastCount[256];
  67509. + MV_U32* hashPtr;
  67510. + void *osHandle;
  67511. +} ETH_PORT_CTRL;
  67512. +
  67513. +/************** MACROs ****************/
  67514. +
  67515. +/* MACROs to Flush / Invalidate TX / RX Buffers */
  67516. +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_TX_BUFFERS)
  67517. +# define ETH_PACKET_CACHE_FLUSH(pAddr, size) \
  67518. + mvOsCacheClear(NULL, (pAddr), (size)); \
  67519. + /*CPU_PIPE_FLUSH;*/
  67520. +#else
  67521. +# define ETH_PACKET_CACHE_FLUSH(pAddr, size) \
  67522. + mvOsIoVirtToPhy(NULL, (pAddr));
  67523. +#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW */
  67524. +
  67525. +#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_RX_BUFFERS) )
  67526. +# define ETH_PACKET_CACHE_INVALIDATE(pAddr, size) \
  67527. + mvOsCacheInvalidate (NULL, (pAddr), (size)); \
  67528. + /*CPU_PIPE_FLUSH;*/
  67529. +#else
  67530. +# define ETH_PACKET_CACHE_INVALIDATE(pAddr, size)
  67531. +#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW && !UNCACHED_RX_BUFFERS */
  67532. +
  67533. +#ifdef ETH_DESCR_UNCACHED
  67534. +
  67535. +#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr)
  67536. +#define ETH_DESCR_INV(pPortCtrl, pDescr)
  67537. +
  67538. +#else
  67539. +
  67540. +#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr) \
  67541. + mvOsCacheLineFlushInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))
  67542. +
  67543. +#define ETH_DESCR_INV(pPortCtrl, pDescr) \
  67544. + mvOsCacheLineInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))
  67545. +
  67546. +#endif /* ETH_DESCR_UNCACHED */
  67547. +
  67548. +#include "eth/gbe/mvEthGbe.h"
  67549. +
  67550. +#endif /* __mvEth_h__ */
  67551. +
  67552. +
  67553. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c
  67554. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c 1970-01-01 01:00:00.000000000 +0100
  67555. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c 2011-07-31 11:32:00.443429216 +0200
  67556. @@ -0,0 +1,362 @@
  67557. +/*******************************************************************************
  67558. +Copyright (C) Marvell International Ltd. and its affiliates
  67559. +
  67560. +This software file (the "File") is owned and distributed by Marvell
  67561. +International Ltd. and/or its affiliates ("Marvell") under the following
  67562. +alternative licensing terms. Once you have made an election to distribute the
  67563. +File under one of the following license alternatives, please (i) delete this
  67564. +introductory statement regarding license alternatives, (ii) delete the two
  67565. +license alternatives that you have not elected to use and (iii) preserve the
  67566. +Marvell copyright notice above.
  67567. +
  67568. +********************************************************************************
  67569. +Marvell Commercial License Option
  67570. +
  67571. +If you received this File from Marvell and you have entered into a commercial
  67572. +license agreement (a "Commercial License") with Marvell, the File is licensed
  67573. +to you under the terms of the applicable Commercial License.
  67574. +
  67575. +********************************************************************************
  67576. +Marvell GPL License Option
  67577. +
  67578. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67579. +modify this File in accordance with the terms and conditions of the General
  67580. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  67581. +available along with the File in the license.txt file or by writing to the Free
  67582. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  67583. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  67584. +
  67585. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  67586. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  67587. +DISCLAIMED. The GPL License provides additional details about this warranty
  67588. +disclaimer.
  67589. +********************************************************************************
  67590. +Marvell BSD License Option
  67591. +
  67592. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67593. +modify this File under the following licensing terms.
  67594. +Redistribution and use in source and binary forms, with or without modification,
  67595. +are permitted provided that the following conditions are met:
  67596. +
  67597. + * Redistributions of source code must retain the above copyright notice,
  67598. + this list of conditions and the following disclaimer.
  67599. +
  67600. + * Redistributions in binary form must reproduce the above copyright
  67601. + notice, this list of conditions and the following disclaimer in the
  67602. + documentation and/or other materials provided with the distribution.
  67603. +
  67604. + * Neither the name of Marvell nor the names of its contributors may be
  67605. + used to endorse or promote products derived from this software without
  67606. + specific prior written permission.
  67607. +
  67608. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  67609. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  67610. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  67611. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  67612. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  67613. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  67614. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  67615. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  67616. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  67617. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  67618. +
  67619. +*******************************************************************************/
  67620. +
  67621. +#include "gpp/mvGpp.h"
  67622. +#include "ctrlEnv/mvCtrlEnvLib.h"
  67623. +/* defines */
  67624. +#ifdef MV_DEBUG
  67625. + #define DB(x) x
  67626. +#else
  67627. + #define DB(x)
  67628. +#endif
  67629. +
  67630. +static MV_VOID gppRegSet(MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value);
  67631. +
  67632. +/*******************************************************************************
  67633. +* mvGppTypeSet - Enable a GPP (OUT) pin
  67634. +*
  67635. +* DESCRIPTION:
  67636. +*
  67637. +* INPUT:
  67638. +* group - GPP group number
  67639. +* mask - 32bit mask value. Each set bit in the mask means that the type
  67640. +* of corresponding GPP will be set. Other GPPs are ignored.
  67641. +* value - 32bit value that describes GPP type per pin.
  67642. +*
  67643. +* OUTPUT:
  67644. +* None.
  67645. +*
  67646. +* EXAMPLE:
  67647. +* Set GPP8 to input and GPP15 to output.
  67648. +* mvGppTypeSet(0, (GPP8 | GPP15),
  67649. +* ((MV_GPP_IN & GPP8) | (MV_GPP_OUT & GPP15)) );
  67650. +*
  67651. +* RETURN:
  67652. +* None.
  67653. +*
  67654. +*******************************************************************************/
  67655. +MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value)
  67656. +{
  67657. + if (group >= MV_GPP_MAX_GROUP)
  67658. + {
  67659. + DB(mvOsPrintf("mvGppTypeSet: ERR. invalid group number \n"));
  67660. + return MV_BAD_PARAM;
  67661. + }
  67662. +
  67663. + gppRegSet(group, GPP_DATA_OUT_EN_REG(group), mask, value);
  67664. +
  67665. + /* Workaround for Erratum FE-MISC-70*/
  67666. + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))
  67667. + {
  67668. + mask &= 0x2;
  67669. + gppRegSet(0, GPP_DATA_OUT_EN_REG(0), mask, value);
  67670. + } /*End of WA*/
  67671. +
  67672. + return MV_OK;
  67673. +
  67674. +}
  67675. +
  67676. +/*******************************************************************************
  67677. +* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms
  67678. +*
  67679. +* DESCRIPTION:
  67680. +*
  67681. +* INPUT:
  67682. +* group - GPP group number
  67683. +* mask - 32bit mask value. Each set bit in the mask means that the type
  67684. +* of corresponding GPP will be set. Other GPPs are ignored.
  67685. +* value - 32bit value that describes GPP blink per pin.
  67686. +*
  67687. +* OUTPUT:
  67688. +* None.
  67689. +*
  67690. +* EXAMPLE:
  67691. +* Set GPP8 to be static and GPP15 to be blinking.
  67692. +* mvGppBlinkEn(0, (GPP8 | GPP15),
  67693. +* ((MV_GPP_OUT_STATIC & GPP8) | (MV_GPP_OUT_BLINK & GPP15)) );
  67694. +*
  67695. +* RETURN:
  67696. +* None.
  67697. +*
  67698. +*******************************************************************************/
  67699. +MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value)
  67700. +{
  67701. + if (group >= MV_GPP_MAX_GROUP)
  67702. + {
  67703. + DB(mvOsPrintf("mvGppBlinkEn: ERR. invalid group number \n"));
  67704. + return MV_BAD_PARAM;
  67705. + }
  67706. +
  67707. + gppRegSet(group, GPP_BLINK_EN_REG(group), mask, value);
  67708. +
  67709. + return MV_OK;
  67710. +
  67711. +}
  67712. +/*******************************************************************************
  67713. +* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode
  67714. +*
  67715. +* DESCRIPTION:
  67716. +*
  67717. +* INPUT:
  67718. +* group - GPP group number
  67719. +* mask - 32bit mask value. Each set bit in the mask means that the type
  67720. +* of corresponding GPP will be set. Other GPPs are ignored.
  67721. +* value - 32bit value that describes GPP polarity per pin.
  67722. +*
  67723. +* OUTPUT:
  67724. +* None.
  67725. +*
  67726. +* EXAMPLE:
  67727. +* Set GPP8 to the actual pin value and GPP15 to be inverted.
  67728. +* mvGppPolaritySet(0, (GPP8 | GPP15),
  67729. +* ((MV_GPP_IN_ORIGIN & GPP8) | (MV_GPP_IN_INVERT & GPP15)) );
  67730. +*
  67731. +* RETURN:
  67732. +* None.
  67733. +*
  67734. +*******************************************************************************/
  67735. +MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value)
  67736. +{
  67737. + if (group >= MV_GPP_MAX_GROUP)
  67738. + {
  67739. + DB(mvOsPrintf("mvGppPolaritySet: ERR. invalid group number \n"));
  67740. + return MV_BAD_PARAM;
  67741. + }
  67742. +
  67743. + gppRegSet(group, GPP_DATA_IN_POL_REG(group), mask, value);
  67744. +
  67745. + return MV_OK;
  67746. +
  67747. +}
  67748. +
  67749. +/*******************************************************************************
  67750. +* mvGppPolarityGet - Get a value of relevant bits from GPP Polarity register.
  67751. +*
  67752. +* DESCRIPTION:
  67753. +*
  67754. +* INPUT:
  67755. +* group - GPP group number
  67756. +* mask - 32bit mask value. Each set bit in the mask means that the
  67757. +* returned value is valid for it.
  67758. +*
  67759. +* OUTPUT:
  67760. +* None.
  67761. +*
  67762. +* EXAMPLE:
  67763. +* Get GPP8 and GPP15 value.
  67764. +* mvGppPolarityGet(0, (GPP8 | GPP15));
  67765. +*
  67766. +* RETURN:
  67767. +* 32bit value that describes GPP polatity mode per pin.
  67768. +*
  67769. +*******************************************************************************/
  67770. +MV_U32 mvGppPolarityGet(MV_U32 group, MV_U32 mask)
  67771. +{
  67772. + MV_U32 regVal;
  67773. +
  67774. + if (group >= MV_GPP_MAX_GROUP)
  67775. + {
  67776. + DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));
  67777. + return MV_ERROR;
  67778. + }
  67779. + regVal = MV_REG_READ(GPP_DATA_IN_POL_REG(group));
  67780. +
  67781. + return (regVal & mask);
  67782. +}
  67783. +
  67784. +/*******************************************************************************
  67785. +* mvGppValueGet - Get a GPP Pin list value.
  67786. +*
  67787. +* DESCRIPTION:
  67788. +* This function get GPP value.
  67789. +*
  67790. +* INPUT:
  67791. +* group - GPP group number
  67792. +* mask - 32bit mask value. Each set bit in the mask means that the
  67793. +* returned value is valid for it.
  67794. +*
  67795. +* OUTPUT:
  67796. +* None.
  67797. +*
  67798. +* EXAMPLE:
  67799. +* Get GPP8 and GPP15 value.
  67800. +* mvGppValueGet(0, (GPP8 | GPP15));
  67801. +*
  67802. +* RETURN:
  67803. +* 32bit value that describes GPP activity mode per pin.
  67804. +*
  67805. +*******************************************************************************/
  67806. +MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask)
  67807. +{
  67808. + MV_U32 gppData;
  67809. +
  67810. + gppData = MV_REG_READ(GPP_DATA_IN_REG(group));
  67811. +
  67812. + gppData &= mask;
  67813. +
  67814. + return gppData;
  67815. +
  67816. +}
  67817. +
  67818. +/*******************************************************************************
  67819. +* mvGppValueSet - Set a GPP Pin list value.
  67820. +*
  67821. +* DESCRIPTION:
  67822. +* This function set value for given GPP pin list.
  67823. +*
  67824. +* INPUT:
  67825. +* group - GPP group number
  67826. +* mask - 32bit mask value. Each set bit in the mask means that the
  67827. +* value of corresponding GPP will be set accordingly. Other GPP
  67828. +* are not affected.
  67829. +* value - 32bit value that describes GPP value per pin.
  67830. +*
  67831. +* OUTPUT:
  67832. +* None.
  67833. +*
  67834. +* EXAMPLE:
  67835. +* Set GPP8 value of '0' and GPP15 value of '1'.
  67836. +* mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (GPP15)) );
  67837. +*
  67838. +* RETURN:
  67839. +* None.
  67840. +*
  67841. +*******************************************************************************/
  67842. +MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value)
  67843. +{
  67844. + MV_U32 outEnable, tmp;
  67845. + MV_U32 i;
  67846. +
  67847. + if (group >= MV_GPP_MAX_GROUP)
  67848. + {
  67849. + DB(mvOsPrintf("mvGppValueSet: Error invalid group number \n"));
  67850. + return MV_BAD_PARAM;
  67851. + }
  67852. +
  67853. + /* verify that the gpp pin is configured as output */
  67854. + /* Note that in the register out enabled -> bit = '0'. */
  67855. + outEnable = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(group));
  67856. +
  67857. + /* Workaround for Erratum FE-MISC-70*/
  67858. + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))
  67859. + {
  67860. + tmp = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(0));
  67861. + outEnable &= 0xfffffffd;
  67862. + outEnable |= (tmp & 0x2);
  67863. + } /*End of WA*/
  67864. +
  67865. + for (i = 0 ; i < 32 ;i++)
  67866. + {
  67867. + if (((mask & (1 << i)) & (outEnable & (1 << i))) != (mask & (1 << i)))
  67868. + {
  67869. + mvOsPrintf("mvGppValueSet: Err. An attempt to set output "\
  67870. + "value to GPP %d in input mode.\n", i);
  67871. + return MV_ERROR;
  67872. + }
  67873. + }
  67874. +
  67875. + gppRegSet(group, GPP_DATA_OUT_REG(group), mask, value);
  67876. +
  67877. + return MV_OK;
  67878. +
  67879. +}
  67880. +/*******************************************************************************
  67881. +* gppRegSet - Set a specific GPP pin on a specific GPP register
  67882. +*
  67883. +* DESCRIPTION:
  67884. +* This function set a specific GPP pin on a specific GPP register
  67885. +*
  67886. +* INPUT:
  67887. +* regOffs - GPP Register offset
  67888. +* group - GPP group number
  67889. +* mask - 32bit mask value. Each set bit in the mask means that the
  67890. +* value of corresponding GPP will be set accordingly. Other GPP
  67891. +* are not affected.
  67892. +* value - 32bit value that describes GPP value per pin.
  67893. +*
  67894. +* OUTPUT:
  67895. +* None.
  67896. +*
  67897. +* EXAMPLE:
  67898. +* Set GPP8 value of '0' and GPP15 value of '1'.
  67899. +* mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (1 & GPP15)) );
  67900. +*
  67901. +* RETURN:
  67902. +* None.
  67903. +*
  67904. +*******************************************************************************/
  67905. +static MV_VOID gppRegSet (MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value)
  67906. +{
  67907. + MV_U32 gppData;
  67908. +
  67909. + gppData = MV_REG_READ(regOffs);
  67910. +
  67911. + gppData &= ~mask;
  67912. +
  67913. + gppData |= (value & mask);
  67914. +
  67915. + MV_REG_WRITE(regOffs, gppData);
  67916. +}
  67917. +
  67918. +
  67919. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h
  67920. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h 1970-01-01 01:00:00.000000000 +0100
  67921. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h 2011-07-31 11:32:00.513421842 +0200
  67922. @@ -0,0 +1,118 @@
  67923. +/*******************************************************************************
  67924. +Copyright (C) Marvell International Ltd. and its affiliates
  67925. +
  67926. +This software file (the "File") is owned and distributed by Marvell
  67927. +International Ltd. and/or its affiliates ("Marvell") under the following
  67928. +alternative licensing terms. Once you have made an election to distribute the
  67929. +File under one of the following license alternatives, please (i) delete this
  67930. +introductory statement regarding license alternatives, (ii) delete the two
  67931. +license alternatives that you have not elected to use and (iii) preserve the
  67932. +Marvell copyright notice above.
  67933. +
  67934. +********************************************************************************
  67935. +Marvell Commercial License Option
  67936. +
  67937. +If you received this File from Marvell and you have entered into a commercial
  67938. +license agreement (a "Commercial License") with Marvell, the File is licensed
  67939. +to you under the terms of the applicable Commercial License.
  67940. +
  67941. +********************************************************************************
  67942. +Marvell GPL License Option
  67943. +
  67944. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67945. +modify this File in accordance with the terms and conditions of the General
  67946. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  67947. +available along with the File in the license.txt file or by writing to the Free
  67948. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  67949. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  67950. +
  67951. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  67952. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  67953. +DISCLAIMED. The GPL License provides additional details about this warranty
  67954. +disclaimer.
  67955. +********************************************************************************
  67956. +Marvell BSD License Option
  67957. +
  67958. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67959. +modify this File under the following licensing terms.
  67960. +Redistribution and use in source and binary forms, with or without modification,
  67961. +are permitted provided that the following conditions are met:
  67962. +
  67963. + * Redistributions of source code must retain the above copyright notice,
  67964. + this list of conditions and the following disclaimer.
  67965. +
  67966. + * Redistributions in binary form must reproduce the above copyright
  67967. + notice, this list of conditions and the following disclaimer in the
  67968. + documentation and/or other materials provided with the distribution.
  67969. +
  67970. + * Neither the name of Marvell nor the names of its contributors may be
  67971. + used to endorse or promote products derived from this software without
  67972. + specific prior written permission.
  67973. +
  67974. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  67975. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  67976. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  67977. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  67978. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  67979. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  67980. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  67981. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  67982. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  67983. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  67984. +
  67985. +*******************************************************************************/
  67986. +
  67987. +#ifndef __INCmvGppH
  67988. +#define __INCmvGppH
  67989. +
  67990. +#include "mvCommon.h"
  67991. +#include "mvOs.h"
  67992. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  67993. +#include "gpp/mvGppRegs.h"
  67994. +
  67995. +/* These macros describes the GPP type. Each of the GPPs pins can */
  67996. +/* be assigned to act as a general purpose input or output pin. */
  67997. +#define MV_GPP_IN 0xFFFFFFFF /* GPP input */
  67998. +#define MV_GPP_OUT 0 /* GPP output */
  67999. +
  68000. +
  68001. +/* These macros describes the GPP Out Enable. */
  68002. +#define MV_GPP_OUT_DIS 0xFFFFFFFF /* Out pin disabled*/
  68003. +#define MV_GPP_OUT_EN 0 /* Out pin enabled*/
  68004. +
  68005. +/* These macros describes the GPP Out Blinking. */
  68006. +/* When set and the corresponding bit in GPIO Data Out Enable Control */
  68007. +/* Register is enabled, the GPIO pin blinks every ~100 ms (a period of */
  68008. +/* 2^24 TCLK clocks). */
  68009. +#define MV_GPP_OUT_BLINK 0xFFFFFFFF /* Out pin blinking*/
  68010. +#define MV_GPP_OUT_STATIC 0 /* Out pin static*/
  68011. +
  68012. +
  68013. +/* These macros describes the GPP Polarity. */
  68014. +/* When set to 1 GPIO Data In Register reflects the inverted value of the */
  68015. +/* corresponding pin. */
  68016. +
  68017. +#define MV_GPP_IN_INVERT 0xFFFFFFFF /* Inverted value is got*/
  68018. +#define MV_GPP_IN_ORIGIN 0 /* original value is got*/
  68019. +
  68020. +/* mvGppTypeSet - Set PP pin mode (IN or OUT) */
  68021. +MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value);
  68022. +
  68023. +/* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms */
  68024. +MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value);
  68025. +
  68026. +/* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode. */
  68027. +MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value);
  68028. +
  68029. +/* mvGppPolarityGet - Get the Polarity of a GPP Pin */
  68030. +MV_U32 mvGppPolarityGet(MV_U32 group, MV_U32 mask);
  68031. +
  68032. +/* mvGppValueGet - Get a GPP Pin list value.*/
  68033. +MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask);
  68034. +
  68035. +
  68036. +/* mvGppValueSet - Set a GPP Pin list value. */
  68037. +MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value);
  68038. +
  68039. +#endif /* #ifndef __INCmvGppH */
  68040. +
  68041. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h
  68042. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h 1970-01-01 01:00:00.000000000 +0100
  68043. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h 2011-07-31 11:32:00.553416918 +0200
  68044. @@ -0,0 +1,116 @@
  68045. +/*******************************************************************************
  68046. +Copyright (C) Marvell International Ltd. and its affiliates
  68047. +
  68048. +This software file (the "File") is owned and distributed by Marvell
  68049. +International Ltd. and/or its affiliates ("Marvell") under the following
  68050. +alternative licensing terms. Once you have made an election to distribute the
  68051. +File under one of the following license alternatives, please (i) delete this
  68052. +introductory statement regarding license alternatives, (ii) delete the two
  68053. +license alternatives that you have not elected to use and (iii) preserve the
  68054. +Marvell copyright notice above.
  68055. +
  68056. +********************************************************************************
  68057. +Marvell Commercial License Option
  68058. +
  68059. +If you received this File from Marvell and you have entered into a commercial
  68060. +license agreement (a "Commercial License") with Marvell, the File is licensed
  68061. +to you under the terms of the applicable Commercial License.
  68062. +
  68063. +********************************************************************************
  68064. +Marvell GPL License Option
  68065. +
  68066. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68067. +modify this File in accordance with the terms and conditions of the General
  68068. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  68069. +available along with the File in the license.txt file or by writing to the Free
  68070. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  68071. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  68072. +
  68073. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  68074. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  68075. +DISCLAIMED. The GPL License provides additional details about this warranty
  68076. +disclaimer.
  68077. +********************************************************************************
  68078. +Marvell BSD License Option
  68079. +
  68080. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68081. +modify this File under the following licensing terms.
  68082. +Redistribution and use in source and binary forms, with or without modification,
  68083. +are permitted provided that the following conditions are met:
  68084. +
  68085. + * Redistributions of source code must retain the above copyright notice,
  68086. + this list of conditions and the following disclaimer.
  68087. +
  68088. + * Redistributions in binary form must reproduce the above copyright
  68089. + notice, this list of conditions and the following disclaimer in the
  68090. + documentation and/or other materials provided with the distribution.
  68091. +
  68092. + * Neither the name of Marvell nor the names of its contributors may be
  68093. + used to endorse or promote products derived from this software without
  68094. + specific prior written permission.
  68095. +
  68096. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  68097. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  68098. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  68099. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  68100. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  68101. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  68102. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  68103. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  68104. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  68105. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  68106. +
  68107. +*******************************************************************************/
  68108. +
  68109. +#ifndef __INCmvGppRegsH
  68110. +#define __INCmvGppRegsH
  68111. +
  68112. +#define MV_GPP0 BIT0
  68113. +#define MV_GPP1 BIT1
  68114. +#define MV_GPP2 BIT2
  68115. +#define MV_GPP3 BIT3
  68116. +#define MV_GPP4 BIT4
  68117. +#define MV_GPP5 BIT5
  68118. +#define MV_GPP6 BIT6
  68119. +#define MV_GPP7 BIT7
  68120. +#define MV_GPP8 BIT8
  68121. +#define MV_GPP9 BIT9
  68122. +#define MV_GPP10 BIT10
  68123. +#define MV_GPP11 BIT11
  68124. +#define MV_GPP12 BIT12
  68125. +#define MV_GPP13 BIT13
  68126. +#define MV_GPP14 BIT14
  68127. +#define MV_GPP15 BIT15
  68128. +#define MV_GPP16 BIT16
  68129. +#define MV_GPP17 BIT17
  68130. +#define MV_GPP18 BIT18
  68131. +#define MV_GPP19 BIT19
  68132. +#define MV_GPP20 BIT20
  68133. +#define MV_GPP21 BIT21
  68134. +#define MV_GPP22 BIT22
  68135. +#define MV_GPP23 BIT23
  68136. +#define MV_GPP24 BIT24
  68137. +#define MV_GPP25 BIT25
  68138. +#define MV_GPP26 BIT26
  68139. +#define MV_GPP27 BIT27
  68140. +#define MV_GPP28 BIT28
  68141. +#define MV_GPP29 BIT29
  68142. +#define MV_GPP30 BIT30
  68143. +#define MV_GPP31 BIT31
  68144. +
  68145. +
  68146. +/* registers offsets */
  68147. +
  68148. +#define GPP_DATA_OUT_REG(grp) ((grp == 0) ? 0x10100 : 0x10140)
  68149. +#define GPP_DATA_OUT_EN_REG(grp) ((grp == 0) ? 0x10104 : 0x10144)
  68150. +#define GPP_BLINK_EN_REG(grp) ((grp == 0) ? 0x10108 : 0x10148)
  68151. +#define GPP_DATA_IN_POL_REG(grp) ((grp == 0) ? 0x1010C : 0x1014c)
  68152. +#define GPP_DATA_IN_REG(grp) ((grp == 0) ? 0x10110 : 0x10150)
  68153. +#define GPP_INT_CAUSE_REG(grp) ((grp == 0) ? 0x10114 : 0x10154)
  68154. +#define GPP_INT_MASK_REG(grp) ((grp == 0) ? 0x10118 : 0x10158)
  68155. +#define GPP_INT_LVL_REG(grp) ((grp == 0) ? 0x1011c : 0x1015c)
  68156. +
  68157. +#define GPP_DATA_OUT_SET_REG 0x10120
  68158. +#define GPP_DATA_OUT_CLEAR_REG 0x10124
  68159. +
  68160. +#endif /* #ifndef __INCmvGppRegsH */
  68161. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c
  68162. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c 1970-01-01 01:00:00.000000000 +0100
  68163. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c 2011-07-31 11:32:00.613425350 +0200
  68164. @@ -0,0 +1,1047 @@
  68165. +/*******************************************************************************
  68166. +Copyright (C) Marvell International Ltd. and its affiliates
  68167. +
  68168. +This software file (the "File") is owned and distributed by Marvell
  68169. +International Ltd. and/or its affiliates ("Marvell") under the following
  68170. +alternative licensing terms. Once you have made an election to distribute the
  68171. +File under one of the following license alternatives, please (i) delete this
  68172. +introductory statement regarding license alternatives, (ii) delete the two
  68173. +license alternatives that you have not elected to use and (iii) preserve the
  68174. +Marvell copyright notice above.
  68175. +
  68176. +********************************************************************************
  68177. +Marvell Commercial License Option
  68178. +
  68179. +If you received this File from Marvell and you have entered into a commercial
  68180. +license agreement (a "Commercial License") with Marvell, the File is licensed
  68181. +to you under the terms of the applicable Commercial License.
  68182. +
  68183. +********************************************************************************
  68184. +Marvell GPL License Option
  68185. +
  68186. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68187. +modify this File in accordance with the terms and conditions of the General
  68188. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  68189. +available along with the File in the license.txt file or by writing to the Free
  68190. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  68191. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  68192. +
  68193. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  68194. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  68195. +DISCLAIMED. The GPL License provides additional details about this warranty
  68196. +disclaimer.
  68197. +********************************************************************************
  68198. +Marvell BSD License Option
  68199. +
  68200. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68201. +modify this File under the following licensing terms.
  68202. +Redistribution and use in source and binary forms, with or without modification,
  68203. +are permitted provided that the following conditions are met:
  68204. +
  68205. + * Redistributions of source code must retain the above copyright notice,
  68206. + this list of conditions and the following disclaimer.
  68207. +
  68208. + * Redistributions in binary form must reproduce the above copyright
  68209. + notice, this list of conditions and the following disclaimer in the
  68210. + documentation and/or other materials provided with the distribution.
  68211. +
  68212. + * Neither the name of Marvell nor the names of its contributors may be
  68213. + used to endorse or promote products derived from this software without
  68214. + specific prior written permission.
  68215. +
  68216. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  68217. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  68218. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  68219. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  68220. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  68221. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  68222. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  68223. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  68224. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  68225. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  68226. +
  68227. +*******************************************************************************/
  68228. +#include "pci/mvPci.h"
  68229. +
  68230. +#include "ctrlEnv/mvCtrlEnvLib.h"
  68231. +
  68232. +/* defines */
  68233. +#ifdef MV_DEBUG
  68234. + #define DB(x) x
  68235. +#else
  68236. + #define DB(x)
  68237. +#endif
  68238. +
  68239. +
  68240. +
  68241. +MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod)
  68242. +{
  68243. + if (MV_PCI_MOD_HOST == pciIfmod)
  68244. + {
  68245. +
  68246. + mvPciLocalBusNumSet(pciIf, PCI_HOST_BUS_NUM(pciIf));
  68247. + mvPciLocalDevNumSet(pciIf, PCI_HOST_DEV_NUM(pciIf));
  68248. +
  68249. + /* Local device master Enable */
  68250. + mvPciMasterEnable(pciIf, MV_TRUE);
  68251. +
  68252. + /* Local device slave Enable */
  68253. + mvPciSlaveEnable(pciIf, mvPciLocalBusNumGet(pciIf),
  68254. + mvPciLocalDevNumGet(pciIf), MV_TRUE);
  68255. + }
  68256. + /* enable CPU-2-PCI ordering */
  68257. + MV_REG_BIT_SET(PCI_CMD_REG(0), PCR_CPU_TO_PCI_ORDER_EN);
  68258. +}
  68259. +
  68260. +/*******************************************************************************
  68261. +* mvPciCommandSet - Set PCI comman register value.
  68262. +*
  68263. +* DESCRIPTION:
  68264. +* This function sets a given PCI interface with its command register
  68265. +* value.
  68266. +*
  68267. +* INPUT:
  68268. +* pciIf - PCI interface number.
  68269. +* command - 32bit value to be written to comamnd register.
  68270. +*
  68271. +* OUTPUT:
  68272. +* None.
  68273. +*
  68274. +* RETURN:
  68275. +* MV_BAD_PARAM if pciIf is not in range otherwise MV_OK
  68276. +*
  68277. +*******************************************************************************/
  68278. +MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command)
  68279. +{
  68280. + MV_U32 locBusNum, locDevNum, regVal;
  68281. +
  68282. + locBusNum = mvPciLocalBusNumGet(pciIf);
  68283. + locDevNum = mvPciLocalDevNumGet(pciIf);
  68284. +
  68285. + /* Parameter checking */
  68286. + if (pciIf >= mvCtrlPciMaxIfGet())
  68287. + {
  68288. + mvOsPrintf("mvPciCommandSet: ERR. Invalid PCI IF num %d\n", pciIf);
  68289. + return MV_BAD_PARAM;
  68290. + }
  68291. +
  68292. + /* Set command register */
  68293. + MV_REG_WRITE(PCI_CMD_REG(pciIf), command);
  68294. +
  68295. + /* Upodate device max outstanding split tarnsaction */
  68296. + if ((command & PCR_CPU_TO_PCI_ORDER_EN) &&
  68297. + (command & PCR_PCI_TO_CPU_ORDER_EN))
  68298. + {
  68299. + /* Read PCI-X command register */
  68300. + regVal = mvPciConfigRead (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND);
  68301. +
  68302. + /* clear bits 22:20 */
  68303. + regVal &= 0xff8fffff;
  68304. +
  68305. + /* set reset value */
  68306. + regVal |= (0x3 << 20);
  68307. +
  68308. + /* Write back the value */
  68309. + mvPciConfigWrite (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND, regVal);
  68310. + }
  68311. +
  68312. + return MV_OK;
  68313. +
  68314. +
  68315. +}
  68316. +
  68317. +
  68318. +/*******************************************************************************
  68319. +* mvPciModeGet - Get PCI interface mode.
  68320. +*
  68321. +* DESCRIPTION:
  68322. +* This function returns the given PCI interface mode.
  68323. +*
  68324. +* INPUT:
  68325. +* pciIf - PCI interface number.
  68326. +*
  68327. +* OUTPUT:
  68328. +* pPciMode - Pointer to PCI mode structure.
  68329. +*
  68330. +* RETURN:
  68331. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  68332. +*
  68333. +*******************************************************************************/
  68334. +MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode)
  68335. +{
  68336. + MV_U32 pciMode;
  68337. +
  68338. + /* Parameter checking */
  68339. + if (pciIf >= mvCtrlPciMaxIfGet())
  68340. + {
  68341. + mvOsPrintf("mvPciModeGet: ERR. Invalid PCI interface %d\n", pciIf);
  68342. + return MV_BAD_PARAM;
  68343. + }
  68344. + if (NULL == pPciMode)
  68345. + {
  68346. + mvOsPrintf("mvPciModeGet: ERR. pPciMode = NULL \n");
  68347. + return MV_BAD_PARAM;
  68348. + }
  68349. +
  68350. + /* Read pci mode register */
  68351. + pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));
  68352. +
  68353. + switch (pciMode & PMR_PCI_MODE_MASK)
  68354. + {
  68355. + case PMR_PCI_MODE_CONV:
  68356. + pPciMode->pciType = MV_PCI_CONV;
  68357. +
  68358. + if (MV_REG_READ(PCI_DLL_CTRL_REG(pciIf)) & PDC_DLL_EN)
  68359. + {
  68360. + pPciMode->pciSpeed = 66000000; /* 66MHZ */
  68361. + }
  68362. + else
  68363. + {
  68364. + pPciMode->pciSpeed = 33000000; /* 33MHZ */
  68365. + }
  68366. +
  68367. + break;
  68368. +
  68369. + case PMR_PCI_MODE_PCIX_66MHZ:
  68370. + pPciMode->pciType = MV_PCIX;
  68371. + pPciMode->pciSpeed = 66000000; /* 66MHZ */
  68372. + break;
  68373. +
  68374. + case PMR_PCI_MODE_PCIX_100MHZ:
  68375. + pPciMode->pciType = MV_PCIX;
  68376. + pPciMode->pciSpeed = 100000000; /* 100MHZ */
  68377. + break;
  68378. +
  68379. + case PMR_PCI_MODE_PCIX_133MHZ:
  68380. + pPciMode->pciType = MV_PCIX;
  68381. + pPciMode->pciSpeed = 133000000; /* 133MHZ */
  68382. + break;
  68383. +
  68384. + default:
  68385. + {
  68386. + mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");
  68387. + return MV_ERROR;
  68388. + }
  68389. + }
  68390. +
  68391. + switch (pciMode & PMR_PCI_64_MASK)
  68392. + {
  68393. + case PMR_PCI_64_64BIT:
  68394. + pPciMode->pciWidth = MV_PCI_64;
  68395. + break;
  68396. +
  68397. + case PMR_PCI_64_32BIT:
  68398. + pPciMode->pciWidth = MV_PCI_32;
  68399. + break;
  68400. +
  68401. + default:
  68402. + {
  68403. + mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");
  68404. + return MV_ERROR;
  68405. + }
  68406. + }
  68407. +
  68408. + return MV_OK;
  68409. +}
  68410. +
  68411. +/*******************************************************************************
  68412. +* mvPciRetrySet - Set PCI retry counters
  68413. +*
  68414. +* DESCRIPTION:
  68415. +* This function specifies the number of times the PCI controller
  68416. +* retries a transaction before it quits.
  68417. +* Applies to the PCI Master when acting as a requester.
  68418. +* Applies to the PCI slave when acting as a completer (PCI-X mode).
  68419. +* A 0x00 value means a "retry forever".
  68420. +*
  68421. +* INPUT:
  68422. +* pciIf - PCI interface number.
  68423. +* counter - Number of times PCI controller retry. Use counter value
  68424. +* up to PRR_RETRY_CNTR_MAX.
  68425. +*
  68426. +* OUTPUT:
  68427. +* None.
  68428. +*
  68429. +* RETURN:
  68430. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  68431. +*
  68432. +*******************************************************************************/
  68433. +MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter)
  68434. +{
  68435. + MV_U32 pciRetry;
  68436. +
  68437. + /* Parameter checking */
  68438. + if (pciIf >= mvCtrlPciMaxIfGet())
  68439. + {
  68440. + mvOsPrintf("mvPciRetrySet: ERR. Invalid PCI interface %d\n", pciIf);
  68441. + return MV_BAD_PARAM;
  68442. + }
  68443. +
  68444. + if (counter >= PRR_RETRY_CNTR_MAX)
  68445. + {
  68446. + mvOsPrintf("mvPciRetrySet: ERR. Invalid counter: %d\n", counter);
  68447. + return MV_BAD_PARAM;
  68448. +
  68449. + }
  68450. +
  68451. + /* Reading PCI retry register */
  68452. + pciRetry = MV_REG_READ(PCI_RETRY_REG(pciIf));
  68453. +
  68454. + pciRetry &= ~PRR_RETRY_CNTR_MASK;
  68455. +
  68456. + pciRetry |= (counter << PRR_RETRY_CNTR_OFFS);
  68457. +
  68458. + /* write new value */
  68459. + MV_REG_WRITE(PCI_RETRY_REG(pciIf), pciRetry);
  68460. +
  68461. + return MV_OK;
  68462. +}
  68463. +
  68464. +
  68465. +/*******************************************************************************
  68466. +* mvPciDiscardTimerSet - Set PCI discard timer
  68467. +*
  68468. +* DESCRIPTION:
  68469. +* This function set PCI discard timer.
  68470. +* In conventional PCI mode:
  68471. +* Specifies the number of PCLK cycles the PCI slave keeps a non-accessed
  68472. +* read buffers (non-completed delayed read) before invalidate the buffer.
  68473. +* Set to '0' to disable the timer. The PCI slave waits for delayed
  68474. +* read completion forever.
  68475. +* In PCI-X mode:
  68476. +* Specifies the number of PCLK cycles the PCI master waits for split
  68477. +* completion transaction, before it invalidates the pre-allocated read
  68478. +* buffer.
  68479. +* Set to '0' to disable the timer. The PCI master waits for split
  68480. +* completion forever.
  68481. +* NOTE: Must be set to a number greater than MV_PCI_MAX_DISCARD_CLK,
  68482. +* unless using the "wait for ever" setting 0x0.
  68483. +* NOTE: Must not be updated while there are pending read requests.
  68484. +*
  68485. +* INPUT:
  68486. +* pciIf - PCI interface number.
  68487. +* pClkCycles - Number of PCI clock cycles.
  68488. +*
  68489. +* OUTPUT:
  68490. +* None.
  68491. +*
  68492. +* RETURN:
  68493. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  68494. +*
  68495. +*******************************************************************************/
  68496. +MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles)
  68497. +{
  68498. + MV_U32 pciDiscardTimer;
  68499. +
  68500. + /* Parameter checking */
  68501. + if (pciIf >= mvCtrlPciMaxIfGet())
  68502. + {
  68503. + mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid PCI interface %d\n",
  68504. + pciIf);
  68505. + return MV_BAD_PARAM;
  68506. + }
  68507. +
  68508. + if (pClkCycles >= PDTR_TIMER_MIN)
  68509. + {
  68510. + mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid Clk value: %d\n",
  68511. + pClkCycles);
  68512. + return MV_BAD_PARAM;
  68513. +
  68514. + }
  68515. +
  68516. + /* Read PCI Discard Timer */
  68517. + pciDiscardTimer = MV_REG_READ(PCI_DISCARD_TIMER_REG(pciIf));
  68518. +
  68519. + pciDiscardTimer &= ~PDTR_TIMER_MASK;
  68520. +
  68521. + pciDiscardTimer |= (pClkCycles << PDTR_TIMER_OFFS);
  68522. +
  68523. + /* Write new value */
  68524. + MV_REG_WRITE(PCI_DISCARD_TIMER_REG(pciIf), pciDiscardTimer);
  68525. +
  68526. + return MV_OK;
  68527. +
  68528. +}
  68529. +
  68530. +/* PCI Arbiter routines */
  68531. +
  68532. +/*******************************************************************************
  68533. +* mvPciArbEnable - PCI arbiter enable/disable
  68534. +*
  68535. +* DESCRIPTION:
  68536. +* This fuction enable/disables a given PCI interface arbiter.
  68537. +* NOTE: Arbiter setting can not be changed while in work. It should only
  68538. +* be set once.
  68539. +* INPUT:
  68540. +* pciIf - PCI interface number.
  68541. +* enable - Enable/disable parameter. If enable = MV_TRUE then enable.
  68542. +*
  68543. +* OUTPUT:
  68544. +* None.
  68545. +*
  68546. +* RETURN:
  68547. +* None.
  68548. +*
  68549. +*******************************************************************************/
  68550. +MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable)
  68551. +{
  68552. + MV_U32 regVal;
  68553. +
  68554. + /* Parameter checking */
  68555. + if (pciIf >= mvCtrlPciMaxIfGet())
  68556. + {
  68557. + mvOsPrintf("mvPciArbEnable: ERR. Invalid PCI interface %d\n", pciIf);
  68558. + return MV_ERROR;
  68559. + }
  68560. +
  68561. + /* Set PCI Arbiter Control register according to default configuration */
  68562. + regVal = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
  68563. +
  68564. + /* Make sure arbiter disabled before changing its values */
  68565. + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
  68566. +
  68567. + regVal &= ~PCI_ARBITER_CTRL_DEFAULT_MASK;
  68568. +
  68569. + regVal |= PCI_ARBITER_CTRL_DEFAULT; /* Set default configuration */
  68570. +
  68571. + if (MV_TRUE == enable)
  68572. + {
  68573. + regVal |= PACR_ARB_ENABLE;
  68574. + }
  68575. + else
  68576. + {
  68577. + regVal &= ~PACR_ARB_ENABLE;
  68578. + }
  68579. +
  68580. + /* Write to register */
  68581. + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), regVal);
  68582. +
  68583. + return MV_OK;
  68584. +}
  68585. +
  68586. +
  68587. +/*******************************************************************************
  68588. +* mvPciArbParkDis - Disable arbiter parking on agent
  68589. +*
  68590. +* DESCRIPTION:
  68591. +* This function disables the PCI arbiter from parking on the given agent
  68592. +* list.
  68593. +*
  68594. +* INPUT:
  68595. +* pciIf - PCI interface number.
  68596. +* pciAgentMask - When a bit in the mask is set to '1', parking on
  68597. +* the associated PCI master is disabled. Mask bit
  68598. +* refers to bit 0 - 6. For example disable parking on PCI
  68599. +* agent 3 set pciAgentMask 0x4 (bit 3 is set).
  68600. +*
  68601. +* OUTPUT:
  68602. +* None.
  68603. +*
  68604. +* RETURN:
  68605. +* None.
  68606. +*
  68607. +*******************************************************************************/
  68608. +MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask)
  68609. +{
  68610. + MV_U32 pciArbiterCtrl;
  68611. +
  68612. + /* Parameter checking */
  68613. + if (pciIf >= mvCtrlPciMaxIfGet())
  68614. + {
  68615. + mvOsPrintf("mvPciArbParkDis: ERR. Invalid PCI interface %d\n", pciIf);
  68616. + return MV_ERROR;
  68617. + }
  68618. +
  68619. + /* Reading Arbiter Control register */
  68620. + pciArbiterCtrl = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
  68621. +
  68622. + /* Arbiter must be disabled before changing parking */
  68623. + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
  68624. +
  68625. + /* do the change */
  68626. + pciArbiterCtrl &= ~PACR_PARK_DIS_MASK;
  68627. + pciArbiterCtrl |= (pciAgentMask << PACR_PARK_DIS_OFFS);
  68628. +
  68629. + /* writing new value ( if th earbiter was enabled before the change */
  68630. + /* here it will be reenabled */
  68631. + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);
  68632. +
  68633. + return MV_OK;
  68634. +}
  68635. +
  68636. +
  68637. +/*******************************************************************************
  68638. +* mvPciArbBrokDetectSet - Set PCI arbiter broken detection
  68639. +*
  68640. +* DESCRIPTION:
  68641. +* This function sets the maximum number of cycles that the arbiter
  68642. +* waits for a PCI master to respond to its grant assertion. If a
  68643. +* PCI agent fails to respond within this time, the PCI arbiter aborts
  68644. +* the transaction and performs a new arbitration cycle.
  68645. +* NOTE: Value must be greater than '1' for conventional PCI and
  68646. +* greater than '5' for PCI-X.
  68647. +*
  68648. +* INPUT:
  68649. +* pciIf - PCI interface number.
  68650. +* pClkCycles - Number of PCI clock cycles. If equal to '0' the broken
  68651. +* master detection is disabled.
  68652. +*
  68653. +* OUTPUT:
  68654. +* None.
  68655. +*
  68656. +* RETURN:
  68657. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  68658. +*
  68659. +*******************************************************************************/
  68660. +MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles)
  68661. +{
  68662. + MV_U32 pciArbiterCtrl;
  68663. + MV_U32 pciMode;
  68664. +
  68665. + /* Parameter checking */
  68666. + if (pciIf >= mvCtrlPciMaxIfGet())
  68667. + {
  68668. + mvOsPrintf("mvPciArbBrokDetectSet: ERR. Invalid PCI interface %d\n",
  68669. + pciIf);
  68670. + return MV_BAD_PARAM;
  68671. + }
  68672. +
  68673. + /* Checking PCI mode and if pClkCycles is legal value */
  68674. + pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));
  68675. + pciMode &= PMR_PCI_MODE_MASK;
  68676. +
  68677. + if (PMR_PCI_MODE_CONV == pciMode)
  68678. + {
  68679. + if (pClkCycles < PACR_BROKEN_VAL_CONV_MIN)
  68680. + return MV_ERROR;
  68681. + }
  68682. + else
  68683. + {
  68684. + if (pClkCycles < PACR_BROKEN_VAL_PCIX_MIN)
  68685. + return MV_ERROR;
  68686. + }
  68687. +
  68688. + pClkCycles <<= PACR_BROKEN_VAL_OFFS;
  68689. +
  68690. + /* Reading Arbiter Control register */
  68691. + pciArbiterCtrl = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
  68692. + pciArbiterCtrl &= ~PACR_BROKEN_VAL_MASK;
  68693. + pciArbiterCtrl |= pClkCycles;
  68694. +
  68695. + /* Arbiter must be disabled before changing broken detection */
  68696. + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
  68697. +
  68698. + /* writing new value ( if th earbiter was enabled before the change */
  68699. + /* here it will be reenabled */
  68700. +
  68701. + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);
  68702. +
  68703. + return MV_OK;
  68704. +}
  68705. +
  68706. +/* PCI configuration space read write */
  68707. +
  68708. +/*******************************************************************************
  68709. +* mvPciConfigRead - Read from configuration space
  68710. +*
  68711. +* DESCRIPTION:
  68712. +* This function performs a 32 bit read from PCI configuration space.
  68713. +* It supports both type 0 and type 1 of Configuration Transactions
  68714. +* (local and over bridge). In order to read from local bus segment, use
  68715. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  68716. +* will result configuration transaction of type 1 (over bridge).
  68717. +*
  68718. +* INPUT:
  68719. +* pciIf - PCI interface number.
  68720. +* bus - PCI segment bus number.
  68721. +* dev - PCI device number.
  68722. +* func - Function number.
  68723. +* regOffs - Register offset.
  68724. +*
  68725. +* OUTPUT:
  68726. +* None.
  68727. +*
  68728. +* RETURN:
  68729. +* 32bit register data, 0xffffffff on error
  68730. +*
  68731. +*******************************************************************************/
  68732. +MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  68733. + MV_U32 regOff)
  68734. +{
  68735. + MV_U32 pciData = 0;
  68736. +
  68737. + /* Parameter checking */
  68738. + if (PCI_DEFAULT_IF != pciIf)
  68739. + {
  68740. + if (pciIf >= mvCtrlPciMaxIfGet())
  68741. + {
  68742. + mvOsPrintf("mvPciConfigRead: ERR. Invalid PCI interface %d\n",pciIf);
  68743. + return 0xFFFFFFFF;
  68744. + }
  68745. + }
  68746. +
  68747. + if (dev >= MAX_PCI_DEVICES)
  68748. + {
  68749. + DB(mvOsPrintf("mvPciConfigRead: ERR. device number illigal %d\n", dev));
  68750. + return 0xFFFFFFFF;
  68751. + }
  68752. +
  68753. + if (func >= MAX_PCI_FUNCS)
  68754. + {
  68755. + DB(mvOsPrintf("mvPciConfigRead: ERR. function number illigal %d\n", func));
  68756. + return 0xFFFFFFFF;
  68757. + }
  68758. +
  68759. + if (bus >= MAX_PCI_BUSSES)
  68760. + {
  68761. + DB(mvOsPrintf("mvPciConfigRead: ERR. bus number illigal %d\n", bus));
  68762. + return MV_ERROR;
  68763. + }
  68764. +
  68765. +
  68766. + /* Creating PCI address to be passed */
  68767. + pciData |= (bus << PCAR_BUS_NUM_OFFS);
  68768. + pciData |= (dev << PCAR_DEVICE_NUM_OFFS);
  68769. + pciData |= (func << PCAR_FUNC_NUM_OFFS);
  68770. + pciData |= (regOff & PCAR_REG_NUM_MASK);
  68771. +
  68772. + pciData |= PCAR_CONFIG_EN;
  68773. +
  68774. + /* Write the address to the PCI configuration address register */
  68775. + MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);
  68776. +
  68777. + /* In order to let the PCI controller absorbed the address of the read */
  68778. + /* transaction we perform a validity check that the address was written */
  68779. + if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))
  68780. + {
  68781. + return MV_ERROR;
  68782. + }
  68783. + /* Read the Data returned in the PCI Data register */
  68784. + pciData = MV_REG_READ(PCI_CONFIG_DATA_REG(pciIf));
  68785. +
  68786. + return pciData;
  68787. +}
  68788. +
  68789. +/*******************************************************************************
  68790. +* mvPciConfigWrite - Write to configuration space
  68791. +*
  68792. +* DESCRIPTION:
  68793. +* This function performs a 32 bit write to PCI configuration space.
  68794. +* It supports both type 0 and type 1 of Configuration Transactions
  68795. +* (local and over bridge). In order to write to local bus segment, use
  68796. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  68797. +* will result configuration transaction of type 1 (over bridge).
  68798. +*
  68799. +* INPUT:
  68800. +* pciIf - PCI interface number.
  68801. +* bus - PCI segment bus number.
  68802. +* dev - PCI device number.
  68803. +* func - Function number.
  68804. +* regOffs - Register offset.
  68805. +* data - 32bit data.
  68806. +*
  68807. +* OUTPUT:
  68808. +* None.
  68809. +*
  68810. +* RETURN:
  68811. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  68812. +*
  68813. +*******************************************************************************/
  68814. +MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  68815. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  68816. +{
  68817. + MV_U32 pciData = 0;
  68818. +
  68819. + /* Parameter checking */
  68820. + if (PCI_DEFAULT_IF != pciIf)
  68821. + {
  68822. + if (pciIf >= mvCtrlPciMaxIfGet())
  68823. + {
  68824. + mvOsPrintf("mvPciConfigWrite: ERR. Invalid PCI interface %d\n",
  68825. + pciIf);
  68826. + return 0xFFFFFFFF;
  68827. + }
  68828. + }
  68829. +
  68830. + if (dev >= MAX_PCI_DEVICES)
  68831. + {
  68832. + mvOsPrintf("mvPciConfigWrite: ERR. device number illigal %d\n",dev);
  68833. + return MV_BAD_PARAM;
  68834. + }
  68835. +
  68836. + if (func >= MAX_PCI_FUNCS)
  68837. + {
  68838. + mvOsPrintf("mvPciConfigWrite: ERR. function number illigal %d\n", func);
  68839. + return MV_ERROR;
  68840. + }
  68841. +
  68842. + if (bus >= MAX_PCI_BUSSES)
  68843. + {
  68844. + mvOsPrintf("mvPciConfigWrite: ERR. bus number illigal %d\n", bus);
  68845. + return MV_ERROR;
  68846. + }
  68847. +
  68848. + /* Creating PCI address to be passed */
  68849. + pciData |= (bus << PCAR_BUS_NUM_OFFS);
  68850. + pciData |= (dev << PCAR_DEVICE_NUM_OFFS);
  68851. + pciData |= (func << PCAR_FUNC_NUM_OFFS);
  68852. + pciData |= (regOff & PCAR_REG_NUM_MASK);
  68853. +
  68854. + pciData |= PCAR_CONFIG_EN;
  68855. +
  68856. + /* Write the address to the PCI configuration address register */
  68857. + MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);
  68858. +
  68859. + /* In order to let the PCI controller absorbed the address of the read */
  68860. + /* transaction we perform a validity check that the address was written */
  68861. + if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))
  68862. + {
  68863. + return MV_ERROR;
  68864. + }
  68865. +
  68866. + /* Write the Data passed to the PCI Data register */
  68867. + MV_REG_WRITE(PCI_CONFIG_DATA_REG(pciIf), data);
  68868. +
  68869. + return MV_OK;
  68870. +}
  68871. +
  68872. +/*******************************************************************************
  68873. +* mvPciMasterEnable - Enable/disale PCI interface master transactions.
  68874. +*
  68875. +* DESCRIPTION:
  68876. +* This function performs read modified write to PCI command status
  68877. +* (offset 0x4) to set/reset bit 2. After this bit is set, the PCI
  68878. +* master is allowed to gain ownership on the bus, otherwise it is
  68879. +* incapable to do so.
  68880. +*
  68881. +* INPUT:
  68882. +* pciIf - PCI interface number.
  68883. +* enable - Enable/disable parameter.
  68884. +*
  68885. +* OUTPUT:
  68886. +* None.
  68887. +*
  68888. +* RETURN:
  68889. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  68890. +*
  68891. +*******************************************************************************/
  68892. +MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable)
  68893. +{
  68894. + MV_U32 pciCommandStatus;
  68895. + MV_U32 RegOffs;
  68896. + MV_U32 localBus;
  68897. + MV_U32 localDev;
  68898. +
  68899. + /* Parameter checking */
  68900. + if (pciIf >= mvCtrlPciMaxIfGet())
  68901. + {
  68902. + mvOsPrintf("mvPciMasterEnable: ERR. Invalid PCI interface %d\n", pciIf);
  68903. + return MV_ERROR;
  68904. + }
  68905. +
  68906. + localBus = mvPciLocalBusNumGet(pciIf);
  68907. + localDev = mvPciLocalDevNumGet(pciIf);
  68908. +
  68909. + RegOffs = PCI_STATUS_AND_COMMAND;
  68910. +
  68911. + pciCommandStatus = mvPciConfigRead(pciIf, localBus, localDev, 0, RegOffs);
  68912. +
  68913. + if (MV_TRUE == enable)
  68914. + {
  68915. + pciCommandStatus |= PSCR_MASTER_EN;
  68916. + }
  68917. + else
  68918. + {
  68919. + pciCommandStatus &= ~PSCR_MASTER_EN;
  68920. + }
  68921. +
  68922. + mvPciConfigWrite(pciIf, localBus, localDev, 0, RegOffs, pciCommandStatus);
  68923. +
  68924. + return MV_OK;
  68925. +}
  68926. +
  68927. +
  68928. +/*******************************************************************************
  68929. +* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.
  68930. +*
  68931. +* DESCRIPTION:
  68932. +* This function performs read modified write to PCI command status
  68933. +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
  68934. +* the PCI slave is allowed to respond to PCI IO space access (bit 0)
  68935. +* and PCI memory space access (bit 1).
  68936. +*
  68937. +* INPUT:
  68938. +* pciIf - PCI interface number.
  68939. +* dev - PCI device number.
  68940. +* enable - Enable/disable parameter.
  68941. +*
  68942. +* OUTPUT:
  68943. +* None.
  68944. +*
  68945. +* RETURN:
  68946. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  68947. +*
  68948. +*******************************************************************************/
  68949. +MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_BOOL enable)
  68950. +{
  68951. + MV_U32 pciCommandStatus;
  68952. + MV_U32 RegOffs;
  68953. +
  68954. + /* Parameter checking */
  68955. + if (pciIf >= mvCtrlPciMaxIfGet())
  68956. + {
  68957. + mvOsPrintf("mvPciSlaveEnable: ERR. Invalid PCI interface %d\n", pciIf);
  68958. + return MV_BAD_PARAM;
  68959. + }
  68960. + if (dev >= MAX_PCI_DEVICES)
  68961. + {
  68962. + mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n", dev);
  68963. + return MV_BAD_PARAM;
  68964. +
  68965. + }
  68966. +
  68967. + RegOffs = PCI_STATUS_AND_COMMAND;
  68968. +
  68969. + pciCommandStatus=mvPciConfigRead(pciIf, bus, dev, 0, RegOffs);
  68970. +
  68971. + if (MV_TRUE == enable)
  68972. + {
  68973. + pciCommandStatus |= (PSCR_IO_EN | PSCR_MEM_EN);
  68974. + }
  68975. + else
  68976. + {
  68977. + pciCommandStatus &= ~(PSCR_IO_EN | PSCR_MEM_EN);
  68978. + }
  68979. +
  68980. + mvPciConfigWrite(pciIf, bus, dev, 0, RegOffs, pciCommandStatus);
  68981. +
  68982. + return MV_OK;
  68983. +}
  68984. +
  68985. +/*******************************************************************************
  68986. +* mvPciLocalBusNumSet - Set PCI interface local bus number.
  68987. +*
  68988. +* DESCRIPTION:
  68989. +* This function sets given PCI interface its local bus number.
  68990. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  68991. +*
  68992. +* INPUT:
  68993. +* pciIf - PCI interface number.
  68994. +* busNum - Bus number.
  68995. +*
  68996. +* OUTPUT:
  68997. +* None.
  68998. +*
  68999. +* RETURN:
  69000. +* MV_NOT_ALLOWED in case PCI interface is PCI-X.
  69001. +* MV_BAD_PARAM on bad parameters ,
  69002. +* otherwise MV_OK
  69003. +*
  69004. +*******************************************************************************/
  69005. +MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)
  69006. +{
  69007. + MV_U32 pciP2PConfig;
  69008. + MV_PCI_MODE pciMode;
  69009. + MV_U32 localBus;
  69010. + MV_U32 localDev;
  69011. +
  69012. +
  69013. + /* Parameter checking */
  69014. + if (pciIf >= mvCtrlPciMaxIfGet())
  69015. + {
  69016. + mvOsPrintf("mvPciLocalBusNumSet: ERR. Invalid PCI interface %d\n",pciIf);
  69017. + return MV_BAD_PARAM;
  69018. + }
  69019. + if (busNum >= MAX_PCI_BUSSES)
  69020. + {
  69021. + mvOsPrintf("mvPciLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
  69022. + return MV_ERROR;
  69023. +
  69024. + }
  69025. +
  69026. + localBus = mvPciLocalBusNumGet(pciIf);
  69027. + localDev = mvPciLocalDevNumGet(pciIf);
  69028. +
  69029. +
  69030. + /* PCI interface mode */
  69031. + mvPciModeGet(pciIf, &pciMode);
  69032. +
  69033. + /* if PCI type is PCI-X then it is not allowed to change the dev number */
  69034. + if (MV_PCIX == pciMode.pciType)
  69035. + {
  69036. + pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );
  69037. +
  69038. + pciP2PConfig &= ~PXS_BN_MASK;
  69039. +
  69040. + pciP2PConfig |= (busNum << PXS_BN_OFFS) & PXS_BN_MASK;
  69041. +
  69042. + mvPciConfigWrite(pciIf, localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );
  69043. +
  69044. + }
  69045. + else
  69046. + {
  69047. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  69048. +
  69049. + pciP2PConfig &= ~PPCR_BUS_NUM_MASK;
  69050. +
  69051. + pciP2PConfig |= (busNum << PPCR_BUS_NUM_OFFS) & PPCR_BUS_NUM_MASK;
  69052. +
  69053. + MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);
  69054. +
  69055. + }
  69056. +
  69057. +
  69058. + return MV_OK;
  69059. +}
  69060. +
  69061. +
  69062. +/*******************************************************************************
  69063. +* mvPciLocalBusNumGet - Get PCI interface local bus number.
  69064. +*
  69065. +* DESCRIPTION:
  69066. +* This function gets the local bus number of a given PCI interface.
  69067. +*
  69068. +* INPUT:
  69069. +* pciIf - PCI interface number.
  69070. +*
  69071. +* OUTPUT:
  69072. +* None.
  69073. +*
  69074. +* RETURN:
  69075. +* Local bus number.0xffffffff on Error
  69076. +*
  69077. +*******************************************************************************/
  69078. +MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf)
  69079. +{
  69080. + MV_U32 pciP2PConfig;
  69081. +
  69082. + /* Parameter checking */
  69083. + if (PCI_DEFAULT_IF != pciIf)
  69084. + {
  69085. + if (pciIf >= mvCtrlPciMaxIfGet())
  69086. + {
  69087. + mvOsPrintf("mvPciLocalBusNumGet: ERR. Invalid PCI interface %d\n",
  69088. + pciIf);
  69089. + return 0xFFFFFFFF;
  69090. + }
  69091. + }
  69092. +
  69093. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  69094. + pciP2PConfig &= PPCR_BUS_NUM_MASK;
  69095. + return (pciP2PConfig >> PPCR_BUS_NUM_OFFS);
  69096. +}
  69097. +
  69098. +
  69099. +/*******************************************************************************
  69100. +* mvPciLocalDevNumSet - Set PCI interface local device number.
  69101. +*
  69102. +* DESCRIPTION:
  69103. +* This function sets given PCI interface its local device number.
  69104. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  69105. +*
  69106. +* INPUT:
  69107. +* pciIf - PCI interface number.
  69108. +* devNum - Device number.
  69109. +*
  69110. +* OUTPUT:
  69111. +* None.
  69112. +*
  69113. +* RETURN:
  69114. +* MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,
  69115. +* otherwise MV_OK
  69116. +*
  69117. +*******************************************************************************/
  69118. +MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)
  69119. +{
  69120. + MV_U32 pciP2PConfig;
  69121. + MV_PCI_MODE pciMode;
  69122. + MV_U32 localBus;
  69123. + MV_U32 localDev;
  69124. +
  69125. + /* Parameter checking */
  69126. + if (pciIf >= mvCtrlPciMaxIfGet())
  69127. + {
  69128. + mvOsPrintf("mvPciLocalDevNumSet: ERR. Invalid PCI interface %d\n",pciIf);
  69129. + return MV_BAD_PARAM;
  69130. + }
  69131. + if (devNum >= MAX_PCI_DEVICES)
  69132. + {
  69133. + mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n",
  69134. + devNum);
  69135. + return MV_BAD_PARAM;
  69136. +
  69137. + }
  69138. +
  69139. + localBus = mvPciLocalBusNumGet(pciIf);
  69140. + localDev = mvPciLocalDevNumGet(pciIf);
  69141. +
  69142. + /* PCI interface mode */
  69143. + mvPciModeGet(pciIf, &pciMode);
  69144. +
  69145. + /* if PCI type is PCIX then it is not allowed to change the dev number */
  69146. + if (MV_PCIX == pciMode.pciType)
  69147. + {
  69148. + pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );
  69149. +
  69150. + pciP2PConfig &= ~PXS_DN_MASK;
  69151. +
  69152. + pciP2PConfig |= (devNum << PXS_DN_OFFS) & PXS_DN_MASK;
  69153. +
  69154. + mvPciConfigWrite(pciIf,localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );
  69155. + }
  69156. + else
  69157. + {
  69158. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  69159. +
  69160. + pciP2PConfig &= ~PPCR_DEV_NUM_MASK;
  69161. +
  69162. + pciP2PConfig |= (devNum << PPCR_DEV_NUM_OFFS) & PPCR_DEV_NUM_MASK;
  69163. +
  69164. + MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);
  69165. + }
  69166. +
  69167. + return MV_OK;
  69168. +}
  69169. +
  69170. +/*******************************************************************************
  69171. +* mvPciLocalDevNumGet - Get PCI interface local device number.
  69172. +*
  69173. +* DESCRIPTION:
  69174. +* This function gets the local device number of a given PCI interface.
  69175. +*
  69176. +* INPUT:
  69177. +* pciIf - PCI interface number.
  69178. +*
  69179. +* OUTPUT:
  69180. +* None.
  69181. +*
  69182. +* RETURN:
  69183. +* Local device number. 0xffffffff on Error
  69184. +*
  69185. +*******************************************************************************/
  69186. +MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf)
  69187. +{
  69188. + MV_U32 pciP2PConfig;
  69189. +
  69190. + /* Parameter checking */
  69191. +
  69192. + if (PCI_DEFAULT_IF != pciIf)
  69193. + {
  69194. + if (pciIf >= mvCtrlPciMaxIfGet())
  69195. + {
  69196. + mvOsPrintf("mvPciLocalDevNumGet: ERR. Invalid PCI interface %d\n",
  69197. + pciIf);
  69198. + return 0xFFFFFFFF;
  69199. + }
  69200. + }
  69201. +
  69202. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  69203. +
  69204. + pciP2PConfig &= PPCR_DEV_NUM_MASK;
  69205. +
  69206. + return (pciP2PConfig >> PPCR_DEV_NUM_OFFS);
  69207. +}
  69208. +
  69209. +
  69210. +
  69211. +
  69212. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h
  69213. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h 1970-01-01 01:00:00.000000000 +0100
  69214. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h 2011-07-31 11:32:00.683428754 +0200
  69215. @@ -0,0 +1,185 @@
  69216. +/*******************************************************************************
  69217. +Copyright (C) Marvell International Ltd. and its affiliates
  69218. +
  69219. +This software file (the "File") is owned and distributed by Marvell
  69220. +International Ltd. and/or its affiliates ("Marvell") under the following
  69221. +alternative licensing terms. Once you have made an election to distribute the
  69222. +File under one of the following license alternatives, please (i) delete this
  69223. +introductory statement regarding license alternatives, (ii) delete the two
  69224. +license alternatives that you have not elected to use and (iii) preserve the
  69225. +Marvell copyright notice above.
  69226. +
  69227. +********************************************************************************
  69228. +Marvell Commercial License Option
  69229. +
  69230. +If you received this File from Marvell and you have entered into a commercial
  69231. +license agreement (a "Commercial License") with Marvell, the File is licensed
  69232. +to you under the terms of the applicable Commercial License.
  69233. +
  69234. +********************************************************************************
  69235. +Marvell GPL License Option
  69236. +
  69237. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69238. +modify this File in accordance with the terms and conditions of the General
  69239. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  69240. +available along with the File in the license.txt file or by writing to the Free
  69241. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  69242. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  69243. +
  69244. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  69245. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  69246. +DISCLAIMED. The GPL License provides additional details about this warranty
  69247. +disclaimer.
  69248. +********************************************************************************
  69249. +Marvell BSD License Option
  69250. +
  69251. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69252. +modify this File under the following licensing terms.
  69253. +Redistribution and use in source and binary forms, with or without modification,
  69254. +are permitted provided that the following conditions are met:
  69255. +
  69256. + * Redistributions of source code must retain the above copyright notice,
  69257. + this list of conditions and the following disclaimer.
  69258. +
  69259. + * Redistributions in binary form must reproduce the above copyright
  69260. + notice, this list of conditions and the following disclaimer in the
  69261. + documentation and/or other materials provided with the distribution.
  69262. +
  69263. + * Neither the name of Marvell nor the names of its contributors may be
  69264. + used to endorse or promote products derived from this software without
  69265. + specific prior written permission.
  69266. +
  69267. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  69268. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  69269. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  69270. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  69271. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  69272. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  69273. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  69274. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  69275. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  69276. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  69277. +
  69278. +*******************************************************************************/
  69279. +
  69280. +
  69281. +#ifndef __INCPCIH
  69282. +#define __INCPCIH
  69283. +
  69284. +#include "mvCommon.h"
  69285. +#include "mvOs.h"
  69286. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  69287. +#include "pci/mvPciRegs.h"
  69288. +
  69289. +
  69290. +/* NOTE not supported in this driver:
  69291. +
  69292. + Built In Self Test (BIST)
  69293. + Vital Product Data (VPD)
  69294. + Message Signaled Interrupt (MSI)
  69295. + Power Management
  69296. + Compact PCI Hot Swap
  69297. + Header retarget
  69298. +
  69299. +Registers not supported:
  69300. +1) PCI DLL Status and Control (PCI0 0x1D20, PCI1 0x1DA0)
  69301. +2) PCI/MPP Pads Calibration (CI0/MPP[31:16] 0x1D1C, PCI1/MPP[15:0] 0X1D9C)
  69302. +*/
  69303. +
  69304. +/* defines */
  69305. +/* The number of supported PCI interfaces depend on Marvell controller */
  69306. +/* device number. This device number ID is located on the PCI unit */
  69307. +/* configuration header. This creates a loop where calling PCI */
  69308. +/* configuration read/write routine results a call to get PCI configuration */
  69309. +/* information etc. This macro defines a default PCI interface. This PCI */
  69310. +/* interface is sure to exist. */
  69311. +#define PCI_DEFAULT_IF 0
  69312. +
  69313. +
  69314. +/* typedefs */
  69315. +/* The Marvell controller supports both conventional PCI and PCI-X. */
  69316. +/* This enumeration describes the PCI type. */
  69317. +typedef enum _mvPciType
  69318. +{
  69319. + MV_PCI_CONV, /* Conventional PCI */
  69320. + MV_PCIX /* PCI-X */
  69321. +}MV_PCI_TYPE;
  69322. +
  69323. +typedef enum _mvPciMod
  69324. +{
  69325. + MV_PCI_MOD_HOST,
  69326. + MV_PCI_MOD_DEVICE
  69327. +}MV_PCI_MOD;
  69328. +
  69329. +
  69330. +/* The Marvell controller supports both PCI width of 32 and 64 bit. */
  69331. +/* This enumerator describes PCI width */
  69332. +typedef enum _mvPciWidth
  69333. +{
  69334. + MV_PCI_32, /* PCI width 32bit */
  69335. + MV_PCI_64 /* PCI width 64bit */
  69336. +}MV_PCI_WIDTH;
  69337. +
  69338. +/* This structure describes the PCI unit configured type, speed and width. */
  69339. +typedef struct _mvPciMode
  69340. +{
  69341. + MV_PCI_TYPE pciType; /* PCI type */
  69342. + MV_U32 pciSpeed; /* Assuming PCI base clock on board is 33MHz */
  69343. + MV_PCI_WIDTH pciWidth; /* PCI bus width */
  69344. +}MV_PCI_MODE;
  69345. +
  69346. +/* mvPciInit - Initialize PCI interfaces*/
  69347. +MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod);
  69348. +
  69349. +/* mvPciCommandSet - Set PCI comman register value.*/
  69350. +MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command);
  69351. +
  69352. +/* mvPciModeGet - Get PCI interface mode.*/
  69353. +MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode);
  69354. +
  69355. +/* mvPciRetrySet - Set PCI retry counters*/
  69356. +MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter);
  69357. +
  69358. +/* mvPciDiscardTimerSet - Set PCI discard timer*/
  69359. +MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles);
  69360. +
  69361. +/* mvPciArbEnable - PCI arbiter enable/disable*/
  69362. +MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable);
  69363. +
  69364. +/* mvPciArbParkDis - Disable arbiter parking on agent */
  69365. +MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask);
  69366. +
  69367. +/* mvPciArbBrokDetectSet - Set PCI arbiter broken detection */
  69368. +MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles);
  69369. +
  69370. +/* mvPciConfigRead - Read from configuration space */
  69371. +MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  69372. + MV_U32 func,MV_U32 regOff);
  69373. +
  69374. +/* mvPciConfigWrite - Write to configuration space */
  69375. +MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  69376. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  69377. +
  69378. +/* mvPciMasterEnable - Enable/disale PCI interface master transactions.*/
  69379. +MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable);
  69380. +
  69381. +/* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.*/
  69382. +MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,MV_BOOL enable);
  69383. +
  69384. +/* mvPciLocalBusNumSet - Set PCI interface local bus number.*/
  69385. +MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);
  69386. +
  69387. +/* mvPciLocalBusNumGet - Get PCI interface local bus number.*/
  69388. +MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf);
  69389. +
  69390. +/* mvPciLocalDevNumSet - Set PCI interface local device number.*/
  69391. +MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);
  69392. +
  69393. +/* mvPciLocalDevNumGet - Get PCI interface local device number.*/
  69394. +MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf);
  69395. +
  69396. +
  69397. +#endif /* #ifndef __INCPCIH */
  69398. +
  69399. +
  69400. +
  69401. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h
  69402. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h 1970-01-01 01:00:00.000000000 +0100
  69403. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h 2011-07-31 11:32:00.763876199 +0200
  69404. @@ -0,0 +1,411 @@
  69405. +/*******************************************************************************
  69406. +Copyright (C) Marvell International Ltd. and its affiliates
  69407. +
  69408. +This software file (the "File") is owned and distributed by Marvell
  69409. +International Ltd. and/or its affiliates ("Marvell") under the following
  69410. +alternative licensing terms. Once you have made an election to distribute the
  69411. +File under one of the following license alternatives, please (i) delete this
  69412. +introductory statement regarding license alternatives, (ii) delete the two
  69413. +license alternatives that you have not elected to use and (iii) preserve the
  69414. +Marvell copyright notice above.
  69415. +
  69416. +********************************************************************************
  69417. +Marvell Commercial License Option
  69418. +
  69419. +If you received this File from Marvell and you have entered into a commercial
  69420. +license agreement (a "Commercial License") with Marvell, the File is licensed
  69421. +to you under the terms of the applicable Commercial License.
  69422. +
  69423. +********************************************************************************
  69424. +Marvell GPL License Option
  69425. +
  69426. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69427. +modify this File in accordance with the terms and conditions of the General
  69428. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  69429. +available along with the File in the license.txt file or by writing to the Free
  69430. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  69431. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  69432. +
  69433. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  69434. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  69435. +DISCLAIMED. The GPL License provides additional details about this warranty
  69436. +disclaimer.
  69437. +********************************************************************************
  69438. +Marvell BSD License Option
  69439. +
  69440. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69441. +modify this File under the following licensing terms.
  69442. +Redistribution and use in source and binary forms, with or without modification,
  69443. +are permitted provided that the following conditions are met:
  69444. +
  69445. + * Redistributions of source code must retain the above copyright notice,
  69446. + this list of conditions and the following disclaimer.
  69447. +
  69448. + * Redistributions in binary form must reproduce the above copyright
  69449. + notice, this list of conditions and the following disclaimer in the
  69450. + documentation and/or other materials provided with the distribution.
  69451. +
  69452. + * Neither the name of Marvell nor the names of its contributors may be
  69453. + used to endorse or promote products derived from this software without
  69454. + specific prior written permission.
  69455. +
  69456. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  69457. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  69458. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  69459. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  69460. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  69461. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  69462. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  69463. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  69464. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  69465. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  69466. +
  69467. +*******************************************************************************/
  69468. +
  69469. +#ifndef __INCPCIREGSH
  69470. +#define __INCPCIREGSH
  69471. +
  69472. +
  69473. +#include "pci-if/mvPciIfRegs.h"
  69474. +/* defines */
  69475. +#define MAX_PCI_DEVICES 32
  69476. +#define MAX_PCI_FUNCS 8
  69477. +#define MAX_PCI_BUSSES 128
  69478. +
  69479. +/* enumerators */
  69480. +
  69481. +/* This enumerator described the possible PCI slave targets. */
  69482. +/* PCI slave targets are designated memory/IO address spaces that the */
  69483. +/* PCI slave targets can access. They are also refered as "targets" */
  69484. +/* this enumeratoe order is determined by the content of :
  69485. + PCI_BASE_ADDR_ENABLE_REG */
  69486. +
  69487. +
  69488. +/* registers offsetes defines */
  69489. +
  69490. +
  69491. +
  69492. +/*************************/
  69493. +/* PCI control registers */
  69494. +/*************************/
  69495. +/* maen : should add new registers */
  69496. +#define PCI_CMD_REG(pciIf) (0x30c00 + ((pciIf) * 0x80))
  69497. +#define PCI_MODE_REG(pciIf) (0x30d00 + ((pciIf) * 0x80))
  69498. +#define PCI_RETRY_REG(pciIf) (0x30c04 + ((pciIf) * 0x80))
  69499. +#define PCI_DISCARD_TIMER_REG(pciIf) (0x30d04 + ((pciIf) * 0x80))
  69500. +#define PCI_ARBITER_CTRL_REG(pciIf) (0x31d00 + ((pciIf) * 0x80))
  69501. +#define PCI_P2P_CONFIG_REG(pciIf) (0x31d14 + ((pciIf) * 0x80))
  69502. +#define PCI_ACCESS_CTRL_BASEL_REG(pciIf, targetWin) \
  69503. + (0x31e00 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
  69504. +#define PCI_ACCESS_CTRL_BASEH_REG(pciIf, targetWin) \
  69505. + (0x31e04 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
  69506. +#define PCI_ACCESS_CTRL_SIZE_REG(pciIf, targetWin) \
  69507. + (0x31e08 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
  69508. +
  69509. +#define PCI_DLL_CTRL_REG(pciIf) (0x31d20 + ((pciIf) * 0x80))
  69510. +
  69511. +/* PCI Dll Control (PDC)*/
  69512. +#define PDC_DLL_EN BIT0
  69513. +
  69514. +
  69515. +/* PCI Command Register (PCR) */
  69516. +#define PCR_MASTER_BYTE_SWAP_EN BIT0
  69517. +#define PCR_MASTER_WR_COMBINE_EN BIT4
  69518. +#define PCR_MASTER_RD_COMBINE_EN BIT5
  69519. +#define PCR_MASTER_WR_TRIG_WHOLE BIT6
  69520. +#define PCR_MASTER_RD_TRIG_WHOLE BIT7
  69521. +#define PCR_MASTER_MEM_RD_LINE_EN BIT8
  69522. +#define PCR_MASTER_MEM_RD_MULT_EN BIT9
  69523. +#define PCR_MASTER_WORD_SWAP_EN BIT10
  69524. +#define PCR_SLAVE_WORD_SWAP_EN BIT11
  69525. +#define PCR_NS_ACCORDING_RCV_TRANS BIT14
  69526. +#define PCR_MASTER_PCIX_REQ64N_EN BIT15
  69527. +#define PCR_SLAVE_BYTE_SWAP_EN BIT16
  69528. +#define PCR_MASTER_DAC_EN BIT17
  69529. +#define PCR_MASTER_M64_ALLIGN BIT18
  69530. +#define PCR_ERRORS_PROPAGATION_EN BIT19
  69531. +#define PCR_SLAVE_SWAP_ENABLE BIT20
  69532. +#define PCR_MASTER_SWAP_ENABLE BIT21
  69533. +#define PCR_MASTER_INT_SWAP_EN BIT22
  69534. +#define PCR_LOOP_BACK_ENABLE BIT23
  69535. +#define PCR_SLAVE_INTREG_SWAP_OFFS 24
  69536. +#define PCR_SLAVE_INTREG_SWAP_MASK 0x3
  69537. +#define PCR_SLAVE_INTREG_BYTE_SWAP \
  69538. + (MV_BYTE_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  69539. +#define PCR_SLAVE_INTREG_NO_SWAP \
  69540. + (MV_NO_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  69541. +#define PCR_SLAVE_INTREG_BYTE_WORD \
  69542. + (MV_BYTE_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  69543. +#define PCR_SLAVE_INTREG_WORD_SWAP \
  69544. + (MV_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  69545. +#define PCR_RESET_REASSERTION_EN BIT26
  69546. +#define PCR_PCI_TO_CPU_REG_ORDER_EN BIT28
  69547. +#define PCR_CPU_TO_PCI_ORDER_EN BIT29
  69548. +#define PCR_PCI_TO_CPU_ORDER_EN BIT30
  69549. +
  69550. +/* PCI Mode Register (PMR) */
  69551. +#define PMR_PCI_ID_OFFS 0 /* PCI Interface ID */
  69552. +#define PMR_PCI_ID_MASK (0x1 << PMR_PCI_ID_OFFS)
  69553. +#define PMR_PCI_ID_PCI(pciNum) ((pciNum) << PCI_MODE_PCIID_OFFS)
  69554. +
  69555. +#define PMR_PCI_64_OFFS 2 /* 64-bit PCI Interface */
  69556. +#define PMR_PCI_64_MASK (0x1 << PMR_PCI_64_OFFS)
  69557. +#define PMR_PCI_64_64BIT (0x1 << PMR_PCI_64_OFFS)
  69558. +#define PMR_PCI_64_32BIT (0x0 << PMR_PCI_64_OFFS)
  69559. +
  69560. +#define PMR_PCI_MODE_OFFS 4 /* PCI interface mode of operation */
  69561. +#define PMR_PCI_MODE_MASK (0x3 << PMR_PCI_MODE_OFFS)
  69562. +#define PMR_PCI_MODE_CONV (0x0 << PMR_PCI_MODE_OFFS)
  69563. +#define PMR_PCI_MODE_PCIX_66MHZ (0x1 << PMR_PCI_MODE_OFFS)
  69564. +#define PMR_PCI_MODE_PCIX_100MHZ (0x2 << PMR_PCI_MODE_OFFS)
  69565. +#define PMR_PCI_MODE_PCIX_133MHZ (0x3 << PMR_PCI_MODE_OFFS)
  69566. +
  69567. +#define PMR_EXP_ROM_SUPPORT BIT8 /* Expansion ROM Active */
  69568. +
  69569. +#define PMR_PCI_RESET_OFFS 31 /* PCI Interface Reset Indication */
  69570. +#define PMR_PCI_RESET_MASK (0x1 << PMR_PCI_RESET_OFFS)
  69571. +#define PMR_PCI_RESET_PCIXRST (0x0 << PMR_PCI_RESET_OFFS)
  69572. +
  69573. +
  69574. +/* PCI Retry Register (PRR) */
  69575. +#define PRR_RETRY_CNTR_OFFS 16 /* Retry Counter */
  69576. +#define PRR_RETRY_CNTR_MAX 0xff
  69577. +#define PRR_RETRY_CNTR_MASK (PRR_RETRY_CNTR_MAX << PRR_RETRY_CNTR_OFFS)
  69578. +
  69579. +
  69580. +/* PCI Discard Timer Register (PDTR) */
  69581. +#define PDTR_TIMER_OFFS 0 /* Timer */
  69582. +#define PDTR_TIMER_MAX 0xffff
  69583. +#define PDTR_TIMER_MIN 0x7F
  69584. +#define PDTR_TIMER_MASK (PDTR_TIMER_MAX << PDTR_TIMER_OFFS)
  69585. +
  69586. +
  69587. +/* PCI Arbiter Control Register (PACR) */
  69588. +#define PACR_BROKEN_DETECT_EN BIT1 /* Broken Detection Enable */
  69589. +
  69590. +#define PACR_BROKEN_VAL_OFFS 3 /* Broken Value */
  69591. +#define PACR_BROKEN_VAL_MASK (0xf << PACR_BROKEN_VAL_OFFS)
  69592. +#define PACR_BROKEN_VAL_CONV_MIN 0x2
  69593. +#define PACR_BROKEN_VAL_PCIX_MIN 0x6
  69594. +
  69595. +#define PACR_PARK_DIS_OFFS 14 /* Parking Disable */
  69596. +#define PACR_PARK_DIS_MAX_AGENT 0x3f
  69597. +#define PACR_PARK_DIS_MASK (PACR_PARK_DIS_MAX_AGENT<<PACR_PARK_DIS_OFFS)
  69598. +#define PACR_PARK_DIS(agent) ((1 << (agent)) << PACR_PARK_DIS_OFFS)
  69599. +
  69600. +#define PACR_ARB_ENABLE BIT31 /* Enable Internal Arbiter */
  69601. +
  69602. +
  69603. +/* PCI P2P Configuration Register (PPCR) */
  69604. +#define PPCR_2ND_BUS_L_OFFS 0 /* 2nd PCI Interface Bus Range Lower */
  69605. +#define PPCR_2ND_BUS_L_MASK (0xff << PPCR_2ND_BUS_L_OFFS)
  69606. +
  69607. +#define PPCR_2ND_BUS_H_OFFS 8 /* 2nd PCI Interface Bus Range Upper */
  69608. +#define PPCR_2ND_BUS_H_MASK (0xff << PPCR_2ND_BUS_H_OFFS)
  69609. +
  69610. +#define PPCR_BUS_NUM_OFFS 16 /* The PCI interface's Bus number */
  69611. +#define PPCR_BUS_NUM_MASK (0xff << PPCR_BUS_NUM_OFFS)
  69612. +
  69613. +#define PPCR_DEV_NUM_OFFS 24 /* The PCI interface’s Device number */
  69614. +#define PPCR_DEV_NUM_MASK (0xff << PPCR_DEV_NUM_OFFS)
  69615. +
  69616. +
  69617. +/* PCI Access Control Base Low Register (PACBLR) */
  69618. +#define PACBLR_EN BIT0 /* Access control window enable */
  69619. +
  69620. +#define PACBLR_ACCPROT BIT4 /* Access Protect */
  69621. +#define PACBLR_WRPROT BIT5 /* Write Protect */
  69622. +
  69623. +#define PACBLR_PCISWAP_OFFS 6 /* PCI slave Data Swap Control */
  69624. +#define PACBLR_PCISWAP_MASK (0x3 << PACBLR_PCISWAP_OFFS)
  69625. +#define PACBLR_PCISWAP_BYTE (0x0 << PACBLR_PCISWAP_OFFS)
  69626. +#define PACBLR_PCISWAP_NO_SWAP (0x1 << PACBLR_PCISWAP_OFFS)
  69627. +#define PACBLR_PCISWAP_BYTE_WORD (0x2 << PACBLR_PCISWAP_OFFS)
  69628. +#define PACBLR_PCISWAP_WORD (0x3 << PACBLR_PCISWAP_OFFS)
  69629. +
  69630. +#define PACBLR_RDMBURST_OFFS 8 /* Read Max Burst */
  69631. +#define PACBLR_RDMBURST_MASK (0x3 << PACBLR_RDMBURST_OFFS)
  69632. +#define PACBLR_RDMBURST_32BYTE (0x0 << PACBLR_RDMBURST_OFFS)
  69633. +#define PACBLR_RDMBURST_64BYTE (0x1 << PACBLR_RDMBURST_OFFS)
  69634. +#define PACBLR_RDMBURST_128BYTE (0x2 << PACBLR_RDMBURST_OFFS)
  69635. +
  69636. +#define PACBLR_RDSIZE_OFFS 10 /* Typical PCI read transaction Size. */
  69637. +#define PACBLR_RDSIZE_MASK (0x3 << PACBLR_RDSIZE_OFFS)
  69638. +#define PACBLR_RDSIZE_32BYTE (0x0 << PACBLR_RDSIZE_OFFS)
  69639. +#define PACBLR_RDSIZE_64BYTE (0x1 << PACBLR_RDSIZE_OFFS)
  69640. +#define PACBLR_RDSIZE_128BYTE (0x2 << PACBLR_RDSIZE_OFFS)
  69641. +#define PACBLR_RDSIZE_256BYTE (0x3 << PACBLR_RDSIZE_OFFS)
  69642. +
  69643. +#define PACBLR_BASE_L_OFFS 12 /* Corresponds to address bits [31:12] */
  69644. +#define PACBLR_BASE_L_MASK (0xfffff << PACBLR_BASE_L_OFFS)
  69645. +#define PACBLR_BASE_L_ALIGNMENT (1 << PACBLR_BASE_L_OFFS)
  69646. +#define PACBLR_BASE_ALIGN_UP(base) \
  69647. + ((base+PACBLR_BASE_L_ALIGNMENT)&PACBLR_BASE_L_MASK)
  69648. +#define PACBLR_BASE_ALIGN_DOWN(base) (base & PACBLR_BASE_L_MASK)
  69649. +
  69650. +
  69651. +/* PCI Access Control Base High Register (PACBHR) */
  69652. +#define PACBHR_BASE_H_OFFS 0 /* Corresponds to address bits [63:32] */
  69653. +#define PACBHR_CTRL_BASE_H_MASK (0xffffffff << PACBHR_BASE_H_OFFS)
  69654. +
  69655. +/* PCI Access Control Size Register (PACSR) */
  69656. +#define PACSR_WRMBURST_OFFS 8 /* Write Max Burst */
  69657. +#define PACSR_WRMBURST_MASK (0x3 << PACSR_WRMBURST_OFFS)
  69658. +#define PACSR_WRMBURST_32BYTE (0x0 << PACSR_WRMBURST_OFFS)
  69659. +#define PACSR_WRMBURST_64BYTE (0x1 << PACSR_WRMBURST_OFFS)
  69660. +#define PACSR_WRMBURST_128BYTE (0x2 << PACSR_WRMBURST_OFFS)
  69661. +
  69662. +#define PACSR_PCI_ORDERING BIT11 /* PCI Ordering required */
  69663. +
  69664. +#define PACSR_SIZE_OFFS 12 /* PCI access window size */
  69665. +#define PACSR_SIZE_MASK (0xfffff << PACSR_SIZE_OFFS)
  69666. +#define PACSR_SIZE_ALIGNMENT (1 << PACSR_SIZE_OFFS)
  69667. +#define PACSR_SIZE_ALIGN_UP(size) \
  69668. + ((size+PACSR_SIZE_ALIGNMENT)&PACSR_SIZE_MASK)
  69669. +#define PACSR_SIZE_ALIGN_DOWN(size) (size & PACSR_SIZE_MASK)
  69670. +
  69671. +
  69672. +/***************************************/
  69673. +/* PCI Configuration Access Registers */
  69674. +/***************************************/
  69675. +
  69676. +#define PCI_CONFIG_ADDR_REG(pciIf) (0x30C78 - ((pciIf) * 0x80) )
  69677. +#define PCI_CONFIG_DATA_REG(pciIf) (0x30C7C - ((pciIf) * 0x80) )
  69678. +#define PCI_INT_ACK_REG(pciIf) (0x30C34 + ((pciIf) * 0x80) )
  69679. +
  69680. +/* PCI Configuration Address Register (PCAR) */
  69681. +#define PCAR_REG_NUM_OFFS 2
  69682. +#define PCAR_REG_NUM_MASK (0x3F << PCAR_REG_NUM_OFFS)
  69683. +
  69684. +#define PCAR_FUNC_NUM_OFFS 8
  69685. +#define PCAR_FUNC_NUM_MASK (0x7 << PCAR_FUNC_NUM_OFFS)
  69686. +
  69687. +#define PCAR_DEVICE_NUM_OFFS 11
  69688. +#define PCAR_DEVICE_NUM_MASK (0x1F << PCAR_DEVICE_NUM_OFFS)
  69689. +
  69690. +#define PCAR_BUS_NUM_OFFS 16
  69691. +#define PCAR_BUS_NUM_MASK (0xFF << PCAR_BUS_NUM_OFFS)
  69692. +
  69693. +#define PCAR_CONFIG_EN BIT31
  69694. +
  69695. +
  69696. +/***************************************/
  69697. +/* PCI Configuration registers */
  69698. +/***************************************/
  69699. +
  69700. +/*********************************************/
  69701. +/* PCI Configuration, Function 0, Registers */
  69702. +/*********************************************/
  69703. +
  69704. +/* Marvell Specific */
  69705. +#define PCI_SCS0_BASE_ADDR_LOW 0x010
  69706. +#define PCI_SCS0_BASE_ADDR_HIGH 0x014
  69707. +#define PCI_SCS1_BASE_ADDR_LOW 0x018
  69708. +#define PCI_SCS1_BASE_ADDR_HIGH 0x01C
  69709. +#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_L 0x020
  69710. +#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_H 0x024
  69711. +
  69712. +/* capability list */
  69713. +#define PCI_POWER_MNG_CAPABILITY 0x040
  69714. +#define PCI_POWER_MNG_STATUS_CONTROL 0x044
  69715. +#define PCI_VPD_ADDRESS_REG 0x048
  69716. +#define PCI_VPD_DATA_REG 0x04c
  69717. +#define PCI_MSI_MESSAGE_CONTROL 0x050
  69718. +#define PCI_MSI_MESSAGE_ADDR 0x054
  69719. +#define PCI_MSI_MESSAGE_UPPER_ADDR 0x058
  69720. +#define PCI_MSI_MESSAGE_DATA 0x05c
  69721. +#define PCIX_COMMAND 0x060
  69722. +#define PCIX_STATUS 0x064
  69723. +#define PCI_COMPACT_PCI_HOT_SWAP 0x068
  69724. +
  69725. +
  69726. +/*********************************************/
  69727. +/* PCI Configuration, Function 1, Registers */
  69728. +/*********************************************/
  69729. +
  69730. +#define PCI_SCS2_BASE_ADDR_LOW 0x10
  69731. +#define PCI_SCS2_BASE_ADDR_HIGH 0x14
  69732. +#define PCI_SCS3_BASE_ADDR_LOW 0x18
  69733. +#define PCI_SCS3_BASE_ADDR_HIGH 0x1c
  69734. +
  69735. +
  69736. +/***********************************************/
  69737. +/* PCI Configuration, Function 2, Registers */
  69738. +/***********************************************/
  69739. +
  69740. +#define PCI_DEVCS0_BASE_ADDR_LOW 0x10
  69741. +#define PCI_DEVCS0_BASE_ADDR_HIGH 0x14
  69742. +#define PCI_DEVCS1_BASE_ADDR_LOW 0x18
  69743. +#define PCI_DEVCS1_BASE_ADDR_HIGH 0x1c
  69744. +#define PCI_DEVCS2_BASE_ADDR_LOW 0x20
  69745. +#define PCI_DEVCS2_BASE_ADDR_HIGH 0x24
  69746. +
  69747. +/***********************************************/
  69748. +/* PCI Configuration, Function 3, Registers */
  69749. +/***********************************************/
  69750. +
  69751. +#define PCI_BOOTCS_BASE_ADDR_LOW 0x18
  69752. +#define PCI_BOOTCS_BASE_ADDR_HIGH 0x1c
  69753. +
  69754. +/***********************************************/
  69755. +/* PCI Configuration, Function 4, Registers */
  69756. +/***********************************************/
  69757. +
  69758. +#define PCI_P2P_MEM0_BASE_ADDR_LOW 0x10
  69759. +#define PCI_P2P_MEM0_BASE_ADDR_HIGH 0x14
  69760. +#define PCI_P2P_IO_BASE_ADDR 0x20
  69761. +#define PCI_INTER_REGS_IO_MAPPED_BASE_ADDR 0x24
  69762. +
  69763. +/* PCIX_STATUS register fields (PXS) */
  69764. +
  69765. +#define PXS_FN_OFFS 0 /* Description Number */
  69766. +#define PXS_FN_MASK (0x7 << PXS_FN_OFFS)
  69767. +
  69768. +#define PXS_DN_OFFS 3 /* Device Number */
  69769. +#define PXS_DN_MASK (0x1f << PXS_DN_OFFS)
  69770. +
  69771. +#define PXS_BN_OFFS 8 /* Bus Number */
  69772. +#define PXS_BN_MASK (0xff << PXS_BN_OFFS)
  69773. +
  69774. +
  69775. +/* PCI Error Report Register Map */
  69776. +#define PCI_SERRN_MASK_REG(pciIf) (0x30c28 + (pciIf * 0x80))
  69777. +#define PCI_CAUSE_REG(pciIf) (0x31d58 + (pciIf * 0x80))
  69778. +#define PCI_MASK_REG(pciIf) (0x31d5C + (pciIf * 0x80))
  69779. +#define PCI_ERROR_ADDR_LOW_REG(pciIf) (0x31d40 + (pciIf * 0x80))
  69780. +#define PCI_ERROR_ADDR_HIGH_REG(pciIf) (0x31d44 + (pciIf * 0x80))
  69781. +#define PCI_ERROR_ATTRIBUTE_REG(pciIf) (0x31d48 + (pciIf * 0x80))
  69782. +#define PCI_ERROR_COMMAND_REG(pciIf) (0x31d50 + (pciIf * 0x80))
  69783. +
  69784. +/* PCI Interrupt Cause Register (PICR) */
  69785. +#define PICR_ERR_SEL_OFFS 27
  69786. +#define PICR_ERR_SEL_MASK (0x1f << PICR_ERR_SEL_OFFS)
  69787. +
  69788. +/* PCI Error Command Register (PECR) */
  69789. +#define PECR_ERR_CMD_OFFS 0
  69790. +#define PECR_ERR_CMD_MASK (0xf << PECR_ERR_CMD_OFFS)
  69791. +#define PECR_DAC BIT4
  69792. +
  69793. +
  69794. +/* defaults */
  69795. +/* Set bits means value is about to change according to new value */
  69796. +#define PCI_COMMAND_DEFAULT_MASK 0xffffdff1
  69797. +#define PCI_COMMAND_DEFAULT \
  69798. + (PCR_MASTER_WR_TRIG_WHOLE | \
  69799. + PCR_MASTER_RD_TRIG_WHOLE | \
  69800. + PCR_MASTER_MEM_RD_LINE_EN | \
  69801. + PCR_MASTER_MEM_RD_MULT_EN | \
  69802. + PCR_NS_ACCORDING_RCV_TRANS | \
  69803. + PCR_MASTER_PCIX_REQ64N_EN | \
  69804. + PCR_MASTER_DAC_EN | \
  69805. + PCR_MASTER_M64_ALLIGN | \
  69806. + PCR_ERRORS_PROPAGATION_EN)
  69807. +
  69808. +
  69809. +#define PCI_ARBITER_CTRL_DEFAULT_MASK 0x801fc07a
  69810. +#define PCI_ARBITER_CTRL_DEFAULT \
  69811. + (PACR_BROKEN_VAL_PCIX_MIN << PACR_BROKEN_VAL_OFFS)
  69812. +
  69813. +
  69814. +#endif /* #ifndef __INCPCIREGSH */
  69815. +
  69816. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c
  69817. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c 1970-01-01 01:00:00.000000000 +0100
  69818. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c 2011-07-31 11:32:00.813955320 +0200
  69819. @@ -0,0 +1,669 @@
  69820. +/*******************************************************************************
  69821. +Copyright (C) Marvell International Ltd. and its affiliates
  69822. +
  69823. +This software file (the "File") is owned and distributed by Marvell
  69824. +International Ltd. and/or its affiliates ("Marvell") under the following
  69825. +alternative licensing terms. Once you have made an election to distribute the
  69826. +File under one of the following license alternatives, please (i) delete this
  69827. +introductory statement regarding license alternatives, (ii) delete the two
  69828. +license alternatives that you have not elected to use and (iii) preserve the
  69829. +Marvell copyright notice above.
  69830. +
  69831. +********************************************************************************
  69832. +Marvell Commercial License Option
  69833. +
  69834. +If you received this File from Marvell and you have entered into a commercial
  69835. +license agreement (a "Commercial License") with Marvell, the File is licensed
  69836. +to you under the terms of the applicable Commercial License.
  69837. +
  69838. +********************************************************************************
  69839. +Marvell GPL License Option
  69840. +
  69841. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69842. +modify this File in accordance with the terms and conditions of the General
  69843. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  69844. +available along with the File in the license.txt file or by writing to the Free
  69845. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  69846. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  69847. +
  69848. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  69849. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  69850. +DISCLAIMED. The GPL License provides additional details about this warranty
  69851. +disclaimer.
  69852. +********************************************************************************
  69853. +Marvell BSD License Option
  69854. +
  69855. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69856. +modify this File under the following licensing terms.
  69857. +Redistribution and use in source and binary forms, with or without modification,
  69858. +are permitted provided that the following conditions are met:
  69859. +
  69860. + * Redistributions of source code must retain the above copyright notice,
  69861. + this list of conditions and the following disclaimer.
  69862. +
  69863. + * Redistributions in binary form must reproduce the above copyright
  69864. + notice, this list of conditions and the following disclaimer in the
  69865. + documentation and/or other materials provided with the distribution.
  69866. +
  69867. + * Neither the name of Marvell nor the names of its contributors may be
  69868. + used to endorse or promote products derived from this software without
  69869. + specific prior written permission.
  69870. +
  69871. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  69872. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  69873. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  69874. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  69875. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  69876. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  69877. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  69878. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  69879. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  69880. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  69881. +
  69882. +*******************************************************************************/
  69883. +
  69884. +#include "mvPciIf.h"
  69885. +#include "ctrlEnv/sys/mvSysPex.h"
  69886. +
  69887. +#if defined(MV_INCLUDE_PCI)
  69888. +#include "ctrlEnv/sys/mvSysPci.h"
  69889. +#endif
  69890. +
  69891. +
  69892. +/* defines */
  69893. +#ifdef MV_DEBUG
  69894. + #define DB(x) x
  69895. +#else
  69896. + #define DB(x)
  69897. +#endif
  69898. +
  69899. +
  69900. +/*******************************************************************************
  69901. +* mvPciInit - Initialize PCI interfaces
  69902. +*
  69903. +* DESCRIPTION:
  69904. +*
  69905. +* INPUT:
  69906. +*
  69907. +*
  69908. +* OUTPUT:
  69909. +* None.
  69910. +*
  69911. +* RETURN:
  69912. +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
  69913. +*
  69914. +*******************************************************************************/
  69915. +
  69916. +
  69917. +MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode)
  69918. +{
  69919. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69920. +
  69921. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69922. + {
  69923. + #if defined(MV_INCLUDE_PCI)
  69924. +
  69925. + MV_PCI_MOD pciMod;
  69926. +
  69927. + if (PCI_IF_MODE_HOST == pciIfmode)
  69928. + {
  69929. + pciMod = MV_PCI_MOD_HOST;
  69930. + }
  69931. + else if (PCI_IF_MODE_DEVICE == pciIfmode)
  69932. + {
  69933. + pciMod = MV_PCI_MOD_DEVICE;
  69934. + }
  69935. + else
  69936. + {
  69937. + mvOsPrintf("%s: ERROR!!! Bus %d mode %d neither host nor device!\n",
  69938. + __FUNCTION__, pciIf, pciIfmode);
  69939. + return MV_FAIL;
  69940. + }
  69941. +
  69942. + return mvPciInit(pciIf - MV_PCI_START_IF, pciMod);
  69943. + #else
  69944. + return MV_OK;
  69945. + #endif
  69946. + }
  69947. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69948. + {
  69949. + #if defined(MV_INCLUDE_PEX)
  69950. +
  69951. + MV_PEX_TYPE pexType;
  69952. +
  69953. + if (PCI_IF_MODE_HOST == pciIfmode)
  69954. + {
  69955. + pexType = MV_PEX_ROOT_COMPLEX;
  69956. + }
  69957. + else if (PCI_IF_MODE_DEVICE == pciIfmode)
  69958. + {
  69959. + pexType = MV_PEX_END_POINT;
  69960. + }
  69961. + else
  69962. + {
  69963. + mvOsPrintf("%s: ERROR!!! Bus %d type %d neither root complex nor" \
  69964. + " end point\n", __FUNCTION__, pciIf, pciIfmode);
  69965. + return MV_FAIL;
  69966. + }
  69967. + return mvPexInit(pciIf - MV_PEX_START_IF, pexType);
  69968. +
  69969. + #else
  69970. + return MV_OK;
  69971. + #endif
  69972. +
  69973. + }
  69974. + else
  69975. + {
  69976. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69977. + }
  69978. +
  69979. + return MV_FAIL;
  69980. +
  69981. +}
  69982. +
  69983. +/* PCI configuration space read write */
  69984. +
  69985. +/*******************************************************************************
  69986. +* mvPciConfigRead - Read from configuration space
  69987. +*
  69988. +* DESCRIPTION:
  69989. +* This function performs a 32 bit read from PCI configuration space.
  69990. +* It supports both type 0 and type 1 of Configuration Transactions
  69991. +* (local and over bridge). In order to read from local bus segment, use
  69992. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  69993. +* will result configuration transaction of type 1 (over bridge).
  69994. +*
  69995. +* INPUT:
  69996. +* pciIf - PCI interface number.
  69997. +* bus - PCI segment bus number.
  69998. +* dev - PCI device number.
  69999. +* func - Function number.
  70000. +* regOffs - Register offset.
  70001. +*
  70002. +* OUTPUT:
  70003. +* None.
  70004. +*
  70005. +* RETURN:
  70006. +* 32bit register data, 0xffffffff on error
  70007. +*
  70008. +*******************************************************************************/
  70009. +MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  70010. + MV_U32 regOff)
  70011. +{
  70012. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70013. +
  70014. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70015. + {
  70016. + #if defined(MV_INCLUDE_PCI)
  70017. + return mvPciConfigRead(pciIf - MV_PCI_START_IF,
  70018. + bus,
  70019. + dev,
  70020. + func,
  70021. + regOff);
  70022. + #else
  70023. + return 0xffffffff;
  70024. + #endif
  70025. + }
  70026. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70027. + {
  70028. + #if defined(MV_INCLUDE_PEX)
  70029. + return mvPexConfigRead(pciIf - MV_PEX_START_IF,
  70030. + bus,
  70031. + dev,
  70032. + func,
  70033. + regOff);
  70034. + #else
  70035. + return 0xffffffff;
  70036. + #endif
  70037. +
  70038. + }
  70039. + else
  70040. + {
  70041. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70042. + }
  70043. +
  70044. + return 0;
  70045. +
  70046. +}
  70047. +
  70048. +/*******************************************************************************
  70049. +* mvPciConfigWrite - Write to configuration space
  70050. +*
  70051. +* DESCRIPTION:
  70052. +* This function performs a 32 bit write to PCI configuration space.
  70053. +* It supports both type 0 and type 1 of Configuration Transactions
  70054. +* (local and over bridge). In order to write to local bus segment, use
  70055. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  70056. +* will result configuration transaction of type 1 (over bridge).
  70057. +*
  70058. +* INPUT:
  70059. +* pciIf - PCI interface number.
  70060. +* bus - PCI segment bus number.
  70061. +* dev - PCI device number.
  70062. +* func - Function number.
  70063. +* regOffs - Register offset.
  70064. +* data - 32bit data.
  70065. +*
  70066. +* OUTPUT:
  70067. +* None.
  70068. +*
  70069. +* RETURN:
  70070. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  70071. +*
  70072. +*******************************************************************************/
  70073. +MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  70074. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  70075. +{
  70076. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70077. +
  70078. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70079. + {
  70080. + #if defined(MV_INCLUDE_PCI)
  70081. + return mvPciConfigWrite(pciIf - MV_PCI_START_IF,
  70082. + bus,
  70083. + dev,
  70084. + func,
  70085. + regOff,
  70086. + data);
  70087. + #else
  70088. + return MV_OK;
  70089. + #endif
  70090. + }
  70091. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70092. + {
  70093. + #if defined(MV_INCLUDE_PEX)
  70094. + return mvPexConfigWrite(pciIf - MV_PEX_START_IF,
  70095. + bus,
  70096. + dev,
  70097. + func,
  70098. + regOff,
  70099. + data);
  70100. + #else
  70101. + return MV_OK;
  70102. + #endif
  70103. +
  70104. + }
  70105. + else
  70106. + {
  70107. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70108. + }
  70109. +
  70110. + return MV_FAIL;
  70111. +
  70112. +}
  70113. +
  70114. +/*******************************************************************************
  70115. +* mvPciMasterEnable - Enable/disale PCI interface master transactions.
  70116. +*
  70117. +* DESCRIPTION:
  70118. +* This function performs read modified write to PCI command status
  70119. +* (offset 0x4) to set/reset bit 2. After this bit is set, the PCI
  70120. +* master is allowed to gain ownership on the bus, otherwise it is
  70121. +* incapable to do so.
  70122. +*
  70123. +* INPUT:
  70124. +* pciIf - PCI interface number.
  70125. +* enable - Enable/disable parameter.
  70126. +*
  70127. +* OUTPUT:
  70128. +* None.
  70129. +*
  70130. +* RETURN:
  70131. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  70132. +*
  70133. +*******************************************************************************/
  70134. +MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable)
  70135. +{
  70136. +
  70137. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70138. +
  70139. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70140. + {
  70141. + #if defined(MV_INCLUDE_PCI)
  70142. + return mvPciMasterEnable(pciIf - MV_PCI_START_IF,
  70143. + enable);
  70144. + #else
  70145. + return MV_OK;
  70146. + #endif
  70147. + }
  70148. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70149. + {
  70150. + #if defined(MV_INCLUDE_PEX)
  70151. + return mvPexMasterEnable(pciIf - MV_PEX_START_IF,
  70152. + enable);
  70153. + #else
  70154. + return MV_OK;
  70155. + #endif
  70156. + }
  70157. + else
  70158. + {
  70159. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70160. + }
  70161. +
  70162. + return MV_FAIL;
  70163. +
  70164. +}
  70165. +
  70166. +
  70167. +/*******************************************************************************
  70168. +* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.
  70169. +*
  70170. +* DESCRIPTION:
  70171. +* This function performs read modified write to PCI command status
  70172. +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
  70173. +* the PCI slave is allowed to respond to PCI IO space access (bit 0)
  70174. +* and PCI memory space access (bit 1).
  70175. +*
  70176. +* INPUT:
  70177. +* pciIf - PCI interface number.
  70178. +* dev - PCI device number.
  70179. +* enable - Enable/disable parameter.
  70180. +*
  70181. +* OUTPUT:
  70182. +* None.
  70183. +*
  70184. +* RETURN:
  70185. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  70186. +*
  70187. +*******************************************************************************/
  70188. +MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev, MV_BOOL enable)
  70189. +{
  70190. +
  70191. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70192. +
  70193. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70194. + {
  70195. + #if defined(MV_INCLUDE_PCI)
  70196. + return mvPciSlaveEnable(pciIf - MV_PCI_START_IF,bus,dev,
  70197. + enable);
  70198. + #else
  70199. + return MV_OK;
  70200. + #endif
  70201. + }
  70202. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70203. + {
  70204. + #if defined(MV_INCLUDE_PEX)
  70205. + return mvPexSlaveEnable(pciIf - MV_PEX_START_IF,bus,dev,
  70206. + enable);
  70207. + #else
  70208. + return MV_OK;
  70209. + #endif
  70210. + }
  70211. + else
  70212. + {
  70213. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70214. + }
  70215. +
  70216. + return MV_FAIL;
  70217. +
  70218. +}
  70219. +
  70220. +/*******************************************************************************
  70221. +* mvPciLocalBusNumSet - Set PCI interface local bus number.
  70222. +*
  70223. +* DESCRIPTION:
  70224. +* This function sets given PCI interface its local bus number.
  70225. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  70226. +*
  70227. +* INPUT:
  70228. +* pciIf - PCI interface number.
  70229. +* busNum - Bus number.
  70230. +*
  70231. +* OUTPUT:
  70232. +* None.
  70233. +*
  70234. +* RETURN:
  70235. +* MV_NOT_ALLOWED in case PCI interface is PCI-X.
  70236. +* MV_BAD_PARAM on bad parameters ,
  70237. +* otherwise MV_OK
  70238. +*
  70239. +*******************************************************************************/
  70240. +MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)
  70241. +{
  70242. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70243. +
  70244. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70245. + {
  70246. + #if defined(MV_INCLUDE_PCI)
  70247. + return mvPciLocalBusNumSet(pciIf - MV_PCI_START_IF,
  70248. + busNum);
  70249. + #else
  70250. + return MV_OK;
  70251. + #endif
  70252. + }
  70253. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70254. + {
  70255. + #if defined(MV_INCLUDE_PEX)
  70256. + return mvPexLocalBusNumSet(pciIf - MV_PEX_START_IF,
  70257. + busNum);
  70258. + #else
  70259. + return MV_OK;
  70260. + #endif
  70261. + }
  70262. + else
  70263. + {
  70264. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70265. + }
  70266. +
  70267. + return MV_FAIL;
  70268. +
  70269. +}
  70270. +
  70271. +/*******************************************************************************
  70272. +* mvPciLocalBusNumGet - Get PCI interface local bus number.
  70273. +*
  70274. +* DESCRIPTION:
  70275. +* This function gets the local bus number of a given PCI interface.
  70276. +*
  70277. +* INPUT:
  70278. +* pciIf - PCI interface number.
  70279. +*
  70280. +* OUTPUT:
  70281. +* None.
  70282. +*
  70283. +* RETURN:
  70284. +* Local bus number.0xffffffff on Error
  70285. +*
  70286. +*******************************************************************************/
  70287. +MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf)
  70288. +{
  70289. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70290. +
  70291. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70292. + {
  70293. + #if defined(MV_INCLUDE_PCI)
  70294. + return mvPciLocalBusNumGet(pciIf - MV_PCI_START_IF);
  70295. + #else
  70296. + return 0xFFFFFFFF;
  70297. + #endif
  70298. + }
  70299. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70300. + {
  70301. + #if defined(MV_INCLUDE_PEX)
  70302. + return mvPexLocalBusNumGet(pciIf - MV_PEX_START_IF);
  70303. + #else
  70304. + return 0xFFFFFFFF;
  70305. + #endif
  70306. +
  70307. + }
  70308. + else
  70309. + {
  70310. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n",__FUNCTION__, pciIf);
  70311. + }
  70312. +
  70313. + return 0;
  70314. +
  70315. +}
  70316. +
  70317. +
  70318. +/*******************************************************************************
  70319. +* mvPciLocalDevNumSet - Set PCI interface local device number.
  70320. +*
  70321. +* DESCRIPTION:
  70322. +* This function sets given PCI interface its local device number.
  70323. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  70324. +*
  70325. +* INPUT:
  70326. +* pciIf - PCI interface number.
  70327. +* devNum - Device number.
  70328. +*
  70329. +* OUTPUT:
  70330. +* None.
  70331. +*
  70332. +* RETURN:
  70333. +* MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,
  70334. +* otherwise MV_OK
  70335. +*
  70336. +*******************************************************************************/
  70337. +MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)
  70338. +{
  70339. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70340. +
  70341. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70342. + {
  70343. + #if defined(MV_INCLUDE_PCI)
  70344. + return mvPciLocalDevNumSet(pciIf - MV_PCI_START_IF,
  70345. + devNum);
  70346. + #else
  70347. + return MV_OK;
  70348. + #endif
  70349. + }
  70350. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70351. + {
  70352. + #if defined(MV_INCLUDE_PEX)
  70353. + return mvPexLocalDevNumSet(pciIf - MV_PEX_START_IF,
  70354. + devNum);
  70355. + #else
  70356. + return MV_OK;
  70357. + #endif
  70358. + }
  70359. + else
  70360. + {
  70361. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70362. + }
  70363. +
  70364. + return MV_FAIL;
  70365. +
  70366. +}
  70367. +
  70368. +/*******************************************************************************
  70369. +* mvPciLocalDevNumGet - Get PCI interface local device number.
  70370. +*
  70371. +* DESCRIPTION:
  70372. +* This function gets the local device number of a given PCI interface.
  70373. +*
  70374. +* INPUT:
  70375. +* pciIf - PCI interface number.
  70376. +*
  70377. +* OUTPUT:
  70378. +* None.
  70379. +*
  70380. +* RETURN:
  70381. +* Local device number. 0xffffffff on Error
  70382. +*
  70383. +*******************************************************************************/
  70384. +MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf)
  70385. +{
  70386. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70387. +
  70388. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70389. + {
  70390. + #if defined(MV_INCLUDE_PCI)
  70391. + return mvPciLocalDevNumGet(pciIf - MV_PCI_START_IF);
  70392. + #else
  70393. + return 0xFFFFFFFF;
  70394. + #endif
  70395. + }
  70396. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70397. + {
  70398. + #if defined(MV_INCLUDE_PEX)
  70399. + return mvPexLocalDevNumGet(pciIf - MV_PEX_START_IF);
  70400. + #else
  70401. + return 0xFFFFFFFF;
  70402. + #endif
  70403. +
  70404. + }
  70405. + else
  70406. + {
  70407. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70408. + }
  70409. +
  70410. + return 0;
  70411. +
  70412. +}
  70413. +
  70414. +/*******************************************************************************
  70415. +* mvPciIfTypeGet -
  70416. +*
  70417. +* DESCRIPTION:
  70418. +*
  70419. +* INPUT:
  70420. +*
  70421. +* OUTPUT:
  70422. +* None.
  70423. +*
  70424. +* RETURN:
  70425. +*
  70426. +*******************************************************************************/
  70427. +
  70428. +PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf)
  70429. +{
  70430. +
  70431. + if ((pciIf >= MV_PCI_START_IF)&&(pciIf < MV_PCI_MAX_IF + MV_PCI_START_IF))
  70432. + {
  70433. + return PCI_IF_TYPE_CONVEN_PCIX;
  70434. + }
  70435. + else if ((pciIf >= MV_PEX_START_IF) &&
  70436. + (pciIf < MV_PEX_MAX_IF + MV_PEX_START_IF))
  70437. + {
  70438. + return PCI_IF_TYPE_PEX;
  70439. +
  70440. + }
  70441. + else
  70442. + {
  70443. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70444. + }
  70445. +
  70446. + return 0xffffffff;
  70447. +
  70448. +}
  70449. +
  70450. +/*******************************************************************************
  70451. +* mvPciIfTypeGet -
  70452. +*
  70453. +* DESCRIPTION:
  70454. +*
  70455. +* INPUT:
  70456. +*
  70457. +* OUTPUT:
  70458. +* None.
  70459. +*
  70460. +* RETURN:
  70461. +*
  70462. +*******************************************************************************/
  70463. +
  70464. +MV_U32 mvPciRealIfNumGet(MV_U32 pciIf)
  70465. +{
  70466. +
  70467. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70468. +
  70469. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70470. + {
  70471. + return (pciIf - MV_PCI_START_IF);
  70472. + }
  70473. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70474. + {
  70475. + return (pciIf - MV_PEX_START_IF);
  70476. +
  70477. + }
  70478. + else
  70479. + {
  70480. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70481. + }
  70482. +
  70483. + return 0xffffffff;
  70484. +
  70485. +}
  70486. +
  70487. +
  70488. +
  70489. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h
  70490. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h 1970-01-01 01:00:00.000000000 +0100
  70491. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h 2011-07-31 11:32:00.873625579 +0200
  70492. @@ -0,0 +1,134 @@
  70493. +/*******************************************************************************
  70494. +Copyright (C) Marvell International Ltd. and its affiliates
  70495. +
  70496. +This software file (the "File") is owned and distributed by Marvell
  70497. +International Ltd. and/or its affiliates ("Marvell") under the following
  70498. +alternative licensing terms. Once you have made an election to distribute the
  70499. +File under one of the following license alternatives, please (i) delete this
  70500. +introductory statement regarding license alternatives, (ii) delete the two
  70501. +license alternatives that you have not elected to use and (iii) preserve the
  70502. +Marvell copyright notice above.
  70503. +
  70504. +********************************************************************************
  70505. +Marvell Commercial License Option
  70506. +
  70507. +If you received this File from Marvell and you have entered into a commercial
  70508. +license agreement (a "Commercial License") with Marvell, the File is licensed
  70509. +to you under the terms of the applicable Commercial License.
  70510. +
  70511. +********************************************************************************
  70512. +Marvell GPL License Option
  70513. +
  70514. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70515. +modify this File in accordance with the terms and conditions of the General
  70516. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  70517. +available along with the File in the license.txt file or by writing to the Free
  70518. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  70519. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  70520. +
  70521. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  70522. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  70523. +DISCLAIMED. The GPL License provides additional details about this warranty
  70524. +disclaimer.
  70525. +********************************************************************************
  70526. +Marvell BSD License Option
  70527. +
  70528. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70529. +modify this File under the following licensing terms.
  70530. +Redistribution and use in source and binary forms, with or without modification,
  70531. +are permitted provided that the following conditions are met:
  70532. +
  70533. + * Redistributions of source code must retain the above copyright notice,
  70534. + this list of conditions and the following disclaimer.
  70535. +
  70536. + * Redistributions in binary form must reproduce the above copyright
  70537. + notice, this list of conditions and the following disclaimer in the
  70538. + documentation and/or other materials provided with the distribution.
  70539. +
  70540. + * Neither the name of Marvell nor the names of its contributors may be
  70541. + used to endorse or promote products derived from this software without
  70542. + specific prior written permission.
  70543. +
  70544. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  70545. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  70546. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  70547. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  70548. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  70549. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  70550. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  70551. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  70552. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  70553. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  70554. +
  70555. +*******************************************************************************/
  70556. +
  70557. +#ifndef __INCPCIIFH
  70558. +#define __INCPCIIFH
  70559. +
  70560. +#include "mvSysHwConfig.h"
  70561. +#include "pci-if/mvPciIfRegs.h"
  70562. +#if defined(MV_INCLUDE_PEX)
  70563. +#include "pex/mvPex.h"
  70564. +#endif
  70565. +#if defined(MV_INCLUDE_PCI)
  70566. +#include "pci/mvPci.h"
  70567. +#endif
  70568. +#include "ctrlEnv/mvCtrlEnvLib.h"
  70569. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  70570. +
  70571. +typedef enum _mvPCIIfType
  70572. +{
  70573. + PCI_IF_TYPE_CONVEN_PCIX,
  70574. + PCI_IF_TYPE_PEX
  70575. +
  70576. +}PCI_IF_TYPE;
  70577. +
  70578. +typedef enum _mvPCIIfMode
  70579. +{
  70580. + PCI_IF_MODE_HOST,
  70581. + PCI_IF_MODE_DEVICE
  70582. +}PCI_IF_MODE;
  70583. +
  70584. +
  70585. +/* Global Functions prototypes */
  70586. +
  70587. +/* mvPciIfInit - Initialize PCI interfaces*/
  70588. +MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode);
  70589. +
  70590. +/* mvPciIfConfigRead - Read from configuration space */
  70591. +MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  70592. + MV_U32 func,MV_U32 regOff);
  70593. +
  70594. +/* mvPciIfConfigWrite - Write to configuration space */
  70595. +MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  70596. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  70597. +
  70598. +/* mvPciIfMasterEnable - Enable/disale PCI interface master transactions.*/
  70599. +MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable);
  70600. +
  70601. +/* mvPciIfSlaveEnable - Enable/disale PCI interface slave transactions.*/
  70602. +MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev,
  70603. + MV_BOOL enable);
  70604. +
  70605. +/* mvPciIfLocalBusNumSet - Set PCI interface local bus number.*/
  70606. +MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);
  70607. +
  70608. +/* mvPciIfLocalBusNumGet - Get PCI interface local bus number.*/
  70609. +MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf);
  70610. +
  70611. +/* mvPciIfLocalDevNumSet - Set PCI interface local device number.*/
  70612. +MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);
  70613. +
  70614. +/* mvPciIfLocalDevNumGet - Get PCI interface local device number.*/
  70615. +MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf);
  70616. +
  70617. +/* mvPciIfTypeGet - Get PCI If type*/
  70618. +PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf);
  70619. +
  70620. +MV_U32 mvPciRealIfNumGet(MV_U32 pciIf);
  70621. +
  70622. +/* mvPciIfAddrDecShow - Display address decode windows attributes */
  70623. +MV_VOID mvPciIfAddrDecShow(MV_VOID);
  70624. +
  70625. +#endif /* #ifndef __INCPCIIFH */
  70626. +
  70627. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h
  70628. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  70629. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h 2011-07-31 11:32:00.943680001 +0200
  70630. @@ -0,0 +1,245 @@
  70631. +/*******************************************************************************
  70632. +Copyright (C) Marvell International Ltd. and its affiliates
  70633. +
  70634. +This software file (the "File") is owned and distributed by Marvell
  70635. +International Ltd. and/or its affiliates ("Marvell") under the following
  70636. +alternative licensing terms. Once you have made an election to distribute the
  70637. +File under one of the following license alternatives, please (i) delete this
  70638. +introductory statement regarding license alternatives, (ii) delete the two
  70639. +license alternatives that you have not elected to use and (iii) preserve the
  70640. +Marvell copyright notice above.
  70641. +
  70642. +********************************************************************************
  70643. +Marvell Commercial License Option
  70644. +
  70645. +If you received this File from Marvell and you have entered into a commercial
  70646. +license agreement (a "Commercial License") with Marvell, the File is licensed
  70647. +to you under the terms of the applicable Commercial License.
  70648. +
  70649. +********************************************************************************
  70650. +Marvell GPL License Option
  70651. +
  70652. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70653. +modify this File in accordance with the terms and conditions of the General
  70654. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  70655. +available along with the File in the license.txt file or by writing to the Free
  70656. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  70657. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  70658. +
  70659. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  70660. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  70661. +DISCLAIMED. The GPL License provides additional details about this warranty
  70662. +disclaimer.
  70663. +********************************************************************************
  70664. +Marvell BSD License Option
  70665. +
  70666. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70667. +modify this File under the following licensing terms.
  70668. +Redistribution and use in source and binary forms, with or without modification,
  70669. +are permitted provided that the following conditions are met:
  70670. +
  70671. + * Redistributions of source code must retain the above copyright notice,
  70672. + this list of conditions and the following disclaimer.
  70673. +
  70674. + * Redistributions in binary form must reproduce the above copyright
  70675. + notice, this list of conditions and the following disclaimer in the
  70676. + documentation and/or other materials provided with the distribution.
  70677. +
  70678. + * Neither the name of Marvell nor the names of its contributors may be
  70679. + used to endorse or promote products derived from this software without
  70680. + specific prior written permission.
  70681. +
  70682. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  70683. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  70684. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  70685. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  70686. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  70687. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  70688. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  70689. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  70690. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  70691. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  70692. +
  70693. +*******************************************************************************/
  70694. +
  70695. +#ifndef __INCPCIIFREGSH
  70696. +#define __INCPCIIFREGSH
  70697. +
  70698. +
  70699. +/* defines */
  70700. +#define MAX_PCI_DEVICES 32
  70701. +#define MAX_PCI_FUNCS 8
  70702. +#define MAX_PCI_BUSSES 128
  70703. +
  70704. +/***************************************/
  70705. +/* PCI Configuration registers */
  70706. +/***************************************/
  70707. +
  70708. +/*********************************************/
  70709. +/* PCI Configuration, Function 0, Registers */
  70710. +/*********************************************/
  70711. +
  70712. +
  70713. +/* Standard registers */
  70714. +#define PCI_DEVICE_AND_VENDOR_ID 0x000
  70715. +#define PCI_STATUS_AND_COMMAND 0x004
  70716. +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008
  70717. +#define PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE 0x00C
  70718. +#define PCI_MEMORY_BAR_BASE_ADDR(barNum) (0x010 + ((barNum) << 2))
  70719. +#define PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID 0x02C
  70720. +#define PCI_EXPANSION_ROM_BASE_ADDR_REG 0x030
  70721. +#define PCI_CAPABILTY_LIST_POINTER 0x034
  70722. +#define PCI_INTERRUPT_PIN_AND_LINE 0x03C
  70723. +
  70724. +
  70725. +/* PCI Device and Vendor ID Register (PDVIR) */
  70726. +#define PDVIR_VEN_ID_OFFS 0 /* Vendor ID */
  70727. +#define PDVIR_VEN_ID_MASK (0xffff << PDVIR_VEN_ID_OFFS)
  70728. +
  70729. +#define PDVIR_DEV_ID_OFFS 16 /* Device ID */
  70730. +#define PDVIR_DEV_ID_MASK (0xffff << PDVIR_DEV_ID_OFFS)
  70731. +
  70732. +/* PCI Status and Command Register (PSCR) */
  70733. +#define PSCR_IO_EN BIT0 /* IO Enable */
  70734. +#define PSCR_MEM_EN BIT1 /* Memory Enable */
  70735. +#define PSCR_MASTER_EN BIT2 /* Master Enable */
  70736. +#define PSCR_SPECIAL_EN BIT3 /* Special Cycle Enable */
  70737. +#define PSCR_MEM_WRI_INV BIT4 /* Memory Write and Invalidate Enable */
  70738. +#define PSCR_VGA BIT5 /* VGA Palette Snoops */
  70739. +#define PSCR_PERR_EN BIT6 /* Parity Errors Respond Enable */
  70740. +#define PSCR_ADDR_STEP BIT7 /* Address Stepping Enable (Wait Cycle En)*/
  70741. +#define PSCR_SERR_EN BIT8 /* Ability to assert SERR# line */
  70742. +#define PSCR_FAST_BTB_EN BIT9 /* generate fast back-to-back transactions*/
  70743. +#define PSCR_CAP_LIST BIT20 /* Capability List Support */
  70744. +#define PSCR_66MHZ_EN BIT21 /* 66 MHz Capable */
  70745. +#define PSCR_UDF_EN BIT22 /* User definable features */
  70746. +#define PSCR_TAR_FAST_BB BIT23 /* fast back-to-back transactions capable */
  70747. +#define PSCR_DATA_PERR BIT24 /* Data Parity reported */
  70748. +
  70749. +#define PSCR_DEVSEL_TIM_OFFS 25 /* DEVSEL timing */
  70750. +#define PSCR_DEVSEL_TIM_MASK (0x3 << PSCR_DEVSEL_TIM_OFFS)
  70751. +#define PSCR_DEVSEL_TIM_FAST (0x0 << PSCR_DEVSEL_TIM_OFFS)
  70752. +#define PSCR_DEVSEL_TIM_MED (0x1 << PSCR_DEVSEL_TIM_OFFS)
  70753. +#define PSCR_DEVSEL_TIM_SLOW (0x2 << PSCR_DEVSEL_TIM_OFFS)
  70754. +
  70755. +#define PSCR_SLAVE_TABORT BIT27 /* Signalled Target Abort */
  70756. +#define PSCR_MASTER_TABORT BIT28 /* Recieved Target Abort */
  70757. +#define PSCR_MABORT BIT29 /* Recieved Master Abort */
  70758. +#define PSCR_SYSERR BIT30 /* Signalled system error */
  70759. +#define PSCR_DET_PARERR BIT31 /* Detect Parity Error */
  70760. +
  70761. +/* PCI configuration register offset=0x08 fields
  70762. + (PCI_CLASS_CODE_AND_REVISION_ID)(PCCRI) */
  70763. +
  70764. +#define PCCRIR_REVID_OFFS 0 /* Revision ID */
  70765. +#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS)
  70766. +
  70767. +#define PCCRIR_FULL_CLASS_OFFS 8 /* Full Class Code */
  70768. +#define PCCRIR_FULL_CLASS_MASK (0xffffff << PCCRIR_FULL_CLASS_OFFS)
  70769. +
  70770. +#define PCCRIR_PROGIF_OFFS 8 /* Prog .I/F*/
  70771. +#define PCCRIR_PROGIF_MASK (0xff << PCCRIR_PROGIF_OFFS)
  70772. +
  70773. +#define PCCRIR_SUB_CLASS_OFFS 16 /* Sub Class*/
  70774. +#define PCCRIR_SUB_CLASS_MASK (0xff << PCCRIR_SUB_CLASS_OFFS)
  70775. +
  70776. +#define PCCRIR_BASE_CLASS_OFFS 24 /* Base Class*/
  70777. +#define PCCRIR_BASE_CLASS_MASK (0xff << PCCRIR_BASE_CLASS_OFFS)
  70778. +
  70779. +/* PCI configuration register offset=0x0C fields
  70780. + (PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE)(PBHTLTCL) */
  70781. +
  70782. +#define PBHTLTCLR_CACHELINE_OFFS 0 /* Specifies the cache line size */
  70783. +#define PBHTLTCLR_CACHELINE_MASK (0xff << PBHTLTCLR_CACHELINE_OFFS)
  70784. +
  70785. +#define PBHTLTCLR_LATTIMER_OFFS 8 /* latency timer */
  70786. +#define PBHTLTCLR_LATTIMER_MASK (0xff << PBHTLTCLR_LATTIMER_OFFS)
  70787. +
  70788. +#define PBHTLTCLR_HEADTYPE_FULL_OFFS 16 /* Full Header Type */
  70789. +#define PBHTLTCLR_HEADTYPE_FULL_MASK (0xff << PBHTLTCLR_HEADTYPE_FULL_OFFS)
  70790. +
  70791. +#define PBHTLTCLR_MULTI_FUNC BIT23 /* Multi/Single function */
  70792. +
  70793. +#define PBHTLTCLR_HEADER_OFFS 16 /* Header type */
  70794. +#define PBHTLTCLR_HEADER_MASK (0x7f << PBHTLTCLR_HEADER_OFFS)
  70795. +#define PBHTLTCLR_HEADER_STANDARD (0x0 << PBHTLTCLR_HEADER_OFFS)
  70796. +#define PBHTLTCLR_HEADER_PCI2PCI_BRIDGE (0x1 << PBHTLTCLR_HEADER_OFFS)
  70797. +
  70798. +
  70799. +#define PBHTLTCLR_BISTCOMP_OFFS 24 /* BIST Completion Code */
  70800. +#define PBHTLTCLR_BISTCOMP_MASK (0xf << PBHTLTCLR_BISTCOMP_OFFS)
  70801. +
  70802. +#define PBHTLTCLR_BISTACT BIT30 /* BIST Activate bit */
  70803. +#define PBHTLTCLR_BISTCAP BIT31 /* BIST Capable Bit */
  70804. +
  70805. +
  70806. +/* PCI Bar Base Low Register (PBBLR) */
  70807. +#define PBBLR_IOSPACE BIT0 /* Memory Space Indicator */
  70808. +
  70809. +#define PBBLR_TYPE_OFFS 1 /* BAR Type/Init Val. */
  70810. +#define PBBLR_TYPE_MASK (0x3 << PBBLR_TYPE_OFFS)
  70811. +#define PBBLR_TYPE_32BIT_ADDR (0x0 << PBBLR_TYPE_OFFS)
  70812. +#define PBBLR_TYPE_64BIT_ADDR (0x2 << PBBLR_TYPE_OFFS)
  70813. +
  70814. +#define PBBLR_PREFETCH_EN BIT3 /* Prefetch Enable */
  70815. +
  70816. +
  70817. +#define PBBLR_MEM_BASE_OFFS 4 /* Memory Bar Base address. Corresponds to
  70818. + address bits [31:4] */
  70819. +#define PBBLR_MEM_BASE_MASK (0xfffffff << PBBLR_MEM_BASE_OFFS)
  70820. +
  70821. +#define PBBLR_IO_BASE_OFFS 2 /* IO Bar Base address. Corresponds to
  70822. + address bits [31:2] */
  70823. +#define PBBLR_IO_BASE_MASK (0x3fffffff << PBBLR_IO_BASE_OFFS)
  70824. +
  70825. +
  70826. +#define PBBLR_BASE_OFFS 12 /* Base address. Address bits [31:12] */
  70827. +#define PBBLR_BASE_MASK (0xfffff << PBBLR_BASE_OFFS)
  70828. +#define PBBLR_BASE_ALIGNMET (1 << PBBLR_BASE_OFFS)
  70829. +
  70830. +
  70831. +/* PCI Bar Base High Fegister (PBBHR) */
  70832. +#define PBBHR_BASE_OFFS 0 /* Base address. Address bits [31:12] */
  70833. +#define PBBHR_BASE_MASK (0xffffffff << PBBHR_BASE_OFFS)
  70834. +
  70835. +
  70836. +/* PCI configuration register offset=0x2C fields
  70837. + (PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID)(PSISVI) */
  70838. +
  70839. +#define PSISVIR_VENID_OFFS 0 /* Subsystem Manufacturer Vendor ID Number */
  70840. +#define PSISVIR_VENID_MASK (0xffff << PSISVIR_VENID_OFFS)
  70841. +
  70842. +#define PSISVIR_DEVID_OFFS 16 /* Subsystem Device ID Number */
  70843. +#define PSISVIR_DEVID_MASK (0xffff << PSISVIR_DEVID_OFFS)
  70844. +
  70845. +/* PCI configuration register offset=0x30 fields
  70846. + (PCI_EXPANSION_ROM_BASE_ADDR_REG)(PERBA) */
  70847. +
  70848. +#define PERBAR_EXPROMEN BIT0 /* Expansion ROM Enable */
  70849. +
  70850. +#define PERBAR_BASE_OFFS 12 /* Expansion ROM Base Address */
  70851. +#define PERBAR_BASE_MASK (0xfffff << PERBAR_BASE_OFFS)
  70852. +
  70853. +/* PCI configuration register offset=0x34 fields
  70854. + (PCI_CAPABILTY_LIST_POINTER)(PCLP) */
  70855. +
  70856. +#define PCLPR_CAPPTR_OFFS 0 /* Capability List Pointer */
  70857. +#define PCLPR_CAPPTR_MASK (0xff << PCLPR_CAPPTR_OFFS)
  70858. +
  70859. +/* PCI configuration register offset=0x3C fields
  70860. + (PCI_INTERRUPT_PIN_AND_LINE)(PIPL) */
  70861. +
  70862. +#define PIPLR_INTLINE_OFFS 0 /* Interrupt line (IRQ) */
  70863. +#define PIPLR_INTLINE_MASK (0xff << PIPLR_INTLINE_OFFS)
  70864. +
  70865. +#define PIPLR_INTPIN_OFFS 8 /* interrupt pin (A,B,C,D) */
  70866. +#define PIPLR_INTPIN_MASK (0xff << PIPLR_INTPIN_OFFS)
  70867. +
  70868. +#define PIPLR_MINGRANT_OFFS 16 /* Minimum Grant on 250 nano seconds units */
  70869. +#define PIPLR_MINGRANT_MASK (0xff << PIPLR_MINGRANT_OFFS)
  70870. +
  70871. +#define PIPLR_MAXLATEN_OFFS 24 /* Maximum latency on 250 nano seconds units */
  70872. +#define PIPLR_MAXLATEN_MASK (0xff << PIPLR_MAXLATEN_OFFS)
  70873. +
  70874. +#endif /* #ifndef __INCPCIIFREGSH */
  70875. +
  70876. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c
  70877. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c 1970-01-01 01:00:00.000000000 +0100
  70878. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c 2011-07-31 11:32:01.013425599 +0200
  70879. @@ -0,0 +1,1006 @@
  70880. +/*******************************************************************************
  70881. +Copyright (C) Marvell International Ltd. and its affiliates
  70882. +
  70883. +This software file (the "File") is owned and distributed by Marvell
  70884. +International Ltd. and/or its affiliates ("Marvell") under the following
  70885. +alternative licensing terms. Once you have made an election to distribute the
  70886. +File under one of the following license alternatives, please (i) delete this
  70887. +introductory statement regarding license alternatives, (ii) delete the two
  70888. +license alternatives that you have not elected to use and (iii) preserve the
  70889. +Marvell copyright notice above.
  70890. +
  70891. +********************************************************************************
  70892. +Marvell Commercial License Option
  70893. +
  70894. +If you received this File from Marvell and you have entered into a commercial
  70895. +license agreement (a "Commercial License") with Marvell, the File is licensed
  70896. +to you under the terms of the applicable Commercial License.
  70897. +
  70898. +********************************************************************************
  70899. +Marvell GPL License Option
  70900. +
  70901. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70902. +modify this File in accordance with the terms and conditions of the General
  70903. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  70904. +available along with the File in the license.txt file or by writing to the Free
  70905. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  70906. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  70907. +
  70908. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  70909. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  70910. +DISCLAIMED. The GPL License provides additional details about this warranty
  70911. +disclaimer.
  70912. +********************************************************************************
  70913. +Marvell BSD License Option
  70914. +
  70915. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70916. +modify this File under the following licensing terms.
  70917. +Redistribution and use in source and binary forms, with or without modification,
  70918. +are permitted provided that the following conditions are met:
  70919. +
  70920. + * Redistributions of source code must retain the above copyright notice,
  70921. + this list of conditions and the following disclaimer.
  70922. +
  70923. + * Redistributions in binary form must reproduce the above copyright
  70924. + notice, this list of conditions and the following disclaimer in the
  70925. + documentation and/or other materials provided with the distribution.
  70926. +
  70927. + * Neither the name of Marvell nor the names of its contributors may be
  70928. + used to endorse or promote products derived from this software without
  70929. + specific prior written permission.
  70930. +
  70931. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  70932. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  70933. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  70934. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  70935. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  70936. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  70937. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  70938. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  70939. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  70940. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  70941. +
  70942. +*******************************************************************************/
  70943. +
  70944. +/* includes */
  70945. +#include "mvPciUtils.h"
  70946. +
  70947. +#include "ctrlEnv/mvCtrlEnvLib.h"
  70948. +
  70949. +/* #define MV_DEBUG */
  70950. +/* defines */
  70951. +#ifdef MV_DEBUG
  70952. + #define DB(x) x
  70953. + #define mvOsPrintf printf
  70954. +#else
  70955. + #define DB(x)
  70956. +#endif
  70957. +
  70958. +/*
  70959. +This module only support scanning of Header type 00h of pci devices
  70960. +There is no suppotr for Header type 01h of pci devices ( PCI bridges )
  70961. +*/
  70962. +
  70963. +
  70964. +static MV_STATUS pciDetectDevice(MV_U32 pciIf,
  70965. + MV_U32 bus,
  70966. + MV_U32 dev,
  70967. + MV_U32 func,
  70968. + MV_PCI_DEVICE *pPciAgent);
  70969. +
  70970. +static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
  70971. + MV_U32 bus,
  70972. + MV_U32 dev,
  70973. + MV_U32 func,
  70974. + MV_PCI_DEVICE *pPciAgent);
  70975. +
  70976. +
  70977. +
  70978. +
  70979. +
  70980. +
  70981. +/*******************************************************************************
  70982. +* mvPciScan - Scan a PCI interface bus
  70983. +*
  70984. +* DESCRIPTION:
  70985. +* Performs a full scan on a PCI interface and returns all possible details
  70986. +* on the agents found on the bus.
  70987. +*
  70988. +* INPUT:
  70989. +* pciIf - PCI Interface
  70990. +* pPciAgents - Pointer to an Array of the pci agents to be detected
  70991. +* pPciAgentsNum - pPciAgents array maximum number of elements
  70992. +*
  70993. +* OUTPUT:
  70994. +* pPciAgents - Array of the pci agents detected on the bus
  70995. +* pPciAgentsNum - Number of pci agents detected on the bus
  70996. +*
  70997. +* RETURN:
  70998. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  70999. +*
  71000. +*******************************************************************************/
  71001. +
  71002. +MV_STATUS mvPciScan(MV_U32 pciIf,
  71003. + MV_PCI_DEVICE *pPciAgents,
  71004. + MV_U32 *pPciAgentsNum)
  71005. +{
  71006. +
  71007. + MV_U32 devIndex,funcIndex=0,busIndex=0,detectedDevNum=0;
  71008. + MV_U32 localBus=mvPciIfLocalBusNumGet(pciIf);
  71009. + MV_PCI_DEVICE *pPciDevice;
  71010. + MV_PCI_DEVICE *pMainDevice;
  71011. +
  71012. + DB(mvOsPrintf("mvPciScan: PCI interface num %d\n", pciIf));
  71013. + /* Parameter checking */
  71014. + if (pciIf >= mvCtrlPexMaxIfGet())
  71015. + {
  71016. + DB(mvOsPrintf("mvPciScan: ERR. Invalid PCI interface num %d\n", pciIf));
  71017. + return MV_BAD_PARAM;
  71018. + }
  71019. + if (NULL == pPciAgents)
  71020. + {
  71021. + DB(mvOsPrintf("mvPciScan: ERR. pPciAgents=NULL \n"));
  71022. + return MV_BAD_PARAM;
  71023. + }
  71024. + if (NULL == pPciAgentsNum)
  71025. + {
  71026. + DB(mvOsPrintf("mvPciScan: ERR. pPciAgentsNum=NULL \n"));
  71027. + return MV_BAD_PARAM;
  71028. + }
  71029. +
  71030. +
  71031. + DB(mvOsPrintf("mvPciScan: PCI interface num %d mvPciMasterEnable\n", pciIf));
  71032. + /* Master enable the MV PCI master */
  71033. + if (MV_OK != mvPciIfMasterEnable(pciIf,MV_TRUE))
  71034. + {
  71035. + DB(mvOsPrintf("mvPciScan: ERR. mvPciMasterEnable failed \n"));
  71036. + return MV_ERROR;
  71037. +
  71038. + }
  71039. +
  71040. + DB(mvOsPrintf("mvPciScan: PCI interface num scan%d\n", pciIf));
  71041. +
  71042. + /* go through all busses */
  71043. + for (busIndex=localBus ; busIndex < MAX_PCI_BUSSES ; busIndex++)
  71044. + {
  71045. + /* go through all possible devices on the local bus */
  71046. + for (devIndex=0 ; devIndex < MAX_PCI_DEVICES ; devIndex++)
  71047. + {
  71048. + /* always start with function equal to zero */
  71049. + funcIndex=0;
  71050. +
  71051. + pPciDevice=&pPciAgents[detectedDevNum];
  71052. + DB(mvOsPrintf("mvPciScan: PCI interface num scan%d:%d\n", busIndex, devIndex));
  71053. +
  71054. + if (MV_ERROR == pciDetectDevice(pciIf,
  71055. + busIndex,
  71056. + devIndex,
  71057. + funcIndex,
  71058. + pPciDevice))
  71059. + {
  71060. + /* no device detected , try the next address */
  71061. + continue;
  71062. + }
  71063. +
  71064. + /* We are here ! means we have detected a device*/
  71065. + /* always we start with only one function per device */
  71066. + pMainDevice = pPciDevice;
  71067. + pPciDevice->funtionsNum = 1;
  71068. +
  71069. +
  71070. + /* move on */
  71071. + detectedDevNum++;
  71072. +
  71073. +
  71074. + /* check if we have no more room for a new device */
  71075. + if (detectedDevNum == *pPciAgentsNum)
  71076. + {
  71077. + DB(mvOsPrintf("mvPciScan: ERR. array passed too small \n"));
  71078. + return MV_ERROR;
  71079. + }
  71080. +
  71081. + /* check the detected device if it is a multi functional device then
  71082. + scan all device functions*/
  71083. + if (pPciDevice->isMultiFunction == MV_TRUE)
  71084. + {
  71085. + /* start with function number 1 because we have already detected
  71086. + function 0 */
  71087. + for (funcIndex=1; funcIndex<MAX_PCI_FUNCS ; funcIndex++)
  71088. + {
  71089. + pPciDevice=&pPciAgents[detectedDevNum];
  71090. +
  71091. + if (MV_ERROR == pciDetectDevice(pciIf,
  71092. + busIndex,
  71093. + devIndex,
  71094. + funcIndex,
  71095. + pPciDevice))
  71096. + {
  71097. + /* no device detected means no more functions !*/
  71098. + continue;
  71099. + }
  71100. + /* We are here ! means we have detected a device */
  71101. +
  71102. + /* move on */
  71103. + pMainDevice->funtionsNum++;
  71104. + detectedDevNum++;
  71105. +
  71106. + /* check if we have no more room for a new device */
  71107. + if (detectedDevNum == *pPciAgentsNum)
  71108. + {
  71109. + DB(mvOsPrintf("mvPciScan: ERR. Array too small\n"));
  71110. + return MV_ERROR;
  71111. + }
  71112. +
  71113. +
  71114. + }
  71115. + }
  71116. +
  71117. + }
  71118. +
  71119. + }
  71120. +
  71121. + /* return the number of devices actually detected on the bus ! */
  71122. + *pPciAgentsNum = detectedDevNum;
  71123. +
  71124. + return MV_OK;
  71125. +
  71126. +}
  71127. +
  71128. +
  71129. +/*******************************************************************************
  71130. +* pciDetectDevice - Detect a pci device parameters
  71131. +*
  71132. +* DESCRIPTION:
  71133. +* This function detect if a pci agent exist on certain address !
  71134. +* and if exists then it fills all possible information on the
  71135. +* agent
  71136. +*
  71137. +* INPUT:
  71138. +* pciIf - PCI Interface
  71139. +* bus - Bus number
  71140. +* dev - Device number
  71141. +* func - Function number
  71142. +*
  71143. +*
  71144. +*
  71145. +* OUTPUT:
  71146. +* pPciAgent - pointer to the pci agent filled with its information
  71147. +*
  71148. +* RETURN:
  71149. +* MV_ERROR if no device , MV_OK otherwise
  71150. +*
  71151. +*******************************************************************************/
  71152. +
  71153. +static MV_STATUS pciDetectDevice(MV_U32 pciIf,
  71154. + MV_U32 bus,
  71155. + MV_U32 dev,
  71156. + MV_U32 func,
  71157. + MV_PCI_DEVICE *pPciAgent)
  71158. +{
  71159. + MV_U32 pciData;
  71160. +
  71161. + /* no Parameters checking ! because it is static function and it is assumed
  71162. + that all parameters were checked in the calling function */
  71163. +
  71164. +
  71165. + /* Try read the PCI Vendor ID and Device ID */
  71166. +
  71167. + /* We will scan only ourselves and the PCI slots that exist on the
  71168. + board, because we may have a case that we have one slot that has
  71169. + a Cardbus connector, and because CardBus answers all IDsels we want
  71170. + to scan only this slot and ourseleves.
  71171. +
  71172. + */
  71173. + #if defined(MV_INCLUDE_PCI)
  71174. + if ((PCI_IF_TYPE_CONVEN_PCIX == mvPciIfTypeGet(pciIf)) &&
  71175. + (DB_88F5181_DDR1_PRPMC != mvBoardIdGet()) &&
  71176. + (DB_88F5181_DDR1_PEXPCI != mvBoardIdGet()) &&
  71177. + (DB_88F5181_DDR1_MNG != mvBoardIdGet()))
  71178. + {
  71179. +
  71180. + if (mvBoardIsOurPciSlot(bus, dev) == MV_FALSE)
  71181. + {
  71182. + return MV_ERROR;
  71183. + }
  71184. + }
  71185. + #endif /* defined(MV_INCLUDE_PCI) */
  71186. +
  71187. + pciData = mvPciIfConfigRead(pciIf, bus,dev,func, PCI_DEVICE_AND_VENDOR_ID);
  71188. +
  71189. + if (PCI_ERROR_CODE == pciData)
  71190. + {
  71191. + /* no device exist */
  71192. + return MV_ERROR;
  71193. + }
  71194. +
  71195. + /* we are here ! means a device is detected */
  71196. +
  71197. + /* fill basic information */
  71198. + pPciAgent->busNumber=bus;
  71199. + pPciAgent->deviceNum=dev;
  71200. + pPciAgent->function=func;
  71201. +
  71202. + /* Fill the PCI Vendor ID and Device ID */
  71203. +
  71204. + pPciAgent->venID = (pciData & PDVIR_VEN_ID_MASK) >> PDVIR_VEN_ID_OFFS;
  71205. + pPciAgent->deviceID = (pciData & PDVIR_DEV_ID_MASK) >> PDVIR_DEV_ID_OFFS;
  71206. +
  71207. + /* Read Status and command */
  71208. + pciData = mvPciIfConfigRead(pciIf,
  71209. + bus,dev,func,
  71210. + PCI_STATUS_AND_COMMAND);
  71211. +
  71212. +
  71213. + /* Fill related Status and Command information*/
  71214. +
  71215. + if (pciData & PSCR_TAR_FAST_BB)
  71216. + {
  71217. + pPciAgent->isFastB2BCapable = MV_TRUE;
  71218. + }
  71219. + else
  71220. + {
  71221. + pPciAgent->isFastB2BCapable = MV_FALSE;
  71222. + }
  71223. +
  71224. + if (pciData & PSCR_CAP_LIST)
  71225. + {
  71226. + pPciAgent->isCapListSupport=MV_TRUE;
  71227. + }
  71228. + else
  71229. + {
  71230. + pPciAgent->isCapListSupport=MV_FALSE;
  71231. + }
  71232. +
  71233. + if (pciData & PSCR_66MHZ_EN)
  71234. + {
  71235. + pPciAgent->is66MHZCapable=MV_TRUE;
  71236. + }
  71237. + else
  71238. + {
  71239. + pPciAgent->is66MHZCapable=MV_FALSE;
  71240. + }
  71241. +
  71242. + /* Read Class Code and Revision */
  71243. + pciData = mvPciIfConfigRead(pciIf,
  71244. + bus,dev,func,
  71245. + PCI_CLASS_CODE_AND_REVISION_ID);
  71246. +
  71247. +
  71248. + pPciAgent->baseClassCode =
  71249. + (pciData & PCCRIR_BASE_CLASS_MASK) >> PCCRIR_BASE_CLASS_OFFS;
  71250. +
  71251. + pPciAgent->subClassCode =
  71252. + (pciData & PCCRIR_SUB_CLASS_MASK) >> PCCRIR_SUB_CLASS_OFFS;
  71253. +
  71254. + pPciAgent->progIf =
  71255. + (pciData & PCCRIR_PROGIF_MASK) >> PCCRIR_PROGIF_OFFS;
  71256. +
  71257. + pPciAgent->revisionID =
  71258. + (pciData & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS;
  71259. +
  71260. + /* Read PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE */
  71261. + pciData = mvPciIfConfigRead(pciIf,
  71262. + bus,dev,func,
  71263. + PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE);
  71264. +
  71265. +
  71266. +
  71267. + pPciAgent->pciCacheLine=
  71268. + (pciData & PBHTLTCLR_CACHELINE_MASK ) >> PBHTLTCLR_CACHELINE_OFFS;
  71269. + pPciAgent->pciLatencyTimer=
  71270. + (pciData & PBHTLTCLR_LATTIMER_MASK) >> PBHTLTCLR_LATTIMER_OFFS;
  71271. +
  71272. + switch (pciData & PBHTLTCLR_HEADER_MASK)
  71273. + {
  71274. + case PBHTLTCLR_HEADER_STANDARD:
  71275. +
  71276. + pPciAgent->pciHeader=MV_PCI_STANDARD;
  71277. + break;
  71278. + case PBHTLTCLR_HEADER_PCI2PCI_BRIDGE:
  71279. +
  71280. + pPciAgent->pciHeader=MV_PCI_PCI2PCI_BRIDGE;
  71281. + break;
  71282. +
  71283. + }
  71284. +
  71285. + if (pciData & PBHTLTCLR_MULTI_FUNC)
  71286. + {
  71287. + pPciAgent->isMultiFunction=MV_TRUE;
  71288. + }
  71289. + else
  71290. + {
  71291. + pPciAgent->isMultiFunction=MV_FALSE;
  71292. + }
  71293. +
  71294. + if (pciData & PBHTLTCLR_BISTCAP)
  71295. + {
  71296. + pPciAgent->isBISTCapable=MV_TRUE;
  71297. + }
  71298. + else
  71299. + {
  71300. + pPciAgent->isBISTCapable=MV_FALSE;
  71301. + }
  71302. +
  71303. +
  71304. + /* read this device pci bars */
  71305. +
  71306. + pciDetectDeviceBars(pciIf,
  71307. + bus,dev,func,
  71308. + pPciAgent);
  71309. +
  71310. +
  71311. + /* check if we are bridge*/
  71312. + if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
  71313. + (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
  71314. + {
  71315. +
  71316. + /* Read P2P_BUSSES_NUM */
  71317. + pciData = mvPciIfConfigRead(pciIf,
  71318. + bus,dev,func,
  71319. + P2P_BUSSES_NUM);
  71320. +
  71321. + pPciAgent->p2pPrimBusNum =
  71322. + (pciData & PBM_PRIME_BUS_NUM_MASK) >> PBM_PRIME_BUS_NUM_OFFS;
  71323. +
  71324. + pPciAgent->p2pSecBusNum =
  71325. + (pciData & PBM_SEC_BUS_NUM_MASK) >> PBM_SEC_BUS_NUM_OFFS;
  71326. +
  71327. + pPciAgent->p2pSubBusNum =
  71328. + (pciData & PBM_SUB_BUS_NUM_MASK) >> PBM_SUB_BUS_NUM_OFFS;
  71329. +
  71330. + pPciAgent->p2pSecLatencyTimer =
  71331. + (pciData & PBM_SEC_LAT_TMR_MASK) >> PBM_SEC_LAT_TMR_OFFS;
  71332. +
  71333. + /* Read P2P_IO_BASE_LIMIT_SEC_STATUS */
  71334. + pciData = mvPciIfConfigRead(pciIf,
  71335. + bus,dev,func,
  71336. + P2P_IO_BASE_LIMIT_SEC_STATUS);
  71337. +
  71338. + pPciAgent->p2pSecStatus =
  71339. + (pciData & PIBLSS_SEC_STATUS_MASK) >> PIBLSS_SEC_STATUS_OFFS;
  71340. +
  71341. +
  71342. + pPciAgent->p2pIObase =
  71343. + (pciData & PIBLSS_IO_BASE_MASK) << PIBLSS_IO_LIMIT_OFFS;
  71344. +
  71345. + /* clear low address (should be zero)*/
  71346. + pPciAgent->p2pIObase &= PIBLSS_HIGH_ADDR_MASK;
  71347. +
  71348. + pPciAgent->p2pIOLimit =
  71349. + (pciData & PIBLSS_IO_LIMIT_MASK);
  71350. +
  71351. + /* fill low address with 0xfff */
  71352. + pPciAgent->p2pIOLimit |= PIBLSS_LOW_ADDR_MASK;
  71353. +
  71354. +
  71355. + switch ((pciData & PIBLSS_ADD_CAP_MASK) >> PIBLSS_ADD_CAP_OFFS)
  71356. + {
  71357. + case PIBLSS_ADD_CAP_16BIT:
  71358. +
  71359. + pPciAgent->bIO32 = MV_FALSE;
  71360. +
  71361. + break;
  71362. + case PIBLSS_ADD_CAP_32BIT:
  71363. +
  71364. + pPciAgent->bIO32 = MV_TRUE;
  71365. +
  71366. + /* Read P2P_IO_BASE_LIMIT_UPPER_16 */
  71367. + pciData = mvPciIfConfigRead(pciIf,
  71368. + bus,dev,func,
  71369. + P2P_IO_BASE_LIMIT_UPPER_16);
  71370. +
  71371. + pPciAgent->p2pIObase |=
  71372. + (pciData & PRBU_IO_UPP_BASE_MASK) << PRBU_IO_UPP_LIMIT_OFFS;
  71373. +
  71374. +
  71375. + pPciAgent->p2pIOLimit |=
  71376. + (pciData & PRBU_IO_UPP_LIMIT_MASK);
  71377. +
  71378. + break;
  71379. +
  71380. + }
  71381. +
  71382. +
  71383. + /* Read P2P_MEM_BASE_LIMIT */
  71384. + pciData = mvPciIfConfigRead(pciIf,
  71385. + bus,dev,func,
  71386. + P2P_MEM_BASE_LIMIT);
  71387. +
  71388. + pPciAgent->p2pMemBase =
  71389. + (pciData & PMBL_MEM_BASE_MASK) << PMBL_MEM_LIMIT_OFFS;
  71390. +
  71391. + /* clear low address */
  71392. + pPciAgent->p2pMemBase &= PMBL_HIGH_ADDR_MASK;
  71393. +
  71394. + pPciAgent->p2pMemLimit =
  71395. + (pciData & PMBL_MEM_LIMIT_MASK);
  71396. +
  71397. + /* add 0xfffff */
  71398. + pPciAgent->p2pMemLimit |= PMBL_LOW_ADDR_MASK;
  71399. +
  71400. +
  71401. + /* Read P2P_PREF_MEM_BASE_LIMIT */
  71402. + pciData = mvPciIfConfigRead(pciIf,
  71403. + bus,dev,func,
  71404. + P2P_PREF_MEM_BASE_LIMIT);
  71405. +
  71406. +
  71407. + pPciAgent->p2pPrefMemBase =
  71408. + (pciData & PRMBL_PREF_MEM_BASE_MASK) << PRMBL_PREF_MEM_LIMIT_OFFS;
  71409. +
  71410. + /* get high address only */
  71411. + pPciAgent->p2pPrefMemBase &= PRMBL_HIGH_ADDR_MASK;
  71412. +
  71413. +
  71414. +
  71415. + pPciAgent->p2pPrefMemLimit =
  71416. + (pciData & PRMBL_PREF_MEM_LIMIT_MASK);
  71417. +
  71418. + /* add 0xfffff */
  71419. + pPciAgent->p2pPrefMemLimit |= PRMBL_LOW_ADDR_MASK;
  71420. +
  71421. + switch (pciData & PRMBL_ADD_CAP_MASK)
  71422. + {
  71423. + case PRMBL_ADD_CAP_32BIT:
  71424. +
  71425. + pPciAgent->bPrefMem64 = MV_FALSE;
  71426. +
  71427. + /* Read P2P_PREF_BASE_UPPER_32 */
  71428. + pPciAgent->p2pPrefBaseUpper32Bits = 0;
  71429. +
  71430. + /* Read P2P_PREF_LIMIT_UPPER_32 */
  71431. + pPciAgent->p2pPrefLimitUpper32Bits = 0;
  71432. +
  71433. + break;
  71434. + case PRMBL_ADD_CAP_64BIT:
  71435. +
  71436. + pPciAgent->bPrefMem64 = MV_TRUE;
  71437. +
  71438. + /* Read P2P_PREF_BASE_UPPER_32 */
  71439. + pPciAgent->p2pPrefBaseUpper32Bits = mvPciIfConfigRead(pciIf,
  71440. + bus,dev,func,
  71441. + P2P_PREF_BASE_UPPER_32);
  71442. +
  71443. + /* Read P2P_PREF_LIMIT_UPPER_32 */
  71444. + pPciAgent->p2pPrefLimitUpper32Bits = mvPciIfConfigRead(pciIf,
  71445. + bus,dev,func,
  71446. + P2P_PREF_LIMIT_UPPER_32);
  71447. +
  71448. + break;
  71449. +
  71450. + }
  71451. +
  71452. + }
  71453. + else /* no bridge */
  71454. + {
  71455. + /* Read PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID */
  71456. + pciData = mvPciIfConfigRead(pciIf,
  71457. + bus,dev,func,
  71458. + PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID);
  71459. +
  71460. +
  71461. + pPciAgent->subSysVenID =
  71462. + (pciData & PSISVIR_VENID_MASK) >> PSISVIR_VENID_OFFS;
  71463. + pPciAgent->subSysID =
  71464. + (pciData & PSISVIR_DEVID_MASK) >> PSISVIR_DEVID_OFFS;
  71465. +
  71466. +
  71467. + /* Read PCI_EXPANSION_ROM_BASE_ADDR_REG */
  71468. + pciData = mvPciIfConfigRead(pciIf,
  71469. + bus,dev,func,
  71470. + PCI_EXPANSION_ROM_BASE_ADDR_REG);
  71471. +
  71472. +
  71473. + if (pciData & PERBAR_EXPROMEN)
  71474. + {
  71475. + pPciAgent->isExpRom = MV_TRUE;
  71476. + }
  71477. + else
  71478. + {
  71479. + pPciAgent->isExpRom = MV_FALSE;
  71480. + }
  71481. +
  71482. + pPciAgent->expRomAddr =
  71483. + (pciData & PERBAR_BASE_MASK) >> PERBAR_BASE_OFFS;
  71484. +
  71485. + }
  71486. +
  71487. +
  71488. + if (MV_TRUE == pPciAgent->isCapListSupport)
  71489. + {
  71490. + /* Read PCI_CAPABILTY_LIST_POINTER */
  71491. + pciData = mvPciIfConfigRead(pciIf,
  71492. + bus,dev,func,
  71493. + PCI_CAPABILTY_LIST_POINTER);
  71494. +
  71495. + pPciAgent->capListPointer =
  71496. + (pciData & PCLPR_CAPPTR_MASK) >> PCLPR_CAPPTR_OFFS;
  71497. +
  71498. + }
  71499. +
  71500. + /* Read PCI_INTERRUPT_PIN_AND_LINE */
  71501. + pciData = mvPciIfConfigRead(pciIf,
  71502. + bus,dev,func,
  71503. + PCI_INTERRUPT_PIN_AND_LINE);
  71504. +
  71505. +
  71506. + pPciAgent->irqLine=
  71507. + (pciData & PIPLR_INTLINE_MASK) >> PIPLR_INTLINE_OFFS;
  71508. +
  71509. + pPciAgent->intPin=
  71510. + (MV_PCI_INT_PIN)(pciData & PIPLR_INTPIN_MASK) >> PIPLR_INTPIN_OFFS;
  71511. +
  71512. + pPciAgent->minGrant=
  71513. + (pciData & PIPLR_MINGRANT_MASK) >> PIPLR_MINGRANT_OFFS;
  71514. + pPciAgent->maxLatency=
  71515. + (pciData & PIPLR_MAXLATEN_MASK) >> PIPLR_MAXLATEN_OFFS;
  71516. +
  71517. + mvPciClassNameGet(pPciAgent->baseClassCode,
  71518. + (MV_8 *)pPciAgent->type);
  71519. +
  71520. + return MV_OK;
  71521. +
  71522. +
  71523. +}
  71524. +
  71525. +/*******************************************************************************
  71526. +* pciDetectDeviceBars - Detect a pci device bars
  71527. +*
  71528. +* DESCRIPTION:
  71529. +* This function detects all pci agent bars
  71530. +*
  71531. +* INPUT:
  71532. +* pciIf - PCI Interface
  71533. +* bus - Bus number
  71534. +* dev - Device number
  71535. +* func - Function number
  71536. +*
  71537. +*
  71538. +*
  71539. +* OUTPUT:
  71540. +* pPciAgent - pointer to the pci agent filled with its information
  71541. +*
  71542. +* RETURN:
  71543. +* detected bars number
  71544. +*
  71545. +*******************************************************************************/
  71546. +static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
  71547. + MV_U32 bus,
  71548. + MV_U32 dev,
  71549. + MV_U32 func,
  71550. + MV_PCI_DEVICE *pPciAgent)
  71551. +{
  71552. + MV_U32 pciData,barIndex,detectedBar=0;
  71553. + MV_U32 tmpBaseHigh=0,tmpBaseLow=0;
  71554. + MV_U32 pciMaxBars=0;
  71555. +
  71556. + pPciAgent->barsNum=0;
  71557. +
  71558. + /* check if we are bridge*/
  71559. + if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
  71560. + (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
  71561. + {
  71562. + pciMaxBars = 2;
  71563. + }
  71564. + else /* no bridge */
  71565. + {
  71566. + pciMaxBars = 6;
  71567. + }
  71568. +
  71569. + /* read this device pci bars */
  71570. + for (barIndex = 0 ; barIndex < pciMaxBars ; barIndex++ )
  71571. + {
  71572. + /* Read PCI_MEMORY_BAR_BASE_ADDR */
  71573. + tmpBaseLow = pciData = mvPciIfConfigRead(pciIf,
  71574. + bus,dev,func,
  71575. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  71576. +
  71577. + pPciAgent->pciBar[detectedBar].barOffset =
  71578. + PCI_MEMORY_BAR_BASE_ADDR(barIndex);
  71579. +
  71580. + /* check if the bar is 32bit or 64bit bar */
  71581. + switch (pciData & PBBLR_TYPE_MASK)
  71582. + {
  71583. + case PBBLR_TYPE_32BIT_ADDR:
  71584. + pPciAgent->pciBar[detectedBar].barType = PCI_32BIT_BAR;
  71585. + break;
  71586. + case PBBLR_TYPE_64BIT_ADDR:
  71587. + pPciAgent->pciBar[detectedBar].barType = PCI_64BIT_BAR;
  71588. + break;
  71589. +
  71590. + }
  71591. +
  71592. + /* check if it is memory or IO bar */
  71593. + if (pciData & PBBLR_IOSPACE)
  71594. + {
  71595. + pPciAgent->pciBar[detectedBar].barMapping=PCI_IO_BAR;
  71596. + }
  71597. + else
  71598. + {
  71599. + pPciAgent->pciBar[detectedBar].barMapping=PCI_MEMORY_BAR;
  71600. + }
  71601. +
  71602. + /* if it is memory bar then check if it is prefetchable */
  71603. + if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
  71604. + {
  71605. + if (pciData & PBBLR_PREFETCH_EN)
  71606. + {
  71607. + pPciAgent->pciBar[detectedBar].isPrefetchable = MV_TRUE;
  71608. + }
  71609. + else
  71610. + {
  71611. + pPciAgent->pciBar[detectedBar].isPrefetchable = MV_FALSE;
  71612. + }
  71613. +
  71614. + pPciAgent->pciBar[detectedBar].barBaseLow =
  71615. + pciData & PBBLR_MEM_BASE_MASK;
  71616. +
  71617. +
  71618. + }
  71619. + else /* IO Bar */
  71620. + {
  71621. + pPciAgent->pciBar[detectedBar].barBaseLow =
  71622. + pciData & PBBLR_IO_BASE_MASK;
  71623. +
  71624. + }
  71625. +
  71626. + pPciAgent->pciBar[detectedBar].barBaseHigh=0;
  71627. +
  71628. + if (PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType)
  71629. + {
  71630. + barIndex++;
  71631. +
  71632. + tmpBaseHigh = pPciAgent->pciBar[detectedBar].barBaseHigh =
  71633. + mvPciIfConfigRead(pciIf,
  71634. + bus,dev,func,
  71635. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  71636. +
  71637. +
  71638. + }
  71639. +
  71640. + /* calculating full base address (64bit) */
  71641. + pPciAgent->pciBar[detectedBar].barBaseAddr =
  71642. + (MV_U64)pPciAgent->pciBar[detectedBar].barBaseHigh;
  71643. +
  71644. + pPciAgent->pciBar[detectedBar].barBaseAddr <<= 32;
  71645. +
  71646. + pPciAgent->pciBar[detectedBar].barBaseAddr |=
  71647. + (MV_U64)pPciAgent->pciBar[detectedBar].barBaseLow;
  71648. +
  71649. +
  71650. +
  71651. + /* get the sizes of the the bar */
  71652. +
  71653. + pPciAgent->pciBar[detectedBar].barSizeHigh=0;
  71654. +
  71655. + if ((PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType) &&
  71656. + (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping))
  71657. +
  71658. + {
  71659. + /* write oxffffffff to the bar to get the size */
  71660. + /* start with sizelow ( original value was saved in tmpBaseLow ) */
  71661. + mvPciIfConfigWrite(pciIf,
  71662. + bus,dev,func,
  71663. + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
  71664. + 0xffffffff);
  71665. +
  71666. + /* read size */
  71667. + pPciAgent->pciBar[detectedBar].barSizeLow =
  71668. + mvPciIfConfigRead(pciIf,
  71669. + bus,dev,func,
  71670. + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1));
  71671. +
  71672. +
  71673. +
  71674. + /* restore original value */
  71675. + mvPciIfConfigWrite(pciIf,
  71676. + bus,dev,func,
  71677. + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
  71678. + tmpBaseLow);
  71679. +
  71680. +
  71681. + /* now do the same for BaseHigh */
  71682. +
  71683. + /* write oxffffffff to the bar to get the size */
  71684. + mvPciIfConfigWrite(pciIf,
  71685. + bus,dev,func,
  71686. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  71687. + 0xffffffff);
  71688. +
  71689. + /* read size */
  71690. + pPciAgent->pciBar[detectedBar].barSizeHigh =
  71691. + mvPciIfConfigRead(pciIf,
  71692. + bus,dev,func,
  71693. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  71694. +
  71695. + /* restore original value */
  71696. + mvPciIfConfigWrite(pciIf,
  71697. + bus,dev,func,
  71698. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  71699. + tmpBaseHigh);
  71700. +
  71701. + if ((0 == pPciAgent->pciBar[detectedBar].barSizeLow)&&
  71702. + (0 == pPciAgent->pciBar[detectedBar].barSizeHigh))
  71703. + {
  71704. + /* this bar is not applicable for this device,
  71705. + ignore all previous settings and check the next bar*/
  71706. +
  71707. + /* we though this was a 64bit bar , and it seems this
  71708. + was wrong ! so decrement barIndex */
  71709. + barIndex--;
  71710. + continue;
  71711. + }
  71712. +
  71713. + /* calculate the full 64 bit size */
  71714. +
  71715. + if (0 != pPciAgent->pciBar[detectedBar].barSizeHigh)
  71716. + {
  71717. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
  71718. +
  71719. + pPciAgent->pciBar[detectedBar].barSizeLow =
  71720. + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
  71721. +
  71722. + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
  71723. +
  71724. + }
  71725. + else
  71726. + {
  71727. +
  71728. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
  71729. +
  71730. + pPciAgent->pciBar[detectedBar].barSizeLow =
  71731. + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
  71732. +
  71733. + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
  71734. +
  71735. + }
  71736. +
  71737. +
  71738. +
  71739. + }
  71740. + else /* 32bit bar */
  71741. + {
  71742. + /* write oxffffffff to the bar to get the size */
  71743. + mvPciIfConfigWrite(pciIf,
  71744. + bus,dev,func,
  71745. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  71746. + 0xffffffff);
  71747. +
  71748. + /* read size */
  71749. + pPciAgent->pciBar[detectedBar].barSizeLow =
  71750. + mvPciIfConfigRead(pciIf,
  71751. + bus,dev,func,
  71752. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  71753. +
  71754. + if (0 == pPciAgent->pciBar[detectedBar].barSizeLow)
  71755. + {
  71756. + /* this bar is not applicable for this device,
  71757. + ignore all previous settings and check the next bar*/
  71758. + continue;
  71759. + }
  71760. +
  71761. +
  71762. + /* restore original value */
  71763. + mvPciIfConfigWrite(pciIf,
  71764. + bus,dev,func,
  71765. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  71766. + tmpBaseLow);
  71767. +
  71768. + /* calculate size low */
  71769. +
  71770. + if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
  71771. + {
  71772. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
  71773. + }
  71774. + else
  71775. + {
  71776. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_IO_BASE_MASK;
  71777. + }
  71778. +
  71779. + pPciAgent->pciBar[detectedBar].barSizeLow =
  71780. + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
  71781. +
  71782. + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
  71783. + pPciAgent->pciBar[detectedBar].barSize =
  71784. + (MV_U64)pPciAgent->pciBar[detectedBar].barSizeLow;
  71785. +
  71786. +
  71787. + }
  71788. +
  71789. + /* we are here ! this means we have already detected a bar for
  71790. + this device , now move on */
  71791. +
  71792. + detectedBar++;
  71793. + pPciAgent->barsNum++;
  71794. + }
  71795. +
  71796. + return detectedBar;
  71797. +}
  71798. +
  71799. +
  71800. +/*******************************************************************************
  71801. +* mvPciClassNameGet - get PCI class name
  71802. +*
  71803. +* DESCRIPTION:
  71804. +* This function returns the PCI class name
  71805. +*
  71806. +* INPUT:
  71807. +* baseClassCode - Base Class Code.
  71808. +*
  71809. +* OUTPUT:
  71810. +* pType - the class name
  71811. +*
  71812. +* RETURN:
  71813. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  71814. +*
  71815. +*******************************************************************************/
  71816. +MV_STATUS mvPciClassNameGet(MV_U32 baseClassCode, MV_8 *pType)
  71817. +{
  71818. +
  71819. + switch(baseClassCode)
  71820. + {
  71821. + case 0x0:
  71822. + strcpy(pType,"Old generation device");
  71823. + break;
  71824. + case 0x1:
  71825. + strcpy(pType,"Mass storage controller");
  71826. + break;
  71827. + case 0x2:
  71828. + strcpy(pType,"Network controller");
  71829. + break;
  71830. + case 0x3:
  71831. + strcpy(pType,"Display controller");
  71832. + break;
  71833. + case 0x4:
  71834. + strcpy(pType,"Multimedia device");
  71835. + break;
  71836. + case 0x5:
  71837. + strcpy(pType,"Memory controller");
  71838. + break;
  71839. + case 0x6:
  71840. + strcpy(pType,"Bridge Device");
  71841. + break;
  71842. + case 0x7:
  71843. + strcpy(pType,"Simple Communication controllers");
  71844. + break;
  71845. + case 0x8:
  71846. + strcpy(pType,"Base system peripherals");
  71847. + break;
  71848. + case 0x9:
  71849. + strcpy(pType,"Input Devices");
  71850. + break;
  71851. + case 0xa:
  71852. + strcpy(pType,"Docking stations");
  71853. + break;
  71854. + case 0xb:
  71855. + strcpy(pType,"Processors");
  71856. + break;
  71857. + case 0xc:
  71858. + strcpy(pType,"Serial bus controllers");
  71859. + break;
  71860. + case 0xd:
  71861. + strcpy(pType,"Wireless controllers");
  71862. + break;
  71863. + case 0xe:
  71864. + strcpy(pType,"Intelligent I/O controllers");
  71865. + break;
  71866. + case 0xf:
  71867. + strcpy(pType,"Satellite communication controllers");
  71868. + break;
  71869. + case 0x10:
  71870. + strcpy(pType,"Encryption/Decryption controllers");
  71871. + break;
  71872. + case 0x11:
  71873. + strcpy(pType,"Data acquisition and signal processing controllers");
  71874. + break;
  71875. + default:
  71876. + strcpy(pType,"Unknown device");
  71877. + break;
  71878. + }
  71879. +
  71880. + return MV_OK;
  71881. +
  71882. +}
  71883. +
  71884. +
  71885. +
  71886. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h
  71887. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h 1970-01-01 01:00:00.000000000 +0100
  71888. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h 2011-07-31 11:32:01.073415309 +0200
  71889. @@ -0,0 +1,323 @@
  71890. +/*******************************************************************************
  71891. +Copyright (C) Marvell International Ltd. and its affiliates
  71892. +
  71893. +This software file (the "File") is owned and distributed by Marvell
  71894. +International Ltd. and/or its affiliates ("Marvell") under the following
  71895. +alternative licensing terms. Once you have made an election to distribute the
  71896. +File under one of the following license alternatives, please (i) delete this
  71897. +introductory statement regarding license alternatives, (ii) delete the two
  71898. +license alternatives that you have not elected to use and (iii) preserve the
  71899. +Marvell copyright notice above.
  71900. +
  71901. +********************************************************************************
  71902. +Marvell Commercial License Option
  71903. +
  71904. +If you received this File from Marvell and you have entered into a commercial
  71905. +license agreement (a "Commercial License") with Marvell, the File is licensed
  71906. +to you under the terms of the applicable Commercial License.
  71907. +
  71908. +********************************************************************************
  71909. +Marvell GPL License Option
  71910. +
  71911. +If you received this File from Marvell, you may opt to use, redistribute and/or
  71912. +modify this File in accordance with the terms and conditions of the General
  71913. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  71914. +available along with the File in the license.txt file or by writing to the Free
  71915. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  71916. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  71917. +
  71918. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  71919. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  71920. +DISCLAIMED. The GPL License provides additional details about this warranty
  71921. +disclaimer.
  71922. +********************************************************************************
  71923. +Marvell BSD License Option
  71924. +
  71925. +If you received this File from Marvell, you may opt to use, redistribute and/or
  71926. +modify this File under the following licensing terms.
  71927. +Redistribution and use in source and binary forms, with or without modification,
  71928. +are permitted provided that the following conditions are met:
  71929. +
  71930. + * Redistributions of source code must retain the above copyright notice,
  71931. + this list of conditions and the following disclaimer.
  71932. +
  71933. + * Redistributions in binary form must reproduce the above copyright
  71934. + notice, this list of conditions and the following disclaimer in the
  71935. + documentation and/or other materials provided with the distribution.
  71936. +
  71937. + * Neither the name of Marvell nor the names of its contributors may be
  71938. + used to endorse or promote products derived from this software without
  71939. + specific prior written permission.
  71940. +
  71941. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  71942. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  71943. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  71944. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  71945. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  71946. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  71947. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  71948. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  71949. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  71950. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  71951. +
  71952. +*******************************************************************************/
  71953. +
  71954. +#ifndef __INCmvPciUtilsh
  71955. +#define __INCmvPciUtilsh
  71956. +
  71957. +/*
  71958. +This module only support scanning of Header type 00h of pci devices
  71959. +There is no suppotr for Header type 01h of pci devices ( PCI bridges )
  71960. +*/
  71961. +
  71962. +/* includes */
  71963. +#include "mvSysHwConfig.h"
  71964. +#include "pci-if/mvPciIf.h"
  71965. +#include "pci/mvPciRegs.h"
  71966. +
  71967. +
  71968. +
  71969. +/* PCI base address low bar mask */
  71970. +#define PCI_ERROR_CODE 0xffffffff
  71971. +
  71972. +#define PCI_BRIDGE_CLASS 0x6
  71973. +#define P2P_BRIDGE_SUB_CLASS_CODE 0x4
  71974. +
  71975. +
  71976. +#define P2P_BUSSES_NUM 0x18
  71977. +#define P2P_IO_BASE_LIMIT_SEC_STATUS 0x1C
  71978. +#define P2P_MEM_BASE_LIMIT 0x20
  71979. +#define P2P_PREF_MEM_BASE_LIMIT 0x24
  71980. +#define P2P_PREF_BASE_UPPER_32 0x28
  71981. +#define P2P_PREF_LIMIT_UPPER_32 0x2C
  71982. +#define P2P_IO_BASE_LIMIT_UPPER_16 0x30
  71983. +#define P2P_EXP_ROM 0x38
  71984. +
  71985. +/* P2P_BUSSES_NUM (PBM) */
  71986. +
  71987. +#define PBM_PRIME_BUS_NUM_OFFS 0
  71988. +#define PBM_PRIME_BUS_NUM_MASK (0xff << PBM_PRIME_BUS_NUM_OFFS)
  71989. +
  71990. +#define PBM_SEC_BUS_NUM_OFFS 8
  71991. +#define PBM_SEC_BUS_NUM_MASK (0xff << PBM_SEC_BUS_NUM_OFFS)
  71992. +
  71993. +#define PBM_SUB_BUS_NUM_OFFS 16
  71994. +#define PBM_SUB_BUS_NUM_MASK (0xff << PBM_SUB_BUS_NUM_OFFS)
  71995. +
  71996. +#define PBM_SEC_LAT_TMR_OFFS 24
  71997. +#define PBM_SEC_LAT_TMR_MASK (0xff << PBM_SEC_LAT_TMR_OFFS)
  71998. +
  71999. +/* P2P_IO_BASE_LIMIT_SEC_STATUS (PIBLSS) */
  72000. +
  72001. +#define PIBLSS_IO_BASE_OFFS 0
  72002. +#define PIBLSS_IO_BASE_MASK (0xff << PIBLSS_IO_BASE_OFFS)
  72003. +
  72004. +#define PIBLSS_ADD_CAP_OFFS 0
  72005. +#define PIBLSS_ADD_CAP_MASK (0x3 << PIBLSS_ADD_CAP_OFFS)
  72006. +#define PIBLSS_ADD_CAP_16BIT (0x0 << PIBLSS_ADD_CAP_OFFS)
  72007. +#define PIBLSS_ADD_CAP_32BIT (0x1 << PIBLSS_ADD_CAP_OFFS)
  72008. +
  72009. +#define PIBLSS_LOW_ADDR_OFFS 0
  72010. +#define PIBLSS_LOW_ADDR_MASK (0xFFF << PIBLSS_LOW_ADDR_OFFS)
  72011. +
  72012. +#define PIBLSS_HIGH_ADDR_OFFS 12
  72013. +#define PIBLSS_HIGH_ADDR_MASK (0xF << PIBLSS_HIGH_ADDR_OFFS)
  72014. +
  72015. +#define PIBLSS_IO_LIMIT_OFFS 8
  72016. +#define PIBLSS_IO_LIMIT_MASK (0xff << PIBLSS_IO_LIMIT_OFFS)
  72017. +
  72018. +#define PIBLSS_SEC_STATUS_OFFS 16
  72019. +#define PIBLSS_SEC_STATUS_MASK (0xffff << PIBLSS_SEC_STATUS_OFFS)
  72020. +
  72021. +
  72022. +/* P2P_MEM_BASE_LIMIT (PMBL)*/
  72023. +
  72024. +#define PMBL_MEM_BASE_OFFS 0
  72025. +#define PMBL_MEM_BASE_MASK (0xffff << PMBL_MEM_BASE_OFFS)
  72026. +
  72027. +#define PMBL_MEM_LIMIT_OFFS 16
  72028. +#define PMBL_MEM_LIMIT_MASK (0xffff << PMBL_MEM_LIMIT_OFFS)
  72029. +
  72030. +
  72031. +#define PMBL_LOW_ADDR_OFFS 0
  72032. +#define PMBL_LOW_ADDR_MASK (0xFFFFF << PMBL_LOW_ADDR_OFFS)
  72033. +
  72034. +#define PMBL_HIGH_ADDR_OFFS 20
  72035. +#define PMBL_HIGH_ADDR_MASK (0xFFF << PMBL_HIGH_ADDR_OFFS)
  72036. +
  72037. +
  72038. +/* P2P_PREF_MEM_BASE_LIMIT (PRMBL) */
  72039. +
  72040. +#define PRMBL_PREF_MEM_BASE_OFFS 0
  72041. +#define PRMBL_PREF_MEM_BASE_MASK (0xffff << PRMBL_PREF_MEM_BASE_OFFS)
  72042. +
  72043. +#define PRMBL_PREF_MEM_LIMIT_OFFS 16
  72044. +#define PRMBL_PREF_MEM_LIMIT_MASK (0xffff<<PRMBL_PREF_MEM_LIMIT_OFFS)
  72045. +
  72046. +#define PRMBL_LOW_ADDR_OFFS 0
  72047. +#define PRMBL_LOW_ADDR_MASK (0xFFFFF << PRMBL_LOW_ADDR_OFFS)
  72048. +
  72049. +#define PRMBL_HIGH_ADDR_OFFS 20
  72050. +#define PRMBL_HIGH_ADDR_MASK (0xFFF << PRMBL_HIGH_ADDR_OFFS)
  72051. +
  72052. +#define PRMBL_ADD_CAP_OFFS 0
  72053. +#define PRMBL_ADD_CAP_MASK (0xf << PRMBL_ADD_CAP_OFFS)
  72054. +#define PRMBL_ADD_CAP_32BIT (0x0 << PRMBL_ADD_CAP_OFFS)
  72055. +#define PRMBL_ADD_CAP_64BIT (0x1 << PRMBL_ADD_CAP_OFFS)
  72056. +
  72057. +/* P2P_IO_BASE_LIMIT_UPPER_16 (PIBLU) */
  72058. +
  72059. +#define PRBU_IO_UPP_BASE_OFFS 0
  72060. +#define PRBU_IO_UPP_BASE_MASK (0xffff << PRBU_IO_UPP_BASE_OFFS)
  72061. +
  72062. +#define PRBU_IO_UPP_LIMIT_OFFS 16
  72063. +#define PRBU_IO_UPP_LIMIT_MASK (0xffff << PRBU_IO_UPP_LIMIT_OFFS)
  72064. +
  72065. +
  72066. +/* typedefs */
  72067. +
  72068. +typedef enum _mvPciBarMapping
  72069. +{
  72070. + PCI_MEMORY_BAR,
  72071. + PCI_IO_BAR,
  72072. + PCI_NO_MAPPING
  72073. +}MV_PCI_BAR_MAPPING;
  72074. +
  72075. +typedef enum _mvPciBarType
  72076. +{
  72077. + PCI_32BIT_BAR,
  72078. + PCI_64BIT_BAR
  72079. +}MV_PCI_BAR_TYPE;
  72080. +
  72081. +typedef enum _mvPciIntPin
  72082. +{
  72083. + MV_PCI_INTA = 1,
  72084. + MV_PCI_INTB = 2,
  72085. + MV_PCI_INTC = 3,
  72086. + MV_PCI_INTD = 4
  72087. +}MV_PCI_INT_PIN;
  72088. +
  72089. +typedef enum _mvPciHeader
  72090. +{
  72091. + MV_PCI_STANDARD,
  72092. + MV_PCI_PCI2PCI_BRIDGE
  72093. +
  72094. +}MV_PCI_HEADER;
  72095. +
  72096. +
  72097. +/* BAR structure */
  72098. +typedef struct _pciBar
  72099. +{
  72100. + MV_U32 barOffset;
  72101. + MV_U32 barBaseLow;
  72102. + MV_U32 barBaseHigh;
  72103. + MV_U32 barSizeLow;
  72104. + MV_U32 barSizeHigh;
  72105. + /* The 'barBaseAddr' is a 64-bit variable
  72106. + that will contain the TOTAL base address
  72107. + value achived by combining both the 'barBaseLow'
  72108. + and the 'barBaseHigh' parameters as follows:
  72109. +
  72110. + BIT: 63 31 0
  72111. + | | |
  72112. + barBaseHigh barBaseLow */
  72113. + MV_U64 barBaseAddr;
  72114. + /* The 'barSize' is a 64-bit variable
  72115. + that will contain the TOTAL size achived
  72116. + by combining both the 'barSizeLow' and
  72117. + the 'barSizeHigh' parameters as follows:
  72118. +
  72119. + BIT: 63 31 0
  72120. + | | |
  72121. + barSizeHigh barSizeLow
  72122. +
  72123. + NOTE: The total size described above
  72124. + is AFTER the size calculation as
  72125. + described in PCI spec rev2.2 */
  72126. + MV_U64 barSize;
  72127. + MV_BOOL isPrefetchable;
  72128. + MV_PCI_BAR_TYPE barType;
  72129. + MV_PCI_BAR_MAPPING barMapping;
  72130. +
  72131. +
  72132. +} PCI_BAR;
  72133. +
  72134. +/* Device information structure */
  72135. +typedef struct _mvPciDevice
  72136. +{
  72137. + /* Device specific information */
  72138. + MV_U32 busNumber; /* Pci agent bus number */
  72139. + MV_U32 deviceNum; /* Pci agent device number */
  72140. + MV_U32 function; /* Pci agent function number */
  72141. +
  72142. + MV_U32 venID; /* Pci agent Vendor ID */
  72143. + MV_U32 deviceID; /* Pci agent Device ID */
  72144. +
  72145. + MV_BOOL isFastB2BCapable; /* Capability of Fast Back to Back
  72146. + transactions */
  72147. + MV_BOOL isCapListSupport; /* Support of Capability list */
  72148. + MV_BOOL is66MHZCapable; /* 66MHZ support */
  72149. +
  72150. + MV_U32 baseClassCode; /* Pci agent base Class Code */
  72151. + MV_U32 subClassCode; /* Pci agent sub Class Code */
  72152. + MV_U32 progIf; /* Pci agent Programing interface */
  72153. + MV_U32 revisionID;
  72154. +
  72155. + PCI_BAR pciBar[6]; /* Pci agent bar list */
  72156. +
  72157. + MV_U32 p2pPrimBusNum; /* P2P Primary Bus number*/
  72158. + MV_U32 p2pSecBusNum; /* P2P Secondary Bus Number*/
  72159. + MV_U32 p2pSubBusNum; /* P2P Subordinate bus Number */
  72160. + MV_U32 p2pSecLatencyTimer; /* P2P Econdary Latency Timer*/
  72161. + MV_U32 p2pIObase; /* P2P IO Base */
  72162. + MV_U32 p2pIOLimit; /* P2P IO Linit */
  72163. + MV_BOOL bIO32;
  72164. + MV_U32 p2pSecStatus; /* P2P Secondary Status */
  72165. + MV_U32 p2pMemBase; /* P2P Memory Space */
  72166. + MV_U32 p2pMemLimit; /* P2P Memory Limit*/
  72167. + MV_U32 p2pPrefMemBase; /* P2P Prefetchable Mem Base*/
  72168. + MV_U32 p2pPrefMemLimit; /* P2P Prefetchable Memory Limit*/
  72169. + MV_BOOL bPrefMem64;
  72170. + MV_U32 p2pPrefBaseUpper32Bits;/* P2P Prefetchable upper 32 bits*/
  72171. + MV_U32 p2pPrefLimitUpper32Bits;/* P2P prefetchable limit upper 32*/
  72172. +
  72173. +
  72174. + MV_U32 pciCacheLine; /* Pci agent cache line */
  72175. + MV_U32 pciLatencyTimer; /* Pci agent Latency timer */
  72176. + MV_PCI_HEADER pciHeader; /* Pci agent header type*/
  72177. + MV_BOOL isMultiFunction; /* Multi function support */
  72178. + MV_BOOL isBISTCapable; /* Self test capable */
  72179. +
  72180. + MV_U32 subSysID; /* Sub System ID */
  72181. + MV_U32 subSysVenID; /* Sub System Vendor ID */
  72182. +
  72183. + MV_BOOL isExpRom; /* Expantion Rom support */
  72184. + MV_U32 expRomAddr; /* Expantion Rom pointer */
  72185. +
  72186. + MV_U32 capListPointer; /* Capability list pointer */
  72187. +
  72188. + MV_U32 irqLine; /* IRQ line */
  72189. + MV_PCI_INT_PIN intPin; /* Interrupt pin */
  72190. + MV_U32 minGrant; /* Minimum grant*/
  72191. + MV_U32 maxLatency; /* Maximum latency*/
  72192. +
  72193. + MV_U32 funtionsNum; /* pci agent total functions number */
  72194. +
  72195. + MV_U32 barsNum;
  72196. + MV_U8 type[60]; /* class name of the pci agent */
  72197. +
  72198. +
  72199. +} MV_PCI_DEVICE;
  72200. +
  72201. +/* PCI gloabl functions */
  72202. +MV_STATUS mvPciClassNameGet(MV_U32 classCode, MV_8 *pType);
  72203. +
  72204. +
  72205. +/* Performs a full scan on both PCIs and returns all possible details on the
  72206. + agents found on the bus. */
  72207. +MV_STATUS mvPciScan(MV_U32 pciIf,
  72208. + MV_PCI_DEVICE *pPciAgents,
  72209. + MV_U32 *pPciAgentsNum);
  72210. +
  72211. +
  72212. +#endif /* #ifndef __INCmvPciUtilsh */
  72213. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c
  72214. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c 1970-01-01 01:00:00.000000000 +0100
  72215. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c 2011-07-31 11:32:01.113957654 +0200
  72216. @@ -0,0 +1,1143 @@
  72217. +/*******************************************************************************
  72218. +Copyright (C) Marvell International Ltd. and its affiliates
  72219. +
  72220. +This software file (the "File") is owned and distributed by Marvell
  72221. +International Ltd. and/or its affiliates ("Marvell") under the following
  72222. +alternative licensing terms. Once you have made an election to distribute the
  72223. +File under one of the following license alternatives, please (i) delete this
  72224. +introductory statement regarding license alternatives, (ii) delete the two
  72225. +license alternatives that you have not elected to use and (iii) preserve the
  72226. +Marvell copyright notice above.
  72227. +
  72228. +********************************************************************************
  72229. +Marvell Commercial License Option
  72230. +
  72231. +If you received this File from Marvell and you have entered into a commercial
  72232. +license agreement (a "Commercial License") with Marvell, the File is licensed
  72233. +to you under the terms of the applicable Commercial License.
  72234. +
  72235. +********************************************************************************
  72236. +Marvell GPL License Option
  72237. +
  72238. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72239. +modify this File in accordance with the terms and conditions of the General
  72240. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  72241. +available along with the File in the license.txt file or by writing to the Free
  72242. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  72243. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  72244. +
  72245. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  72246. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  72247. +DISCLAIMED. The GPL License provides additional details about this warranty
  72248. +disclaimer.
  72249. +********************************************************************************
  72250. +Marvell BSD License Option
  72251. +
  72252. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72253. +modify this File under the following licensing terms.
  72254. +Redistribution and use in source and binary forms, with or without modification,
  72255. +are permitted provided that the following conditions are met:
  72256. +
  72257. + * Redistributions of source code must retain the above copyright notice,
  72258. + this list of conditions and the following disclaimer.
  72259. +
  72260. + * Redistributions in binary form must reproduce the above copyright
  72261. + notice, this list of conditions and the following disclaimer in the
  72262. + documentation and/or other materials provided with the distribution.
  72263. +
  72264. + * Neither the name of Marvell nor the names of its contributors may be
  72265. + used to endorse or promote products derived from this software without
  72266. + specific prior written permission.
  72267. +
  72268. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  72269. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  72270. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  72271. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  72272. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  72273. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  72274. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  72275. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  72276. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  72277. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  72278. +
  72279. +*******************************************************************************/
  72280. +
  72281. +#include "pex/mvPex.h"
  72282. +
  72283. +#include "ctrlEnv/mvCtrlEnvLib.h"
  72284. +
  72285. +/* defines */
  72286. +#ifdef MV_DEBUG
  72287. +#define DB(x) x
  72288. +#else
  72289. +#define DB(x)
  72290. +#endif
  72291. +
  72292. +MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
  72293. +{
  72294. + MV_PEX_MODE pexMode;
  72295. + MV_U32 regVal;
  72296. + MV_U32 status;
  72297. +
  72298. + /* First implement Guideline (GL# PCI Express-2) Wrong Default Value */
  72299. + /* to Transmitter Output Current (TXAMP) Relevant for: 88F5181-A1/B0/B1 */
  72300. + /* and 88F5281-B0 and above, 88F5182, 88F5082, 88F5181L, 88F6082/L */
  72301. +
  72302. + if ((mvCtrlModelGet() != MV_1281_DEV_ID) &&
  72303. + (mvCtrlModelGet() != MV_6281_DEV_ID) &&
  72304. + (mvCtrlModelGet() != MV_6192_DEV_ID) &&
  72305. + (mvCtrlModelGet() != MV_6190_DEV_ID) &&
  72306. + (mvCtrlModelGet() != MV_6180_DEV_ID) &&
  72307. + (mvCtrlModelGet() != MV_6183_DEV_ID) &&
  72308. + (mvCtrlModelGet() != MV_6183L_DEV_ID) &&
  72309. + (mvCtrlModelGet() != MV_78100_DEV_ID) &&
  72310. + (mvCtrlModelGet() != MV_78200_DEV_ID) &&
  72311. + (mvCtrlModelGet() != MV_76100_DEV_ID) &&
  72312. + (mvCtrlModelGet() != MV_78XX0_DEV_ID))
  72313. + {
  72314. +
  72315. + /* Read current value of TXAMP */
  72316. + MV_REG_WRITE(0x41b00, 0x80820000); /* Write the read command */
  72317. +
  72318. + regVal = MV_REG_READ(0x41b00); /* Extract the data */
  72319. +
  72320. + /* Prepare new data for write */
  72321. + regVal &= ~0x7; /* Clear bits [2:0] */
  72322. + regVal |= 0x4; /* Set the new value */
  72323. + regVal &= ~0x80000000; /* Set "write" command */
  72324. + MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
  72325. +
  72326. + }
  72327. + else
  72328. + {
  72329. + /* Implement 1.0V termination GL for 88F1281 device only */
  72330. + /* BIT0 - Common mode feedback */
  72331. + /* BIT3 - TxBuf, extra drive for 1.0V termination */
  72332. + if (mvCtrlModelGet() == MV_1281_DEV_ID)
  72333. + {
  72334. + MV_REG_WRITE(0x41b00, 0x80860000); /* Write the read command */
  72335. + regVal = MV_REG_READ(0x41b00); /* Extract the data */
  72336. + regVal |= (BIT0 | BIT3);
  72337. + regVal &= ~0x80000000; /* Set "write" command */
  72338. + MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
  72339. +
  72340. + MV_REG_WRITE(0x31b00, 0x80860000); /* Write the read command */
  72341. + regVal = MV_REG_READ(0x31b00); /* Extract the data */
  72342. + regVal |= (BIT0 | BIT3);
  72343. + regVal &= ~0x80000000; /* Set "write" command */
  72344. + MV_REG_WRITE(0x31b00, regVal); /* Write the write command */
  72345. + }
  72346. + }
  72347. +
  72348. + if( mvPexModeGet(pexIf, &pexMode) != MV_OK)
  72349. + {
  72350. + mvOsPrintf("PEX init ERR. mvPexModeGet failed (pexType=%d)\n",pexMode.pexType);
  72351. + return MV_ERROR;
  72352. + }
  72353. +
  72354. + /* Check that required PEX type is the one set in reset time */
  72355. + if (pexType != pexMode.pexType)
  72356. + {
  72357. + /* No Link. Shut down the Phy */
  72358. + mvPexPowerDown(pexIf);
  72359. + mvOsPrintf("PEX init ERR. PEX type sampled mismatch (%d,%d)\n",pexType,pexMode.pexType);
  72360. + return MV_ERROR;
  72361. + }
  72362. +
  72363. + if (MV_PEX_ROOT_COMPLEX == pexType)
  72364. + {
  72365. + mvPexLocalBusNumSet(pexIf, PEX_HOST_BUS_NUM(pexIf));
  72366. + mvPexLocalDevNumSet(pexIf, PEX_HOST_DEV_NUM(pexIf));
  72367. +
  72368. + /* Local device master Enable */
  72369. + mvPexMasterEnable(pexIf, MV_TRUE);
  72370. +
  72371. + /* Local device slave Enable */
  72372. + mvPexSlaveEnable(pexIf, mvPexLocalBusNumGet(pexIf),
  72373. + mvPexLocalDevNumGet(pexIf), MV_TRUE);
  72374. + /* Interrupt disable */
  72375. + status = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND));
  72376. + status |= PXSAC_INT_DIS;
  72377. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND), status);
  72378. + }
  72379. +
  72380. + /* now wait 500 ms to be sure the link is valid (spec compliant) */
  72381. + mvOsDelay(500);
  72382. + /* Check if we have link */
  72383. + if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
  72384. + {
  72385. + mvOsPrintf("PEX%d interface detected no Link.\n",pexIf);
  72386. + return MV_NO_SUCH;
  72387. + }
  72388. +
  72389. + if (MV_PEX_WITDH_X1 == pexMode.pexWidth)
  72390. + {
  72391. + mvOsPrintf("PEX%d interface detected Link X1\n",pexIf);
  72392. + }
  72393. + else
  72394. + {
  72395. + mvOsPrintf("PEX%d interface detected Link X4\n",pexIf);
  72396. + }
  72397. +
  72398. +#ifdef PCIE_VIRTUAL_BRIDGE_SUPPORT
  72399. + mvPexVrtBrgInit(pexIf);
  72400. +#endif
  72401. + return MV_OK;
  72402. +}
  72403. +
  72404. +/*******************************************************************************
  72405. +* mvPexModeGet - Get Pex Mode
  72406. +*
  72407. +* DESCRIPTION:
  72408. +*
  72409. +* INPUT:
  72410. +* pexIf - PEX interface number.
  72411. +*
  72412. +* OUTPUT:
  72413. +* pexMode - Pex mode structure
  72414. +*
  72415. +* RETURN:
  72416. +* MV_OK on success , MV_ERROR otherwise
  72417. +*
  72418. +*******************************************************************************/
  72419. +MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode)
  72420. +{
  72421. + MV_U32 pexData;
  72422. +
  72423. + /* Parameter checking */
  72424. + if (PEX_DEFAULT_IF != pexIf)
  72425. + {
  72426. + if (pexIf >= mvCtrlPexMaxIfGet())
  72427. + {
  72428. + mvOsPrintf("mvPexModeGet: ERR. Invalid PEX interface %d\n",pexIf);
  72429. + return MV_ERROR;
  72430. + }
  72431. + }
  72432. +
  72433. + pexData = MV_REG_READ(PEX_CTRL_REG(pexIf));
  72434. +
  72435. + switch (pexData & PXCR_DEV_TYPE_CTRL_MASK)
  72436. + {
  72437. + case PXCR_DEV_TYPE_CTRL_CMPLX:
  72438. + pexMode->pexType = MV_PEX_ROOT_COMPLEX;
  72439. + break;
  72440. + case PXCR_DEV_TYPE_CTRL_POINT:
  72441. + pexMode->pexType = MV_PEX_END_POINT;
  72442. + break;
  72443. +
  72444. + }
  72445. +
  72446. + /* Check if we have link */
  72447. + if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
  72448. + {
  72449. + pexMode->pexLinkUp = MV_FALSE;
  72450. +
  72451. + /* If there is no link, the auto negotiation data is worthless */
  72452. + pexMode->pexWidth = MV_PEX_WITDH_INVALID;
  72453. + }
  72454. + else
  72455. + {
  72456. + pexMode->pexLinkUp = MV_TRUE;
  72457. +
  72458. + /* We have link. The link width is now valid */
  72459. + pexData = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG));
  72460. + pexMode->pexWidth = ((pexData & PXLCSR_NEG_LNK_WDTH_MASK) >>
  72461. + PXLCSR_NEG_LNK_WDTH_OFFS);
  72462. + }
  72463. +
  72464. + return MV_OK;
  72465. +}
  72466. +
  72467. +
  72468. +/* PEX configuration space read write */
  72469. +
  72470. +/*******************************************************************************
  72471. +* mvPexConfigRead - Read from configuration space
  72472. +*
  72473. +* DESCRIPTION:
  72474. +* This function performs a 32 bit read from PEX configuration space.
  72475. +* It supports both type 0 and type 1 of Configuration Transactions
  72476. +* (local and over bridge). In order to read from local bus segment, use
  72477. +* bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
  72478. +* will result configuration transaction of type 1 (over bridge).
  72479. +*
  72480. +* INPUT:
  72481. +* pexIf - PEX interface number.
  72482. +* bus - PEX segment bus number.
  72483. +* dev - PEX device number.
  72484. +* func - Function number.
  72485. +* regOffs - Register offset.
  72486. +*
  72487. +* OUTPUT:
  72488. +* None.
  72489. +*
  72490. +* RETURN:
  72491. +* 32bit register data, 0xffffffff on error
  72492. +*
  72493. +*******************************************************************************/
  72494. +MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  72495. + MV_U32 regOff)
  72496. +{
  72497. +#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
  72498. + return mvPexVrtBrgConfigRead (pexIf, bus, dev, func, regOff);
  72499. +}
  72500. +
  72501. +MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  72502. + MV_U32 regOff)
  72503. +{
  72504. +#endif
  72505. + MV_U32 pexData = 0;
  72506. + MV_U32 localDev,localBus;
  72507. +
  72508. + /* Parameter checking */
  72509. + if (PEX_DEFAULT_IF != pexIf)
  72510. + {
  72511. + if (pexIf >= mvCtrlPexMaxIfGet())
  72512. + {
  72513. + mvOsPrintf("mvPexConfigRead: ERR. Invalid PEX interface %d\n",pexIf);
  72514. + return 0xFFFFFFFF;
  72515. + }
  72516. + }
  72517. +
  72518. + if (dev >= MAX_PEX_DEVICES)
  72519. + {
  72520. + DB(mvOsPrintf("mvPexConfigRead: ERR. device number illigal %d\n", dev));
  72521. + return 0xFFFFFFFF;
  72522. + }
  72523. +
  72524. + if (func >= MAX_PEX_FUNCS)
  72525. + {
  72526. + DB(mvOsPrintf("mvPexConfigRead: ERR. function num illigal %d\n", func));
  72527. + return 0xFFFFFFFF;
  72528. + }
  72529. +
  72530. + if (bus >= MAX_PEX_BUSSES)
  72531. + {
  72532. + DB(mvOsPrintf("mvPexConfigRead: ERR. bus number illigal %d\n", bus));
  72533. + return MV_ERROR;
  72534. + }
  72535. +
  72536. + DB(mvOsPrintf("mvPexConfigRead: pexIf %d, bus %d, dev %d, func %d, regOff 0x%x\n",
  72537. + pexIf, bus, dev, func, regOff));
  72538. +
  72539. + localDev = mvPexLocalDevNumGet(pexIf);
  72540. + localBus = mvPexLocalBusNumGet(pexIf);
  72541. +
  72542. + /* Speed up the process. In case on no link, return MV_ERROR */
  72543. + if ((dev != localDev) || (bus != localBus))
  72544. + {
  72545. + pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
  72546. +
  72547. + if ((pexData & PXSR_DL_DOWN))
  72548. + {
  72549. + return MV_ERROR;
  72550. + }
  72551. + }
  72552. +
  72553. + /* in PCI Express we have only one device number */
  72554. + /* and this number is the first number we encounter
  72555. + else that the localDev*/
  72556. + /* spec pex define return on config read/write on any device */
  72557. + if (bus == localBus)
  72558. + {
  72559. + if (localDev == 0)
  72560. + {
  72561. + /* if local dev is 0 then the first number we encounter
  72562. + after 0 is 1 */
  72563. + if ((dev != 1)&&(dev != localDev))
  72564. + {
  72565. + return MV_ERROR;
  72566. + }
  72567. + }
  72568. + else
  72569. + {
  72570. + /* if local dev is not 0 then the first number we encounter
  72571. + is 0 */
  72572. +
  72573. + if ((dev != 0)&&(dev != localDev))
  72574. + {
  72575. + return MV_ERROR;
  72576. + }
  72577. + }
  72578. + if(func != 0 ) /* i.e bridge */
  72579. + {
  72580. + return MV_ERROR;
  72581. + }
  72582. + }
  72583. +
  72584. +
  72585. + /* Creating PEX address to be passed */
  72586. + pexData = (bus << PXCAR_BUS_NUM_OFFS);
  72587. + pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
  72588. + pexData |= (func << PXCAR_FUNC_NUM_OFFS);
  72589. + pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
  72590. + /* extended register space */
  72591. + pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
  72592. + PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
  72593. +
  72594. + pexData |= PXCAR_CONFIG_EN;
  72595. +
  72596. + /* Write the address to the PEX configuration address register */
  72597. + MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
  72598. +
  72599. + DB(mvOsPrintf("mvPexConfigRead:address pexData=%x ",pexData));
  72600. +
  72601. +
  72602. + /* In order to let the PEX controller absorbed the address of the read */
  72603. + /* transaction we perform a validity check that the address was written */
  72604. + if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
  72605. + {
  72606. + return MV_ERROR;
  72607. + }
  72608. +
  72609. + /* cleaning Master Abort */
  72610. + MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
  72611. + PXSAC_MABORT);
  72612. +#if 0
  72613. + /* Guideline (GL# PCI Express-1) Erroneous Read Data on Configuration */
  72614. + /* This guideline is relevant for all devices except of the following devices:
  72615. + 88F5281-BO and above, 88F5181L-A0 and above, 88F1281 A0 and above
  72616. + 88F6183 A0 and above, 88F6183L */
  72617. + if ( ( (dev != localDev) || (bus != localBus) ) &&
  72618. + (
  72619. + !(MV_5281_DEV_ID == mvCtrlModelGet())&&
  72620. + !((MV_5181_DEV_ID == mvCtrlModelGet())&& (mvCtrlRevGet() >= MV_5181L_A0_REV))&&
  72621. + !(MV_1281_DEV_ID == mvCtrlModelGet())&&
  72622. + !(MV_6183_DEV_ID == mvCtrlModelGet())&&
  72623. + !(MV_6183L_DEV_ID == mvCtrlModelGet())&&
  72624. + !(MV_6281_DEV_ID == mvCtrlModelGet())&&
  72625. + !(MV_6192_DEV_ID == mvCtrlModelGet())&&
  72626. + !(MV_6190_DEV_ID == mvCtrlModelGet())&&
  72627. + !(MV_6180_DEV_ID == mvCtrlModelGet())&&
  72628. + !(MV_78XX0_DEV_ID == mvCtrlModelGet())
  72629. + ))
  72630. + {
  72631. +
  72632. + /* PCI-Express configuration read work-around */
  72633. +
  72634. + /* we will use one of the Punit (AHBToMbus) windows to access the xbar
  72635. + and read the data from there */
  72636. + /*
  72637. + Need to configure the 2 free Punit (AHB to MBus bridge)
  72638. + address decoding windows:
  72639. + Configure the flash Window to handle Configuration space requests
  72640. + for PEX0/1:
  72641. + 1. write 0x7931/0x7941 to the flash window and the size,
  72642. + 79-xbar attr (pci cfg), 3/4-xbar target (pex0/1), 1-WinEn
  72643. + 2. write base to flash window
  72644. +
  72645. + Configuration transactions from the CPU should write/read the data
  72646. + to/from address of the form:
  72647. + addr[31:28] = 0x5 (for PEX0) or 0x6 (for PEX1)
  72648. + addr[27:24] = extended register number
  72649. + addr[23:16] = bus number
  72650. + addr[15:11] = device number
  72651. + addr[10:8] = function number
  72652. + addr[7:0] = register number
  72653. + */
  72654. +
  72655. + #include "ctrlEnv/sys/mvAhbToMbus.h"
  72656. + {
  72657. + MV_U32 winNum;
  72658. + MV_AHB_TO_MBUS_DEC_WIN originWin;
  72659. + MV_U32 pciAddr=0;
  72660. + MV_U32 remapLow=0,remapHigh=0;
  72661. +
  72662. + /*
  72663. + We will use DEV_CS2\Flash window for this workarround
  72664. + */
  72665. +
  72666. + winNum = mvAhbToMbusWinTargetGet(PEX_CONFIG_RW_WA_TARGET);
  72667. +
  72668. + /* save remap values if exist */
  72669. + if ((1 == winNum)||(0 == winNum))
  72670. + {
  72671. + remapLow = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum));
  72672. + remapHigh = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum));
  72673. +
  72674. + }
  72675. +
  72676. +
  72677. + /* save the original window values */
  72678. + mvAhbToMbusWinGet(winNum,&originWin);
  72679. +
  72680. + if (PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES)
  72681. + {
  72682. + /* set the window as xbar window */
  72683. + if (pexIf)
  72684. + {
  72685. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  72686. + (0x7931 | (((originWin.addrWin.size >> 16)-1) ) << 16));
  72687. + }
  72688. + else
  72689. + {
  72690. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  72691. + (0x7941 | (((originWin.addrWin.size >> 16)-1) ) << 16));
  72692. + }
  72693. +
  72694. + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
  72695. + originWin.addrWin.baseLow);
  72696. +
  72697. + /*pciAddr = originWin.addrWin.baseLow;*/
  72698. + pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(
  72699. + (MV_U32)originWin.addrWin.baseLow);
  72700. +
  72701. + }
  72702. + else
  72703. + {
  72704. + /* set the window as xbar window */
  72705. + if (pexIf)
  72706. + {
  72707. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  72708. + (0x7931 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
  72709. + }
  72710. + else
  72711. + {
  72712. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  72713. + (0x7941 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
  72714. + }
  72715. +
  72716. + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
  72717. + PEX_CONFIG_RW_WA_BASE);
  72718. +
  72719. + pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(PEX_CONFIG_RW_WA_BASE);
  72720. + }
  72721. +
  72722. +
  72723. + /* remap should be as base */
  72724. + if ((1 == winNum)||(0 == winNum))
  72725. + {
  72726. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),pciAddr);
  72727. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),0);
  72728. +
  72729. + }
  72730. +
  72731. + /* extended register space */
  72732. + pciAddr |= (bus << 16);
  72733. + pciAddr |= (dev << 11);
  72734. + pciAddr |= (func << 8);
  72735. + pciAddr |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
  72736. +
  72737. + pexData = *(MV_U32*)pciAddr;
  72738. + pexData = MV_32BIT_LE(pexData); /* Data always in LE */
  72739. +
  72740. + /* restore the original window values */
  72741. + mvAhbToMbusWinSet(winNum,&originWin);
  72742. +
  72743. + /* restore original remap values*/
  72744. + if ((1 == winNum)||(0 == winNum))
  72745. + {
  72746. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),remapLow);
  72747. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),remapHigh);
  72748. +
  72749. + }
  72750. + }
  72751. + }
  72752. + else
  72753. +#endif
  72754. + {
  72755. + /* Read the Data returned in the PEX Data register */
  72756. + pexData = MV_REG_READ(PEX_CFG_DATA_REG(pexIf));
  72757. +
  72758. + }
  72759. +
  72760. + DB(mvOsPrintf("mvPexConfigRead: got : %x \n",pexData));
  72761. +
  72762. + return pexData;
  72763. +
  72764. +}
  72765. +
  72766. +/*******************************************************************************
  72767. +* mvPexConfigWrite - Write to configuration space
  72768. +*
  72769. +* DESCRIPTION:
  72770. +* This function performs a 32 bit write to PEX configuration space.
  72771. +* It supports both type 0 and type 1 of Configuration Transactions
  72772. +* (local and over bridge). In order to write to local bus segment, use
  72773. +* bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
  72774. +* will result configuration transaction of type 1 (over bridge).
  72775. +*
  72776. +* INPUT:
  72777. +* pexIf - PEX interface number.
  72778. +* bus - PEX segment bus number.
  72779. +* dev - PEX device number.
  72780. +* func - Function number.
  72781. +* regOffs - Register offset.
  72782. +* data - 32bit data.
  72783. +*
  72784. +* OUTPUT:
  72785. +* None.
  72786. +*
  72787. +* RETURN:
  72788. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  72789. +*
  72790. +*******************************************************************************/
  72791. +MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  72792. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  72793. +{
  72794. +#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
  72795. + return mvPexVrtBrgConfigWrite (pexIf, bus, dev, func, regOff, data);
  72796. +}
  72797. +
  72798. +MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  72799. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  72800. +{
  72801. +#endif
  72802. + MV_U32 pexData = 0;
  72803. + MV_U32 localDev,localBus;
  72804. +
  72805. + /* Parameter checking */
  72806. + if (PEX_DEFAULT_IF != pexIf)
  72807. + {
  72808. + if (pexIf >= mvCtrlPexMaxIfGet())
  72809. + {
  72810. + mvOsPrintf("mvPexConfigWrite: ERR. Invalid PEX interface %d\n",
  72811. + pexIf);
  72812. + return MV_ERROR;
  72813. + }
  72814. + }
  72815. +
  72816. + if (dev >= MAX_PEX_DEVICES)
  72817. + {
  72818. + mvOsPrintf("mvPexConfigWrite: ERR. device number illigal %d\n",dev);
  72819. + return MV_BAD_PARAM;
  72820. + }
  72821. +
  72822. + if (func >= MAX_PEX_FUNCS)
  72823. + {
  72824. + mvOsPrintf("mvPexConfigWrite: ERR. function number illigal %d\n", func);
  72825. + return MV_ERROR;
  72826. + }
  72827. +
  72828. + if (bus >= MAX_PEX_BUSSES)
  72829. + {
  72830. + mvOsPrintf("mvPexConfigWrite: ERR. bus number illigal %d\n", bus);
  72831. + return MV_ERROR;
  72832. + }
  72833. +
  72834. +
  72835. +
  72836. + localDev = mvPexLocalDevNumGet(pexIf);
  72837. + localBus = mvPexLocalBusNumGet(pexIf);
  72838. +
  72839. +
  72840. + /* in PCI Express we have only one device number other than ourselves*/
  72841. + /* and this number is the first number we encounter
  72842. + else than the localDev that can be any valid dev number*/
  72843. + /* pex spec define return on config read/write on any device */
  72844. + if (bus == localBus)
  72845. + {
  72846. +
  72847. + if (localDev == 0)
  72848. + {
  72849. + /* if local dev is 0 then the first number we encounter
  72850. + after 0 is 1 */
  72851. + if ((dev != 1)&&(dev != localDev))
  72852. + {
  72853. + return MV_ERROR;
  72854. + }
  72855. +
  72856. + }
  72857. + else
  72858. + {
  72859. + /* if local dev is not 0 then the first number we encounter
  72860. + is 0 */
  72861. +
  72862. + if ((dev != 0)&&(dev != localDev))
  72863. + {
  72864. + return MV_ERROR;
  72865. + }
  72866. + }
  72867. +
  72868. +
  72869. + }
  72870. +
  72871. + /* if we are not accessing ourselves , then check the link */
  72872. + if ((dev != localDev) || (bus != localBus) )
  72873. + {
  72874. + /* workarround */
  72875. + /* when no link return MV_ERROR */
  72876. +
  72877. + pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
  72878. +
  72879. + if ((pexData & PXSR_DL_DOWN))
  72880. + {
  72881. + return MV_ERROR;
  72882. + }
  72883. +
  72884. + }
  72885. +
  72886. + pexData =0;
  72887. +
  72888. + /* Creating PEX address to be passed */
  72889. + pexData |= (bus << PXCAR_BUS_NUM_OFFS);
  72890. + pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
  72891. + pexData |= (func << PXCAR_FUNC_NUM_OFFS);
  72892. + pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
  72893. + /* extended register space */
  72894. + pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
  72895. + PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
  72896. + pexData |= PXCAR_CONFIG_EN;
  72897. +
  72898. + DB(mvOsPrintf("mvPexConfigWrite: If=%x bus=%x func=%x dev=%x regOff=%x data=%x \n",
  72899. + pexIf,bus,func,dev,regOff,data,pexData) );
  72900. +
  72901. + /* Write the address to the PEX configuration address register */
  72902. + MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
  72903. +
  72904. + /* Clear CPU pipe. Important where CPU can perform OOO execution */
  72905. + CPU_PIPE_FLUSH;
  72906. +
  72907. + /* In order to let the PEX controller absorbed the address of the read */
  72908. + /* transaction we perform a validity check that the address was written */
  72909. + if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
  72910. + {
  72911. + return MV_ERROR;
  72912. + }
  72913. +
  72914. + /* Write the Data passed to the PEX Data register */
  72915. + MV_REG_WRITE(PEX_CFG_DATA_REG(pexIf), data);
  72916. +
  72917. + return MV_OK;
  72918. +
  72919. +}
  72920. +
  72921. +/*******************************************************************************
  72922. +* mvPexMasterEnable - Enable/disale PEX interface master transactions.
  72923. +*
  72924. +* DESCRIPTION:
  72925. +* This function performs read modified write to PEX command status
  72926. +* (offset 0x4) to set/reset bit 2. After this bit is set, the PEX
  72927. +* master is allowed to gain ownership on the bus, otherwise it is
  72928. +* incapable to do so.
  72929. +*
  72930. +* INPUT:
  72931. +* pexIf - PEX interface number.
  72932. +* enable - Enable/disable parameter.
  72933. +*
  72934. +* OUTPUT:
  72935. +* None.
  72936. +*
  72937. +* RETURN:
  72938. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  72939. +*
  72940. +*******************************************************************************/
  72941. +MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable)
  72942. +{
  72943. + MV_U32 pexCommandStatus;
  72944. + MV_U32 localBus;
  72945. + MV_U32 localDev;
  72946. +
  72947. + /* Parameter checking */
  72948. + if (pexIf >= mvCtrlPexMaxIfGet())
  72949. + {
  72950. + mvOsPrintf("mvPexMasterEnable: ERR. Invalid PEX interface %d\n", pexIf);
  72951. + return MV_ERROR;
  72952. + }
  72953. +
  72954. + localBus = mvPexLocalBusNumGet(pexIf);
  72955. + localDev = mvPexLocalDevNumGet(pexIf);
  72956. +
  72957. + pexCommandStatus = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
  72958. + PEX_STATUS_AND_COMMAND));
  72959. +
  72960. +
  72961. + if (MV_TRUE == enable)
  72962. + {
  72963. + pexCommandStatus |= PXSAC_MASTER_EN;
  72964. + }
  72965. + else
  72966. + {
  72967. + pexCommandStatus &= ~PXSAC_MASTER_EN;
  72968. + }
  72969. +
  72970. +
  72971. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
  72972. + pexCommandStatus);
  72973. +
  72974. + return MV_OK;
  72975. +}
  72976. +
  72977. +
  72978. +/*******************************************************************************
  72979. +* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.
  72980. +*
  72981. +* DESCRIPTION:
  72982. +* This function performs read modified write to PEX command status
  72983. +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
  72984. +* the PEX slave is allowed to respond to PEX IO space access (bit 0)
  72985. +* and PEX memory space access (bit 1).
  72986. +*
  72987. +* INPUT:
  72988. +* pexIf - PEX interface number.
  72989. +* dev - PEX device number.
  72990. +* enable - Enable/disable parameter.
  72991. +*
  72992. +* OUTPUT:
  72993. +* None.
  72994. +*
  72995. +* RETURN:
  72996. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  72997. +*
  72998. +*******************************************************************************/
  72999. +MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable)
  73000. +{
  73001. + MV_U32 pexCommandStatus;
  73002. + MV_U32 RegOffs;
  73003. +
  73004. + /* Parameter checking */
  73005. + if (pexIf >= mvCtrlPexMaxIfGet())
  73006. + {
  73007. + mvOsPrintf("mvPexSlaveEnable: ERR. Invalid PEX interface %d\n", pexIf);
  73008. + return MV_BAD_PARAM;
  73009. + }
  73010. + if (dev >= MAX_PEX_DEVICES)
  73011. + {
  73012. + mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n", dev);
  73013. + return MV_BAD_PARAM;
  73014. +
  73015. + }
  73016. +
  73017. +
  73018. + RegOffs = PEX_STATUS_AND_COMMAND;
  73019. +
  73020. + pexCommandStatus = mvPexConfigRead(pexIf, bus, dev, 0, RegOffs);
  73021. +
  73022. + if (MV_TRUE == enable)
  73023. + {
  73024. + pexCommandStatus |= (PXSAC_IO_EN | PXSAC_MEM_EN);
  73025. + }
  73026. + else
  73027. + {
  73028. + pexCommandStatus &= ~(PXSAC_IO_EN | PXSAC_MEM_EN);
  73029. + }
  73030. +
  73031. + mvPexConfigWrite(pexIf, bus, dev, 0, RegOffs, pexCommandStatus);
  73032. +
  73033. + return MV_OK;
  73034. +
  73035. +}
  73036. +
  73037. +/*******************************************************************************
  73038. +* mvPexLocalBusNumSet - Set PEX interface local bus number.
  73039. +*
  73040. +* DESCRIPTION:
  73041. +* This function sets given PEX interface its local bus number.
  73042. +* Note: In case the PEX interface is PEX-X, the information is read-only.
  73043. +*
  73044. +* INPUT:
  73045. +* pexIf - PEX interface number.
  73046. +* busNum - Bus number.
  73047. +*
  73048. +* OUTPUT:
  73049. +* None.
  73050. +*
  73051. +* RETURN:
  73052. +* MV_NOT_ALLOWED in case PEX interface is PEX-X.
  73053. +* MV_BAD_PARAM on bad parameters ,
  73054. +* otherwise MV_OK
  73055. +*
  73056. +*******************************************************************************/
  73057. +MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum)
  73058. +{
  73059. + MV_U32 pexStatus;
  73060. + MV_U32 localBus;
  73061. + MV_U32 localDev;
  73062. +
  73063. +
  73064. + /* Parameter checking */
  73065. + if (pexIf >= mvCtrlPexMaxIfGet())
  73066. + {
  73067. + mvOsPrintf("mvPexLocalBusNumSet: ERR. Invalid PEX interface %d\n",pexIf);
  73068. + return MV_BAD_PARAM;
  73069. + }
  73070. + if (busNum >= MAX_PEX_BUSSES)
  73071. + {
  73072. + mvOsPrintf("mvPexLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
  73073. + return MV_ERROR;
  73074. +
  73075. + }
  73076. +
  73077. + localBus = mvPexLocalBusNumGet(pexIf);
  73078. + localDev = mvPexLocalDevNumGet(pexIf);
  73079. +
  73080. +
  73081. +
  73082. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  73083. +
  73084. + pexStatus &= ~PXSR_PEX_BUS_NUM_MASK;
  73085. +
  73086. + pexStatus |= (busNum << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
  73087. +
  73088. + MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
  73089. +
  73090. +
  73091. + return MV_OK;
  73092. +}
  73093. +
  73094. +
  73095. +/*******************************************************************************
  73096. +* mvPexLocalBusNumGet - Get PEX interface local bus number.
  73097. +*
  73098. +* DESCRIPTION:
  73099. +* This function gets the local bus number of a given PEX interface.
  73100. +*
  73101. +* INPUT:
  73102. +* pexIf - PEX interface number.
  73103. +*
  73104. +* OUTPUT:
  73105. +* None.
  73106. +*
  73107. +* RETURN:
  73108. +* Local bus number.0xffffffff on Error
  73109. +*
  73110. +*******************************************************************************/
  73111. +MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf)
  73112. +{
  73113. + MV_U32 pexStatus;
  73114. +
  73115. + /* Parameter checking */
  73116. + if (PEX_DEFAULT_IF != pexIf)
  73117. + {
  73118. + if (pexIf >= mvCtrlPexMaxIfGet())
  73119. + {
  73120. + mvOsPrintf("mvPexLocalBusNumGet: ERR. Invalid PEX interface %d\n",pexIf);
  73121. + return 0xFFFFFFFF;
  73122. + }
  73123. + }
  73124. +
  73125. +
  73126. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  73127. +
  73128. + pexStatus &= PXSR_PEX_BUS_NUM_MASK;
  73129. +
  73130. + return (pexStatus >> PXSR_PEX_BUS_NUM_OFFS);
  73131. +
  73132. +}
  73133. +
  73134. +
  73135. +/*******************************************************************************
  73136. +* mvPexLocalDevNumSet - Set PEX interface local device number.
  73137. +*
  73138. +* DESCRIPTION:
  73139. +* This function sets given PEX interface its local device number.
  73140. +* Note: In case the PEX interface is PEX-X, the information is read-only.
  73141. +*
  73142. +* INPUT:
  73143. +* pexIf - PEX interface number.
  73144. +* devNum - Device number.
  73145. +*
  73146. +* OUTPUT:
  73147. +* None.
  73148. +*
  73149. +* RETURN:
  73150. +* MV_NOT_ALLOWED in case PEX interface is PEX-X.
  73151. +* MV_BAD_PARAM on bad parameters ,
  73152. +* otherwise MV_OK
  73153. +*
  73154. +*******************************************************************************/
  73155. +MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum)
  73156. +{
  73157. + MV_U32 pexStatus;
  73158. + MV_U32 localBus;
  73159. + MV_U32 localDev;
  73160. +
  73161. + /* Parameter checking */
  73162. + if (pexIf >= mvCtrlPexMaxIfGet())
  73163. + {
  73164. + mvOsPrintf("mvPexLocalDevNumSet: ERR. Invalid PEX interface %d\n",pexIf);
  73165. + return MV_BAD_PARAM;
  73166. + }
  73167. + if (devNum >= MAX_PEX_DEVICES)
  73168. + {
  73169. + mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n",
  73170. + devNum);
  73171. + return MV_BAD_PARAM;
  73172. +
  73173. + }
  73174. +
  73175. + localBus = mvPexLocalBusNumGet(pexIf);
  73176. + localDev = mvPexLocalDevNumGet(pexIf);
  73177. +
  73178. +
  73179. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  73180. +
  73181. + pexStatus &= ~PXSR_PEX_DEV_NUM_MASK;
  73182. +
  73183. + pexStatus |= (devNum << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
  73184. +
  73185. + MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
  73186. +
  73187. +
  73188. + return MV_OK;
  73189. +}
  73190. +
  73191. +/*******************************************************************************
  73192. +* mvPexLocalDevNumGet - Get PEX interface local device number.
  73193. +*
  73194. +* DESCRIPTION:
  73195. +* This function gets the local device number of a given PEX interface.
  73196. +*
  73197. +* INPUT:
  73198. +* pexIf - PEX interface number.
  73199. +*
  73200. +* OUTPUT:
  73201. +* None.
  73202. +*
  73203. +* RETURN:
  73204. +* Local device number. 0xffffffff on Error
  73205. +*
  73206. +*******************************************************************************/
  73207. +MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf)
  73208. +{
  73209. + MV_U32 pexStatus;
  73210. +
  73211. + /* Parameter checking */
  73212. +
  73213. + if (PEX_DEFAULT_IF != pexIf)
  73214. + {
  73215. + if (pexIf >= mvCtrlPexMaxIfGet())
  73216. + {
  73217. + mvOsPrintf("mvPexLocalDevNumGet: ERR. Invalid PEX interface %d\n",
  73218. + pexIf);
  73219. + return 0xFFFFFFFF;
  73220. + }
  73221. + }
  73222. +
  73223. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  73224. +
  73225. + pexStatus &= PXSR_PEX_DEV_NUM_MASK;
  73226. +
  73227. + return (pexStatus >> PXSR_PEX_DEV_NUM_OFFS);
  73228. +}
  73229. +
  73230. +MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value)
  73231. +{
  73232. +
  73233. + MV_U32 regAddr;
  73234. + if (pexIf >= mvCtrlPexMaxIfGet())
  73235. + {
  73236. + mvOsPrintf("mvPexPhyRegRead: ERR. Invalid PEX interface %d\n", pexIf);
  73237. + return;
  73238. + }
  73239. + regAddr = (BIT31 | ((regOffset & 0x3fff) << 16));
  73240. + MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
  73241. + *value = MV_REG_READ(PEX_PHY_ACCESS_REG(pexIf));
  73242. +}
  73243. +
  73244. +
  73245. +MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value)
  73246. +{
  73247. +
  73248. + MV_U32 regAddr;
  73249. + if(pexIf >= mvCtrlPexMaxIfGet())
  73250. + {
  73251. + mvOsPrintf("mvPexPhyRegWrite: ERR. Invalid PEX interface %d\n", pexIf);
  73252. + return;
  73253. + }
  73254. + regAddr = (((regOffset & 0x3fff) << 16) | value);
  73255. + MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
  73256. +}
  73257. +
  73258. +/*******************************************************************************
  73259. +* mvPexActiveStateLinkPMEnable
  73260. +*
  73261. +* DESCRIPTION:
  73262. +* Enable Active Link State Power Management
  73263. +*
  73264. +* INPUT:
  73265. +* pexIf - PEX interface number.
  73266. +* enable - MV_TRUE to enable ASPM, MV_FALSE to disable.
  73267. +*
  73268. +* OUTPUT:
  73269. +* None
  73270. +*
  73271. +* RETURN:
  73272. +* MV_OK on success , MV_ERROR otherwise
  73273. +*
  73274. +*******************************************************************************/
  73275. +MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable)
  73276. +{
  73277. + MV_U32 reg;
  73278. +
  73279. + if(pexIf >= mvCtrlPexMaxIfGet())
  73280. + {
  73281. + mvOsPrintf("mvPexActiveStateLinkPMEnable: ERR. Invalid PEX interface %d\n", pexIf);
  73282. + return MV_ERROR;
  73283. + }
  73284. +
  73285. + reg = MV_REG_READ(PEX_PWR_MNG_EXT_REG(pexIf)) & ~PXPMER_L1_ASPM_EN_MASK;
  73286. + if(enable == MV_TRUE)
  73287. + reg |= PXPMER_L1_ASPM_EN_MASK;
  73288. + MV_REG_WRITE(PEX_PWR_MNG_EXT_REG(pexIf), reg);
  73289. +
  73290. + /* Enable / Disable L0/1 entry */
  73291. + reg = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG))
  73292. + & ~PXLCSR_ASPM_CNT_MASK;
  73293. + if(enable == MV_TRUE)
  73294. + reg |= PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP;
  73295. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG), reg);
  73296. +
  73297. + return MV_OK;
  73298. +}
  73299. +
  73300. +
  73301. +/*******************************************************************************
  73302. +* mvPexForceX1
  73303. +*
  73304. +* DESCRIPTION:
  73305. +* shut down lanes 1-3 if recognize that attached to an x1 end-point
  73306. +* INPUT:
  73307. +* pexIf - PEX interface number.
  73308. +*
  73309. +* OUTPUT:
  73310. +* None
  73311. +*
  73312. +* RETURN:
  73313. +* MV_OK on success , MV_ERROR otherwise
  73314. +*
  73315. +*******************************************************************************/
  73316. +MV_U32 mvPexForceX1(MV_U32 pexIf)
  73317. +{
  73318. + MV_U32 regData = 0;
  73319. + if(pexIf >= mvCtrlPexMaxIfGet())
  73320. + {
  73321. + mvOsPrintf("mvPexForceX1: ERR. Invalid PEX interface %d\n", pexIf);
  73322. + return MV_BAD_PARAM;
  73323. + }
  73324. +
  73325. + regData = MV_REG_READ(PEX_CTRL_REG(pexIf)) & ~(PXCR_CONF_LINK_MASK) ;
  73326. + regData |= PXCR_CONF_LINK_X1;
  73327. +
  73328. + MV_REG_WRITE(PEX_CTRL_REG(pexIf), regData);
  73329. + return MV_OK;
  73330. +}
  73331. +
  73332. +MV_BOOL mvPexIsPowerUp(MV_U32 pexIf)
  73333. +{
  73334. + if(pexIf >= mvCtrlPexMaxIfGet())
  73335. + {
  73336. + mvOsPrintf("mvPexIsPowerUp: ERR. Invalid PEX interface %d\n", pexIf);
  73337. + return MV_FALSE;
  73338. + }
  73339. + return mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf);
  73340. +}
  73341. +
  73342. +
  73343. +MV_VOID mvPexPowerDown(MV_U32 pexIf)
  73344. +{
  73345. + if ( (mvCtrlModelGet() == MV_78XX0_DEV_ID) ||
  73346. + (mvCtrlModelGet() == MV_76100_DEV_ID) ||
  73347. + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
  73348. + (mvCtrlModelGet() == MV_78200_DEV_ID) )
  73349. + {
  73350. + mvCtrlPwrClckSet(PEX_UNIT_ID, pexIf, MV_FALSE);
  73351. + }
  73352. + else
  73353. + {
  73354. + MV_REG_WRITE((0x41B00 -(pexIf)*0x10000), 0x20800087);
  73355. + }
  73356. +}
  73357. +
  73358. +
  73359. +
  73360. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h
  73361. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h 1970-01-01 01:00:00.000000000 +0100
  73362. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h 2011-07-31 11:32:01.193522686 +0200
  73363. @@ -0,0 +1,168 @@
  73364. +/*******************************************************************************
  73365. +Copyright (C) Marvell International Ltd. and its affiliates
  73366. +
  73367. +This software file (the "File") is owned and distributed by Marvell
  73368. +International Ltd. and/or its affiliates ("Marvell") under the following
  73369. +alternative licensing terms. Once you have made an election to distribute the
  73370. +File under one of the following license alternatives, please (i) delete this
  73371. +introductory statement regarding license alternatives, (ii) delete the two
  73372. +license alternatives that you have not elected to use and (iii) preserve the
  73373. +Marvell copyright notice above.
  73374. +
  73375. +********************************************************************************
  73376. +Marvell Commercial License Option
  73377. +
  73378. +If you received this File from Marvell and you have entered into a commercial
  73379. +license agreement (a "Commercial License") with Marvell, the File is licensed
  73380. +to you under the terms of the applicable Commercial License.
  73381. +
  73382. +********************************************************************************
  73383. +Marvell GPL License Option
  73384. +
  73385. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73386. +modify this File in accordance with the terms and conditions of the General
  73387. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  73388. +available along with the File in the license.txt file or by writing to the Free
  73389. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  73390. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  73391. +
  73392. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  73393. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  73394. +DISCLAIMED. The GPL License provides additional details about this warranty
  73395. +disclaimer.
  73396. +********************************************************************************
  73397. +Marvell BSD License Option
  73398. +
  73399. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73400. +modify this File under the following licensing terms.
  73401. +Redistribution and use in source and binary forms, with or without modification,
  73402. +are permitted provided that the following conditions are met:
  73403. +
  73404. + * Redistributions of source code must retain the above copyright notice,
  73405. + this list of conditions and the following disclaimer.
  73406. +
  73407. + * Redistributions in binary form must reproduce the above copyright
  73408. + notice, this list of conditions and the following disclaimer in the
  73409. + documentation and/or other materials provided with the distribution.
  73410. +
  73411. + * Neither the name of Marvell nor the names of its contributors may be
  73412. + used to endorse or promote products derived from this software without
  73413. + specific prior written permission.
  73414. +
  73415. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  73416. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  73417. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  73418. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  73419. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  73420. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  73421. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  73422. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  73423. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  73424. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  73425. +
  73426. +*******************************************************************************/
  73427. +
  73428. +#ifndef __INCPEXH
  73429. +#define __INCPEXH
  73430. +
  73431. +#include "mvCommon.h"
  73432. +#include "mvOs.h"
  73433. +#include "pex/mvPexRegs.h"
  73434. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  73435. +
  73436. +
  73437. +
  73438. +/* NOTE not supported in this driver:*/
  73439. +
  73440. +
  73441. +/* defines */
  73442. +/* The number of supported PEX interfaces depend on Marvell controller */
  73443. +/* device number. This device number ID is located on the PEX unit */
  73444. +/* configuration header. This creates a loop where calling PEX */
  73445. +/* configuration read/write routine results a call to get PEX configuration */
  73446. +/* information etc. This macro defines a default PEX interface. This PEX */
  73447. +/* interface is sure to exist. */
  73448. +#define PEX_DEFAULT_IF 0
  73449. +
  73450. +
  73451. +/* typedefs */
  73452. +/* The Marvell controller supports both root complex and end point devices */
  73453. +/* This enumeration describes the PEX type. */
  73454. +typedef enum _mvPexType
  73455. +{
  73456. + MV_PEX_ROOT_COMPLEX, /* root complex device */
  73457. + MV_PEX_END_POINT /* end point device */
  73458. +}MV_PEX_TYPE;
  73459. +
  73460. +typedef enum _mvPexWidth
  73461. +{
  73462. + MV_PEX_WITDH_X1 = 1,
  73463. + MV_PEX_WITDH_X2,
  73464. + MV_PEX_WITDH_X3,
  73465. + MV_PEX_WITDH_X4,
  73466. + MV_PEX_WITDH_INVALID
  73467. +}MV_PEX_WIDTH;
  73468. +
  73469. +/* PEX Bar attributes */
  73470. +typedef struct _mvPexMode
  73471. +{
  73472. + MV_PEX_TYPE pexType;
  73473. + MV_PEX_WIDTH pexWidth;
  73474. + MV_BOOL pexLinkUp;
  73475. +}MV_PEX_MODE;
  73476. +
  73477. +
  73478. +
  73479. +/* Global Functions prototypes */
  73480. +/* mvPexInit - Initialize PEX interfaces*/
  73481. +MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType);
  73482. +
  73483. +/* mvPexModeGet - Get Pex If mode */
  73484. +MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode);
  73485. +
  73486. +/* mvPexConfigRead - Read from configuration space */
  73487. +MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  73488. + MV_U32 func,MV_U32 regOff);
  73489. +
  73490. +/* mvPexConfigWrite - Write to configuration space */
  73491. +MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  73492. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  73493. +
  73494. +/* mvPexMasterEnable - Enable/disale PEX interface master transactions.*/
  73495. +MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable);
  73496. +
  73497. +/* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.*/
  73498. +MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable);
  73499. +
  73500. +/* mvPexLocalBusNumSet - Set PEX interface local bus number.*/
  73501. +MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum);
  73502. +
  73503. +/* mvPexLocalBusNumGet - Get PEX interface local bus number.*/
  73504. +MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf);
  73505. +
  73506. +/* mvPexLocalDevNumSet - Set PEX interface local device number.*/
  73507. +MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum);
  73508. +
  73509. +/* mvPexLocalDevNumGet - Get PEX interface local device number.*/
  73510. +MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf);
  73511. +/* mvPexForceX1 - Force PEX interface to X1 mode. */
  73512. +MV_U32 mvPexForceX1(MV_U32 pexIf);
  73513. +
  73514. +/* mvPexIsPowerUp - Is PEX interface Power up? */
  73515. +MV_BOOL mvPexIsPowerUp(MV_U32 pexIf);
  73516. +
  73517. +/* mvPexPowerDown - Power Down */
  73518. +MV_VOID mvPexPowerDown(MV_U32 pexIf);
  73519. +
  73520. +/* mvPexPowerUp - Power Up */
  73521. +MV_VOID mvPexPowerUp(MV_U32 pexIf);
  73522. +
  73523. +/* mvPexPhyRegRead - Pex phy read */
  73524. +MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value);
  73525. +
  73526. +/* mvPexPhyRegWrite - Pex phy write */
  73527. +MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value);
  73528. +
  73529. +MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable);
  73530. +
  73531. +#endif /* #ifndef __INCPEXH */
  73532. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h
  73533. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h 1970-01-01 01:00:00.000000000 +0100
  73534. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h 2011-07-31 11:32:01.273424287 +0200
  73535. @@ -0,0 +1,751 @@
  73536. +/*******************************************************************************
  73537. +Copyright (C) Marvell International Ltd. and its affiliates
  73538. +
  73539. +This software file (the "File") is owned and distributed by Marvell
  73540. +International Ltd. and/or its affiliates ("Marvell") under the following
  73541. +alternative licensing terms. Once you have made an election to distribute the
  73542. +File under one of the following license alternatives, please (i) delete this
  73543. +introductory statement regarding license alternatives, (ii) delete the two
  73544. +license alternatives that you have not elected to use and (iii) preserve the
  73545. +Marvell copyright notice above.
  73546. +
  73547. +********************************************************************************
  73548. +Marvell Commercial License Option
  73549. +
  73550. +If you received this File from Marvell and you have entered into a commercial
  73551. +license agreement (a "Commercial License") with Marvell, the File is licensed
  73552. +to you under the terms of the applicable Commercial License.
  73553. +
  73554. +********************************************************************************
  73555. +Marvell GPL License Option
  73556. +
  73557. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73558. +modify this File in accordance with the terms and conditions of the General
  73559. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  73560. +available along with the File in the license.txt file or by writing to the Free
  73561. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  73562. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  73563. +
  73564. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  73565. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  73566. +DISCLAIMED. The GPL License provides additional details about this warranty
  73567. +disclaimer.
  73568. +********************************************************************************
  73569. +Marvell BSD License Option
  73570. +
  73571. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73572. +modify this File under the following licensing terms.
  73573. +Redistribution and use in source and binary forms, with or without modification,
  73574. +are permitted provided that the following conditions are met:
  73575. +
  73576. + * Redistributions of source code must retain the above copyright notice,
  73577. + this list of conditions and the following disclaimer.
  73578. +
  73579. + * Redistributions in binary form must reproduce the above copyright
  73580. + notice, this list of conditions and the following disclaimer in the
  73581. + documentation and/or other materials provided with the distribution.
  73582. +
  73583. + * Neither the name of Marvell nor the names of its contributors may be
  73584. + used to endorse or promote products derived from this software without
  73585. + specific prior written permission.
  73586. +
  73587. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  73588. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  73589. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  73590. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  73591. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  73592. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  73593. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  73594. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  73595. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  73596. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  73597. +
  73598. +*******************************************************************************/
  73599. +
  73600. +#ifndef __INCPEXREGSH
  73601. +#define __INCPEXREGSH
  73602. +
  73603. +#ifdef __cplusplus
  73604. +extern "C" {
  73605. +#endif /* __cplusplus */
  73606. +
  73607. +/* defines */
  73608. +#define MAX_PEX_DEVICES 32
  73609. +#define MAX_PEX_FUNCS 8
  73610. +#define MAX_PEX_BUSSES 256
  73611. +
  73612. +
  73613. +
  73614. +/*********************************************************/
  73615. +/* PCI Express Configuration Cycles Generation Registers */
  73616. +/*********************************************************/
  73617. +
  73618. +#define PEX_CFG_ADDR_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x18F8)
  73619. +#define PEX_CFG_DATA_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x18FC)
  73620. +#define PEX_PHY_ACCESS_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1B00)
  73621. +/* PCI Express Configuration Address Register */
  73622. +/* PEX_CFG_ADDR_REG (PXCAR)*/
  73623. +
  73624. +#define PXCAR_REG_NUM_OFFS 2
  73625. +#define PXCAR_REG_NUM_MAX 0x3F
  73626. +#define PXCAR_REG_NUM_MASK (PXCAR_REG_NUM_MAX << PXCAR_REG_NUM_OFFS)
  73627. +#define PXCAR_FUNC_NUM_OFFS 8
  73628. +#define PXCAR_FUNC_NUM_MAX 0x7
  73629. +#define PXCAR_FUNC_NUM_MASK (PXCAR_FUNC_NUM_MAX << PXCAR_FUNC_NUM_OFFS)
  73630. +#define PXCAR_DEVICE_NUM_OFFS 11
  73631. +#define PXCAR_DEVICE_NUM_MAX 0x1F
  73632. +#define PXCAR_DEVICE_NUM_MASK (PXCAR_DEVICE_NUM_MAX << PXCAR_DEVICE_NUM_OFFS)
  73633. +#define PXCAR_BUS_NUM_OFFS 16
  73634. +#define PXCAR_BUS_NUM_MAX 0xFF
  73635. +#define PXCAR_BUS_NUM_MASK (PXCAR_BUS_NUM_MAX << PXCAR_BUS_NUM_OFFS)
  73636. +#define PXCAR_EXT_REG_NUM_OFFS 24
  73637. +#define PXCAR_EXT_REG_NUM_MAX 0xF
  73638. +
  73639. +/* in pci express register address is now the legacy register address (8 bits)
  73640. +with the new extended register address (more 4 bits) , below is the mask of
  73641. +the upper 4 bits of the full register address */
  73642. +
  73643. +#define PXCAR_REAL_EXT_REG_NUM_OFFS 8
  73644. +#define PXCAR_EXT_REG_NUM_MASK (PXCAR_EXT_REG_NUM_MAX << PXCAR_EXT_REG_NUM_OFFS)
  73645. +#define PXCAR_CONFIG_EN BIT31
  73646. +
  73647. +#define PXCAR_REAL_EXT_REG_NUM_OFFS 8
  73648. +#define PXCAR_REAL_EXT_REG_NUM_MASK (0xF << PXCAR_REAL_EXT_REG_NUM_OFFS)
  73649. +
  73650. +/* The traditional PCI spec defined 6-bit field to describe register offset.*/
  73651. +/* The new PCI Express extend the register offset by an extra 4-bits. */
  73652. +/* The below macro assign 10-bit register offset into the apprpreate */
  73653. +/* fields in the CFG_ADDR_REG */
  73654. +#define PXCAR_REG_OFFS_SET(regOffs) \
  73655. + ( (regOff & PXCAR_REG_NUM_MASK) | \
  73656. + ( ((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >> PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS) )
  73657. +
  73658. +/***********************************/
  73659. +/* PCI Express Interrupt registers */
  73660. +/***********************************/
  73661. +#define PEX_CAUSE_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1900)
  73662. +#define PEX_MASK_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1910)
  73663. +
  73664. +#define PXICR_TX_REQ_IN_DLDOWN_ERR BIT0 /* Transmit request while field */
  73665. + /* <DLDown> of the PCI Express */
  73666. +/* PCI Express Interrupt Cause */
  73667. +/* PEX_INT_CAUSE_REG (PXICR)*/
  73668. +/* PEX_INT_MASK_REG*/
  73669. +/*
  73670. +NOTE:All bits except bits[27:24] are Read/Write Clear only. A cause bit sets
  73671. +upon an error event occurrence. A write of 0 clears the bit. A write of 1 has
  73672. +no affect. Bits[24:27} are set and cleared upon reception of interrupt
  73673. +emulation messages.
  73674. +
  73675. +Mask bit per cause bit. If a bit is set to 1, the corresponding event is
  73676. +enabled. Mask does not affect setting of the Interrupt Cause register bits;
  73677. +it only affects the assertion of the interrupt .*/
  73678. +
  73679. +
  73680. +#define PXICR_MDIS_CAUSE BIT1 /* Attempt to generate PCI transaction
  73681. + while master is disabled */
  73682. +#define PXICR_ERR_WRTO_REG_CAUSE BIT3 /* Erroneous write attempt to
  73683. + PCI Express internal register*/
  73684. +#define PXICR_HIT_DFLT_WIN_ERR BIT4 /* Hit Default Window Error */
  73685. +#define PXICR_RX_RAM_PAR_ERR BIT6 /* Rx RAM Parity Error */
  73686. +#define PXICR_TX_RAM_PAR_ERR BIT7 /* Tx RAM Parity Error */
  73687. +#define PXICR_COR_ERR_DET BIT8 /* Correctable Error Detected*/
  73688. +#define PXICR_NF_ERR_DET BIT9 /* Non-Fatal Error Detected*/
  73689. +#define PXICR_FERR_DET BIT10 /* Fatal Error Detected*/
  73690. +#define PXICR_DSTATE_CHANGE BIT11 /* Dstate Change Indication*/
  73691. +#define PXICR_BIST BIT12 /* PCI-Express BIST activated*/
  73692. +#define PXICR_FLW_CTRL_PROT BIT14 /* Flow Control Protocol Error */
  73693. +
  73694. +#define PXICR_RCV_UR_CA_ERR BIT15 /* Received UR or CA status. */
  73695. +#define PXICR_RCV_ERR_FATAL BIT16 /* Received ERR_FATAL message.*/
  73696. +#define PXICR_RCV_ERR_NON_FATAL BIT17 /* Received ERR_NONFATAL message*/
  73697. +#define PXICR_RCV_ERR_COR BIT18 /* Received ERR_COR message.*/
  73698. +#define PXICR_RCV_CRS BIT19 /* Received CRS completion status*/
  73699. +#define PXICR_SLV_HOT_RESET BIT20 /* Received Hot Reset Indication*/
  73700. +#define PXICR_SLV_DIS_LINK BIT21 /* Slave Disable Link Indication*/
  73701. +#define PXICR_SLV_LB BIT22 /* Slave Loopback Indication*/
  73702. +#define PXICR_LINK_FAIL BIT23 /* Link Failure indication.*/
  73703. +#define PXICR_RCV_INTA BIT24 /* IntA status.*/
  73704. +#define PXICR_RCV_INTB BIT25 /* IntB status.*/
  73705. +#define PXICR_RCV_INTC BIT26 /* IntC status.*/
  73706. +#define PXICR_RCV_INTD BIT27 /* IntD status.*/
  73707. +#define PXICR_RCV_PM_PME BIT28 /* Received PM_PME message. */
  73708. +
  73709. +
  73710. +/********************************************/
  73711. +/* PCI Express Control and Status Registers */
  73712. +/********************************************/
  73713. +#define PEX_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A00)
  73714. +#define PEX_STATUS_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A04)
  73715. +#define PEX_COMPLT_TMEOUT_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A10)
  73716. +#define PEX_PWR_MNG_EXT_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A18)
  73717. +#define PEX_FLOW_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A20)
  73718. +#define PEX_ACK_TMR_4X_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A30)
  73719. +#define PEX_ACK_TMR_1X_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A40)
  73720. +#define PEX_TL_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1AB0)
  73721. +
  73722. +
  73723. +#define PEX_RAM_PARITY_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A50)
  73724. +/* PCI Express Control Register */
  73725. +/* PEX_CTRL_REG (PXCR) */
  73726. +
  73727. +#define PXCR_CONF_LINK_OFFS 0
  73728. +#define PXCR_CONF_LINK_MASK (1 << PXCR_CONF_LINK_OFFS)
  73729. +#define PXCR_CONF_LINK_X4 (0 << PXCR_CONF_LINK_OFFS)
  73730. +#define PXCR_CONF_LINK_X1 (1 << PXCR_CONF_LINK_OFFS)
  73731. +#define PXCR_DEV_TYPE_CTRL_OFFS 1 /*PCI ExpressDevice Type Control*/
  73732. +#define PXCR_DEV_TYPE_CTRL_MASK BIT1
  73733. +#define PXCR_DEV_TYPE_CTRL_CMPLX (1 << PXCR_DEV_TYPE_CTRL_OFFS)
  73734. +#define PXCR_DEV_TYPE_CTRL_POINT (0 << PXCR_DEV_TYPE_CTRL_OFFS)
  73735. +#define PXCR_CFG_MAP_TO_MEM_EN BIT2 /* Configuration Header Mapping
  73736. + to Memory Space Enable */
  73737. +
  73738. +#define PXCR_CFG_MAP_TO_MEM_EN BIT2 /* Configuration Header Mapping
  73739. + to Memory Space Enable*/
  73740. +
  73741. +#define PXCR_RSRV1_OFFS 5
  73742. +#define PXCR_RSRV1_MASK (0x7 << PXCR_RSRV1_OFFS)
  73743. +#define PXCR_RSRV1_VAL (0x0 << PXCR_RSRV1_OFFS)
  73744. +
  73745. +#define PXCR_CONF_MAX_OUTSTND_OFFS 8 /*Maximum outstanding NP requests as a master*/
  73746. +#define PXCR_CONF_MAX_OUTSTND_MASK (0x3 << PXCR_CONF_MAX_OUTSTND_OFFS)
  73747. +
  73748. +
  73749. +#define PXCR_CONF_NFTS_OFFS 16 /*number of FTS Ordered-Sets*/
  73750. +#define PXCR_CONF_NFTS_MASK (0xff << PXCR_CONF_NFTS_OFFS)
  73751. +
  73752. +#define PXCR_CONF_MSTR_HOT_RESET BIT24 /*Master Hot-Reset.*/
  73753. +#define PXCR_CONF_MSTR_LB BIT26 /* Master Loopback */
  73754. +#define PXCR_CONF_MSTR_DIS_SCRMB BIT27 /* Master Disable Scrambling*/
  73755. +#define PXCR_CONF_DIRECT_DIS_SCRMB BIT28 /* Direct Disable Scrambling*/
  73756. +
  73757. +/* PCI Express Status Register */
  73758. +/* PEX_STATUS_REG (PXSR) */
  73759. +
  73760. +#define PXSR_DL_DOWN BIT0 /* DL_Down indication.*/
  73761. +
  73762. +#define PXSR_PEX_BUS_NUM_OFFS 8 /* Bus Number Indication */
  73763. +#define PXSR_PEX_BUS_NUM_MASK (0xff << PXSR_PEX_BUS_NUM_OFFS)
  73764. +
  73765. +#define PXSR_PEX_DEV_NUM_OFFS 16 /* Device Number Indication */
  73766. +#define PXSR_PEX_DEV_NUM_MASK (0x1f << PXSR_PEX_DEV_NUM_OFFS)
  73767. +
  73768. +#define PXSR_PEX_SLV_HOT_RESET BIT24 /* Slave Hot Reset Indication*/
  73769. +#define PXSR_PEX_SLV_DIS_LINK BIT25 /* Slave Disable Link Indication*/
  73770. +#define PXSR_PEX_SLV_LB BIT26 /* Slave Loopback Indication*/
  73771. +#define PXSR_PEX_SLV_DIS_SCRMB BIT27 /* Slave Disable Scrambling Indication*/
  73772. +
  73773. +
  73774. +/* PCI Express Completion Timeout Register */
  73775. +/* PEX_COMPLT_TMEOUT_REG (PXCTR)*/
  73776. +
  73777. +#define PXCTR_CMP_TO_THRSHLD_OFFS 0 /* Completion Timeout Threshold */
  73778. +#define PXCTR_CMP_TO_THRSHLD_MASK (0xffff << PXCTR_CMP_TO_THRSHLD_OFFS)
  73779. +
  73780. +/* PCI Express Power Management Extended Register */
  73781. +/* PEX_PWR_MNG_EXT_REG (PXPMER) */
  73782. +
  73783. +#define PXPMER_L1_ASPM_EN_OFFS 1
  73784. +#define PXPMER_L1_ASPM_EN_MASK (0x1 << PXPMER_L1_ASPM_EN_OFFS)
  73785. +
  73786. +/* PCI Express Flow Control Register */
  73787. +/* PEX_FLOW_CTRL_REG (PXFCR)*/
  73788. +
  73789. +#define PXFCR_PH_INIT_FC_OFFS 0 /*Posted Headers Flow Control Credit
  73790. + Initial Value.*/
  73791. +#define PXFCR_PH_INIT_FC_MASK (0xff << PXFCR_PH_INIT_FC_OFFS)
  73792. +
  73793. +
  73794. +#define PXFCR_NPH_INIT_FC_OFFS 8 /* Classified Non-Posted Headers
  73795. + Flow Control Credit Initial Value*/
  73796. +#define PXFCR_NPH_INIT_FC_MASK (0xff << PXFCR_NPH_INIT_FC_OFFS)
  73797. +
  73798. +#define PXFCR_CH_INIT_FC_OFFS 16 /* Completion Headers Flow Control
  73799. + Credit Initial Value Infinite*/
  73800. +
  73801. +#define PXFCR_CH_INIT_FC_MASK (0xff << PXFCR_CH_INIT_FC_OFFS)
  73802. +
  73803. +#define PXFCR_FC_UPDATE_TO_OFFS 24 /* Flow Control Update Timeout */
  73804. +#define PXFCR_FC_UPDATE_TO_MASK (0xff << PXFCR_FC_UPDATE_TO_OFFS)
  73805. +
  73806. +/* PCI Express Acknowledge Timers (4X) Register */
  73807. +/* PEX_ACK_TMR_4X_REG (PXAT4R) */
  73808. +#define PXAT1R_ACK_LAT_TOX4_OFFS 0 /* Ack Latency Timer Timeout Value */
  73809. +#define PXAT1R_ACK_LAT_TOX4_MASK (0xffff << PXAT4R_ACK_LAT_TOX1_OFFS)
  73810. +#define PXAT1R_ACK_RPLY_TOX4_OFFS 16 /* Ack Replay Timer Timeout Value */
  73811. +#define PXAT1R_ACK_RPLY_TOX4_MASK (0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)
  73812. +
  73813. +/* PCI Express Acknowledge Timers (1X) Register */
  73814. +/* PEX_ACK_TMR_1X_REG (PXAT1R) */
  73815. +
  73816. +#define PXAT1R_ACK_LAT_TOX1_OFFS 0 /* Acknowledge Latency Timer Timeout
  73817. + Value for 1X Link*/
  73818. +#define PXAT1R_ACK_LAT_TOX1_MASK (0xffff << PXAT1R_ACK_LAT_TOX1_OFFS)
  73819. +
  73820. +#define PXAT1R_ACK_RPLY_TOX1_OFFS 16 /* Acknowledge Replay Timer Timeout
  73821. + Value for 1X*/
  73822. +#define PXAT1R_ACK_RPLY_TOX1_MASK (0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)
  73823. +
  73824. +
  73825. +/* PCI Express TL Control Register */
  73826. +/* PEX_TL_CTRL_REG (PXTCR) */
  73827. +
  73828. +#define PXTCR_TX_CMP_BUFF_NO_OFFS 8 /*Number of completion buffers in Tx*/
  73829. +#define PXTCR_TX_CMP_BUFF_NO_MASK (0xf << PXTCR_TX_CMP_BUFF_NO_OFFS)
  73830. +
  73831. +/* PCI Express Debug MAC Control Register */
  73832. +/* PEX_DEBUG_MAC_CTRL_REG (PXDMCR) */
  73833. +
  73834. +#define PXDMCR_LINKUP BIT4
  73835. +
  73836. +
  73837. +
  73838. +/**********************************************/
  73839. +/* PCI Express Configuration Header Registers */
  73840. +/**********************************************/
  73841. +#define PEX_CFG_DIRECT_ACCESS(pexIf,cfgReg) ((PEX_IF_BASE(pexIf)) + (cfgReg))
  73842. +
  73843. +#define PEX_DEVICE_AND_VENDOR_ID 0x000
  73844. +#define PEX_STATUS_AND_COMMAND 0x004
  73845. +#define PEX_CLASS_CODE_AND_REVISION_ID 0x008
  73846. +#define PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE 0x00C
  73847. +#define PEX_MEMORY_BAR_BASE_ADDR(barNum) (0x010 + ((barNum) << 2))
  73848. +#define PEX_MV_BAR_BASE(barNum) (0x010 + (barNum) * 8)
  73849. +#define PEX_MV_BAR_BASE_HIGH(barNum) (0x014 + (barNum) * 8)
  73850. +#define PEX_BAR0_INTER_REG 0x010
  73851. +#define PEX_BAR0_INTER_REG_HIGH 0x014
  73852. +#define PEX_BAR1_REG 0x018
  73853. +#define PEX_BAR1_REG_HIGH 0x01C
  73854. +#define PEX_BAR2_REG 0x020
  73855. +#define PEX_BAR2_REG_HIGH 0x024
  73856. +
  73857. +#define PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID 0x02C
  73858. +#define PEX_EXPANSION_ROM_BASE_ADDR_REG 0x030
  73859. +#define PEX_CAPABILTY_LIST_POINTER 0x034
  73860. +#define PEX_INTERRUPT_PIN_AND_LINE 0x03C
  73861. +
  73862. +/* capability list */
  73863. +#define PEX_POWER_MNG_CAPABILITY 0x040
  73864. +#define PEX_POWER_MNG_STATUS_CONTROL 0x044
  73865. +
  73866. +#define PEX_MSI_MESSAGE_CONTROL 0x050
  73867. +#define PEX_MSI_MESSAGE_ADDR 0x054
  73868. +#define PEX_MSI_MESSAGE_HIGH_ADDR 0x058
  73869. +#define PEX_MSI_MESSAGE_DATA 0x05C
  73870. +
  73871. +#define PEX_CAPABILITY_REG 0x60
  73872. +#define PEX_DEV_CAPABILITY_REG 0x64
  73873. +#define PEX_DEV_CTRL_STAT_REG 0x68
  73874. +#define PEX_LINK_CAPABILITY_REG 0x6C
  73875. +#define PEX_LINK_CTRL_STAT_REG 0x70
  73876. +
  73877. +#define PEX_ADV_ERR_RPRT_HDR_TRGT_REG 0x100
  73878. +#define PEX_UNCORRECT_ERR_STAT_REG 0x104
  73879. +#define PEX_UNCORRECT_ERR_MASK_REG 0x108
  73880. +#define PEX_UNCORRECT_ERR_SERVITY_REG 0x10C
  73881. +#define PEX_CORRECT_ERR_STAT_REG 0x110
  73882. +#define PEX_CORRECT_ERR_MASK_REG 0x114
  73883. +#define PEX_ADV_ERR_CAPABILITY_CTRL_REG 0x118
  73884. +#define PEX_HDR_LOG_FIRST_DWORD_REG 0x11C
  73885. +#define PEX_HDR_LOG_SECOND_DWORD_REG 0x120
  73886. +#define PEX_HDR_LOG_THIRD_DWORD_REG 0x124
  73887. +#define PEX_HDR_LOG_FOURTH_DWORD_REG 0x128
  73888. +
  73889. +
  73890. +
  73891. +/* PCI Express Device and Vendor ID Register*/
  73892. +/*PEX_DEVICE_AND_VENDOR_ID (PXDAVI)*/
  73893. +
  73894. +#define PXDAVI_VEN_ID_OFFS 0 /* Vendor ID */
  73895. +#define PXDAVI_VEN_ID_MASK (0xffff << PXDAVI_VEN_ID_OFFS)
  73896. +
  73897. +#define PXDAVI_DEV_ID_OFFS 16 /* Device ID */
  73898. +#define PXDAVI_DEV_ID_MASK (0xffff << PXDAVI_DEV_ID_OFFS)
  73899. +
  73900. +
  73901. +/* PCI Express Command and Status Register*/
  73902. +/*PEX_STATUS_AND_COMMAND (PXSAC)*/
  73903. +
  73904. +#define PXSAC_IO_EN BIT0 /* IO Enable */
  73905. +#define PXSAC_MEM_EN BIT1 /* Memory Enable */
  73906. +#define PXSAC_MASTER_EN BIT2 /* Master Enable */
  73907. +#define PXSAC_PERR_EN BIT6 /* Parity Errors Respond Enable */
  73908. +#define PXSAC_SERR_EN BIT8 /* Ability to assert SERR# line */
  73909. +#define PXSAC_INT_DIS BIT10 /* Interrupt Disable */
  73910. +#define PXSAC_INT_STAT BIT19 /* Interrupt Status */
  73911. +#define PXSAC_CAP_LIST BIT20 /* Capability List Support */
  73912. +#define PXSAC_MAS_DATA_PERR BIT24 /* Master Data Parity Error */
  73913. +#define PXSAC_SLAVE_TABORT BIT27 /* Signalled Target Abort */
  73914. +#define PXSAC_RT_ABORT BIT28 /* Recieved Target Abort */
  73915. +#define PXSAC_MABORT BIT29 /* Recieved Master Abort */
  73916. +#define PXSAC_SYSERR BIT30 /* Signalled system error */
  73917. +#define PXSAC_DET_PARERR BIT31 /* Detect Parity Error */
  73918. +
  73919. +
  73920. +/* PCI Express Class Code and Revision ID Register*/
  73921. +/*PEX_CLASS_CODE_AND_REVISION_ID (PXCCARI)*/
  73922. +
  73923. +#define PXCCARI_REVID_OFFS 0 /* Revision ID */
  73924. +#define PXCCARI_REVID_MASK (0xff << PXCCARI_REVID_OFFS)
  73925. +
  73926. +#define PXCCARI_FULL_CLASS_OFFS 8 /* Full Class Code */
  73927. +#define PXCCARI_FULL_CLASS_MASK (0xffffff << PXCCARI_FULL_CLASS_OFFS)
  73928. +
  73929. +#define PXCCARI_PROGIF_OFFS 8 /* Prog .I/F*/
  73930. +#define PXCCARI_PROGIF_MASK (0xff << PXCCARI_PROGIF_OFFS)
  73931. +
  73932. +#define PXCCARI_SUB_CLASS_OFFS 16 /* Sub Class*/
  73933. +#define PXCCARI_SUB_CLASS_MASK (0xff << PXCCARI_SUB_CLASS_OFFS)
  73934. +
  73935. +#define PXCCARI_BASE_CLASS_OFFS 24 /* Base Class*/
  73936. +#define PXCCARI_BASE_CLASS_MASK (0xff << PXCCARI_BASE_CLASS_OFFS)
  73937. +
  73938. +
  73939. +/* PCI Express BIST, Header Type and Cache Line Size Register*/
  73940. +/*PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE (PXBHTLTCL)*/
  73941. +
  73942. +#define PXBHTLTCL_CACHELINE_OFFS 0 /* Specifies the cache line size */
  73943. +#define PXBHTLTCL_CACHELINE_MASK (0xff << PXBHTLTCL_CACHELINE_OFFS)
  73944. +
  73945. +#define PXBHTLTCL_HEADTYPE_FULL_OFFS 16 /* Full Header Type */
  73946. +#define PXBHTLTCL_HEADTYPE_FULL_MASK (0xff << PXBHTLTCL_HEADTYPE_FULL_OFFS)
  73947. +
  73948. +#define PXBHTLTCL_MULTI_FUNC BIT23 /* Multi/Single function */
  73949. +
  73950. +#define PXBHTLTCL_HEADER_OFFS 16 /* Header type */
  73951. +#define PXBHTLTCL_HEADER_MASK (0x7f << PXBHTLTCL_HEADER_OFFS)
  73952. +#define PXBHTLTCL_HEADER_STANDARD (0x0 << PXBHTLTCL_HEADER_OFFS)
  73953. +#define PXBHTLTCL_HEADER_PCI2PCI_BRIDGE (0x1 << PXBHTLTCL_HEADER_OFFS)
  73954. +
  73955. +
  73956. +#define PXBHTLTCL_BISTCOMP_OFFS 24 /* BIST Completion Code */
  73957. +#define PXBHTLTCL_BISTCOMP_MASK (0xf << PXBHTLTCL_BISTCOMP_OFFS)
  73958. +
  73959. +#define PXBHTLTCL_BISTACT BIT30 /* BIST Activate bit */
  73960. +#define PXBHTLTCL_BISTCAP BIT31 /* BIST Capable Bit */
  73961. +#define PXBHTLTCL_BISTCAP_OFFS 31
  73962. +#define PXBHTLTCL_BISTCAP_MASK BIT31
  73963. +#define PXBHTLTCL_BISTCAP_VAL 0
  73964. +
  73965. +
  73966. +/* PCI Express Subsystem Device and Vendor ID */
  73967. +/*PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID (PXSIASVI)*/
  73968. +
  73969. +#define PXSIASVI_VENID_OFFS 0 /* Subsystem Manufacturer Vendor ID Number */
  73970. +#define PXSIASVI_VENID_MASK (0xffff << PXSIASVI_VENID_OFFS)
  73971. +
  73972. +#define PXSIASVI_DEVID_OFFS 16 /* Subsystem Device ID Number */
  73973. +#define PXSIASVI_DEVID_MASK (0xffff << PXSIASVI_DEVID_OFFS)
  73974. +
  73975. +
  73976. +/* PCI Express Capability List Pointer Register*/
  73977. +/*PEX_CAPABILTY_LIST_POINTER (PXCLP)*/
  73978. +
  73979. +#define PXCLP_CAPPTR_OFFS 0 /* Capability List Pointer */
  73980. +#define PXCLP_CAPPTR_MASK (0xff << PXCLP_CAPPTR_OFFS)
  73981. +
  73982. +/* PCI Express Interrupt Pin and Line Register */
  73983. +/*PEX_INTERRUPT_PIN_AND_LINE (PXIPAL)*/
  73984. +
  73985. +#define PXIPAL_INTLINE_OFFS 0 /* Interrupt line (IRQ) */
  73986. +#define PXIPAL_INTLINE_MASK (0xff << PXIPAL_INTLINE_OFFS)
  73987. +
  73988. +#define PXIPAL_INTPIN_OFFS 8 /* interrupt pin (A,B,C,D) */
  73989. +#define PXIPAL_INTPIN_MASK (0xff << PXIPAL_INTPIN_OFFS)
  73990. +
  73991. +
  73992. +/* PCI Express Power Management Capability Header Register*/
  73993. +/*PEX_POWER_MNG_CAPABILITY (PXPMC)*/
  73994. +
  73995. +#define PXPMC_CAP_ID_OFFS 0 /* Capability ID */
  73996. +#define PXPMC_CAP_ID_MASK (0xff << PXPMC_CAP_ID_OFFS)
  73997. +
  73998. +#define PXPMC_NEXT_PTR_OFFS 8 /* Next Item Pointer */
  73999. +#define PXPMC_NEXT_PTR_MASK (0xff << PXPMC_NEXT_PTR_OFFS)
  74000. +
  74001. +#define PXPMC_PMC_VER_OFFS 16 /* PCI Power Management Capability Version*/
  74002. +#define PXPMC_PMC_VER_MASK (0x7 << PXPMC_PMC_VER_OFFS)
  74003. +
  74004. +#define PXPMC_DSI BIT21/* Device Specific Initialization */
  74005. +
  74006. +#define PXPMC_AUX_CUR_OFFS 22 /* Auxiliary Current Requirements */
  74007. +#define PXPMC_AUX_CUR_MASK (0x7 << PXPMC_AUX_CUR_OFFS)
  74008. +
  74009. +#define PXPMC_D1_SUP BIT25 /* D1 Power Management support*/
  74010. +
  74011. +#define PXPMC_D2_SUP BIT26 /* D2 Power Management support*/
  74012. +
  74013. +#define PXPMC_PME_SUP_OFFS 27 /* PM Event generation support*/
  74014. +#define PXPMC_PME_SUP_MASK (0x1f << PXPMC_PME_SUP_OFFS)
  74015. +
  74016. +/* PCI Express Power Management Control and Status Register*/
  74017. +/*PEX_POWER_MNG_STATUS_CONTROL (PXPMSC)*/
  74018. +
  74019. +#define PXPMSC_PM_STATE_OFFS 0 /* Power State */
  74020. +#define PXPMSC_PM_STATE_MASK (0x3 << PXPMSC_PM_STATE_OFFS)
  74021. +#define PXPMSC_PM_STATE_D0 (0x0 << PXPMSC_PM_STATE_OFFS)
  74022. +#define PXPMSC_PM_STATE_D1 (0x1 << PXPMSC_PM_STATE_OFFS)
  74023. +#define PXPMSC_PM_STATE_D2 (0x2 << PXPMSC_PM_STATE_OFFS)
  74024. +#define PXPMSC_PM_STATE_D3 (0x3 << PXPMSC_PM_STATE_OFFS)
  74025. +
  74026. +#define PXPMSC_PME_EN BIT8/* PM_PME Message Generation Enable */
  74027. +
  74028. +#define PXPMSC_PM_DATA_SEL_OFFS 9 /* Data Select*/
  74029. +#define PXPMSC_PM_DATA_SEL_MASK (0xf << PXPMSC_PM_DATA_SEL_OFFS)
  74030. +
  74031. +#define PXPMSC_PM_DATA_SCALE_OFFS 13 /* Data Scale */
  74032. +#define PXPMSC_PM_DATA_SCALE_MASK (0x3 << PXPMSC_PM_DATA_SCALE_OFFS)
  74033. +
  74034. +#define PXPMSC_PME_STAT BIT15/* PME Status */
  74035. +
  74036. +#define PXPMSC_PM_DATA_OFFS 24 /* State Data */
  74037. +#define PXPMSC_PM_DATA_MASK (0xff << PXPMSC_PM_DATA_OFFS)
  74038. +
  74039. +
  74040. +/* PCI Express MSI Message Control Register*/
  74041. +/*PEX_MSI_MESSAGE_CONTROL (PXMMC)*/
  74042. +
  74043. +#define PXMMC_CAP_ID_OFFS 0 /* Capability ID */
  74044. +#define PXMMC_CAP_ID_MASK (0xff << PXMMC_CAP_ID_OFFS)
  74045. +
  74046. +#define PXMMC_NEXT_PTR_OFFS 8 /* Next Item Pointer */
  74047. +#define PXMMC_NEXT_PTR_MASK (0xff << PXMMC_NEXT_PTR_OFFS)
  74048. +
  74049. +#define PXMMC_MSI_EN BIT18 /* MSI Enable */
  74050. +
  74051. +#define PXMMC_MULTI_CAP_OFFS 17 /* Multiple Message Capable */
  74052. +#define PXMMC_MULTI_CAP_MASK (0x7 << PXMMC_MULTI_CAP_OFFS)
  74053. +
  74054. +#define PXMMC_MULTI_EN_OFFS 20 /* Multiple Messages Enable */
  74055. +#define PXMMC_MULTI_EN_MASK (0x7 << PXMMC_MULTI_EN_OFFS)
  74056. +
  74057. +#define PXMMC_ADDR64 BIT23 /* 64-bit Addressing Capable */
  74058. +
  74059. +
  74060. +/* PCI Express MSI Message Address Register*/
  74061. +/*PEX_MSI_MESSAGE_ADDR (PXMMA)*/
  74062. +
  74063. +#define PXMMA_MSI_ADDR_OFFS 2 /* Message Address corresponds to
  74064. + Address[31:2] of the MSI MWr TLP*/
  74065. +#define PXMMA_MSI_ADDR_MASK (0x3fffffff << PXMMA_MSI_ADDR_OFFS)
  74066. +
  74067. +
  74068. +/* PCI Express MSI Message Address (High) Register */
  74069. +/*PEX_MSI_MESSAGE_HIGH_ADDR (PXMMHA)*/
  74070. +
  74071. +#define PXMMA_MSI_ADDR_H_OFFS 0 /* Message Upper Address corresponds to
  74072. + Address[63:32] of the MSI MWr TLP*/
  74073. +#define PXMMA_MSI_ADDR_H_MASK (0xffffffff << PXMMA_MSI_ADDR_H_OFFS )
  74074. +
  74075. +
  74076. +/* PCI Express MSI Message Data Register*/
  74077. +/*PEX_MSI_MESSAGE_DATA (PXMMD)*/
  74078. +
  74079. +#define PXMMD_MSI_DATA_OFFS 0 /* Message Data */
  74080. +#define PXMMD_MSI_DATA_MASK (0xffff << PXMMD_MSI_DATA_OFFS )
  74081. +
  74082. +
  74083. +/* PCI Express Capability Register*/
  74084. +/*PEX_CAPABILITY_REG (PXCR)*/
  74085. +
  74086. +#define PXCR_CAP_ID_OFFS 0 /* Capability ID*/
  74087. +#define PXCR_CAP_ID_MASK (0xff << PXCR_CAP_ID_OFFS)
  74088. +
  74089. +#define PXCR_NEXT_PTR_OFFS 8 /* Next Item Pointer*/
  74090. +#define PXCR_NEXT_PTR_MASK (0xff << PXCR_NEXT_PTR_OFFS)
  74091. +
  74092. +#define PXCR_CAP_VER_OFFS 16 /* Capability Version*/
  74093. +#define PXCR_CAP_VER_MASK (0xf << PXCR_CAP_VER_OFFS)
  74094. +
  74095. +#define PXCR_DEV_TYPE_OFFS 20 /* Device/Port Type*/
  74096. +#define PXCR_DEV_TYPE_MASK (0xf << PXCR_DEV_TYPE_OFFS)
  74097. +
  74098. +#define PXCR_SLOT_IMP BIT24 /* Slot Implemented*/
  74099. +
  74100. +#define PXCR_INT_MSG_NUM_OFFS 25 /* Interrupt Message Number*/
  74101. +#define PXCR_INT_MSG_NUM_MASK (0x1f << PXCR_INT_MSG_NUM_OFFS)
  74102. +
  74103. +
  74104. +/* PCI Express Device Capabilities Register */
  74105. +/*PEX_DEV_CAPABILITY_REG (PXDCR)*/
  74106. +
  74107. +#define PXDCR_MAX_PLD_SIZE_SUP_OFFS 0 /* Maximum Payload Size Supported*/
  74108. +#define PXDCR_MAX_PLD_SIZE_SUP_MASK (0x7 << PXDCR_MAX_PLD_SIZE_SUP_OFFS)
  74109. +
  74110. +#define PXDCR_EP_L0S_ACC_LAT_OFFS 6/* Endpoint L0s Acceptable Latency*/
  74111. +#define PXDCR_EP_L0S_ACC_LAT_MASK (0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74112. +#define PXDCR_EP_L0S_ACC_LAT_64NS_LESS (0x0 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74113. +#define PXDCR_EP_L0S_ACC_LAT_64NS_128NS (0x1 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74114. +#define PXDCR_EP_L0S_ACC_LAT_128NS_256NS (0x2 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74115. +#define PXDCR_EP_L0S_ACC_LAT_256NS_512NS (0x3 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74116. +#define PXDCR_EP_L0S_ACC_LAT_512NS_1US (0x4 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74117. +#define PXDCR_EP_L0S_ACC_LAT_1US_2US (0x5 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74118. +#define PXDCR_EP_L0S_ACC_LAT_2US_4US (0x6 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74119. +#define PXDCR_EP_L0S_ACC_LAT_4US_MORE (0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74120. +
  74121. +#define PXDCR_EP_L1_ACC_LAT_OFFS 9 /* Endpoint L1 Acceptable Latency*/
  74122. +#define PXDCR_EP_L1_ACC_LAT_MASK (0x7 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74123. +#define PXDCR_EP_L1_ACC_LAT_64NS_LESS (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74124. +#define PXDCR_EP_L1_ACC_LAT_64NS_128NS (0x1 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74125. +#define PXDCR_EP_L1_ACC_LAT_128NS_256NS (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74126. +#define PXDCR_EP_L1_ACC_LAT_256NS_512NS (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74127. +#define PXDCR_EP_L1_ACC_LAT_512NS_1US (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74128. +#define PXDCR_EP_L1_ACC_LAT_1US_2US (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74129. +#define PXDCR_EP_L1_ACC_LAT_2US_4US (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74130. +#define PXDCR_EP_L1_ACC_LAT_4US_MORE (0x7 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74131. +
  74132. +
  74133. +#define PXDCR_ATT_BUT_PRS_OFFS 12 /* Attention Button Present*/
  74134. +#define PXDCR_ATT_BUT_PRS_MASK BIT12
  74135. +#define PXDCR_ATT_BUT_PRS_IMPLEMENTED BIT12
  74136. +
  74137. +#define PXDCR_ATT_IND_PRS_OFFS 13 /* Attention Indicator Present*/
  74138. +#define PXDCR_ATT_IND_PRS_MASK BIT13
  74139. +#define PXDCR_ATT_IND_PRS_IMPLEMENTED BIT13
  74140. +
  74141. +#define PXDCR_PWR_IND_PRS_OFFS 14/* Power Indicator Present*/
  74142. +#define PXDCR_PWR_IND_PRS_MASK BIT14
  74143. +#define PXDCR_PWR_IND_PRS_IMPLEMENTED BIT14
  74144. +
  74145. +#define PXDCR_CAP_SPL_VAL_OFFS 18 /*Captured Slot Power Limit
  74146. + Value*/
  74147. +#define PXDCR_CAP_SPL_VAL_MASK (0xff << PXDCR_CAP_SPL_VAL_OFFS)
  74148. +
  74149. +#define PXDCR_CAP_SP_LSCL_OFFS 26 /* Captured Slot Power Limit
  74150. + Scale */
  74151. +#define PXDCR_CAP_SP_LSCL_MASK (0x3 << PXDCR_CAP_SP_LSCL_OFFS)
  74152. +
  74153. +/* PCI Express Device Control Status Register */
  74154. +/*PEX_DEV_CTRL_STAT_REG (PXDCSR)*/
  74155. +
  74156. +#define PXDCSR_COR_ERR_REP_EN BIT0 /* Correctable Error Reporting Enable*/
  74157. +#define PXDCSR_NF_ERR_REP_EN BIT1 /* Non-Fatal Error Reporting Enable*/
  74158. +#define PXDCSR_F_ERR_REP_EN BIT2 /* Fatal Error Reporting Enable*/
  74159. +#define PXDCSR_UR_REP_EN BIT3 /* Unsupported Request (UR)
  74160. + Reporting Enable*/
  74161. +#define PXDCSR_EN_RO BIT4 /* Enable Relaxed Ordering*/
  74162. +
  74163. +#define PXDCSR_MAX_PLD_SZ_OFFS 5 /* Maximum Payload Size*/
  74164. +#define PXDCSR_MAX_PLD_SZ_MASK (0x7 << PXDCSR_MAX_PLD_SZ_OFFS)
  74165. +#define PXDCSR_MAX_PLD_SZ_128B (0x0 << PXDCSR_MAX_PLD_SZ_OFFS)
  74166. +#define PXDCSR_EN_NS BIT11 /* Enable No Snoop*/
  74167. +
  74168. +#define PXDCSR_MAX_RD_RQ_SZ_OFFS 12 /* Maximum Read Request Size*/
  74169. +#define PXDCSR_MAX_RD_RQ_SZ_MASK (0x7 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74170. +#define PXDCSR_MAX_RD_RQ_SZ_128B (0x0 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74171. +#define PXDCSR_MAX_RD_RQ_SZ_256B (0x1 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74172. +#define PXDCSR_MAX_RD_RQ_SZ_512B (0x2 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74173. +#define PXDCSR_MAX_RD_RQ_SZ_1KB (0x3 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74174. +#define PXDCSR_MAX_RD_RQ_SZ_2KB (0x4 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74175. +#define PXDCSR_MAX_RD_RQ_SZ_4KB (0x5 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74176. +
  74177. +#define PXDCSR_COR_ERR_DET BIT16 /* Correctable Error Detected*/
  74178. +#define PXDCSR_NF_ERR_DET BIT17 /* Non-Fatal Error Detected.*/
  74179. +#define PXDCSR_F_ERR_DET BIT18 /* Fatal Error Detected.*/
  74180. +#define PXDCSR_UR_DET BIT19 /* Unsupported Request Detected */
  74181. +#define PXDCSR_AUX_PWR_DET BIT20 /* Reserved*/
  74182. +
  74183. +#define PXDCSR_TRANS_PEND_OFFS 21 /* Transactions Pending*/
  74184. +#define PXDCSR_TRANS_PEND_MASK BIT21
  74185. +#define PXDCSR_TRANS_PEND_NOT_COMPLETED (0x1 << PXDCSR_TRANS_PEND_OFFS)
  74186. +
  74187. +
  74188. +/* PCI Express Link Capabilities Register*/
  74189. +/*PEX_LINK_CAPABILITY_REG (PXLCR)*/
  74190. +
  74191. +#define PXLCR_MAX_LINK_SPD_OFFS 0 /* Maximum Link Speed*/
  74192. +#define PXLCR_MAX_LINK_SPD_MASK (0xf << PXLCR_MAX_LINK_SPD_OFFS)
  74193. +
  74194. +#define PXLCR_MAX_LNK_WDTH_OFFS 3 /* Maximum Link Width*/
  74195. +#define PXLCR_MAX_LNK_WDTH_MASK (0x3f << PXLCR_MAX_LNK_WDTH_OFFS)
  74196. +
  74197. +#define PXLCR_ASPM_SUP_OFFS 10 /* Active State Link PM Support*/
  74198. +#define PXLCR_ASPM_SUP_MASK (0x3 << PXLCR_ASPM_SUP_OFFS)
  74199. +
  74200. +#define PXLCR_L0S_EXT_LAT_OFFS 12 /* L0s Exit Latency*/
  74201. +#define PXLCR_L0S_EXT_LAT_MASK (0x7 << PXLCR_L0S_EXT_LAT_OFFS)
  74202. +#define PXLCR_L0S_EXT_LAT_64NS_LESS (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74203. +#define PXLCR_L0S_EXT_LAT_64NS_128NS (0x1 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74204. +#define PXLCR_L0S_EXT_LAT_128NS_256NS (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74205. +#define PXLCR_L0S_EXT_LAT_256NS_512NS (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74206. +#define PXLCR_L0S_EXT_LAT_512NS_1US (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74207. +#define PXLCR_L0S_EXT_LAT_1US_2US (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74208. +#define PXLCR_L0S_EXT_LAT_2US_4US (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74209. +
  74210. +#define PXLCR_POR_TNUM_OFFS 24 /* Port Number */
  74211. +#define PXLCR_POR_TNUM_MASK (0xff << PXLCR_POR_TNUM_OFFS)
  74212. +
  74213. +/* PCI Express Link Control Status Register */
  74214. +/*PEX_LINK_CTRL_STAT_REG (PXLCSR)*/
  74215. +
  74216. +#define PXLCSR_ASPM_CNT_OFFS 0 /* Active State Link PM Control */
  74217. +#define PXLCSR_ASPM_CNT_MASK (0x3 << PXLCSR_ASPM_CNT_OFFS)
  74218. +#define PXLCSR_ASPM_CNT_DISABLED (0x0 << PXLCSR_ASPM_CNT_OFFS)
  74219. +#define PXLCSR_ASPM_CNT_L0S_ENT_SUPP (0x1 << PXLCSR_ASPM_CNT_OFFS)
  74220. +#define PXLCSR_ASPM_CNT_L1S_ENT_SUPP (0x2 << PXLCSR_ASPM_CNT_OFFS)
  74221. +#define PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP (0x3 << PXLCSR_ASPM_CNT_OFFS)
  74222. +
  74223. +#define PXLCSR_RCB_OFFS 3 /* Read Completion Boundary */
  74224. +#define PXLCSR_RCB_MASK BIT3
  74225. +#define PXLCSR_RCB_64B (0 << PXLCSR_RCB_OFFS)
  74226. +#define PXLCSR_RCB_128B (1 << PXLCSR_RCB_OFFS)
  74227. +
  74228. +#define PXLCSR_LNK_DIS BIT4 /* Link Disable */
  74229. +#define PXLCSR_RETRN_LNK BIT5 /* Retrain Link */
  74230. +#define PXLCSR_CMN_CLK_CFG BIT6 /* Common Clock Configuration */
  74231. +#define PXLCSR_EXTD_SNC BIT7 /* Extended Sync */
  74232. +
  74233. +#define PXLCSR_LNK_SPD_OFFS 16 /* Link Speed */
  74234. +#define PXLCSR_LNK_SPD_MASK (0xf << PXLCSR_LNK_SPD_OFFS)
  74235. +
  74236. +#define PXLCSR_NEG_LNK_WDTH_OFFS 20 /* Negotiated Link Width */
  74237. +#define PXLCSR_NEG_LNK_WDTH_MASK (0x3f << PXLCSR_NEG_LNK_WDTH_OFFS)
  74238. +#define PXLCSR_NEG_LNK_WDTH_X1 (0x1 << PXLCSR_NEG_LNK_WDTH_OFFS)
  74239. +
  74240. +#define PXLCSR_LNK_TRN BIT27 /* Link Training */
  74241. +
  74242. +#define PXLCSR_SLT_CLK_CFG_OFFS 28 /* Slot Clock Configuration */
  74243. +#define PXLCSR_SLT_CLK_CFG_MASK BIT28
  74244. +#define PXLCSR_SLT_CLK_CFG_INDPNT (0x0 << PXLCSR_SLT_CLK_CFG_OFFS)
  74245. +#define PXLCSR_SLT_CLK_CFG_REF (0x1 << PXLCSR_SLT_CLK_CFG_OFFS)
  74246. +
  74247. +/* PCI Express Advanced Error Report Header Register */
  74248. +/*PEX_ADV_ERR_RPRT_HDR_TRGT_REG (PXAERHTR)*/
  74249. +
  74250. +/* PCI Express Uncorrectable Error Status Register*/
  74251. +/*PEX_UNCORRECT_ERR_STAT_REG (PXUESR)*/
  74252. +
  74253. +/* PCI Express Uncorrectable Error Mask Register */
  74254. +/*PEX_UNCORRECT_ERR_MASK_REG (PXUEMR)*/
  74255. +
  74256. +/* PCI Express Uncorrectable Error Severity Register */
  74257. +/*PEX_UNCORRECT_ERR_SERVITY_REG (PXUESR)*/
  74258. +
  74259. +/* PCI Express Correctable Error Status Register */
  74260. +/*PEX_CORRECT_ERR_STAT_REG (PXCESR)*/
  74261. +
  74262. +/* PCI Express Correctable Error Mask Register */
  74263. +/*PEX_CORRECT_ERR_MASK_REG (PXCEMR)*/
  74264. +
  74265. +/* PCI Express Advanced Error Capability and Control Register*/
  74266. +/*PEX_ADV_ERR_CAPABILITY_CTRL_REG (PXAECCR)*/
  74267. +
  74268. +/* PCI Express Header Log First DWORD Register*/
  74269. +/*PEX_HDR_LOG_FIRST_DWORD_REG (PXHLFDR)*/
  74270. +
  74271. +/* PCI Express Header Log Second DWORD Register*/
  74272. +/*PEX_HDR_LOG_SECOND_DWORD_REG (PXHLSDR)*/
  74273. +
  74274. +/* PCI Express Header Log Third DWORD Register*/
  74275. +/*PEX_HDR_LOG_THIRD_DWORD_REG (PXHLTDR)*/
  74276. +
  74277. +/* PCI Express Header Log Fourth DWORD Register*/
  74278. +/*PEX_HDR_LOG_FOURTH_DWORD_REG (PXHLFDR)*/
  74279. +
  74280. +#ifdef __cplusplus
  74281. +}
  74282. +#endif /* __cplusplus */
  74283. +
  74284. +#endif /* #ifndef __INCPEXREGSH */
  74285. +
  74286. +
  74287. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c
  74288. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c 1970-01-01 01:00:00.000000000 +0100
  74289. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c 2011-07-31 11:32:01.333424120 +0200
  74290. @@ -0,0 +1,313 @@
  74291. +/*******************************************************************************
  74292. +Copyright (C) Marvell International Ltd. and its affiliates
  74293. +
  74294. +This software file (the "File") is owned and distributed by Marvell
  74295. +International Ltd. and/or its affiliates ("Marvell") under the following
  74296. +alternative licensing terms. Once you have made an election to distribute the
  74297. +File under one of the following license alternatives, please (i) delete this
  74298. +introductory statement regarding license alternatives, (ii) delete the two
  74299. +license alternatives that you have not elected to use and (iii) preserve the
  74300. +Marvell copyright notice above.
  74301. +
  74302. +********************************************************************************
  74303. +Marvell Commercial License Option
  74304. +
  74305. +If you received this File from Marvell and you have entered into a commercial
  74306. +license agreement (a "Commercial License") with Marvell, the File is licensed
  74307. +to you under the terms of the applicable Commercial License.
  74308. +
  74309. +********************************************************************************
  74310. +Marvell GPL License Option
  74311. +
  74312. +If you received this File from Marvell, you may opt to use, redistribute and/or
  74313. +modify this File in accordance with the terms and conditions of the General
  74314. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  74315. +available along with the File in the license.txt file or by writing to the Free
  74316. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  74317. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  74318. +
  74319. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  74320. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  74321. +DISCLAIMED. The GPL License provides additional details about this warranty
  74322. +disclaimer.
  74323. +********************************************************************************
  74324. +Marvell BSD License Option
  74325. +
  74326. +If you received this File from Marvell, you may opt to use, redistribute and/or
  74327. +modify this File under the following licensing terms.
  74328. +Redistribution and use in source and binary forms, with or without modification,
  74329. +are permitted provided that the following conditions are met:
  74330. +
  74331. + * Redistributions of source code must retain the above copyright notice,
  74332. + this list of conditions and the following disclaimer.
  74333. +
  74334. + * Redistributions in binary form must reproduce the above copyright
  74335. + notice, this list of conditions and the following disclaimer in the
  74336. + documentation and/or other materials provided with the distribution.
  74337. +
  74338. + * Neither the name of Marvell nor the names of its contributors may be
  74339. + used to endorse or promote products derived from this software without
  74340. + specific prior written permission.
  74341. +
  74342. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  74343. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  74344. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  74345. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  74346. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  74347. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  74348. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  74349. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  74350. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  74351. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  74352. +
  74353. +*******************************************************************************/
  74354. +
  74355. +#include "mvPex.h"
  74356. +
  74357. +//#define MV_DEBUG
  74358. +/* defines */
  74359. +#ifdef MV_DEBUG
  74360. + #define DB(x) x
  74361. +#else
  74362. + #define DB(x)
  74363. +#endif
  74364. +
  74365. +/* locals */
  74366. +typedef struct
  74367. +{
  74368. + MV_U32 data;
  74369. + MV_U32 mask;
  74370. +}PEX_HEADER_DATA;
  74371. +
  74372. +/* local function forwad decleration */
  74373. +MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  74374. + MV_U32 regOff);
  74375. +MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  74376. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  74377. +void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev);
  74378. +
  74379. +
  74380. +PEX_HEADER_DATA configHdr[16] =
  74381. +{
  74382. +{0x888811ab, 0x00000000}, /*[device ID, vendor ID] */
  74383. +{0x00100007, 0x0000ffff}, /*[status register, command register] */
  74384. +{0x0604000e, 0x00000000}, /*[programming interface, sub class code, class code, revision ID] */
  74385. +{0x00010008, 0x00000000}, /*[BIST, header type, latency time, cache line] */
  74386. +{0x00000000, 0x00000000}, /*[base address 0] */
  74387. +{0x00000000, 0x00000000}, /*[base address 1] */
  74388. +{0x00000000, 0x00ffffff}, /*[secondary latency timersubordinate bus number, secondary bus number, primary bus number] */
  74389. +{0x0000f101, 0x00000000}, /*[secondary status ,IO limit, IO base] */
  74390. +{0x9ff0a000, 0x00000000}, /*[memory limit, memory base] */
  74391. +{0x0001fff1, 0x00000000}, /*[prefetch memory limit, prefetch memory base] */
  74392. +{0xffffffff, 0x00000000}, /*[prefetch memory base upper] */
  74393. +{0x00000000, 0x00000000}, /*[prefetch memory limit upper] */
  74394. +{0xeffff000, 0x00000000}, /*[IO limit upper 16 bits, IO base upper 16 bits] */
  74395. +{0x00000000, 0x00000000}, /*[reserved, capability pointer] */
  74396. +{0x00000000, 0x00000000}, /*[expansion ROM base address] */
  74397. +{0x00000000, 0x000000FF}, /*[bridge control, interrupt pin, interrupt line] */
  74398. +};
  74399. +
  74400. +
  74401. +#define HEADER_WRITE(data, offset) configHdr[offset/4].data = ((configHdr[offset/4].data & ~configHdr[offset/4].mask) | \
  74402. + (data & configHdr[offset/4].mask))
  74403. +#define HEADER_READ(offset) configHdr[offset/4].data
  74404. +
  74405. +/*******************************************************************************
  74406. +* mvVrtBrgPexInit - Initialize PEX interfaces
  74407. +*
  74408. +* DESCRIPTION:
  74409. +*
  74410. +* This function is responsible of intialization of the Pex Interface , It
  74411. +* configure the Pex Bars and Windows in the following manner:
  74412. +*
  74413. +* Assumptions :
  74414. +* Bar0 is always internal registers bar
  74415. +* Bar1 is always the DRAM bar
  74416. +* Bar2 is always the Device bar
  74417. +*
  74418. +* 1) Sets the Internal registers bar base by obtaining the base from
  74419. +* the CPU Interface
  74420. +* 2) Sets the DRAM bar base and size by getting the base and size from
  74421. +* the CPU Interface when the size is the sum of all enabled DRAM
  74422. +* chip selects and the base is the base of CS0 .
  74423. +* 3) Sets the Device bar base and size by getting these values from the
  74424. +* CPU Interface when the base is the base of the lowest base of the
  74425. +* Device chip selects, and the
  74426. +*
  74427. +*
  74428. +* INPUT:
  74429. +*
  74430. +* pexIf - PEX interface number.
  74431. +*
  74432. +*
  74433. +* OUTPUT:
  74434. +* None.
  74435. +*
  74436. +* RETURN:
  74437. +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
  74438. +*
  74439. +*******************************************************************************/
  74440. +MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf)
  74441. +{
  74442. + /* reset PEX tree to recover previous U-boot/Boot configurations */
  74443. + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
  74444. +
  74445. +
  74446. + resetPexConfig(pexIf, localBus, 1);
  74447. + return MV_OK;
  74448. +}
  74449. +
  74450. +
  74451. +MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  74452. + MV_U32 regOff)
  74453. +{
  74454. +
  74455. + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
  74456. + MV_U32 localDev = mvPexLocalDevNumGet(pexIf);
  74457. + MV_U32 val;
  74458. + if(bus == localBus)
  74459. + {
  74460. + if(dev > 1)
  74461. + {
  74462. +/* on the local device allow only device #0 & #1 */
  74463. + return 0xffffffff;
  74464. + }
  74465. + else
  74466. + if (dev == localDev)
  74467. + {
  74468. + /* read the memory controller registers */
  74469. + return mvPexHwConfigRead (pexIf, bus, dev, func, regOff);
  74470. + }
  74471. + else
  74472. + {
  74473. + /* access the virtual brg header */
  74474. + return HEADER_READ(regOff);
  74475. + }
  74476. + }
  74477. + else
  74478. + if(bus == (localBus + 1))
  74479. + {
  74480. + /* access the device behind the virtual bridge */
  74481. + if((dev == localDev) || (dev > 1))
  74482. + {
  74483. + return 0xffffffff;
  74484. + }
  74485. + else
  74486. + {
  74487. + /* access the device behind the virtual bridge, in this case
  74488. + * change the bus number to the local bus number in order to
  74489. + * generate type 0 config cycle
  74490. + */
  74491. + mvPexLocalBusNumSet(pexIf, bus);
  74492. + mvPexLocalDevNumSet(pexIf, 1);
  74493. + val = mvPexHwConfigRead (pexIf, bus, 0, func, regOff);
  74494. + mvPexLocalBusNumSet(pexIf, localBus);
  74495. + mvPexLocalDevNumSet(pexIf, localDev);
  74496. + return val;
  74497. + }
  74498. + }
  74499. + /* for all other devices use the HW function to get the
  74500. + * requested registers
  74501. + */
  74502. + mvPexLocalDevNumSet(pexIf, 1);
  74503. + val = mvPexHwConfigRead (pexIf, bus, dev, func, regOff);
  74504. + mvPexLocalDevNumSet(pexIf, localDev);
  74505. + return val;
  74506. +}
  74507. +
  74508. +
  74509. +MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  74510. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  74511. +{
  74512. + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
  74513. + MV_U32 localDev = mvPexLocalDevNumGet(pexIf);
  74514. + MV_STATUS status;
  74515. +
  74516. + if(bus == localBus)
  74517. + {
  74518. + if(dev > 1)
  74519. + {
  74520. + /* on the local device allow only device #0 & #1 */
  74521. + return MV_ERROR;
  74522. + }
  74523. + else
  74524. + if (dev == localDev)
  74525. + {
  74526. + /* read the memory controller registers */
  74527. + return mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);
  74528. + }
  74529. + else
  74530. + {
  74531. + /* access the virtual brg header */
  74532. + HEADER_WRITE(data, regOff);
  74533. + return MV_OK;
  74534. + }
  74535. + }
  74536. + else
  74537. + if(bus == (localBus + 1))
  74538. + {
  74539. + /* access the device behind the virtual bridge */
  74540. + if((dev == localDev) || (dev > 1))
  74541. + {
  74542. + return MV_ERROR;
  74543. + }
  74544. + else
  74545. + {
  74546. + /* access the device behind the virtual bridge, in this case
  74547. + * change the bus number to the local bus number in order to
  74548. + * generate type 0 config cycle
  74549. + */
  74550. + //return mvPexHwConfigWrite (pexIf, localBus, dev, func, regOff, data);
  74551. + mvPexLocalBusNumSet(pexIf, bus);
  74552. + mvPexLocalDevNumSet(pexIf, 1);
  74553. + status = mvPexHwConfigWrite (pexIf, bus, 0, func, regOff, data);
  74554. + mvPexLocalBusNumSet(pexIf, localBus);
  74555. + mvPexLocalDevNumSet(pexIf, localDev);
  74556. + return status;
  74557. +
  74558. + }
  74559. + }
  74560. + /* for all other devices use the HW function to get the
  74561. + * requested registers
  74562. + */
  74563. + mvPexLocalDevNumSet(pexIf, 1);
  74564. + status = mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);
  74565. + mvPexLocalDevNumSet(pexIf, localDev);
  74566. + return status;
  74567. +}
  74568. +
  74569. +
  74570. +
  74571. +
  74572. +void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev)
  74573. +{
  74574. + MV_U32 tData;
  74575. + MV_U32 i;
  74576. +
  74577. + /* restore the PEX configuration to initialization state */
  74578. + /* in case PEX P2P call recursive and reset config */
  74579. + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x0);
  74580. + if(tData != 0xffffffff)
  74581. + {
  74582. + /* agent had been found - check whether P2P */
  74583. + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x8);
  74584. + if((tData & 0xffff0000) == 0x06040000)
  74585. + {/* P2P */
  74586. + /* get the sec bus and the subordinate */
  74587. + MV_U32 secBus;
  74588. + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x18);
  74589. + secBus = ((tData >> 8) & 0xff);
  74590. + /* now scan on sec bus */
  74591. + for(i = 0;i < 0xff;i++)
  74592. + {
  74593. + resetPexConfig(pexIf, secBus, i);
  74594. + }
  74595. + /* now reset this device */
  74596. + DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));
  74597. + mvPexHwConfigWrite(pexIf, bus, dev, 0x0, 0x18, 0x0);
  74598. + DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));
  74599. + }
  74600. + }
  74601. +}
  74602. +
  74603. +
  74604. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h
  74605. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h 1970-01-01 01:00:00.000000000 +0100
  74606. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h 2011-07-31 11:32:01.383424915 +0200
  74607. @@ -0,0 +1,82 @@
  74608. +/*******************************************************************************
  74609. +Copyright (C) Marvell International Ltd. and its affiliates
  74610. +
  74611. +This software file (the "File") is owned and distributed by Marvell
  74612. +International Ltd. and/or its affiliates ("Marvell") under the following
  74613. +alternative licensing terms. Once you have made an election to distribute the
  74614. +File under one of the following license alternatives, please (i) delete this
  74615. +introductory statement regarding license alternatives, (ii) delete the two
  74616. +license alternatives that you have not elected to use and (iii) preserve the
  74617. +Marvell copyright notice above.
  74618. +
  74619. +********************************************************************************
  74620. +Marvell Commercial License Option
  74621. +
  74622. +If you received this File from Marvell and you have entered into a commercial
  74623. +license agreement (a "Commercial License") with Marvell, the File is licensed
  74624. +to you under the terms of the applicable Commercial License.
  74625. +
  74626. +********************************************************************************
  74627. +Marvell GPL License Option
  74628. +
  74629. +If you received this File from Marvell, you may opt to use, redistribute and/or
  74630. +modify this File in accordance with the terms and conditions of the General
  74631. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  74632. +available along with the File in the license.txt file or by writing to the Free
  74633. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  74634. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  74635. +
  74636. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  74637. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  74638. +DISCLAIMED. The GPL License provides additional details about this warranty
  74639. +disclaimer.
  74640. +********************************************************************************
  74641. +Marvell BSD License Option
  74642. +
  74643. +If you received this File from Marvell, you may opt to use, redistribute and/or
  74644. +modify this File under the following licensing terms.
  74645. +Redistribution and use in source and binary forms, with or without modification,
  74646. +are permitted provided that the following conditions are met:
  74647. +
  74648. + * Redistributions of source code must retain the above copyright notice,
  74649. + this list of conditions and the following disclaimer.
  74650. +
  74651. + * Redistributions in binary form must reproduce the above copyright
  74652. + notice, this list of conditions and the following disclaimer in the
  74653. + documentation and/or other materials provided with the distribution.
  74654. +
  74655. + * Neither the name of Marvell nor the names of its contributors may be
  74656. + used to endorse or promote products derived from this software without
  74657. + specific prior written permission.
  74658. +
  74659. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  74660. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  74661. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  74662. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  74663. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  74664. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  74665. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  74666. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  74667. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  74668. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  74669. +
  74670. +*******************************************************************************/
  74671. +
  74672. +#ifndef __INCVRTBRGPEXH
  74673. +#define __INCVRTBRGPEXH
  74674. +
  74675. +
  74676. +/* Global Functions prototypes */
  74677. +/* mvPexInit - Initialize PEX interfaces*/
  74678. +MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf);
  74679. +
  74680. +/* mvPexConfigRead - Read from configuration space */
  74681. +MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  74682. + MV_U32 func,MV_U32 regOff);
  74683. +
  74684. +/* mvPexConfigWrite - Write to configuration space */
  74685. +MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  74686. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  74687. +
  74688. +
  74689. +#endif /* #ifndef __INCPEXH */
  74690. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c
  74691. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c 1970-01-01 01:00:00.000000000 +0100
  74692. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c 2011-07-31 11:32:01.433415347 +0200
  74693. @@ -0,0 +1,1522 @@
  74694. +/*******************************************************************************
  74695. +Copyright (C) Marvell International Ltd. and its affiliates
  74696. +
  74697. +This software file (the "File") is owned and distributed by Marvell
  74698. +International Ltd. and/or its affiliates ("Marvell") under the following
  74699. +alternative licensing terms. Once you have made an election to distribute the
  74700. +File under one of the following license alternatives, please (i) delete this
  74701. +introductory statement regarding license alternatives, (ii) delete the two
  74702. +license alternatives that you have not elected to use and (iii) preserve the
  74703. +Marvell copyright notice above.
  74704. +
  74705. +********************************************************************************
  74706. +Marvell Commercial License Option
  74707. +
  74708. +If you received this File from Marvell and you have entered into a commercial
  74709. +license agreement (a "Commercial License") with Marvell, the File is licensed
  74710. +to you under the terms of the applicable Commercial License.
  74711. +
  74712. +********************************************************************************
  74713. +Marvell GPL License Option
  74714. +
  74715. +If you received this File from Marvell, you may opt to use, redistribute and/or
  74716. +modify this File in accordance with the terms and conditions of the General
  74717. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  74718. +available along with the File in the license.txt file or by writing to the Free
  74719. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  74720. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  74721. +
  74722. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  74723. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  74724. +DISCLAIMED. The GPL License provides additional details about this warranty
  74725. +disclaimer.
  74726. +********************************************************************************
  74727. +Marvell BSD License Option
  74728. +
  74729. +If you received this File from Marvell, you may opt to use, redistribute and/or
  74730. +modify this File under the following licensing terms.
  74731. +Redistribution and use in source and binary forms, with or without modification,
  74732. +are permitted provided that the following conditions are met:
  74733. +
  74734. + * Redistributions of source code must retain the above copyright notice,
  74735. + this list of conditions and the following disclaimer.
  74736. +
  74737. + * Redistributions in binary form must reproduce the above copyright
  74738. + notice, this list of conditions and the following disclaimer in the
  74739. + documentation and/or other materials provided with the distribution.
  74740. +
  74741. + * Neither the name of Marvell nor the names of its contributors may be
  74742. + used to endorse or promote products derived from this software without
  74743. + specific prior written permission.
  74744. +
  74745. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  74746. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  74747. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  74748. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  74749. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  74750. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  74751. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  74752. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  74753. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  74754. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  74755. +
  74756. +*******************************************************************************/
  74757. +#include "mvOs.h"
  74758. +#include "sflash/mvSFlash.h"
  74759. +#include "sflash/mvSFlashSpec.h"
  74760. +#include "spi/mvSpi.h"
  74761. +#include "spi/mvSpiCmnd.h"
  74762. +#include "ctrlEnv/mvCtrlEnvLib.h"
  74763. +
  74764. +/*#define MV_DEBUG*/
  74765. +#ifdef MV_DEBUG
  74766. +#define DB(x) x
  74767. +#else
  74768. +#define DB(x)
  74769. +#endif
  74770. +
  74771. +/* Globals */
  74772. +static MV_SFLASH_DEVICE_PARAMS sflash[] = {
  74773. + /* ST M25P32 SPI flash, 4MB, 64 sectors of 64K each */
  74774. + {
  74775. + MV_M25P_WREN_CMND_OPCD,
  74776. + MV_M25P_WRDI_CMND_OPCD,
  74777. + MV_M25P_RDID_CMND_OPCD,
  74778. + MV_M25P_RDSR_CMND_OPCD,
  74779. + MV_M25P_WRSR_CMND_OPCD,
  74780. + MV_M25P_READ_CMND_OPCD,
  74781. + MV_M25P_FAST_RD_CMND_OPCD,
  74782. + MV_M25P_PP_CMND_OPCD,
  74783. + MV_M25P_SE_CMND_OPCD,
  74784. + MV_M25P_BE_CMND_OPCD,
  74785. + MV_M25P_RES_CMND_OPCD,
  74786. + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
  74787. + MV_M25P32_SECTOR_SIZE,
  74788. + MV_M25P32_SECTOR_NUMBER,
  74789. + MV_M25P_PAGE_SIZE,
  74790. + "ST M25P32",
  74791. + MV_M25PXXX_ST_MANF_ID,
  74792. + MV_M25P32_DEVICE_ID,
  74793. + MV_M25P32_MAX_SPI_FREQ,
  74794. + MV_M25P32_MAX_FAST_SPI_FREQ,
  74795. + MV_M25P32_FAST_READ_DUMMY_BYTES
  74796. + },
  74797. + /* ST M25P64 SPI flash, 8MB, 128 sectors of 64K each */
  74798. + {
  74799. + MV_M25P_WREN_CMND_OPCD,
  74800. + MV_M25P_WRDI_CMND_OPCD,
  74801. + MV_M25P_RDID_CMND_OPCD,
  74802. + MV_M25P_RDSR_CMND_OPCD,
  74803. + MV_M25P_WRSR_CMND_OPCD,
  74804. + MV_M25P_READ_CMND_OPCD,
  74805. + MV_M25P_FAST_RD_CMND_OPCD,
  74806. + MV_M25P_PP_CMND_OPCD,
  74807. + MV_M25P_SE_CMND_OPCD,
  74808. + MV_M25P_BE_CMND_OPCD,
  74809. + MV_M25P_RES_CMND_OPCD,
  74810. + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
  74811. + MV_M25P64_SECTOR_SIZE,
  74812. + MV_M25P64_SECTOR_NUMBER,
  74813. + MV_M25P_PAGE_SIZE,
  74814. + "ST M25P64",
  74815. + MV_M25PXXX_ST_MANF_ID,
  74816. + MV_M25P64_DEVICE_ID,
  74817. + MV_M25P64_MAX_SPI_FREQ,
  74818. + MV_M25P64_MAX_FAST_SPI_FREQ,
  74819. + MV_M25P64_FAST_READ_DUMMY_BYTES
  74820. + },
  74821. + /* ST M25P128 SPI flash, 16MB, 64 sectors of 256K each */
  74822. + {
  74823. + MV_M25P_WREN_CMND_OPCD,
  74824. + MV_M25P_WRDI_CMND_OPCD,
  74825. + MV_M25P_RDID_CMND_OPCD,
  74826. + MV_M25P_RDSR_CMND_OPCD,
  74827. + MV_M25P_WRSR_CMND_OPCD,
  74828. + MV_M25P_READ_CMND_OPCD,
  74829. + MV_M25P_FAST_RD_CMND_OPCD,
  74830. + MV_M25P_PP_CMND_OPCD,
  74831. + MV_M25P_SE_CMND_OPCD,
  74832. + MV_M25P_BE_CMND_OPCD,
  74833. + MV_M25P_RES_CMND_OPCD,
  74834. + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
  74835. + MV_M25P128_SECTOR_SIZE,
  74836. + MV_M25P128_SECTOR_NUMBER,
  74837. + MV_M25P_PAGE_SIZE,
  74838. + "ST M25P128",
  74839. + MV_M25PXXX_ST_MANF_ID,
  74840. + MV_M25P128_DEVICE_ID,
  74841. + MV_M25P128_MAX_SPI_FREQ,
  74842. + MV_M25P128_MAX_FAST_SPI_FREQ,
  74843. + MV_M25P128_FAST_READ_DUMMY_BYTES
  74844. + },
  74845. + /* Macronix MXIC MX25L6405 SPI flash, 8MB, 128 sectors of 64K each */
  74846. + {
  74847. + MV_MX25L_WREN_CMND_OPCD,
  74848. + MV_MX25L_WRDI_CMND_OPCD,
  74849. + MV_MX25L_RDID_CMND_OPCD,
  74850. + MV_MX25L_RDSR_CMND_OPCD,
  74851. + MV_MX25L_WRSR_CMND_OPCD,
  74852. + MV_MX25L_READ_CMND_OPCD,
  74853. + MV_MX25L_FAST_RD_CMND_OPCD,
  74854. + MV_MX25L_PP_CMND_OPCD,
  74855. + MV_MX25L_SE_CMND_OPCD,
  74856. + MV_MX25L_BE_CMND_OPCD,
  74857. + MV_MX25L_RES_CMND_OPCD,
  74858. + MV_MX25L_DP_CMND_OPCD,
  74859. + MV_MX25L6405_SECTOR_SIZE,
  74860. + MV_MX25L6405_SECTOR_NUMBER,
  74861. + MV_MXIC_PAGE_SIZE,
  74862. + "MXIC MX25L6405",
  74863. + MV_MXIC_MANF_ID,
  74864. + MV_MX25L6405_DEVICE_ID,
  74865. + MV_MX25L6405_MAX_SPI_FREQ,
  74866. + MV_MX25L6405_MAX_FAST_SPI_FREQ,
  74867. + MV_MX25L6405_FAST_READ_DUMMY_BYTES
  74868. + },
  74869. + /* SPANSION S25FL128P SPI flash, 16MB, 64 sectors of 256K each */
  74870. + {
  74871. + MV_S25FL_WREN_CMND_OPCD,
  74872. + MV_S25FL_WRDI_CMND_OPCD,
  74873. + MV_S25FL_RDID_CMND_OPCD,
  74874. + MV_S25FL_RDSR_CMND_OPCD,
  74875. + MV_S25FL_WRSR_CMND_OPCD,
  74876. + MV_S25FL_READ_CMND_OPCD,
  74877. + MV_S25FL_FAST_RD_CMND_OPCD,
  74878. + MV_S25FL_PP_CMND_OPCD,
  74879. + MV_S25FL_SE_CMND_OPCD,
  74880. + MV_S25FL_BE_CMND_OPCD,
  74881. + MV_S25FL_RES_CMND_OPCD,
  74882. + MV_S25FL_DP_CMND_OPCD,
  74883. + MV_S25FL128_SECTOR_SIZE,
  74884. + MV_S25FL128_SECTOR_NUMBER,
  74885. + MV_S25FL_PAGE_SIZE,
  74886. + "SPANSION S25FL128",
  74887. + MV_SPANSION_MANF_ID,
  74888. + MV_S25FL128_DEVICE_ID,
  74889. + MV_S25FL128_MAX_SPI_FREQ,
  74890. + MV_M25P128_MAX_FAST_SPI_FREQ,
  74891. + MV_M25P128_FAST_READ_DUMMY_BYTES
  74892. + }
  74893. +};
  74894. +
  74895. +/* Static Functions */
  74896. +static MV_STATUS mvWriteEnable (MV_SFLASH_INFO * pFlinfo);
  74897. +static MV_STATUS mvStatusRegGet (MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg);
  74898. +static MV_STATUS mvStatusRegSet (MV_SFLASH_INFO * pFlinfo, MV_U8 sr);
  74899. +static MV_STATUS mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo);
  74900. +static MV_STATUS mvSFlashPageWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset, \
  74901. + MV_U8* pPageBuff, MV_U32 buffSize);
  74902. +static MV_STATUS mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, \
  74903. + MV_U8* manId, MV_U16* devId);
  74904. +
  74905. +/*******************************************************************************
  74906. +* mvWriteEnable - serialize the write enable sequence
  74907. +*
  74908. +* DESCRIPTION:
  74909. +* transmit the sequence for write enable
  74910. +*
  74911. +********************************************************************************/
  74912. +static MV_STATUS mvWriteEnable(MV_SFLASH_INFO * pFlinfo)
  74913. +{
  74914. + MV_U8 cmd[MV_SFLASH_WREN_CMND_LENGTH];
  74915. +
  74916. +
  74917. + cmd[0] = sflash[pFlinfo->index].opcdWREN;
  74918. +
  74919. + return mvSpiWriteThenRead(cmd, MV_SFLASH_WREN_CMND_LENGTH, NULL, 0, 0);
  74920. +}
  74921. +
  74922. +/*******************************************************************************
  74923. +* mvStatusRegGet - Retrieve the value of the status register
  74924. +*
  74925. +* DESCRIPTION:
  74926. +* perform the RDSR sequence to get the 8bit status register
  74927. +*
  74928. +********************************************************************************/
  74929. +static MV_STATUS mvStatusRegGet(MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg)
  74930. +{
  74931. + MV_STATUS ret;
  74932. + MV_U8 cmd[MV_SFLASH_RDSR_CMND_LENGTH];
  74933. + MV_U8 sr[MV_SFLASH_RDSR_REPLY_LENGTH];
  74934. +
  74935. +
  74936. +
  74937. +
  74938. + cmd[0] = sflash[pFlinfo->index].opcdRDSR;
  74939. +
  74940. + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDSR_CMND_LENGTH, sr,
  74941. + MV_SFLASH_RDSR_REPLY_LENGTH,0)) != MV_OK)
  74942. + return ret;
  74943. +
  74944. + *pStatReg = sr[0];
  74945. +
  74946. + return MV_OK;
  74947. +}
  74948. +
  74949. +/*******************************************************************************
  74950. +* mvWaitOnWipClear - Block waiting for the WIP (write in progress) to be cleared
  74951. +*
  74952. +* DESCRIPTION:
  74953. +* Block waiting for the WIP (write in progress) to be cleared
  74954. +*
  74955. +********************************************************************************/
  74956. +static MV_STATUS mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo)
  74957. +{
  74958. + MV_STATUS ret;
  74959. + MV_U32 i;
  74960. + MV_U8 stat;
  74961. +
  74962. + for (i=0; i<MV_SFLASH_MAX_WAIT_LOOP; i++)
  74963. + {
  74964. + if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)
  74965. + return ret;
  74966. +
  74967. + if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)
  74968. + return MV_OK;
  74969. + }
  74970. +
  74971. + DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)
  74972. + return MV_TIMEOUT;
  74973. +}
  74974. +
  74975. +/*******************************************************************************
  74976. +* mvWaitOnChipEraseDone - Block waiting for the WIP (write in progress) to be
  74977. +* cleared after a chip erase command which is supposed
  74978. +* to take about 2:30 minutes
  74979. +*
  74980. +* DESCRIPTION:
  74981. +* Block waiting for the WIP (write in progress) to be cleared
  74982. +*
  74983. +********************************************************************************/
  74984. +static MV_STATUS mvWaitOnChipEraseDone(MV_SFLASH_INFO * pFlinfo)
  74985. +{
  74986. + MV_STATUS ret;
  74987. + MV_U32 i;
  74988. + MV_U8 stat;
  74989. +
  74990. + for (i=0; i<MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP; i++)
  74991. + {
  74992. + if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)
  74993. + return ret;
  74994. +
  74995. + if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)
  74996. + return MV_OK;
  74997. + }
  74998. +
  74999. + DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)
  75000. + return MV_TIMEOUT;
  75001. +}
  75002. +
  75003. +/*******************************************************************************
  75004. +* mvStatusRegSet - Set the value of the 8bit status register
  75005. +*
  75006. +* DESCRIPTION:
  75007. +* Set the value of the 8bit status register
  75008. +*
  75009. +********************************************************************************/
  75010. +static MV_STATUS mvStatusRegSet(MV_SFLASH_INFO * pFlinfo, MV_U8 sr)
  75011. +{
  75012. + MV_STATUS ret;
  75013. + MV_U8 cmd[MV_SFLASH_WRSR_CMND_LENGTH];
  75014. +
  75015. +
  75016. + /* Issue the Write enable command prior the WRSR command */
  75017. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  75018. + return ret;
  75019. +
  75020. + /* Write the SR with the new values */
  75021. + cmd[0] = sflash[pFlinfo->index].opcdWRSR;
  75022. + cmd[1] = sr;
  75023. +
  75024. + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_WRSR_CMND_LENGTH, NULL, 0, 0)) != MV_OK)
  75025. + return ret;
  75026. +
  75027. + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
  75028. + return ret;
  75029. +
  75030. + mvOsDelay(1);
  75031. +
  75032. + return MV_OK;
  75033. +}
  75034. +
  75035. +/*******************************************************************************
  75036. +* mvSFlashPageWr - Write up to 256 Bytes in the same page
  75037. +*
  75038. +* DESCRIPTION:
  75039. +* Write a buffer up to the page size in length provided that the whole address
  75040. +* range is within the same page (alligned to page bounderies)
  75041. +*
  75042. +*******************************************************************************/
  75043. +static MV_STATUS mvSFlashPageWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  75044. + MV_U8* pPageBuff, MV_U32 buffSize)
  75045. +{
  75046. + MV_STATUS ret;
  75047. + MV_U8 cmd[MV_SFLASH_PP_CMND_LENGTH];
  75048. +
  75049. +
  75050. + /* Protection - check if the model was detected */
  75051. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75052. + {
  75053. + DB(mvOsPrintf("%s WARNING: Invalid parameter device index!\n", __FUNCTION__);)
  75054. + return MV_BAD_PARAM;
  75055. + }
  75056. +
  75057. + /* check that we do not cross the page bounderies */
  75058. + if (((offset & (sflash[pFlinfo->index].pageSize - 1)) + buffSize) >
  75059. + sflash[pFlinfo->index].pageSize)
  75060. + {
  75061. + DB(mvOsPrintf("%s WARNING: Page allignment problem!\n", __FUNCTION__);)
  75062. + return MV_OUT_OF_RANGE;
  75063. + }
  75064. +
  75065. + /* Issue the Write enable command prior the page program command */
  75066. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  75067. + return ret;
  75068. +
  75069. + cmd[0] = sflash[pFlinfo->index].opcdPP;
  75070. + cmd[1] = ((offset >> 16) & 0xFF);
  75071. + cmd[2] = ((offset >> 8) & 0xFF);
  75072. + cmd[3] = (offset & 0xFF);
  75073. +
  75074. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_PP_CMND_LENGTH, pPageBuff, buffSize)) != MV_OK)
  75075. + return ret;
  75076. +
  75077. + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
  75078. + return ret;
  75079. +
  75080. + return MV_OK;
  75081. +}
  75082. +
  75083. +/*******************************************************************************
  75084. +* mvSFlashWithDefaultsIdGet - Try to read the manufacturer and Device IDs from
  75085. +* the device using the default RDID opcode and the default WREN opcode.
  75086. +*
  75087. +* DESCRIPTION:
  75088. +* This is used to detect a generic device that uses the default opcodes
  75089. +* for the WREN and RDID.
  75090. +*
  75091. +********************************************************************************/
  75092. +static MV_STATUS mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* manId, MV_U16* devId)
  75093. +{
  75094. + MV_STATUS ret;
  75095. + MV_U8 cmdRDID[MV_SFLASH_RDID_CMND_LENGTH];
  75096. + MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];
  75097. +
  75098. +
  75099. +
  75100. + /* Use the default RDID opcode to read the IDs */
  75101. + cmdRDID[0] = MV_SFLASH_DEFAULT_RDID_OPCD; /* unknown model try default */
  75102. + if ((ret = mvSpiWriteThenRead(cmdRDID, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)
  75103. + return ret;
  75104. +
  75105. + *manId = id[0];
  75106. + *devId = 0;
  75107. + *devId |= (id[1] << 8);
  75108. + *devId |= id[2];
  75109. +
  75110. + return MV_OK;
  75111. +}
  75112. +
  75113. +/*
  75114. +#####################################################################################
  75115. +#####################################################################################
  75116. +*/
  75117. +
  75118. +/*******************************************************************************
  75119. +* mvSFlashInit - Initialize the serial flash device
  75120. +*
  75121. +* DESCRIPTION:
  75122. +* Perform the neccessary initialization and configuration
  75123. +*
  75124. +* INPUT:
  75125. +* pFlinfo: pointer to the Flash information structure
  75126. +* pFlinfo->baseAddr: base address in fast mode.
  75127. +* pFlinfo->index: Index of the flash in the sflash tabel. If the SPI
  75128. +* flash device does not support read Id command with
  75129. +* the standard opcode, then the user should supply this
  75130. +* as an input to skip the autodetection process!!!!
  75131. +*
  75132. +* OUTPUT:
  75133. +* pFlinfo: pointer to the Flash information structure after detection
  75134. +* pFlinfo->manufacturerId: Manufacturer ID
  75135. +* pFlinfo->deviceId: Device ID
  75136. +* pFlinfo->sectorSize: size of the sector (all sectors are the same).
  75137. +* pFlinfo->sectorNumber: number of sectors.
  75138. +* pFlinfo->pageSize: size of the page.
  75139. +* pFlinfo->index: Index of the detected flash in the sflash tabel
  75140. +*
  75141. +* RETURN:
  75142. +* Success or Error code.
  75143. +*
  75144. +*
  75145. +*******************************************************************************/
  75146. +MV_STATUS mvSFlashInit (MV_SFLASH_INFO * pFlinfo)
  75147. +{
  75148. + MV_STATUS ret;
  75149. + MV_U8 manf;
  75150. + MV_U16 dev;
  75151. + MV_U32 indx;
  75152. + MV_BOOL detectFlag = MV_FALSE;
  75153. +
  75154. + /* check for NULL pointer */
  75155. + if (pFlinfo == NULL)
  75156. + {
  75157. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75158. + return MV_BAD_PARAM;
  75159. + }
  75160. +
  75161. + /* Initialize the SPI interface with low frequency to make sure that the read ID succeeds */
  75162. + if ((ret = mvSpiInit(MV_SFLASH_BASIC_SPI_FREQ)) != MV_OK)
  75163. + {
  75164. + mvOsPrintf("%s ERROR: Failed to initialize the SPI interface!\n", __FUNCTION__);
  75165. + return ret;
  75166. + }
  75167. +
  75168. + /* First try to read the Manufacturer and Device IDs */
  75169. + if ((ret = mvSFlashIdGet(pFlinfo, &manf, &dev)) != MV_OK)
  75170. + {
  75171. + mvOsPrintf("%s ERROR: Failed to get the SFlash ID!\n", __FUNCTION__);
  75172. + return ret;
  75173. + }
  75174. +
  75175. + /* loop over the whole table and look for the appropriate SFLASH */
  75176. + for (indx=0; indx<MV_ARRAY_SIZE(sflash); indx++)
  75177. + {
  75178. + if ((manf == sflash[indx].manufacturerId) && (dev == sflash[indx].deviceId))
  75179. + {
  75180. + pFlinfo->manufacturerId = manf;
  75181. + pFlinfo->deviceId = dev;
  75182. + pFlinfo->index = indx;
  75183. + detectFlag = MV_TRUE;
  75184. + }
  75185. + }
  75186. +
  75187. + if(!detectFlag)
  75188. + {
  75189. + mvOsPrintf("%s ERROR: Unknown SPI flash device!\n", __FUNCTION__);
  75190. + return MV_FAIL;
  75191. + }
  75192. +
  75193. + /* fill the info based on the model detected */
  75194. + pFlinfo->sectorSize = sflash[pFlinfo->index].sectorSize;
  75195. + pFlinfo->sectorNumber = sflash[pFlinfo->index].sectorNumber;
  75196. + pFlinfo->pageSize = sflash[pFlinfo->index].pageSize;
  75197. +
  75198. + /* Set the SPI frequency to the MAX allowed for the device for best performance */
  75199. + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)
  75200. + {
  75201. + mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);
  75202. + return ret;
  75203. + }
  75204. +
  75205. + /* As default lock the SR */
  75206. + if ((ret = mvSFlashStatRegLock(pFlinfo, MV_TRUE)) != MV_OK)
  75207. + return ret;
  75208. +
  75209. + return MV_OK;
  75210. +}
  75211. +
  75212. +/*******************************************************************************
  75213. +* mvSFlashSectorErase - Erasse a single sector of the serial flash
  75214. +*
  75215. +* DESCRIPTION:
  75216. +* Issue the erase sector command and address
  75217. +*
  75218. +* INPUT:
  75219. +* pFlinfo: pointer to the Flash information structure
  75220. +* secNumber: sector Number to erase (0 -> (sectorNumber-1))
  75221. +*
  75222. +* OUTPUT:
  75223. +* None
  75224. +*
  75225. +* RETURN:
  75226. +* Success or Error code.
  75227. +*
  75228. +*
  75229. +*******************************************************************************/
  75230. +MV_STATUS mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber)
  75231. +{
  75232. + MV_STATUS ret;
  75233. + MV_U8 cmd[MV_SFLASH_SE_CMND_LENGTH];
  75234. +
  75235. + MV_U32 secAddr = (secNumber * pFlinfo->sectorSize);
  75236. +#if 0
  75237. + MV_U32 i;
  75238. + MV_U32 * pW = (MV_U32*) (secAddr + pFlinfo->baseAddr);
  75239. + MV_U32 erasedWord = 0xFFFFFFFF;
  75240. + MV_U32 wordsPerSector = (pFlinfo->sectorSize / sizeof(MV_U32));
  75241. + MV_BOOL eraseNeeded = MV_FALSE;
  75242. +#endif
  75243. + /* check for NULL pointer */
  75244. + if (pFlinfo == NULL)
  75245. + {
  75246. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75247. + return MV_BAD_PARAM;
  75248. + }
  75249. +
  75250. + /* Protection - check if the model was detected */
  75251. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75252. + {
  75253. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75254. + return MV_BAD_PARAM;
  75255. + }
  75256. +
  75257. + /* check that the sector number is valid */
  75258. + if (secNumber >= pFlinfo->sectorNumber)
  75259. + {
  75260. + DB(mvOsPrintf("%s WARNING: Invaild parameter sector number!\n", __FUNCTION__);)
  75261. + return MV_BAD_PARAM;
  75262. + }
  75263. +
  75264. + /* we don't want to access SPI in direct mode from in-direct API,
  75265. + becasue of timing issue between CS asserts. */
  75266. +#if 0
  75267. + /* First compare to FF and check if erase is needed */
  75268. + for (i=0; i<wordsPerSector; i++)
  75269. + {
  75270. + if (memcmp(pW, &erasedWord, sizeof(MV_U32)) != 0)
  75271. + {
  75272. + eraseNeeded = MV_TRUE;
  75273. + break;
  75274. + }
  75275. +
  75276. + ++pW;
  75277. + }
  75278. + if (!eraseNeeded)
  75279. + return MV_OK;
  75280. +#endif
  75281. +
  75282. + cmd[0] = sflash[pFlinfo->index].opcdSE;
  75283. + cmd[1] = ((secAddr >> 16) & 0xFF);
  75284. + cmd[2] = ((secAddr >> 8) & 0xFF);
  75285. + cmd[3] = (secAddr & 0xFF);
  75286. +
  75287. + /* Issue the Write enable command prior the sector erase command */
  75288. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  75289. + return ret;
  75290. +
  75291. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_SE_CMND_LENGTH, NULL, 0)) != MV_OK)
  75292. + return ret;
  75293. +
  75294. + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
  75295. + return ret;
  75296. +
  75297. + return MV_OK;
  75298. +}
  75299. +
  75300. +/*******************************************************************************
  75301. +* mvSFlashChipErase - Erasse the whole serial flash
  75302. +*
  75303. +* DESCRIPTION:
  75304. +* Issue the bulk (chip) erase command
  75305. +*
  75306. +* INPUT:
  75307. +* pFlinfo: pointer to the Flash information structure
  75308. +*
  75309. +* OUTPUT:
  75310. +* None
  75311. +*
  75312. +* RETURN:
  75313. +* Success or Error code.
  75314. +*
  75315. +*
  75316. +*******************************************************************************/
  75317. +MV_STATUS mvSFlashChipErase (MV_SFLASH_INFO * pFlinfo)
  75318. +{
  75319. + MV_STATUS ret;
  75320. + MV_U8 cmd[MV_SFLASH_BE_CMND_LENGTH];
  75321. +
  75322. +
  75323. + /* check for NULL pointer */
  75324. + if (pFlinfo == NULL)
  75325. + {
  75326. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75327. + return MV_BAD_PARAM;
  75328. + }
  75329. +
  75330. + /* Protection - check if the model was detected */
  75331. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75332. + {
  75333. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75334. + return MV_BAD_PARAM;
  75335. + }
  75336. +
  75337. + cmd[0] = sflash[pFlinfo->index].opcdBE;
  75338. +
  75339. + /* Issue the Write enable command prior the Bulk erase command */
  75340. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  75341. + return ret;
  75342. +
  75343. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_BE_CMND_LENGTH, NULL, 0)) != MV_OK)
  75344. + return ret;
  75345. +
  75346. + if ((ret = mvWaitOnChipEraseDone(pFlinfo)) != MV_OK)
  75347. + return ret;
  75348. +
  75349. + return MV_OK;
  75350. +}
  75351. +
  75352. +/*******************************************************************************
  75353. +* mvSFlashBlockRd - Read from the serial flash
  75354. +*
  75355. +* DESCRIPTION:
  75356. +* Issue the read command and address then perfom the needed read
  75357. +*
  75358. +* INPUT:
  75359. +* pFlinfo: pointer to the Flash information structure
  75360. +* offset: byte offset with the flash to start reading from
  75361. +* pReadBuff: pointer to the buffer to read the data in
  75362. +* buffSize: size of the buffer to read.
  75363. +*
  75364. +* OUTPUT:
  75365. +* pReadBuff: pointer to the buffer containing the read data
  75366. +*
  75367. +* RETURN:
  75368. +* Success or Error code.
  75369. +*
  75370. +*
  75371. +*******************************************************************************/
  75372. +MV_STATUS mvSFlashBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  75373. + MV_U8* pReadBuff, MV_U32 buffSize)
  75374. +{
  75375. + MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];
  75376. +
  75377. +
  75378. + /* check for NULL pointer */
  75379. + if ((pFlinfo == NULL) || (pReadBuff == NULL))
  75380. + {
  75381. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75382. + return MV_BAD_PARAM;
  75383. + }
  75384. +
  75385. + /* Protection - check if the model was detected */
  75386. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75387. + {
  75388. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75389. + return MV_BAD_PARAM;
  75390. + }
  75391. +
  75392. + cmd[0] = sflash[pFlinfo->index].opcdREAD;
  75393. + cmd[1] = ((offset >> 16) & 0xFF);
  75394. + cmd[2] = ((offset >> 8) & 0xFF);
  75395. + cmd[3] = (offset & 0xFF);
  75396. +
  75397. + return mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize, 0);
  75398. +}
  75399. +
  75400. +/*******************************************************************************
  75401. +* mvSFlashFastBlockRd - Fast read from the serial flash
  75402. +*
  75403. +* DESCRIPTION:
  75404. +* Issue the fast read command and address then perfom the needed read
  75405. +*
  75406. +* INPUT:
  75407. +* pFlinfo: pointer to the Flash information structure
  75408. +* offset: byte offset with the flash to start reading from
  75409. +* pReadBuff: pointer to the buffer to read the data in
  75410. +* buffSize: size of the buffer to read.
  75411. +*
  75412. +* OUTPUT:
  75413. +* pReadBuff: pointer to the buffer containing the read data
  75414. +*
  75415. +* RETURN:
  75416. +* Success or Error code.
  75417. +*
  75418. +*
  75419. +*******************************************************************************/
  75420. +MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  75421. + MV_U8* pReadBuff, MV_U32 buffSize)
  75422. +{
  75423. + MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];
  75424. + MV_STATUS ret;
  75425. +
  75426. + /* check for NULL pointer */
  75427. + if ((pFlinfo == NULL) || (pReadBuff == NULL))
  75428. + {
  75429. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75430. + return MV_BAD_PARAM;
  75431. + }
  75432. +
  75433. + /* Protection - check if the model was detected */
  75434. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75435. + {
  75436. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75437. + return MV_BAD_PARAM;
  75438. + }
  75439. +
  75440. + /* Set the SPI frequency to the MAX allowed for fast-read operations */
  75441. + mvOsPrintf("Setting freq to %d.\n",sflash[pFlinfo->index].spiMaxFastFreq);
  75442. + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFastFreq)) != MV_OK)
  75443. + {
  75444. + mvOsPrintf("%s ERROR: Failed to set the SPI fast frequency!\n", __FUNCTION__);
  75445. + return ret;
  75446. + }
  75447. +
  75448. + cmd[0] = sflash[pFlinfo->index].opcdFSTRD;
  75449. + cmd[1] = ((offset >> 16) & 0xFF);
  75450. + cmd[2] = ((offset >> 8) & 0xFF);
  75451. + cmd[3] = (offset & 0xFF);
  75452. +
  75453. +
  75454. + ret = mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize,
  75455. + sflash[pFlinfo->index].spiFastRdDummyBytes);
  75456. +
  75457. + /* Reset the SPI frequency to the MAX allowed for the device for best performance */
  75458. + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)
  75459. + {
  75460. + mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);
  75461. + return ret;
  75462. + }
  75463. +
  75464. + return ret;
  75465. +}
  75466. +
  75467. +
  75468. +/*******************************************************************************
  75469. +* mvSFlashBlockWr - Write a buffer with any size
  75470. +*
  75471. +* DESCRIPTION:
  75472. +* write regardless of the page boundaries and size limit per Page
  75473. +* program command
  75474. +*
  75475. +* INPUT:
  75476. +* pFlinfo: pointer to the Flash information structure
  75477. +* offset: byte offset within the flash region
  75478. +* pWriteBuff: pointer to the buffer holding the data to program
  75479. +* buffSize: size of the buffer to write
  75480. +*
  75481. +* OUTPUT:
  75482. +* None
  75483. +*
  75484. +* RETURN:
  75485. +* Success or Error code.
  75486. +*
  75487. +*
  75488. +*******************************************************************************/
  75489. +MV_STATUS mvSFlashBlockWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  75490. + MV_U8* pWriteBuff, MV_U32 buffSize)
  75491. +{
  75492. + MV_STATUS ret;
  75493. + MV_U32 data2write = buffSize;
  75494. + MV_U32 preAllOffset = (offset & MV_SFLASH_PAGE_ALLIGN_MASK(MV_M25P_PAGE_SIZE));
  75495. + MV_U32 preAllSz = (preAllOffset ? (MV_M25P_PAGE_SIZE - preAllOffset) : 0);
  75496. + MV_U32 writeOffset = offset;
  75497. +
  75498. + /* check for NULL pointer */
  75499. +#ifndef CONFIG_MARVELL
  75500. + if(NULL == pWriteBuff)
  75501. + {
  75502. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75503. + return MV_BAD_PARAM;
  75504. + }
  75505. +#endif
  75506. +
  75507. + if (pFlinfo == NULL)
  75508. + {
  75509. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75510. + return MV_BAD_PARAM;
  75511. + }
  75512. +
  75513. + /* Protection - check if the model was detected */
  75514. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75515. + {
  75516. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75517. + return MV_BAD_PARAM;
  75518. + }
  75519. +
  75520. + /* check that the buffer size does not exceed the flash size */
  75521. + if ((offset + buffSize) > mvSFlashSizeGet(pFlinfo))
  75522. + {
  75523. + DB(mvOsPrintf("%s WARNING: Write exceeds flash size!\n", __FUNCTION__);)
  75524. + return MV_OUT_OF_RANGE;
  75525. + }
  75526. +
  75527. + /* check if the total block size is less than the first chunk remainder */
  75528. + if (data2write < preAllSz)
  75529. + preAllSz = data2write;
  75530. +
  75531. + /* check if programing does not start at a 64byte alligned offset */
  75532. + if (preAllSz)
  75533. + {
  75534. + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, preAllSz)) != MV_OK)
  75535. + return ret;
  75536. +
  75537. + /* increment pointers and counters */
  75538. + writeOffset += preAllSz;
  75539. + data2write -= preAllSz;
  75540. + pWriteBuff += preAllSz;
  75541. + }
  75542. +
  75543. + /* program the data that fits in complete page chunks */
  75544. + while (data2write >= sflash[pFlinfo->index].pageSize)
  75545. + {
  75546. + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, sflash[pFlinfo->index].pageSize)) != MV_OK)
  75547. + return ret;
  75548. +
  75549. + /* increment pointers and counters */
  75550. + writeOffset += sflash[pFlinfo->index].pageSize;
  75551. + data2write -= sflash[pFlinfo->index].pageSize;
  75552. + pWriteBuff += sflash[pFlinfo->index].pageSize;
  75553. + }
  75554. +
  75555. + /* program the last partial chunk */
  75556. + if (data2write)
  75557. + {
  75558. + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, data2write)) != MV_OK)
  75559. + return ret;
  75560. + }
  75561. +
  75562. + return MV_OK;
  75563. +}
  75564. +
  75565. +/*******************************************************************************
  75566. +* mvSFlashIdGet - Get the manufacturer and device IDs.
  75567. +*
  75568. +* DESCRIPTION:
  75569. +* Get the Manufacturer and device IDs from the serial flash through
  75570. +* writing the RDID command then reading 3 bytes of data. In case that
  75571. +* this command was called for the first time in order to detect the
  75572. +* manufacturer and device IDs, then the default RDID opcode will be used
  75573. +* unless the device index is indicated by the user (in case the SPI flash
  75574. +* does not use the default RDID opcode).
  75575. +*
  75576. +* INPUT:
  75577. +* pFlinfo: pointer to the Flash information structure
  75578. +* pManId: pointer to the 8bit variable to hold the manufacturing ID
  75579. +* pDevId: pointer to the 16bit variable to hold the device ID
  75580. +*
  75581. +* OUTPUT:
  75582. +* pManId: pointer to the 8bit variable holding the manufacturing ID
  75583. +* pDevId: pointer to the 16bit variable holding the device ID
  75584. +*
  75585. +* RETURN:
  75586. +* Success or Error code.
  75587. +*
  75588. +*
  75589. +*******************************************************************************/
  75590. +MV_STATUS mvSFlashIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId)
  75591. +{
  75592. + MV_STATUS ret;
  75593. + MV_U8 cmd[MV_SFLASH_RDID_CMND_LENGTH];
  75594. + MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];
  75595. +
  75596. +
  75597. +
  75598. + /* check for NULL pointer */
  75599. + if ((pFlinfo == NULL) || (pManId == NULL) || (pDevId == NULL))
  75600. + {
  75601. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75602. + return MV_BAD_PARAM;
  75603. + }
  75604. +
  75605. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75606. + return mvSFlashWithDefaultsIdGet(pFlinfo, pManId, pDevId);
  75607. + else
  75608. + cmd[0] = sflash[pFlinfo->index].opcdRDID;
  75609. +
  75610. + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)
  75611. + return ret;
  75612. +
  75613. + *pManId = id[0];
  75614. + *pDevId = 0;
  75615. + *pDevId |= (id[1] << 8);
  75616. + *pDevId |= id[2];
  75617. +
  75618. + return MV_OK;
  75619. +}
  75620. +
  75621. +/*******************************************************************************
  75622. +* mvSFlashWpRegionSet - Set the Write-Protected region
  75623. +*
  75624. +* DESCRIPTION:
  75625. +* Set the Write-Protected region
  75626. +*
  75627. +* INPUT:
  75628. +* pFlinfo: pointer to the Flash information structure
  75629. +* wpRegion: which region will be protected
  75630. +*
  75631. +* OUTPUT:
  75632. +* None
  75633. +*
  75634. +* RETURN:
  75635. +* Success or Error code.
  75636. +*
  75637. +*
  75638. +*******************************************************************************/
  75639. +MV_STATUS mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion)
  75640. +{
  75641. + MV_U8 wpMask;
  75642. +
  75643. + /* check for NULL pointer */
  75644. + if (pFlinfo == NULL)
  75645. + {
  75646. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75647. + return MV_BAD_PARAM;
  75648. + }
  75649. +
  75650. + /* Protection - check if the model was detected */
  75651. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75652. + {
  75653. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75654. + return MV_BAD_PARAM;
  75655. + }
  75656. +
  75657. + /* Check if the chip is an ST flash; then WP supports only 3 bits */
  75658. + if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)
  75659. + {
  75660. + switch (wpRegion)
  75661. + {
  75662. + case MV_WP_NONE:
  75663. + wpMask = MV_M25P_STATUS_BP_NONE;
  75664. + break;
  75665. +
  75666. + case MV_WP_UPR_1OF128:
  75667. + DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)
  75668. + return MV_NOT_SUPPORTED;
  75669. +
  75670. + case MV_WP_UPR_1OF64:
  75671. + wpMask = MV_M25P_STATUS_BP_1_OF_64;
  75672. + break;
  75673. +
  75674. + case MV_WP_UPR_1OF32:
  75675. + wpMask = MV_M25P_STATUS_BP_1_OF_32;
  75676. + break;
  75677. +
  75678. + case MV_WP_UPR_1OF16:
  75679. + wpMask = MV_M25P_STATUS_BP_1_OF_16;
  75680. + break;
  75681. +
  75682. + case MV_WP_UPR_1OF8:
  75683. + wpMask = MV_M25P_STATUS_BP_1_OF_8;
  75684. + break;
  75685. +
  75686. + case MV_WP_UPR_1OF4:
  75687. + wpMask = MV_M25P_STATUS_BP_1_OF_4;
  75688. + break;
  75689. +
  75690. + case MV_WP_UPR_1OF2:
  75691. + wpMask = MV_M25P_STATUS_BP_1_OF_2;
  75692. + break;
  75693. +
  75694. + case MV_WP_ALL:
  75695. + wpMask = MV_M25P_STATUS_BP_ALL;
  75696. + break;
  75697. +
  75698. + default:
  75699. + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
  75700. + return MV_BAD_PARAM;
  75701. + }
  75702. + }
  75703. + /* check if the manufacturer is MXIC then the WP is 4bits */
  75704. + else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)
  75705. + {
  75706. + switch (wpRegion)
  75707. + {
  75708. + case MV_WP_NONE:
  75709. + wpMask = MV_MX25L_STATUS_BP_NONE;
  75710. + break;
  75711. +
  75712. + case MV_WP_UPR_1OF128:
  75713. + wpMask = MV_MX25L_STATUS_BP_1_OF_128;
  75714. + break;
  75715. +
  75716. + case MV_WP_UPR_1OF64:
  75717. + wpMask = MV_MX25L_STATUS_BP_1_OF_64;
  75718. + break;
  75719. +
  75720. + case MV_WP_UPR_1OF32:
  75721. + wpMask = MV_MX25L_STATUS_BP_1_OF_32;
  75722. + break;
  75723. +
  75724. + case MV_WP_UPR_1OF16:
  75725. + wpMask = MV_MX25L_STATUS_BP_1_OF_16;
  75726. + break;
  75727. +
  75728. + case MV_WP_UPR_1OF8:
  75729. + wpMask = MV_MX25L_STATUS_BP_1_OF_8;
  75730. + break;
  75731. +
  75732. + case MV_WP_UPR_1OF4:
  75733. + wpMask = MV_MX25L_STATUS_BP_1_OF_4;
  75734. + break;
  75735. +
  75736. + case MV_WP_UPR_1OF2:
  75737. + wpMask = MV_MX25L_STATUS_BP_1_OF_2;
  75738. + break;
  75739. +
  75740. + case MV_WP_ALL:
  75741. + wpMask = MV_MX25L_STATUS_BP_ALL;
  75742. + break;
  75743. +
  75744. + default:
  75745. + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
  75746. + return MV_BAD_PARAM;
  75747. + }
  75748. + }
  75749. + /* check if the manufacturer is SPANSION then the WP is 4bits */
  75750. + else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)
  75751. + {
  75752. + switch (wpRegion)
  75753. + {
  75754. + case MV_WP_NONE:
  75755. + wpMask = MV_S25FL_STATUS_BP_NONE;
  75756. + break;
  75757. +
  75758. + case MV_WP_UPR_1OF128:
  75759. + DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)
  75760. + return MV_NOT_SUPPORTED;
  75761. +
  75762. + case MV_WP_UPR_1OF64:
  75763. + wpMask = MV_S25FL_STATUS_BP_1_OF_64;
  75764. + break;
  75765. +
  75766. + case MV_WP_UPR_1OF32:
  75767. + wpMask = MV_S25FL_STATUS_BP_1_OF_32;
  75768. + break;
  75769. +
  75770. + case MV_WP_UPR_1OF16:
  75771. + wpMask = MV_S25FL_STATUS_BP_1_OF_16;
  75772. + break;
  75773. +
  75774. + case MV_WP_UPR_1OF8:
  75775. + wpMask = MV_S25FL_STATUS_BP_1_OF_8;
  75776. + break;
  75777. +
  75778. + case MV_WP_UPR_1OF4:
  75779. + wpMask = MV_S25FL_STATUS_BP_1_OF_4;
  75780. + break;
  75781. +
  75782. + case MV_WP_UPR_1OF2:
  75783. + wpMask = MV_S25FL_STATUS_BP_1_OF_2;
  75784. + break;
  75785. +
  75786. + case MV_WP_ALL:
  75787. + wpMask = MV_S25FL_STATUS_BP_ALL;
  75788. + break;
  75789. +
  75790. +
  75791. + default:
  75792. + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
  75793. + return MV_BAD_PARAM;
  75794. + }
  75795. + }
  75796. + else
  75797. + {
  75798. + DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)
  75799. + return MV_BAD_PARAM;
  75800. + }
  75801. +
  75802. + /* Verify that the SRWD bit is always set - register is s/w locked */
  75803. + wpMask |= MV_SFLASH_STATUS_REG_SRWD_MASK;
  75804. +
  75805. + return mvStatusRegSet(pFlinfo, wpMask);
  75806. +}
  75807. +
  75808. +/*******************************************************************************
  75809. +* mvSFlashWpRegionGet - Get the Write-Protected region configured
  75810. +*
  75811. +* DESCRIPTION:
  75812. +* Get from the chip the Write-Protected region configured
  75813. +*
  75814. +* INPUT:
  75815. +* pFlinfo: pointer to the Flash information structure
  75816. +* pWpRegion: pointer to the variable to return the WP region in
  75817. +*
  75818. +* OUTPUT:
  75819. +* wpRegion: pointer to the variable holding the WP region configured
  75820. +*
  75821. +* RETURN:
  75822. +* Success or Error code.
  75823. +*
  75824. +*
  75825. +*******************************************************************************/
  75826. +MV_STATUS mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion)
  75827. +{
  75828. + MV_STATUS ret;
  75829. + MV_U8 reg;
  75830. +
  75831. + /* check for NULL pointer */
  75832. + if ((pFlinfo == NULL) || (pWpRegion == NULL))
  75833. + {
  75834. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75835. + return MV_BAD_PARAM;
  75836. + }
  75837. +
  75838. + /* Protection - check if the model was detected */
  75839. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75840. + {
  75841. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75842. + return MV_BAD_PARAM;
  75843. + }
  75844. +
  75845. + if ((ret = mvStatusRegGet(pFlinfo, &reg)) != MV_OK)
  75846. + return ret;
  75847. +
  75848. + /* Check if the chip is an ST flash; then WP supports only 3 bits */
  75849. + if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)
  75850. + {
  75851. + switch ((reg & MV_M25P_STATUS_REG_WP_MASK))
  75852. + {
  75853. + case MV_M25P_STATUS_BP_NONE:
  75854. + *pWpRegion = MV_WP_NONE;
  75855. + break;
  75856. +
  75857. + case MV_M25P_STATUS_BP_1_OF_64:
  75858. + *pWpRegion = MV_WP_UPR_1OF64;
  75859. + break;
  75860. +
  75861. + case MV_M25P_STATUS_BP_1_OF_32:
  75862. + *pWpRegion = MV_WP_UPR_1OF32;
  75863. + break;
  75864. +
  75865. + case MV_M25P_STATUS_BP_1_OF_16:
  75866. + *pWpRegion = MV_WP_UPR_1OF16;
  75867. + break;
  75868. +
  75869. + case MV_M25P_STATUS_BP_1_OF_8:
  75870. + *pWpRegion = MV_WP_UPR_1OF8;
  75871. + break;
  75872. +
  75873. + case MV_M25P_STATUS_BP_1_OF_4:
  75874. + *pWpRegion = MV_WP_UPR_1OF4;
  75875. + break;
  75876. +
  75877. + case MV_M25P_STATUS_BP_1_OF_2:
  75878. + *pWpRegion = MV_WP_UPR_1OF2;
  75879. + break;
  75880. +
  75881. + case MV_M25P_STATUS_BP_ALL:
  75882. + *pWpRegion = MV_WP_ALL;
  75883. + break;
  75884. +
  75885. + default:
  75886. + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
  75887. + return MV_BAD_VALUE;
  75888. + }
  75889. + }
  75890. + /* check if the manufacturer is MXIC then the WP is 4bits */
  75891. + else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)
  75892. + {
  75893. + switch ((reg & MV_MX25L_STATUS_REG_WP_MASK))
  75894. + {
  75895. + case MV_MX25L_STATUS_BP_NONE:
  75896. + *pWpRegion = MV_WP_NONE;
  75897. + break;
  75898. +
  75899. + case MV_MX25L_STATUS_BP_1_OF_128:
  75900. + *pWpRegion = MV_WP_UPR_1OF128;
  75901. + break;
  75902. +
  75903. + case MV_MX25L_STATUS_BP_1_OF_64:
  75904. + *pWpRegion = MV_WP_UPR_1OF64;
  75905. + break;
  75906. +
  75907. + case MV_MX25L_STATUS_BP_1_OF_32:
  75908. + *pWpRegion = MV_WP_UPR_1OF32;
  75909. + break;
  75910. +
  75911. + case MV_MX25L_STATUS_BP_1_OF_16:
  75912. + *pWpRegion = MV_WP_UPR_1OF16;
  75913. + break;
  75914. +
  75915. + case MV_MX25L_STATUS_BP_1_OF_8:
  75916. + *pWpRegion = MV_WP_UPR_1OF8;
  75917. + break;
  75918. +
  75919. + case MV_MX25L_STATUS_BP_1_OF_4:
  75920. + *pWpRegion = MV_WP_UPR_1OF4;
  75921. + break;
  75922. +
  75923. + case MV_MX25L_STATUS_BP_1_OF_2:
  75924. + *pWpRegion = MV_WP_UPR_1OF2;
  75925. + break;
  75926. +
  75927. + case MV_MX25L_STATUS_BP_ALL:
  75928. + *pWpRegion = MV_WP_ALL;
  75929. + break;
  75930. +
  75931. + default:
  75932. + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
  75933. + return MV_BAD_VALUE;
  75934. + }
  75935. + }
  75936. + /* Check if the chip is an SPANSION flash; then WP supports only 3 bits */
  75937. + else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)
  75938. + {
  75939. + switch ((reg & MV_S25FL_STATUS_REG_WP_MASK))
  75940. + {
  75941. + case MV_S25FL_STATUS_BP_NONE:
  75942. + *pWpRegion = MV_WP_NONE;
  75943. + break;
  75944. +
  75945. + case MV_S25FL_STATUS_BP_1_OF_64:
  75946. + *pWpRegion = MV_WP_UPR_1OF64;
  75947. + break;
  75948. +
  75949. + case MV_S25FL_STATUS_BP_1_OF_32:
  75950. + *pWpRegion = MV_WP_UPR_1OF32;
  75951. + break;
  75952. +
  75953. + case MV_S25FL_STATUS_BP_1_OF_16:
  75954. + *pWpRegion = MV_WP_UPR_1OF16;
  75955. + break;
  75956. +
  75957. + case MV_S25FL_STATUS_BP_1_OF_8:
  75958. + *pWpRegion = MV_WP_UPR_1OF8;
  75959. + break;
  75960. +
  75961. + case MV_S25FL_STATUS_BP_1_OF_4:
  75962. + *pWpRegion = MV_WP_UPR_1OF4;
  75963. + break;
  75964. +
  75965. + case MV_S25FL_STATUS_BP_1_OF_2:
  75966. + *pWpRegion = MV_WP_UPR_1OF2;
  75967. + break;
  75968. +
  75969. + case MV_S25FL_STATUS_BP_ALL:
  75970. + *pWpRegion = MV_WP_ALL;
  75971. + break;
  75972. +
  75973. + default:
  75974. + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
  75975. + return MV_BAD_VALUE;
  75976. + }
  75977. + }
  75978. + else
  75979. + {
  75980. + DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)
  75981. + return MV_BAD_PARAM;
  75982. + }
  75983. +
  75984. + return MV_OK;
  75985. +}
  75986. +
  75987. +/*******************************************************************************
  75988. +* mvSFlashStatRegLock - Lock the status register for writing - W/Vpp
  75989. +* pin should be low to take effect
  75990. +*
  75991. +* DESCRIPTION:
  75992. +* Lock the access to the Status Register for writing. This will
  75993. +* cause the flash to enter the hardware protection mode if the W/Vpp
  75994. +* is low. If the W/Vpp is hi, the chip will be in soft protection mode, but
  75995. +* the register will continue to be writable if WREN sequence was used.
  75996. +*
  75997. +* INPUT:
  75998. +* pFlinfo: pointer to the Flash information structure
  75999. +* srLock: enable/disable (MV_TRUE/MV_FALSE) status registor lock mechanism
  76000. +*
  76001. +* OUTPUT:
  76002. +* None
  76003. +*
  76004. +* RETURN:
  76005. +* Success or Error code.
  76006. +*
  76007. +*
  76008. +*******************************************************************************/
  76009. +MV_STATUS mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock)
  76010. +{
  76011. + MV_STATUS ret;
  76012. + MV_U8 reg;
  76013. +
  76014. + /* check for NULL pointer */
  76015. + if (pFlinfo == NULL)
  76016. + {
  76017. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76018. + return MV_BAD_PARAM;
  76019. + }
  76020. +
  76021. + /* Protection - check if the model was detected */
  76022. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76023. + {
  76024. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76025. + return MV_BAD_PARAM;
  76026. + }
  76027. +
  76028. + if ((ret = mvStatusRegGet(pFlinfo, &reg)) != MV_OK)
  76029. + return ret;
  76030. +
  76031. + if (srLock)
  76032. + reg |= MV_SFLASH_STATUS_REG_SRWD_MASK;
  76033. + else
  76034. + reg &= ~MV_SFLASH_STATUS_REG_SRWD_MASK;
  76035. +
  76036. + return mvStatusRegSet(pFlinfo, reg);
  76037. +}
  76038. +
  76039. +/*******************************************************************************
  76040. +* mvSFlashSizeGet - Get the size of the SPI flash
  76041. +*
  76042. +* DESCRIPTION:
  76043. +* based on the sector number and size of each sector calculate the total
  76044. +* size of the flash memory.
  76045. +*
  76046. +* INPUT:
  76047. +* pFlinfo: pointer to the Flash information structure
  76048. +*
  76049. +* OUTPUT:
  76050. +* None.
  76051. +*
  76052. +* RETURN:
  76053. +* Size of the flash in bytes.
  76054. +*
  76055. +*
  76056. +*******************************************************************************/
  76057. +MV_U32 mvSFlashSizeGet (MV_SFLASH_INFO * pFlinfo)
  76058. +{
  76059. + /* check for NULL pointer */
  76060. + if (pFlinfo == NULL)
  76061. + {
  76062. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76063. + return 0;
  76064. + }
  76065. +
  76066. + return (pFlinfo->sectorSize * pFlinfo->sectorNumber);
  76067. +}
  76068. +
  76069. +/*******************************************************************************
  76070. +* mvSFlashPowerSaveEnter - Cause the falsh device to go into power save mode
  76071. +*
  76072. +* DESCRIPTION:
  76073. +* Enter a special power save mode.
  76074. +*
  76075. +* INPUT:
  76076. +* pFlinfo: pointer to the Flash information structure
  76077. +*
  76078. +* OUTPUT:
  76079. +* None.
  76080. +*
  76081. +* RETURN:
  76082. +* Size of the flash in bytes.
  76083. +*
  76084. +*
  76085. +*******************************************************************************/
  76086. +MV_STATUS mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo)
  76087. +{
  76088. + MV_STATUS ret;
  76089. + MV_U8 cmd[MV_SFLASH_DP_CMND_LENGTH];
  76090. +
  76091. +
  76092. + /* check for NULL pointer */
  76093. + if (pFlinfo == NULL)
  76094. + {
  76095. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76096. + return 0;
  76097. + }
  76098. +
  76099. + /* Protection - check if the model was detected */
  76100. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76101. + {
  76102. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76103. + return MV_BAD_PARAM;
  76104. + }
  76105. +
  76106. + /* check that power save mode is supported in the specific device */
  76107. + if (sflash[pFlinfo->index].opcdPwrSave == MV_SFLASH_NO_SPECIFIC_OPCD)
  76108. + {
  76109. + DB(mvOsPrintf("%s WARNING: Power save not supported for this device!\n", __FUNCTION__);)
  76110. + return MV_NOT_SUPPORTED;
  76111. + }
  76112. +
  76113. + cmd[0] = sflash[pFlinfo->index].opcdPwrSave;
  76114. +
  76115. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_DP_CMND_LENGTH, NULL, 0)) != MV_OK)
  76116. + return ret;
  76117. +
  76118. + return MV_OK;
  76119. +
  76120. +}
  76121. +
  76122. +/*******************************************************************************
  76123. +* mvSFlashPowerSaveExit - Cause the falsh device to exit the power save mode
  76124. +*
  76125. +* DESCRIPTION:
  76126. +* Exit the deep power save mode.
  76127. +*
  76128. +* INPUT:
  76129. +* pFlinfo: pointer to the Flash information structure
  76130. +*
  76131. +* OUTPUT:
  76132. +* None.
  76133. +*
  76134. +* RETURN:
  76135. +* Size of the flash in bytes.
  76136. +*
  76137. +*
  76138. +*******************************************************************************/
  76139. +MV_STATUS mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo)
  76140. +{
  76141. + MV_STATUS ret;
  76142. + MV_U8 cmd[MV_SFLASH_RES_CMND_LENGTH];
  76143. +
  76144. +
  76145. + /* check for NULL pointer */
  76146. + if (pFlinfo == NULL)
  76147. + {
  76148. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76149. + return 0;
  76150. + }
  76151. +
  76152. + /* Protection - check if the model was detected */
  76153. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76154. + {
  76155. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76156. + return MV_BAD_PARAM;
  76157. + }
  76158. +
  76159. + /* check that power save mode is supported in the specific device */
  76160. + if (sflash[pFlinfo->index].opcdRES == MV_SFLASH_NO_SPECIFIC_OPCD)
  76161. + {
  76162. + DB(mvOsPrintf("%s WARNING: Read Electronic Signature not supported for this device!\n", __FUNCTION__);)
  76163. + return MV_NOT_SUPPORTED;
  76164. + }
  76165. +
  76166. + cmd[0] = sflash[pFlinfo->index].opcdRES;
  76167. +
  76168. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_RES_CMND_LENGTH, NULL, 0)) != MV_OK)
  76169. + return ret;
  76170. +
  76171. + /* add the delay needed for the device to wake up */
  76172. + mvOsDelay(MV_MXIC_DP_EXIT_DELAY); /* 30 ms */
  76173. +
  76174. + return MV_OK;
  76175. +
  76176. +}
  76177. +
  76178. +/*******************************************************************************
  76179. +* mvSFlashModelGet - Retreive the string with the device manufacturer and model
  76180. +*
  76181. +* DESCRIPTION:
  76182. +* Retreive the string with the device manufacturer and model
  76183. +*
  76184. +* INPUT:
  76185. +* pFlinfo: pointer to the Flash information structure
  76186. +*
  76187. +* OUTPUT:
  76188. +* None.
  76189. +*
  76190. +* RETURN:
  76191. +* pointer to the string indicating the device manufacturer and model
  76192. +*
  76193. +*
  76194. +*******************************************************************************/
  76195. +const MV_8 * mvSFlashModelGet (MV_SFLASH_INFO * pFlinfo)
  76196. +{
  76197. + static const MV_8 * unknModel = (const MV_8 *)"Unknown";
  76198. +
  76199. + /* check for NULL pointer */
  76200. + if (pFlinfo == NULL)
  76201. + {
  76202. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76203. + return 0;
  76204. + }
  76205. +
  76206. + /* Protection - check if the model was detected */
  76207. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76208. + {
  76209. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76210. + return unknModel;
  76211. + }
  76212. +
  76213. + return sflash[pFlinfo->index].deviceModel;
  76214. +}
  76215. +
  76216. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h
  76217. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h 1970-01-01 01:00:00.000000000 +0100
  76218. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h 2011-07-31 11:32:01.483424510 +0200
  76219. @@ -0,0 +1,166 @@
  76220. +/*******************************************************************************
  76221. +Copyright (C) Marvell International Ltd. and its affiliates
  76222. +
  76223. +This software file (the "File") is owned and distributed by Marvell
  76224. +International Ltd. and/or its affiliates ("Marvell") under the following
  76225. +alternative licensing terms. Once you have made an election to distribute the
  76226. +File under one of the following license alternatives, please (i) delete this
  76227. +introductory statement regarding license alternatives, (ii) delete the two
  76228. +license alternatives that you have not elected to use and (iii) preserve the
  76229. +Marvell copyright notice above.
  76230. +
  76231. +********************************************************************************
  76232. +Marvell Commercial License Option
  76233. +
  76234. +If you received this File from Marvell and you have entered into a commercial
  76235. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76236. +to you under the terms of the applicable Commercial License.
  76237. +
  76238. +********************************************************************************
  76239. +Marvell GPL License Option
  76240. +
  76241. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76242. +modify this File in accordance with the terms and conditions of the General
  76243. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76244. +available along with the File in the license.txt file or by writing to the Free
  76245. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76246. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76247. +
  76248. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76249. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76250. +DISCLAIMED. The GPL License provides additional details about this warranty
  76251. +disclaimer.
  76252. +********************************************************************************
  76253. +Marvell BSD License Option
  76254. +
  76255. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76256. +modify this File under the following licensing terms.
  76257. +Redistribution and use in source and binary forms, with or without modification,
  76258. +are permitted provided that the following conditions are met:
  76259. +
  76260. + * Redistributions of source code must retain the above copyright notice,
  76261. + this list of conditions and the following disclaimer.
  76262. +
  76263. + * Redistributions in binary form must reproduce the above copyright
  76264. + notice, this list of conditions and the following disclaimer in the
  76265. + documentation and/or other materials provided with the distribution.
  76266. +
  76267. + * Neither the name of Marvell nor the names of its contributors may be
  76268. + used to endorse or promote products derived from this software without
  76269. + specific prior written permission.
  76270. +
  76271. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76272. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76273. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76274. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76275. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76276. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76277. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76278. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76279. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76280. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76281. +
  76282. +*******************************************************************************/
  76283. +
  76284. +#ifndef __INCmvSFlashH
  76285. +#define __INCmvSFlashH
  76286. +
  76287. +#include "mvTypes.h"
  76288. +
  76289. +/* MCAROS */
  76290. +#define MV_SFLASH_PAGE_ALLIGN_MASK(pgSz) (pgSz-1)
  76291. +#define MV_ARRAY_SIZE(a) ((sizeof(a)) / (sizeof(a[0])))
  76292. +
  76293. +/* Constants */
  76294. +#define MV_INVALID_DEVICE_NUMBER 0xFFFFFFFF
  76295. +/* 10 MHz is the minimum possible SPI frequency when tclk is set 200MHz*/
  76296. +#define MV_SFLASH_BASIC_SPI_FREQ 10000000
  76297. +/* enumerations */
  76298. +typedef enum
  76299. +{
  76300. + MV_WP_NONE, /* Unprotect the whole chip */
  76301. + MV_WP_UPR_1OF128, /* Write protect the upper 1/128 part */
  76302. + MV_WP_UPR_1OF64, /* Write protect the upper 1/64 part */
  76303. + MV_WP_UPR_1OF32, /* Write protect the upper 1/32 part */
  76304. + MV_WP_UPR_1OF16, /* Write protect the upper 1/16 part */
  76305. + MV_WP_UPR_1OF8, /* Write protect the upper 1/8 part */
  76306. + MV_WP_UPR_1OF4, /* Write protect the upper 1/4 part */
  76307. + MV_WP_UPR_1OF2, /* Write protect the upper 1/2 part */
  76308. + MV_WP_ALL /* Write protect the whole chip */
  76309. +} MV_SFLASH_WP_REGION;
  76310. +
  76311. +/* Type Definitions */
  76312. +typedef struct
  76313. +{
  76314. + MV_U8 opcdWREN; /* Write enable opcode */
  76315. + MV_U8 opcdWRDI; /* Write disable opcode */
  76316. + MV_U8 opcdRDID; /* Read ID opcode */
  76317. + MV_U8 opcdRDSR; /* Read Status Register opcode */
  76318. + MV_U8 opcdWRSR; /* Write Status register opcode */
  76319. + MV_U8 opcdREAD; /* Read opcode */
  76320. + MV_U8 opcdFSTRD; /* Fast Read opcode */
  76321. + MV_U8 opcdPP; /* Page program opcode */
  76322. + MV_U8 opcdSE; /* Sector erase opcode */
  76323. + MV_U8 opcdBE; /* Bulk erase opcode */
  76324. + MV_U8 opcdRES; /* Read electronic signature */
  76325. + MV_U8 opcdPwrSave; /* Go into power save mode */
  76326. + MV_U32 sectorSize; /* Size of each sector */
  76327. + MV_U32 sectorNumber; /* Number of sectors */
  76328. + MV_U32 pageSize; /* size of each page */
  76329. + const char * deviceModel; /* string with the device model */
  76330. + MV_U32 manufacturerId; /* The manufacturer ID */
  76331. + MV_U32 deviceId; /* Device ID */
  76332. + MV_U32 spiMaxFreq; /* The MAX frequency that can be used with the device */
  76333. + MV_U32 spiMaxFastFreq; /* The MAX frequency that can be used with the device for fast reads */
  76334. + MV_U32 spiFastRdDummyBytes; /* Number of dumy bytes to read before real data when working in fast read mode. */
  76335. +} MV_SFLASH_DEVICE_PARAMS;
  76336. +
  76337. +typedef struct
  76338. +{
  76339. + MV_U32 baseAddr; /* Flash Base Address used in fast mode */
  76340. + MV_U8 manufacturerId; /* Manufacturer ID */
  76341. + MV_U16 deviceId; /* Device ID */
  76342. + MV_U32 sectorSize; /* Size of each sector - all the same */
  76343. + MV_U32 sectorNumber; /* Number of sectors */
  76344. + MV_U32 pageSize; /* Page size - affect allignment */
  76345. + MV_U32 index; /* index of the device in the sflash table (internal parameter) */
  76346. +} MV_SFLASH_INFO;
  76347. +
  76348. +/* Function Prototypes */
  76349. +/* Init */
  76350. +MV_STATUS mvSFlashInit (MV_SFLASH_INFO * pFlinfo);
  76351. +
  76352. +/* erase */
  76353. +MV_STATUS mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber);
  76354. +MV_STATUS mvSFlashChipErase (MV_SFLASH_INFO * pFlinfo);
  76355. +
  76356. +/* Read */
  76357. +MV_STATUS mvSFlashBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  76358. + MV_U8* pReadBuff, MV_U32 buffSize);
  76359. +MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  76360. + MV_U8* pReadBuff, MV_U32 buffSize);
  76361. +
  76362. +/* write regardless of the page boundaries and size limit per Page program command */
  76363. +MV_STATUS mvSFlashBlockWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  76364. + MV_U8* pWriteBuff, MV_U32 buffSize);
  76365. +/* Get IDs */
  76366. +MV_STATUS mvSFlashIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId);
  76367. +
  76368. +/* Set and Get the Write Protection region - if the Status register is not locked */
  76369. +MV_STATUS mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion);
  76370. +MV_STATUS mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion);
  76371. +
  76372. +/* Lock the status register for writing - W/Vpp pin should be low to take effect */
  76373. +MV_STATUS mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock);
  76374. +
  76375. +/* Get the regions sizes */
  76376. +MV_U32 mvSFlashSizeGet (MV_SFLASH_INFO * pFlinfo);
  76377. +
  76378. +/* Cause the falsh device to go into power save mode */
  76379. +MV_STATUS mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo);
  76380. +MV_STATUS mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo);
  76381. +
  76382. +/* Retreive the string with the device manufacturer and model */
  76383. +const MV_8 * mvSFlashModelGet (MV_SFLASH_INFO * pFlinfo);
  76384. +
  76385. +#endif /* __INCmvSFlashH */
  76386. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h
  76387. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h 1970-01-01 01:00:00.000000000 +0100
  76388. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h 2011-07-31 11:32:01.533415775 +0200
  76389. @@ -0,0 +1,233 @@
  76390. +/*******************************************************************************
  76391. +Copyright (C) Marvell International Ltd. and its affiliates
  76392. +
  76393. +This software file (the "File") is owned and distributed by Marvell
  76394. +International Ltd. and/or its affiliates ("Marvell") under the following
  76395. +alternative licensing terms. Once you have made an election to distribute the
  76396. +File under one of the following license alternatives, please (i) delete this
  76397. +introductory statement regarding license alternatives, (ii) delete the two
  76398. +license alternatives that you have not elected to use and (iii) preserve the
  76399. +Marvell copyright notice above.
  76400. +
  76401. +********************************************************************************
  76402. +Marvell Commercial License Option
  76403. +
  76404. +If you received this File from Marvell and you have entered into a commercial
  76405. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76406. +to you under the terms of the applicable Commercial License.
  76407. +
  76408. +********************************************************************************
  76409. +Marvell GPL License Option
  76410. +
  76411. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76412. +modify this File in accordance with the terms and conditions of the General
  76413. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76414. +available along with the File in the license.txt file or by writing to the Free
  76415. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76416. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76417. +
  76418. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76419. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76420. +DISCLAIMED. The GPL License provides additional details about this warranty
  76421. +disclaimer.
  76422. +********************************************************************************
  76423. +Marvell BSD License Option
  76424. +
  76425. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76426. +modify this File under the following licensing terms.
  76427. +Redistribution and use in source and binary forms, with or without modification,
  76428. +are permitted provided that the following conditions are met:
  76429. +
  76430. + * Redistributions of source code must retain the above copyright notice,
  76431. + this list of conditions and the following disclaimer.
  76432. +
  76433. + * Redistributions in binary form must reproduce the above copyright
  76434. + notice, this list of conditions and the following disclaimer in the
  76435. + documentation and/or other materials provided with the distribution.
  76436. +
  76437. + * Neither the name of Marvell nor the names of its contributors may be
  76438. + used to endorse or promote products derived from this software without
  76439. + specific prior written permission.
  76440. +
  76441. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76442. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76443. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76444. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76445. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76446. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76447. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76448. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76449. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76450. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76451. +
  76452. +*******************************************************************************/
  76453. +
  76454. +#ifndef __INCmvSFlashSpecH
  76455. +#define __INCmvSFlashSpecH
  76456. +
  76457. +/* Constants */
  76458. +#define MV_SFLASH_READ_CMND_LENGTH 4 /* 1B opcode + 3B address */
  76459. +#define MV_SFLASH_SE_CMND_LENGTH 4 /* 1B opcode + 3B address */
  76460. +#define MV_SFLASH_BE_CMND_LENGTH 1 /* 1B opcode */
  76461. +#define MV_SFLASH_PP_CMND_LENGTH 4 /* 1B opcode + 3B address */
  76462. +#define MV_SFLASH_WREN_CMND_LENGTH 1 /* 1B opcode */
  76463. +#define MV_SFLASH_WRDI_CMND_LENGTH 1 /* 1B opcode */
  76464. +#define MV_SFLASH_RDID_CMND_LENGTH 1 /* 1B opcode */
  76465. +#define MV_SFLASH_RDID_REPLY_LENGTH 3 /* 1B manf ID and 2B device ID */
  76466. +#define MV_SFLASH_RDSR_CMND_LENGTH 1 /* 1B opcode */
  76467. +#define MV_SFLASH_RDSR_REPLY_LENGTH 1 /* 1B status */
  76468. +#define MV_SFLASH_WRSR_CMND_LENGTH 2 /* 1B opcode + 1B status value */
  76469. +#define MV_SFLASH_DP_CMND_LENGTH 1 /* 1B opcode */
  76470. +#define MV_SFLASH_RES_CMND_LENGTH 1 /* 1B opcode */
  76471. +
  76472. +/* Status Register Bit Masks */
  76473. +#define MV_SFLASH_STATUS_REG_WIP_OFFSET 0 /* bit 0; write in progress */
  76474. +#define MV_SFLASH_STATUS_REG_WP_OFFSET 2 /* bit 2-4; write protect option */
  76475. +#define MV_SFLASH_STATUS_REG_SRWD_OFFSET 7 /* bit 7; lock status register write */
  76476. +#define MV_SFLASH_STATUS_REG_WIP_MASK (0x1 << MV_SFLASH_STATUS_REG_WIP_OFFSET)
  76477. +#define MV_SFLASH_STATUS_REG_SRWD_MASK (0x1 << MV_SFLASH_STATUS_REG_SRWD_OFFSET)
  76478. +
  76479. +#define MV_SFLASH_MAX_WAIT_LOOP 1000000
  76480. +#define MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP 0x50000000
  76481. +
  76482. +#define MV_SFLASH_DEFAULT_RDID_OPCD 0x9F /* Default Read ID */
  76483. +#define MV_SFLASH_DEFAULT_WREN_OPCD 0x06 /* Default Write Enable */
  76484. +#define MV_SFLASH_NO_SPECIFIC_OPCD 0x00
  76485. +
  76486. +/********************************/
  76487. +/* ST M25Pxxx Device Specific */
  76488. +/********************************/
  76489. +
  76490. +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
  76491. +#define MV_M25PXXX_ST_MANF_ID 0x20
  76492. +#define MV_M25P32_DEVICE_ID 0x2016
  76493. +#define MV_M25P32_MAX_SPI_FREQ 20000000 /* 20MHz */
  76494. +#define MV_M25P32_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  76495. +#define MV_M25P32_FAST_READ_DUMMY_BYTES 1
  76496. +#define MV_M25P64_DEVICE_ID 0x2017
  76497. +#define MV_M25P64_MAX_SPI_FREQ 20000000 /* 20MHz */
  76498. +#define MV_M25P64_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  76499. +#define MV_M25P64_FAST_READ_DUMMY_BYTES 1
  76500. +#define MV_M25P128_DEVICE_ID 0x2018
  76501. +#define MV_M25P128_MAX_SPI_FREQ 20000000 /* 20MHz */
  76502. +#define MV_M25P128_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  76503. +#define MV_M25P128_FAST_READ_DUMMY_BYTES 1
  76504. +
  76505. +
  76506. +/* Sector Sizes and population per device model*/
  76507. +#define MV_M25P32_SECTOR_SIZE 0x10000 /* 64K */
  76508. +#define MV_M25P64_SECTOR_SIZE 0x10000 /* 64K */
  76509. +#define MV_M25P128_SECTOR_SIZE 0x40000 /* 256K */
  76510. +#define MV_M25P32_SECTOR_NUMBER 64
  76511. +#define MV_M25P64_SECTOR_NUMBER 128
  76512. +#define MV_M25P128_SECTOR_NUMBER 64
  76513. +#define MV_M25P_PAGE_SIZE 0x100 /* 256 byte */
  76514. +
  76515. +#define MV_M25P_WREN_CMND_OPCD 0x06 /* Write Enable */
  76516. +#define MV_M25P_WRDI_CMND_OPCD 0x04 /* Write Disable */
  76517. +#define MV_M25P_RDID_CMND_OPCD 0x9F /* Read ID */
  76518. +#define MV_M25P_RDSR_CMND_OPCD 0x05 /* Read Status Register */
  76519. +#define MV_M25P_WRSR_CMND_OPCD 0x01 /* Write Status Register */
  76520. +#define MV_M25P_READ_CMND_OPCD 0x03 /* Sequential Read */
  76521. +#define MV_M25P_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
  76522. +#define MV_M25P_PP_CMND_OPCD 0x02 /* Page Program */
  76523. +#define MV_M25P_SE_CMND_OPCD 0xD8 /* Sector Erase */
  76524. +#define MV_M25P_BE_CMND_OPCD 0xC7 /* Bulk Erase */
  76525. +#define MV_M25P_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
  76526. +
  76527. +/* Status Register Write Protect Bit Masks - 3bits */
  76528. +#define MV_M25P_STATUS_REG_WP_MASK (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76529. +#define MV_M25P_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76530. +#define MV_M25P_STATUS_BP_1_OF_64 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76531. +#define MV_M25P_STATUS_BP_1_OF_32 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76532. +#define MV_M25P_STATUS_BP_1_OF_16 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76533. +#define MV_M25P_STATUS_BP_1_OF_8 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76534. +#define MV_M25P_STATUS_BP_1_OF_4 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76535. +#define MV_M25P_STATUS_BP_1_OF_2 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76536. +#define MV_M25P_STATUS_BP_ALL (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76537. +
  76538. +/************************************/
  76539. +/* MXIC MX25L6405 Device Specific */
  76540. +/************************************/
  76541. +
  76542. +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
  76543. +#define MV_MXIC_MANF_ID 0xC2
  76544. +#define MV_MX25L6405_DEVICE_ID 0x2017
  76545. +#define MV_MX25L6405_MAX_SPI_FREQ 20000000 /* 20MHz */
  76546. +#define MV_MX25L6405_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  76547. +#define MV_MX25L6405_FAST_READ_DUMMY_BYTES 1
  76548. +#define MV_MXIC_DP_EXIT_DELAY 30 /* 30 ms */
  76549. +
  76550. +/* Sector Sizes and population per device model*/
  76551. +#define MV_MX25L6405_SECTOR_SIZE 0x10000 /* 64K */
  76552. +#define MV_MX25L6405_SECTOR_NUMBER 128
  76553. +#define MV_MXIC_PAGE_SIZE 0x100 /* 256 byte */
  76554. +
  76555. +#define MV_MX25L_WREN_CMND_OPCD 0x06 /* Write Enable */
  76556. +#define MV_MX25L_WRDI_CMND_OPCD 0x04 /* Write Disable */
  76557. +#define MV_MX25L_RDID_CMND_OPCD 0x9F /* Read ID */
  76558. +#define MV_MX25L_RDSR_CMND_OPCD 0x05 /* Read Status Register */
  76559. +#define MV_MX25L_WRSR_CMND_OPCD 0x01 /* Write Status Register */
  76560. +#define MV_MX25L_READ_CMND_OPCD 0x03 /* Sequential Read */
  76561. +#define MV_MX25L_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
  76562. +#define MV_MX25L_PP_CMND_OPCD 0x02 /* Page Program */
  76563. +#define MV_MX25L_SE_CMND_OPCD 0xD8 /* Sector Erase */
  76564. +#define MV_MX25L_BE_CMND_OPCD 0xC7 /* Bulk Erase */
  76565. +#define MV_MX25L_DP_CMND_OPCD 0xB9 /* Deep Power Down */
  76566. +#define MV_MX25L_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
  76567. +
  76568. +/* Status Register Write Protect Bit Masks - 4bits */
  76569. +#define MV_MX25L_STATUS_REG_WP_MASK (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76570. +#define MV_MX25L_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76571. +#define MV_MX25L_STATUS_BP_1_OF_128 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76572. +#define MV_MX25L_STATUS_BP_1_OF_64 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76573. +#define MV_MX25L_STATUS_BP_1_OF_32 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76574. +#define MV_MX25L_STATUS_BP_1_OF_16 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76575. +#define MV_MX25L_STATUS_BP_1_OF_8 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76576. +#define MV_MX25L_STATUS_BP_1_OF_4 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76577. +#define MV_MX25L_STATUS_BP_1_OF_2 (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76578. +#define MV_MX25L_STATUS_BP_ALL (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76579. +
  76580. +/************************************/
  76581. +/* SPANSION S25FL128P Device Specific */
  76582. +/************************************/
  76583. +
  76584. +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
  76585. +#define MV_SPANSION_MANF_ID 0x01
  76586. +#define MV_S25FL128_DEVICE_ID 0x2018
  76587. +#define MV_S25FL128_MAX_SPI_FREQ 33000000 /* 33MHz */
  76588. +#define MV_S25FL128_MAX_FAST_SPI_FREQ 104000000 /* 104MHz */
  76589. +#define MV_S25FL128_FAST_READ_DUMMY_BYTES 1
  76590. +
  76591. +/* Sector Sizes and population per device model*/
  76592. +#define MV_S25FL128_SECTOR_SIZE 0x40000 /* 256K */
  76593. +#define MV_S25FL128_SECTOR_NUMBER 64
  76594. +#define MV_S25FL_PAGE_SIZE 0x100 /* 256 byte */
  76595. +
  76596. +#define MV_S25FL_WREN_CMND_OPCD 0x06 /* Write Enable */
  76597. +#define MV_S25FL_WRDI_CMND_OPCD 0x04 /* Write Disable */
  76598. +#define MV_S25FL_RDID_CMND_OPCD 0x9F /* Read ID */
  76599. +#define MV_S25FL_RDSR_CMND_OPCD 0x05 /* Read Status Register */
  76600. +#define MV_S25FL_WRSR_CMND_OPCD 0x01 /* Write Status Register */
  76601. +#define MV_S25FL_READ_CMND_OPCD 0x03 /* Sequential Read */
  76602. +#define MV_S25FL_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
  76603. +#define MV_S25FL_PP_CMND_OPCD 0x02 /* Page Program */
  76604. +#define MV_S25FL_SE_CMND_OPCD 0xD8 /* Sector Erase */
  76605. +#define MV_S25FL_BE_CMND_OPCD 0xC7 /* Bulk Erase */
  76606. +#define MV_S25FL_DP_CMND_OPCD 0xB9 /* Deep Power Down */
  76607. +#define MV_S25FL_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
  76608. +
  76609. +/* Status Register Write Protect Bit Masks - 4bits */
  76610. +#define MV_S25FL_STATUS_REG_WP_MASK (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76611. +#define MV_S25FL_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76612. +#define MV_S25FL_STATUS_BP_1_OF_128 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76613. +#define MV_S25FL_STATUS_BP_1_OF_64 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76614. +#define MV_S25FL_STATUS_BP_1_OF_32 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76615. +#define MV_S25FL_STATUS_BP_1_OF_16 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76616. +#define MV_S25FL_STATUS_BP_1_OF_8 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76617. +#define MV_S25FL_STATUS_BP_1_OF_4 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76618. +#define MV_S25FL_STATUS_BP_1_OF_2 (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76619. +#define MV_S25FL_STATUS_BP_ALL (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  76620. +
  76621. +#endif /* __INCmvSFlashSpecH */
  76622. +
  76623. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c
  76624. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c 1970-01-01 01:00:00.000000000 +0100
  76625. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c 2011-07-31 11:32:01.583509976 +0200
  76626. @@ -0,0 +1,576 @@
  76627. +/*******************************************************************************
  76628. +Copyright (C) Marvell International Ltd. and its affiliates
  76629. +
  76630. +This software file (the "File") is owned and distributed by Marvell
  76631. +International Ltd. and/or its affiliates ("Marvell") under the following
  76632. +alternative licensing terms. Once you have made an election to distribute the
  76633. +File under one of the following license alternatives, please (i) delete this
  76634. +introductory statement regarding license alternatives, (ii) delete the two
  76635. +license alternatives that you have not elected to use and (iii) preserve the
  76636. +Marvell copyright notice above.
  76637. +
  76638. +********************************************************************************
  76639. +Marvell Commercial License Option
  76640. +
  76641. +If you received this File from Marvell and you have entered into a commercial
  76642. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76643. +to you under the terms of the applicable Commercial License.
  76644. +
  76645. +********************************************************************************
  76646. +Marvell GPL License Option
  76647. +
  76648. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76649. +modify this File in accordance with the terms and conditions of the General
  76650. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76651. +available along with the File in the license.txt file or by writing to the Free
  76652. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76653. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76654. +
  76655. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76656. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76657. +DISCLAIMED. The GPL License provides additional details about this warranty
  76658. +disclaimer.
  76659. +********************************************************************************
  76660. +Marvell BSD License Option
  76661. +
  76662. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76663. +modify this File under the following licensing terms.
  76664. +Redistribution and use in source and binary forms, with or without modification,
  76665. +are permitted provided that the following conditions are met:
  76666. +
  76667. + * Redistributions of source code must retain the above copyright notice,
  76668. + this list of conditions and the following disclaimer.
  76669. +
  76670. + * Redistributions in binary form must reproduce the above copyright
  76671. + notice, this list of conditions and the following disclaimer in the
  76672. + documentation and/or other materials provided with the distribution.
  76673. +
  76674. + * Neither the name of Marvell nor the names of its contributors may be
  76675. + used to endorse or promote products derived from this software without
  76676. + specific prior written permission.
  76677. +
  76678. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76679. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76680. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76681. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76682. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76683. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76684. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76685. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76686. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76687. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76688. +
  76689. +*******************************************************************************/
  76690. +
  76691. +#include "spi/mvSpi.h"
  76692. +#include "spi/mvSpiSpec.h"
  76693. +
  76694. +#include "ctrlEnv/mvCtrlEnvLib.h"
  76695. +
  76696. +/* #define MV_DEBUG */
  76697. +#ifdef MV_DEBUG
  76698. +#define DB(x) x
  76699. +#define mvOsPrintf printf
  76700. +#else
  76701. +#define DB(x)
  76702. +#endif
  76703. +
  76704. +
  76705. +/*******************************************************************************
  76706. +* mvSpi16bitDataTxRx - Transmt and receive data
  76707. +*
  76708. +* DESCRIPTION:
  76709. +* Tx data and block waiting for data to be transmitted
  76710. +*
  76711. +********************************************************************************/
  76712. +static MV_STATUS mvSpi16bitDataTxRx (MV_U16 txData, MV_U16 * pRxData)
  76713. +{
  76714. + MV_U32 i;
  76715. + MV_BOOL ready = MV_FALSE;
  76716. +
  76717. + /* First clear the bit in the interrupt cause register */
  76718. + MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);
  76719. +
  76720. + /* Transmit data */
  76721. + MV_REG_WRITE(MV_SPI_DATA_OUT_REG, MV_16BIT_LE(txData));
  76722. +
  76723. + /* wait with timeout for memory ready */
  76724. + for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)
  76725. + {
  76726. + if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))
  76727. + {
  76728. + ready = MV_TRUE;
  76729. + break;
  76730. + }
  76731. +#ifdef MV_SPI_SLEEP_ON_WAIT
  76732. + mvOsSleep(1);
  76733. +#endif /* MV_SPI_SLEEP_ON_WAIT */
  76734. + }
  76735. +
  76736. + if (!ready)
  76737. + return MV_TIMEOUT;
  76738. +
  76739. + /* check that the RX data is needed */
  76740. + if (pRxData)
  76741. + {
  76742. + if ((MV_U32)pRxData & 0x1) /* check if address is not alligned to 16bit */
  76743. + {
  76744. +#if defined(MV_CPU_LE)
  76745. + /* perform the data write to the buffer in two stages with 8bit each */
  76746. + MV_U8 * bptr = (MV_U8*)pRxData;
  76747. + MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
  76748. + *bptr = (data & 0xFF);
  76749. + ++bptr;
  76750. + *bptr = ((data >> 8) & 0xFF);
  76751. +
  76752. +#elif defined(MV_CPU_BE)
  76753. +
  76754. + /* perform the data write to the buffer in two stages with 8bit each */
  76755. + MV_U8 * bptr = (MV_U8 *)pRxData;
  76756. + MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
  76757. + *bptr = ((data >> 8) & 0xFF);
  76758. + ++bptr;
  76759. + *bptr = (data & 0xFF);
  76760. +
  76761. +#else
  76762. + #error "CPU endianess isn't defined!\n"
  76763. +#endif
  76764. +
  76765. + }
  76766. + else
  76767. + *pRxData = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
  76768. + }
  76769. +
  76770. + return MV_OK;
  76771. +}
  76772. +
  76773. +
  76774. +/*******************************************************************************
  76775. +* mvSpi8bitDataTxRx - Transmt and receive data (8bits)
  76776. +*
  76777. +* DESCRIPTION:
  76778. +* Tx data and block waiting for data to be transmitted
  76779. +*
  76780. +********************************************************************************/
  76781. +static MV_STATUS mvSpi8bitDataTxRx (MV_U8 txData, MV_U8 * pRxData)
  76782. +{
  76783. + MV_U32 i;
  76784. + MV_BOOL ready = MV_FALSE;
  76785. +
  76786. + /* First clear the bit in the interrupt cause register */
  76787. + MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);
  76788. +
  76789. + /* Transmit data */
  76790. + MV_REG_WRITE(MV_SPI_DATA_OUT_REG, txData);
  76791. +
  76792. + /* wait with timeout for memory ready */
  76793. + for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)
  76794. + {
  76795. + if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))
  76796. + {
  76797. + ready = MV_TRUE;
  76798. + break;
  76799. + }
  76800. +#ifdef MV_SPI_SLEEP_ON_WAIT
  76801. + mvOsSleep(1);
  76802. +#endif /* MV_SPI_SLEEP_ON_WAIT */
  76803. + }
  76804. +
  76805. + if (!ready)
  76806. + return MV_TIMEOUT;
  76807. +
  76808. + /* check that the RX data is needed */
  76809. + if (pRxData)
  76810. + *pRxData = MV_REG_READ(MV_SPI_DATA_IN_REG);
  76811. +
  76812. + return MV_OK;
  76813. +}
  76814. +
  76815. +/*
  76816. +#####################################################################################
  76817. +#####################################################################################
  76818. +*/
  76819. +
  76820. +/*******************************************************************************
  76821. +* mvSpiInit - Initialize the SPI controller
  76822. +*
  76823. +* DESCRIPTION:
  76824. +* Perform the neccessary initialization in order to be able to send an
  76825. +* receive over the SPI interface.
  76826. +*
  76827. +* INPUT:
  76828. +* serialBaudRate: Baud rate (SPI clock frequency)
  76829. +* use16BitMode: Whether to use 2bytes (MV_TRUE) or 1bytes (MV_FALSE)
  76830. +*
  76831. +* OUTPUT:
  76832. +* None.
  76833. +*
  76834. +* RETURN:
  76835. +* Success or Error code.
  76836. +*
  76837. +*
  76838. +*******************************************************************************/
  76839. +MV_STATUS mvSpiInit (MV_U32 serialBaudRate)
  76840. +{
  76841. + MV_STATUS ret;
  76842. +
  76843. + /* Set the serial clock */
  76844. + if ((ret = mvSpiBaudRateSet(serialBaudRate)) != MV_OK)
  76845. + return ret;
  76846. +
  76847. + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
  76848. + mvMPPConfigToSPI();
  76849. +
  76850. + /* Configure the default SPI mode to be 16bit */
  76851. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  76852. +
  76853. + /* Fix ac timing on SPI in 6183, 6183L and 78x00 only */
  76854. + if ( (mvCtrlModelGet() == MV_6183_DEV_ID) ||
  76855. + (mvCtrlModelGet() == MV_6183L_DEV_ID) ||
  76856. + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
  76857. + (mvCtrlModelGet() == MV_78200_DEV_ID) ||
  76858. + (mvCtrlModelGet() == MV_76100_DEV_ID))
  76859. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, BIT14);
  76860. +
  76861. + /* Verify that the CS is deasserted */
  76862. + mvSpiCsDeassert();
  76863. +
  76864. + return MV_OK;
  76865. +}
  76866. +
  76867. +/*******************************************************************************
  76868. +* mvSpiBaudRateSet - Set the Frequency of the SPI clock
  76869. +*
  76870. +* DESCRIPTION:
  76871. +* Set the Prescale bits to adapt to the requested baud rate (the clock
  76872. +* used for thr SPI).
  76873. +*
  76874. +* INPUT:
  76875. +* serialBaudRate: Baud rate (SPI clock frequency)
  76876. +*
  76877. +* OUTPUT:
  76878. +* None.
  76879. +*
  76880. +* RETURN:
  76881. +* Success or Error code.
  76882. +*
  76883. +*
  76884. +*******************************************************************************/
  76885. +MV_STATUS mvSpiBaudRateSet (MV_U32 serialBaudRate)
  76886. +{
  76887. + MV_U8 i;
  76888. + /* MV_U8 preScale[32] = {1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  76889. + 2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
  76890. + */
  76891. + MV_U8 preScale[14] = { 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
  76892. + MV_U8 bestPrescaleIndx = 100;
  76893. + MV_U32 minBaudOffset = 0xFFFFFFFF;
  76894. + MV_U32 cpuClk = mvBoardTclkGet(); /*mvCpuPclkGet();*/
  76895. + MV_U32 tempReg;
  76896. +
  76897. + /* Find the best prescale configuration - less or equal */
  76898. + for (i=0; i<14; i++)
  76899. + {
  76900. + /* check for higher - irrelevent */
  76901. + if ((cpuClk / preScale[i]) > serialBaudRate)
  76902. + continue;
  76903. +
  76904. + /* check for exact fit */
  76905. + if ((cpuClk / preScale[i]) == serialBaudRate)
  76906. + {
  76907. + bestPrescaleIndx = i;
  76908. + break;
  76909. + }
  76910. +
  76911. + /* check if this is better than the previous one */
  76912. + if ((serialBaudRate - (cpuClk / preScale[i])) < minBaudOffset)
  76913. + {
  76914. + minBaudOffset = (serialBaudRate - (cpuClk / preScale[i]));
  76915. + bestPrescaleIndx = i;
  76916. + }
  76917. + }
  76918. +
  76919. + if (bestPrescaleIndx > 14)
  76920. + {
  76921. + mvOsPrintf("%s ERROR: SPI baud rate prescale error!\n", __FUNCTION__);
  76922. + return MV_OUT_OF_RANGE;
  76923. + }
  76924. +
  76925. + /* configure the Prescale */
  76926. + tempReg = MV_REG_READ(MV_SPI_IF_CONFIG_REG);
  76927. + tempReg = ((tempReg & ~MV_SPI_CLK_PRESCALE_MASK) | (bestPrescaleIndx + 0x12));
  76928. + MV_REG_WRITE(MV_SPI_IF_CONFIG_REG, tempReg);
  76929. +
  76930. + return MV_OK;
  76931. +}
  76932. +
  76933. +/*******************************************************************************
  76934. +* mvSpiCsAssert - Assert the Chip Select pin indicating a new transfer
  76935. +*
  76936. +* DESCRIPTION:
  76937. +* Assert The chip select - used to select an external SPI device
  76938. +*
  76939. +* INPUT:
  76940. +* None.
  76941. +*
  76942. +* OUTPUT:
  76943. +* None.
  76944. +*
  76945. +* RETURN:
  76946. +* Success or Error code.
  76947. +*
  76948. +********************************************************************************/
  76949. +MV_VOID mvSpiCsAssert(MV_VOID)
  76950. +{
  76951. + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
  76952. + mvMPPConfigToSPI();
  76953. + mvOsUDelay(1);
  76954. + MV_REG_BIT_SET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);
  76955. +}
  76956. +
  76957. +/*******************************************************************************
  76958. +* mvSpiCsDeassert - DeAssert the Chip Select pin indicating the end of a
  76959. +* SPI transfer sequence
  76960. +*
  76961. +* DESCRIPTION:
  76962. +* DeAssert the chip select pin
  76963. +*
  76964. +* INPUT:
  76965. +* None.
  76966. +*
  76967. +* OUTPUT:
  76968. +* None.
  76969. +*
  76970. +* RETURN:
  76971. +* Success or Error code.
  76972. +*
  76973. +********************************************************************************/
  76974. +MV_VOID mvSpiCsDeassert(MV_VOID)
  76975. +{
  76976. + MV_REG_BIT_RESET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);
  76977. +
  76978. + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
  76979. + mvMPPConfigToDefault();
  76980. +}
  76981. +
  76982. +/*******************************************************************************
  76983. +* mvSpiRead - Read a buffer over the SPI interface
  76984. +*
  76985. +* DESCRIPTION:
  76986. +* Receive (read) a buffer over the SPI interface in 16bit chunks. If the
  76987. +* buffer size is odd, then the last chunk will be 8bits. Chip select is not
  76988. +* handled at this level.
  76989. +*
  76990. +* INPUT:
  76991. +* pRxBuff: Pointer to the buffer to hold the received data
  76992. +* buffSize: length of the pRxBuff
  76993. +*
  76994. +* OUTPUT:
  76995. +* pRxBuff: Pointer to the buffer with the received data
  76996. +*
  76997. +* RETURN:
  76998. +* Success or Error code.
  76999. +*
  77000. +*
  77001. +*******************************************************************************/
  77002. +MV_STATUS mvSpiRead (MV_U8* pRxBuff, MV_U32 buffSize)
  77003. +{
  77004. + MV_STATUS ret;
  77005. + MV_U32 bytesLeft = buffSize;
  77006. + MV_U16* rxPtr = (MV_U16*)pRxBuff;
  77007. +
  77008. + /* check for null parameters */
  77009. + if (pRxBuff == NULL)
  77010. + {
  77011. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  77012. + return MV_BAD_PARAM;
  77013. + }
  77014. +
  77015. + /* Check that the buffer pointer and the buffer size are 16bit aligned */
  77016. + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))
  77017. + {
  77018. + /* Verify that the SPI mode is in 16bit mode */
  77019. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  77020. +
  77021. + /* TX/RX as long we have complete 16bit chunks */
  77022. + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
  77023. + {
  77024. + /* Transmitted and wait for the transfer to be completed */
  77025. + if ((ret = mvSpi16bitDataTxRx(MV_SPI_DUMMY_WRITE_16BITS, rxPtr)) != MV_OK)
  77026. + return ret;
  77027. +
  77028. + /* increment the pointers */
  77029. + rxPtr++;
  77030. + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
  77031. + }
  77032. +
  77033. + }
  77034. + else
  77035. + {
  77036. + /* Verify that the SPI mode is in 8bit mode */
  77037. + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  77038. +
  77039. + /* TX/RX in 8bit chanks */
  77040. + while (bytesLeft > 0)
  77041. + {
  77042. + /* Transmitted and wait for the transfer to be completed */
  77043. + if ((ret = mvSpi8bitDataTxRx(MV_SPI_DUMMY_WRITE_8BITS, pRxBuff)) != MV_OK)
  77044. + return ret;
  77045. + /* increment the pointers */
  77046. + pRxBuff++;
  77047. + bytesLeft--;
  77048. + }
  77049. + }
  77050. +
  77051. + return MV_OK;
  77052. +}
  77053. +
  77054. +/*******************************************************************************
  77055. +* mvSpiWrite - Transmit a buffer over the SPI interface
  77056. +*
  77057. +* DESCRIPTION:
  77058. +* Transmit a buffer over the SPI interface in 16bit chunks. If the
  77059. +* buffer size is odd, then the last chunk will be 8bits. No chip select
  77060. +* action is taken.
  77061. +*
  77062. +* INPUT:
  77063. +* pTxBuff: Pointer to the buffer holding the TX data
  77064. +* buffSize: length of the pTxBuff
  77065. +*
  77066. +* OUTPUT:
  77067. +* None.
  77068. +*
  77069. +* RETURN:
  77070. +* Success or Error code.
  77071. +*
  77072. +*
  77073. +*******************************************************************************/
  77074. +MV_STATUS mvSpiWrite(MV_U8* pTxBuff, MV_U32 buffSize)
  77075. +{
  77076. + MV_STATUS ret;
  77077. + MV_U32 bytesLeft = buffSize;
  77078. + MV_U16* txPtr = (MV_U16*)pTxBuff;
  77079. +
  77080. + /* check for null parameters */
  77081. + if (pTxBuff == NULL)
  77082. + {
  77083. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  77084. + return MV_BAD_PARAM;
  77085. + }
  77086. +
  77087. + /* Check that the buffer pointer and the buffer size are 16bit aligned */
  77088. + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0))
  77089. + {
  77090. + /* Verify that the SPI mode is in 16bit mode */
  77091. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  77092. +
  77093. + /* TX/RX as long we have complete 16bit chunks */
  77094. + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
  77095. + {
  77096. + /* Transmitted and wait for the transfer to be completed */
  77097. + if ((ret = mvSpi16bitDataTxRx(*txPtr, NULL)) != MV_OK)
  77098. + return ret;
  77099. +
  77100. + /* increment the pointers */
  77101. + txPtr++;
  77102. + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
  77103. + }
  77104. + }
  77105. + else
  77106. + {
  77107. +
  77108. + /* Verify that the SPI mode is in 8bit mode */
  77109. + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  77110. +
  77111. + /* TX/RX in 8bit chanks */
  77112. + while (bytesLeft > 0)
  77113. + {
  77114. + /* Transmitted and wait for the transfer to be completed */
  77115. + if ((ret = mvSpi8bitDataTxRx(*pTxBuff, NULL)) != MV_OK)
  77116. + return ret;
  77117. +
  77118. + /* increment the pointers */
  77119. + pTxBuff++;
  77120. + bytesLeft--;
  77121. + }
  77122. + }
  77123. +
  77124. + return MV_OK;
  77125. +}
  77126. +
  77127. +
  77128. +/*******************************************************************************
  77129. +* mvSpiReadWrite - Read and Write a buffer simultanuosely
  77130. +*
  77131. +* DESCRIPTION:
  77132. +* Transmit and receive a buffer over the SPI in 16bit chunks. If the
  77133. +* buffer size is odd, then the last chunk will be 8bits. The SPI chip
  77134. +* select is not handled implicitely.
  77135. +*
  77136. +* INPUT:
  77137. +* pRxBuff: Pointer to the buffer to write the RX info in
  77138. +* pTxBuff: Pointer to the buffer holding the TX info
  77139. +* buffSize: length of both the pTxBuff and pRxBuff
  77140. +*
  77141. +* OUTPUT:
  77142. +* pRxBuff: Pointer of the buffer holding the RX data
  77143. +*
  77144. +* RETURN:
  77145. +* Success or Error code.
  77146. +*
  77147. +*
  77148. +*******************************************************************************/
  77149. +MV_STATUS mvSpiReadWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)
  77150. +{
  77151. + MV_STATUS ret;
  77152. + MV_U32 bytesLeft = buffSize;
  77153. + MV_U16* txPtr = (MV_U16*)pTxBuff;
  77154. + MV_U16* rxPtr = (MV_U16*)pRxBuff;
  77155. +
  77156. + /* check for null parameters */
  77157. + if ((pRxBuff == NULL) || (pTxBuff == NULL))
  77158. + {
  77159. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  77160. + return MV_BAD_PARAM;
  77161. + }
  77162. +
  77163. + /* Check that the buffer pointer and the buffer size are 16bit aligned */
  77164. + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))
  77165. + {
  77166. + /* Verify that the SPI mode is in 16bit mode */
  77167. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  77168. +
  77169. + /* TX/RX as long we have complete 16bit chunks */
  77170. + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
  77171. + {
  77172. + /* Transmitted and wait for the transfer to be completed */
  77173. + if ((ret = mvSpi16bitDataTxRx(*txPtr, rxPtr)) != MV_OK)
  77174. + return ret;
  77175. +
  77176. + /* increment the pointers */
  77177. + txPtr++;
  77178. + rxPtr++;
  77179. + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
  77180. + }
  77181. + }
  77182. + else
  77183. + {
  77184. + /* Verify that the SPI mode is in 8bit mode */
  77185. + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  77186. +
  77187. + /* TX/RX in 8bit chanks */
  77188. + while (bytesLeft > 0)
  77189. + {
  77190. + /* Transmitted and wait for the transfer to be completed */
  77191. + if ( (ret = mvSpi8bitDataTxRx(*pTxBuff, pRxBuff) ) != MV_OK)
  77192. + return ret;
  77193. + pRxBuff++;
  77194. + pTxBuff++;
  77195. + bytesLeft--;
  77196. + }
  77197. + }
  77198. +
  77199. + return MV_OK;
  77200. +}
  77201. +
  77202. +
  77203. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c
  77204. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c 1970-01-01 01:00:00.000000000 +0100
  77205. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c 2011-07-31 11:32:01.653424091 +0200
  77206. @@ -0,0 +1,249 @@
  77207. +/*******************************************************************************
  77208. +Copyright (C) Marvell International Ltd. and its affiliates
  77209. +
  77210. +This software file (the "File") is owned and distributed by Marvell
  77211. +International Ltd. and/or its affiliates ("Marvell") under the following
  77212. +alternative licensing terms. Once you have made an election to distribute the
  77213. +File under one of the following license alternatives, please (i) delete this
  77214. +introductory statement regarding license alternatives, (ii) delete the two
  77215. +license alternatives that you have not elected to use and (iii) preserve the
  77216. +Marvell copyright notice above.
  77217. +
  77218. +********************************************************************************
  77219. +Marvell Commercial License Option
  77220. +
  77221. +If you received this File from Marvell and you have entered into a commercial
  77222. +license agreement (a "Commercial License") with Marvell, the File is licensed
  77223. +to you under the terms of the applicable Commercial License.
  77224. +
  77225. +********************************************************************************
  77226. +Marvell GPL License Option
  77227. +
  77228. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77229. +modify this File in accordance with the terms and conditions of the General
  77230. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  77231. +available along with the File in the license.txt file or by writing to the Free
  77232. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  77233. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  77234. +
  77235. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  77236. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  77237. +DISCLAIMED. The GPL License provides additional details about this warranty
  77238. +disclaimer.
  77239. +********************************************************************************
  77240. +Marvell BSD License Option
  77241. +
  77242. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77243. +modify this File under the following licensing terms.
  77244. +Redistribution and use in source and binary forms, with or without modification,
  77245. +are permitted provided that the following conditions are met:
  77246. +
  77247. + * Redistributions of source code must retain the above copyright notice,
  77248. + this list of conditions and the following disclaimer.
  77249. +
  77250. + * Redistributions in binary form must reproduce the above copyright
  77251. + notice, this list of conditions and the following disclaimer in the
  77252. + documentation and/or other materials provided with the distribution.
  77253. +
  77254. + * Neither the name of Marvell nor the names of its contributors may be
  77255. + used to endorse or promote products derived from this software without
  77256. + specific prior written permission.
  77257. +
  77258. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  77259. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  77260. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  77261. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  77262. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  77263. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  77264. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  77265. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  77266. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  77267. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  77268. +
  77269. +*******************************************************************************/
  77270. +
  77271. +#include "spi/mvSpi.h"
  77272. +#include "spi/mvSpiSpec.h"
  77273. +
  77274. +/*#define MV_DEBUG*/
  77275. +#ifdef MV_DEBUG
  77276. +#define DB(x) x
  77277. +#else
  77278. +#define DB(x)
  77279. +#endif
  77280. +
  77281. +
  77282. +/*******************************************************************************
  77283. +* mvSpiReadAndWrite - Read and Write a buffer simultanuousely
  77284. +*
  77285. +* DESCRIPTION:
  77286. +* Transmit and receive a buffer over the SPI in 16bit chunks. If the
  77287. +* buffer size is odd, then the last chunk will be 8bits.
  77288. +*
  77289. +* INPUT:
  77290. +* pRxBuff: Pointer to the buffer to write the RX info in
  77291. +* pTxBuff: Pointer to the buffer holding the TX info
  77292. +* buffSize: length of both the pTxBuff and pRxBuff
  77293. +*
  77294. +* OUTPUT:
  77295. +* pRxBuff: Pointer of the buffer holding the RX data
  77296. +*
  77297. +* RETURN:
  77298. +* Success or Error code.
  77299. +*
  77300. +*
  77301. +*******************************************************************************/
  77302. +MV_STATUS mvSpiReadAndWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)
  77303. +{
  77304. + MV_STATUS ret;
  77305. +
  77306. + /* check for null parameters */
  77307. + if ((pRxBuff == NULL) || (pTxBuff == NULL) || (buffSize == 0))
  77308. + {
  77309. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  77310. + return MV_BAD_PARAM;
  77311. + }
  77312. +
  77313. + /* First assert the chip select */
  77314. + mvSpiCsAssert();
  77315. +
  77316. + ret = mvSpiReadWrite(pRxBuff, pTxBuff, buffSize);
  77317. +
  77318. + /* Finally deassert the chip select */
  77319. + mvSpiCsDeassert();
  77320. +
  77321. + return ret;
  77322. +}
  77323. +
  77324. +/*******************************************************************************
  77325. +* mvSpiWriteThenWrite - Serialize a command followed by the data over the TX line
  77326. +*
  77327. +* DESCRIPTION:
  77328. +* Assert the chip select line. Transmit the command buffer followed by
  77329. +* the data buffer. Then deassert the CS line.
  77330. +*
  77331. +* INPUT:
  77332. +* pCmndBuff: Pointer to the command buffer to transmit
  77333. +* cmndSize: length of the command size
  77334. +* pTxDataBuff: Pointer to the data buffer to transmit
  77335. +* txDataSize: length of the data buffer
  77336. +*
  77337. +* OUTPUT:
  77338. +* None.
  77339. +*
  77340. +* RETURN:
  77341. +* Success or Error code.
  77342. +*
  77343. +*
  77344. +*******************************************************************************/
  77345. +MV_STATUS mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff,
  77346. + MV_U32 txDataSize)
  77347. +{
  77348. + MV_STATUS ret = MV_OK, tempRet;
  77349. +
  77350. + /* check for null parameters */
  77351. +#ifndef CONFIG_MARVELL
  77352. + if(NULL == pTxDataBuff)
  77353. + {
  77354. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  77355. + return MV_BAD_PARAM;
  77356. + }
  77357. +#endif
  77358. +
  77359. + if (pCmndBuff == NULL)
  77360. + {
  77361. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  77362. + return MV_BAD_PARAM;
  77363. + }
  77364. +
  77365. + /* First assert the chip select */
  77366. + mvSpiCsAssert();
  77367. +
  77368. + /* first write the command */
  77369. + if ((cmndSize) && (pCmndBuff != NULL))
  77370. + {
  77371. + if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)
  77372. + ret = tempRet;
  77373. + }
  77374. +
  77375. + /* Then write the data buffer */
  77376. +#ifndef CONFIG_MARVELL
  77377. + if (txDataSize)
  77378. +#else
  77379. + if ((txDataSize) && (pTxDataBuff != NULL))
  77380. +#endif
  77381. + {
  77382. + if ((tempRet = mvSpiWrite(pTxDataBuff, txDataSize)) != MV_OK)
  77383. + ret = tempRet;
  77384. + }
  77385. +
  77386. + /* Finally deassert the chip select */
  77387. + mvSpiCsDeassert();
  77388. +
  77389. + return ret;
  77390. +}
  77391. +
  77392. +/*******************************************************************************
  77393. +* mvSpiWriteThenRead - Serialize a command then read a data buffer
  77394. +*
  77395. +* DESCRIPTION:
  77396. +* Assert the chip select line. Transmit the command buffer then read
  77397. +* the data buffer. Then deassert the CS line.
  77398. +*
  77399. +* INPUT:
  77400. +* pCmndBuff: Pointer to the command buffer to transmit
  77401. +* cmndSize: length of the command size
  77402. +* pRxDataBuff: Pointer to the buffer to read the data in
  77403. +* txDataSize: length of the data buffer
  77404. +*
  77405. +* OUTPUT:
  77406. +* pRxDataBuff: Pointer to the buffer holding the data
  77407. +*
  77408. +* RETURN:
  77409. +* Success or Error code.
  77410. +*
  77411. +*
  77412. +*******************************************************************************/
  77413. +MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,
  77414. + MV_U32 rxDataSize,MV_U32 dummyBytesToRead)
  77415. +{
  77416. + MV_STATUS ret = MV_OK, tempRet;
  77417. + MV_U8 dummyByte;
  77418. +
  77419. + /* check for null parameters */
  77420. + if ((pCmndBuff == NULL) && (pRxDataBuff == NULL))
  77421. + {
  77422. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  77423. + return MV_BAD_PARAM;
  77424. + }
  77425. +
  77426. + /* First assert the chip select */
  77427. + mvSpiCsAssert();
  77428. +
  77429. + /* first write the command */
  77430. + if ((cmndSize) && (pCmndBuff != NULL))
  77431. + {
  77432. + if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)
  77433. + ret = tempRet;
  77434. + }
  77435. +
  77436. + /* Read dummy bytes before real data. */
  77437. + while(dummyBytesToRead)
  77438. + {
  77439. + mvSpiRead(&dummyByte,1);
  77440. + dummyBytesToRead--;
  77441. + }
  77442. +
  77443. + /* Then write the data buffer */
  77444. + if ((rxDataSize) && (pRxDataBuff != NULL))
  77445. + {
  77446. + if ((tempRet = mvSpiRead(pRxDataBuff, rxDataSize)) != MV_OK)
  77447. + ret = tempRet;
  77448. + }
  77449. +
  77450. + /* Finally deassert the chip select */
  77451. + mvSpiCsDeassert();
  77452. +
  77453. + return ret;
  77454. +}
  77455. +
  77456. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h
  77457. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h 1970-01-01 01:00:00.000000000 +0100
  77458. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h 2011-07-31 11:32:01.703503465 +0200
  77459. @@ -0,0 +1,82 @@
  77460. +/*******************************************************************************
  77461. +Copyright (C) Marvell International Ltd. and its affiliates
  77462. +
  77463. +This software file (the "File") is owned and distributed by Marvell
  77464. +International Ltd. and/or its affiliates ("Marvell") under the following
  77465. +alternative licensing terms. Once you have made an election to distribute the
  77466. +File under one of the following license alternatives, please (i) delete this
  77467. +introductory statement regarding license alternatives, (ii) delete the two
  77468. +license alternatives that you have not elected to use and (iii) preserve the
  77469. +Marvell copyright notice above.
  77470. +
  77471. +********************************************************************************
  77472. +Marvell Commercial License Option
  77473. +
  77474. +If you received this File from Marvell and you have entered into a commercial
  77475. +license agreement (a "Commercial License") with Marvell, the File is licensed
  77476. +to you under the terms of the applicable Commercial License.
  77477. +
  77478. +********************************************************************************
  77479. +Marvell GPL License Option
  77480. +
  77481. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77482. +modify this File in accordance with the terms and conditions of the General
  77483. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  77484. +available along with the File in the license.txt file or by writing to the Free
  77485. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  77486. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  77487. +
  77488. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  77489. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  77490. +DISCLAIMED. The GPL License provides additional details about this warranty
  77491. +disclaimer.
  77492. +********************************************************************************
  77493. +Marvell BSD License Option
  77494. +
  77495. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77496. +modify this File under the following licensing terms.
  77497. +Redistribution and use in source and binary forms, with or without modification,
  77498. +are permitted provided that the following conditions are met:
  77499. +
  77500. + * Redistributions of source code must retain the above copyright notice,
  77501. + this list of conditions and the following disclaimer.
  77502. +
  77503. + * Redistributions in binary form must reproduce the above copyright
  77504. + notice, this list of conditions and the following disclaimer in the
  77505. + documentation and/or other materials provided with the distribution.
  77506. +
  77507. + * Neither the name of Marvell nor the names of its contributors may be
  77508. + used to endorse or promote products derived from this software without
  77509. + specific prior written permission.
  77510. +
  77511. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  77512. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  77513. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  77514. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  77515. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  77516. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  77517. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  77518. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  77519. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  77520. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  77521. +
  77522. +*******************************************************************************/
  77523. +
  77524. +#ifndef __INCmvSpiCmndhH
  77525. +#define __INCmvSpiCmndhH
  77526. +
  77527. +#include "mvTypes.h"
  77528. +
  77529. +/* Function Prototypes */
  77530. +
  77531. +/* Simultanuous Read and write */
  77532. +MV_STATUS mvSpiReadAndWrite (MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);
  77533. +
  77534. +/* write command - write a command and then write data */
  77535. +MV_STATUS mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff, MV_U32 txDataSize);
  77536. +
  77537. +/* read command - write a command and then read data by writing dummy data */
  77538. +MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,
  77539. + MV_U32 rxDataSize,MV_U32 dummyBytesToRead);
  77540. +
  77541. +#endif /* __INCmvSpiCmndhH */
  77542. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h
  77543. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h 1970-01-01 01:00:00.000000000 +0100
  77544. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h 2011-07-31 11:32:01.773424275 +0200
  77545. @@ -0,0 +1,94 @@
  77546. +/*******************************************************************************
  77547. +Copyright (C) Marvell International Ltd. and its affiliates
  77548. +
  77549. +This software file (the "File") is owned and distributed by Marvell
  77550. +International Ltd. and/or its affiliates ("Marvell") under the following
  77551. +alternative licensing terms. Once you have made an election to distribute the
  77552. +File under one of the following license alternatives, please (i) delete this
  77553. +introductory statement regarding license alternatives, (ii) delete the two
  77554. +license alternatives that you have not elected to use and (iii) preserve the
  77555. +Marvell copyright notice above.
  77556. +
  77557. +********************************************************************************
  77558. +Marvell Commercial License Option
  77559. +
  77560. +If you received this File from Marvell and you have entered into a commercial
  77561. +license agreement (a "Commercial License") with Marvell, the File is licensed
  77562. +to you under the terms of the applicable Commercial License.
  77563. +
  77564. +********************************************************************************
  77565. +Marvell GPL License Option
  77566. +
  77567. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77568. +modify this File in accordance with the terms and conditions of the General
  77569. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  77570. +available along with the File in the license.txt file or by writing to the Free
  77571. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  77572. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  77573. +
  77574. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  77575. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  77576. +DISCLAIMED. The GPL License provides additional details about this warranty
  77577. +disclaimer.
  77578. +********************************************************************************
  77579. +Marvell BSD License Option
  77580. +
  77581. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77582. +modify this File under the following licensing terms.
  77583. +Redistribution and use in source and binary forms, with or without modification,
  77584. +are permitted provided that the following conditions are met:
  77585. +
  77586. + * Redistributions of source code must retain the above copyright notice,
  77587. + this list of conditions and the following disclaimer.
  77588. +
  77589. + * Redistributions in binary form must reproduce the above copyright
  77590. + notice, this list of conditions and the following disclaimer in the
  77591. + documentation and/or other materials provided with the distribution.
  77592. +
  77593. + * Neither the name of Marvell nor the names of its contributors may be
  77594. + used to endorse or promote products derived from this software without
  77595. + specific prior written permission.
  77596. +
  77597. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  77598. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  77599. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  77600. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  77601. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  77602. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  77603. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  77604. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  77605. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  77606. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  77607. +
  77608. +*******************************************************************************/
  77609. +
  77610. +#ifndef __INCmvSpihH
  77611. +#define __INCmvSpihH
  77612. +
  77613. +#include "mvCommon.h"
  77614. +#include "mvOs.h"
  77615. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  77616. +
  77617. +/* Function Prototypes */
  77618. +/* Init */
  77619. +MV_STATUS mvSpiInit (MV_U32 serialBaudRate);
  77620. +
  77621. +/* Set the Frequency of the Spi clock */
  77622. +MV_STATUS mvSpiBaudRateSet(MV_U32 serialBaudRate);
  77623. +
  77624. +/* Assert the SPI chip select */
  77625. +MV_VOID mvSpiCsAssert (MV_VOID);
  77626. +
  77627. +/* De-assert the SPI chip select */
  77628. +MV_VOID mvSpiCsDeassert (MV_VOID);
  77629. +
  77630. +/* Simultanuous Read and write */
  77631. +MV_STATUS mvSpiReadWrite (MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);
  77632. +
  77633. +/* serialize a buffer on the TX line - Rx is ignored */
  77634. +MV_STATUS mvSpiWrite (MV_U8* pTxBuff, MV_U32 buffSize);
  77635. +
  77636. +/* read from the RX line by writing dummy values to the TX line */
  77637. +MV_STATUS mvSpiRead (MV_U8* pRxBuff, MV_U32 buffSize);
  77638. +
  77639. +#endif /* __INCmvSpihH */
  77640. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h
  77641. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h 1970-01-01 01:00:00.000000000 +0100
  77642. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h 2011-07-31 11:32:01.823425403 +0200
  77643. @@ -0,0 +1,98 @@
  77644. +/*******************************************************************************
  77645. +Copyright (C) Marvell International Ltd. and its affiliates
  77646. +
  77647. +This software file (the "File") is owned and distributed by Marvell
  77648. +International Ltd. and/or its affiliates ("Marvell") under the following
  77649. +alternative licensing terms. Once you have made an election to distribute the
  77650. +File under one of the following license alternatives, please (i) delete this
  77651. +introductory statement regarding license alternatives, (ii) delete the two
  77652. +license alternatives that you have not elected to use and (iii) preserve the
  77653. +Marvell copyright notice above.
  77654. +
  77655. +********************************************************************************
  77656. +Marvell Commercial License Option
  77657. +
  77658. +If you received this File from Marvell and you have entered into a commercial
  77659. +license agreement (a "Commercial License") with Marvell, the File is licensed
  77660. +to you under the terms of the applicable Commercial License.
  77661. +
  77662. +********************************************************************************
  77663. +Marvell GPL License Option
  77664. +
  77665. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77666. +modify this File in accordance with the terms and conditions of the General
  77667. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  77668. +available along with the File in the license.txt file or by writing to the Free
  77669. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  77670. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  77671. +
  77672. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  77673. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  77674. +DISCLAIMED. The GPL License provides additional details about this warranty
  77675. +disclaimer.
  77676. +********************************************************************************
  77677. +Marvell BSD License Option
  77678. +
  77679. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77680. +modify this File under the following licensing terms.
  77681. +Redistribution and use in source and binary forms, with or without modification,
  77682. +are permitted provided that the following conditions are met:
  77683. +
  77684. + * Redistributions of source code must retain the above copyright notice,
  77685. + this list of conditions and the following disclaimer.
  77686. +
  77687. + * Redistributions in binary form must reproduce the above copyright
  77688. + notice, this list of conditions and the following disclaimer in the
  77689. + documentation and/or other materials provided with the distribution.
  77690. +
  77691. + * Neither the name of Marvell nor the names of its contributors may be
  77692. + used to endorse or promote products derived from this software without
  77693. + specific prior written permission.
  77694. +
  77695. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  77696. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  77697. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  77698. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  77699. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  77700. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  77701. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  77702. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  77703. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  77704. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  77705. +
  77706. +*******************************************************************************/
  77707. +
  77708. +#ifndef __INCmvSpiSpecH
  77709. +#define __INCmvSpiSpecH
  77710. +
  77711. +/* Constants */
  77712. +#define MV_SPI_WAIT_RDY_MAX_LOOP 100000
  77713. +#define MV_SPI_16_BIT_CHUNK_SIZE 2
  77714. +#define MV_SPI_DUMMY_WRITE_16BITS 0xFFFF
  77715. +#define MV_SPI_DUMMY_WRITE_8BITS 0xFF
  77716. +
  77717. +/* Marvell Flash Device Controller Registers */
  77718. +#define MV_SPI_CTRLR_OFST 0x10600
  77719. +#define MV_SPI_IF_CTRL_REG (MV_SPI_CTRLR_OFST + 0x00)
  77720. +#define MV_SPI_IF_CONFIG_REG (MV_SPI_CTRLR_OFST + 0x04)
  77721. +#define MV_SPI_DATA_OUT_REG (MV_SPI_CTRLR_OFST + 0x08)
  77722. +#define MV_SPI_DATA_IN_REG (MV_SPI_CTRLR_OFST + 0x0c)
  77723. +#define MV_SPI_INT_CAUSE_REG (MV_SPI_CTRLR_OFST + 0x10)
  77724. +#define MV_SPI_INT_CAUSE_MASK_REG (MV_SPI_CTRLR_OFST + 0x14)
  77725. +
  77726. +/* Serial Memory Interface Control Register Masks */
  77727. +#define MV_SPI_CS_ENABLE_OFFSET 0 /* bit 0 */
  77728. +#define MV_SPI_MEMORY_READY_OFFSET 1 /* bit 1 */
  77729. +#define MV_SPI_CS_ENABLE_MASK (0x1 << MV_SPI_CS_ENABLE_OFFSET)
  77730. +#define MV_SPI_MEMORY_READY_MASK (0x1 << MV_SPI_MEMORY_READY_OFFSET)
  77731. +
  77732. +/* Serial Memory Interface Configuration Register Masks */
  77733. +#define MV_SPI_CLK_PRESCALE_OFFSET 0 /* bit 0-4 */
  77734. +#define MV_SPI_BYTE_LENGTH_OFFSET 5 /* bit 5 */
  77735. +#define MV_SPI_ADDRESS_BURST_LENGTH_OFFSET 8 /* bit 8-9 */
  77736. +#define MV_SPI_CLK_PRESCALE_MASK (0x1F << MV_SPI_CLK_PRESCALE_OFFSET)
  77737. +#define MV_SPI_BYTE_LENGTH_MASK (0x1 << MV_SPI_BYTE_LENGTH_OFFSET)
  77738. +#define MV_SPI_ADDRESS_BURST_LENGTH_MASK (0x3 << MV_SPI_ADDRESS_BURST_LENGTH_OFFSET)
  77739. +
  77740. +#endif /* __INCmvSpiSpecH */
  77741. +
  77742. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c
  77743. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c 1970-01-01 01:00:00.000000000 +0100
  77744. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c 2011-07-31 11:32:01.863415702 +0200
  77745. @@ -0,0 +1,1023 @@
  77746. +/*******************************************************************************
  77747. +Copyright (C) Marvell International Ltd. and its affiliates
  77748. +
  77749. +This software file (the "File") is owned and distributed by Marvell
  77750. +International Ltd. and/or its affiliates ("Marvell") under the following
  77751. +alternative licensing terms. Once you have made an election to distribute the
  77752. +File under one of the following license alternatives, please (i) delete this
  77753. +introductory statement regarding license alternatives, (ii) delete the two
  77754. +license alternatives that you have not elected to use and (iii) preserve the
  77755. +Marvell copyright notice above.
  77756. +
  77757. +********************************************************************************
  77758. +Marvell Commercial License Option
  77759. +
  77760. +If you received this File from Marvell and you have entered into a commercial
  77761. +license agreement (a "Commercial License") with Marvell, the File is licensed
  77762. +to you under the terms of the applicable Commercial License.
  77763. +
  77764. +********************************************************************************
  77765. +Marvell GPL License Option
  77766. +
  77767. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77768. +modify this File in accordance with the terms and conditions of the General
  77769. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  77770. +available along with the File in the license.txt file or by writing to the Free
  77771. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  77772. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  77773. +
  77774. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  77775. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  77776. +DISCLAIMED. The GPL License provides additional details about this warranty
  77777. +disclaimer.
  77778. +********************************************************************************
  77779. +Marvell BSD License Option
  77780. +
  77781. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77782. +modify this File under the following licensing terms.
  77783. +Redistribution and use in source and binary forms, with or without modification,
  77784. +are permitted provided that the following conditions are met:
  77785. +
  77786. + * Redistributions of source code must retain the above copyright notice,
  77787. + this list of conditions and the following disclaimer.
  77788. +
  77789. + * Redistributions in binary form must reproduce the above copyright
  77790. + notice, this list of conditions and the following disclaimer in the
  77791. + documentation and/or other materials provided with the distribution.
  77792. +
  77793. + * Neither the name of Marvell nor the names of its contributors may be
  77794. + used to endorse or promote products derived from this software without
  77795. + specific prior written permission.
  77796. +
  77797. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  77798. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  77799. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  77800. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  77801. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  77802. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  77803. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  77804. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  77805. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  77806. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  77807. +
  77808. +*******************************************************************************/
  77809. +
  77810. +
  77811. +#include "mvTwsi.h"
  77812. +#include "mvTwsiSpec.h"
  77813. +#include "cpu/mvCpu.h"
  77814. +
  77815. +
  77816. +/*#define MV_DEBUG*/
  77817. +#ifdef MV_DEBUG
  77818. +#define DB(x) x
  77819. +#else
  77820. +#define DB(x)
  77821. +#endif
  77822. +
  77823. +static MV_VOID twsiIntFlgClr(MV_U8 chanNum);
  77824. +static MV_BOOL twsiMainIntGet(MV_U8 chanNum);
  77825. +static MV_VOID twsiAckBitSet(MV_U8 chanNum);
  77826. +static MV_U32 twsiStsGet(MV_U8 chanNum);
  77827. +static MV_VOID twsiReset(MV_U8 chanNum);
  77828. +static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);
  77829. +static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);
  77830. +static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);
  77831. +static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);
  77832. +static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset,MV_BOOL moreThen256);
  77833. +
  77834. +
  77835. +static MV_BOOL twsiTimeoutChk(MV_U32 timeout, const MV_8 *pString)
  77836. +{
  77837. + if(timeout >= TWSI_TIMEOUT_VALUE)
  77838. + {
  77839. + DB(mvOsPrintf("%s",pString));
  77840. + return MV_TRUE;
  77841. + }
  77842. + return MV_FALSE;
  77843. +
  77844. +}
  77845. +/*******************************************************************************
  77846. +* mvTwsiStartBitSet - Set start bit on the bus
  77847. +*
  77848. +* DESCRIPTION:
  77849. +* This routine sets the start bit on the TWSI bus.
  77850. +* The routine first checks for interrupt flag condition, then it sets
  77851. +* the start bit in the TWSI Control register.
  77852. +* If the interrupt flag condition check previously was set, the function
  77853. +* will clear it.
  77854. +* The function then wait for the start bit to be cleared by the HW.
  77855. +* Then it waits for the interrupt flag to be set and eventually, the
  77856. +* TWSI status is checked to be 0x8 or 0x10(repeated start bit).
  77857. +*
  77858. +* INPUT:
  77859. +* chanNum - TWSI channel.
  77860. +*
  77861. +* OUTPUT:
  77862. +* None.
  77863. +*
  77864. +* RETURN:
  77865. +* MV_OK is start bit was set successfuly on the bus.
  77866. +* MV_FAIL if interrupt flag was set before setting start bit.
  77867. +*
  77868. +*******************************************************************************/
  77869. +MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum)
  77870. +{
  77871. + MV_BOOL isIntFlag = MV_FALSE;
  77872. + MV_U32 timeout, temp;
  77873. +
  77874. + DB(mvOsPrintf("TWSI: mvTwsiStartBitSet \n"));
  77875. + /* check Int flag */
  77876. + if(twsiMainIntGet(chanNum))
  77877. + isIntFlag = MV_TRUE;
  77878. + /* set start Bit */
  77879. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  77880. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_START_BIT);
  77881. +
  77882. + /* in case that the int flag was set before i.e. repeated start bit */
  77883. + if(isIntFlag){
  77884. + DB(mvOsPrintf("TWSI: mvTwsiStartBitSet repeated start Bit\n"));
  77885. + twsiIntFlgClr(chanNum);
  77886. + }
  77887. +
  77888. + /* wait for interrupt */
  77889. + timeout = 0;
  77890. + while(!twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77891. +
  77892. + /* check for timeout */
  77893. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStartBitSet ERROR - Start Clear bit TimeOut .\n"))
  77894. + return MV_TIMEOUT;
  77895. +
  77896. +
  77897. + /* check that start bit went down */
  77898. + if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_START_BIT) != 0)
  77899. + {
  77900. + mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - start bit didn't went down\n");
  77901. + return MV_FAIL;
  77902. + }
  77903. +
  77904. + /* check the status */
  77905. + temp = twsiStsGet(chanNum);
  77906. + if(( temp != TWSI_START_CON_TRA ) && ( temp != TWSI_REPEATED_START_CON_TRA ))
  77907. + {
  77908. + mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - status %x after Set Start Bit. \n",temp);
  77909. + return MV_FAIL;
  77910. + }
  77911. +
  77912. + return MV_OK;
  77913. +
  77914. +}
  77915. +
  77916. +/*******************************************************************************
  77917. +* mvTwsiStopBitSet - Set stop bit on the bus
  77918. +*
  77919. +* DESCRIPTION:
  77920. +* This routine set the stop bit on the TWSI bus.
  77921. +* The function then wait for the stop bit to be cleared by the HW.
  77922. +* Finally the function checks for status of 0xF8.
  77923. +*
  77924. +* INPUT:
  77925. +* chanNum - TWSI channel
  77926. +*
  77927. +* OUTPUT:
  77928. +* None.
  77929. +*
  77930. +* RETURN:
  77931. +* MV_TRUE is stop bit was set successfuly on the bus.
  77932. +*
  77933. +*******************************************************************************/
  77934. +MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum)
  77935. +{
  77936. + MV_U32 timeout, temp;
  77937. +
  77938. + /* Generate stop bit */
  77939. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  77940. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_STOP_BIT);
  77941. +
  77942. + twsiIntFlgClr(chanNum);
  77943. +
  77944. + /* wait for stop bit to come down */
  77945. + timeout = 0;
  77946. + while( ((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77947. +
  77948. + /* check for timeout */
  77949. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStopBitSet ERROR - Stop bit TimeOut .\n"))
  77950. + return MV_TIMEOUT;
  77951. +
  77952. + /* check that the stop bit went down */
  77953. + if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0)
  77954. + {
  77955. + mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - stop bit didn't went down. \n");
  77956. + return MV_FAIL;
  77957. + }
  77958. +
  77959. + /* check the status */
  77960. + temp = twsiStsGet(chanNum);
  77961. + if( temp != TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0){
  77962. + mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - status %x after Stop Bit. \n", temp);
  77963. + return MV_FAIL;
  77964. + }
  77965. +
  77966. + return MV_OK;
  77967. +}
  77968. +
  77969. +/*******************************************************************************
  77970. +* twsiMainIntGet - Get twsi bit from main Interrupt cause.
  77971. +*
  77972. +* DESCRIPTION:
  77973. +* This routine returns the twsi interrupt flag value.
  77974. +*
  77975. +* INPUT:
  77976. +* None.
  77977. +*
  77978. +* OUTPUT:
  77979. +* None.
  77980. +*
  77981. +* RETURN:
  77982. +* MV_TRUE is interrupt flag is set, MV_FALSE otherwise.
  77983. +*
  77984. +*******************************************************************************/
  77985. +static MV_BOOL twsiMainIntGet(MV_U8 chanNum)
  77986. +{
  77987. + MV_U32 temp;
  77988. +
  77989. + /* get the int flag bit */
  77990. +
  77991. + temp = MV_REG_READ(TWSI_CPU_MAIN_INT_CAUSE_REG);
  77992. + if (temp & (TWSI0_CPU_MAIN_INT_BIT << chanNum))
  77993. + return MV_TRUE;
  77994. +
  77995. + return MV_FALSE;
  77996. +}
  77997. +/*******************************************************************************
  77998. +* twsiIntFlgClr - Clear Interrupt flag.
  77999. +*
  78000. +* DESCRIPTION:
  78001. +* This routine clears the interrupt flag. It does NOT poll the interrupt
  78002. +* to make sure the clear. After clearing the interrupt, it waits for at
  78003. +* least 1 miliseconds.
  78004. +*
  78005. +* INPUT:
  78006. +* chanNum - TWSI channel
  78007. +*
  78008. +* OUTPUT:
  78009. +* None.
  78010. +*
  78011. +* RETURN:
  78012. +* None.
  78013. +*
  78014. +*******************************************************************************/
  78015. +static MV_VOID twsiIntFlgClr(MV_U8 chanNum)
  78016. +{
  78017. + MV_U32 temp;
  78018. +
  78019. + /* wait for 1 mili to prevent TWSI register write after write problems */
  78020. + mvOsDelay(1);
  78021. + /* clear the int flag bit */
  78022. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  78023. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum),temp & ~(TWSI_CONTROL_INT_FLAG_SET));
  78024. +
  78025. + /* wait for 1 mili sec for the clear to take effect */
  78026. + mvOsDelay(1);
  78027. +
  78028. + return;
  78029. +}
  78030. +
  78031. +
  78032. +/*******************************************************************************
  78033. +* twsiAckBitSet - Set acknowledge bit on the bus
  78034. +*
  78035. +* DESCRIPTION:
  78036. +* This routine set the acknowledge bit on the TWSI bus.
  78037. +*
  78038. +* INPUT:
  78039. +* None.
  78040. +*
  78041. +* OUTPUT:
  78042. +* None.
  78043. +*
  78044. +* RETURN:
  78045. +* None.
  78046. +*
  78047. +*******************************************************************************/
  78048. +static MV_VOID twsiAckBitSet(MV_U8 chanNum)
  78049. +{
  78050. + MV_U32 temp;
  78051. +
  78052. + /*Set the Ack bit */
  78053. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  78054. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_ACK);
  78055. +
  78056. + /* Add delay of 1ms */
  78057. + mvOsDelay(1);
  78058. + return;
  78059. +}
  78060. +
  78061. +
  78062. +/*******************************************************************************
  78063. +* twsiInit - Initialize TWSI interface
  78064. +*
  78065. +* DESCRIPTION:
  78066. +* This routine:
  78067. +* -Reset the TWSI.
  78068. +* -Initialize the TWSI clock baud rate according to given frequancy
  78069. +* parameter based on Tclk frequancy and enables TWSI slave.
  78070. +* -Set the ack bit.
  78071. +* -Assign the TWSI slave address according to the TWSI address Type.
  78072. +*
  78073. +*
  78074. +* INPUT:
  78075. +* chanNum - TWSI channel
  78076. +* frequancy - TWSI frequancy in KHz. (up to 100KHZ)
  78077. +*
  78078. +* OUTPUT:
  78079. +* None.
  78080. +*
  78081. +* RETURN:
  78082. +* Actual frequancy.
  78083. +*
  78084. +*******************************************************************************/
  78085. +MV_U32 mvTwsiInit(MV_U8 chanNum, MV_HZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *pTwsiAddr, MV_BOOL generalCallEnable)
  78086. +{
  78087. + MV_U32 n,m,freq,margin,minMargin = 0xffffffff;
  78088. + MV_U32 power;
  78089. + MV_U32 actualFreq = 0,actualN = 0,actualM = 0,val;
  78090. +
  78091. + if(frequancy > 100000)
  78092. + {
  78093. + mvOsPrintf("Warning TWSI frequancy is too high, please use up tp 100Khz. \n");
  78094. + }
  78095. +
  78096. + DB(mvOsPrintf("TWSI: mvTwsiInit - Tclk = %d freq = %d\n",Tclk,frequancy));
  78097. + /* Calucalte N and M for the TWSI clock baud rate */
  78098. + for(n = 0 ; n < 8 ; n++)
  78099. + {
  78100. + for(m = 0 ; m < 16 ; m++)
  78101. + {
  78102. + power = 2 << n; /* power = 2^(n+1) */
  78103. + freq = Tclk/(10*(m+1)*power);
  78104. + margin = MV_ABS(frequancy - freq);
  78105. + if(margin < minMargin)
  78106. + {
  78107. + minMargin = margin;
  78108. + actualFreq = freq;
  78109. + actualN = n;
  78110. + actualM = m;
  78111. + }
  78112. + }
  78113. + }
  78114. + DB(mvOsPrintf("TWSI: mvTwsiInit - actN %d actM %d actFreq %d\n",actualN , actualM, actualFreq));
  78115. + /* Reset the TWSI logic */
  78116. + twsiReset(chanNum);
  78117. +
  78118. + /* Set the baud rate */
  78119. + val = ((actualM<< TWSI_BAUD_RATE_M_OFFS) | actualN << TWSI_BAUD_RATE_N_OFFS);
  78120. + MV_REG_WRITE(TWSI_STATUS_BAUDE_RATE_REG(chanNum),val);
  78121. +
  78122. + /* Enable the TWSI and slave */
  78123. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), TWSI_CONTROL_ENA | TWSI_CONTROL_ACK);
  78124. +
  78125. + /* set the TWSI slave address */
  78126. + if( pTwsiAddr->type == ADDR10_BIT )/* 10 Bit deviceAddress */
  78127. + {
  78128. + /* writing the 2 most significant bits of the 10 bit address*/
  78129. + val = ((pTwsiAddr->address & TWSI_SLAVE_ADDR_10BIT_MASK) >> TWSI_SLAVE_ADDR_10BIT_OFFS );
  78130. + /* bits 7:3 must be 0x11110 */
  78131. + val |= TWSI_SLAVE_ADDR_10BIT_CONST;
  78132. + /* set GCE bit */
  78133. + if(generalCallEnable)
  78134. + val |= TWSI_SLAVE_ADDR_GCE_ENA;
  78135. + /* write slave address */
  78136. + MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum),val);
  78137. +
  78138. + /* writing the 8 least significant bits of the 10 bit address*/
  78139. + val = (pTwsiAddr->address << TWSI_EXTENDED_SLAVE_OFFS) & TWSI_EXTENDED_SLAVE_MASK;
  78140. + MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum), val);
  78141. + }
  78142. + else /*7 bit address*/
  78143. + {
  78144. + /* set the 7 Bits address */
  78145. + MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum),0x0);
  78146. + val = (pTwsiAddr->address << TWSI_SLAVE_ADDR_7BIT_OFFS) & TWSI_SLAVE_ADDR_7BIT_MASK;
  78147. + MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum), val);
  78148. + }
  78149. +
  78150. + /* unmask twsi int */
  78151. + val = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  78152. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), val | TWSI_CONTROL_INT_ENA);
  78153. + /* Add delay of 1ms */
  78154. + mvOsDelay(1);
  78155. +
  78156. + return actualFreq;
  78157. +}
  78158. +
  78159. +
  78160. +/*******************************************************************************
  78161. +* twsiStsGet - Get the TWSI status value.
  78162. +*
  78163. +* DESCRIPTION:
  78164. +* This routine returns the TWSI status value.
  78165. +*
  78166. +* INPUT:
  78167. +* chanNum - TWSI channel
  78168. +*
  78169. +* OUTPUT:
  78170. +* None.
  78171. +*
  78172. +* RETURN:
  78173. +* MV_U32 - the TWSI status.
  78174. +*
  78175. +*******************************************************************************/
  78176. +static MV_U32 twsiStsGet(MV_U8 chanNum)
  78177. +{
  78178. + return MV_REG_READ(TWSI_STATUS_BAUDE_RATE_REG(chanNum));
  78179. +
  78180. +}
  78181. +
  78182. +/*******************************************************************************
  78183. +* twsiReset - Reset the TWSI.
  78184. +*
  78185. +* DESCRIPTION:
  78186. +* Resets the TWSI logic and sets all TWSI registers to their reset values.
  78187. +*
  78188. +* INPUT:
  78189. +* chanNum - TWSI channel
  78190. +*
  78191. +* OUTPUT:
  78192. +* None.
  78193. +*
  78194. +* RETURN:
  78195. +* None
  78196. +*
  78197. +*******************************************************************************/
  78198. +static MV_VOID twsiReset(MV_U8 chanNum)
  78199. +{
  78200. + /* Reset the TWSI logic */
  78201. + MV_REG_WRITE(TWSI_SOFT_RESET_REG(chanNum),0);
  78202. +
  78203. + /* wait for 2 mili sec */
  78204. + mvOsDelay(2);
  78205. +
  78206. + return;
  78207. +}
  78208. +
  78209. +
  78210. +
  78211. +
  78212. +/******************************* POLICY ****************************************/
  78213. +
  78214. +
  78215. +
  78216. +/*******************************************************************************
  78217. +* mvTwsiAddrSet - Set address on TWSI bus.
  78218. +*
  78219. +* DESCRIPTION:
  78220. +* This function Set address (7 or 10 Bit address) on the Twsi Bus.
  78221. +*
  78222. +* INPUT:
  78223. +* chanNum - TWSI channel
  78224. +* pTwsiAddr - twsi address.
  78225. +* command - read / write .
  78226. +*
  78227. +* OUTPUT:
  78228. +* None.
  78229. +*
  78230. +* RETURN:
  78231. +* MV_OK - if setting the address completed succesfully.
  78232. +* MV_FAIL otherwmise.
  78233. +*
  78234. +*******************************************************************************/
  78235. +MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *pTwsiAddr, MV_TWSI_CMD command)
  78236. +{
  78237. + DB(mvOsPrintf("TWSI: mvTwsiAddr7BitSet addr %x , type %d, cmd is %s\n",pTwsiAddr->address,\
  78238. + pTwsiAddr->type, ((command==MV_TWSI_WRITE)?"Write":"Read") ));
  78239. + /* 10 Bit address */
  78240. + if(pTwsiAddr->type == ADDR10_BIT)
  78241. + {
  78242. + return twsiAddr10BitSet(chanNum, pTwsiAddr->address,command);
  78243. + }
  78244. + /* 7 Bit address */
  78245. + else
  78246. + {
  78247. + return twsiAddr7BitSet(chanNum, pTwsiAddr->address,command);
  78248. + }
  78249. +
  78250. +}
  78251. +
  78252. +/*******************************************************************************
  78253. +* twsiAddr10BitSet - Set 10 Bit address on TWSI bus.
  78254. +*
  78255. +* DESCRIPTION:
  78256. +* There are two address phases:
  78257. +* 1) Write '11110' to data register bits [7:3] and 10-bit address MSB
  78258. +* (bits [9:8]) to data register bits [2:1] plus a write(0) or read(1) bit
  78259. +* to the Data register. Then it clears interrupt flag which drive
  78260. +* the address on the TWSI bus. The function then waits for interrupt
  78261. +* flag to be active and status 0x18 (write) or 0x40 (read) to be set.
  78262. +* 2) write the rest of 10-bit address to data register and clears
  78263. +* interrupt flag which drive the address on the TWSI bus. The
  78264. +* function then waits for interrupt flag to be active and status
  78265. +* 0xD0 (write) or 0xE0 (read) to be set.
  78266. +*
  78267. +* INPUT:
  78268. +* chanNum - TWSI channel
  78269. +* deviceAddress - twsi address.
  78270. +* command - read / write .
  78271. +*
  78272. +* OUTPUT:
  78273. +* None.
  78274. +*
  78275. +* RETURN:
  78276. +* MV_OK - if setting the address completed succesfully.
  78277. +* MV_FAIL otherwmise.
  78278. +*
  78279. +*******************************************************************************/
  78280. +static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)
  78281. +{
  78282. + MV_U32 val,timeout;
  78283. +
  78284. + /* writing the 2 most significant bits of the 10 bit address*/
  78285. + val = ((deviceAddress & TWSI_DATA_ADDR_10BIT_MASK) >> TWSI_DATA_ADDR_10BIT_OFFS );
  78286. + /* bits 7:3 must be 0x11110 */
  78287. + val |= TWSI_DATA_ADDR_10BIT_CONST;
  78288. + /* set command */
  78289. + val |= command;
  78290. + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
  78291. + /* WA add a delay */
  78292. + mvOsDelay(1);
  78293. +
  78294. + /* clear Int flag */
  78295. + twsiIntFlgClr(chanNum);
  78296. +
  78297. + /* wait for Int to be Set */
  78298. + timeout = 0;
  78299. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  78300. +
  78301. + /* check for timeout */
  78302. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 1st addr (10Bit) Int TimeOut.\n"))
  78303. + return MV_TIMEOUT;
  78304. +
  78305. + /* check the status */
  78306. + val = twsiStsGet(chanNum);
  78307. + if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
  78308. + ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
  78309. + {
  78310. + mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 1st addr (10 Bit) in %s mode.\n"\
  78311. + ,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );
  78312. + return MV_FAIL;
  78313. + }
  78314. +
  78315. + /* set 8 LSB of the address */
  78316. + val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;
  78317. + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
  78318. +
  78319. + /* clear Int flag */
  78320. + twsiIntFlgClr(chanNum);
  78321. +
  78322. + /* wait for Int to be Set */
  78323. + timeout = 0;
  78324. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  78325. +
  78326. + /* check for timeout */
  78327. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 2nd (10 Bit) Int TimOut.\n"))
  78328. + return MV_TIMEOUT;
  78329. +
  78330. + /* check the status */
  78331. + val = twsiStsGet(chanNum);
  78332. + if(( (val != TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
  78333. + ( (val != TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
  78334. + {
  78335. + mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 2nd addr(10 Bit) in %s mode.\n"\
  78336. + ,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );
  78337. + return MV_FAIL;
  78338. + }
  78339. +
  78340. + return MV_OK;
  78341. +}
  78342. +
  78343. +/*******************************************************************************
  78344. +* twsiAddr7BitSet - Set 7 Bit address on TWSI bus.
  78345. +*
  78346. +* DESCRIPTION:
  78347. +* This function writes 7 bit address plus a write or read bit to the
  78348. +* Data register. Then it clears interrupt flag which drive the address on
  78349. +* the TWSI bus. The function then waits for interrupt flag to be active
  78350. +* and status 0x18 (write) or 0x40 (read) to be set.
  78351. +*
  78352. +* INPUT:
  78353. +* chanNum - TWSI channel
  78354. +* deviceAddress - twsi address.
  78355. +* command - read / write .
  78356. +*
  78357. +* OUTPUT:
  78358. +* None.
  78359. +*
  78360. +* RETURN:
  78361. +* MV_OK - if setting the address completed succesfully.
  78362. +* MV_FAIL otherwmise.
  78363. +*
  78364. +*******************************************************************************/
  78365. +static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)
  78366. +{
  78367. + MV_U32 val,timeout;
  78368. +
  78369. + /* set the address */
  78370. + val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;
  78371. + /* set command */
  78372. + val |= command;
  78373. + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
  78374. + /* WA add a delay */
  78375. + mvOsDelay(1);
  78376. +
  78377. + /* clear Int flag */
  78378. + twsiIntFlgClr(chanNum);
  78379. +
  78380. + /* wait for Int to be Set */
  78381. + timeout = 0;
  78382. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  78383. +
  78384. + /* check for timeout */
  78385. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr7BitSet ERROR - Addr (7 Bit) int TimeOut.\n"))
  78386. + return MV_TIMEOUT;
  78387. +
  78388. + /* check the status */
  78389. + val = twsiStsGet(chanNum);
  78390. + if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
  78391. + ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
  78392. + {
  78393. + /* only in debug, since in boot we try to read the SPD of both DRAM, and we don't
  78394. + want error messeges in case DIMM doesn't exist. */
  78395. + DB(mvOsPrintf("TWSI: twsiAddr7BitSet ERROR - status %x addr (7 Bit) in %s mode.\n"\
  78396. + ,val,((command==MV_TWSI_WRITE)?"Write":"Read") ));
  78397. + return MV_FAIL;
  78398. + }
  78399. +
  78400. + return MV_OK;
  78401. +}
  78402. +
  78403. +/*******************************************************************************
  78404. +* twsiDataWrite - Trnasmit a data block over TWSI bus.
  78405. +*
  78406. +* DESCRIPTION:
  78407. +* This function writes a given data block to TWSI bus in 8 bit granularity.
  78408. +* first The function waits for interrupt flag to be active then
  78409. +* For each 8-bit data:
  78410. +* The function writes data to data register. It then clears
  78411. +* interrupt flag which drives the data on the TWSI bus.
  78412. +* The function then waits for interrupt flag to be active and status
  78413. +* 0x28 to be set.
  78414. +*
  78415. +*
  78416. +* INPUT:
  78417. +* chanNum - TWSI channel
  78418. +* pBlock - Data block.
  78419. +* blockSize - number of chars in pBlock.
  78420. +*
  78421. +* OUTPUT:
  78422. +* None.
  78423. +*
  78424. +* RETURN:
  78425. +* MV_OK - if transmiting the block completed succesfully,
  78426. +* MV_BAD_PARAM - if pBlock is NULL,
  78427. +* MV_FAIL otherwmise.
  78428. +*
  78429. +*******************************************************************************/
  78430. +static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)
  78431. +{
  78432. + MV_U32 timeout, temp, blockSizeWr = blockSize;
  78433. +
  78434. + if(NULL == pBlock)
  78435. + return MV_BAD_PARAM;
  78436. +
  78437. + /* wait for Int to be Set */
  78438. + timeout = 0;
  78439. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  78440. +
  78441. + /* check for timeout */
  78442. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))
  78443. + return MV_TIMEOUT;
  78444. +
  78445. + while(blockSizeWr)
  78446. + {
  78447. + /* write the data*/
  78448. + MV_REG_WRITE(TWSI_DATA_REG(chanNum),(MV_U32)*pBlock);
  78449. + DB(mvOsPrintf("TWSI: twsiDataTransmit place = %d write %x \n",\
  78450. + blockSize - blockSizeWr, *pBlock));
  78451. + pBlock++;
  78452. + blockSizeWr--;
  78453. +
  78454. + twsiIntFlgClr(chanNum);
  78455. +
  78456. + /* wait for Int to be Set */
  78457. + timeout = 0;
  78458. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  78459. +
  78460. + /* check for timeout */
  78461. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))
  78462. + return MV_TIMEOUT;
  78463. +
  78464. + /* check the status */
  78465. + temp = twsiStsGet(chanNum);
  78466. + if(temp != TWSI_M_TRAN_DATA_BYTE_ACK_REC)
  78467. + {
  78468. + mvOsPrintf("TWSI: twsiDataTransmit ERROR - status %x in write trans\n",temp);
  78469. + return MV_FAIL;
  78470. + }
  78471. +
  78472. + }
  78473. +
  78474. + return MV_OK;
  78475. +}
  78476. +
  78477. +/*******************************************************************************
  78478. +* twsiDataReceive - Receive data block from TWSI bus.
  78479. +*
  78480. +* DESCRIPTION:
  78481. +* This function receive data block from TWSI bus in 8bit granularity
  78482. +* into pBlock buffer.
  78483. +* first The function waits for interrupt flag to be active then
  78484. +* For each 8-bit data:
  78485. +* It clears the interrupt flag which allows the next data to be
  78486. +* received from TWSI bus.
  78487. +* The function waits for interrupt flag to be active,
  78488. +* and status reg is 0x50.
  78489. +* Then the function reads data from data register, and copies it to
  78490. +* the given buffer.
  78491. +*
  78492. +* INPUT:
  78493. +* chanNum - TWSI channel
  78494. +* blockSize - number of bytes to read.
  78495. +*
  78496. +* OUTPUT:
  78497. +* pBlock - Data block.
  78498. +*
  78499. +* RETURN:
  78500. +* MV_OK - if receive transaction completed succesfully,
  78501. +* MV_BAD_PARAM - if pBlock is NULL,
  78502. +* MV_FAIL otherwmise.
  78503. +*
  78504. +*******************************************************************************/
  78505. +static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)
  78506. +{
  78507. + MV_U32 timeout, temp, blockSizeRd = blockSize;
  78508. + if(NULL == pBlock)
  78509. + return MV_BAD_PARAM;
  78510. +
  78511. + /* wait for Int to be Set */
  78512. + timeout = 0;
  78513. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  78514. +
  78515. + /* check for timeout */
  78516. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data int Time out .\n"))
  78517. + return MV_TIMEOUT;
  78518. +
  78519. + while(blockSizeRd)
  78520. + {
  78521. + if(blockSizeRd == 1)
  78522. + {
  78523. + /* clear ack and Int flag */
  78524. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  78525. + temp &= ~(TWSI_CONTROL_ACK);
  78526. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp);
  78527. + }
  78528. + twsiIntFlgClr(chanNum);
  78529. + /* wait for Int to be Set */
  78530. + timeout = 0;
  78531. + while( (!twsiMainIntGet(chanNum)) && (timeout++ < TWSI_TIMEOUT_VALUE));
  78532. +
  78533. + /* check for timeout */
  78534. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data Int Time out .\n"))
  78535. + return MV_TIMEOUT;
  78536. +
  78537. + /* check the status */
  78538. + temp = twsiStsGet(chanNum);
  78539. + if((temp != TWSI_M_REC_RD_DATA_ACK_TRA) && (blockSizeRd !=1))
  78540. + {
  78541. + mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in read trans \n",temp);
  78542. + return MV_FAIL;
  78543. + }
  78544. + else if((temp != TWSI_M_REC_RD_DATA_ACK_NOT_TRA) && (blockSizeRd ==1))
  78545. + {
  78546. + mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in Rd Terminate\n",temp);
  78547. + return MV_FAIL;
  78548. + }
  78549. +
  78550. + /* read the data*/
  78551. + *pBlock = (MV_U8)MV_REG_READ(TWSI_DATA_REG(chanNum));
  78552. + DB(mvOsPrintf("TWSI: twsiDataReceive place %d read %x \n",\
  78553. + blockSize - blockSizeRd,*pBlock));
  78554. + pBlock++;
  78555. + blockSizeRd--;
  78556. + }
  78557. +
  78558. + return MV_OK;
  78559. +}
  78560. +
  78561. +
  78562. +
  78563. +/*******************************************************************************
  78564. +* twsiTargetOffsSet - Set TWST target offset on TWSI bus.
  78565. +*
  78566. +* DESCRIPTION:
  78567. +* The function support TWSI targets that have inside address space (for
  78568. +* example EEPROMs). The function:
  78569. +* 1) Convert the given offset into pBlock and size.
  78570. +* in case the offset should be set to a TWSI slave which support
  78571. +* more then 256 bytes offset, the offset setting will be done
  78572. +* in 2 transactions.
  78573. +* 2) Use twsiDataTransmit to place those on the bus.
  78574. +*
  78575. +* INPUT:
  78576. +* chanNum - TWSI channel
  78577. +* offset - offset to be set on the EEPROM device.
  78578. +* moreThen256 - whether the EEPROM device support more then 256 byte offset.
  78579. +*
  78580. +* OUTPUT:
  78581. +* None.
  78582. +*
  78583. +* RETURN:
  78584. +* MV_OK - if setting the offset completed succesfully.
  78585. +* MV_FAIL otherwmise.
  78586. +*
  78587. +*******************************************************************************/
  78588. +static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset, MV_BOOL moreThen256)
  78589. +{
  78590. + MV_U8 offBlock[2];
  78591. + MV_U32 offSize;
  78592. +
  78593. + if(moreThen256 == MV_TRUE)
  78594. + {
  78595. + offBlock[0] = (offset >> 8) & 0xff;
  78596. + offBlock[1] = offset & 0xff;
  78597. + offSize = 2;
  78598. + }
  78599. + else
  78600. + {
  78601. + offBlock[0] = offset & 0xff;
  78602. + offSize = 1;
  78603. + }
  78604. + DB(mvOsPrintf("TWSI: twsiTargetOffsSet offSize = %x addr1 = %x addr2 = %x\n",\
  78605. + offSize,offBlock[0],offBlock[1]));
  78606. + return twsiDataTransmit(chanNum, offBlock, offSize);
  78607. +
  78608. +}
  78609. +
  78610. +/*******************************************************************************
  78611. +* mvTwsiRead - Read data block from a TWSI Slave.
  78612. +*
  78613. +* DESCRIPTION:
  78614. +* The function calls the following functions:
  78615. +* -) mvTwsiStartBitSet();
  78616. +* if(EEPROM device)
  78617. +* -) mvTwsiAddrSet(w);
  78618. +* -) twsiTargetOffsSet();
  78619. +* -) mvTwsiStartBitSet();
  78620. +* -) mvTwsiAddrSet(r);
  78621. +* -) twsiDataReceive();
  78622. +* -) mvTwsiStopBitSet();
  78623. +*
  78624. +* INPUT:
  78625. +* chanNum - TWSI channel
  78626. +* pTwsiSlave - Twsi Slave structure.
  78627. +* blockSize - number of bytes to read.
  78628. +*
  78629. +* OUTPUT:
  78630. +* pBlock - Data block.
  78631. +*
  78632. +* RETURN:
  78633. +* MV_OK - if EEPROM read transaction completed succesfully,
  78634. +* MV_BAD_PARAM - if pBlock is NULL,
  78635. +* MV_FAIL otherwmise.
  78636. +*
  78637. +*******************************************************************************/
  78638. +MV_STATUS mvTwsiRead(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)
  78639. +{
  78640. + if((NULL == pBlock) || (NULL == pTwsiSlave))
  78641. + return MV_BAD_PARAM;
  78642. + if(MV_OK != mvTwsiStartBitSet(chanNum))
  78643. + {
  78644. + mvTwsiStopBitSet(chanNum);
  78645. + return MV_FAIL;
  78646. + }
  78647. +
  78648. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));
  78649. +
  78650. + /* in case offset exsist (i.e. eeprom ) */
  78651. + if(MV_TRUE == pTwsiSlave->validOffset)
  78652. + {
  78653. + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE))
  78654. + {
  78655. + mvTwsiStopBitSet(chanNum);
  78656. + return MV_FAIL;
  78657. + }
  78658. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));
  78659. + if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256))
  78660. + {
  78661. + mvTwsiStopBitSet(chanNum);
  78662. + return MV_FAIL;
  78663. + }
  78664. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiTargetOffsSet\n"));
  78665. + if(MV_OK != mvTwsiStartBitSet(chanNum))
  78666. + {
  78667. + mvTwsiStopBitSet(chanNum);
  78668. + return MV_FAIL;
  78669. + }
  78670. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));
  78671. + }
  78672. + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_READ))
  78673. + {
  78674. + mvTwsiStopBitSet(chanNum);
  78675. + return MV_FAIL;
  78676. + }
  78677. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));
  78678. + if(MV_OK != twsiDataReceive(chanNum, pBlock, blockSize))
  78679. + {
  78680. + mvTwsiStopBitSet(chanNum);
  78681. + return MV_FAIL;
  78682. + }
  78683. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiDataReceive\n"));
  78684. +
  78685. + if(MV_OK != mvTwsiStopBitSet(chanNum))
  78686. + {
  78687. + return MV_FAIL;
  78688. + }
  78689. +
  78690. + twsiAckBitSet(chanNum);
  78691. +
  78692. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStopBitSet\n"));
  78693. +
  78694. + return MV_OK;
  78695. +}
  78696. +
  78697. +/*******************************************************************************
  78698. +* mvTwsiWrite - Write data block to a TWSI Slave.
  78699. +*
  78700. +* DESCRIPTION:
  78701. +* The function calls the following functions:
  78702. +* -) mvTwsiStartBitSet();
  78703. +* -) mvTwsiAddrSet();
  78704. +* -)if(EEPROM device)
  78705. +* -) twsiTargetOffsSet();
  78706. +* -) twsiDataTransmit();
  78707. +* -) mvTwsiStopBitSet();
  78708. +*
  78709. +* INPUT:
  78710. +* chanNum - TWSI channel
  78711. +* eepromAddress - eeprom address.
  78712. +* blockSize - number of bytes to write.
  78713. +* pBlock - Data block.
  78714. +*
  78715. +* OUTPUT:
  78716. +* None
  78717. +*
  78718. +* RETURN:
  78719. +* MV_OK - if EEPROM read transaction completed succesfully.
  78720. +* MV_BAD_PARAM - if pBlock is NULL,
  78721. +* MV_FAIL otherwmise.
  78722. +*
  78723. +* NOTE: Part of the EEPROM, required that the offset will be aligned to the
  78724. +* max write burst supported.
  78725. +*******************************************************************************/
  78726. +MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)
  78727. +{
  78728. + if((NULL == pBlock) || (NULL == pTwsiSlave))
  78729. + return MV_BAD_PARAM;
  78730. +
  78731. + if(MV_OK != mvTwsiStartBitSet(chanNum))
  78732. + {
  78733. + mvTwsiStopBitSet(chanNum);
  78734. + return MV_FAIL;
  78735. + }
  78736. +
  78737. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStartBitSet\n"));
  78738. + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE))
  78739. + {
  78740. + mvTwsiStopBitSet(chanNum);
  78741. + return MV_FAIL;
  78742. + }
  78743. + DB(mvOsPrintf("TWSI :mvTwsiEepromWrite after mvTwsiAddrSet\n"));
  78744. +
  78745. + /* in case offset exsist (i.e. eeprom ) */
  78746. + if(MV_TRUE == pTwsiSlave->validOffset)
  78747. + {
  78748. + if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256))
  78749. + {
  78750. + mvTwsiStopBitSet(chanNum);
  78751. + return MV_FAIL;
  78752. + }
  78753. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiTargetOffsSet\n"));
  78754. + }
  78755. + if(MV_OK != twsiDataTransmit(chanNum, pBlock, blockSize))
  78756. + {
  78757. + mvTwsiStopBitSet(chanNum);
  78758. + return MV_FAIL;
  78759. + }
  78760. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiDataTransmit\n"));
  78761. + if(MV_OK != mvTwsiStopBitSet(chanNum))
  78762. + {
  78763. + return MV_FAIL;
  78764. + }
  78765. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStopBitSet\n"));
  78766. +
  78767. + return MV_OK;
  78768. +}
  78769. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h
  78770. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h 1970-01-01 01:00:00.000000000 +0100
  78771. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h 2011-07-31 11:32:01.943468546 +0200
  78772. @@ -0,0 +1,121 @@
  78773. +/*******************************************************************************
  78774. +Copyright (C) Marvell International Ltd. and its affiliates
  78775. +
  78776. +This software file (the "File") is owned and distributed by Marvell
  78777. +International Ltd. and/or its affiliates ("Marvell") under the following
  78778. +alternative licensing terms. Once you have made an election to distribute the
  78779. +File under one of the following license alternatives, please (i) delete this
  78780. +introductory statement regarding license alternatives, (ii) delete the two
  78781. +license alternatives that you have not elected to use and (iii) preserve the
  78782. +Marvell copyright notice above.
  78783. +
  78784. +********************************************************************************
  78785. +Marvell Commercial License Option
  78786. +
  78787. +If you received this File from Marvell and you have entered into a commercial
  78788. +license agreement (a "Commercial License") with Marvell, the File is licensed
  78789. +to you under the terms of the applicable Commercial License.
  78790. +
  78791. +********************************************************************************
  78792. +Marvell GPL License Option
  78793. +
  78794. +If you received this File from Marvell, you may opt to use, redistribute and/or
  78795. +modify this File in accordance with the terms and conditions of the General
  78796. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  78797. +available along with the File in the license.txt file or by writing to the Free
  78798. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  78799. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  78800. +
  78801. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  78802. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  78803. +DISCLAIMED. The GPL License provides additional details about this warranty
  78804. +disclaimer.
  78805. +********************************************************************************
  78806. +Marvell BSD License Option
  78807. +
  78808. +If you received this File from Marvell, you may opt to use, redistribute and/or
  78809. +modify this File under the following licensing terms.
  78810. +Redistribution and use in source and binary forms, with or without modification,
  78811. +are permitted provided that the following conditions are met:
  78812. +
  78813. + * Redistributions of source code must retain the above copyright notice,
  78814. + this list of conditions and the following disclaimer.
  78815. +
  78816. + * Redistributions in binary form must reproduce the above copyright
  78817. + notice, this list of conditions and the following disclaimer in the
  78818. + documentation and/or other materials provided with the distribution.
  78819. +
  78820. + * Neither the name of Marvell nor the names of its contributors may be
  78821. + used to endorse or promote products derived from this software without
  78822. + specific prior written permission.
  78823. +
  78824. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  78825. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  78826. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  78827. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  78828. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  78829. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  78830. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  78831. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  78832. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  78833. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  78834. +
  78835. +*******************************************************************************/
  78836. +#ifndef __INCmvTwsiH
  78837. +#define __INCmvTwsiH
  78838. +
  78839. +#ifdef __cplusplus
  78840. +extern "C" {
  78841. +#endif /* __cplusplus */
  78842. +
  78843. +/* need to update this includes */
  78844. +#include "twsi/mvTwsiSpec.h"
  78845. +#include "ctrlEnv/mvCtrlEnvLib.h"
  78846. +
  78847. +
  78848. +/* The TWSI interface supports both 7-bit and 10-bit addressing. */
  78849. +/* This enumerator describes addressing type. */
  78850. +typedef enum _mvTwsiAddrType
  78851. +{
  78852. + ADDR7_BIT, /* 7 bit address */
  78853. + ADDR10_BIT /* 10 bit address */
  78854. +}MV_TWSI_ADDR_TYPE;
  78855. +
  78856. +/* This structure describes TWSI address. */
  78857. +typedef struct _mvTwsiAddr
  78858. +{
  78859. + MV_U32 address; /* address */
  78860. + MV_TWSI_ADDR_TYPE type; /* Address type */
  78861. +}MV_TWSI_ADDR;
  78862. +
  78863. +/* This structure describes a TWSI slave. */
  78864. +typedef struct _mvTwsiSlave
  78865. +{
  78866. + MV_TWSI_ADDR slaveAddr;
  78867. + MV_BOOL validOffset; /* whether the slave has offset (i.e. Eeprom etc.) */
  78868. + MV_U32 offset; /* offset in the slave. */
  78869. + MV_BOOL moreThen256; /* whether the ofset is bigger then 256 */
  78870. +}MV_TWSI_SLAVE;
  78871. +
  78872. +/* This enumerator describes TWSI protocol commands. */
  78873. +typedef enum _mvTwsiCmd
  78874. +{
  78875. + MV_TWSI_WRITE, /* TWSI write command - 0 according to spec */
  78876. + MV_TWSI_READ /* TWSI read command - 1 according to spec */
  78877. +}MV_TWSI_CMD;
  78878. +
  78879. +MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum);
  78880. +MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum);
  78881. +MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *twsiAddr, MV_TWSI_CMD command);
  78882. +
  78883. +MV_U32 mvTwsiInit(MV_U8 chanNum, MV_KHZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *twsiAddr, MV_BOOL generalCallEnable);
  78884. +MV_STATUS mvTwsiRead (MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);
  78885. +MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);
  78886. +
  78887. +
  78888. +#ifdef __cplusplus
  78889. +}
  78890. +#endif /* __cplusplus */
  78891. +
  78892. +#endif /* __INCmvTwsiH */
  78893. +
  78894. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h
  78895. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h 1970-01-01 01:00:00.000000000 +0100
  78896. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h 2011-07-31 11:32:02.014130488 +0200
  78897. @@ -0,0 +1,160 @@
  78898. +/*******************************************************************************
  78899. +Copyright (C) Marvell International Ltd. and its affiliates
  78900. +
  78901. +This software file (the "File") is owned and distributed by Marvell
  78902. +International Ltd. and/or its affiliates ("Marvell") under the following
  78903. +alternative licensing terms. Once you have made an election to distribute the
  78904. +File under one of the following license alternatives, please (i) delete this
  78905. +introductory statement regarding license alternatives, (ii) delete the two
  78906. +license alternatives that you have not elected to use and (iii) preserve the
  78907. +Marvell copyright notice above.
  78908. +
  78909. +********************************************************************************
  78910. +Marvell Commercial License Option
  78911. +
  78912. +If you received this File from Marvell and you have entered into a commercial
  78913. +license agreement (a "Commercial License") with Marvell, the File is licensed
  78914. +to you under the terms of the applicable Commercial License.
  78915. +
  78916. +********************************************************************************
  78917. +Marvell GPL License Option
  78918. +
  78919. +If you received this File from Marvell, you may opt to use, redistribute and/or
  78920. +modify this File in accordance with the terms and conditions of the General
  78921. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  78922. +available along with the File in the license.txt file or by writing to the Free
  78923. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  78924. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  78925. +
  78926. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  78927. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  78928. +DISCLAIMED. The GPL License provides additional details about this warranty
  78929. +disclaimer.
  78930. +********************************************************************************
  78931. +Marvell BSD License Option
  78932. +
  78933. +If you received this File from Marvell, you may opt to use, redistribute and/or
  78934. +modify this File under the following licensing terms.
  78935. +Redistribution and use in source and binary forms, with or without modification,
  78936. +are permitted provided that the following conditions are met:
  78937. +
  78938. + * Redistributions of source code must retain the above copyright notice,
  78939. + this list of conditions and the following disclaimer.
  78940. +
  78941. + * Redistributions in binary form must reproduce the above copyright
  78942. + notice, this list of conditions and the following disclaimer in the
  78943. + documentation and/or other materials provided with the distribution.
  78944. +
  78945. + * Neither the name of Marvell nor the names of its contributors may be
  78946. + used to endorse or promote products derived from this software without
  78947. + specific prior written permission.
  78948. +
  78949. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  78950. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  78951. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  78952. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  78953. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  78954. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  78955. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  78956. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  78957. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  78958. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  78959. +
  78960. +*******************************************************************************/
  78961. +/****************************************/
  78962. +/* TWSI Registers */
  78963. +/****************************************/
  78964. +#ifndef __INCmvTwsiSpech
  78965. +#define __INCmvTwsiSpech
  78966. +
  78967. +#ifdef __cplusplus
  78968. +extern "C" {
  78969. +#endif /* __cplusplus */
  78970. +
  78971. +/* defines */
  78972. +#define TWSI_SLAVE_ADDR_REG(chanNum) (TWSI_SLAVE_BASE(chanNum)+ 0x00)
  78973. +
  78974. +#define TWSI_SLAVE_ADDR_GCE_ENA BIT0
  78975. +#define TWSI_SLAVE_ADDR_7BIT_OFFS 0x1
  78976. +#define TWSI_SLAVE_ADDR_7BIT_MASK (0xFF << TWSI_SLAVE_ADDR_7BIT_OFFS)
  78977. +#define TWSI_SLAVE_ADDR_10BIT_OFFS 0x7
  78978. +#define TWSI_SLAVE_ADDR_10BIT_MASK 0x300
  78979. +#define TWSI_SLAVE_ADDR_10BIT_CONST 0xF0
  78980. +
  78981. +
  78982. +#define TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x10)
  78983. +#define TWSI_EXTENDED_SLAVE_OFFS 0
  78984. +#define TWSI_EXTENDED_SLAVE_MASK (0xFF << TWSI_EXTENDED_SLAVE_OFFS)
  78985. +
  78986. +
  78987. +#define TWSI_DATA_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x04)
  78988. +#define TWSI_DATA_COMMAND_OFFS 0x0
  78989. +#define TWSI_DATA_COMMAND_MASK (0x1 << TWSI_DATA_COMMAND_OFFS)
  78990. +#define TWSI_DATA_COMMAND_WR (0x1 << TWSI_DATA_COMMAND_OFFS)
  78991. +#define TWSI_DATA_COMMAND_RD (0x0 << TWSI_DATA_COMMAND_OFFS)
  78992. +#define TWSI_DATA_ADDR_7BIT_OFFS 0x1
  78993. +#define TWSI_DATA_ADDR_7BIT_MASK (0xFF << TWSI_DATA_ADDR_7BIT_OFFS)
  78994. +#define TWSI_DATA_ADDR_10BIT_OFFS 0x7
  78995. +#define TWSI_DATA_ADDR_10BIT_MASK 0x300
  78996. +#define TWSI_DATA_ADDR_10BIT_CONST 0xF0
  78997. +
  78998. +
  78999. +#define TWSI_CONTROL_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x08)
  79000. +#define TWSI_CONTROL_ACK BIT2
  79001. +#define TWSI_CONTROL_INT_FLAG_SET BIT3
  79002. +#define TWSI_CONTROL_STOP_BIT BIT4
  79003. +#define TWSI_CONTROL_START_BIT BIT5
  79004. +#define TWSI_CONTROL_ENA BIT6
  79005. +#define TWSI_CONTROL_INT_ENA BIT7
  79006. +
  79007. +
  79008. +#define TWSI_STATUS_BAUDE_RATE_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x0c)
  79009. +#define TWSI_BAUD_RATE_N_OFFS 0
  79010. +#define TWSI_BAUD_RATE_N_MASK (0x7 << TWSI_BAUD_RATE_N_OFFS)
  79011. +#define TWSI_BAUD_RATE_M_OFFS 3
  79012. +#define TWSI_BAUD_RATE_M_MASK (0xF << TWSI_BAUD_RATE_M_OFFS)
  79013. +
  79014. +#define TWSI_SOFT_RESET_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x1c)
  79015. +
  79016. +/* defines */
  79017. +#define TWSI_TIMEOUT_VALUE 0x500
  79018. +
  79019. +/* TWSI status codes */
  79020. +#define TWSI_BUS_ERROR 0x00
  79021. +#define TWSI_START_CON_TRA 0x08
  79022. +#define TWSI_REPEATED_START_CON_TRA 0x10
  79023. +#define TWSI_AD_PLS_WR_BIT_TRA_ACK_REC 0x18
  79024. +#define TWSI_AD_PLS_WR_BIT_TRA_ACK_NOT_REC 0x20
  79025. +#define TWSI_M_TRAN_DATA_BYTE_ACK_REC 0x28
  79026. +#define TWSI_M_TRAN_DATA_BYTE_ACK_NOT_REC 0x30
  79027. +#define TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA 0x38
  79028. +#define TWSI_AD_PLS_RD_BIT_TRA_ACK_REC 0x40
  79029. +#define TWSI_AD_PLS_RD_BIT_TRA_ACK_NOT_REC 0x48
  79030. +#define TWSI_M_REC_RD_DATA_ACK_TRA 0x50
  79031. +#define TWSI_M_REC_RD_DATA_ACK_NOT_TRA 0x58
  79032. +#define TWSI_SLA_REC_AD_PLS_WR_BIT_ACK_TRA 0x60
  79033. +#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_W 0x68
  79034. +#define TWSI_GNL_CALL_REC_ACK_TRA 0x70
  79035. +#define TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA 0x78
  79036. +#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_TRAN 0x80
  79037. +#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_NOT_TRAN 0x88
  79038. +#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_TRAN 0x90
  79039. +#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_NOT_TRAN 0x98
  79040. +#define TWSI_SLA_REC_STOP_OR_REPEATED_STRT_CON 0xA0
  79041. +#define TWSI_SLA_REC_AD_PLS_RD_BIT_ACK_TRA 0xA8
  79042. +#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_R 0xB0
  79043. +#define TWSI_SLA_TRA_RD_DATA_ACK_REC 0xB8
  79044. +#define TWSI_SLA_TRA_RD_DATA_ACK_NOT_REC 0xC0
  79045. +#define TWSI_SLA_TRA_LAST_RD_DATA_ACK_REC 0xC8
  79046. +#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC 0xD0
  79047. +#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_NOT_REC 0xD8
  79048. +#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC 0xE0
  79049. +#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_NOT_REC 0xE8
  79050. +#define TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0 0xF8
  79051. +
  79052. +
  79053. +#ifdef __cplusplus
  79054. +}
  79055. +#endif /* __cplusplus */
  79056. +
  79057. +#endif /* __INCmvTwsiSpech */
  79058. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h
  79059. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h 1970-01-01 01:00:00.000000000 +0100
  79060. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h 2011-07-31 11:32:02.063979754 +0200
  79061. @@ -0,0 +1,375 @@
  79062. +/*******************************************************************************
  79063. +Copyright (C) Marvell International Ltd. and its affiliates
  79064. +
  79065. +********************************************************************************
  79066. +Marvell GPL License Option
  79067. +
  79068. +If you received this File from Marvell, you may opt to use, redistribute and/or
  79069. +modify this File in accordance with the terms and conditions of the General
  79070. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  79071. +available along with the File in the license.txt file or by writing to the Free
  79072. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  79073. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  79074. +
  79075. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  79076. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  79077. +DISCLAIMED. The GPL License provides additional details about this warranty
  79078. +disclaimer.
  79079. +
  79080. +*******************************************************************************/
  79081. +/*******************************************************************************
  79082. +* mvSysHwCfg.h - Marvell system HW configuration file
  79083. +*
  79084. +* DESCRIPTION:
  79085. +* None.
  79086. +*
  79087. +* DEPENDENCIES:
  79088. +* None.
  79089. +*
  79090. +*******************************************************************************/
  79091. +
  79092. +#ifndef __INCmvSysHwConfigh
  79093. +#define __INCmvSysHwConfigh
  79094. +
  79095. +#include "../../../../include/linux/autoconf.h"
  79096. +
  79097. +#define CONFIG_MARVELL 1
  79098. +
  79099. +/* includes */
  79100. +#define _1K 0x00000400
  79101. +#define _4K 0x00001000
  79102. +#define _8K 0x00002000
  79103. +#define _16K 0x00004000
  79104. +#define _32K 0x00008000
  79105. +#define _64K 0x00010000
  79106. +#define _128K 0x00020000
  79107. +#define _256K 0x00040000
  79108. +#define _512K 0x00080000
  79109. +
  79110. +#define _1M 0x00100000
  79111. +#define _2M 0x00200000
  79112. +#define _4M 0x00400000
  79113. +#define _8M 0x00800000
  79114. +#define _16M 0x01000000
  79115. +#define _32M 0x02000000
  79116. +#define _64M 0x04000000
  79117. +#define _128M 0x08000000
  79118. +#define _256M 0x10000000
  79119. +#define _512M 0x20000000
  79120. +
  79121. +#define _1G 0x40000000
  79122. +#define _2G 0x80000000
  79123. +
  79124. +/****************************************/
  79125. +/* Soc supporeted Units definitions */
  79126. +/****************************************/
  79127. +
  79128. +#ifdef CONFIG_MV_INCLUDE_PEX
  79129. +#define MV_INCLUDE_PEX
  79130. +#endif
  79131. +#ifdef CONFIG_MV_INCLUDE_TWSI
  79132. +#define MV_INCLUDE_TWSI
  79133. +#endif
  79134. +#ifdef CONFIG_MV_INCLUDE_CESA
  79135. +#define MV_INCLUDE_CESA
  79136. +#endif
  79137. +#ifdef CONFIG_MV_INCLUDE_GIG_ETH
  79138. +#define MV_INCLUDE_GIG_ETH
  79139. +#endif
  79140. +#ifdef CONFIG_MV_INCLUDE_INTEG_SATA
  79141. +#define MV_INCLUDE_INTEG_SATA
  79142. +#define MV_INCLUDE_SATA
  79143. +#endif
  79144. +#ifdef CONFIG_MV_INCLUDE_USB
  79145. +#define MV_INCLUDE_USB
  79146. +#define MV_USB_VOLTAGE_FIX
  79147. +#endif
  79148. +#ifdef CONFIG_MV_INCLUDE_NAND
  79149. +#define MV_INCLUDE_NAND
  79150. +#endif
  79151. +#ifdef CONFIG_MV_INCLUDE_TDM
  79152. +#define MV_INCLUDE_TDM
  79153. +#endif
  79154. +#ifdef CONFIG_MV_INCLUDE_XOR
  79155. +#define MV_INCLUDE_XOR
  79156. +#endif
  79157. +#ifdef CONFIG_MV_INCLUDE_TWSI
  79158. +#define MV_INCLUDE_TWSI
  79159. +#endif
  79160. +#ifdef CONFIG_MV_INCLUDE_UART
  79161. +#define MV_INCLUDE_UART
  79162. +#endif
  79163. +#ifdef CONFIG_MV_INCLUDE_SPI
  79164. +#define MV_INCLUDE_SPI
  79165. +#endif
  79166. +#ifdef CONFIG_MV_INCLUDE_SFLASH_MTD
  79167. +#define MV_INCLUDE_SFLASH_MTD
  79168. +#endif
  79169. +#ifdef CONFIG_MV_INCLUDE_AUDIO
  79170. +#define MV_INCLUDE_AUDIO
  79171. +#endif
  79172. +#ifdef CONFIG_MV_INCLUDE_TS
  79173. +#define MV_INCLUDE_TS
  79174. +#endif
  79175. +#ifdef CONFIG_MV_INCLUDE_SDIO
  79176. +#define MV_INCLUDE_SDIO
  79177. +#endif
  79178. +
  79179. +
  79180. +/* NAND flash stuff */
  79181. +#ifdef CONFIG_MV_NAND_BOOT
  79182. +#define MV_NAND_BOOT
  79183. +#endif
  79184. +#ifdef CONFIG_MV_NAND
  79185. +#define MV_NAND
  79186. +#endif
  79187. +
  79188. +/* SPI flash stuff */
  79189. +#ifdef CONFIG_MV_SPI_BOOT
  79190. +#define MV_SPI_BOOT
  79191. +#endif
  79192. +
  79193. +
  79194. +/****************************************************************/
  79195. +/************* General configuration ********************/
  79196. +/****************************************************************/
  79197. +
  79198. +/* Enable Clock Power Control */
  79199. +#define MV_INCLUDE_CLK_PWR_CNTRL
  79200. +
  79201. +/* Disable the DEVICE BAR in the PEX */
  79202. +#define MV_DISABLE_PEX_DEVICE_BAR
  79203. +
  79204. +/* Allow the usage of early printings during initialization */
  79205. +#define MV_INCLUDE_EARLY_PRINTK
  79206. +
  79207. +/****************************************************************/
  79208. +/************* NFP configuration ********************************/
  79209. +/****************************************************************/
  79210. +#define MV_NFP_SEC_Q_SIZE 64
  79211. +#define MV_NFP_SEC_REQ_Q_SIZE 1000
  79212. +
  79213. +
  79214. +
  79215. +/****************************************************************/
  79216. +/************* CESA configuration ********************/
  79217. +/****************************************************************/
  79218. +
  79219. +#ifdef MV_INCLUDE_CESA
  79220. +
  79221. +#define MV_CESA_MAX_CHAN 4
  79222. +
  79223. +/* Use 2K of SRAM */
  79224. +#define MV_CESA_MAX_BUF_SIZE 1600
  79225. +
  79226. +#endif /* MV_INCLUDE_CESA */
  79227. +
  79228. +#if defined(CONFIG_MV_INCLUDE_GIG_ETH)
  79229. +
  79230. +#ifdef CONFIG_MV_NFP_STATS
  79231. +#define MV_FP_STATISTICS
  79232. +#else
  79233. +#undef MV_FP_STATISTICS
  79234. +#endif
  79235. +/* Default configuration for SKB_REUSE: 0 - Disabled, 1 - Enabled */
  79236. +#define MV_ETH_SKB_REUSE_DEFAULT 1
  79237. +/* Default configuration for TX_EN workaround: 0 - Disabled, 1 - Enabled */
  79238. +#define MV_ETH_TX_EN_DEFAULT 0
  79239. +
  79240. +/* un-comment if you want to perform tx_done from within the poll function */
  79241. +/* #define ETH_TX_DONE_ISR */
  79242. +
  79243. +/* put descriptors in uncached memory */
  79244. +/* #define ETH_DESCR_UNCACHED */
  79245. +
  79246. +/* Descriptors location: DRAM/internal-SRAM */
  79247. +#define ETH_DESCR_IN_SDRAM
  79248. +#undef ETH_DESCR_IN_SRAM /* No integrated SRAM in 88Fxx81 devices */
  79249. +
  79250. +#if defined(ETH_DESCR_IN_SRAM)
  79251. +#if defined(ETH_DESCR_UNCACHED)
  79252. + #define ETH_DESCR_CONFIG_STR "Uncached descriptors in integrated SRAM"
  79253. +#else
  79254. + #define ETH_DESCR_CONFIG_STR "Cached descriptors in integrated SRAM"
  79255. +#endif
  79256. +#elif defined(ETH_DESCR_IN_SDRAM)
  79257. +#if defined(ETH_DESCR_UNCACHED)
  79258. + #define ETH_DESCR_CONFIG_STR "Uncached descriptors in DRAM"
  79259. +#else
  79260. + #define ETH_DESCR_CONFIG_STR "Cached descriptors in DRAM"
  79261. +#endif
  79262. +#else
  79263. + #error "Ethernet descriptors location undefined"
  79264. +#endif /* ETH_DESCR_IN_SRAM or ETH_DESCR_IN_SDRAM*/
  79265. +
  79266. +/* SW Sync-Barrier: not relevant for 88fxx81*/
  79267. +/* Reasnable to define this macro when descriptors in SRAM and buffers in DRAM */
  79268. +/* In RX the CPU theoretically might see himself as the descriptor owner, */
  79269. +/* although the buffer hadn't been written to DRAM yet. Performance cost. */
  79270. +/* #define INCLUDE_SYNC_BARR */
  79271. +
  79272. +/* Buffers cache coherency method (buffers in DRAM) */
  79273. +#ifndef MV_CACHE_COHER_SW
  79274. +/* Taken from mvCommon.h */
  79275. +/* Memory uncached, HW or SW cache coherency is not needed */
  79276. +#define MV_UNCACHED 0
  79277. +/* Memory cached, HW cache coherency supported in WriteThrough mode */
  79278. +#define MV_CACHE_COHER_HW_WT 1
  79279. +/* Memory cached, HW cache coherency supported in WriteBack mode */
  79280. +#define MV_CACHE_COHER_HW_WB 2
  79281. +/* Memory cached, No HW cache coherency, Cache coherency must be in SW */
  79282. +#define MV_CACHE_COHER_SW 3
  79283. +
  79284. +#endif
  79285. +
  79286. +/* DRAM cache coherency configuration */
  79287. +#define MV_CACHE_COHERENCY MV_CACHE_COHER_SW
  79288. +
  79289. +
  79290. +#define ETHER_DRAM_COHER MV_CACHE_COHER_SW /* No HW coherency in 88Fxx81 devices */
  79291. +
  79292. +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB)
  79293. + #define ETH_SDRAM_CONFIG_STR "DRAM HW cache coherency (write-back)"
  79294. +#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT)
  79295. + #define ETH_SDRAM_CONFIG_STR "DRAM HW cache coherency (write-through)"
  79296. +#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_SW)
  79297. + #define ETH_SDRAM_CONFIG_STR "DRAM SW cache-coherency"
  79298. +#elif (ETHER_DRAM_COHER == MV_UNCACHED)
  79299. +# define ETH_SDRAM_CONFIG_STR "DRAM uncached"
  79300. +#else
  79301. + #error "Ethernet-DRAM undefined"
  79302. +#endif /* ETHER_DRAM_COHER */
  79303. +
  79304. +
  79305. +/****************************************************************/
  79306. +/************* Ethernet driver configuration ********************/
  79307. +/****************************************************************/
  79308. +
  79309. +/* port's default queueus */
  79310. +#define ETH_DEF_TXQ 0
  79311. +#define ETH_DEF_RXQ 0
  79312. +
  79313. +#define MV_ETH_RX_Q_NUM CONFIG_MV_ETH_RX_Q_NUM
  79314. +#define MV_ETH_TX_Q_NUM CONFIG_MV_ETH_TX_Q_NUM
  79315. +
  79316. +/* interrupt coalescing setting */
  79317. +#define ETH_TX_COAL 200
  79318. +#define ETH_RX_COAL 200
  79319. +
  79320. +/* Checksum offloading */
  79321. +#define TX_CSUM_OFFLOAD
  79322. +#define RX_CSUM_OFFLOAD
  79323. +
  79324. +#endif /* CONFIG_MV_INCLUDE_GIG_ETH */
  79325. +
  79326. +/****************************************************************/
  79327. +/*************** Telephony configuration ************************/
  79328. +/****************************************************************/
  79329. +#if defined(CONFIG_MV_TDM_LINEAR_MODE)
  79330. + #define MV_TDM_LINEAR_MODE
  79331. +#elif defined(CONFIG_MV_TDM_ULAW_MODE)
  79332. + #define MV_TDM_ULAW_MODE
  79333. +#endif
  79334. +
  79335. +#if defined(CONFIG_MV_TDM_5CHANNELS)
  79336. + #define MV_TDM_5CHANNELS
  79337. +#endif
  79338. +
  79339. +#if defined(CONFIG_MV_TDM_USE_EXTERNAL_PCLK_SOURCE)
  79340. + #define MV_TDM_USE_EXTERNAL_PCLK_SOURCE
  79341. +#endif
  79342. +
  79343. +/* We use the following registers to store DRAM interface pre configuration */
  79344. +/* auto-detection results */
  79345. +/* IMPORTANT: We are using mask register for that purpose. Before writing */
  79346. +/* to units mask register, make sure main maks register is set to disable */
  79347. +/* all interrupts. */
  79348. +#define DRAM_BUF_REG0 0x30810 /* sdram bank 0 size */
  79349. +#define DRAM_BUF_REG1 0x30820 /* sdram config */
  79350. +#define DRAM_BUF_REG2 0x30830 /* sdram mode */
  79351. +#define DRAM_BUF_REG3 0x308c4 /* dunit control low */
  79352. +#define DRAM_BUF_REG4 0x60a90 /* sdram address control */
  79353. +#define DRAM_BUF_REG5 0x60a94 /* sdram timing control low */
  79354. +#define DRAM_BUF_REG6 0x60a98 /* sdram timing control high */
  79355. +#define DRAM_BUF_REG7 0x60a9c /* sdram ODT control low */
  79356. +#define DRAM_BUF_REG8 0x60b90 /* sdram ODT control high */
  79357. +#define DRAM_BUF_REG9 0x60b94 /* sdram Dunit ODT control */
  79358. +#define DRAM_BUF_REG10 0x60b98 /* sdram Extended Mode */
  79359. +#define DRAM_BUF_REG11 0x60b9c /* sdram Ddr2 Time Low Reg */
  79360. +#define DRAM_BUF_REG12 0x60a00 /* sdram Ddr2 Time High Reg */
  79361. +#define DRAM_BUF_REG13 0x60a04 /* dunit Ctrl High */
  79362. +#define DRAM_BUF_REG14 0x60b00 /* sdram second DIMM exist */
  79363. +
  79364. +/* Following the pre-configuration registers default values restored after */
  79365. +/* auto-detection is done */
  79366. +#define DRAM_BUF_REG_DV 0
  79367. +
  79368. +/* System Mapping */
  79369. +#define SDRAM_CS0_BASE 0x00000000
  79370. +#define SDRAM_CS0_SIZE _256M
  79371. +
  79372. +#define SDRAM_CS1_BASE 0x10000000
  79373. +#define SDRAM_CS1_SIZE _256M
  79374. +
  79375. +#define SDRAM_CS2_BASE 0x20000000
  79376. +#define SDRAM_CS2_SIZE _256M
  79377. +
  79378. +#define SDRAM_CS3_BASE 0x30000000
  79379. +#define SDRAM_CS3_SIZE _256M
  79380. +
  79381. +/* PEX */
  79382. +#define PEX0_MEM_BASE 0xe8000000
  79383. +#define PEX0_MEM_SIZE _128M
  79384. +
  79385. +#define PEX0_IO_BASE 0xf2000000
  79386. +#define PEX0_IO_SIZE _1M
  79387. +
  79388. +/* Device Chip Selects */
  79389. +#define NFLASH_CS_BASE 0xfa000000
  79390. +#define NFLASH_CS_SIZE _2M
  79391. +
  79392. +#define SPI_CS_BASE 0xf4000000
  79393. +#define SPI_CS_SIZE _16M
  79394. +
  79395. +#define CRYPT_ENG_BASE 0xf0000000
  79396. +#define CRYPT_ENG_SIZE _2M
  79397. +
  79398. +#define BOOTDEV_CS_BASE 0xff800000
  79399. +#define BOOTDEV_CS_SIZE _8M
  79400. +
  79401. +/* CS2 - BOOTROM */
  79402. +#define DEVICE_CS2_BASE 0xff900000
  79403. +#define DEVICE_CS2_SIZE _1M
  79404. +
  79405. +/* PEX Work arround */
  79406. +/* the target we will use for the workarround */
  79407. +#define PEX_CONFIG_RW_WA_TARGET PEX0_MEM
  79408. +/*a flag that indicates if we are going to use the
  79409. +size and base of the target we using for the workarround
  79410. +window */
  79411. +#define PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES 1
  79412. +/* if the above flag is 0 then the following values
  79413. +will be used for the workarround window base and size,
  79414. +otherwise the following defines will be ignored */
  79415. +#define PEX_CONFIG_RW_WA_BASE 0xF3000000
  79416. +#define PEX_CONFIG_RW_WA_SIZE _16M
  79417. +
  79418. +/* Internal registers: size is defined in Controllerenvironment */
  79419. +#define INTER_REGS_BASE 0xFEE00000
  79420. +
  79421. +/* DRAM detection stuff */
  79422. +#define MV_DRAM_AUTO_SIZE
  79423. +
  79424. +/* Board clock detection */
  79425. +#define TCLK_AUTO_DETECT /* Use Tclk auto detection */
  79426. +#define SYSCLK_AUTO_DETECT /* Use SysClk auto detection */
  79427. +#define PCLCK_AUTO_DETECT /* Use PClk auto detection */
  79428. +#define L2CLK_AUTO_DETECT /* Use L2Clk auto detection */
  79429. +
  79430. +/* PEX-PCI\PCI-PCI Bridge*/
  79431. +#define PCI0_IF_PTP 0 /* Bridge exist on pciIf0*/
  79432. +
  79433. +
  79434. +
  79435. +#endif /* __INCmvSysHwConfigh */
  79436. +
  79437. diff -Nur linux-2.6.39.orig/crypto/ocf/Makefile linux-2.6.39/crypto/ocf/Makefile
  79438. --- linux-2.6.39.orig/crypto/ocf/Makefile 1970-01-01 01:00:00.000000000 +0100
  79439. +++ linux-2.6.39/crypto/ocf/Makefile 2011-07-31 11:32:02.263415742 +0200
  79440. @@ -0,0 +1,124 @@
  79441. +# for SGlinux builds
  79442. +-include $(ROOTDIR)/modules/.config
  79443. +
  79444. +OCF_OBJS = crypto.o criov.o
  79445. +
  79446. +ifdef CONFIG_OCF_RANDOMHARVEST
  79447. + OCF_OBJS += random.o
  79448. +endif
  79449. +
  79450. +ifdef CONFIG_OCF_FIPS
  79451. + OCF_OBJS += rndtest.o
  79452. +endif
  79453. +
  79454. +# Add in autoconf.h to get #defines for CONFIG_xxx
  79455. +AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h
  79456. +ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))
  79457. + EXTRA_CFLAGS += -include $(AUTOCONF_H)
  79458. + export EXTRA_CFLAGS
  79459. +endif
  79460. +
  79461. +ifndef obj
  79462. + obj ?= .
  79463. + _obj = subdir
  79464. + mod-subdirs := safe hifn ixp4xx talitos ocfnull
  79465. + export-objs += crypto.o criov.o random.o
  79466. + list-multi += ocf.o
  79467. + _slash :=
  79468. +else
  79469. + _obj = obj
  79470. + _slash := /
  79471. +endif
  79472. +
  79473. +EXTRA_CFLAGS += -I$(obj)/.
  79474. +
  79475. +obj-$(CONFIG_OCF_OCF) += ocf.o
  79476. +obj-$(CONFIG_OCF_CRYPTODEV) += cryptodev.o
  79477. +obj-$(CONFIG_OCF_CRYPTOSOFT) += cryptosoft.o
  79478. +obj-$(CONFIG_OCF_BENCH) += ocf-bench.o
  79479. +
  79480. +$(_obj)-$(CONFIG_OCF_SAFE) += safe$(_slash)
  79481. +$(_obj)-$(CONFIG_OCF_HIFN) += hifn$(_slash)
  79482. +$(_obj)-$(CONFIG_OCF_IXP4XX) += ixp4xx$(_slash)
  79483. +$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)
  79484. +$(_obj)-$(CONFIG_OCF_PASEMI) += pasemi$(_slash)
  79485. +$(_obj)-$(CONFIG_OCF_EP80579) += ep80579$(_slash)
  79486. +$(_obj)-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon$(_slash)
  79487. +$(_obj)-$(CONFIG_OCF_KIRKWOOD) += kirkwood$(_slash)
  79488. +$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
  79489. +$(_obj)-$(CONFIG_OCF_C7108) += c7108$(_slash)
  79490. +
  79491. +ocf-objs := $(OCF_OBJS)
  79492. +
  79493. +$(list-multi) dummy1: $(ocf-objs)
  79494. + $(LD) -r -o $@ $(ocf-objs)
  79495. +
  79496. +.PHONY:
  79497. +clean:
  79498. + rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c
  79499. + rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags
  79500. +
  79501. +ifdef TOPDIR
  79502. +-include $(TOPDIR)/Rules.make
  79503. +endif
  79504. +
  79505. +#
  79506. +# release gen targets
  79507. +#
  79508. +
  79509. +.PHONY: patch
  79510. +patch:
  79511. + REL=`date +%Y%m%d`; \
  79512. + patch=ocf-linux-$$REL.patch; \
  79513. + patch24=ocf-linux-24-$$REL.patch; \
  79514. + patch26=ocf-linux-26-$$REL.patch; \
  79515. + ( \
  79516. + find . -name Makefile; \
  79517. + find . -name Config.in; \
  79518. + find . -name Kconfig; \
  79519. + find . -name README; \
  79520. + find . -name '*.[ch]' | grep -v '.mod.c'; \
  79521. + ) | while read t; do \
  79522. + diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \
  79523. + done > $$patch; \
  79524. + cat patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
  79525. + cat patches/linux-2.6.33-ocf.patch $$patch > $$patch26
  79526. +
  79527. +.PHONY: tarball
  79528. +tarball:
  79529. + REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \
  79530. + CURDIR=`pwd`; \
  79531. + rm -rf /tmp/ocf-linux-$$REL*; \
  79532. + mkdir -p $$RELDIR/tools; \
  79533. + cp README* $$RELDIR; \
  79534. + cp patches/openss*.patch $$RELDIR; \
  79535. + cp patches/crypto-tools.patch $$RELDIR; \
  79536. + cp tools/[!C]* $$RELDIR/tools; \
  79537. + cd ..; \
  79538. + tar cvf $$RELDIR/ocf-linux.tar \
  79539. + --exclude=CVS \
  79540. + --exclude=.* \
  79541. + --exclude=*.o \
  79542. + --exclude=*.ko \
  79543. + --exclude=*.mod.* \
  79544. + --exclude=README* \
  79545. + --exclude=ocf-*.patch \
  79546. + --exclude=ocf/patches/openss*.patch \
  79547. + --exclude=ocf/patches/crypto-tools.patch \
  79548. + --exclude=ocf/tools \
  79549. + ocf; \
  79550. + gzip -9 $$RELDIR/ocf-linux.tar; \
  79551. + cd /tmp; \
  79552. + tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \
  79553. + gzip -9 ocf-linux-$$REL.tar; \
  79554. + cd $$CURDIR/../../user; \
  79555. + rm -rf /tmp/crypto-tools-$$REL*; \
  79556. + tar cvf /tmp/crypto-tools-$$REL.tar \
  79557. + --exclude=CVS \
  79558. + --exclude=.* \
  79559. + --exclude=*.o \
  79560. + --exclude=cryptotest \
  79561. + --exclude=cryptokeytest \
  79562. + crypto-tools; \
  79563. + gzip -9 /tmp/crypto-tools-$$REL.tar
  79564. +
  79565. diff -Nur linux-2.6.39.orig/crypto/ocf/ocf-bench.c linux-2.6.39/crypto/ocf/ocf-bench.c
  79566. --- linux-2.6.39.orig/crypto/ocf/ocf-bench.c 1970-01-01 01:00:00.000000000 +0100
  79567. +++ linux-2.6.39/crypto/ocf/ocf-bench.c 2011-07-31 11:32:02.503619326 +0200
  79568. @@ -0,0 +1,436 @@
  79569. +/*
  79570. + * A loadable module that benchmarks the OCF crypto speed from kernel space.
  79571. + *
  79572. + * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
  79573. + *
  79574. + * LICENSE TERMS
  79575. + *
  79576. + * The free distribution and use of this software in both source and binary
  79577. + * form is allowed (with or without changes) provided that:
  79578. + *
  79579. + * 1. distributions of this source code include the above copyright
  79580. + * notice, this list of conditions and the following disclaimer;
  79581. + *
  79582. + * 2. distributions in binary form include the above copyright
  79583. + * notice, this list of conditions and the following disclaimer
  79584. + * in the documentation and/or other associated materials;
  79585. + *
  79586. + * 3. the copyright holder's name is not used to endorse products
  79587. + * built using this software without specific written permission.
  79588. + *
  79589. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  79590. + * may be distributed under the terms of the GNU General Public License (GPL),
  79591. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  79592. + *
  79593. + * DISCLAIMER
  79594. + *
  79595. + * This software is provided 'as is' with no explicit or implied warranties
  79596. + * in respect of its properties, including, but not limited to, correctness
  79597. + * and/or fitness for purpose.
  79598. + */
  79599. +
  79600. +
  79601. +#ifndef AUTOCONF_INCLUDED
  79602. +#include <linux/config.h>
  79603. +#endif
  79604. +#include <linux/module.h>
  79605. +#include <linux/init.h>
  79606. +#include <linux/list.h>
  79607. +#include <linux/slab.h>
  79608. +#include <linux/wait.h>
  79609. +#include <linux/sched.h>
  79610. +#include <linux/spinlock.h>
  79611. +#include <linux/version.h>
  79612. +#include <linux/interrupt.h>
  79613. +#include <cryptodev.h>
  79614. +
  79615. +#ifdef I_HAVE_AN_XSCALE_WITH_INTEL_SDK
  79616. +#define BENCH_IXP_ACCESS_LIB 1
  79617. +#endif
  79618. +#ifdef BENCH_IXP_ACCESS_LIB
  79619. +#include <IxTypes.h>
  79620. +#include <IxOsBuffMgt.h>
  79621. +#include <IxNpeDl.h>
  79622. +#include <IxCryptoAcc.h>
  79623. +#include <IxQMgr.h>
  79624. +#include <IxOsServices.h>
  79625. +#include <IxOsCacheMMU.h>
  79626. +#endif
  79627. +
  79628. +/*
  79629. + * support for access lib version 1.4
  79630. + */
  79631. +#ifndef IX_MBUF_PRIV
  79632. +#define IX_MBUF_PRIV(x) ((x)->priv)
  79633. +#endif
  79634. +
  79635. +/*
  79636. + * the number of simultaneously active requests
  79637. + */
  79638. +static int request_q_len = 20;
  79639. +module_param(request_q_len, int, 0);
  79640. +MODULE_PARM_DESC(request_q_len, "Number of outstanding requests");
  79641. +/*
  79642. + * how many requests we want to have processed
  79643. + */
  79644. +static int request_num = 1024;
  79645. +module_param(request_num, int, 0);
  79646. +MODULE_PARM_DESC(request_num, "run for at least this many requests");
  79647. +/*
  79648. + * the size of each request
  79649. + */
  79650. +static int request_size = 1500;
  79651. +module_param(request_size, int, 0);
  79652. +MODULE_PARM_DESC(request_size, "size of each request");
  79653. +
  79654. +/*
  79655. + * a structure for each request
  79656. + */
  79657. +typedef struct {
  79658. + struct work_struct work;
  79659. +#ifdef BENCH_IXP_ACCESS_LIB
  79660. + IX_MBUF mbuf;
  79661. +#endif
  79662. + unsigned char *buffer;
  79663. +} request_t;
  79664. +
  79665. +static request_t *requests;
  79666. +
  79667. +static int outstanding;
  79668. +static int total;
  79669. +
  79670. +/*************************************************************************/
  79671. +/*
  79672. + * OCF benchmark routines
  79673. + */
  79674. +
  79675. +static uint64_t ocf_cryptoid;
  79676. +static int ocf_init(void);
  79677. +static int ocf_cb(struct cryptop *crp);
  79678. +static void ocf_request(void *arg);
  79679. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  79680. +static void ocf_request_wq(struct work_struct *work);
  79681. +#endif
  79682. +
  79683. +static int
  79684. +ocf_init(void)
  79685. +{
  79686. + int error;
  79687. + struct cryptoini crie, cria;
  79688. + struct cryptodesc crda, crde;
  79689. +
  79690. + memset(&crie, 0, sizeof(crie));
  79691. + memset(&cria, 0, sizeof(cria));
  79692. + memset(&crde, 0, sizeof(crde));
  79693. + memset(&crda, 0, sizeof(crda));
  79694. +
  79695. + cria.cri_alg = CRYPTO_SHA1_HMAC;
  79696. + cria.cri_klen = 20 * 8;
  79697. + cria.cri_key = "0123456789abcdefghij";
  79698. +
  79699. + crie.cri_alg = CRYPTO_3DES_CBC;
  79700. + crie.cri_klen = 24 * 8;
  79701. + crie.cri_key = "0123456789abcdefghijklmn";
  79702. +
  79703. + crie.cri_next = &cria;
  79704. +
  79705. + error = crypto_newsession(&ocf_cryptoid, &crie, 0);
  79706. + if (error) {
  79707. + printk("crypto_newsession failed %d\n", error);
  79708. + return -1;
  79709. + }
  79710. + return 0;
  79711. +}
  79712. +
  79713. +static int
  79714. +ocf_cb(struct cryptop *crp)
  79715. +{
  79716. + request_t *r = (request_t *) crp->crp_opaque;
  79717. +
  79718. + if (crp->crp_etype)
  79719. + printk("Error in OCF processing: %d\n", crp->crp_etype);
  79720. + total++;
  79721. + crypto_freereq(crp);
  79722. + crp = NULL;
  79723. +
  79724. + if (total > request_num) {
  79725. + outstanding--;
  79726. + return 0;
  79727. + }
  79728. +
  79729. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  79730. + INIT_WORK(&r->work, ocf_request_wq);
  79731. +#else
  79732. + INIT_WORK(&r->work, ocf_request, r);
  79733. +#endif
  79734. + schedule_work(&r->work);
  79735. + return 0;
  79736. +}
  79737. +
  79738. +
  79739. +static void
  79740. +ocf_request(void *arg)
  79741. +{
  79742. + request_t *r = arg;
  79743. + struct cryptop *crp = crypto_getreq(2);
  79744. + struct cryptodesc *crde, *crda;
  79745. +
  79746. + if (!crp) {
  79747. + outstanding--;
  79748. + return;
  79749. + }
  79750. +
  79751. + crde = crp->crp_desc;
  79752. + crda = crde->crd_next;
  79753. +
  79754. + crda->crd_skip = 0;
  79755. + crda->crd_flags = 0;
  79756. + crda->crd_len = request_size;
  79757. + crda->crd_inject = request_size;
  79758. + crda->crd_alg = CRYPTO_SHA1_HMAC;
  79759. + crda->crd_key = "0123456789abcdefghij";
  79760. + crda->crd_klen = 20 * 8;
  79761. +
  79762. + crde->crd_skip = 0;
  79763. + crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_ENCRYPT;
  79764. + crde->crd_len = request_size;
  79765. + crde->crd_inject = request_size;
  79766. + crde->crd_alg = CRYPTO_3DES_CBC;
  79767. + crde->crd_key = "0123456789abcdefghijklmn";
  79768. + crde->crd_klen = 24 * 8;
  79769. +
  79770. + crp->crp_ilen = request_size + 64;
  79771. + crp->crp_flags = CRYPTO_F_CBIMM;
  79772. + crp->crp_buf = (caddr_t) r->buffer;
  79773. + crp->crp_callback = ocf_cb;
  79774. + crp->crp_sid = ocf_cryptoid;
  79775. + crp->crp_opaque = (caddr_t) r;
  79776. + crypto_dispatch(crp);
  79777. +}
  79778. +
  79779. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  79780. +static void
  79781. +ocf_request_wq(struct work_struct *work)
  79782. +{
  79783. + request_t *r = container_of(work, request_t, work);
  79784. + ocf_request(r);
  79785. +}
  79786. +#endif
  79787. +
  79788. +/*************************************************************************/
  79789. +#ifdef BENCH_IXP_ACCESS_LIB
  79790. +/*************************************************************************/
  79791. +/*
  79792. + * CryptoAcc benchmark routines
  79793. + */
  79794. +
  79795. +static IxCryptoAccCtx ixp_ctx;
  79796. +static UINT32 ixp_ctx_id;
  79797. +static IX_MBUF ixp_pri;
  79798. +static IX_MBUF ixp_sec;
  79799. +static int ixp_registered = 0;
  79800. +
  79801. +static void ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp,
  79802. + IxCryptoAccStatus status);
  79803. +static void ixp_perform_cb(UINT32 ctx_id, IX_MBUF *sbufp, IX_MBUF *dbufp,
  79804. + IxCryptoAccStatus status);
  79805. +static void ixp_request(void *arg);
  79806. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  79807. +static void ixp_request_wq(struct work_struct *work);
  79808. +#endif
  79809. +
  79810. +static int
  79811. +ixp_init(void)
  79812. +{
  79813. + IxCryptoAccStatus status;
  79814. +
  79815. + ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
  79816. + ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  79817. + ixp_ctx.cipherCtx.cipherKeyLen = 24;
  79818. + ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  79819. + ixp_ctx.cipherCtx.cipherInitialVectorLen = IX_CRYPTO_ACC_DES_IV_64;
  79820. + memcpy(ixp_ctx.cipherCtx.key.cipherKey, "0123456789abcdefghijklmn", 24);
  79821. +
  79822. + ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
  79823. + ixp_ctx.authCtx.authDigestLen = 12;
  79824. + ixp_ctx.authCtx.aadLen = 0;
  79825. + ixp_ctx.authCtx.authKeyLen = 20;
  79826. + memcpy(ixp_ctx.authCtx.key.authKey, "0123456789abcdefghij", 20);
  79827. +
  79828. + ixp_ctx.useDifferentSrcAndDestMbufs = 0;
  79829. + ixp_ctx.operation = IX_CRYPTO_ACC_OP_ENCRYPT_AUTH ;
  79830. +
  79831. + IX_MBUF_MLEN(&ixp_pri) = IX_MBUF_PKT_LEN(&ixp_pri) = 128;
  79832. + IX_MBUF_MDATA(&ixp_pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  79833. + IX_MBUF_MLEN(&ixp_sec) = IX_MBUF_PKT_LEN(&ixp_sec) = 128;
  79834. + IX_MBUF_MDATA(&ixp_sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  79835. +
  79836. + status = ixCryptoAccCtxRegister(&ixp_ctx, &ixp_pri, &ixp_sec,
  79837. + ixp_register_cb, ixp_perform_cb, &ixp_ctx_id);
  79838. +
  79839. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {
  79840. + while (!ixp_registered)
  79841. + schedule();
  79842. + return ixp_registered < 0 ? -1 : 0;
  79843. + }
  79844. +
  79845. + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
  79846. + return -1;
  79847. +}
  79848. +
  79849. +static void
  79850. +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
  79851. +{
  79852. + if (bufp) {
  79853. + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
  79854. + kfree(IX_MBUF_MDATA(bufp));
  79855. + IX_MBUF_MDATA(bufp) = NULL;
  79856. + }
  79857. +
  79858. + if (IX_CRYPTO_ACC_STATUS_WAIT == status)
  79859. + return;
  79860. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  79861. + ixp_registered = 1;
  79862. + else
  79863. + ixp_registered = -1;
  79864. +}
  79865. +
  79866. +static void
  79867. +ixp_perform_cb(
  79868. + UINT32 ctx_id,
  79869. + IX_MBUF *sbufp,
  79870. + IX_MBUF *dbufp,
  79871. + IxCryptoAccStatus status)
  79872. +{
  79873. + request_t *r = NULL;
  79874. +
  79875. + total++;
  79876. + if (total > request_num) {
  79877. + outstanding--;
  79878. + return;
  79879. + }
  79880. +
  79881. + if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {
  79882. + printk("crappo %p %p\n", sbufp, r);
  79883. + outstanding--;
  79884. + return;
  79885. + }
  79886. +
  79887. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  79888. + INIT_WORK(&r->work, ixp_request_wq);
  79889. +#else
  79890. + INIT_WORK(&r->work, ixp_request, r);
  79891. +#endif
  79892. + schedule_work(&r->work);
  79893. +}
  79894. +
  79895. +static void
  79896. +ixp_request(void *arg)
  79897. +{
  79898. + request_t *r = arg;
  79899. + IxCryptoAccStatus status;
  79900. +
  79901. + memset(&r->mbuf, 0, sizeof(r->mbuf));
  79902. + IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;
  79903. + IX_MBUF_MDATA(&r->mbuf) = r->buffer;
  79904. + IX_MBUF_PRIV(&r->mbuf) = r;
  79905. + status = ixCryptoAccAuthCryptPerform(ixp_ctx_id, &r->mbuf, NULL,
  79906. + 0, request_size, 0, request_size, request_size, r->buffer);
  79907. + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
  79908. + printk("status1 = %d\n", status);
  79909. + outstanding--;
  79910. + return;
  79911. + }
  79912. + return;
  79913. +}
  79914. +
  79915. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  79916. +static void
  79917. +ixp_request_wq(struct work_struct *work)
  79918. +{
  79919. + request_t *r = container_of(work, request_t, work);
  79920. + ixp_request(r);
  79921. +}
  79922. +#endif
  79923. +
  79924. +/*************************************************************************/
  79925. +#endif /* BENCH_IXP_ACCESS_LIB */
  79926. +/*************************************************************************/
  79927. +
  79928. +int
  79929. +ocfbench_init(void)
  79930. +{
  79931. + int i, jstart, jstop;
  79932. +
  79933. + printk("Crypto Speed tests\n");
  79934. +
  79935. + requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);
  79936. + if (!requests) {
  79937. + printk("malloc failed\n");
  79938. + return -EINVAL;
  79939. + }
  79940. +
  79941. + for (i = 0; i < request_q_len; i++) {
  79942. + /* +64 for return data */
  79943. + requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
  79944. + if (!requests[i].buffer) {
  79945. + printk("malloc failed\n");
  79946. + return -EINVAL;
  79947. + }
  79948. + memset(requests[i].buffer, '0' + i, request_size + 128);
  79949. + }
  79950. +
  79951. + /*
  79952. + * OCF benchmark
  79953. + */
  79954. + printk("OCF: testing ...\n");
  79955. + ocf_init();
  79956. + total = outstanding = 0;
  79957. + jstart = jiffies;
  79958. + for (i = 0; i < request_q_len; i++) {
  79959. + outstanding++;
  79960. + ocf_request(&requests[i]);
  79961. + }
  79962. + while (outstanding > 0)
  79963. + schedule();
  79964. + jstop = jiffies;
  79965. +
  79966. + printk("OCF: %d requests of %d bytes in %d jiffies\n", total, request_size,
  79967. + jstop - jstart);
  79968. +
  79969. +#ifdef BENCH_IXP_ACCESS_LIB
  79970. + /*
  79971. + * IXP benchmark
  79972. + */
  79973. + printk("IXP: testing ...\n");
  79974. + ixp_init();
  79975. + total = outstanding = 0;
  79976. + jstart = jiffies;
  79977. + for (i = 0; i < request_q_len; i++) {
  79978. + outstanding++;
  79979. + ixp_request(&requests[i]);
  79980. + }
  79981. + while (outstanding > 0)
  79982. + schedule();
  79983. + jstop = jiffies;
  79984. +
  79985. + printk("IXP: %d requests of %d bytes in %d jiffies\n", total, request_size,
  79986. + jstop - jstart);
  79987. +#endif /* BENCH_IXP_ACCESS_LIB */
  79988. +
  79989. + for (i = 0; i < request_q_len; i++)
  79990. + kfree(requests[i].buffer);
  79991. + kfree(requests);
  79992. + return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */
  79993. +}
  79994. +
  79995. +static void __exit ocfbench_exit(void)
  79996. +{
  79997. +}
  79998. +
  79999. +module_init(ocfbench_init);
  80000. +module_exit(ocfbench_exit);
  80001. +
  80002. +MODULE_LICENSE("BSD");
  80003. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  80004. +MODULE_DESCRIPTION("Benchmark various in-kernel crypto speeds");
  80005. diff -Nur linux-2.6.39.orig/crypto/ocf/ocf-compat.h linux-2.6.39/crypto/ocf/ocf-compat.h
  80006. --- linux-2.6.39.orig/crypto/ocf/ocf-compat.h 1970-01-01 01:00:00.000000000 +0100
  80007. +++ linux-2.6.39/crypto/ocf/ocf-compat.h 2011-07-31 11:32:02.553424762 +0200
  80008. @@ -0,0 +1,294 @@
  80009. +#ifndef _BSD_COMPAT_H_
  80010. +#define _BSD_COMPAT_H_ 1
  80011. +/****************************************************************************/
  80012. +/*
  80013. + * Provide compat routines for older linux kernels and BSD kernels
  80014. + *
  80015. + * Written by David McCullough <david_mccullough@mcafee.com>
  80016. + * Copyright (C) 2010 David McCullough <david_mccullough@mcafee.com>
  80017. + *
  80018. + * LICENSE TERMS
  80019. + *
  80020. + * The free distribution and use of this software in both source and binary
  80021. + * form is allowed (with or without changes) provided that:
  80022. + *
  80023. + * 1. distributions of this source code include the above copyright
  80024. + * notice, this list of conditions and the following disclaimer;
  80025. + *
  80026. + * 2. distributions in binary form include the above copyright
  80027. + * notice, this list of conditions and the following disclaimer
  80028. + * in the documentation and/or other associated materials;
  80029. + *
  80030. + * 3. the copyright holder's name is not used to endorse products
  80031. + * built using this software without specific written permission.
  80032. + *
  80033. + * ALTERNATIVELY, provided that this notice is retained in full, this file
  80034. + * may be distributed under the terms of the GNU General Public License (GPL),
  80035. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  80036. + *
  80037. + * DISCLAIMER
  80038. + *
  80039. + * This software is provided 'as is' with no explicit or implied warranties
  80040. + * in respect of its properties, including, but not limited to, correctness
  80041. + * and/or fitness for purpose.
  80042. + */
  80043. +/****************************************************************************/
  80044. +#ifdef __KERNEL__
  80045. +/*
  80046. + * fake some BSD driver interface stuff specifically for OCF use
  80047. + */
  80048. +
  80049. +typedef struct ocf_device *device_t;
  80050. +
  80051. +typedef struct {
  80052. + int (*cryptodev_newsession)(device_t dev, u_int32_t *sidp, struct cryptoini *cri);
  80053. + int (*cryptodev_freesession)(device_t dev, u_int64_t tid);
  80054. + int (*cryptodev_process)(device_t dev, struct cryptop *crp, int hint);
  80055. + int (*cryptodev_kprocess)(device_t dev, struct cryptkop *krp, int hint);
  80056. +} device_method_t;
  80057. +#define DEVMETHOD(id, func) id: func
  80058. +
  80059. +struct ocf_device {
  80060. + char name[32]; /* the driver name */
  80061. + char nameunit[32]; /* the driver name + HW instance */
  80062. + int unit;
  80063. + device_method_t methods;
  80064. + void *softc;
  80065. +};
  80066. +
  80067. +#define CRYPTODEV_NEWSESSION(dev, sid, cri) \
  80068. + ((*(dev)->methods.cryptodev_newsession)(dev,sid,cri))
  80069. +#define CRYPTODEV_FREESESSION(dev, sid) \
  80070. + ((*(dev)->methods.cryptodev_freesession)(dev, sid))
  80071. +#define CRYPTODEV_PROCESS(dev, crp, hint) \
  80072. + ((*(dev)->methods.cryptodev_process)(dev, crp, hint))
  80073. +#define CRYPTODEV_KPROCESS(dev, krp, hint) \
  80074. + ((*(dev)->methods.cryptodev_kprocess)(dev, krp, hint))
  80075. +
  80076. +#define device_get_name(dev) ((dev)->name)
  80077. +#define device_get_nameunit(dev) ((dev)->nameunit)
  80078. +#define device_get_unit(dev) ((dev)->unit)
  80079. +#define device_get_softc(dev) ((dev)->softc)
  80080. +
  80081. +#define softc_device_decl \
  80082. + struct ocf_device _device; \
  80083. + device_t
  80084. +
  80085. +#define softc_device_init(_sc, _name, _unit, _methods) \
  80086. + if (1) {\
  80087. + strncpy((_sc)->_device.name, _name, sizeof((_sc)->_device.name) - 1); \
  80088. + snprintf((_sc)->_device.nameunit, sizeof((_sc)->_device.name), "%s%d", _name, _unit); \
  80089. + (_sc)->_device.unit = _unit; \
  80090. + (_sc)->_device.methods = _methods; \
  80091. + (_sc)->_device.softc = (void *) _sc; \
  80092. + *(device_t *)((softc_get_device(_sc))+1) = &(_sc)->_device; \
  80093. + } else
  80094. +
  80095. +#define softc_get_device(_sc) (&(_sc)->_device)
  80096. +
  80097. +/*
  80098. + * iomem support for 2.4 and 2.6 kernels
  80099. + */
  80100. +#include <linux/version.h>
  80101. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  80102. +#define ocf_iomem_t unsigned long
  80103. +
  80104. +/*
  80105. + * implement simple workqueue like support for older kernels
  80106. + */
  80107. +
  80108. +#include <linux/tqueue.h>
  80109. +
  80110. +#define work_struct tq_struct
  80111. +
  80112. +#define INIT_WORK(wp, fp, ap) \
  80113. + do { \
  80114. + (wp)->sync = 0; \
  80115. + (wp)->routine = (fp); \
  80116. + (wp)->data = (ap); \
  80117. + } while (0)
  80118. +
  80119. +#define schedule_work(wp) \
  80120. + do { \
  80121. + queue_task((wp), &tq_immediate); \
  80122. + mark_bh(IMMEDIATE_BH); \
  80123. + } while (0)
  80124. +
  80125. +#define flush_scheduled_work() run_task_queue(&tq_immediate)
  80126. +
  80127. +#else
  80128. +#define ocf_iomem_t void __iomem *
  80129. +
  80130. +#include <linux/workqueue.h>
  80131. +
  80132. +#endif
  80133. +
  80134. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
  80135. +#include <linux/fdtable.h>
  80136. +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
  80137. +#define files_fdtable(files) (files)
  80138. +#endif
  80139. +
  80140. +#ifdef MODULE_PARM
  80141. +#undef module_param /* just in case */
  80142. +#define module_param(a,b,c) MODULE_PARM(a,"i")
  80143. +#endif
  80144. +
  80145. +#define bzero(s,l) memset(s,0,l)
  80146. +#define bcopy(s,d,l) memcpy(d,s,l)
  80147. +#define bcmp(x, y, l) memcmp(x,y,l)
  80148. +
  80149. +#define MIN(x,y) ((x) < (y) ? (x) : (y))
  80150. +
  80151. +#define device_printf(dev, a...) ({ \
  80152. + printk("%s: ", device_get_nameunit(dev)); printk(a); \
  80153. + })
  80154. +
  80155. +#undef printf
  80156. +#define printf(fmt...) printk(fmt)
  80157. +
  80158. +#define KASSERT(c,p) if (!(c)) { printk p ; } else
  80159. +
  80160. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  80161. +#define ocf_daemonize(str) \
  80162. + daemonize(); \
  80163. + spin_lock_irq(&current->sigmask_lock); \
  80164. + sigemptyset(&current->blocked); \
  80165. + recalc_sigpending(current); \
  80166. + spin_unlock_irq(&current->sigmask_lock); \
  80167. + sprintf(current->comm, str);
  80168. +#else
  80169. +#define ocf_daemonize(str) daemonize(str);
  80170. +#endif
  80171. +
  80172. +#define TAILQ_INSERT_TAIL(q,d,m) list_add_tail(&(d)->m, (q))
  80173. +#define TAILQ_EMPTY(q) list_empty(q)
  80174. +#define TAILQ_FOREACH(v, q, m) list_for_each_entry(v, q, m)
  80175. +
  80176. +#define read_random(p,l) get_random_bytes(p,l)
  80177. +
  80178. +#define DELAY(x) ((x) > 2000 ? mdelay((x)/1000) : udelay(x))
  80179. +#define strtoul simple_strtoul
  80180. +
  80181. +#define pci_get_vendor(dev) ((dev)->vendor)
  80182. +#define pci_get_device(dev) ((dev)->device)
  80183. +
  80184. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  80185. +#define pci_set_consistent_dma_mask(dev, mask) (0)
  80186. +#endif
  80187. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
  80188. +#define pci_dma_sync_single_for_cpu pci_dma_sync_single
  80189. +#endif
  80190. +
  80191. +#ifndef DMA_32BIT_MASK
  80192. +#define DMA_32BIT_MASK 0x00000000ffffffffULL
  80193. +#endif
  80194. +
  80195. +#ifndef htole32
  80196. +#define htole32(x) cpu_to_le32(x)
  80197. +#endif
  80198. +#ifndef htobe32
  80199. +#define htobe32(x) cpu_to_be32(x)
  80200. +#endif
  80201. +#ifndef htole16
  80202. +#define htole16(x) cpu_to_le16(x)
  80203. +#endif
  80204. +#ifndef htobe16
  80205. +#define htobe16(x) cpu_to_be16(x)
  80206. +#endif
  80207. +
  80208. +/* older kernels don't have these */
  80209. +
  80210. +#include <asm/irq.h>
  80211. +#if !defined(IRQ_NONE) && !defined(IRQ_RETVAL)
  80212. +#define IRQ_NONE
  80213. +#define IRQ_HANDLED
  80214. +#define IRQ_WAKE_THREAD
  80215. +#define IRQ_RETVAL
  80216. +#define irqreturn_t void
  80217. +typedef irqreturn_t (*irq_handler_t)(int irq, void *arg, struct pt_regs *regs);
  80218. +#endif
  80219. +#ifndef IRQF_SHARED
  80220. +#define IRQF_SHARED SA_SHIRQ
  80221. +#endif
  80222. +
  80223. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  80224. +# define strlcpy(dest,src,len) \
  80225. + ({strncpy(dest,src,(len)-1); ((char *)dest)[(len)-1] = '\0'; })
  80226. +#endif
  80227. +
  80228. +#ifndef MAX_ERRNO
  80229. +#define MAX_ERRNO 4095
  80230. +#endif
  80231. +#ifndef IS_ERR_VALUE
  80232. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,5)
  80233. +#include <linux/err.h>
  80234. +#endif
  80235. +#ifndef IS_ERR_VALUE
  80236. +#define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-MAX_ERRNO)
  80237. +#endif
  80238. +#endif
  80239. +
  80240. +/*
  80241. + * common debug for all
  80242. + */
  80243. +#if 1
  80244. +#define dprintk(a...) do { if (debug) printk(a); } while(0)
  80245. +#else
  80246. +#define dprintk(a...)
  80247. +#endif
  80248. +
  80249. +#ifndef SLAB_ATOMIC
  80250. +/* Changed in 2.6.20, must use GFP_ATOMIC now */
  80251. +#define SLAB_ATOMIC GFP_ATOMIC
  80252. +#endif
  80253. +
  80254. +/*
  80255. + * need some additional support for older kernels */
  80256. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,2)
  80257. +#define pci_register_driver_compat(driver, rc) \
  80258. + do { \
  80259. + if ((rc) > 0) { \
  80260. + (rc) = 0; \
  80261. + } else if (rc == 0) { \
  80262. + (rc) = -ENODEV; \
  80263. + } else { \
  80264. + pci_unregister_driver(driver); \
  80265. + } \
  80266. + } while (0)
  80267. +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
  80268. +#define pci_register_driver_compat(driver,rc) ((rc) = (rc) < 0 ? (rc) : 0)
  80269. +#else
  80270. +#define pci_register_driver_compat(driver,rc)
  80271. +#endif
  80272. +
  80273. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
  80274. +
  80275. +#include <linux/mm.h>
  80276. +#include <asm/scatterlist.h>
  80277. +
  80278. +static inline void sg_set_page(struct scatterlist *sg, struct page *page,
  80279. + unsigned int len, unsigned int offset)
  80280. +{
  80281. + sg->page = page;
  80282. + sg->offset = offset;
  80283. + sg->length = len;
  80284. +}
  80285. +
  80286. +static inline void *sg_virt(struct scatterlist *sg)
  80287. +{
  80288. + return page_address(sg->page) + sg->offset;
  80289. +}
  80290. +
  80291. +#define sg_init_table(sg, n)
  80292. +
  80293. +#endif
  80294. +
  80295. +#ifndef late_initcall
  80296. +#define late_initcall(init) module_init(init)
  80297. +#endif
  80298. +
  80299. +#endif /* __KERNEL__ */
  80300. +
  80301. +/****************************************************************************/
  80302. +#endif /* _BSD_COMPAT_H_ */
  80303. diff -Nur linux-2.6.39.orig/crypto/ocf/ocfnull/Makefile linux-2.6.39/crypto/ocf/ocfnull/Makefile
  80304. --- linux-2.6.39.orig/crypto/ocf/ocfnull/Makefile 1970-01-01 01:00:00.000000000 +0100
  80305. +++ linux-2.6.39/crypto/ocf/ocfnull/Makefile 2011-07-31 11:32:02.593968342 +0200
  80306. @@ -0,0 +1,12 @@
  80307. +# for SGlinux builds
  80308. +-include $(ROOTDIR)/modules/.config
  80309. +
  80310. +obj-$(CONFIG_OCF_OCFNULL) += ocfnull.o
  80311. +
  80312. +obj ?= .
  80313. +EXTRA_CFLAGS += -I$(obj)/..
  80314. +
  80315. +ifdef TOPDIR
  80316. +-include $(TOPDIR)/Rules.make
  80317. +endif
  80318. +
  80319. diff -Nur linux-2.6.39.orig/crypto/ocf/ocfnull/ocfnull.c linux-2.6.39/crypto/ocf/ocfnull/ocfnull.c
  80320. --- linux-2.6.39.orig/crypto/ocf/ocfnull/ocfnull.c 1970-01-01 01:00:00.000000000 +0100
  80321. +++ linux-2.6.39/crypto/ocf/ocfnull/ocfnull.c 2011-07-31 11:32:02.673779571 +0200
  80322. @@ -0,0 +1,203 @@
  80323. +/*
  80324. + * An OCF module for determining the cost of crypto versus the cost of
  80325. + * IPSec processing outside of OCF. This modules gives us the effect of
  80326. + * zero cost encryption, of course you will need to run it at both ends
  80327. + * since it does no crypto at all.
  80328. + *
  80329. + * Written by David McCullough <david_mccullough@mcafee.com>
  80330. + * Copyright (C) 2006-2010 David McCullough
  80331. + *
  80332. + * LICENSE TERMS
  80333. + *
  80334. + * The free distribution and use of this software in both source and binary
  80335. + * form is allowed (with or without changes) provided that:
  80336. + *
  80337. + * 1. distributions of this source code include the above copyright
  80338. + * notice, this list of conditions and the following disclaimer;
  80339. + *
  80340. + * 2. distributions in binary form include the above copyright
  80341. + * notice, this list of conditions and the following disclaimer
  80342. + * in the documentation and/or other associated materials;
  80343. + *
  80344. + * 3. the copyright holder's name is not used to endorse products
  80345. + * built using this software without specific written permission.
  80346. + *
  80347. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  80348. + * may be distributed under the terms of the GNU General Public License (GPL),
  80349. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  80350. + *
  80351. + * DISCLAIMER
  80352. + *
  80353. + * This software is provided 'as is' with no explicit or implied warranties
  80354. + * in respect of its properties, including, but not limited to, correctness
  80355. + * and/or fitness for purpose.
  80356. + */
  80357. +
  80358. +#ifndef AUTOCONF_INCLUDED
  80359. +#include <linux/config.h>
  80360. +#endif
  80361. +#include <linux/module.h>
  80362. +#include <linux/init.h>
  80363. +#include <linux/list.h>
  80364. +#include <linux/slab.h>
  80365. +#include <linux/sched.h>
  80366. +#include <linux/wait.h>
  80367. +#include <linux/crypto.h>
  80368. +#include <linux/interrupt.h>
  80369. +
  80370. +#include <cryptodev.h>
  80371. +#include <uio.h>
  80372. +
  80373. +static int32_t null_id = -1;
  80374. +static u_int32_t null_sesnum = 0;
  80375. +
  80376. +static int null_process(device_t, struct cryptop *, int);
  80377. +static int null_newsession(device_t, u_int32_t *, struct cryptoini *);
  80378. +static int null_freesession(device_t, u_int64_t);
  80379. +
  80380. +#define debug ocfnull_debug
  80381. +int ocfnull_debug = 0;
  80382. +module_param(ocfnull_debug, int, 0644);
  80383. +MODULE_PARM_DESC(ocfnull_debug, "Enable debug");
  80384. +
  80385. +/*
  80386. + * dummy device structure
  80387. + */
  80388. +
  80389. +static struct {
  80390. + softc_device_decl sc_dev;
  80391. +} nulldev;
  80392. +
  80393. +static device_method_t null_methods = {
  80394. + /* crypto device methods */
  80395. + DEVMETHOD(cryptodev_newsession, null_newsession),
  80396. + DEVMETHOD(cryptodev_freesession,null_freesession),
  80397. + DEVMETHOD(cryptodev_process, null_process),
  80398. +};
  80399. +
  80400. +/*
  80401. + * Generate a new software session.
  80402. + */
  80403. +static int
  80404. +null_newsession(device_t arg, u_int32_t *sid, struct cryptoini *cri)
  80405. +{
  80406. + dprintk("%s()\n", __FUNCTION__);
  80407. + if (sid == NULL || cri == NULL) {
  80408. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  80409. + return EINVAL;
  80410. + }
  80411. +
  80412. + if (null_sesnum == 0)
  80413. + null_sesnum++;
  80414. + *sid = null_sesnum++;
  80415. + return 0;
  80416. +}
  80417. +
  80418. +
  80419. +/*
  80420. + * Free a session.
  80421. + */
  80422. +static int
  80423. +null_freesession(device_t arg, u_int64_t tid)
  80424. +{
  80425. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  80426. +
  80427. + dprintk("%s()\n", __FUNCTION__);
  80428. + if (sid > null_sesnum) {
  80429. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  80430. + return EINVAL;
  80431. + }
  80432. +
  80433. + /* Silently accept and return */
  80434. + if (sid == 0)
  80435. + return 0;
  80436. + return 0;
  80437. +}
  80438. +
  80439. +
  80440. +/*
  80441. + * Process a request.
  80442. + */
  80443. +static int
  80444. +null_process(device_t arg, struct cryptop *crp, int hint)
  80445. +{
  80446. + unsigned int lid;
  80447. +
  80448. + dprintk("%s()\n", __FUNCTION__);
  80449. +
  80450. + /* Sanity check */
  80451. + if (crp == NULL) {
  80452. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  80453. + return EINVAL;
  80454. + }
  80455. +
  80456. + crp->crp_etype = 0;
  80457. +
  80458. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  80459. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  80460. + crp->crp_etype = EINVAL;
  80461. + goto done;
  80462. + }
  80463. +
  80464. + /*
  80465. + * find the session we are using
  80466. + */
  80467. +
  80468. + lid = crp->crp_sid & 0xffffffff;
  80469. + if (lid >= null_sesnum || lid == 0) {
  80470. + crp->crp_etype = ENOENT;
  80471. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  80472. + goto done;
  80473. + }
  80474. +
  80475. +done:
  80476. + crypto_done(crp);
  80477. + return 0;
  80478. +}
  80479. +
  80480. +
  80481. +/*
  80482. + * our driver startup and shutdown routines
  80483. + */
  80484. +
  80485. +static int
  80486. +null_init(void)
  80487. +{
  80488. + dprintk("%s(%p)\n", __FUNCTION__, null_init);
  80489. +
  80490. + memset(&nulldev, 0, sizeof(nulldev));
  80491. + softc_device_init(&nulldev, "ocfnull", 0, null_methods);
  80492. +
  80493. + null_id = crypto_get_driverid(softc_get_device(&nulldev),
  80494. + CRYPTOCAP_F_HARDWARE);
  80495. + if (null_id < 0)
  80496. + panic("ocfnull: crypto device cannot initialize!");
  80497. +
  80498. +#define REGISTER(alg) \
  80499. + crypto_register(null_id,alg,0,0)
  80500. + REGISTER(CRYPTO_DES_CBC);
  80501. + REGISTER(CRYPTO_3DES_CBC);
  80502. + REGISTER(CRYPTO_RIJNDAEL128_CBC);
  80503. + REGISTER(CRYPTO_MD5);
  80504. + REGISTER(CRYPTO_SHA1);
  80505. + REGISTER(CRYPTO_MD5_HMAC);
  80506. + REGISTER(CRYPTO_SHA1_HMAC);
  80507. +#undef REGISTER
  80508. +
  80509. + return 0;
  80510. +}
  80511. +
  80512. +static void
  80513. +null_exit(void)
  80514. +{
  80515. + dprintk("%s()\n", __FUNCTION__);
  80516. + crypto_unregister_all(null_id);
  80517. + null_id = -1;
  80518. +}
  80519. +
  80520. +module_init(null_init);
  80521. +module_exit(null_exit);
  80522. +
  80523. +MODULE_LICENSE("Dual BSD/GPL");
  80524. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  80525. +MODULE_DESCRIPTION("ocfnull - claims a lot but does nothing");
  80526. diff -Nur linux-2.6.39.orig/crypto/ocf/pasemi/Makefile linux-2.6.39/crypto/ocf/pasemi/Makefile
  80527. --- linux-2.6.39.orig/crypto/ocf/pasemi/Makefile 1970-01-01 01:00:00.000000000 +0100
  80528. +++ linux-2.6.39/crypto/ocf/pasemi/Makefile 2011-07-31 11:32:02.723416783 +0200
  80529. @@ -0,0 +1,12 @@
  80530. +# for SGlinux builds
  80531. +-include $(ROOTDIR)/modules/.config
  80532. +
  80533. +obj-$(CONFIG_OCF_PASEMI) += pasemi.o
  80534. +
  80535. +obj ?= .
  80536. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  80537. +
  80538. +ifdef TOPDIR
  80539. +-include $(TOPDIR)/Rules.make
  80540. +endif
  80541. +
  80542. diff -Nur linux-2.6.39.orig/crypto/ocf/pasemi/pasemi.c linux-2.6.39/crypto/ocf/pasemi/pasemi.c
  80543. --- linux-2.6.39.orig/crypto/ocf/pasemi/pasemi.c 1970-01-01 01:00:00.000000000 +0100
  80544. +++ linux-2.6.39/crypto/ocf/pasemi/pasemi.c 2011-07-31 11:32:02.773425799 +0200
  80545. @@ -0,0 +1,1009 @@
  80546. +/*
  80547. + * Copyright (C) 2007 PA Semi, Inc
  80548. + *
  80549. + * Driver for the PA Semi PWRficient DMA Crypto Engine
  80550. + *
  80551. + * This program is free software; you can redistribute it and/or modify
  80552. + * it under the terms of the GNU General Public License version 2 as
  80553. + * published by the Free Software Foundation.
  80554. + *
  80555. + * This program is distributed in the hope that it will be useful,
  80556. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  80557. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  80558. + * GNU General Public License for more details.
  80559. + *
  80560. + * You should have received a copy of the GNU General Public License
  80561. + * along with this program; if not, write to the Free Software
  80562. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  80563. + */
  80564. +
  80565. +#ifndef AUTOCONF_INCLUDED
  80566. +#include <linux/config.h>
  80567. +#endif
  80568. +#include <linux/module.h>
  80569. +#include <linux/init.h>
  80570. +#include <linux/interrupt.h>
  80571. +#include <linux/timer.h>
  80572. +#include <linux/random.h>
  80573. +#include <linux/skbuff.h>
  80574. +#include <asm/scatterlist.h>
  80575. +#include <linux/moduleparam.h>
  80576. +#include <linux/pci.h>
  80577. +#include <cryptodev.h>
  80578. +#include <uio.h>
  80579. +#include "pasemi_fnu.h"
  80580. +
  80581. +#define DRV_NAME "pasemi"
  80582. +
  80583. +#define TIMER_INTERVAL 1000
  80584. +
  80585. +static void __devexit pasemi_dma_remove(struct pci_dev *pdev);
  80586. +static struct pasdma_status volatile * dma_status;
  80587. +
  80588. +static int debug;
  80589. +module_param(debug, int, 0644);
  80590. +MODULE_PARM_DESC(debug, "Enable debug");
  80591. +
  80592. +static void pasemi_desc_start(struct pasemi_desc *desc, u64 hdr)
  80593. +{
  80594. + desc->postop = 0;
  80595. + desc->quad[0] = hdr;
  80596. + desc->quad_cnt = 1;
  80597. + desc->size = 1;
  80598. +}
  80599. +
  80600. +static void pasemi_desc_build(struct pasemi_desc *desc, u64 val)
  80601. +{
  80602. + desc->quad[desc->quad_cnt++] = val;
  80603. + desc->size = (desc->quad_cnt + 1) / 2;
  80604. +}
  80605. +
  80606. +static void pasemi_desc_hdr(struct pasemi_desc *desc, u64 hdr)
  80607. +{
  80608. + desc->quad[0] |= hdr;
  80609. +}
  80610. +
  80611. +static int pasemi_desc_size(struct pasemi_desc *desc)
  80612. +{
  80613. + return desc->size;
  80614. +}
  80615. +
  80616. +static void pasemi_ring_add_desc(
  80617. + struct pasemi_fnu_txring *ring,
  80618. + struct pasemi_desc *desc,
  80619. + struct cryptop *crp) {
  80620. + int i;
  80621. + int ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
  80622. +
  80623. + TX_DESC_INFO(ring, ring->next_to_fill).desc_size = desc->size;
  80624. + TX_DESC_INFO(ring, ring->next_to_fill).desc_postop = desc->postop;
  80625. + TX_DESC_INFO(ring, ring->next_to_fill).cf_crp = crp;
  80626. +
  80627. + for (i = 0; i < desc->quad_cnt; i += 2) {
  80628. + ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
  80629. + ring->desc[ring_index] = desc->quad[i];
  80630. + ring->desc[ring_index + 1] = desc->quad[i + 1];
  80631. + ring->next_to_fill++;
  80632. + }
  80633. +
  80634. + if (desc->quad_cnt & 1)
  80635. + ring->desc[ring_index + 1] = 0;
  80636. +}
  80637. +
  80638. +static void pasemi_ring_incr(struct pasemi_softc *sc, int chan_index, int incr)
  80639. +{
  80640. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_INCR(sc->base_chan + chan_index),
  80641. + incr);
  80642. +}
  80643. +
  80644. +/*
  80645. + * Generate a new software session.
  80646. + */
  80647. +static int
  80648. +pasemi_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  80649. +{
  80650. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  80651. + struct pasemi_softc *sc = device_get_softc(dev);
  80652. + struct pasemi_session *ses = NULL, **sespp;
  80653. + int sesn, blksz = 0;
  80654. + u64 ccmd = 0;
  80655. + unsigned long flags;
  80656. + struct pasemi_desc init_desc;
  80657. + struct pasemi_fnu_txring *txring;
  80658. +
  80659. + DPRINTF("%s()\n", __FUNCTION__);
  80660. + if (sidp == NULL || cri == NULL || sc == NULL) {
  80661. + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
  80662. + return -EINVAL;
  80663. + }
  80664. + for (c = cri; c != NULL; c = c->cri_next) {
  80665. + if (ALG_IS_SIG(c->cri_alg)) {
  80666. + if (macini)
  80667. + return -EINVAL;
  80668. + macini = c;
  80669. + } else if (ALG_IS_CIPHER(c->cri_alg)) {
  80670. + if (encini)
  80671. + return -EINVAL;
  80672. + encini = c;
  80673. + } else {
  80674. + DPRINTF("UNKNOWN c->cri_alg %d\n", c->cri_alg);
  80675. + return -EINVAL;
  80676. + }
  80677. + }
  80678. + if (encini == NULL && macini == NULL)
  80679. + return -EINVAL;
  80680. + if (encini) {
  80681. + /* validate key length */
  80682. + switch (encini->cri_alg) {
  80683. + case CRYPTO_DES_CBC:
  80684. + if (encini->cri_klen != 64)
  80685. + return -EINVAL;
  80686. + ccmd = DMA_CALGO_DES;
  80687. + break;
  80688. + case CRYPTO_3DES_CBC:
  80689. + if (encini->cri_klen != 192)
  80690. + return -EINVAL;
  80691. + ccmd = DMA_CALGO_3DES;
  80692. + break;
  80693. + case CRYPTO_AES_CBC:
  80694. + if (encini->cri_klen != 128 &&
  80695. + encini->cri_klen != 192 &&
  80696. + encini->cri_klen != 256)
  80697. + return -EINVAL;
  80698. + ccmd = DMA_CALGO_AES;
  80699. + break;
  80700. + case CRYPTO_ARC4:
  80701. + if (encini->cri_klen != 128)
  80702. + return -EINVAL;
  80703. + ccmd = DMA_CALGO_ARC;
  80704. + break;
  80705. + default:
  80706. + DPRINTF("UNKNOWN encini->cri_alg %d\n",
  80707. + encini->cri_alg);
  80708. + return -EINVAL;
  80709. + }
  80710. + }
  80711. +
  80712. + if (macini) {
  80713. + switch (macini->cri_alg) {
  80714. + case CRYPTO_MD5:
  80715. + case CRYPTO_MD5_HMAC:
  80716. + blksz = 16;
  80717. + break;
  80718. + case CRYPTO_SHA1:
  80719. + case CRYPTO_SHA1_HMAC:
  80720. + blksz = 20;
  80721. + break;
  80722. + default:
  80723. + DPRINTF("UNKNOWN macini->cri_alg %d\n",
  80724. + macini->cri_alg);
  80725. + return -EINVAL;
  80726. + }
  80727. + if (((macini->cri_klen + 7) / 8) > blksz) {
  80728. + DPRINTF("key length %d bigger than blksize %d not supported\n",
  80729. + ((macini->cri_klen + 7) / 8), blksz);
  80730. + return -EINVAL;
  80731. + }
  80732. + }
  80733. +
  80734. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  80735. + if (sc->sc_sessions[sesn] == NULL) {
  80736. + sc->sc_sessions[sesn] = (struct pasemi_session *)
  80737. + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
  80738. + ses = sc->sc_sessions[sesn];
  80739. + break;
  80740. + } else if (sc->sc_sessions[sesn]->used == 0) {
  80741. + ses = sc->sc_sessions[sesn];
  80742. + break;
  80743. + }
  80744. + }
  80745. +
  80746. + if (ses == NULL) {
  80747. + sespp = (struct pasemi_session **)
  80748. + kzalloc(sc->sc_nsessions * 2 *
  80749. + sizeof(struct pasemi_session *), GFP_ATOMIC);
  80750. + if (sespp == NULL)
  80751. + return -ENOMEM;
  80752. + memcpy(sespp, sc->sc_sessions,
  80753. + sc->sc_nsessions * sizeof(struct pasemi_session *));
  80754. + kfree(sc->sc_sessions);
  80755. + sc->sc_sessions = sespp;
  80756. + sesn = sc->sc_nsessions;
  80757. + ses = sc->sc_sessions[sesn] = (struct pasemi_session *)
  80758. + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
  80759. + if (ses == NULL)
  80760. + return -ENOMEM;
  80761. + sc->sc_nsessions *= 2;
  80762. + }
  80763. +
  80764. + ses->used = 1;
  80765. +
  80766. + ses->dma_addr = pci_map_single(sc->dma_pdev, (void *) ses->civ,
  80767. + sizeof(struct pasemi_session), DMA_TO_DEVICE);
  80768. +
  80769. + /* enter the channel scheduler */
  80770. + spin_lock_irqsave(&sc->sc_chnlock, flags);
  80771. +
  80772. + /* ARC4 has to be processed by the even channel */
  80773. + if (encini && (encini->cri_alg == CRYPTO_ARC4))
  80774. + ses->chan = sc->sc_lastchn & ~1;
  80775. + else
  80776. + ses->chan = sc->sc_lastchn;
  80777. + sc->sc_lastchn = (sc->sc_lastchn + 1) % sc->sc_num_channels;
  80778. +
  80779. + spin_unlock_irqrestore(&sc->sc_chnlock, flags);
  80780. +
  80781. + txring = &sc->tx[ses->chan];
  80782. +
  80783. + if (encini) {
  80784. + ses->ccmd = ccmd;
  80785. +
  80786. + /* get an IV */
  80787. + /* XXX may read fewer than requested */
  80788. + get_random_bytes(ses->civ, sizeof(ses->civ));
  80789. +
  80790. + ses->keysz = (encini->cri_klen - 63) / 64;
  80791. + memcpy(ses->key, encini->cri_key, (ses->keysz + 1) * 8);
  80792. +
  80793. + pasemi_desc_start(&init_desc,
  80794. + XCT_CTRL_HDR(ses->chan, (encini && macini) ? 0x68 : 0x40, DMA_FN_CIV0));
  80795. + pasemi_desc_build(&init_desc,
  80796. + XCT_FUN_SRC_PTR((encini && macini) ? 0x68 : 0x40, ses->dma_addr));
  80797. + }
  80798. + if (macini) {
  80799. + if (macini->cri_alg == CRYPTO_MD5_HMAC ||
  80800. + macini->cri_alg == CRYPTO_SHA1_HMAC)
  80801. + memcpy(ses->hkey, macini->cri_key, blksz);
  80802. + else {
  80803. + /* Load initialization constants(RFC 1321, 3174) */
  80804. + ses->hiv[0] = 0x67452301efcdab89ULL;
  80805. + ses->hiv[1] = 0x98badcfe10325476ULL;
  80806. + ses->hiv[2] = 0xc3d2e1f000000000ULL;
  80807. + }
  80808. + ses->hseq = 0ULL;
  80809. + }
  80810. +
  80811. + spin_lock_irqsave(&txring->fill_lock, flags);
  80812. +
  80813. + if (((txring->next_to_fill + pasemi_desc_size(&init_desc)) -
  80814. + txring->next_to_clean) > TX_RING_SIZE) {
  80815. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  80816. + return ERESTART;
  80817. + }
  80818. +
  80819. + if (encini) {
  80820. + pasemi_ring_add_desc(txring, &init_desc, NULL);
  80821. + pasemi_ring_incr(sc, ses->chan,
  80822. + pasemi_desc_size(&init_desc));
  80823. + }
  80824. +
  80825. + txring->sesn = sesn;
  80826. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  80827. +
  80828. + *sidp = PASEMI_SID(sesn);
  80829. + return 0;
  80830. +}
  80831. +
  80832. +/*
  80833. + * Deallocate a session.
  80834. + */
  80835. +static int
  80836. +pasemi_freesession(device_t dev, u_int64_t tid)
  80837. +{
  80838. + struct pasemi_softc *sc = device_get_softc(dev);
  80839. + int session;
  80840. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  80841. +
  80842. + DPRINTF("%s()\n", __FUNCTION__);
  80843. +
  80844. + if (sc == NULL)
  80845. + return -EINVAL;
  80846. + session = PASEMI_SESSION(sid);
  80847. + if (session >= sc->sc_nsessions || !sc->sc_sessions[session])
  80848. + return -EINVAL;
  80849. +
  80850. + pci_unmap_single(sc->dma_pdev,
  80851. + sc->sc_sessions[session]->dma_addr,
  80852. + sizeof(struct pasemi_session), DMA_TO_DEVICE);
  80853. + memset(sc->sc_sessions[session], 0,
  80854. + sizeof(struct pasemi_session));
  80855. +
  80856. + return 0;
  80857. +}
  80858. +
  80859. +static int
  80860. +pasemi_process(device_t dev, struct cryptop *crp, int hint)
  80861. +{
  80862. +
  80863. + int err = 0, ivsize, srclen = 0, reinit = 0, reinit_size = 0, chsel;
  80864. + struct pasemi_softc *sc = device_get_softc(dev);
  80865. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  80866. + caddr_t ivp;
  80867. + struct pasemi_desc init_desc, work_desc;
  80868. + struct pasemi_session *ses;
  80869. + struct sk_buff *skb;
  80870. + struct uio *uiop;
  80871. + unsigned long flags;
  80872. + struct pasemi_fnu_txring *txring;
  80873. +
  80874. + DPRINTF("%s()\n", __FUNCTION__);
  80875. +
  80876. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL)
  80877. + return -EINVAL;
  80878. +
  80879. + crp->crp_etype = 0;
  80880. + if (PASEMI_SESSION(crp->crp_sid) >= sc->sc_nsessions)
  80881. + return -EINVAL;
  80882. +
  80883. + ses = sc->sc_sessions[PASEMI_SESSION(crp->crp_sid)];
  80884. +
  80885. + crd1 = crp->crp_desc;
  80886. + if (crd1 == NULL) {
  80887. + err = -EINVAL;
  80888. + goto errout;
  80889. + }
  80890. + crd2 = crd1->crd_next;
  80891. +
  80892. + if (ALG_IS_SIG(crd1->crd_alg)) {
  80893. + maccrd = crd1;
  80894. + if (crd2 == NULL)
  80895. + enccrd = NULL;
  80896. + else if (ALG_IS_CIPHER(crd2->crd_alg) &&
  80897. + (crd2->crd_flags & CRD_F_ENCRYPT) == 0)
  80898. + enccrd = crd2;
  80899. + else
  80900. + goto erralg;
  80901. + } else if (ALG_IS_CIPHER(crd1->crd_alg)) {
  80902. + enccrd = crd1;
  80903. + if (crd2 == NULL)
  80904. + maccrd = NULL;
  80905. + else if (ALG_IS_SIG(crd2->crd_alg) &&
  80906. + (crd1->crd_flags & CRD_F_ENCRYPT))
  80907. + maccrd = crd2;
  80908. + else
  80909. + goto erralg;
  80910. + } else
  80911. + goto erralg;
  80912. +
  80913. + chsel = ses->chan;
  80914. +
  80915. + txring = &sc->tx[chsel];
  80916. +
  80917. + if (enccrd && !maccrd) {
  80918. + if (enccrd->crd_alg == CRYPTO_ARC4)
  80919. + reinit = 1;
  80920. + reinit_size = 0x40;
  80921. + srclen = crp->crp_ilen;
  80922. +
  80923. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I
  80924. + | XCT_FUN_FUN(chsel));
  80925. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  80926. + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_ENC);
  80927. + else
  80928. + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_DEC);
  80929. + } else if (enccrd && maccrd) {
  80930. + if (enccrd->crd_alg == CRYPTO_ARC4)
  80931. + reinit = 1;
  80932. + reinit_size = 0x68;
  80933. +
  80934. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  80935. + /* Encrypt -> Authenticate */
  80936. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_ENC_SIG
  80937. + | XCT_FUN_A | XCT_FUN_FUN(chsel));
  80938. + srclen = maccrd->crd_skip + maccrd->crd_len;
  80939. + } else {
  80940. + /* Authenticate -> Decrypt */
  80941. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG_DEC
  80942. + | XCT_FUN_24BRES | XCT_FUN_FUN(chsel));
  80943. + pasemi_desc_build(&work_desc, 0);
  80944. + pasemi_desc_build(&work_desc, 0);
  80945. + pasemi_desc_build(&work_desc, 0);
  80946. + work_desc.postop = PASEMI_CHECK_SIG;
  80947. + srclen = crp->crp_ilen;
  80948. + }
  80949. +
  80950. + pasemi_desc_hdr(&work_desc, XCT_FUN_SHL(maccrd->crd_skip / 4));
  80951. + pasemi_desc_hdr(&work_desc, XCT_FUN_CHL(enccrd->crd_skip - maccrd->crd_skip));
  80952. + } else if (!enccrd && maccrd) {
  80953. + srclen = maccrd->crd_len;
  80954. +
  80955. + pasemi_desc_start(&init_desc,
  80956. + XCT_CTRL_HDR(chsel, 0x58, DMA_FN_HKEY0));
  80957. + pasemi_desc_build(&init_desc,
  80958. + XCT_FUN_SRC_PTR(0x58, ((struct pasemi_session *)ses->dma_addr)->hkey));
  80959. +
  80960. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG
  80961. + | XCT_FUN_A | XCT_FUN_FUN(chsel));
  80962. + }
  80963. +
  80964. + if (enccrd) {
  80965. + switch (enccrd->crd_alg) {
  80966. + case CRYPTO_3DES_CBC:
  80967. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_3DES |
  80968. + XCT_FUN_BCM_CBC);
  80969. + ivsize = sizeof(u64);
  80970. + break;
  80971. + case CRYPTO_DES_CBC:
  80972. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_DES |
  80973. + XCT_FUN_BCM_CBC);
  80974. + ivsize = sizeof(u64);
  80975. + break;
  80976. + case CRYPTO_AES_CBC:
  80977. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_AES |
  80978. + XCT_FUN_BCM_CBC);
  80979. + ivsize = 2 * sizeof(u64);
  80980. + break;
  80981. + case CRYPTO_ARC4:
  80982. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_ARC);
  80983. + ivsize = 0;
  80984. + break;
  80985. + default:
  80986. + printk(DRV_NAME ": unimplemented enccrd->crd_alg %d\n",
  80987. + enccrd->crd_alg);
  80988. + err = -EINVAL;
  80989. + goto errout;
  80990. + }
  80991. +
  80992. + ivp = (ivsize == sizeof(u64)) ? (caddr_t) &ses->civ[1] : (caddr_t) &ses->civ[0];
  80993. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  80994. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  80995. + memcpy(ivp, enccrd->crd_iv, ivsize);
  80996. + /* If IV is not present in the buffer already, it has to be copied there */
  80997. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0)
  80998. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  80999. + enccrd->crd_inject, ivsize, ivp);
  81000. + } else {
  81001. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  81002. + /* IV is provided expicitly in descriptor */
  81003. + memcpy(ivp, enccrd->crd_iv, ivsize);
  81004. + else
  81005. + /* IV is provided in the packet */
  81006. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  81007. + enccrd->crd_inject, ivsize,
  81008. + ivp);
  81009. + }
  81010. + }
  81011. +
  81012. + if (maccrd) {
  81013. + switch (maccrd->crd_alg) {
  81014. + case CRYPTO_MD5:
  81015. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_MD5 |
  81016. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  81017. + break;
  81018. + case CRYPTO_SHA1:
  81019. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_SHA1 |
  81020. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  81021. + break;
  81022. + case CRYPTO_MD5_HMAC:
  81023. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_MD5 |
  81024. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  81025. + break;
  81026. + case CRYPTO_SHA1_HMAC:
  81027. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_SHA1 |
  81028. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  81029. + break;
  81030. + default:
  81031. + printk(DRV_NAME ": unimplemented maccrd->crd_alg %d\n",
  81032. + maccrd->crd_alg);
  81033. + err = -EINVAL;
  81034. + goto errout;
  81035. + }
  81036. + }
  81037. +
  81038. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  81039. + /* using SKB buffers */
  81040. + skb = (struct sk_buff *)crp->crp_buf;
  81041. + if (skb_shinfo(skb)->nr_frags) {
  81042. + printk(DRV_NAME ": skb frags unimplemented\n");
  81043. + err = -EINVAL;
  81044. + goto errout;
  81045. + }
  81046. + pasemi_desc_build(
  81047. + &work_desc,
  81048. + XCT_FUN_DST_PTR(skb->len, pci_map_single(
  81049. + sc->dma_pdev, skb->data,
  81050. + skb->len, DMA_TO_DEVICE)));
  81051. + pasemi_desc_build(
  81052. + &work_desc,
  81053. + XCT_FUN_SRC_PTR(
  81054. + srclen, pci_map_single(
  81055. + sc->dma_pdev, skb->data,
  81056. + srclen, DMA_TO_DEVICE)));
  81057. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  81058. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  81059. + /* using IOV buffers */
  81060. + uiop = (struct uio *)crp->crp_buf;
  81061. + if (uiop->uio_iovcnt > 1) {
  81062. + printk(DRV_NAME ": iov frags unimplemented\n");
  81063. + err = -EINVAL;
  81064. + goto errout;
  81065. + }
  81066. +
  81067. + /* crp_olen is never set; always use crp_ilen */
  81068. + pasemi_desc_build(
  81069. + &work_desc,
  81070. + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
  81071. + sc->dma_pdev,
  81072. + uiop->uio_iov->iov_base,
  81073. + crp->crp_ilen, DMA_TO_DEVICE)));
  81074. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  81075. +
  81076. + pasemi_desc_build(
  81077. + &work_desc,
  81078. + XCT_FUN_SRC_PTR(srclen, pci_map_single(
  81079. + sc->dma_pdev,
  81080. + uiop->uio_iov->iov_base,
  81081. + srclen, DMA_TO_DEVICE)));
  81082. + } else {
  81083. + /* using contig buffers */
  81084. + pasemi_desc_build(
  81085. + &work_desc,
  81086. + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
  81087. + sc->dma_pdev,
  81088. + crp->crp_buf,
  81089. + crp->crp_ilen, DMA_TO_DEVICE)));
  81090. + pasemi_desc_build(
  81091. + &work_desc,
  81092. + XCT_FUN_SRC_PTR(srclen, pci_map_single(
  81093. + sc->dma_pdev,
  81094. + crp->crp_buf, srclen,
  81095. + DMA_TO_DEVICE)));
  81096. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  81097. + }
  81098. +
  81099. + spin_lock_irqsave(&txring->fill_lock, flags);
  81100. +
  81101. + if (txring->sesn != PASEMI_SESSION(crp->crp_sid)) {
  81102. + txring->sesn = PASEMI_SESSION(crp->crp_sid);
  81103. + reinit = 1;
  81104. + }
  81105. +
  81106. + if (enccrd) {
  81107. + pasemi_desc_start(&init_desc,
  81108. + XCT_CTRL_HDR(chsel, reinit ? reinit_size : 0x10, DMA_FN_CIV0));
  81109. + pasemi_desc_build(&init_desc,
  81110. + XCT_FUN_SRC_PTR(reinit ? reinit_size : 0x10, ses->dma_addr));
  81111. + }
  81112. +
  81113. + if (((txring->next_to_fill + pasemi_desc_size(&init_desc) +
  81114. + pasemi_desc_size(&work_desc)) -
  81115. + txring->next_to_clean) > TX_RING_SIZE) {
  81116. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  81117. + err = ERESTART;
  81118. + goto errout;
  81119. + }
  81120. +
  81121. + pasemi_ring_add_desc(txring, &init_desc, NULL);
  81122. + pasemi_ring_add_desc(txring, &work_desc, crp);
  81123. +
  81124. + pasemi_ring_incr(sc, chsel,
  81125. + pasemi_desc_size(&init_desc) +
  81126. + pasemi_desc_size(&work_desc));
  81127. +
  81128. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  81129. +
  81130. + mod_timer(&txring->crypto_timer, jiffies + TIMER_INTERVAL);
  81131. +
  81132. + return 0;
  81133. +
  81134. +erralg:
  81135. + printk(DRV_NAME ": unsupported algorithm or algorithm order alg1 %d alg2 %d\n",
  81136. + crd1->crd_alg, crd2->crd_alg);
  81137. + err = -EINVAL;
  81138. +
  81139. +errout:
  81140. + if (err != ERESTART) {
  81141. + crp->crp_etype = err;
  81142. + crypto_done(crp);
  81143. + }
  81144. + return err;
  81145. +}
  81146. +
  81147. +static int pasemi_clean_tx(struct pasemi_softc *sc, int chan)
  81148. +{
  81149. + int i, j, ring_idx;
  81150. + struct pasemi_fnu_txring *ring = &sc->tx[chan];
  81151. + u16 delta_cnt;
  81152. + int flags, loops = 10;
  81153. + int desc_size;
  81154. + struct cryptop *crp;
  81155. +
  81156. + spin_lock_irqsave(&ring->clean_lock, flags);
  81157. +
  81158. + while ((delta_cnt = (dma_status->tx_sta[sc->base_chan + chan]
  81159. + & PAS_STATUS_PCNT_M) - ring->total_pktcnt)
  81160. + && loops--) {
  81161. +
  81162. + for (i = 0; i < delta_cnt; i++) {
  81163. + desc_size = TX_DESC_INFO(ring, ring->next_to_clean).desc_size;
  81164. + crp = TX_DESC_INFO(ring, ring->next_to_clean).cf_crp;
  81165. + if (crp) {
  81166. + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
  81167. + if (TX_DESC_INFO(ring, ring->next_to_clean).desc_postop & PASEMI_CHECK_SIG) {
  81168. + /* Need to make sure signature matched,
  81169. + * if not - return error */
  81170. + if (!(ring->desc[ring_idx + 1] & (1ULL << 63)))
  81171. + crp->crp_etype = -EINVAL;
  81172. + }
  81173. + crypto_done(TX_DESC_INFO(ring,
  81174. + ring->next_to_clean).cf_crp);
  81175. + TX_DESC_INFO(ring, ring->next_to_clean).cf_crp = NULL;
  81176. + pci_unmap_single(
  81177. + sc->dma_pdev,
  81178. + XCT_PTR_ADDR_LEN(ring->desc[ring_idx + 1]),
  81179. + PCI_DMA_TODEVICE);
  81180. +
  81181. + ring->desc[ring_idx] = ring->desc[ring_idx + 1] = 0;
  81182. +
  81183. + ring->next_to_clean++;
  81184. + for (j = 1; j < desc_size; j++) {
  81185. + ring_idx = 2 *
  81186. + (ring->next_to_clean &
  81187. + (TX_RING_SIZE-1));
  81188. + pci_unmap_single(
  81189. + sc->dma_pdev,
  81190. + XCT_PTR_ADDR_LEN(ring->desc[ring_idx]),
  81191. + PCI_DMA_TODEVICE);
  81192. + if (ring->desc[ring_idx + 1])
  81193. + pci_unmap_single(
  81194. + sc->dma_pdev,
  81195. + XCT_PTR_ADDR_LEN(
  81196. + ring->desc[
  81197. + ring_idx + 1]),
  81198. + PCI_DMA_TODEVICE);
  81199. + ring->desc[ring_idx] =
  81200. + ring->desc[ring_idx + 1] = 0;
  81201. + ring->next_to_clean++;
  81202. + }
  81203. + } else {
  81204. + for (j = 0; j < desc_size; j++) {
  81205. + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
  81206. + ring->desc[ring_idx] =
  81207. + ring->desc[ring_idx + 1] = 0;
  81208. + ring->next_to_clean++;
  81209. + }
  81210. + }
  81211. + }
  81212. +
  81213. + ring->total_pktcnt += delta_cnt;
  81214. + }
  81215. + spin_unlock_irqrestore(&ring->clean_lock, flags);
  81216. +
  81217. + return 0;
  81218. +}
  81219. +
  81220. +static void sweepup_tx(struct pasemi_softc *sc)
  81221. +{
  81222. + int i;
  81223. +
  81224. + for (i = 0; i < sc->sc_num_channels; i++)
  81225. + pasemi_clean_tx(sc, i);
  81226. +}
  81227. +
  81228. +static irqreturn_t pasemi_intr(int irq, void *arg, struct pt_regs *regs)
  81229. +{
  81230. + struct pasemi_softc *sc = arg;
  81231. + unsigned int reg;
  81232. + int chan = irq - sc->base_irq;
  81233. + int chan_index = sc->base_chan + chan;
  81234. + u64 stat = dma_status->tx_sta[chan_index];
  81235. +
  81236. + DPRINTF("%s()\n", __FUNCTION__);
  81237. +
  81238. + if (!(stat & PAS_STATUS_CAUSE_M))
  81239. + return IRQ_NONE;
  81240. +
  81241. + pasemi_clean_tx(sc, chan);
  81242. +
  81243. + stat = dma_status->tx_sta[chan_index];
  81244. +
  81245. + reg = PAS_IOB_DMA_TXCH_RESET_PINTC |
  81246. + PAS_IOB_DMA_TXCH_RESET_PCNT(sc->tx[chan].total_pktcnt);
  81247. +
  81248. + if (stat & PAS_STATUS_SOFT)
  81249. + reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
  81250. +
  81251. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), reg);
  81252. +
  81253. +
  81254. + return IRQ_HANDLED;
  81255. +}
  81256. +
  81257. +static int pasemi_dma_setup_tx_resources(struct pasemi_softc *sc, int chan)
  81258. +{
  81259. + u32 val;
  81260. + int chan_index = chan + sc->base_chan;
  81261. + int ret;
  81262. + struct pasemi_fnu_txring *ring;
  81263. +
  81264. + ring = &sc->tx[chan];
  81265. +
  81266. + spin_lock_init(&ring->fill_lock);
  81267. + spin_lock_init(&ring->clean_lock);
  81268. +
  81269. + ring->desc_info = kzalloc(sizeof(struct pasemi_desc_info) *
  81270. + TX_RING_SIZE, GFP_KERNEL);
  81271. + if (!ring->desc_info)
  81272. + return -ENOMEM;
  81273. +
  81274. + /* Allocate descriptors */
  81275. + ring->desc = dma_alloc_coherent(&sc->dma_pdev->dev,
  81276. + TX_RING_SIZE *
  81277. + 2 * sizeof(u64),
  81278. + &ring->dma, GFP_KERNEL);
  81279. + if (!ring->desc)
  81280. + return -ENOMEM;
  81281. +
  81282. + memset((void *) ring->desc, 0, TX_RING_SIZE * 2 * sizeof(u64));
  81283. +
  81284. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), 0x30);
  81285. +
  81286. + ring->total_pktcnt = 0;
  81287. +
  81288. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEL(chan_index),
  81289. + PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
  81290. +
  81291. + val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
  81292. + val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2);
  81293. +
  81294. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEU(chan_index), val);
  81295. +
  81296. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_CFG(chan_index),
  81297. + PAS_DMA_TXCHAN_CFG_TY_FUNC |
  81298. + PAS_DMA_TXCHAN_CFG_TATTR(chan) |
  81299. + PAS_DMA_TXCHAN_CFG_WT(2));
  81300. +
  81301. + /* enable tx channel */
  81302. + out_le32(sc->dma_regs +
  81303. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  81304. + PAS_DMA_TXCHAN_TCMDSTA_EN);
  81305. +
  81306. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_CFG(chan_index),
  81307. + PAS_IOB_DMA_TXCH_CFG_CNTTH(1000));
  81308. +
  81309. + ring->next_to_fill = 0;
  81310. + ring->next_to_clean = 0;
  81311. +
  81312. + snprintf(ring->irq_name, sizeof(ring->irq_name),
  81313. + "%s%d", "crypto", chan);
  81314. +
  81315. + ring->irq = irq_create_mapping(NULL, sc->base_irq + chan);
  81316. + ret = request_irq(ring->irq, (irq_handler_t)
  81317. + pasemi_intr, IRQF_DISABLED, ring->irq_name, sc);
  81318. + if (ret) {
  81319. + printk(KERN_ERR DRV_NAME ": failed to hook irq %d ret %d\n",
  81320. + ring->irq, ret);
  81321. + ring->irq = -1;
  81322. + return ret;
  81323. + }
  81324. +
  81325. + setup_timer(&ring->crypto_timer, (void *) sweepup_tx, (unsigned long) sc);
  81326. +
  81327. + return 0;
  81328. +}
  81329. +
  81330. +static device_method_t pasemi_methods = {
  81331. + /* crypto device methods */
  81332. + DEVMETHOD(cryptodev_newsession, pasemi_newsession),
  81333. + DEVMETHOD(cryptodev_freesession, pasemi_freesession),
  81334. + DEVMETHOD(cryptodev_process, pasemi_process),
  81335. +};
  81336. +
  81337. +/* Set up the crypto device structure, private data,
  81338. + * and anything else we need before we start */
  81339. +
  81340. +static int __devinit
  81341. +pasemi_dma_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  81342. +{
  81343. + struct pasemi_softc *sc;
  81344. + int ret, i;
  81345. +
  81346. + DPRINTF(KERN_ERR "%s()\n", __FUNCTION__);
  81347. +
  81348. + sc = kzalloc(sizeof(*sc), GFP_KERNEL);
  81349. + if (!sc)
  81350. + return -ENOMEM;
  81351. +
  81352. + softc_device_init(sc, DRV_NAME, 1, pasemi_methods);
  81353. +
  81354. + pci_set_drvdata(pdev, sc);
  81355. +
  81356. + spin_lock_init(&sc->sc_chnlock);
  81357. +
  81358. + sc->sc_sessions = (struct pasemi_session **)
  81359. + kzalloc(PASEMI_INITIAL_SESSIONS *
  81360. + sizeof(struct pasemi_session *), GFP_ATOMIC);
  81361. + if (sc->sc_sessions == NULL) {
  81362. + ret = -ENOMEM;
  81363. + goto out;
  81364. + }
  81365. +
  81366. + sc->sc_nsessions = PASEMI_INITIAL_SESSIONS;
  81367. + sc->sc_lastchn = 0;
  81368. + sc->base_irq = pdev->irq + 6;
  81369. + sc->base_chan = 6;
  81370. + sc->sc_cid = -1;
  81371. + sc->dma_pdev = pdev;
  81372. +
  81373. + sc->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
  81374. + if (!sc->iob_pdev) {
  81375. + dev_err(&pdev->dev, "Can't find I/O Bridge\n");
  81376. + ret = -ENODEV;
  81377. + goto out;
  81378. + }
  81379. +
  81380. + /* This is hardcoded and ugly, but we have some firmware versions
  81381. + * who don't provide the register space in the device tree. Luckily
  81382. + * they are at well-known locations so we can just do the math here.
  81383. + */
  81384. + sc->dma_regs =
  81385. + ioremap(0xe0000000 + (sc->dma_pdev->devfn << 12), 0x2000);
  81386. + sc->iob_regs =
  81387. + ioremap(0xe0000000 + (sc->iob_pdev->devfn << 12), 0x2000);
  81388. + if (!sc->dma_regs || !sc->iob_regs) {
  81389. + dev_err(&pdev->dev, "Can't map registers\n");
  81390. + ret = -ENODEV;
  81391. + goto out;
  81392. + }
  81393. +
  81394. + dma_status = __ioremap(0xfd800000, 0x1000, 0);
  81395. + if (!dma_status) {
  81396. + ret = -ENODEV;
  81397. + dev_err(&pdev->dev, "Can't map dmastatus space\n");
  81398. + goto out;
  81399. + }
  81400. +
  81401. + sc->tx = (struct pasemi_fnu_txring *)
  81402. + kzalloc(sizeof(struct pasemi_fnu_txring)
  81403. + * 8, GFP_KERNEL);
  81404. + if (!sc->tx) {
  81405. + ret = -ENOMEM;
  81406. + goto out;
  81407. + }
  81408. +
  81409. + /* Initialize the h/w */
  81410. + out_le32(sc->dma_regs + PAS_DMA_COM_CFG,
  81411. + (in_le32(sc->dma_regs + PAS_DMA_COM_CFG) |
  81412. + PAS_DMA_COM_CFG_FWF));
  81413. + out_le32(sc->dma_regs + PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
  81414. +
  81415. + for (i = 0; i < PASEMI_FNU_CHANNELS; i++) {
  81416. + sc->sc_num_channels++;
  81417. + ret = pasemi_dma_setup_tx_resources(sc, i);
  81418. + if (ret)
  81419. + goto out;
  81420. + }
  81421. +
  81422. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),
  81423. + CRYPTOCAP_F_HARDWARE);
  81424. + if (sc->sc_cid < 0) {
  81425. + printk(KERN_ERR DRV_NAME ": could not get crypto driver id\n");
  81426. + ret = -ENXIO;
  81427. + goto out;
  81428. + }
  81429. +
  81430. + /* register algorithms with the framework */
  81431. + printk(DRV_NAME ":");
  81432. +
  81433. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  81434. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  81435. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  81436. + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
  81437. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  81438. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  81439. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  81440. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  81441. +
  81442. + return 0;
  81443. +
  81444. +out:
  81445. + pasemi_dma_remove(pdev);
  81446. + return ret;
  81447. +}
  81448. +
  81449. +#define MAX_RETRIES 5000
  81450. +
  81451. +static void pasemi_free_tx_resources(struct pasemi_softc *sc, int chan)
  81452. +{
  81453. + struct pasemi_fnu_txring *ring = &sc->tx[chan];
  81454. + int chan_index = chan + sc->base_chan;
  81455. + int retries;
  81456. + u32 stat;
  81457. +
  81458. + /* Stop the channel */
  81459. + out_le32(sc->dma_regs +
  81460. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  81461. + PAS_DMA_TXCHAN_TCMDSTA_ST);
  81462. +
  81463. + for (retries = 0; retries < MAX_RETRIES; retries++) {
  81464. + stat = in_le32(sc->dma_regs +
  81465. + PAS_DMA_TXCHAN_TCMDSTA(chan_index));
  81466. + if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
  81467. + break;
  81468. + cond_resched();
  81469. + }
  81470. +
  81471. + if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
  81472. + dev_err(&sc->dma_pdev->dev, "Failed to stop tx channel %d\n",
  81473. + chan_index);
  81474. +
  81475. + /* Disable the channel */
  81476. + out_le32(sc->dma_regs +
  81477. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  81478. + 0);
  81479. +
  81480. + if (ring->desc_info)
  81481. + kfree((void *) ring->desc_info);
  81482. + if (ring->desc)
  81483. + dma_free_coherent(&sc->dma_pdev->dev,
  81484. + TX_RING_SIZE *
  81485. + 2 * sizeof(u64),
  81486. + (void *) ring->desc, ring->dma);
  81487. + if (ring->irq != -1)
  81488. + free_irq(ring->irq, sc);
  81489. +
  81490. + del_timer(&ring->crypto_timer);
  81491. +}
  81492. +
  81493. +static void __devexit pasemi_dma_remove(struct pci_dev *pdev)
  81494. +{
  81495. + struct pasemi_softc *sc = pci_get_drvdata(pdev);
  81496. + int i;
  81497. +
  81498. + DPRINTF("%s()\n", __FUNCTION__);
  81499. +
  81500. + if (sc->sc_cid >= 0) {
  81501. + crypto_unregister_all(sc->sc_cid);
  81502. + }
  81503. +
  81504. + if (sc->tx) {
  81505. + for (i = 0; i < sc->sc_num_channels; i++)
  81506. + pasemi_free_tx_resources(sc, i);
  81507. +
  81508. + kfree(sc->tx);
  81509. + }
  81510. + if (sc->sc_sessions) {
  81511. + for (i = 0; i < sc->sc_nsessions; i++)
  81512. + kfree(sc->sc_sessions[i]);
  81513. + kfree(sc->sc_sessions);
  81514. + }
  81515. + if (sc->iob_pdev)
  81516. + pci_dev_put(sc->iob_pdev);
  81517. + if (sc->dma_regs)
  81518. + iounmap(sc->dma_regs);
  81519. + if (sc->iob_regs)
  81520. + iounmap(sc->iob_regs);
  81521. + kfree(sc);
  81522. +}
  81523. +
  81524. +static struct pci_device_id pasemi_dma_pci_tbl[] = {
  81525. + { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa007) },
  81526. +};
  81527. +
  81528. +MODULE_DEVICE_TABLE(pci, pasemi_dma_pci_tbl);
  81529. +
  81530. +static struct pci_driver pasemi_dma_driver = {
  81531. + .name = "pasemi_dma",
  81532. + .id_table = pasemi_dma_pci_tbl,
  81533. + .probe = pasemi_dma_probe,
  81534. + .remove = __devexit_p(pasemi_dma_remove),
  81535. +};
  81536. +
  81537. +static void __exit pasemi_dma_cleanup_module(void)
  81538. +{
  81539. + pci_unregister_driver(&pasemi_dma_driver);
  81540. + __iounmap(dma_status);
  81541. + dma_status = NULL;
  81542. +}
  81543. +
  81544. +int pasemi_dma_init_module(void)
  81545. +{
  81546. + return pci_register_driver(&pasemi_dma_driver);
  81547. +}
  81548. +
  81549. +module_init(pasemi_dma_init_module);
  81550. +module_exit(pasemi_dma_cleanup_module);
  81551. +
  81552. +MODULE_LICENSE("Dual BSD/GPL");
  81553. +MODULE_AUTHOR("Egor Martovetsky egor@pasemi.com");
  81554. +MODULE_DESCRIPTION("OCF driver for PA Semi PWRficient DMA Crypto Engine");
  81555. diff -Nur linux-2.6.39.orig/crypto/ocf/pasemi/pasemi_fnu.h linux-2.6.39/crypto/ocf/pasemi/pasemi_fnu.h
  81556. --- linux-2.6.39.orig/crypto/ocf/pasemi/pasemi_fnu.h 1970-01-01 01:00:00.000000000 +0100
  81557. +++ linux-2.6.39/crypto/ocf/pasemi/pasemi_fnu.h 2011-07-31 11:32:02.853424126 +0200
  81558. @@ -0,0 +1,410 @@
  81559. +/*
  81560. + * Copyright (C) 2007 PA Semi, Inc
  81561. + *
  81562. + * Driver for the PA Semi PWRficient DMA Crypto Engine, soft state and
  81563. + * hardware register layouts.
  81564. + *
  81565. + * This program is free software; you can redistribute it and/or modify
  81566. + * it under the terms of the GNU General Public License version 2 as
  81567. + * published by the Free Software Foundation.
  81568. + *
  81569. + * This program is distributed in the hope that it will be useful,
  81570. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  81571. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  81572. + * GNU General Public License for more details.
  81573. + *
  81574. + * You should have received a copy of the GNU General Public License
  81575. + * along with this program; if not, write to the Free Software
  81576. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  81577. + */
  81578. +
  81579. +#ifndef PASEMI_FNU_H
  81580. +#define PASEMI_FNU_H
  81581. +
  81582. +#include <linux/spinlock.h>
  81583. +
  81584. +#define PASEMI_SESSION(sid) ((sid) & 0xffffffff)
  81585. +#define PASEMI_SID(sesn) ((sesn) & 0xffffffff)
  81586. +#define DPRINTF(a...) if (debug) { printk(DRV_NAME ": " a); }
  81587. +
  81588. +/* Must be a power of two */
  81589. +#define RX_RING_SIZE 512
  81590. +#define TX_RING_SIZE 512
  81591. +#define TX_DESC(ring, num) ((ring)->desc[2 * (num & (TX_RING_SIZE-1))])
  81592. +#define TX_DESC_INFO(ring, num) ((ring)->desc_info[(num) & (TX_RING_SIZE-1)])
  81593. +#define MAX_DESC_SIZE 8
  81594. +#define PASEMI_INITIAL_SESSIONS 10
  81595. +#define PASEMI_FNU_CHANNELS 8
  81596. +
  81597. +/* DMA descriptor */
  81598. +struct pasemi_desc {
  81599. + u64 quad[2*MAX_DESC_SIZE];
  81600. + int quad_cnt;
  81601. + int size;
  81602. + int postop;
  81603. +};
  81604. +
  81605. +/*
  81606. + * Holds per descriptor data
  81607. + */
  81608. +struct pasemi_desc_info {
  81609. + int desc_size;
  81610. + int desc_postop;
  81611. +#define PASEMI_CHECK_SIG 0x1
  81612. +
  81613. + struct cryptop *cf_crp;
  81614. +};
  81615. +
  81616. +/*
  81617. + * Holds per channel data
  81618. + */
  81619. +struct pasemi_fnu_txring {
  81620. + volatile u64 *desc;
  81621. + volatile struct
  81622. + pasemi_desc_info *desc_info;
  81623. + dma_addr_t dma;
  81624. + struct timer_list crypto_timer;
  81625. + spinlock_t fill_lock;
  81626. + spinlock_t clean_lock;
  81627. + unsigned int next_to_fill;
  81628. + unsigned int next_to_clean;
  81629. + u16 total_pktcnt;
  81630. + int irq;
  81631. + int sesn;
  81632. + char irq_name[10];
  81633. +};
  81634. +
  81635. +/*
  81636. + * Holds data specific to a single pasemi device.
  81637. + */
  81638. +struct pasemi_softc {
  81639. + softc_device_decl sc_cdev;
  81640. + struct pci_dev *dma_pdev; /* device backpointer */
  81641. + struct pci_dev *iob_pdev; /* device backpointer */
  81642. + void __iomem *dma_regs;
  81643. + void __iomem *iob_regs;
  81644. + int base_irq;
  81645. + int base_chan;
  81646. + int32_t sc_cid; /* crypto tag */
  81647. + int sc_nsessions;
  81648. + struct pasemi_session **sc_sessions;
  81649. + int sc_num_channels;/* number of crypto channels */
  81650. +
  81651. + /* pointer to the array of txring datastructures, one txring per channel */
  81652. + struct pasemi_fnu_txring *tx;
  81653. +
  81654. + /*
  81655. + * mutual exclusion for the channel scheduler
  81656. + */
  81657. + spinlock_t sc_chnlock;
  81658. + /* last channel used, for now use round-robin to allocate channels */
  81659. + int sc_lastchn;
  81660. +};
  81661. +
  81662. +struct pasemi_session {
  81663. + u64 civ[2];
  81664. + u64 keysz;
  81665. + u64 key[4];
  81666. + u64 ccmd;
  81667. + u64 hkey[4];
  81668. + u64 hseq;
  81669. + u64 giv[2];
  81670. + u64 hiv[4];
  81671. +
  81672. + int used;
  81673. + dma_addr_t dma_addr;
  81674. + int chan;
  81675. +};
  81676. +
  81677. +/* status register layout in IOB region, at 0xfd800000 */
  81678. +struct pasdma_status {
  81679. + u64 rx_sta[64];
  81680. + u64 tx_sta[20];
  81681. +};
  81682. +
  81683. +#define ALG_IS_CIPHER(alg) ((alg == CRYPTO_DES_CBC) || \
  81684. + (alg == CRYPTO_3DES_CBC) || \
  81685. + (alg == CRYPTO_AES_CBC) || \
  81686. + (alg == CRYPTO_ARC4) || \
  81687. + (alg == CRYPTO_NULL_CBC))
  81688. +
  81689. +#define ALG_IS_SIG(alg) ((alg == CRYPTO_MD5) || \
  81690. + (alg == CRYPTO_MD5_HMAC) || \
  81691. + (alg == CRYPTO_SHA1) || \
  81692. + (alg == CRYPTO_SHA1_HMAC) || \
  81693. + (alg == CRYPTO_NULL_HMAC))
  81694. +
  81695. +enum {
  81696. + PAS_DMA_COM_TXCMD = 0x100, /* Transmit Command Register */
  81697. + PAS_DMA_COM_TXSTA = 0x104, /* Transmit Status Register */
  81698. + PAS_DMA_COM_RXCMD = 0x108, /* Receive Command Register */
  81699. + PAS_DMA_COM_RXSTA = 0x10c, /* Receive Status Register */
  81700. + PAS_DMA_COM_CFG = 0x114, /* DMA Configuration Register */
  81701. +};
  81702. +
  81703. +/* All these registers live in the PCI configuration space for the DMA PCI
  81704. + * device. Use the normal PCI config access functions for them.
  81705. + */
  81706. +
  81707. +#define PAS_DMA_COM_CFG_FWF 0x18000000
  81708. +
  81709. +#define PAS_DMA_COM_TXCMD_EN 0x00000001 /* enable */
  81710. +#define PAS_DMA_COM_TXSTA_ACT 0x00000001 /* active */
  81711. +#define PAS_DMA_COM_RXCMD_EN 0x00000001 /* enable */
  81712. +#define PAS_DMA_COM_RXSTA_ACT 0x00000001 /* active */
  81713. +
  81714. +#define _PAS_DMA_TXCHAN_STRIDE 0x20 /* Size per channel */
  81715. +#define _PAS_DMA_TXCHAN_TCMDSTA 0x300 /* Command / Status */
  81716. +#define _PAS_DMA_TXCHAN_CFG 0x304 /* Configuration */
  81717. +#define _PAS_DMA_TXCHAN_DSCRBU 0x308 /* Descriptor BU Allocation */
  81718. +#define _PAS_DMA_TXCHAN_INCR 0x310 /* Descriptor increment */
  81719. +#define _PAS_DMA_TXCHAN_CNT 0x314 /* Descriptor count/offset */
  81720. +#define _PAS_DMA_TXCHAN_BASEL 0x318 /* Descriptor ring base (low) */
  81721. +#define _PAS_DMA_TXCHAN_BASEU 0x31c /* (high) */
  81722. +#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE)
  81723. +#define PAS_DMA_TXCHAN_TCMDSTA_EN 0x00000001 /* Enabled */
  81724. +#define PAS_DMA_TXCHAN_TCMDSTA_ST 0x00000002 /* Stop interface */
  81725. +#define PAS_DMA_TXCHAN_TCMDSTA_ACT 0x00010000 /* Active */
  81726. +#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
  81727. +#define PAS_DMA_TXCHAN_CFG_TY_FUNC 0x00000002 /* Type = interface */
  81728. +#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */
  81729. +#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c
  81730. +#define PAS_DMA_TXCHAN_CFG_TATTR_S 2
  81731. +#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
  81732. + PAS_DMA_TXCHAN_CFG_TATTR_M)
  81733. +#define PAS_DMA_TXCHAN_CFG_WT_M 0x000001c0
  81734. +#define PAS_DMA_TXCHAN_CFG_WT_S 6
  81735. +#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
  81736. + PAS_DMA_TXCHAN_CFG_WT_M)
  81737. +#define PAS_DMA_TXCHAN_CFG_LPSQ_FAST 0x00000400
  81738. +#define PAS_DMA_TXCHAN_CFG_LPDQ_FAST 0x00000800
  81739. +#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */
  81740. +#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */
  81741. +#define PAS_DMA_TXCHAN_CFG_UP 0x00004000 /* update tx descr when sent */
  81742. +#define PAS_DMA_TXCHAN_INCR(c) (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
  81743. +#define PAS_DMA_TXCHAN_BASEL(c) (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
  81744. +#define PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0
  81745. +#define PAS_DMA_TXCHAN_BASEL_BRBL_S 0
  81746. +#define PAS_DMA_TXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \
  81747. + PAS_DMA_TXCHAN_BASEL_BRBL_M)
  81748. +#define PAS_DMA_TXCHAN_BASEU(c) (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE)
  81749. +#define PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff
  81750. +#define PAS_DMA_TXCHAN_BASEU_BRBH_S 0
  81751. +#define PAS_DMA_TXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \
  81752. + PAS_DMA_TXCHAN_BASEU_BRBH_M)
  81753. +/* # of cache lines worth of buffer ring */
  81754. +#define PAS_DMA_TXCHAN_BASEU_SIZ_M 0x3fff0000
  81755. +#define PAS_DMA_TXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */
  81756. +#define PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \
  81757. + PAS_DMA_TXCHAN_BASEU_SIZ_M)
  81758. +
  81759. +#define PAS_STATUS_PCNT_M 0x000000000000ffffull
  81760. +#define PAS_STATUS_PCNT_S 0
  81761. +#define PAS_STATUS_DCNT_M 0x00000000ffff0000ull
  81762. +#define PAS_STATUS_DCNT_S 16
  81763. +#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull
  81764. +#define PAS_STATUS_BPCNT_S 32
  81765. +#define PAS_STATUS_CAUSE_M 0xf000000000000000ull
  81766. +#define PAS_STATUS_TIMER 0x1000000000000000ull
  81767. +#define PAS_STATUS_ERROR 0x2000000000000000ull
  81768. +#define PAS_STATUS_SOFT 0x4000000000000000ull
  81769. +#define PAS_STATUS_INT 0x8000000000000000ull
  81770. +
  81771. +#define PAS_IOB_DMA_RXCH_CFG(i) (0x1100 + (i)*4)
  81772. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_M 0x00000fff
  81773. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_S 0
  81774. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \
  81775. + PAS_IOB_DMA_RXCH_CFG_CNTTH_M)
  81776. +#define PAS_IOB_DMA_TXCH_CFG(i) (0x1200 + (i)*4)
  81777. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_M 0x00000fff
  81778. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_S 0
  81779. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \
  81780. + PAS_IOB_DMA_TXCH_CFG_CNTTH_M)
  81781. +#define PAS_IOB_DMA_RXCH_STAT(i) (0x1300 + (i)*4)
  81782. +#define PAS_IOB_DMA_RXCH_STAT_INTGEN 0x00001000
  81783. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_M 0x00000fff
  81784. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_S 0
  81785. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\
  81786. + PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
  81787. +#define PAS_IOB_DMA_TXCH_STAT(i) (0x1400 + (i)*4)
  81788. +#define PAS_IOB_DMA_TXCH_STAT_INTGEN 0x00001000
  81789. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_M 0x00000fff
  81790. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_S 0
  81791. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\
  81792. + PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
  81793. +#define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4)
  81794. +#define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000
  81795. +#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 16
  81796. +#define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \
  81797. + PAS_IOB_DMA_RXCH_RESET_PCNT_M)
  81798. +#define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020
  81799. +#define PAS_IOB_DMA_RXCH_RESET_DCNTRST 0x00000010
  81800. +#define PAS_IOB_DMA_RXCH_RESET_TINTC 0x00000008
  81801. +#define PAS_IOB_DMA_RXCH_RESET_DINTC 0x00000004
  81802. +#define PAS_IOB_DMA_RXCH_RESET_SINTC 0x00000002
  81803. +#define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001
  81804. +#define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4)
  81805. +#define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000
  81806. +#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 16
  81807. +#define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \
  81808. + PAS_IOB_DMA_TXCH_RESET_PCNT_M)
  81809. +#define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020
  81810. +#define PAS_IOB_DMA_TXCH_RESET_DCNTRST 0x00000010
  81811. +#define PAS_IOB_DMA_TXCH_RESET_TINTC 0x00000008
  81812. +#define PAS_IOB_DMA_TXCH_RESET_DINTC 0x00000004
  81813. +#define PAS_IOB_DMA_TXCH_RESET_SINTC 0x00000002
  81814. +#define PAS_IOB_DMA_TXCH_RESET_PINTC 0x00000001
  81815. +
  81816. +#define PAS_IOB_DMA_COM_TIMEOUTCFG 0x1700
  81817. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M 0x00ffffff
  81818. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S 0
  81819. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x) (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \
  81820. + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M)
  81821. +
  81822. +/* Transmit descriptor fields */
  81823. +#define XCT_MACTX_T 0x8000000000000000ull
  81824. +#define XCT_MACTX_ST 0x4000000000000000ull
  81825. +#define XCT_MACTX_NORES 0x0000000000000000ull
  81826. +#define XCT_MACTX_8BRES 0x1000000000000000ull
  81827. +#define XCT_MACTX_24BRES 0x2000000000000000ull
  81828. +#define XCT_MACTX_40BRES 0x3000000000000000ull
  81829. +#define XCT_MACTX_I 0x0800000000000000ull
  81830. +#define XCT_MACTX_O 0x0400000000000000ull
  81831. +#define XCT_MACTX_E 0x0200000000000000ull
  81832. +#define XCT_MACTX_VLAN_M 0x0180000000000000ull
  81833. +#define XCT_MACTX_VLAN_NOP 0x0000000000000000ull
  81834. +#define XCT_MACTX_VLAN_REMOVE 0x0080000000000000ull
  81835. +#define XCT_MACTX_VLAN_INSERT 0x0100000000000000ull
  81836. +#define XCT_MACTX_VLAN_REPLACE 0x0180000000000000ull
  81837. +#define XCT_MACTX_CRC_M 0x0060000000000000ull
  81838. +#define XCT_MACTX_CRC_NOP 0x0000000000000000ull
  81839. +#define XCT_MACTX_CRC_INSERT 0x0020000000000000ull
  81840. +#define XCT_MACTX_CRC_PAD 0x0040000000000000ull
  81841. +#define XCT_MACTX_CRC_REPLACE 0x0060000000000000ull
  81842. +#define XCT_MACTX_SS 0x0010000000000000ull
  81843. +#define XCT_MACTX_LLEN_M 0x00007fff00000000ull
  81844. +#define XCT_MACTX_LLEN_S 32ull
  81845. +#define XCT_MACTX_LLEN(x) ((((long)(x)) << XCT_MACTX_LLEN_S) & \
  81846. + XCT_MACTX_LLEN_M)
  81847. +#define XCT_MACTX_IPH_M 0x00000000f8000000ull
  81848. +#define XCT_MACTX_IPH_S 27ull
  81849. +#define XCT_MACTX_IPH(x) ((((long)(x)) << XCT_MACTX_IPH_S) & \
  81850. + XCT_MACTX_IPH_M)
  81851. +#define XCT_MACTX_IPO_M 0x0000000007c00000ull
  81852. +#define XCT_MACTX_IPO_S 22ull
  81853. +#define XCT_MACTX_IPO(x) ((((long)(x)) << XCT_MACTX_IPO_S) & \
  81854. + XCT_MACTX_IPO_M)
  81855. +#define XCT_MACTX_CSUM_M 0x0000000000000060ull
  81856. +#define XCT_MACTX_CSUM_NOP 0x0000000000000000ull
  81857. +#define XCT_MACTX_CSUM_TCP 0x0000000000000040ull
  81858. +#define XCT_MACTX_CSUM_UDP 0x0000000000000060ull
  81859. +#define XCT_MACTX_V6 0x0000000000000010ull
  81860. +#define XCT_MACTX_C 0x0000000000000004ull
  81861. +#define XCT_MACTX_AL2 0x0000000000000002ull
  81862. +
  81863. +#define XCT_PTR_T 0x8000000000000000ull
  81864. +#define XCT_PTR_LEN_M 0x7ffff00000000000ull
  81865. +#define XCT_PTR_LEN_S 44
  81866. +#define XCT_PTR_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & \
  81867. + XCT_PTR_LEN_M)
  81868. +#define XCT_PTR_ADDR_M 0x00000fffffffffffull
  81869. +#define XCT_PTR_ADDR_S 0
  81870. +#define XCT_PTR_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & \
  81871. + XCT_PTR_ADDR_M)
  81872. +
  81873. +/* Function descriptor fields */
  81874. +#define XCT_FUN_T 0x8000000000000000ull
  81875. +#define XCT_FUN_ST 0x4000000000000000ull
  81876. +#define XCT_FUN_NORES 0x0000000000000000ull
  81877. +#define XCT_FUN_8BRES 0x1000000000000000ull
  81878. +#define XCT_FUN_24BRES 0x2000000000000000ull
  81879. +#define XCT_FUN_40BRES 0x3000000000000000ull
  81880. +#define XCT_FUN_I 0x0800000000000000ull
  81881. +#define XCT_FUN_O 0x0400000000000000ull
  81882. +#define XCT_FUN_E 0x0200000000000000ull
  81883. +#define XCT_FUN_FUN_S 54
  81884. +#define XCT_FUN_FUN_M 0x01c0000000000000ull
  81885. +#define XCT_FUN_FUN(num) ((((long)(num)) << XCT_FUN_FUN_S) & \
  81886. + XCT_FUN_FUN_M)
  81887. +#define XCT_FUN_CRM_NOP 0x0000000000000000ull
  81888. +#define XCT_FUN_CRM_SIG 0x0008000000000000ull
  81889. +#define XCT_FUN_CRM_ENC 0x0010000000000000ull
  81890. +#define XCT_FUN_CRM_DEC 0x0018000000000000ull
  81891. +#define XCT_FUN_CRM_SIG_ENC 0x0020000000000000ull
  81892. +#define XCT_FUN_CRM_ENC_SIG 0x0028000000000000ull
  81893. +#define XCT_FUN_CRM_SIG_DEC 0x0030000000000000ull
  81894. +#define XCT_FUN_CRM_DEC_SIG 0x0038000000000000ull
  81895. +#define XCT_FUN_LLEN_M 0x0007ffff00000000ull
  81896. +#define XCT_FUN_LLEN_S 32ULL
  81897. +#define XCT_FUN_LLEN(x) ((((long)(x)) << XCT_FUN_LLEN_S) & \
  81898. + XCT_FUN_LLEN_M)
  81899. +#define XCT_FUN_SHL_M 0x00000000f8000000ull
  81900. +#define XCT_FUN_SHL_S 27ull
  81901. +#define XCT_FUN_SHL(x) ((((long)(x)) << XCT_FUN_SHL_S) & \
  81902. + XCT_FUN_SHL_M)
  81903. +#define XCT_FUN_CHL_M 0x0000000007c00000ull
  81904. +#define XCT_FUN_CHL_S 22ull
  81905. +#define XCT_FUN_CHL(x) ((((long)(x)) << XCT_FUN_CHL_S) & \
  81906. + XCT_FUN_CHL_M)
  81907. +#define XCT_FUN_HSZ_M 0x00000000003c0000ull
  81908. +#define XCT_FUN_HSZ_S 18ull
  81909. +#define XCT_FUN_HSZ(x) ((((long)(x)) << XCT_FUN_HSZ_S) & \
  81910. + XCT_FUN_HSZ_M)
  81911. +#define XCT_FUN_ALG_DES 0x0000000000000000ull
  81912. +#define XCT_FUN_ALG_3DES 0x0000000000008000ull
  81913. +#define XCT_FUN_ALG_AES 0x0000000000010000ull
  81914. +#define XCT_FUN_ALG_ARC 0x0000000000018000ull
  81915. +#define XCT_FUN_ALG_KASUMI 0x0000000000020000ull
  81916. +#define XCT_FUN_BCM_ECB 0x0000000000000000ull
  81917. +#define XCT_FUN_BCM_CBC 0x0000000000001000ull
  81918. +#define XCT_FUN_BCM_CFB 0x0000000000002000ull
  81919. +#define XCT_FUN_BCM_OFB 0x0000000000003000ull
  81920. +#define XCT_FUN_BCM_CNT 0x0000000000003800ull
  81921. +#define XCT_FUN_BCM_KAS_F8 0x0000000000002800ull
  81922. +#define XCT_FUN_BCM_KAS_F9 0x0000000000001800ull
  81923. +#define XCT_FUN_BCP_NO_PAD 0x0000000000000000ull
  81924. +#define XCT_FUN_BCP_ZRO 0x0000000000000200ull
  81925. +#define XCT_FUN_BCP_PL 0x0000000000000400ull
  81926. +#define XCT_FUN_BCP_INCR 0x0000000000000600ull
  81927. +#define XCT_FUN_SIG_MD5 (0ull << 4)
  81928. +#define XCT_FUN_SIG_SHA1 (2ull << 4)
  81929. +#define XCT_FUN_SIG_HMAC_MD5 (8ull << 4)
  81930. +#define XCT_FUN_SIG_HMAC_SHA1 (10ull << 4)
  81931. +#define XCT_FUN_A 0x0000000000000008ull
  81932. +#define XCT_FUN_C 0x0000000000000004ull
  81933. +#define XCT_FUN_AL2 0x0000000000000002ull
  81934. +#define XCT_FUN_SE 0x0000000000000001ull
  81935. +
  81936. +#define XCT_FUN_SRC_PTR(len, addr) (XCT_PTR_LEN(len) | XCT_PTR_ADDR(addr))
  81937. +#define XCT_FUN_DST_PTR(len, addr) (XCT_FUN_SRC_PTR(len, addr) | \
  81938. + 0x8000000000000000ull)
  81939. +
  81940. +#define XCT_CTRL_HDR_FUN_NUM_M 0x01c0000000000000ull
  81941. +#define XCT_CTRL_HDR_FUN_NUM_S 54
  81942. +#define XCT_CTRL_HDR_LEN_M 0x0007ffff00000000ull
  81943. +#define XCT_CTRL_HDR_LEN_S 32
  81944. +#define XCT_CTRL_HDR_REG_M 0x00000000000000ffull
  81945. +#define XCT_CTRL_HDR_REG_S 0
  81946. +
  81947. +#define XCT_CTRL_HDR(funcN,len,reg) (0x9400000000000000ull | \
  81948. + ((((long)(funcN)) << XCT_CTRL_HDR_FUN_NUM_S) \
  81949. + & XCT_CTRL_HDR_FUN_NUM_M) | \
  81950. + ((((long)(len)) << \
  81951. + XCT_CTRL_HDR_LEN_S) & XCT_CTRL_HDR_LEN_M) | \
  81952. + ((((long)(reg)) << \
  81953. + XCT_CTRL_HDR_REG_S) & XCT_CTRL_HDR_REG_M))
  81954. +
  81955. +/* Function config command options */
  81956. +#define DMA_CALGO_DES 0x00
  81957. +#define DMA_CALGO_3DES 0x01
  81958. +#define DMA_CALGO_AES 0x02
  81959. +#define DMA_CALGO_ARC 0x03
  81960. +
  81961. +#define DMA_FN_CIV0 0x02
  81962. +#define DMA_FN_CIV1 0x03
  81963. +#define DMA_FN_HKEY0 0x0a
  81964. +
  81965. +#define XCT_PTR_ADDR_LEN(ptr) ((ptr) & XCT_PTR_ADDR_M), \
  81966. + (((ptr) & XCT_PTR_LEN_M) >> XCT_PTR_LEN_S)
  81967. +
  81968. +#endif /* PASEMI_FNU_H */
  81969. diff -Nur linux-2.6.39.orig/crypto/ocf/random.c linux-2.6.39/crypto/ocf/random.c
  81970. --- linux-2.6.39.orig/crypto/ocf/random.c 1970-01-01 01:00:00.000000000 +0100
  81971. +++ linux-2.6.39/crypto/ocf/random.c 2011-07-31 11:32:02.893424809 +0200
  81972. @@ -0,0 +1,322 @@
  81973. +/*
  81974. + * A system independant way of adding entropy to the kernels pool
  81975. + * this way the drivers can focus on the real work and we can take
  81976. + * care of pushing it to the appropriate place in the kernel.
  81977. + *
  81978. + * This should be fast and callable from timers/interrupts
  81979. + *
  81980. + * Written by David McCullough <david_mccullough@mcafee.com>
  81981. + * Copyright (C) 2006-2010 David McCullough
  81982. + * Copyright (C) 2004-2005 Intel Corporation.
  81983. + *
  81984. + * LICENSE TERMS
  81985. + *
  81986. + * The free distribution and use of this software in both source and binary
  81987. + * form is allowed (with or without changes) provided that:
  81988. + *
  81989. + * 1. distributions of this source code include the above copyright
  81990. + * notice, this list of conditions and the following disclaimer;
  81991. + *
  81992. + * 2. distributions in binary form include the above copyright
  81993. + * notice, this list of conditions and the following disclaimer
  81994. + * in the documentation and/or other associated materials;
  81995. + *
  81996. + * 3. the copyright holder's name is not used to endorse products
  81997. + * built using this software without specific written permission.
  81998. + *
  81999. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  82000. + * may be distributed under the terms of the GNU General Public License (GPL),
  82001. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  82002. + *
  82003. + * DISCLAIMER
  82004. + *
  82005. + * This software is provided 'as is' with no explicit or implied warranties
  82006. + * in respect of its properties, including, but not limited to, correctness
  82007. + * and/or fitness for purpose.
  82008. + */
  82009. +
  82010. +#ifndef AUTOCONF_INCLUDED
  82011. +#include <linux/config.h>
  82012. +#endif
  82013. +#include <linux/module.h>
  82014. +#include <linux/init.h>
  82015. +#include <linux/list.h>
  82016. +#include <linux/slab.h>
  82017. +#include <linux/wait.h>
  82018. +#include <linux/sched.h>
  82019. +#include <linux/spinlock.h>
  82020. +#include <linux/version.h>
  82021. +#include <linux/unistd.h>
  82022. +#include <linux/poll.h>
  82023. +#include <linux/random.h>
  82024. +#include <cryptodev.h>
  82025. +
  82026. +#ifdef CONFIG_OCF_FIPS
  82027. +#include "rndtest.h"
  82028. +#endif
  82029. +
  82030. +#ifndef HAS_RANDOM_INPUT_WAIT
  82031. +#error "Please do not enable OCF_RANDOMHARVEST unless you have applied patches"
  82032. +#endif
  82033. +
  82034. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
  82035. +#include <linux/sched.h>
  82036. +#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
  82037. +#endif
  82038. +
  82039. +/*
  82040. + * a hack to access the debug levels from the crypto driver
  82041. + */
  82042. +extern int crypto_debug;
  82043. +#define debug crypto_debug
  82044. +
  82045. +/*
  82046. + * a list of all registered random providers
  82047. + */
  82048. +static LIST_HEAD(random_ops);
  82049. +static int started = 0;
  82050. +static int initted = 0;
  82051. +
  82052. +struct random_op {
  82053. + struct list_head random_list;
  82054. + u_int32_t driverid;
  82055. + int (*read_random)(void *arg, u_int32_t *buf, int len);
  82056. + void *arg;
  82057. +};
  82058. +
  82059. +static int random_proc(void *arg);
  82060. +
  82061. +static pid_t randomproc = (pid_t) -1;
  82062. +static spinlock_t random_lock;
  82063. +
  82064. +/*
  82065. + * just init the spin locks
  82066. + */
  82067. +static int
  82068. +crypto_random_init(void)
  82069. +{
  82070. + spin_lock_init(&random_lock);
  82071. + initted = 1;
  82072. + return(0);
  82073. +}
  82074. +
  82075. +/*
  82076. + * Add the given random reader to our list (if not present)
  82077. + * and start the thread (if not already started)
  82078. + *
  82079. + * we have to assume that driver id is ok for now
  82080. + */
  82081. +int
  82082. +crypto_rregister(
  82083. + u_int32_t driverid,
  82084. + int (*read_random)(void *arg, u_int32_t *buf, int len),
  82085. + void *arg)
  82086. +{
  82087. + unsigned long flags;
  82088. + int ret = 0;
  82089. + struct random_op *rops, *tmp;
  82090. +
  82091. + dprintk("%s,%d: %s(0x%x, %p, %p)\n", __FILE__, __LINE__,
  82092. + __FUNCTION__, driverid, read_random, arg);
  82093. +
  82094. + if (!initted)
  82095. + crypto_random_init();
  82096. +
  82097. +#if 0
  82098. + struct cryptocap *cap;
  82099. +
  82100. + cap = crypto_checkdriver(driverid);
  82101. + if (!cap)
  82102. + return EINVAL;
  82103. +#endif
  82104. +
  82105. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  82106. + if (rops->driverid == driverid && rops->read_random == read_random)
  82107. + return EEXIST;
  82108. + }
  82109. +
  82110. + rops = (struct random_op *) kmalloc(sizeof(*rops), GFP_KERNEL);
  82111. + if (!rops)
  82112. + return ENOMEM;
  82113. +
  82114. + rops->driverid = driverid;
  82115. + rops->read_random = read_random;
  82116. + rops->arg = arg;
  82117. +
  82118. + spin_lock_irqsave(&random_lock, flags);
  82119. + list_add_tail(&rops->random_list, &random_ops);
  82120. + if (!started) {
  82121. + randomproc = kernel_thread(random_proc, NULL, CLONE_FS|CLONE_FILES);
  82122. + if (randomproc < 0) {
  82123. + ret = randomproc;
  82124. + printk("crypto: crypto_rregister cannot start random thread; "
  82125. + "error %d", ret);
  82126. + } else
  82127. + started = 1;
  82128. + }
  82129. + spin_unlock_irqrestore(&random_lock, flags);
  82130. +
  82131. + return ret;
  82132. +}
  82133. +EXPORT_SYMBOL(crypto_rregister);
  82134. +
  82135. +int
  82136. +crypto_runregister_all(u_int32_t driverid)
  82137. +{
  82138. + struct random_op *rops, *tmp;
  82139. + unsigned long flags;
  82140. +
  82141. + dprintk("%s,%d: %s(0x%x)\n", __FILE__, __LINE__, __FUNCTION__, driverid);
  82142. +
  82143. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  82144. + if (rops->driverid == driverid) {
  82145. + list_del(&rops->random_list);
  82146. + kfree(rops);
  82147. + }
  82148. + }
  82149. +
  82150. + spin_lock_irqsave(&random_lock, flags);
  82151. + if (list_empty(&random_ops) && started)
  82152. + kill_proc(randomproc, SIGKILL, 1);
  82153. + spin_unlock_irqrestore(&random_lock, flags);
  82154. + return(0);
  82155. +}
  82156. +EXPORT_SYMBOL(crypto_runregister_all);
  82157. +
  82158. +/*
  82159. + * while we can add entropy to random.c continue to read random data from
  82160. + * the drivers and push it to random.
  82161. + */
  82162. +static int
  82163. +random_proc(void *arg)
  82164. +{
  82165. + int n;
  82166. + int wantcnt;
  82167. + int bufcnt = 0;
  82168. + int retval = 0;
  82169. + int *buf = NULL;
  82170. +
  82171. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  82172. + daemonize();
  82173. + spin_lock_irq(&current->sigmask_lock);
  82174. + sigemptyset(&current->blocked);
  82175. + recalc_sigpending(current);
  82176. + spin_unlock_irq(&current->sigmask_lock);
  82177. + sprintf(current->comm, "ocf-random");
  82178. +#else
  82179. + daemonize("ocf-random");
  82180. + allow_signal(SIGKILL);
  82181. +#endif
  82182. +
  82183. + (void) get_fs();
  82184. + set_fs(get_ds());
  82185. +
  82186. +#ifdef CONFIG_OCF_FIPS
  82187. +#define NUM_INT (RNDTEST_NBYTES/sizeof(int))
  82188. +#else
  82189. +#define NUM_INT 32
  82190. +#endif
  82191. +
  82192. + /*
  82193. + * some devices can transferr their RNG data direct into memory,
  82194. + * so make sure it is device friendly
  82195. + */
  82196. + buf = kmalloc(NUM_INT * sizeof(int), GFP_DMA);
  82197. + if (NULL == buf) {
  82198. + printk("crypto: RNG could not allocate memory\n");
  82199. + retval = -ENOMEM;
  82200. + goto bad_alloc;
  82201. + }
  82202. +
  82203. + wantcnt = NUM_INT; /* start by adding some entropy */
  82204. +
  82205. + /*
  82206. + * its possible due to errors or driver removal that we no longer
  82207. + * have anything to do, if so exit or we will consume all the CPU
  82208. + * doing nothing
  82209. + */
  82210. + while (!list_empty(&random_ops)) {
  82211. + struct random_op *rops, *tmp;
  82212. +
  82213. +#ifdef CONFIG_OCF_FIPS
  82214. + if (wantcnt)
  82215. + wantcnt = NUM_INT; /* FIPs mode can do 20000 bits or none */
  82216. +#endif
  82217. +
  82218. + /* see if we can get enough entropy to make the world
  82219. + * a better place.
  82220. + */
  82221. + while (bufcnt < wantcnt && bufcnt < NUM_INT) {
  82222. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  82223. +
  82224. + n = (*rops->read_random)(rops->arg, &buf[bufcnt],
  82225. + NUM_INT - bufcnt);
  82226. +
  82227. + /* on failure remove the random number generator */
  82228. + if (n == -1) {
  82229. + list_del(&rops->random_list);
  82230. + printk("crypto: RNG (driverid=0x%x) failed, disabling\n",
  82231. + rops->driverid);
  82232. + kfree(rops);
  82233. + } else if (n > 0)
  82234. + bufcnt += n;
  82235. + }
  82236. + /* give up CPU for a bit, just in case as this is a loop */
  82237. + schedule();
  82238. + }
  82239. +
  82240. +
  82241. +#ifdef CONFIG_OCF_FIPS
  82242. + if (bufcnt > 0 && rndtest_buf((unsigned char *) &buf[0])) {
  82243. + dprintk("crypto: buffer had fips errors, discarding\n");
  82244. + bufcnt = 0;
  82245. + }
  82246. +#endif
  82247. +
  82248. + /*
  82249. + * if we have a certified buffer, we can send some data
  82250. + * to /dev/random and move along
  82251. + */
  82252. + if (bufcnt > 0) {
  82253. + /* add what we have */
  82254. + random_input_words(buf, bufcnt, bufcnt*sizeof(int)*8);
  82255. + bufcnt = 0;
  82256. + }
  82257. +
  82258. + /* give up CPU for a bit so we don't hog while filling */
  82259. + schedule();
  82260. +
  82261. + /* wait for needing more */
  82262. + wantcnt = random_input_wait();
  82263. +
  82264. + if (wantcnt <= 0)
  82265. + wantcnt = 0; /* try to get some info again */
  82266. + else
  82267. + /* round up to one word or we can loop forever */
  82268. + wantcnt = (wantcnt + (sizeof(int)*8)) / (sizeof(int)*8);
  82269. + if (wantcnt > NUM_INT) {
  82270. + wantcnt = NUM_INT;
  82271. + }
  82272. +
  82273. + if (signal_pending(current)) {
  82274. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  82275. + spin_lock_irq(&current->sigmask_lock);
  82276. +#endif
  82277. + flush_signals(current);
  82278. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  82279. + spin_unlock_irq(&current->sigmask_lock);
  82280. +#endif
  82281. + }
  82282. + }
  82283. +
  82284. + kfree(buf);
  82285. +
  82286. +bad_alloc:
  82287. + spin_lock_irq(&random_lock);
  82288. + randomproc = (pid_t) -1;
  82289. + started = 0;
  82290. + spin_unlock_irq(&random_lock);
  82291. +
  82292. + return retval;
  82293. +}
  82294. +
  82295. diff -Nur linux-2.6.39.orig/crypto/ocf/README linux-2.6.39/crypto/ocf/README
  82296. --- linux-2.6.39.orig/crypto/ocf/README 1970-01-01 01:00:00.000000000 +0100
  82297. +++ linux-2.6.39/crypto/ocf/README 2011-07-31 11:32:02.943424379 +0200
  82298. @@ -0,0 +1,167 @@
  82299. +README - ocf-linux-20100325
  82300. +---------------------------
  82301. +
  82302. +This README provides instructions for getting ocf-linux compiled and
  82303. +operating in a generic linux environment. For other information you
  82304. +might like to visit the home page for this project:
  82305. +
  82306. + http://ocf-linux.sourceforge.net/
  82307. +
  82308. +Adding OCF to linux
  82309. +-------------------
  82310. +
  82311. + Not much in this file for now, just some notes. I usually build
  82312. + the ocf support as modules but it can be built into the kernel as
  82313. + well. To use it:
  82314. +
  82315. + * mknod /dev/crypto c 10 70
  82316. +
  82317. + * to add OCF to your kernel source, you have two options. Apply
  82318. + the kernel specific patch:
  82319. +
  82320. + cd linux-2.4*; gunzip < ocf-linux-24-XXXXXXXX.patch.gz | patch -p1
  82321. + cd linux-2.6*; gunzip < ocf-linux-26-XXXXXXXX.patch.gz | patch -p1
  82322. +
  82323. + if you do one of the above, then you can proceed to the next step,
  82324. + or you can do the above process by hand with using the patches against
  82325. + linux-2.4.35 and 2.6.33 to include the ocf code under crypto/ocf.
  82326. + Here's how to add it:
  82327. +
  82328. + for 2.4.35 (and later)
  82329. +
  82330. + cd linux-2.4.35/crypto
  82331. + tar xvzf ocf-linux.tar.gz
  82332. + cd ..
  82333. + patch -p1 < crypto/ocf/patches/linux-2.4.35-ocf.patch
  82334. +
  82335. + for 2.6.23 (and later), find the kernel patch specific (or nearest)
  82336. + to your kernel versions and then:
  82337. +
  82338. + cd linux-2.6.NN/crypto
  82339. + tar xvzf ocf-linux.tar.gz
  82340. + cd ..
  82341. + patch -p1 < crypto/ocf/patches/linux-2.6.NN-ocf.patch
  82342. +
  82343. + It should be easy to take this patch and apply it to other more
  82344. + recent versions of the kernels. The same patches should also work
  82345. + relatively easily on kernels as old as 2.6.11 and 2.4.18.
  82346. +
  82347. + * under 2.4 if you are on a non-x86 platform, you may need to:
  82348. +
  82349. + cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY
  82350. +
  82351. + so that you can build the kernel crypto support needed for the cryptosoft
  82352. + driver.
  82353. +
  82354. + * For simplicity you should enable all the crypto support in your kernel
  82355. + except for the test driver. Likewise for the OCF options. Do not
  82356. + enable OCF crypto drivers for HW that you do not have (for example
  82357. + ixp4xx will not compile on non-Xscale systems).
  82358. +
  82359. + * make sure that cryptodev.h (from ocf-linux.tar.gz) is installed as
  82360. + crypto/cryptodev.h in an include directory that is used for building
  82361. + applications for your platform. For example on a host system that
  82362. + might be:
  82363. +
  82364. + /usr/include/crypto/cryptodev.h
  82365. +
  82366. + * patch your openssl-0.9.8n code with the openssl-0.9.8n.patch.
  82367. + (NOTE: there is no longer a need to patch ssh). The patch is against:
  82368. + openssl-0_9_8e
  82369. +
  82370. + If you need a patch for an older version of openssl, you should look
  82371. + to older OCF releases. This patch is unlikely to work on older
  82372. + openssl versions.
  82373. +
  82374. + openssl-0.9.8n.patch
  82375. + - enables --with-cryptodev for non BSD systems
  82376. + - adds -cpu option to openssl speed for calculating CPU load
  82377. + under linux
  82378. + - fixes null pointer in openssl speed multi thread output.
  82379. + - fixes test keys to work with linux crypto's more stringent
  82380. + key checking.
  82381. + - adds MD5/SHA acceleration (Ronen Shitrit), only enabled
  82382. + with the --with-cryptodev-digests option
  82383. + - fixes bug in engine code caching.
  82384. +
  82385. + * build crypto-tools-XXXXXXXX.tar.gz if you want to try some of the BSD
  82386. + tools for testing OCF (ie., cryptotest).
  82387. +
  82388. +How to load the OCF drivers
  82389. +---------------------------
  82390. +
  82391. + First insert the base modules:
  82392. +
  82393. + insmod ocf
  82394. + insmod cryptodev
  82395. +
  82396. + You can then install the software OCF driver with:
  82397. +
  82398. + insmod cryptosoft
  82399. +
  82400. + and one or more of the OCF HW drivers with:
  82401. +
  82402. + insmod safe
  82403. + insmod hifn7751
  82404. + insmod ixp4xx
  82405. + ...
  82406. +
  82407. + all the drivers take a debug option to enable verbose debug so that
  82408. + you can see what is going on. For debug you load them as:
  82409. +
  82410. + insmod ocf crypto_debug=1
  82411. + insmod cryptodev cryptodev_debug=1
  82412. + insmod cryptosoft swcr_debug=1
  82413. +
  82414. + You may load more than one OCF crypto driver but then there is no guarantee
  82415. + as to which will be used.
  82416. +
  82417. + You can also enable debug at run time on 2.6 systems with the following:
  82418. +
  82419. + echo 1 > /sys/module/ocf/parameters/crypto_debug
  82420. + echo 1 > /sys/module/cryptodev/parameters/cryptodev_debug
  82421. + echo 1 > /sys/module/cryptosoft/parameters/swcr_debug
  82422. + echo 1 > /sys/module/hifn7751/parameters/hifn_debug
  82423. + echo 1 > /sys/module/safe/parameters/safe_debug
  82424. + echo 1 > /sys/module/ixp4xx/parameters/ixp_debug
  82425. + ...
  82426. +
  82427. +Testing the OCF support
  82428. +-----------------------
  82429. +
  82430. + run "cryptotest", it should do a short test for a couple of
  82431. + des packets. If it does everything is working.
  82432. +
  82433. + If this works, then ssh will use the driver when invoked as:
  82434. +
  82435. + ssh -c 3des username@host
  82436. +
  82437. + to see for sure that it is operating, enable debug as defined above.
  82438. +
  82439. + To get a better idea of performance run:
  82440. +
  82441. + cryptotest 100 4096
  82442. +
  82443. + There are more options to cryptotest, see the help.
  82444. +
  82445. + It is also possible to use openssl to test the speed of the crypto
  82446. + drivers.
  82447. +
  82448. + openssl speed -evp des -engine cryptodev -elapsed
  82449. + openssl speed -evp des3 -engine cryptodev -elapsed
  82450. + openssl speed -evp aes128 -engine cryptodev -elapsed
  82451. +
  82452. + and multiple threads (10) with:
  82453. +
  82454. + openssl speed -evp des -engine cryptodev -elapsed -multi 10
  82455. + openssl speed -evp des3 -engine cryptodev -elapsed -multi 10
  82456. + openssl speed -evp aes128 -engine cryptodev -elapsed -multi 10
  82457. +
  82458. + for public key testing you can try:
  82459. +
  82460. + cryptokeytest
  82461. + openssl speed -engine cryptodev rsa -elapsed
  82462. + openssl speed -engine cryptodev dsa -elapsed
  82463. +
  82464. +David McCullough
  82465. +david_mccullough@mcafee.com
  82466. diff -Nur linux-2.6.39.orig/crypto/ocf/rndtest.c linux-2.6.39/crypto/ocf/rndtest.c
  82467. --- linux-2.6.39.orig/crypto/ocf/rndtest.c 1970-01-01 01:00:00.000000000 +0100
  82468. +++ linux-2.6.39/crypto/ocf/rndtest.c 2011-07-31 11:32:03.003418121 +0200
  82469. @@ -0,0 +1,300 @@
  82470. +/* $OpenBSD$ */
  82471. +
  82472. +/*
  82473. + * OCF/Linux port done by David McCullough <david_mccullough@mcafee.com>
  82474. + * Copyright (C) 2006-2010 David McCullough
  82475. + * Copyright (C) 2004-2005 Intel Corporation.
  82476. + * The license and original author are listed below.
  82477. + *
  82478. + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
  82479. + * All rights reserved.
  82480. + *
  82481. + * Redistribution and use in source and binary forms, with or without
  82482. + * modification, are permitted provided that the following conditions
  82483. + * are met:
  82484. + * 1. Redistributions of source code must retain the above copyright
  82485. + * notice, this list of conditions and the following disclaimer.
  82486. + * 2. Redistributions in binary form must reproduce the above copyright
  82487. + * notice, this list of conditions and the following disclaimer in the
  82488. + * documentation and/or other materials provided with the distribution.
  82489. + * 3. All advertising materials mentioning features or use of this software
  82490. + * must display the following acknowledgement:
  82491. + * This product includes software developed by Jason L. Wright
  82492. + * 4. The name of the author may not be used to endorse or promote products
  82493. + * derived from this software without specific prior written permission.
  82494. + *
  82495. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  82496. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  82497. + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  82498. + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  82499. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  82500. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  82501. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  82502. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  82503. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  82504. + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  82505. + * POSSIBILITY OF SUCH DAMAGE.
  82506. + */
  82507. +
  82508. +#ifndef AUTOCONF_INCLUDED
  82509. +#include <linux/config.h>
  82510. +#endif
  82511. +#include <linux/module.h>
  82512. +#include <linux/list.h>
  82513. +#include <linux/wait.h>
  82514. +#include <linux/time.h>
  82515. +#include <linux/version.h>
  82516. +#include <linux/unistd.h>
  82517. +#include <linux/kernel.h>
  82518. +#include <linux/string.h>
  82519. +#include <linux/time.h>
  82520. +#include <cryptodev.h>
  82521. +#include "rndtest.h"
  82522. +
  82523. +static struct rndtest_stats rndstats;
  82524. +
  82525. +static void rndtest_test(struct rndtest_state *);
  82526. +
  82527. +/* The tests themselves */
  82528. +static int rndtest_monobit(struct rndtest_state *);
  82529. +static int rndtest_runs(struct rndtest_state *);
  82530. +static int rndtest_longruns(struct rndtest_state *);
  82531. +static int rndtest_chi_4(struct rndtest_state *);
  82532. +
  82533. +static int rndtest_runs_check(struct rndtest_state *, int, int *);
  82534. +static void rndtest_runs_record(struct rndtest_state *, int, int *);
  82535. +
  82536. +static const struct rndtest_testfunc {
  82537. + int (*test)(struct rndtest_state *);
  82538. +} rndtest_funcs[] = {
  82539. + { rndtest_monobit },
  82540. + { rndtest_runs },
  82541. + { rndtest_chi_4 },
  82542. + { rndtest_longruns },
  82543. +};
  82544. +
  82545. +#define RNDTEST_NTESTS (sizeof(rndtest_funcs)/sizeof(rndtest_funcs[0]))
  82546. +
  82547. +static void
  82548. +rndtest_test(struct rndtest_state *rsp)
  82549. +{
  82550. + int i, rv = 0;
  82551. +
  82552. + rndstats.rst_tests++;
  82553. + for (i = 0; i < RNDTEST_NTESTS; i++)
  82554. + rv |= (*rndtest_funcs[i].test)(rsp);
  82555. + rsp->rs_discard = (rv != 0);
  82556. +}
  82557. +
  82558. +
  82559. +extern int crypto_debug;
  82560. +#define rndtest_verbose 2
  82561. +#define rndtest_report(rsp, failure, fmt, a...) \
  82562. + { if (failure || crypto_debug) { printk("rng_test: " fmt "\n", a); } else; }
  82563. +
  82564. +#define RNDTEST_MONOBIT_MINONES 9725
  82565. +#define RNDTEST_MONOBIT_MAXONES 10275
  82566. +
  82567. +static int
  82568. +rndtest_monobit(struct rndtest_state *rsp)
  82569. +{
  82570. + int i, ones = 0, j;
  82571. + u_int8_t r;
  82572. +
  82573. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  82574. + r = rsp->rs_buf[i];
  82575. + for (j = 0; j < 8; j++, r <<= 1)
  82576. + if (r & 0x80)
  82577. + ones++;
  82578. + }
  82579. + if (ones > RNDTEST_MONOBIT_MINONES &&
  82580. + ones < RNDTEST_MONOBIT_MAXONES) {
  82581. + if (rndtest_verbose > 1)
  82582. + rndtest_report(rsp, 0, "monobit pass (%d < %d < %d)",
  82583. + RNDTEST_MONOBIT_MINONES, ones,
  82584. + RNDTEST_MONOBIT_MAXONES);
  82585. + return (0);
  82586. + } else {
  82587. + if (rndtest_verbose)
  82588. + rndtest_report(rsp, 1,
  82589. + "monobit failed (%d ones)", ones);
  82590. + rndstats.rst_monobit++;
  82591. + return (-1);
  82592. + }
  82593. +}
  82594. +
  82595. +#define RNDTEST_RUNS_NINTERVAL 6
  82596. +
  82597. +static const struct rndtest_runs_tabs {
  82598. + u_int16_t min, max;
  82599. +} rndtest_runs_tab[] = {
  82600. + { 2343, 2657 },
  82601. + { 1135, 1365 },
  82602. + { 542, 708 },
  82603. + { 251, 373 },
  82604. + { 111, 201 },
  82605. + { 111, 201 },
  82606. +};
  82607. +
  82608. +static int
  82609. +rndtest_runs(struct rndtest_state *rsp)
  82610. +{
  82611. + int i, j, ones, zeros, rv = 0;
  82612. + int onei[RNDTEST_RUNS_NINTERVAL], zeroi[RNDTEST_RUNS_NINTERVAL];
  82613. + u_int8_t c;
  82614. +
  82615. + bzero(onei, sizeof(onei));
  82616. + bzero(zeroi, sizeof(zeroi));
  82617. + ones = zeros = 0;
  82618. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  82619. + c = rsp->rs_buf[i];
  82620. + for (j = 0; j < 8; j++, c <<= 1) {
  82621. + if (c & 0x80) {
  82622. + ones++;
  82623. + rndtest_runs_record(rsp, zeros, zeroi);
  82624. + zeros = 0;
  82625. + } else {
  82626. + zeros++;
  82627. + rndtest_runs_record(rsp, ones, onei);
  82628. + ones = 0;
  82629. + }
  82630. + }
  82631. + }
  82632. + rndtest_runs_record(rsp, ones, onei);
  82633. + rndtest_runs_record(rsp, zeros, zeroi);
  82634. +
  82635. + rv |= rndtest_runs_check(rsp, 0, zeroi);
  82636. + rv |= rndtest_runs_check(rsp, 1, onei);
  82637. +
  82638. + if (rv)
  82639. + rndstats.rst_runs++;
  82640. +
  82641. + return (rv);
  82642. +}
  82643. +
  82644. +static void
  82645. +rndtest_runs_record(struct rndtest_state *rsp, int len, int *intrv)
  82646. +{
  82647. + if (len == 0)
  82648. + return;
  82649. + if (len > RNDTEST_RUNS_NINTERVAL)
  82650. + len = RNDTEST_RUNS_NINTERVAL;
  82651. + len -= 1;
  82652. + intrv[len]++;
  82653. +}
  82654. +
  82655. +static int
  82656. +rndtest_runs_check(struct rndtest_state *rsp, int val, int *src)
  82657. +{
  82658. + int i, rv = 0;
  82659. +
  82660. + for (i = 0; i < RNDTEST_RUNS_NINTERVAL; i++) {
  82661. + if (src[i] < rndtest_runs_tab[i].min ||
  82662. + src[i] > rndtest_runs_tab[i].max) {
  82663. + rndtest_report(rsp, 1,
  82664. + "%s interval %d failed (%d, %d-%d)",
  82665. + val ? "ones" : "zeros",
  82666. + i + 1, src[i], rndtest_runs_tab[i].min,
  82667. + rndtest_runs_tab[i].max);
  82668. + rv = -1;
  82669. + } else {
  82670. + rndtest_report(rsp, 0,
  82671. + "runs pass %s interval %d (%d < %d < %d)",
  82672. + val ? "ones" : "zeros",
  82673. + i + 1, rndtest_runs_tab[i].min, src[i],
  82674. + rndtest_runs_tab[i].max);
  82675. + }
  82676. + }
  82677. + return (rv);
  82678. +}
  82679. +
  82680. +static int
  82681. +rndtest_longruns(struct rndtest_state *rsp)
  82682. +{
  82683. + int i, j, ones = 0, zeros = 0, maxones = 0, maxzeros = 0;
  82684. + u_int8_t c;
  82685. +
  82686. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  82687. + c = rsp->rs_buf[i];
  82688. + for (j = 0; j < 8; j++, c <<= 1) {
  82689. + if (c & 0x80) {
  82690. + zeros = 0;
  82691. + ones++;
  82692. + if (ones > maxones)
  82693. + maxones = ones;
  82694. + } else {
  82695. + ones = 0;
  82696. + zeros++;
  82697. + if (zeros > maxzeros)
  82698. + maxzeros = zeros;
  82699. + }
  82700. + }
  82701. + }
  82702. +
  82703. + if (maxones < 26 && maxzeros < 26) {
  82704. + rndtest_report(rsp, 0, "longruns pass (%d ones, %d zeros)",
  82705. + maxones, maxzeros);
  82706. + return (0);
  82707. + } else {
  82708. + rndtest_report(rsp, 1, "longruns fail (%d ones, %d zeros)",
  82709. + maxones, maxzeros);
  82710. + rndstats.rst_longruns++;
  82711. + return (-1);
  82712. + }
  82713. +}
  82714. +
  82715. +/*
  82716. + * chi^2 test over 4 bits: (this is called the poker test in FIPS 140-2,
  82717. + * but it is really the chi^2 test over 4 bits (the poker test as described
  82718. + * by Knuth vol 2 is something different, and I take him as authoritative
  82719. + * on nomenclature over NIST).
  82720. + */
  82721. +#define RNDTEST_CHI4_K 16
  82722. +#define RNDTEST_CHI4_K_MASK (RNDTEST_CHI4_K - 1)
  82723. +
  82724. +/*
  82725. + * The unnormalized values are used so that we don't have to worry about
  82726. + * fractional precision. The "real" value is found by:
  82727. + * (V - 1562500) * (16 / 5000) = Vn (where V is the unnormalized value)
  82728. + */
  82729. +#define RNDTEST_CHI4_VMIN 1563181 /* 2.1792 */
  82730. +#define RNDTEST_CHI4_VMAX 1576929 /* 46.1728 */
  82731. +
  82732. +static int
  82733. +rndtest_chi_4(struct rndtest_state *rsp)
  82734. +{
  82735. + unsigned int freq[RNDTEST_CHI4_K], i, sum;
  82736. +
  82737. + for (i = 0; i < RNDTEST_CHI4_K; i++)
  82738. + freq[i] = 0;
  82739. +
  82740. + /* Get number of occurances of each 4 bit pattern */
  82741. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  82742. + freq[(rsp->rs_buf[i] >> 4) & RNDTEST_CHI4_K_MASK]++;
  82743. + freq[(rsp->rs_buf[i] >> 0) & RNDTEST_CHI4_K_MASK]++;
  82744. + }
  82745. +
  82746. + for (i = 0, sum = 0; i < RNDTEST_CHI4_K; i++)
  82747. + sum += freq[i] * freq[i];
  82748. +
  82749. + if (sum >= 1563181 && sum <= 1576929) {
  82750. + rndtest_report(rsp, 0, "chi^2(4): pass (sum %u)", sum);
  82751. + return (0);
  82752. + } else {
  82753. + rndtest_report(rsp, 1, "chi^2(4): failed (sum %u)", sum);
  82754. + rndstats.rst_chi++;
  82755. + return (-1);
  82756. + }
  82757. +}
  82758. +
  82759. +int
  82760. +rndtest_buf(unsigned char *buf)
  82761. +{
  82762. + struct rndtest_state rsp;
  82763. +
  82764. + memset(&rsp, 0, sizeof(rsp));
  82765. + rsp.rs_buf = buf;
  82766. + rndtest_test(&rsp);
  82767. + return(rsp.rs_discard);
  82768. +}
  82769. +
  82770. diff -Nur linux-2.6.39.orig/crypto/ocf/rndtest.h linux-2.6.39/crypto/ocf/rndtest.h
  82771. --- linux-2.6.39.orig/crypto/ocf/rndtest.h 1970-01-01 01:00:00.000000000 +0100
  82772. +++ linux-2.6.39/crypto/ocf/rndtest.h 2011-07-31 11:32:03.053424638 +0200
  82773. @@ -0,0 +1,54 @@
  82774. +/* $FreeBSD: src/sys/dev/rndtest/rndtest.h,v 1.1 2003/03/11 22:54:44 sam Exp $ */
  82775. +/* $OpenBSD$ */
  82776. +
  82777. +/*
  82778. + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
  82779. + * All rights reserved.
  82780. + *
  82781. + * Redistribution and use in source and binary forms, with or without
  82782. + * modification, are permitted provided that the following conditions
  82783. + * are met:
  82784. + * 1. Redistributions of source code must retain the above copyright
  82785. + * notice, this list of conditions and the following disclaimer.
  82786. + * 2. Redistributions in binary form must reproduce the above copyright
  82787. + * notice, this list of conditions and the following disclaimer in the
  82788. + * documentation and/or other materials provided with the distribution.
  82789. + * 3. All advertising materials mentioning features or use of this software
  82790. + * must display the following acknowledgement:
  82791. + * This product includes software developed by Jason L. Wright
  82792. + * 4. The name of the author may not be used to endorse or promote products
  82793. + * derived from this software without specific prior written permission.
  82794. + *
  82795. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  82796. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  82797. + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  82798. + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  82799. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  82800. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  82801. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  82802. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  82803. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  82804. + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  82805. + * POSSIBILITY OF SUCH DAMAGE.
  82806. + */
  82807. +
  82808. +
  82809. +/* Some of the tests depend on these values */
  82810. +#define RNDTEST_NBYTES 2500
  82811. +#define RNDTEST_NBITS (8 * RNDTEST_NBYTES)
  82812. +
  82813. +struct rndtest_state {
  82814. + int rs_discard; /* discard/accept random data */
  82815. + u_int8_t *rs_buf;
  82816. +};
  82817. +
  82818. +struct rndtest_stats {
  82819. + u_int32_t rst_discard; /* number of bytes discarded */
  82820. + u_int32_t rst_tests; /* number of test runs */
  82821. + u_int32_t rst_monobit; /* monobit test failures */
  82822. + u_int32_t rst_runs; /* 0/1 runs failures */
  82823. + u_int32_t rst_longruns; /* longruns failures */
  82824. + u_int32_t rst_chi; /* chi^2 failures */
  82825. +};
  82826. +
  82827. +extern int rndtest_buf(unsigned char *buf);
  82828. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/Makefile linux-2.6.39/crypto/ocf/safe/Makefile
  82829. --- linux-2.6.39.orig/crypto/ocf/safe/Makefile 1970-01-01 01:00:00.000000000 +0100
  82830. +++ linux-2.6.39/crypto/ocf/safe/Makefile 2011-07-31 11:32:03.103415819 +0200
  82831. @@ -0,0 +1,12 @@
  82832. +# for SGlinux builds
  82833. +-include $(ROOTDIR)/modules/.config
  82834. +
  82835. +obj-$(CONFIG_OCF_SAFE) += safe.o
  82836. +
  82837. +obj ?= .
  82838. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  82839. +
  82840. +ifdef TOPDIR
  82841. +-include $(TOPDIR)/Rules.make
  82842. +endif
  82843. +
  82844. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/md5.c linux-2.6.39/crypto/ocf/safe/md5.c
  82845. --- linux-2.6.39.orig/crypto/ocf/safe/md5.c 1970-01-01 01:00:00.000000000 +0100
  82846. +++ linux-2.6.39/crypto/ocf/safe/md5.c 2011-07-31 11:32:03.133424181 +0200
  82847. @@ -0,0 +1,308 @@
  82848. +/* $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
  82849. +/*
  82850. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  82851. + * All rights reserved.
  82852. + *
  82853. + * Redistribution and use in source and binary forms, with or without
  82854. + * modification, are permitted provided that the following conditions
  82855. + * are met:
  82856. + * 1. Redistributions of source code must retain the above copyright
  82857. + * notice, this list of conditions and the following disclaimer.
  82858. + * 2. Redistributions in binary form must reproduce the above copyright
  82859. + * notice, this list of conditions and the following disclaimer in the
  82860. + * documentation and/or other materials provided with the distribution.
  82861. + * 3. Neither the name of the project nor the names of its contributors
  82862. + * may be used to endorse or promote products derived from this software
  82863. + * without specific prior written permission.
  82864. + *
  82865. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  82866. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  82867. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  82868. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  82869. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  82870. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  82871. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  82872. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  82873. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  82874. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  82875. + * SUCH DAMAGE.
  82876. + */
  82877. +
  82878. +#if 0
  82879. +#include <sys/cdefs.h>
  82880. +__FBSDID("$FreeBSD: src/sys/crypto/md5.c,v 1.9 2004/01/27 19:49:19 des Exp $");
  82881. +
  82882. +#include <sys/types.h>
  82883. +#include <sys/cdefs.h>
  82884. +#include <sys/time.h>
  82885. +#include <sys/systm.h>
  82886. +#include <crypto/md5.h>
  82887. +#endif
  82888. +
  82889. +#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
  82890. +
  82891. +#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
  82892. +#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
  82893. +#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
  82894. +#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
  82895. +
  82896. +#define ROUND1(a, b, c, d, k, s, i) { \
  82897. + (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
  82898. + (a) = SHIFT((a), (s)); \
  82899. + (a) = (b) + (a); \
  82900. +}
  82901. +
  82902. +#define ROUND2(a, b, c, d, k, s, i) { \
  82903. + (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
  82904. + (a) = SHIFT((a), (s)); \
  82905. + (a) = (b) + (a); \
  82906. +}
  82907. +
  82908. +#define ROUND3(a, b, c, d, k, s, i) { \
  82909. + (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
  82910. + (a) = SHIFT((a), (s)); \
  82911. + (a) = (b) + (a); \
  82912. +}
  82913. +
  82914. +#define ROUND4(a, b, c, d, k, s, i) { \
  82915. + (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
  82916. + (a) = SHIFT((a), (s)); \
  82917. + (a) = (b) + (a); \
  82918. +}
  82919. +
  82920. +#define Sa 7
  82921. +#define Sb 12
  82922. +#define Sc 17
  82923. +#define Sd 22
  82924. +
  82925. +#define Se 5
  82926. +#define Sf 9
  82927. +#define Sg 14
  82928. +#define Sh 20
  82929. +
  82930. +#define Si 4
  82931. +#define Sj 11
  82932. +#define Sk 16
  82933. +#define Sl 23
  82934. +
  82935. +#define Sm 6
  82936. +#define Sn 10
  82937. +#define So 15
  82938. +#define Sp 21
  82939. +
  82940. +#define MD5_A0 0x67452301
  82941. +#define MD5_B0 0xefcdab89
  82942. +#define MD5_C0 0x98badcfe
  82943. +#define MD5_D0 0x10325476
  82944. +
  82945. +/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
  82946. +static const u_int32_t T[65] = {
  82947. + 0,
  82948. + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
  82949. + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
  82950. + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
  82951. + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
  82952. +
  82953. + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
  82954. + 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
  82955. + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
  82956. + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
  82957. +
  82958. + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
  82959. + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
  82960. + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
  82961. + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
  82962. +
  82963. + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
  82964. + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
  82965. + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
  82966. + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
  82967. +};
  82968. +
  82969. +static const u_int8_t md5_paddat[MD5_BUFLEN] = {
  82970. + 0x80, 0, 0, 0, 0, 0, 0, 0,
  82971. + 0, 0, 0, 0, 0, 0, 0, 0,
  82972. + 0, 0, 0, 0, 0, 0, 0, 0,
  82973. + 0, 0, 0, 0, 0, 0, 0, 0,
  82974. + 0, 0, 0, 0, 0, 0, 0, 0,
  82975. + 0, 0, 0, 0, 0, 0, 0, 0,
  82976. + 0, 0, 0, 0, 0, 0, 0, 0,
  82977. + 0, 0, 0, 0, 0, 0, 0, 0,
  82978. +};
  82979. +
  82980. +static void md5_calc(u_int8_t *, md5_ctxt *);
  82981. +
  82982. +void md5_init(ctxt)
  82983. + md5_ctxt *ctxt;
  82984. +{
  82985. + ctxt->md5_n = 0;
  82986. + ctxt->md5_i = 0;
  82987. + ctxt->md5_sta = MD5_A0;
  82988. + ctxt->md5_stb = MD5_B0;
  82989. + ctxt->md5_stc = MD5_C0;
  82990. + ctxt->md5_std = MD5_D0;
  82991. + bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
  82992. +}
  82993. +
  82994. +void md5_loop(ctxt, input, len)
  82995. + md5_ctxt *ctxt;
  82996. + u_int8_t *input;
  82997. + u_int len; /* number of bytes */
  82998. +{
  82999. + u_int gap, i;
  83000. +
  83001. + ctxt->md5_n += len * 8; /* byte to bit */
  83002. + gap = MD5_BUFLEN - ctxt->md5_i;
  83003. +
  83004. + if (len >= gap) {
  83005. + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  83006. + gap);
  83007. + md5_calc(ctxt->md5_buf, ctxt);
  83008. +
  83009. + for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
  83010. + md5_calc((u_int8_t *)(input + i), ctxt);
  83011. + }
  83012. +
  83013. + ctxt->md5_i = len - i;
  83014. + bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
  83015. + } else {
  83016. + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  83017. + len);
  83018. + ctxt->md5_i += len;
  83019. + }
  83020. +}
  83021. +
  83022. +void md5_pad(ctxt)
  83023. + md5_ctxt *ctxt;
  83024. +{
  83025. + u_int gap;
  83026. +
  83027. + /* Don't count up padding. Keep md5_n. */
  83028. + gap = MD5_BUFLEN - ctxt->md5_i;
  83029. + if (gap > 8) {
  83030. + bcopy(md5_paddat,
  83031. + (void *)(ctxt->md5_buf + ctxt->md5_i),
  83032. + gap - sizeof(ctxt->md5_n));
  83033. + } else {
  83034. + /* including gap == 8 */
  83035. + bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
  83036. + gap);
  83037. + md5_calc(ctxt->md5_buf, ctxt);
  83038. + bcopy((md5_paddat + gap),
  83039. + (void *)ctxt->md5_buf,
  83040. + MD5_BUFLEN - sizeof(ctxt->md5_n));
  83041. + }
  83042. +
  83043. + /* 8 byte word */
  83044. +#if BYTE_ORDER == LITTLE_ENDIAN
  83045. + bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
  83046. +#endif
  83047. +#if BYTE_ORDER == BIG_ENDIAN
  83048. + ctxt->md5_buf[56] = ctxt->md5_n8[7];
  83049. + ctxt->md5_buf[57] = ctxt->md5_n8[6];
  83050. + ctxt->md5_buf[58] = ctxt->md5_n8[5];
  83051. + ctxt->md5_buf[59] = ctxt->md5_n8[4];
  83052. + ctxt->md5_buf[60] = ctxt->md5_n8[3];
  83053. + ctxt->md5_buf[61] = ctxt->md5_n8[2];
  83054. + ctxt->md5_buf[62] = ctxt->md5_n8[1];
  83055. + ctxt->md5_buf[63] = ctxt->md5_n8[0];
  83056. +#endif
  83057. +
  83058. + md5_calc(ctxt->md5_buf, ctxt);
  83059. +}
  83060. +
  83061. +void md5_result(digest, ctxt)
  83062. + u_int8_t *digest;
  83063. + md5_ctxt *ctxt;
  83064. +{
  83065. + /* 4 byte words */
  83066. +#if BYTE_ORDER == LITTLE_ENDIAN
  83067. + bcopy(&ctxt->md5_st8[0], digest, 16);
  83068. +#endif
  83069. +#if BYTE_ORDER == BIG_ENDIAN
  83070. + digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
  83071. + digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
  83072. + digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
  83073. + digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
  83074. + digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
  83075. + digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
  83076. + digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
  83077. + digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
  83078. +#endif
  83079. +}
  83080. +
  83081. +static void md5_calc(b64, ctxt)
  83082. + u_int8_t *b64;
  83083. + md5_ctxt *ctxt;
  83084. +{
  83085. + u_int32_t A = ctxt->md5_sta;
  83086. + u_int32_t B = ctxt->md5_stb;
  83087. + u_int32_t C = ctxt->md5_stc;
  83088. + u_int32_t D = ctxt->md5_std;
  83089. +#if BYTE_ORDER == LITTLE_ENDIAN
  83090. + u_int32_t *X = (u_int32_t *)b64;
  83091. +#endif
  83092. +#if BYTE_ORDER == BIG_ENDIAN
  83093. + /* 4 byte words */
  83094. + /* what a brute force but fast! */
  83095. + u_int32_t X[16];
  83096. + u_int8_t *y = (u_int8_t *)X;
  83097. + y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
  83098. + y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
  83099. + y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
  83100. + y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
  83101. + y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
  83102. + y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
  83103. + y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
  83104. + y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
  83105. + y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
  83106. + y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
  83107. + y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
  83108. + y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
  83109. + y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
  83110. + y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
  83111. + y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
  83112. + y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
  83113. +#endif
  83114. +
  83115. + ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
  83116. + ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
  83117. + ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
  83118. + ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
  83119. + ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
  83120. + ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
  83121. + ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
  83122. + ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
  83123. +
  83124. + ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
  83125. + ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
  83126. + ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
  83127. + ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
  83128. + ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
  83129. + ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
  83130. + ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
  83131. + ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
  83132. +
  83133. + ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
  83134. + ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
  83135. + ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
  83136. + ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
  83137. + ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
  83138. + ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
  83139. + ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
  83140. + ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
  83141. +
  83142. + ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
  83143. + ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
  83144. + ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
  83145. + ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
  83146. + ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
  83147. + ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
  83148. + ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
  83149. + ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
  83150. +
  83151. + ctxt->md5_sta += A;
  83152. + ctxt->md5_stb += B;
  83153. + ctxt->md5_stc += C;
  83154. + ctxt->md5_std += D;
  83155. +}
  83156. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/md5.h linux-2.6.39/crypto/ocf/safe/md5.h
  83157. --- linux-2.6.39.orig/crypto/ocf/safe/md5.h 1970-01-01 01:00:00.000000000 +0100
  83158. +++ linux-2.6.39/crypto/ocf/safe/md5.h 2011-07-31 11:32:03.193425406 +0200
  83159. @@ -0,0 +1,76 @@
  83160. +/* $FreeBSD: src/sys/crypto/md5.h,v 1.4 2002/03/20 05:13:50 alfred Exp $ */
  83161. +/* $KAME: md5.h,v 1.4 2000/03/27 04:36:22 sumikawa Exp $ */
  83162. +
  83163. +/*
  83164. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  83165. + * All rights reserved.
  83166. + *
  83167. + * Redistribution and use in source and binary forms, with or without
  83168. + * modification, are permitted provided that the following conditions
  83169. + * are met:
  83170. + * 1. Redistributions of source code must retain the above copyright
  83171. + * notice, this list of conditions and the following disclaimer.
  83172. + * 2. Redistributions in binary form must reproduce the above copyright
  83173. + * notice, this list of conditions and the following disclaimer in the
  83174. + * documentation and/or other materials provided with the distribution.
  83175. + * 3. Neither the name of the project nor the names of its contributors
  83176. + * may be used to endorse or promote products derived from this software
  83177. + * without specific prior written permission.
  83178. + *
  83179. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  83180. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  83181. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  83182. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  83183. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  83184. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  83185. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  83186. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  83187. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  83188. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  83189. + * SUCH DAMAGE.
  83190. + */
  83191. +
  83192. +#ifndef _NETINET6_MD5_H_
  83193. +#define _NETINET6_MD5_H_
  83194. +
  83195. +#define MD5_BUFLEN 64
  83196. +
  83197. +typedef struct {
  83198. + union {
  83199. + u_int32_t md5_state32[4];
  83200. + u_int8_t md5_state8[16];
  83201. + } md5_st;
  83202. +
  83203. +#define md5_sta md5_st.md5_state32[0]
  83204. +#define md5_stb md5_st.md5_state32[1]
  83205. +#define md5_stc md5_st.md5_state32[2]
  83206. +#define md5_std md5_st.md5_state32[3]
  83207. +#define md5_st8 md5_st.md5_state8
  83208. +
  83209. + union {
  83210. + u_int64_t md5_count64;
  83211. + u_int8_t md5_count8[8];
  83212. + } md5_count;
  83213. +#define md5_n md5_count.md5_count64
  83214. +#define md5_n8 md5_count.md5_count8
  83215. +
  83216. + u_int md5_i;
  83217. + u_int8_t md5_buf[MD5_BUFLEN];
  83218. +} md5_ctxt;
  83219. +
  83220. +extern void md5_init(md5_ctxt *);
  83221. +extern void md5_loop(md5_ctxt *, u_int8_t *, u_int);
  83222. +extern void md5_pad(md5_ctxt *);
  83223. +extern void md5_result(u_int8_t *, md5_ctxt *);
  83224. +
  83225. +/* compatibility */
  83226. +#define MD5_CTX md5_ctxt
  83227. +#define MD5Init(x) md5_init((x))
  83228. +#define MD5Update(x, y, z) md5_loop((x), (y), (z))
  83229. +#define MD5Final(x, y) \
  83230. +do { \
  83231. + md5_pad((y)); \
  83232. + md5_result((x), (y)); \
  83233. +} while (0)
  83234. +
  83235. +#endif /* ! _NETINET6_MD5_H_*/
  83236. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/safe.c linux-2.6.39/crypto/ocf/safe/safe.c
  83237. --- linux-2.6.39.orig/crypto/ocf/safe/safe.c 1970-01-01 01:00:00.000000000 +0100
  83238. +++ linux-2.6.39/crypto/ocf/safe/safe.c 2011-07-31 11:32:03.283973139 +0200
  83239. @@ -0,0 +1,2288 @@
  83240. +/*-
  83241. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  83242. + * Copyright (C) 2004-2010 David McCullough
  83243. + * The license and original author are listed below.
  83244. + *
  83245. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  83246. + * Copyright (c) 2003 Global Technology Associates, Inc.
  83247. + * All rights reserved.
  83248. + *
  83249. + * Redistribution and use in source and binary forms, with or without
  83250. + * modification, are permitted provided that the following conditions
  83251. + * are met:
  83252. + * 1. Redistributions of source code must retain the above copyright
  83253. + * notice, this list of conditions and the following disclaimer.
  83254. + * 2. Redistributions in binary form must reproduce the above copyright
  83255. + * notice, this list of conditions and the following disclaimer in the
  83256. + * documentation and/or other materials provided with the distribution.
  83257. + *
  83258. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  83259. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  83260. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  83261. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  83262. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  83263. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  83264. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  83265. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  83266. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  83267. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  83268. + * SUCH DAMAGE.
  83269. + *
  83270. +__FBSDID("$FreeBSD: src/sys/dev/safe/safe.c,v 1.18 2007/03/21 03:42:50 sam Exp $");
  83271. + */
  83272. +
  83273. +#ifndef AUTOCONF_INCLUDED
  83274. +#include <linux/config.h>
  83275. +#endif
  83276. +#include <linux/module.h>
  83277. +#include <linux/kernel.h>
  83278. +#include <linux/init.h>
  83279. +#include <linux/list.h>
  83280. +#include <linux/slab.h>
  83281. +#include <linux/wait.h>
  83282. +#include <linux/sched.h>
  83283. +#include <linux/pci.h>
  83284. +#include <linux/delay.h>
  83285. +#include <linux/interrupt.h>
  83286. +#include <linux/spinlock.h>
  83287. +#include <linux/random.h>
  83288. +#include <linux/version.h>
  83289. +#include <linux/skbuff.h>
  83290. +#include <asm/io.h>
  83291. +
  83292. +/*
  83293. + * SafeNet SafeXcel-1141 hardware crypto accelerator
  83294. + */
  83295. +
  83296. +#include <cryptodev.h>
  83297. +#include <uio.h>
  83298. +#include <safe/safereg.h>
  83299. +#include <safe/safevar.h>
  83300. +
  83301. +#if 1
  83302. +#define DPRINTF(a) do { \
  83303. + if (debug) { \
  83304. + printk("%s: ", sc ? \
  83305. + device_get_nameunit(sc->sc_dev) : "safe"); \
  83306. + printk a; \
  83307. + } \
  83308. + } while (0)
  83309. +#else
  83310. +#define DPRINTF(a)
  83311. +#endif
  83312. +
  83313. +/*
  83314. + * until we find a cleaner way, include the BSD md5/sha1 code
  83315. + * here
  83316. + */
  83317. +#define HMAC_HACK 1
  83318. +#ifdef HMAC_HACK
  83319. +#define LITTLE_ENDIAN 1234
  83320. +#define BIG_ENDIAN 4321
  83321. +#ifdef __LITTLE_ENDIAN
  83322. +#define BYTE_ORDER LITTLE_ENDIAN
  83323. +#endif
  83324. +#ifdef __BIG_ENDIAN
  83325. +#define BYTE_ORDER BIG_ENDIAN
  83326. +#endif
  83327. +#include <safe/md5.h>
  83328. +#include <safe/md5.c>
  83329. +#include <safe/sha1.h>
  83330. +#include <safe/sha1.c>
  83331. +
  83332. +u_int8_t hmac_ipad_buffer[64] = {
  83333. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83334. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83335. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83336. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83337. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83338. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83339. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83340. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
  83341. +};
  83342. +
  83343. +u_int8_t hmac_opad_buffer[64] = {
  83344. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83345. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83346. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83347. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83348. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83349. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83350. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83351. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
  83352. +};
  83353. +#endif /* HMAC_HACK */
  83354. +
  83355. +/* add proc entry for this */
  83356. +struct safe_stats safestats;
  83357. +
  83358. +#define debug safe_debug
  83359. +int safe_debug = 0;
  83360. +module_param(safe_debug, int, 0644);
  83361. +MODULE_PARM_DESC(safe_debug, "Enable debug");
  83362. +
  83363. +static void safe_callback(struct safe_softc *, struct safe_ringentry *);
  83364. +static void safe_feed(struct safe_softc *, struct safe_ringentry *);
  83365. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  83366. +static void safe_rng_init(struct safe_softc *);
  83367. +int safe_rngbufsize = 8; /* 32 bytes each read */
  83368. +module_param(safe_rngbufsize, int, 0644);
  83369. +MODULE_PARM_DESC(safe_rngbufsize, "RNG polling buffer size (32-bit words)");
  83370. +int safe_rngmaxalarm = 8; /* max alarms before reset */
  83371. +module_param(safe_rngmaxalarm, int, 0644);
  83372. +MODULE_PARM_DESC(safe_rngmaxalarm, "RNG max alarms before reset");
  83373. +#endif /* SAFE_NO_RNG */
  83374. +
  83375. +static void safe_totalreset(struct safe_softc *sc);
  83376. +static int safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op);
  83377. +static int safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op);
  83378. +static int safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re);
  83379. +static int safe_kprocess(device_t dev, struct cryptkop *krp, int hint);
  83380. +static int safe_kstart(struct safe_softc *sc);
  83381. +static int safe_ksigbits(struct safe_softc *sc, struct crparam *cr);
  83382. +static void safe_kfeed(struct safe_softc *sc);
  83383. +static void safe_kpoll(unsigned long arg);
  83384. +static void safe_kload_reg(struct safe_softc *sc, u_int32_t off,
  83385. + u_int32_t len, struct crparam *n);
  83386. +
  83387. +static int safe_newsession(device_t, u_int32_t *, struct cryptoini *);
  83388. +static int safe_freesession(device_t, u_int64_t);
  83389. +static int safe_process(device_t, struct cryptop *, int);
  83390. +
  83391. +static device_method_t safe_methods = {
  83392. + /* crypto device methods */
  83393. + DEVMETHOD(cryptodev_newsession, safe_newsession),
  83394. + DEVMETHOD(cryptodev_freesession,safe_freesession),
  83395. + DEVMETHOD(cryptodev_process, safe_process),
  83396. + DEVMETHOD(cryptodev_kprocess, safe_kprocess),
  83397. +};
  83398. +
  83399. +#define READ_REG(sc,r) readl((sc)->sc_base_addr + (r))
  83400. +#define WRITE_REG(sc,r,val) writel((val), (sc)->sc_base_addr + (r))
  83401. +
  83402. +#define SAFE_MAX_CHIPS 8
  83403. +static struct safe_softc *safe_chip_idx[SAFE_MAX_CHIPS];
  83404. +
  83405. +/*
  83406. + * split our buffers up into safe DMAable byte fragments to avoid lockup
  83407. + * bug in 1141 HW on rev 1.0.
  83408. + */
  83409. +
  83410. +static int
  83411. +pci_map_linear(
  83412. + struct safe_softc *sc,
  83413. + struct safe_operand *buf,
  83414. + void *addr,
  83415. + int len)
  83416. +{
  83417. + dma_addr_t tmp;
  83418. + int chunk, tlen = len;
  83419. +
  83420. + tmp = pci_map_single(sc->sc_pcidev, addr, len, PCI_DMA_BIDIRECTIONAL);
  83421. +
  83422. + buf->mapsize += len;
  83423. + while (len > 0) {
  83424. + chunk = (len > sc->sc_max_dsize) ? sc->sc_max_dsize : len;
  83425. + buf->segs[buf->nsegs].ds_addr = tmp;
  83426. + buf->segs[buf->nsegs].ds_len = chunk;
  83427. + buf->segs[buf->nsegs].ds_tlen = tlen;
  83428. + buf->nsegs++;
  83429. + tmp += chunk;
  83430. + len -= chunk;
  83431. + tlen = 0;
  83432. + }
  83433. + return 0;
  83434. +}
  83435. +
  83436. +/*
  83437. + * map in a given uio buffer (great on some arches :-)
  83438. + */
  83439. +
  83440. +static int
  83441. +pci_map_uio(struct safe_softc *sc, struct safe_operand *buf, struct uio *uio)
  83442. +{
  83443. + struct iovec *iov = uio->uio_iov;
  83444. + int n;
  83445. +
  83446. + DPRINTF(("%s()\n", __FUNCTION__));
  83447. +
  83448. + buf->mapsize = 0;
  83449. + buf->nsegs = 0;
  83450. +
  83451. + for (n = 0; n < uio->uio_iovcnt; n++) {
  83452. + pci_map_linear(sc, buf, iov->iov_base, iov->iov_len);
  83453. + iov++;
  83454. + }
  83455. +
  83456. + /* identify this buffer by the first segment */
  83457. + buf->map = (void *) buf->segs[0].ds_addr;
  83458. + return(0);
  83459. +}
  83460. +
  83461. +/*
  83462. + * map in a given sk_buff
  83463. + */
  83464. +
  83465. +static int
  83466. +pci_map_skb(struct safe_softc *sc,struct safe_operand *buf,struct sk_buff *skb)
  83467. +{
  83468. + int i;
  83469. +
  83470. + DPRINTF(("%s()\n", __FUNCTION__));
  83471. +
  83472. + buf->mapsize = 0;
  83473. + buf->nsegs = 0;
  83474. +
  83475. + pci_map_linear(sc, buf, skb->data, skb_headlen(skb));
  83476. +
  83477. + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
  83478. + pci_map_linear(sc, buf,
  83479. + page_address(skb_shinfo(skb)->frags[i].page) +
  83480. + skb_shinfo(skb)->frags[i].page_offset,
  83481. + skb_shinfo(skb)->frags[i].size);
  83482. + }
  83483. +
  83484. + /* identify this buffer by the first segment */
  83485. + buf->map = (void *) buf->segs[0].ds_addr;
  83486. + return(0);
  83487. +}
  83488. +
  83489. +
  83490. +#if 0 /* not needed at this time */
  83491. +static void
  83492. +pci_sync_operand(struct safe_softc *sc, struct safe_operand *buf)
  83493. +{
  83494. + int i;
  83495. +
  83496. + DPRINTF(("%s()\n", __FUNCTION__));
  83497. + for (i = 0; i < buf->nsegs; i++)
  83498. + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
  83499. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  83500. +}
  83501. +#endif
  83502. +
  83503. +static void
  83504. +pci_unmap_operand(struct safe_softc *sc, struct safe_operand *buf)
  83505. +{
  83506. + int i;
  83507. + DPRINTF(("%s()\n", __FUNCTION__));
  83508. + for (i = 0; i < buf->nsegs; i++) {
  83509. + if (buf->segs[i].ds_tlen) {
  83510. + DPRINTF(("%s - unmap %d 0x%x %d\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
  83511. + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
  83512. + buf->segs[i].ds_tlen, PCI_DMA_BIDIRECTIONAL);
  83513. + DPRINTF(("%s - unmap %d 0x%x %d done\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
  83514. + }
  83515. + buf->segs[i].ds_addr = 0;
  83516. + buf->segs[i].ds_len = 0;
  83517. + buf->segs[i].ds_tlen = 0;
  83518. + }
  83519. + buf->nsegs = 0;
  83520. + buf->mapsize = 0;
  83521. + buf->map = 0;
  83522. +}
  83523. +
  83524. +
  83525. +/*
  83526. + * SafeXcel Interrupt routine
  83527. + */
  83528. +static irqreturn_t
  83529. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  83530. +safe_intr(int irq, void *arg)
  83531. +#else
  83532. +safe_intr(int irq, void *arg, struct pt_regs *regs)
  83533. +#endif
  83534. +{
  83535. + struct safe_softc *sc = arg;
  83536. + int stat;
  83537. + unsigned long flags;
  83538. +
  83539. + stat = READ_REG(sc, SAFE_HM_STAT);
  83540. +
  83541. + DPRINTF(("%s(stat=0x%x)\n", __FUNCTION__, stat));
  83542. +
  83543. + if (stat == 0) /* shared irq, not for us */
  83544. + return IRQ_NONE;
  83545. +
  83546. + WRITE_REG(sc, SAFE_HI_CLR, stat); /* IACK */
  83547. +
  83548. + if ((stat & SAFE_INT_PE_DDONE)) {
  83549. + /*
  83550. + * Descriptor(s) done; scan the ring and
  83551. + * process completed operations.
  83552. + */
  83553. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  83554. + while (sc->sc_back != sc->sc_front) {
  83555. + struct safe_ringentry *re = sc->sc_back;
  83556. +
  83557. +#ifdef SAFE_DEBUG
  83558. + if (debug) {
  83559. + safe_dump_ringstate(sc, __func__);
  83560. + safe_dump_request(sc, __func__, re);
  83561. + }
  83562. +#endif
  83563. + /*
  83564. + * safe_process marks ring entries that were allocated
  83565. + * but not used with a csr of zero. This insures the
  83566. + * ring front pointer never needs to be set backwards
  83567. + * in the event that an entry is allocated but not used
  83568. + * because of a setup error.
  83569. + */
  83570. + DPRINTF(("%s re->re_desc.d_csr=0x%x\n", __FUNCTION__, re->re_desc.d_csr));
  83571. + if (re->re_desc.d_csr != 0) {
  83572. + if (!SAFE_PE_CSR_IS_DONE(re->re_desc.d_csr)) {
  83573. + DPRINTF(("%s !CSR_IS_DONE\n", __FUNCTION__));
  83574. + break;
  83575. + }
  83576. + if (!SAFE_PE_LEN_IS_DONE(re->re_desc.d_len)) {
  83577. + DPRINTF(("%s !LEN_IS_DONE\n", __FUNCTION__));
  83578. + break;
  83579. + }
  83580. + sc->sc_nqchip--;
  83581. + safe_callback(sc, re);
  83582. + }
  83583. + if (++(sc->sc_back) == sc->sc_ringtop)
  83584. + sc->sc_back = sc->sc_ring;
  83585. + }
  83586. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  83587. + }
  83588. +
  83589. + /*
  83590. + * Check to see if we got any DMA Error
  83591. + */
  83592. + if (stat & SAFE_INT_PE_ERROR) {
  83593. + printk("%s: dmaerr dmastat %08x\n", device_get_nameunit(sc->sc_dev),
  83594. + (int)READ_REG(sc, SAFE_PE_DMASTAT));
  83595. + safestats.st_dmaerr++;
  83596. + safe_totalreset(sc);
  83597. +#if 0
  83598. + safe_feed(sc);
  83599. +#endif
  83600. + }
  83601. +
  83602. + if (sc->sc_needwakeup) { /* XXX check high watermark */
  83603. + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
  83604. + DPRINTF(("%s: wakeup crypto %x\n", __func__,
  83605. + sc->sc_needwakeup));
  83606. + sc->sc_needwakeup &= ~wakeup;
  83607. + crypto_unblock(sc->sc_cid, wakeup);
  83608. + }
  83609. +
  83610. + return IRQ_HANDLED;
  83611. +}
  83612. +
  83613. +/*
  83614. + * safe_feed() - post a request to chip
  83615. + */
  83616. +static void
  83617. +safe_feed(struct safe_softc *sc, struct safe_ringentry *re)
  83618. +{
  83619. + DPRINTF(("%s()\n", __FUNCTION__));
  83620. +#ifdef SAFE_DEBUG
  83621. + if (debug) {
  83622. + safe_dump_ringstate(sc, __func__);
  83623. + safe_dump_request(sc, __func__, re);
  83624. + }
  83625. +#endif
  83626. + sc->sc_nqchip++;
  83627. + if (sc->sc_nqchip > safestats.st_maxqchip)
  83628. + safestats.st_maxqchip = sc->sc_nqchip;
  83629. + /* poke h/w to check descriptor ring, any value can be written */
  83630. + WRITE_REG(sc, SAFE_HI_RD_DESCR, 0);
  83631. +}
  83632. +
  83633. +#define N(a) (sizeof(a) / sizeof (a[0]))
  83634. +static void
  83635. +safe_setup_enckey(struct safe_session *ses, caddr_t key)
  83636. +{
  83637. + int i;
  83638. +
  83639. + bcopy(key, ses->ses_key, ses->ses_klen / 8);
  83640. +
  83641. + /* PE is little-endian, insure proper byte order */
  83642. + for (i = 0; i < N(ses->ses_key); i++)
  83643. + ses->ses_key[i] = htole32(ses->ses_key[i]);
  83644. +}
  83645. +
  83646. +static void
  83647. +safe_setup_mackey(struct safe_session *ses, int algo, caddr_t key, int klen)
  83648. +{
  83649. +#ifdef HMAC_HACK
  83650. + MD5_CTX md5ctx;
  83651. + SHA1_CTX sha1ctx;
  83652. + int i;
  83653. +
  83654. +
  83655. + for (i = 0; i < klen; i++)
  83656. + key[i] ^= HMAC_IPAD_VAL;
  83657. +
  83658. + if (algo == CRYPTO_MD5_HMAC) {
  83659. + MD5Init(&md5ctx);
  83660. + MD5Update(&md5ctx, key, klen);
  83661. + MD5Update(&md5ctx, hmac_ipad_buffer, MD5_HMAC_BLOCK_LEN - klen);
  83662. + bcopy(md5ctx.md5_st8, ses->ses_hminner, sizeof(md5ctx.md5_st8));
  83663. + } else {
  83664. + SHA1Init(&sha1ctx);
  83665. + SHA1Update(&sha1ctx, key, klen);
  83666. + SHA1Update(&sha1ctx, hmac_ipad_buffer,
  83667. + SHA1_HMAC_BLOCK_LEN - klen);
  83668. + bcopy(sha1ctx.h.b32, ses->ses_hminner, sizeof(sha1ctx.h.b32));
  83669. + }
  83670. +
  83671. + for (i = 0; i < klen; i++)
  83672. + key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
  83673. +
  83674. + if (algo == CRYPTO_MD5_HMAC) {
  83675. + MD5Init(&md5ctx);
  83676. + MD5Update(&md5ctx, key, klen);
  83677. + MD5Update(&md5ctx, hmac_opad_buffer, MD5_HMAC_BLOCK_LEN - klen);
  83678. + bcopy(md5ctx.md5_st8, ses->ses_hmouter, sizeof(md5ctx.md5_st8));
  83679. + } else {
  83680. + SHA1Init(&sha1ctx);
  83681. + SHA1Update(&sha1ctx, key, klen);
  83682. + SHA1Update(&sha1ctx, hmac_opad_buffer,
  83683. + SHA1_HMAC_BLOCK_LEN - klen);
  83684. + bcopy(sha1ctx.h.b32, ses->ses_hmouter, sizeof(sha1ctx.h.b32));
  83685. + }
  83686. +
  83687. + for (i = 0; i < klen; i++)
  83688. + key[i] ^= HMAC_OPAD_VAL;
  83689. +
  83690. +#if 0
  83691. + /*
  83692. + * this code prevents SHA working on a BE host,
  83693. + * so it is obviously wrong. I think the byte
  83694. + * swap setup we do with the chip fixes this for us
  83695. + */
  83696. +
  83697. + /* PE is little-endian, insure proper byte order */
  83698. + for (i = 0; i < N(ses->ses_hminner); i++) {
  83699. + ses->ses_hminner[i] = htole32(ses->ses_hminner[i]);
  83700. + ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]);
  83701. + }
  83702. +#endif
  83703. +#else /* HMAC_HACK */
  83704. + printk("safe: md5/sha not implemented\n");
  83705. +#endif /* HMAC_HACK */
  83706. +}
  83707. +#undef N
  83708. +
  83709. +/*
  83710. + * Allocate a new 'session' and return an encoded session id. 'sidp'
  83711. + * contains our registration id, and should contain an encoded session
  83712. + * id on successful allocation.
  83713. + */
  83714. +static int
  83715. +safe_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  83716. +{
  83717. + struct safe_softc *sc = device_get_softc(dev);
  83718. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  83719. + struct safe_session *ses = NULL;
  83720. + int sesn;
  83721. +
  83722. + DPRINTF(("%s()\n", __FUNCTION__));
  83723. +
  83724. + if (sidp == NULL || cri == NULL || sc == NULL)
  83725. + return (EINVAL);
  83726. +
  83727. + for (c = cri; c != NULL; c = c->cri_next) {
  83728. + if (c->cri_alg == CRYPTO_MD5_HMAC ||
  83729. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  83730. + c->cri_alg == CRYPTO_NULL_HMAC) {
  83731. + if (macini)
  83732. + return (EINVAL);
  83733. + macini = c;
  83734. + } else if (c->cri_alg == CRYPTO_DES_CBC ||
  83735. + c->cri_alg == CRYPTO_3DES_CBC ||
  83736. + c->cri_alg == CRYPTO_AES_CBC ||
  83737. + c->cri_alg == CRYPTO_NULL_CBC) {
  83738. + if (encini)
  83739. + return (EINVAL);
  83740. + encini = c;
  83741. + } else
  83742. + return (EINVAL);
  83743. + }
  83744. + if (encini == NULL && macini == NULL)
  83745. + return (EINVAL);
  83746. + if (encini) { /* validate key length */
  83747. + switch (encini->cri_alg) {
  83748. + case CRYPTO_DES_CBC:
  83749. + if (encini->cri_klen != 64)
  83750. + return (EINVAL);
  83751. + break;
  83752. + case CRYPTO_3DES_CBC:
  83753. + if (encini->cri_klen != 192)
  83754. + return (EINVAL);
  83755. + break;
  83756. + case CRYPTO_AES_CBC:
  83757. + if (encini->cri_klen != 128 &&
  83758. + encini->cri_klen != 192 &&
  83759. + encini->cri_klen != 256)
  83760. + return (EINVAL);
  83761. + break;
  83762. + }
  83763. + }
  83764. +
  83765. + if (sc->sc_sessions == NULL) {
  83766. + ses = sc->sc_sessions = (struct safe_session *)
  83767. + kmalloc(sizeof(struct safe_session), SLAB_ATOMIC);
  83768. + if (ses == NULL)
  83769. + return (ENOMEM);
  83770. + memset(ses, 0, sizeof(struct safe_session));
  83771. + sesn = 0;
  83772. + sc->sc_nsessions = 1;
  83773. + } else {
  83774. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  83775. + if (sc->sc_sessions[sesn].ses_used == 0) {
  83776. + ses = &sc->sc_sessions[sesn];
  83777. + break;
  83778. + }
  83779. + }
  83780. +
  83781. + if (ses == NULL) {
  83782. + sesn = sc->sc_nsessions;
  83783. + ses = (struct safe_session *)
  83784. + kmalloc((sesn + 1) * sizeof(struct safe_session), SLAB_ATOMIC);
  83785. + if (ses == NULL)
  83786. + return (ENOMEM);
  83787. + memset(ses, 0, (sesn + 1) * sizeof(struct safe_session));
  83788. + bcopy(sc->sc_sessions, ses, sesn *
  83789. + sizeof(struct safe_session));
  83790. + bzero(sc->sc_sessions, sesn *
  83791. + sizeof(struct safe_session));
  83792. + kfree(sc->sc_sessions);
  83793. + sc->sc_sessions = ses;
  83794. + ses = &sc->sc_sessions[sesn];
  83795. + sc->sc_nsessions++;
  83796. + }
  83797. + }
  83798. +
  83799. + bzero(ses, sizeof(struct safe_session));
  83800. + ses->ses_used = 1;
  83801. +
  83802. + if (encini) {
  83803. + /* get an IV */
  83804. + /* XXX may read fewer than requested */
  83805. + read_random(ses->ses_iv, sizeof(ses->ses_iv));
  83806. +
  83807. + ses->ses_klen = encini->cri_klen;
  83808. + if (encini->cri_key != NULL)
  83809. + safe_setup_enckey(ses, encini->cri_key);
  83810. + }
  83811. +
  83812. + if (macini) {
  83813. + ses->ses_mlen = macini->cri_mlen;
  83814. + if (ses->ses_mlen == 0) {
  83815. + if (macini->cri_alg == CRYPTO_MD5_HMAC)
  83816. + ses->ses_mlen = MD5_HASH_LEN;
  83817. + else
  83818. + ses->ses_mlen = SHA1_HASH_LEN;
  83819. + }
  83820. +
  83821. + if (macini->cri_key != NULL) {
  83822. + safe_setup_mackey(ses, macini->cri_alg, macini->cri_key,
  83823. + macini->cri_klen / 8);
  83824. + }
  83825. + }
  83826. +
  83827. + *sidp = SAFE_SID(device_get_unit(sc->sc_dev), sesn);
  83828. + return (0);
  83829. +}
  83830. +
  83831. +/*
  83832. + * Deallocate a session.
  83833. + */
  83834. +static int
  83835. +safe_freesession(device_t dev, u_int64_t tid)
  83836. +{
  83837. + struct safe_softc *sc = device_get_softc(dev);
  83838. + int session, ret;
  83839. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  83840. +
  83841. + DPRINTF(("%s()\n", __FUNCTION__));
  83842. +
  83843. + if (sc == NULL)
  83844. + return (EINVAL);
  83845. +
  83846. + session = SAFE_SESSION(sid);
  83847. + if (session < sc->sc_nsessions) {
  83848. + bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
  83849. + ret = 0;
  83850. + } else
  83851. + ret = EINVAL;
  83852. + return (ret);
  83853. +}
  83854. +
  83855. +
  83856. +static int
  83857. +safe_process(device_t dev, struct cryptop *crp, int hint)
  83858. +{
  83859. + struct safe_softc *sc = device_get_softc(dev);
  83860. + int err = 0, i, nicealign, uniform;
  83861. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  83862. + int bypass, oplen, ivsize;
  83863. + caddr_t iv;
  83864. + int16_t coffset;
  83865. + struct safe_session *ses;
  83866. + struct safe_ringentry *re;
  83867. + struct safe_sarec *sa;
  83868. + struct safe_pdesc *pd;
  83869. + u_int32_t cmd0, cmd1, staterec;
  83870. + unsigned long flags;
  83871. +
  83872. + DPRINTF(("%s()\n", __FUNCTION__));
  83873. +
  83874. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
  83875. + safestats.st_invalid++;
  83876. + return (EINVAL);
  83877. + }
  83878. + if (SAFE_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
  83879. + safestats.st_badsession++;
  83880. + return (EINVAL);
  83881. + }
  83882. +
  83883. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  83884. + if (sc->sc_front == sc->sc_back && sc->sc_nqchip != 0) {
  83885. + safestats.st_ringfull++;
  83886. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  83887. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  83888. + return (ERESTART);
  83889. + }
  83890. + re = sc->sc_front;
  83891. +
  83892. + staterec = re->re_sa.sa_staterec; /* save */
  83893. + /* NB: zero everything but the PE descriptor */
  83894. + bzero(&re->re_sa, sizeof(struct safe_ringentry) - sizeof(re->re_desc));
  83895. + re->re_sa.sa_staterec = staterec; /* restore */
  83896. +
  83897. + re->re_crp = crp;
  83898. + re->re_sesn = SAFE_SESSION(crp->crp_sid);
  83899. +
  83900. + re->re_src.nsegs = 0;
  83901. + re->re_dst.nsegs = 0;
  83902. +
  83903. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  83904. + re->re_src_skb = (struct sk_buff *)crp->crp_buf;
  83905. + re->re_dst_skb = (struct sk_buff *)crp->crp_buf;
  83906. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  83907. + re->re_src_io = (struct uio *)crp->crp_buf;
  83908. + re->re_dst_io = (struct uio *)crp->crp_buf;
  83909. + } else {
  83910. + safestats.st_badflags++;
  83911. + err = EINVAL;
  83912. + goto errout; /* XXX we don't handle contiguous blocks! */
  83913. + }
  83914. +
  83915. + sa = &re->re_sa;
  83916. + ses = &sc->sc_sessions[re->re_sesn];
  83917. +
  83918. + crd1 = crp->crp_desc;
  83919. + if (crd1 == NULL) {
  83920. + safestats.st_nodesc++;
  83921. + err = EINVAL;
  83922. + goto errout;
  83923. + }
  83924. + crd2 = crd1->crd_next;
  83925. +
  83926. + cmd0 = SAFE_SA_CMD0_BASIC; /* basic group operation */
  83927. + cmd1 = 0;
  83928. + if (crd2 == NULL) {
  83929. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  83930. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  83931. + crd1->crd_alg == CRYPTO_NULL_HMAC) {
  83932. + maccrd = crd1;
  83933. + enccrd = NULL;
  83934. + cmd0 |= SAFE_SA_CMD0_OP_HASH;
  83935. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  83936. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  83937. + crd1->crd_alg == CRYPTO_AES_CBC ||
  83938. + crd1->crd_alg == CRYPTO_NULL_CBC) {
  83939. + maccrd = NULL;
  83940. + enccrd = crd1;
  83941. + cmd0 |= SAFE_SA_CMD0_OP_CRYPT;
  83942. + } else {
  83943. + safestats.st_badalg++;
  83944. + err = EINVAL;
  83945. + goto errout;
  83946. + }
  83947. + } else {
  83948. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  83949. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  83950. + crd1->crd_alg == CRYPTO_NULL_HMAC) &&
  83951. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  83952. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  83953. + crd2->crd_alg == CRYPTO_AES_CBC ||
  83954. + crd2->crd_alg == CRYPTO_NULL_CBC) &&
  83955. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  83956. + maccrd = crd1;
  83957. + enccrd = crd2;
  83958. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  83959. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  83960. + crd1->crd_alg == CRYPTO_AES_CBC ||
  83961. + crd1->crd_alg == CRYPTO_NULL_CBC) &&
  83962. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  83963. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  83964. + crd2->crd_alg == CRYPTO_NULL_HMAC) &&
  83965. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  83966. + enccrd = crd1;
  83967. + maccrd = crd2;
  83968. + } else {
  83969. + safestats.st_badalg++;
  83970. + err = EINVAL;
  83971. + goto errout;
  83972. + }
  83973. + cmd0 |= SAFE_SA_CMD0_OP_BOTH;
  83974. + }
  83975. +
  83976. + if (enccrd) {
  83977. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
  83978. + safe_setup_enckey(ses, enccrd->crd_key);
  83979. +
  83980. + if (enccrd->crd_alg == CRYPTO_DES_CBC) {
  83981. + cmd0 |= SAFE_SA_CMD0_DES;
  83982. + cmd1 |= SAFE_SA_CMD1_CBC;
  83983. + ivsize = 2*sizeof(u_int32_t);
  83984. + } else if (enccrd->crd_alg == CRYPTO_3DES_CBC) {
  83985. + cmd0 |= SAFE_SA_CMD0_3DES;
  83986. + cmd1 |= SAFE_SA_CMD1_CBC;
  83987. + ivsize = 2*sizeof(u_int32_t);
  83988. + } else if (enccrd->crd_alg == CRYPTO_AES_CBC) {
  83989. + cmd0 |= SAFE_SA_CMD0_AES;
  83990. + cmd1 |= SAFE_SA_CMD1_CBC;
  83991. + if (ses->ses_klen == 128)
  83992. + cmd1 |= SAFE_SA_CMD1_AES128;
  83993. + else if (ses->ses_klen == 192)
  83994. + cmd1 |= SAFE_SA_CMD1_AES192;
  83995. + else
  83996. + cmd1 |= SAFE_SA_CMD1_AES256;
  83997. + ivsize = 4*sizeof(u_int32_t);
  83998. + } else {
  83999. + cmd0 |= SAFE_SA_CMD0_CRYPT_NULL;
  84000. + ivsize = 0;
  84001. + }
  84002. +
  84003. + /*
  84004. + * Setup encrypt/decrypt state. When using basic ops
  84005. + * we can't use an inline IV because hash/crypt offset
  84006. + * must be from the end of the IV to the start of the
  84007. + * crypt data and this leaves out the preceding header
  84008. + * from the hash calculation. Instead we place the IV
  84009. + * in the state record and set the hash/crypt offset to
  84010. + * copy both the header+IV.
  84011. + */
  84012. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  84013. + cmd0 |= SAFE_SA_CMD0_OUTBOUND;
  84014. +
  84015. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  84016. + iv = enccrd->crd_iv;
  84017. + else
  84018. + iv = (caddr_t) ses->ses_iv;
  84019. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  84020. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  84021. + enccrd->crd_inject, ivsize, iv);
  84022. + }
  84023. + bcopy(iv, re->re_sastate.sa_saved_iv, ivsize);
  84024. + /* make iv LE */
  84025. + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
  84026. + re->re_sastate.sa_saved_iv[i] =
  84027. + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
  84028. + cmd0 |= SAFE_SA_CMD0_IVLD_STATE | SAFE_SA_CMD0_SAVEIV;
  84029. + re->re_flags |= SAFE_QFLAGS_COPYOUTIV;
  84030. + } else {
  84031. + cmd0 |= SAFE_SA_CMD0_INBOUND;
  84032. +
  84033. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  84034. + bcopy(enccrd->crd_iv,
  84035. + re->re_sastate.sa_saved_iv, ivsize);
  84036. + } else {
  84037. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  84038. + enccrd->crd_inject, ivsize,
  84039. + (caddr_t)re->re_sastate.sa_saved_iv);
  84040. + }
  84041. + /* make iv LE */
  84042. + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
  84043. + re->re_sastate.sa_saved_iv[i] =
  84044. + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
  84045. + cmd0 |= SAFE_SA_CMD0_IVLD_STATE;
  84046. + }
  84047. + /*
  84048. + * For basic encryption use the zero pad algorithm.
  84049. + * This pads results to an 8-byte boundary and
  84050. + * suppresses padding verification for inbound (i.e.
  84051. + * decrypt) operations.
  84052. + *
  84053. + * NB: Not sure if the 8-byte pad boundary is a problem.
  84054. + */
  84055. + cmd0 |= SAFE_SA_CMD0_PAD_ZERO;
  84056. +
  84057. + /* XXX assert key bufs have the same size */
  84058. + bcopy(ses->ses_key, sa->sa_key, sizeof(sa->sa_key));
  84059. + }
  84060. +
  84061. + if (maccrd) {
  84062. + if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  84063. + safe_setup_mackey(ses, maccrd->crd_alg,
  84064. + maccrd->crd_key, maccrd->crd_klen / 8);
  84065. + }
  84066. +
  84067. + if (maccrd->crd_alg == CRYPTO_MD5_HMAC) {
  84068. + cmd0 |= SAFE_SA_CMD0_MD5;
  84069. + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
  84070. + } else if (maccrd->crd_alg == CRYPTO_SHA1_HMAC) {
  84071. + cmd0 |= SAFE_SA_CMD0_SHA1;
  84072. + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
  84073. + } else {
  84074. + cmd0 |= SAFE_SA_CMD0_HASH_NULL;
  84075. + }
  84076. + /*
  84077. + * Digest data is loaded from the SA and the hash
  84078. + * result is saved to the state block where we
  84079. + * retrieve it for return to the caller.
  84080. + */
  84081. + /* XXX assert digest bufs have the same size */
  84082. + bcopy(ses->ses_hminner, sa->sa_indigest,
  84083. + sizeof(sa->sa_indigest));
  84084. + bcopy(ses->ses_hmouter, sa->sa_outdigest,
  84085. + sizeof(sa->sa_outdigest));
  84086. +
  84087. + cmd0 |= SAFE_SA_CMD0_HSLD_SA | SAFE_SA_CMD0_SAVEHASH;
  84088. + re->re_flags |= SAFE_QFLAGS_COPYOUTICV;
  84089. + }
  84090. +
  84091. + if (enccrd && maccrd) {
  84092. + /*
  84093. + * The offset from hash data to the start of
  84094. + * crypt data is the difference in the skips.
  84095. + */
  84096. + bypass = maccrd->crd_skip;
  84097. + coffset = enccrd->crd_skip - maccrd->crd_skip;
  84098. + if (coffset < 0) {
  84099. + DPRINTF(("%s: hash does not precede crypt; "
  84100. + "mac skip %u enc skip %u\n",
  84101. + __func__, maccrd->crd_skip, enccrd->crd_skip));
  84102. + safestats.st_skipmismatch++;
  84103. + err = EINVAL;
  84104. + goto errout;
  84105. + }
  84106. + oplen = enccrd->crd_skip + enccrd->crd_len;
  84107. + if (maccrd->crd_skip + maccrd->crd_len != oplen) {
  84108. + DPRINTF(("%s: hash amount %u != crypt amount %u\n",
  84109. + __func__, maccrd->crd_skip + maccrd->crd_len,
  84110. + oplen));
  84111. + safestats.st_lenmismatch++;
  84112. + err = EINVAL;
  84113. + goto errout;
  84114. + }
  84115. +#ifdef SAFE_DEBUG
  84116. + if (debug) {
  84117. + printf("mac: skip %d, len %d, inject %d\n",
  84118. + maccrd->crd_skip, maccrd->crd_len,
  84119. + maccrd->crd_inject);
  84120. + printf("enc: skip %d, len %d, inject %d\n",
  84121. + enccrd->crd_skip, enccrd->crd_len,
  84122. + enccrd->crd_inject);
  84123. + printf("bypass %d coffset %d oplen %d\n",
  84124. + bypass, coffset, oplen);
  84125. + }
  84126. +#endif
  84127. + if (coffset & 3) { /* offset must be 32-bit aligned */
  84128. + DPRINTF(("%s: coffset %u misaligned\n",
  84129. + __func__, coffset));
  84130. + safestats.st_coffmisaligned++;
  84131. + err = EINVAL;
  84132. + goto errout;
  84133. + }
  84134. + coffset >>= 2;
  84135. + if (coffset > 255) { /* offset must be <256 dwords */
  84136. + DPRINTF(("%s: coffset %u too big\n",
  84137. + __func__, coffset));
  84138. + safestats.st_cofftoobig++;
  84139. + err = EINVAL;
  84140. + goto errout;
  84141. + }
  84142. + /*
  84143. + * Tell the hardware to copy the header to the output.
  84144. + * The header is defined as the data from the end of
  84145. + * the bypass to the start of data to be encrypted.
  84146. + * Typically this is the inline IV. Note that you need
  84147. + * to do this even if src+dst are the same; it appears
  84148. + * that w/o this bit the crypted data is written
  84149. + * immediately after the bypass data.
  84150. + */
  84151. + cmd1 |= SAFE_SA_CMD1_HDRCOPY;
  84152. + /*
  84153. + * Disable IP header mutable bit handling. This is
  84154. + * needed to get correct HMAC calculations.
  84155. + */
  84156. + cmd1 |= SAFE_SA_CMD1_MUTABLE;
  84157. + } else {
  84158. + if (enccrd) {
  84159. + bypass = enccrd->crd_skip;
  84160. + oplen = bypass + enccrd->crd_len;
  84161. + } else {
  84162. + bypass = maccrd->crd_skip;
  84163. + oplen = bypass + maccrd->crd_len;
  84164. + }
  84165. + coffset = 0;
  84166. + }
  84167. + /* XXX verify multiple of 4 when using s/g */
  84168. + if (bypass > 96) { /* bypass offset must be <= 96 bytes */
  84169. + DPRINTF(("%s: bypass %u too big\n", __func__, bypass));
  84170. + safestats.st_bypasstoobig++;
  84171. + err = EINVAL;
  84172. + goto errout;
  84173. + }
  84174. +
  84175. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  84176. + if (pci_map_skb(sc, &re->re_src, re->re_src_skb)) {
  84177. + safestats.st_noload++;
  84178. + err = ENOMEM;
  84179. + goto errout;
  84180. + }
  84181. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  84182. + if (pci_map_uio(sc, &re->re_src, re->re_src_io)) {
  84183. + safestats.st_noload++;
  84184. + err = ENOMEM;
  84185. + goto errout;
  84186. + }
  84187. + }
  84188. + nicealign = safe_dmamap_aligned(sc, &re->re_src);
  84189. + uniform = safe_dmamap_uniform(sc, &re->re_src);
  84190. +
  84191. + DPRINTF(("src nicealign %u uniform %u nsegs %u\n",
  84192. + nicealign, uniform, re->re_src.nsegs));
  84193. + if (re->re_src.nsegs > 1) {
  84194. + re->re_desc.d_src = sc->sc_spalloc.dma_paddr +
  84195. + ((caddr_t) sc->sc_spfree - (caddr_t) sc->sc_spring);
  84196. + for (i = 0; i < re->re_src_nsegs; i++) {
  84197. + /* NB: no need to check if there's space */
  84198. + pd = sc->sc_spfree;
  84199. + if (++(sc->sc_spfree) == sc->sc_springtop)
  84200. + sc->sc_spfree = sc->sc_spring;
  84201. +
  84202. + KASSERT((pd->pd_flags&3) == 0 ||
  84203. + (pd->pd_flags&3) == SAFE_PD_DONE,
  84204. + ("bogus source particle descriptor; flags %x",
  84205. + pd->pd_flags));
  84206. + pd->pd_addr = re->re_src_segs[i].ds_addr;
  84207. + pd->pd_size = re->re_src_segs[i].ds_len;
  84208. + pd->pd_flags = SAFE_PD_READY;
  84209. + }
  84210. + cmd0 |= SAFE_SA_CMD0_IGATHER;
  84211. + } else {
  84212. + /*
  84213. + * No need for gather, reference the operand directly.
  84214. + */
  84215. + re->re_desc.d_src = re->re_src_segs[0].ds_addr;
  84216. + }
  84217. +
  84218. + if (enccrd == NULL && maccrd != NULL) {
  84219. + /*
  84220. + * Hash op; no destination needed.
  84221. + */
  84222. + } else {
  84223. + if (crp->crp_flags & (CRYPTO_F_IOV|CRYPTO_F_SKBUF)) {
  84224. + if (!nicealign) {
  84225. + safestats.st_iovmisaligned++;
  84226. + err = EINVAL;
  84227. + goto errout;
  84228. + }
  84229. + if (uniform != 1) {
  84230. + device_printf(sc->sc_dev, "!uniform source\n");
  84231. + if (!uniform) {
  84232. + /*
  84233. + * There's no way to handle the DMA
  84234. + * requirements with this uio. We
  84235. + * could create a separate DMA area for
  84236. + * the result and then copy it back,
  84237. + * but for now we just bail and return
  84238. + * an error. Note that uio requests
  84239. + * > SAFE_MAX_DSIZE are handled because
  84240. + * the DMA map and segment list for the
  84241. + * destination wil result in a
  84242. + * destination particle list that does
  84243. + * the necessary scatter DMA.
  84244. + */
  84245. + safestats.st_iovnotuniform++;
  84246. + err = EINVAL;
  84247. + goto errout;
  84248. + }
  84249. + } else
  84250. + re->re_dst = re->re_src;
  84251. + } else {
  84252. + safestats.st_badflags++;
  84253. + err = EINVAL;
  84254. + goto errout;
  84255. + }
  84256. +
  84257. + if (re->re_dst.nsegs > 1) {
  84258. + re->re_desc.d_dst = sc->sc_dpalloc.dma_paddr +
  84259. + ((caddr_t) sc->sc_dpfree - (caddr_t) sc->sc_dpring);
  84260. + for (i = 0; i < re->re_dst_nsegs; i++) {
  84261. + pd = sc->sc_dpfree;
  84262. + KASSERT((pd->pd_flags&3) == 0 ||
  84263. + (pd->pd_flags&3) == SAFE_PD_DONE,
  84264. + ("bogus dest particle descriptor; flags %x",
  84265. + pd->pd_flags));
  84266. + if (++(sc->sc_dpfree) == sc->sc_dpringtop)
  84267. + sc->sc_dpfree = sc->sc_dpring;
  84268. + pd->pd_addr = re->re_dst_segs[i].ds_addr;
  84269. + pd->pd_flags = SAFE_PD_READY;
  84270. + }
  84271. + cmd0 |= SAFE_SA_CMD0_OSCATTER;
  84272. + } else {
  84273. + /*
  84274. + * No need for scatter, reference the operand directly.
  84275. + */
  84276. + re->re_desc.d_dst = re->re_dst_segs[0].ds_addr;
  84277. + }
  84278. + }
  84279. +
  84280. + /*
  84281. + * All done with setup; fillin the SA command words
  84282. + * and the packet engine descriptor. The operation
  84283. + * is now ready for submission to the hardware.
  84284. + */
  84285. + sa->sa_cmd0 = cmd0 | SAFE_SA_CMD0_IPCI | SAFE_SA_CMD0_OPCI;
  84286. + sa->sa_cmd1 = cmd1
  84287. + | (coffset << SAFE_SA_CMD1_OFFSET_S)
  84288. + | SAFE_SA_CMD1_SAREV1 /* Rev 1 SA data structure */
  84289. + | SAFE_SA_CMD1_SRPCI
  84290. + ;
  84291. + /*
  84292. + * NB: the order of writes is important here. In case the
  84293. + * chip is scanning the ring because of an outstanding request
  84294. + * it might nab this one too. In that case we need to make
  84295. + * sure the setup is complete before we write the length
  84296. + * field of the descriptor as it signals the descriptor is
  84297. + * ready for processing.
  84298. + */
  84299. + re->re_desc.d_csr = SAFE_PE_CSR_READY | SAFE_PE_CSR_SAPCI;
  84300. + if (maccrd)
  84301. + re->re_desc.d_csr |= SAFE_PE_CSR_LOADSA | SAFE_PE_CSR_HASHFINAL;
  84302. + wmb();
  84303. + re->re_desc.d_len = oplen
  84304. + | SAFE_PE_LEN_READY
  84305. + | (bypass << SAFE_PE_LEN_BYPASS_S)
  84306. + ;
  84307. +
  84308. + safestats.st_ipackets++;
  84309. + safestats.st_ibytes += oplen;
  84310. +
  84311. + if (++(sc->sc_front) == sc->sc_ringtop)
  84312. + sc->sc_front = sc->sc_ring;
  84313. +
  84314. + /* XXX honor batching */
  84315. + safe_feed(sc, re);
  84316. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  84317. + return (0);
  84318. +
  84319. +errout:
  84320. + if (re->re_src.map != re->re_dst.map)
  84321. + pci_unmap_operand(sc, &re->re_dst);
  84322. + if (re->re_src.map)
  84323. + pci_unmap_operand(sc, &re->re_src);
  84324. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  84325. + if (err != ERESTART) {
  84326. + crp->crp_etype = err;
  84327. + crypto_done(crp);
  84328. + } else {
  84329. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  84330. + }
  84331. + return (err);
  84332. +}
  84333. +
  84334. +static void
  84335. +safe_callback(struct safe_softc *sc, struct safe_ringentry *re)
  84336. +{
  84337. + struct cryptop *crp = (struct cryptop *)re->re_crp;
  84338. + struct cryptodesc *crd;
  84339. +
  84340. + DPRINTF(("%s()\n", __FUNCTION__));
  84341. +
  84342. + safestats.st_opackets++;
  84343. + safestats.st_obytes += re->re_dst.mapsize;
  84344. +
  84345. + if (re->re_desc.d_csr & SAFE_PE_CSR_STATUS) {
  84346. + device_printf(sc->sc_dev, "csr 0x%x cmd0 0x%x cmd1 0x%x\n",
  84347. + re->re_desc.d_csr,
  84348. + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1);
  84349. + safestats.st_peoperr++;
  84350. + crp->crp_etype = EIO; /* something more meaningful? */
  84351. + }
  84352. +
  84353. + if (re->re_dst.map != NULL && re->re_dst.map != re->re_src.map)
  84354. + pci_unmap_operand(sc, &re->re_dst);
  84355. + pci_unmap_operand(sc, &re->re_src);
  84356. +
  84357. + /*
  84358. + * If result was written to a differet mbuf chain, swap
  84359. + * it in as the return value and reclaim the original.
  84360. + */
  84361. + if ((crp->crp_flags & CRYPTO_F_SKBUF) && re->re_src_skb != re->re_dst_skb) {
  84362. + device_printf(sc->sc_dev, "no CRYPTO_F_SKBUF swapping support\n");
  84363. + /* kfree_skb(skb) */
  84364. + /* crp->crp_buf = (caddr_t)re->re_dst_skb */
  84365. + return;
  84366. + }
  84367. +
  84368. + if (re->re_flags & SAFE_QFLAGS_COPYOUTIV) {
  84369. + /* copy out IV for future use */
  84370. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  84371. + int i;
  84372. + int ivsize;
  84373. +
  84374. + if (crd->crd_alg == CRYPTO_DES_CBC ||
  84375. + crd->crd_alg == CRYPTO_3DES_CBC) {
  84376. + ivsize = 2*sizeof(u_int32_t);
  84377. + } else if (crd->crd_alg == CRYPTO_AES_CBC) {
  84378. + ivsize = 4*sizeof(u_int32_t);
  84379. + } else
  84380. + continue;
  84381. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  84382. + crd->crd_skip + crd->crd_len - ivsize, ivsize,
  84383. + (caddr_t)sc->sc_sessions[re->re_sesn].ses_iv);
  84384. + for (i = 0;
  84385. + i < ivsize/sizeof(sc->sc_sessions[re->re_sesn].ses_iv[0]);
  84386. + i++)
  84387. + sc->sc_sessions[re->re_sesn].ses_iv[i] =
  84388. + cpu_to_le32(sc->sc_sessions[re->re_sesn].ses_iv[i]);
  84389. + break;
  84390. + }
  84391. + }
  84392. +
  84393. + if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) {
  84394. + /* copy out ICV result */
  84395. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  84396. + if (!(crd->crd_alg == CRYPTO_MD5_HMAC ||
  84397. + crd->crd_alg == CRYPTO_SHA1_HMAC ||
  84398. + crd->crd_alg == CRYPTO_NULL_HMAC))
  84399. + continue;
  84400. + if (crd->crd_alg == CRYPTO_SHA1_HMAC) {
  84401. + /*
  84402. + * SHA-1 ICV's are byte-swapped; fix 'em up
  84403. + * before copy them to their destination.
  84404. + */
  84405. + re->re_sastate.sa_saved_indigest[0] =
  84406. + cpu_to_be32(re->re_sastate.sa_saved_indigest[0]);
  84407. + re->re_sastate.sa_saved_indigest[1] =
  84408. + cpu_to_be32(re->re_sastate.sa_saved_indigest[1]);
  84409. + re->re_sastate.sa_saved_indigest[2] =
  84410. + cpu_to_be32(re->re_sastate.sa_saved_indigest[2]);
  84411. + } else {
  84412. + re->re_sastate.sa_saved_indigest[0] =
  84413. + cpu_to_le32(re->re_sastate.sa_saved_indigest[0]);
  84414. + re->re_sastate.sa_saved_indigest[1] =
  84415. + cpu_to_le32(re->re_sastate.sa_saved_indigest[1]);
  84416. + re->re_sastate.sa_saved_indigest[2] =
  84417. + cpu_to_le32(re->re_sastate.sa_saved_indigest[2]);
  84418. + }
  84419. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  84420. + crd->crd_inject,
  84421. + sc->sc_sessions[re->re_sesn].ses_mlen,
  84422. + (caddr_t)re->re_sastate.sa_saved_indigest);
  84423. + break;
  84424. + }
  84425. + }
  84426. + crypto_done(crp);
  84427. +}
  84428. +
  84429. +
  84430. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  84431. +#define SAFE_RNG_MAXWAIT 1000
  84432. +
  84433. +static void
  84434. +safe_rng_init(struct safe_softc *sc)
  84435. +{
  84436. + u_int32_t w, v;
  84437. + int i;
  84438. +
  84439. + DPRINTF(("%s()\n", __FUNCTION__));
  84440. +
  84441. + WRITE_REG(sc, SAFE_RNG_CTRL, 0);
  84442. + /* use default value according to the manual */
  84443. + WRITE_REG(sc, SAFE_RNG_CNFG, 0x834); /* magic from SafeNet */
  84444. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  84445. +
  84446. + /*
  84447. + * There is a bug in rev 1.0 of the 1140 that when the RNG
  84448. + * is brought out of reset the ready status flag does not
  84449. + * work until the RNG has finished its internal initialization.
  84450. + *
  84451. + * So in order to determine the device is through its
  84452. + * initialization we must read the data register, using the
  84453. + * status reg in the read in case it is initialized. Then read
  84454. + * the data register until it changes from the first read.
  84455. + * Once it changes read the data register until it changes
  84456. + * again. At this time the RNG is considered initialized.
  84457. + * This could take between 750ms - 1000ms in time.
  84458. + */
  84459. + i = 0;
  84460. + w = READ_REG(sc, SAFE_RNG_OUT);
  84461. + do {
  84462. + v = READ_REG(sc, SAFE_RNG_OUT);
  84463. + if (v != w) {
  84464. + w = v;
  84465. + break;
  84466. + }
  84467. + DELAY(10);
  84468. + } while (++i < SAFE_RNG_MAXWAIT);
  84469. +
  84470. + /* Wait Until data changes again */
  84471. + i = 0;
  84472. + do {
  84473. + v = READ_REG(sc, SAFE_RNG_OUT);
  84474. + if (v != w)
  84475. + break;
  84476. + DELAY(10);
  84477. + } while (++i < SAFE_RNG_MAXWAIT);
  84478. +}
  84479. +
  84480. +static __inline void
  84481. +safe_rng_disable_short_cycle(struct safe_softc *sc)
  84482. +{
  84483. + DPRINTF(("%s()\n", __FUNCTION__));
  84484. +
  84485. + WRITE_REG(sc, SAFE_RNG_CTRL,
  84486. + READ_REG(sc, SAFE_RNG_CTRL) &~ SAFE_RNG_CTRL_SHORTEN);
  84487. +}
  84488. +
  84489. +static __inline void
  84490. +safe_rng_enable_short_cycle(struct safe_softc *sc)
  84491. +{
  84492. + DPRINTF(("%s()\n", __FUNCTION__));
  84493. +
  84494. + WRITE_REG(sc, SAFE_RNG_CTRL,
  84495. + READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN);
  84496. +}
  84497. +
  84498. +static __inline u_int32_t
  84499. +safe_rng_read(struct safe_softc *sc)
  84500. +{
  84501. + int i;
  84502. +
  84503. + i = 0;
  84504. + while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT)
  84505. + ;
  84506. + return READ_REG(sc, SAFE_RNG_OUT);
  84507. +}
  84508. +
  84509. +static int
  84510. +safe_read_random(void *arg, u_int32_t *buf, int maxwords)
  84511. +{
  84512. + struct safe_softc *sc = (struct safe_softc *) arg;
  84513. + int i, rc;
  84514. +
  84515. + DPRINTF(("%s()\n", __FUNCTION__));
  84516. +
  84517. + safestats.st_rng++;
  84518. + /*
  84519. + * Fetch the next block of data.
  84520. + */
  84521. + if (maxwords > safe_rngbufsize)
  84522. + maxwords = safe_rngbufsize;
  84523. + if (maxwords > SAFE_RNG_MAXBUFSIZ)
  84524. + maxwords = SAFE_RNG_MAXBUFSIZ;
  84525. +retry:
  84526. + /* read as much as we can */
  84527. + for (rc = 0; rc < maxwords; rc++) {
  84528. + if (READ_REG(sc, SAFE_RNG_STAT) != 0)
  84529. + break;
  84530. + buf[rc] = READ_REG(sc, SAFE_RNG_OUT);
  84531. + }
  84532. + if (rc == 0)
  84533. + return 0;
  84534. + /*
  84535. + * Check the comparator alarm count and reset the h/w if
  84536. + * it exceeds our threshold. This guards against the
  84537. + * hardware oscillators resonating with external signals.
  84538. + */
  84539. + if (READ_REG(sc, SAFE_RNG_ALM_CNT) > safe_rngmaxalarm) {
  84540. + u_int32_t freq_inc, w;
  84541. +
  84542. + DPRINTF(("%s: alarm count %u exceeds threshold %u\n", __func__,
  84543. + (unsigned)READ_REG(sc, SAFE_RNG_ALM_CNT), safe_rngmaxalarm));
  84544. + safestats.st_rngalarm++;
  84545. + safe_rng_enable_short_cycle(sc);
  84546. + freq_inc = 18;
  84547. + for (i = 0; i < 64; i++) {
  84548. + w = READ_REG(sc, SAFE_RNG_CNFG);
  84549. + freq_inc = ((w + freq_inc) & 0x3fL);
  84550. + w = ((w & ~0x3fL) | freq_inc);
  84551. + WRITE_REG(sc, SAFE_RNG_CNFG, w);
  84552. +
  84553. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  84554. +
  84555. + (void) safe_rng_read(sc);
  84556. + DELAY(25);
  84557. +
  84558. + if (READ_REG(sc, SAFE_RNG_ALM_CNT) == 0) {
  84559. + safe_rng_disable_short_cycle(sc);
  84560. + goto retry;
  84561. + }
  84562. + freq_inc = 1;
  84563. + }
  84564. + safe_rng_disable_short_cycle(sc);
  84565. + } else
  84566. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  84567. +
  84568. + return(rc);
  84569. +}
  84570. +#endif /* defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG) */
  84571. +
  84572. +
  84573. +/*
  84574. + * Resets the board. Values in the regesters are left as is
  84575. + * from the reset (i.e. initial values are assigned elsewhere).
  84576. + */
  84577. +static void
  84578. +safe_reset_board(struct safe_softc *sc)
  84579. +{
  84580. + u_int32_t v;
  84581. + /*
  84582. + * Reset the device. The manual says no delay
  84583. + * is needed between marking and clearing reset.
  84584. + */
  84585. + DPRINTF(("%s()\n", __FUNCTION__));
  84586. +
  84587. + v = READ_REG(sc, SAFE_PE_DMACFG) &~
  84588. + (SAFE_PE_DMACFG_PERESET | SAFE_PE_DMACFG_PDRRESET |
  84589. + SAFE_PE_DMACFG_SGRESET);
  84590. + WRITE_REG(sc, SAFE_PE_DMACFG, v
  84591. + | SAFE_PE_DMACFG_PERESET
  84592. + | SAFE_PE_DMACFG_PDRRESET
  84593. + | SAFE_PE_DMACFG_SGRESET);
  84594. + WRITE_REG(sc, SAFE_PE_DMACFG, v);
  84595. +}
  84596. +
  84597. +/*
  84598. + * Initialize registers we need to touch only once.
  84599. + */
  84600. +static void
  84601. +safe_init_board(struct safe_softc *sc)
  84602. +{
  84603. + u_int32_t v, dwords;
  84604. +
  84605. + DPRINTF(("%s()\n", __FUNCTION__));
  84606. +
  84607. + v = READ_REG(sc, SAFE_PE_DMACFG);
  84608. + v &=~ ( SAFE_PE_DMACFG_PEMODE
  84609. + | SAFE_PE_DMACFG_FSENA /* failsafe enable */
  84610. + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
  84611. + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
  84612. + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
  84613. + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
  84614. + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
  84615. + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
  84616. + );
  84617. + v |= SAFE_PE_DMACFG_FSENA /* failsafe enable */
  84618. + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
  84619. + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
  84620. + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
  84621. + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
  84622. + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
  84623. +#if 0
  84624. + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
  84625. +#endif
  84626. + ;
  84627. + WRITE_REG(sc, SAFE_PE_DMACFG, v);
  84628. +
  84629. +#ifdef __BIG_ENDIAN
  84630. + /* tell the safenet that we are 4321 and not 1234 */
  84631. + WRITE_REG(sc, SAFE_ENDIAN, 0xe4e41b1b);
  84632. +#endif
  84633. +
  84634. + if (sc->sc_chiprev == SAFE_REV(1,0)) {
  84635. + /*
  84636. + * Avoid large PCI DMA transfers. Rev 1.0 has a bug where
  84637. + * "target mode transfers" done while the chip is DMA'ing
  84638. + * >1020 bytes cause the hardware to lockup. To avoid this
  84639. + * we reduce the max PCI transfer size and use small source
  84640. + * particle descriptors (<= 256 bytes).
  84641. + */
  84642. + WRITE_REG(sc, SAFE_DMA_CFG, 256);
  84643. + device_printf(sc->sc_dev,
  84644. + "Reduce max DMA size to %u words for rev %u.%u WAR\n",
  84645. + (unsigned) ((READ_REG(sc, SAFE_DMA_CFG)>>2) & 0xff),
  84646. + (unsigned) SAFE_REV_MAJ(sc->sc_chiprev),
  84647. + (unsigned) SAFE_REV_MIN(sc->sc_chiprev));
  84648. + sc->sc_max_dsize = 256;
  84649. + } else {
  84650. + sc->sc_max_dsize = SAFE_MAX_DSIZE;
  84651. + }
  84652. +
  84653. + /* NB: operands+results are overlaid */
  84654. + WRITE_REG(sc, SAFE_PE_PDRBASE, sc->sc_ringalloc.dma_paddr);
  84655. + WRITE_REG(sc, SAFE_PE_RDRBASE, sc->sc_ringalloc.dma_paddr);
  84656. + /*
  84657. + * Configure ring entry size and number of items in the ring.
  84658. + */
  84659. + KASSERT((sizeof(struct safe_ringentry) % sizeof(u_int32_t)) == 0,
  84660. + ("PE ring entry not 32-bit aligned!"));
  84661. + dwords = sizeof(struct safe_ringentry) / sizeof(u_int32_t);
  84662. + WRITE_REG(sc, SAFE_PE_RINGCFG,
  84663. + (dwords << SAFE_PE_RINGCFG_OFFSET_S) | SAFE_MAX_NQUEUE);
  84664. + WRITE_REG(sc, SAFE_PE_RINGPOLL, 0); /* disable polling */
  84665. +
  84666. + WRITE_REG(sc, SAFE_PE_GRNGBASE, sc->sc_spalloc.dma_paddr);
  84667. + WRITE_REG(sc, SAFE_PE_SRNGBASE, sc->sc_dpalloc.dma_paddr);
  84668. + WRITE_REG(sc, SAFE_PE_PARTSIZE,
  84669. + (SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART);
  84670. + /*
  84671. + * NB: destination particles are fixed size. We use
  84672. + * an mbuf cluster and require all results go to
  84673. + * clusters or smaller.
  84674. + */
  84675. + WRITE_REG(sc, SAFE_PE_PARTCFG, sc->sc_max_dsize);
  84676. +
  84677. + /* it's now safe to enable PE mode, do it */
  84678. + WRITE_REG(sc, SAFE_PE_DMACFG, v | SAFE_PE_DMACFG_PEMODE);
  84679. +
  84680. + /*
  84681. + * Configure hardware to use level-triggered interrupts and
  84682. + * to interrupt after each descriptor is processed.
  84683. + */
  84684. + WRITE_REG(sc, SAFE_HI_CFG, SAFE_HI_CFG_LEVEL);
  84685. + WRITE_REG(sc, SAFE_HI_CLR, 0xffffffff);
  84686. + WRITE_REG(sc, SAFE_HI_DESC_CNT, 1);
  84687. + WRITE_REG(sc, SAFE_HI_MASK, SAFE_INT_PE_DDONE | SAFE_INT_PE_ERROR);
  84688. +}
  84689. +
  84690. +
  84691. +/*
  84692. + * Clean up after a chip crash.
  84693. + * It is assumed that the caller in splimp()
  84694. + */
  84695. +static void
  84696. +safe_cleanchip(struct safe_softc *sc)
  84697. +{
  84698. + DPRINTF(("%s()\n", __FUNCTION__));
  84699. +
  84700. + if (sc->sc_nqchip != 0) {
  84701. + struct safe_ringentry *re = sc->sc_back;
  84702. +
  84703. + while (re != sc->sc_front) {
  84704. + if (re->re_desc.d_csr != 0)
  84705. + safe_free_entry(sc, re);
  84706. + if (++re == sc->sc_ringtop)
  84707. + re = sc->sc_ring;
  84708. + }
  84709. + sc->sc_back = re;
  84710. + sc->sc_nqchip = 0;
  84711. + }
  84712. +}
  84713. +
  84714. +/*
  84715. + * free a safe_q
  84716. + * It is assumed that the caller is within splimp().
  84717. + */
  84718. +static int
  84719. +safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re)
  84720. +{
  84721. + struct cryptop *crp;
  84722. +
  84723. + DPRINTF(("%s()\n", __FUNCTION__));
  84724. +
  84725. + /*
  84726. + * Free header MCR
  84727. + */
  84728. + if ((re->re_dst_skb != NULL) && (re->re_src_skb != re->re_dst_skb))
  84729. +#ifdef NOTYET
  84730. + m_freem(re->re_dst_m);
  84731. +#else
  84732. + printk("%s,%d: SKB not supported\n", __FILE__, __LINE__);
  84733. +#endif
  84734. +
  84735. + crp = (struct cryptop *)re->re_crp;
  84736. +
  84737. + re->re_desc.d_csr = 0;
  84738. +
  84739. + crp->crp_etype = EFAULT;
  84740. + crypto_done(crp);
  84741. + return(0);
  84742. +}
  84743. +
  84744. +/*
  84745. + * Routine to reset the chip and clean up.
  84746. + * It is assumed that the caller is in splimp()
  84747. + */
  84748. +static void
  84749. +safe_totalreset(struct safe_softc *sc)
  84750. +{
  84751. + DPRINTF(("%s()\n", __FUNCTION__));
  84752. +
  84753. + safe_reset_board(sc);
  84754. + safe_init_board(sc);
  84755. + safe_cleanchip(sc);
  84756. +}
  84757. +
  84758. +/*
  84759. + * Is the operand suitable aligned for direct DMA. Each
  84760. + * segment must be aligned on a 32-bit boundary and all
  84761. + * but the last segment must be a multiple of 4 bytes.
  84762. + */
  84763. +static int
  84764. +safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op)
  84765. +{
  84766. + int i;
  84767. +
  84768. + DPRINTF(("%s()\n", __FUNCTION__));
  84769. +
  84770. + for (i = 0; i < op->nsegs; i++) {
  84771. + if (op->segs[i].ds_addr & 3)
  84772. + return (0);
  84773. + if (i != (op->nsegs - 1) && (op->segs[i].ds_len & 3))
  84774. + return (0);
  84775. + }
  84776. + return (1);
  84777. +}
  84778. +
  84779. +/*
  84780. + * Is the operand suitable for direct DMA as the destination
  84781. + * of an operation. The hardware requires that each ``particle''
  84782. + * but the last in an operation result have the same size. We
  84783. + * fix that size at SAFE_MAX_DSIZE bytes. This routine returns
  84784. + * 0 if some segment is not a multiple of of this size, 1 if all
  84785. + * segments are exactly this size, or 2 if segments are at worst
  84786. + * a multple of this size.
  84787. + */
  84788. +static int
  84789. +safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op)
  84790. +{
  84791. + int result = 1;
  84792. +
  84793. + DPRINTF(("%s()\n", __FUNCTION__));
  84794. +
  84795. + if (op->nsegs > 0) {
  84796. + int i;
  84797. +
  84798. + for (i = 0; i < op->nsegs-1; i++) {
  84799. + if (op->segs[i].ds_len % sc->sc_max_dsize)
  84800. + return (0);
  84801. + if (op->segs[i].ds_len != sc->sc_max_dsize)
  84802. + result = 2;
  84803. + }
  84804. + }
  84805. + return (result);
  84806. +}
  84807. +
  84808. +static int
  84809. +safe_kprocess(device_t dev, struct cryptkop *krp, int hint)
  84810. +{
  84811. + struct safe_softc *sc = device_get_softc(dev);
  84812. + struct safe_pkq *q;
  84813. + unsigned long flags;
  84814. +
  84815. + DPRINTF(("%s()\n", __FUNCTION__));
  84816. +
  84817. + if (sc == NULL) {
  84818. + krp->krp_status = EINVAL;
  84819. + goto err;
  84820. + }
  84821. +
  84822. + if (krp->krp_op != CRK_MOD_EXP) {
  84823. + krp->krp_status = EOPNOTSUPP;
  84824. + goto err;
  84825. + }
  84826. +
  84827. + q = (struct safe_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
  84828. + if (q == NULL) {
  84829. + krp->krp_status = ENOMEM;
  84830. + goto err;
  84831. + }
  84832. + memset(q, 0, sizeof(*q));
  84833. + q->pkq_krp = krp;
  84834. + INIT_LIST_HEAD(&q->pkq_list);
  84835. +
  84836. + spin_lock_irqsave(&sc->sc_pkmtx, flags);
  84837. + list_add_tail(&q->pkq_list, &sc->sc_pkq);
  84838. + safe_kfeed(sc);
  84839. + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
  84840. + return (0);
  84841. +
  84842. +err:
  84843. + crypto_kdone(krp);
  84844. + return (0);
  84845. +}
  84846. +
  84847. +#define SAFE_CRK_PARAM_BASE 0
  84848. +#define SAFE_CRK_PARAM_EXP 1
  84849. +#define SAFE_CRK_PARAM_MOD 2
  84850. +
  84851. +static int
  84852. +safe_kstart(struct safe_softc *sc)
  84853. +{
  84854. + struct cryptkop *krp = sc->sc_pkq_cur->pkq_krp;
  84855. + int exp_bits, mod_bits, base_bits;
  84856. + u_int32_t op, a_off, b_off, c_off, d_off;
  84857. +
  84858. + DPRINTF(("%s()\n", __FUNCTION__));
  84859. +
  84860. + if (krp->krp_iparams < 3 || krp->krp_oparams != 1) {
  84861. + krp->krp_status = EINVAL;
  84862. + return (1);
  84863. + }
  84864. +
  84865. + base_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_BASE]);
  84866. + if (base_bits > 2048)
  84867. + goto too_big;
  84868. + if (base_bits <= 0) /* 5. base not zero */
  84869. + goto too_small;
  84870. +
  84871. + exp_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_EXP]);
  84872. + if (exp_bits > 2048)
  84873. + goto too_big;
  84874. + if (exp_bits <= 0) /* 1. exponent word length > 0 */
  84875. + goto too_small; /* 4. exponent not zero */
  84876. +
  84877. + mod_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_MOD]);
  84878. + if (mod_bits > 2048)
  84879. + goto too_big;
  84880. + if (mod_bits <= 32) /* 2. modulus word length > 1 */
  84881. + goto too_small; /* 8. MSW of modulus != zero */
  84882. + if (mod_bits < exp_bits) /* 3 modulus len >= exponent len */
  84883. + goto too_small;
  84884. + if ((krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p[0] & 1) == 0)
  84885. + goto bad_domain; /* 6. modulus is odd */
  84886. + if (mod_bits > krp->krp_param[krp->krp_iparams].crp_nbits)
  84887. + goto too_small; /* make sure result will fit */
  84888. +
  84889. + /* 7. modulus > base */
  84890. + if (mod_bits < base_bits)
  84891. + goto too_small;
  84892. + if (mod_bits == base_bits) {
  84893. + u_int8_t *basep, *modp;
  84894. + int i;
  84895. +
  84896. + basep = krp->krp_param[SAFE_CRK_PARAM_BASE].crp_p +
  84897. + ((base_bits + 7) / 8) - 1;
  84898. + modp = krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p +
  84899. + ((mod_bits + 7) / 8) - 1;
  84900. +
  84901. + for (i = 0; i < (mod_bits + 7) / 8; i++, basep--, modp--) {
  84902. + if (*modp < *basep)
  84903. + goto too_small;
  84904. + if (*modp > *basep)
  84905. + break;
  84906. + }
  84907. + }
  84908. +
  84909. + /* And on the 9th step, he rested. */
  84910. +
  84911. + WRITE_REG(sc, SAFE_PK_A_LEN, (exp_bits + 31) / 32);
  84912. + WRITE_REG(sc, SAFE_PK_B_LEN, (mod_bits + 31) / 32);
  84913. + if (mod_bits > 1024) {
  84914. + op = SAFE_PK_FUNC_EXP4;
  84915. + a_off = 0x000;
  84916. + b_off = 0x100;
  84917. + c_off = 0x200;
  84918. + d_off = 0x300;
  84919. + } else {
  84920. + op = SAFE_PK_FUNC_EXP16;
  84921. + a_off = 0x000;
  84922. + b_off = 0x080;
  84923. + c_off = 0x100;
  84924. + d_off = 0x180;
  84925. + }
  84926. + sc->sc_pk_reslen = b_off - a_off;
  84927. + sc->sc_pk_resoff = d_off;
  84928. +
  84929. + /* A is exponent, B is modulus, C is base, D is result */
  84930. + safe_kload_reg(sc, a_off, b_off - a_off,
  84931. + &krp->krp_param[SAFE_CRK_PARAM_EXP]);
  84932. + WRITE_REG(sc, SAFE_PK_A_ADDR, a_off >> 2);
  84933. + safe_kload_reg(sc, b_off, b_off - a_off,
  84934. + &krp->krp_param[SAFE_CRK_PARAM_MOD]);
  84935. + WRITE_REG(sc, SAFE_PK_B_ADDR, b_off >> 2);
  84936. + safe_kload_reg(sc, c_off, b_off - a_off,
  84937. + &krp->krp_param[SAFE_CRK_PARAM_BASE]);
  84938. + WRITE_REG(sc, SAFE_PK_C_ADDR, c_off >> 2);
  84939. + WRITE_REG(sc, SAFE_PK_D_ADDR, d_off >> 2);
  84940. +
  84941. + WRITE_REG(sc, SAFE_PK_FUNC, op | SAFE_PK_FUNC_RUN);
  84942. +
  84943. + return (0);
  84944. +
  84945. +too_big:
  84946. + krp->krp_status = E2BIG;
  84947. + return (1);
  84948. +too_small:
  84949. + krp->krp_status = ERANGE;
  84950. + return (1);
  84951. +bad_domain:
  84952. + krp->krp_status = EDOM;
  84953. + return (1);
  84954. +}
  84955. +
  84956. +static int
  84957. +safe_ksigbits(struct safe_softc *sc, struct crparam *cr)
  84958. +{
  84959. + u_int plen = (cr->crp_nbits + 7) / 8;
  84960. + int i, sig = plen * 8;
  84961. + u_int8_t c, *p = cr->crp_p;
  84962. +
  84963. + DPRINTF(("%s()\n", __FUNCTION__));
  84964. +
  84965. + for (i = plen - 1; i >= 0; i--) {
  84966. + c = p[i];
  84967. + if (c != 0) {
  84968. + while ((c & 0x80) == 0) {
  84969. + sig--;
  84970. + c <<= 1;
  84971. + }
  84972. + break;
  84973. + }
  84974. + sig -= 8;
  84975. + }
  84976. + return (sig);
  84977. +}
  84978. +
  84979. +static void
  84980. +safe_kfeed(struct safe_softc *sc)
  84981. +{
  84982. + struct safe_pkq *q, *tmp;
  84983. +
  84984. + DPRINTF(("%s()\n", __FUNCTION__));
  84985. +
  84986. + if (list_empty(&sc->sc_pkq) && sc->sc_pkq_cur == NULL)
  84987. + return;
  84988. + if (sc->sc_pkq_cur != NULL)
  84989. + return;
  84990. + list_for_each_entry_safe(q, tmp, &sc->sc_pkq, pkq_list) {
  84991. + sc->sc_pkq_cur = q;
  84992. + list_del(&q->pkq_list);
  84993. + if (safe_kstart(sc) != 0) {
  84994. + crypto_kdone(q->pkq_krp);
  84995. + kfree(q);
  84996. + sc->sc_pkq_cur = NULL;
  84997. + } else {
  84998. + /* op started, start polling */
  84999. + mod_timer(&sc->sc_pkto, jiffies + 1);
  85000. + break;
  85001. + }
  85002. + }
  85003. +}
  85004. +
  85005. +static void
  85006. +safe_kpoll(unsigned long arg)
  85007. +{
  85008. + struct safe_softc *sc = NULL;
  85009. + struct safe_pkq *q;
  85010. + struct crparam *res;
  85011. + int i;
  85012. + u_int32_t buf[64];
  85013. + unsigned long flags;
  85014. +
  85015. + DPRINTF(("%s()\n", __FUNCTION__));
  85016. +
  85017. + if (arg >= SAFE_MAX_CHIPS)
  85018. + return;
  85019. + sc = safe_chip_idx[arg];
  85020. + if (!sc) {
  85021. + DPRINTF(("%s() - bad callback\n", __FUNCTION__));
  85022. + return;
  85023. + }
  85024. +
  85025. + spin_lock_irqsave(&sc->sc_pkmtx, flags);
  85026. + if (sc->sc_pkq_cur == NULL)
  85027. + goto out;
  85028. + if (READ_REG(sc, SAFE_PK_FUNC) & SAFE_PK_FUNC_RUN) {
  85029. + /* still running, check back later */
  85030. + mod_timer(&sc->sc_pkto, jiffies + 1);
  85031. + goto out;
  85032. + }
  85033. +
  85034. + q = sc->sc_pkq_cur;
  85035. + res = &q->pkq_krp->krp_param[q->pkq_krp->krp_iparams];
  85036. + bzero(buf, sizeof(buf));
  85037. + bzero(res->crp_p, (res->crp_nbits + 7) / 8);
  85038. + for (i = 0; i < sc->sc_pk_reslen >> 2; i++)
  85039. + buf[i] = le32_to_cpu(READ_REG(sc, SAFE_PK_RAM_START +
  85040. + sc->sc_pk_resoff + (i << 2)));
  85041. + bcopy(buf, res->crp_p, (res->crp_nbits + 7) / 8);
  85042. + /*
  85043. + * reduce the bits that need copying if possible
  85044. + */
  85045. + res->crp_nbits = min(res->crp_nbits,sc->sc_pk_reslen * 8);
  85046. + res->crp_nbits = safe_ksigbits(sc, res);
  85047. +
  85048. + for (i = SAFE_PK_RAM_START; i < SAFE_PK_RAM_END; i += 4)
  85049. + WRITE_REG(sc, i, 0);
  85050. +
  85051. + crypto_kdone(q->pkq_krp);
  85052. + kfree(q);
  85053. + sc->sc_pkq_cur = NULL;
  85054. +
  85055. + safe_kfeed(sc);
  85056. +out:
  85057. + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
  85058. +}
  85059. +
  85060. +static void
  85061. +safe_kload_reg(struct safe_softc *sc, u_int32_t off, u_int32_t len,
  85062. + struct crparam *n)
  85063. +{
  85064. + u_int32_t buf[64], i;
  85065. +
  85066. + DPRINTF(("%s()\n", __FUNCTION__));
  85067. +
  85068. + bzero(buf, sizeof(buf));
  85069. + bcopy(n->crp_p, buf, (n->crp_nbits + 7) / 8);
  85070. +
  85071. + for (i = 0; i < len >> 2; i++)
  85072. + WRITE_REG(sc, SAFE_PK_RAM_START + off + (i << 2),
  85073. + cpu_to_le32(buf[i]));
  85074. +}
  85075. +
  85076. +#ifdef SAFE_DEBUG
  85077. +static void
  85078. +safe_dump_dmastatus(struct safe_softc *sc, const char *tag)
  85079. +{
  85080. + printf("%s: ENDIAN 0x%x SRC 0x%x DST 0x%x STAT 0x%x\n"
  85081. + , tag
  85082. + , READ_REG(sc, SAFE_DMA_ENDIAN)
  85083. + , READ_REG(sc, SAFE_DMA_SRCADDR)
  85084. + , READ_REG(sc, SAFE_DMA_DSTADDR)
  85085. + , READ_REG(sc, SAFE_DMA_STAT)
  85086. + );
  85087. +}
  85088. +
  85089. +static void
  85090. +safe_dump_intrstate(struct safe_softc *sc, const char *tag)
  85091. +{
  85092. + printf("%s: HI_CFG 0x%x HI_MASK 0x%x HI_DESC_CNT 0x%x HU_STAT 0x%x HM_STAT 0x%x\n"
  85093. + , tag
  85094. + , READ_REG(sc, SAFE_HI_CFG)
  85095. + , READ_REG(sc, SAFE_HI_MASK)
  85096. + , READ_REG(sc, SAFE_HI_DESC_CNT)
  85097. + , READ_REG(sc, SAFE_HU_STAT)
  85098. + , READ_REG(sc, SAFE_HM_STAT)
  85099. + );
  85100. +}
  85101. +
  85102. +static void
  85103. +safe_dump_ringstate(struct safe_softc *sc, const char *tag)
  85104. +{
  85105. + u_int32_t estat = READ_REG(sc, SAFE_PE_ERNGSTAT);
  85106. +
  85107. + /* NB: assume caller has lock on ring */
  85108. + printf("%s: ERNGSTAT %x (next %u) back %lu front %lu\n",
  85109. + tag,
  85110. + estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S),
  85111. + (unsigned long)(sc->sc_back - sc->sc_ring),
  85112. + (unsigned long)(sc->sc_front - sc->sc_ring));
  85113. +}
  85114. +
  85115. +static void
  85116. +safe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re)
  85117. +{
  85118. + int ix, nsegs;
  85119. +
  85120. + ix = re - sc->sc_ring;
  85121. + printf("%s: %p (%u): csr %x src %x dst %x sa %x len %x\n"
  85122. + , tag
  85123. + , re, ix
  85124. + , re->re_desc.d_csr
  85125. + , re->re_desc.d_src
  85126. + , re->re_desc.d_dst
  85127. + , re->re_desc.d_sa
  85128. + , re->re_desc.d_len
  85129. + );
  85130. + if (re->re_src.nsegs > 1) {
  85131. + ix = (re->re_desc.d_src - sc->sc_spalloc.dma_paddr) /
  85132. + sizeof(struct safe_pdesc);
  85133. + for (nsegs = re->re_src.nsegs; nsegs; nsegs--) {
  85134. + printf(" spd[%u] %p: %p size %u flags %x"
  85135. + , ix, &sc->sc_spring[ix]
  85136. + , (caddr_t)(uintptr_t) sc->sc_spring[ix].pd_addr
  85137. + , sc->sc_spring[ix].pd_size
  85138. + , sc->sc_spring[ix].pd_flags
  85139. + );
  85140. + if (sc->sc_spring[ix].pd_size == 0)
  85141. + printf(" (zero!)");
  85142. + printf("\n");
  85143. + if (++ix == SAFE_TOTAL_SPART)
  85144. + ix = 0;
  85145. + }
  85146. + }
  85147. + if (re->re_dst.nsegs > 1) {
  85148. + ix = (re->re_desc.d_dst - sc->sc_dpalloc.dma_paddr) /
  85149. + sizeof(struct safe_pdesc);
  85150. + for (nsegs = re->re_dst.nsegs; nsegs; nsegs--) {
  85151. + printf(" dpd[%u] %p: %p flags %x\n"
  85152. + , ix, &sc->sc_dpring[ix]
  85153. + , (caddr_t)(uintptr_t) sc->sc_dpring[ix].pd_addr
  85154. + , sc->sc_dpring[ix].pd_flags
  85155. + );
  85156. + if (++ix == SAFE_TOTAL_DPART)
  85157. + ix = 0;
  85158. + }
  85159. + }
  85160. + printf("sa: cmd0 %08x cmd1 %08x staterec %x\n",
  85161. + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec);
  85162. + printf("sa: key %x %x %x %x %x %x %x %x\n"
  85163. + , re->re_sa.sa_key[0]
  85164. + , re->re_sa.sa_key[1]
  85165. + , re->re_sa.sa_key[2]
  85166. + , re->re_sa.sa_key[3]
  85167. + , re->re_sa.sa_key[4]
  85168. + , re->re_sa.sa_key[5]
  85169. + , re->re_sa.sa_key[6]
  85170. + , re->re_sa.sa_key[7]
  85171. + );
  85172. + printf("sa: indigest %x %x %x %x %x\n"
  85173. + , re->re_sa.sa_indigest[0]
  85174. + , re->re_sa.sa_indigest[1]
  85175. + , re->re_sa.sa_indigest[2]
  85176. + , re->re_sa.sa_indigest[3]
  85177. + , re->re_sa.sa_indigest[4]
  85178. + );
  85179. + printf("sa: outdigest %x %x %x %x %x\n"
  85180. + , re->re_sa.sa_outdigest[0]
  85181. + , re->re_sa.sa_outdigest[1]
  85182. + , re->re_sa.sa_outdigest[2]
  85183. + , re->re_sa.sa_outdigest[3]
  85184. + , re->re_sa.sa_outdigest[4]
  85185. + );
  85186. + printf("sr: iv %x %x %x %x\n"
  85187. + , re->re_sastate.sa_saved_iv[0]
  85188. + , re->re_sastate.sa_saved_iv[1]
  85189. + , re->re_sastate.sa_saved_iv[2]
  85190. + , re->re_sastate.sa_saved_iv[3]
  85191. + );
  85192. + printf("sr: hashbc %u indigest %x %x %x %x %x\n"
  85193. + , re->re_sastate.sa_saved_hashbc
  85194. + , re->re_sastate.sa_saved_indigest[0]
  85195. + , re->re_sastate.sa_saved_indigest[1]
  85196. + , re->re_sastate.sa_saved_indigest[2]
  85197. + , re->re_sastate.sa_saved_indigest[3]
  85198. + , re->re_sastate.sa_saved_indigest[4]
  85199. + );
  85200. +}
  85201. +
  85202. +static void
  85203. +safe_dump_ring(struct safe_softc *sc, const char *tag)
  85204. +{
  85205. + unsigned long flags;
  85206. +
  85207. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  85208. + printf("\nSafeNet Ring State:\n");
  85209. + safe_dump_intrstate(sc, tag);
  85210. + safe_dump_dmastatus(sc, tag);
  85211. + safe_dump_ringstate(sc, tag);
  85212. + if (sc->sc_nqchip) {
  85213. + struct safe_ringentry *re = sc->sc_back;
  85214. + do {
  85215. + safe_dump_request(sc, tag, re);
  85216. + if (++re == sc->sc_ringtop)
  85217. + re = sc->sc_ring;
  85218. + } while (re != sc->sc_front);
  85219. + }
  85220. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  85221. +}
  85222. +#endif /* SAFE_DEBUG */
  85223. +
  85224. +
  85225. +static int safe_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  85226. +{
  85227. + struct safe_softc *sc = NULL;
  85228. + u32 mem_start, mem_len, cmd;
  85229. + int i, rc, devinfo;
  85230. + dma_addr_t raddr;
  85231. + static int num_chips = 0;
  85232. +
  85233. + DPRINTF(("%s()\n", __FUNCTION__));
  85234. +
  85235. + if (pci_enable_device(dev) < 0)
  85236. + return(-ENODEV);
  85237. +
  85238. + if (!dev->irq) {
  85239. + printk("safe: found device with no IRQ assigned. check BIOS settings!");
  85240. + pci_disable_device(dev);
  85241. + return(-ENODEV);
  85242. + }
  85243. +
  85244. + if (pci_set_mwi(dev)) {
  85245. + printk("safe: pci_set_mwi failed!");
  85246. + return(-ENODEV);
  85247. + }
  85248. +
  85249. + sc = (struct safe_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  85250. + if (!sc)
  85251. + return(-ENOMEM);
  85252. + memset(sc, 0, sizeof(*sc));
  85253. +
  85254. + softc_device_init(sc, "safe", num_chips, safe_methods);
  85255. +
  85256. + sc->sc_irq = -1;
  85257. + sc->sc_cid = -1;
  85258. + sc->sc_pcidev = dev;
  85259. + if (num_chips < SAFE_MAX_CHIPS) {
  85260. + safe_chip_idx[device_get_unit(sc->sc_dev)] = sc;
  85261. + num_chips++;
  85262. + }
  85263. +
  85264. + INIT_LIST_HEAD(&sc->sc_pkq);
  85265. + spin_lock_init(&sc->sc_pkmtx);
  85266. +
  85267. + pci_set_drvdata(sc->sc_pcidev, sc);
  85268. +
  85269. + /* we read its hardware registers as memory */
  85270. + mem_start = pci_resource_start(sc->sc_pcidev, 0);
  85271. + mem_len = pci_resource_len(sc->sc_pcidev, 0);
  85272. +
  85273. + sc->sc_base_addr = (ocf_iomem_t) ioremap(mem_start, mem_len);
  85274. + if (!sc->sc_base_addr) {
  85275. + device_printf(sc->sc_dev, "failed to ioremap 0x%x-0x%x\n",
  85276. + mem_start, mem_start + mem_len - 1);
  85277. + goto out;
  85278. + }
  85279. +
  85280. + /* fix up the bus size */
  85281. + if (pci_set_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
  85282. + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
  85283. + goto out;
  85284. + }
  85285. + if (pci_set_consistent_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
  85286. + device_printf(sc->sc_dev, "No usable consistent DMA configuration, aborting.\n");
  85287. + goto out;
  85288. + }
  85289. +
  85290. + pci_set_master(sc->sc_pcidev);
  85291. +
  85292. + pci_read_config_dword(sc->sc_pcidev, PCI_COMMAND, &cmd);
  85293. +
  85294. + if (!(cmd & PCI_COMMAND_MEMORY)) {
  85295. + device_printf(sc->sc_dev, "failed to enable memory mapping\n");
  85296. + goto out;
  85297. + }
  85298. +
  85299. + if (!(cmd & PCI_COMMAND_MASTER)) {
  85300. + device_printf(sc->sc_dev, "failed to enable bus mastering\n");
  85301. + goto out;
  85302. + }
  85303. +
  85304. + rc = request_irq(dev->irq, safe_intr, IRQF_SHARED, "safe", sc);
  85305. + if (rc) {
  85306. + device_printf(sc->sc_dev, "failed to hook irq %d\n", sc->sc_irq);
  85307. + goto out;
  85308. + }
  85309. + sc->sc_irq = dev->irq;
  85310. +
  85311. + sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) &
  85312. + (SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN);
  85313. +
  85314. + /*
  85315. + * Allocate packet engine descriptors.
  85316. + */
  85317. + sc->sc_ringalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  85318. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  85319. + &sc->sc_ringalloc.dma_paddr);
  85320. + if (!sc->sc_ringalloc.dma_vaddr) {
  85321. + device_printf(sc->sc_dev, "cannot allocate PE descriptor ring\n");
  85322. + goto out;
  85323. + }
  85324. +
  85325. + /*
  85326. + * Hookup the static portion of all our data structures.
  85327. + */
  85328. + sc->sc_ring = (struct safe_ringentry *) sc->sc_ringalloc.dma_vaddr;
  85329. + sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE;
  85330. + sc->sc_front = sc->sc_ring;
  85331. + sc->sc_back = sc->sc_ring;
  85332. + raddr = sc->sc_ringalloc.dma_paddr;
  85333. + bzero(sc->sc_ring, SAFE_MAX_NQUEUE * sizeof(struct safe_ringentry));
  85334. + for (i = 0; i < SAFE_MAX_NQUEUE; i++) {
  85335. + struct safe_ringentry *re = &sc->sc_ring[i];
  85336. +
  85337. + re->re_desc.d_sa = raddr +
  85338. + offsetof(struct safe_ringentry, re_sa);
  85339. + re->re_sa.sa_staterec = raddr +
  85340. + offsetof(struct safe_ringentry, re_sastate);
  85341. +
  85342. + raddr += sizeof (struct safe_ringentry);
  85343. + }
  85344. + spin_lock_init(&sc->sc_ringmtx);
  85345. +
  85346. + /*
  85347. + * Allocate scatter and gather particle descriptors.
  85348. + */
  85349. + sc->sc_spalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  85350. + SAFE_TOTAL_SPART * sizeof (struct safe_pdesc),
  85351. + &sc->sc_spalloc.dma_paddr);
  85352. + if (!sc->sc_spalloc.dma_vaddr) {
  85353. + device_printf(sc->sc_dev, "cannot allocate source particle descriptor ring\n");
  85354. + goto out;
  85355. + }
  85356. + sc->sc_spring = (struct safe_pdesc *) sc->sc_spalloc.dma_vaddr;
  85357. + sc->sc_springtop = sc->sc_spring + SAFE_TOTAL_SPART;
  85358. + sc->sc_spfree = sc->sc_spring;
  85359. + bzero(sc->sc_spring, SAFE_TOTAL_SPART * sizeof(struct safe_pdesc));
  85360. +
  85361. + sc->sc_dpalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  85362. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  85363. + &sc->sc_dpalloc.dma_paddr);
  85364. + if (!sc->sc_dpalloc.dma_vaddr) {
  85365. + device_printf(sc->sc_dev, "cannot allocate destination particle descriptor ring\n");
  85366. + goto out;
  85367. + }
  85368. + sc->sc_dpring = (struct safe_pdesc *) sc->sc_dpalloc.dma_vaddr;
  85369. + sc->sc_dpringtop = sc->sc_dpring + SAFE_TOTAL_DPART;
  85370. + sc->sc_dpfree = sc->sc_dpring;
  85371. + bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc));
  85372. +
  85373. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc), CRYPTOCAP_F_HARDWARE);
  85374. + if (sc->sc_cid < 0) {
  85375. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  85376. + goto out;
  85377. + }
  85378. +
  85379. + printf("%s:", device_get_nameunit(sc->sc_dev));
  85380. +
  85381. + devinfo = READ_REG(sc, SAFE_DEVINFO);
  85382. + if (devinfo & SAFE_DEVINFO_RNG) {
  85383. + sc->sc_flags |= SAFE_FLAGS_RNG;
  85384. + printf(" rng");
  85385. + }
  85386. + if (devinfo & SAFE_DEVINFO_PKEY) {
  85387. + printf(" key");
  85388. + sc->sc_flags |= SAFE_FLAGS_KEY;
  85389. + crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0);
  85390. +#if 0
  85391. + crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0);
  85392. +#endif
  85393. + init_timer(&sc->sc_pkto);
  85394. + sc->sc_pkto.function = safe_kpoll;
  85395. + sc->sc_pkto.data = (unsigned long) device_get_unit(sc->sc_dev);
  85396. + }
  85397. + if (devinfo & SAFE_DEVINFO_DES) {
  85398. + printf(" des/3des");
  85399. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  85400. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  85401. + }
  85402. + if (devinfo & SAFE_DEVINFO_AES) {
  85403. + printf(" aes");
  85404. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  85405. + }
  85406. + if (devinfo & SAFE_DEVINFO_MD5) {
  85407. + printf(" md5");
  85408. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  85409. + }
  85410. + if (devinfo & SAFE_DEVINFO_SHA1) {
  85411. + printf(" sha1");
  85412. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  85413. + }
  85414. + printf(" null");
  85415. + crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0);
  85416. + crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0);
  85417. + /* XXX other supported algorithms */
  85418. + printf("\n");
  85419. +
  85420. + safe_reset_board(sc); /* reset h/w */
  85421. + safe_init_board(sc); /* init h/w */
  85422. +
  85423. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  85424. + if (sc->sc_flags & SAFE_FLAGS_RNG) {
  85425. + safe_rng_init(sc);
  85426. + crypto_rregister(sc->sc_cid, safe_read_random, sc);
  85427. + }
  85428. +#endif /* SAFE_NO_RNG */
  85429. +
  85430. + return (0);
  85431. +
  85432. +out:
  85433. + if (sc->sc_cid >= 0)
  85434. + crypto_unregister_all(sc->sc_cid);
  85435. + if (sc->sc_irq != -1)
  85436. + free_irq(sc->sc_irq, sc);
  85437. + if (sc->sc_ringalloc.dma_vaddr)
  85438. + pci_free_consistent(sc->sc_pcidev,
  85439. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  85440. + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
  85441. + if (sc->sc_spalloc.dma_vaddr)
  85442. + pci_free_consistent(sc->sc_pcidev,
  85443. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  85444. + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
  85445. + if (sc->sc_dpalloc.dma_vaddr)
  85446. + pci_free_consistent(sc->sc_pcidev,
  85447. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  85448. + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
  85449. + kfree(sc);
  85450. + return(-ENODEV);
  85451. +}
  85452. +
  85453. +static void safe_remove(struct pci_dev *dev)
  85454. +{
  85455. + struct safe_softc *sc = pci_get_drvdata(dev);
  85456. +
  85457. + DPRINTF(("%s()\n", __FUNCTION__));
  85458. +
  85459. + /* XXX wait/abort active ops */
  85460. +
  85461. + WRITE_REG(sc, SAFE_HI_MASK, 0); /* disable interrupts */
  85462. +
  85463. + del_timer_sync(&sc->sc_pkto);
  85464. +
  85465. + crypto_unregister_all(sc->sc_cid);
  85466. +
  85467. + safe_cleanchip(sc);
  85468. +
  85469. + if (sc->sc_irq != -1)
  85470. + free_irq(sc->sc_irq, sc);
  85471. + if (sc->sc_ringalloc.dma_vaddr)
  85472. + pci_free_consistent(sc->sc_pcidev,
  85473. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  85474. + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
  85475. + if (sc->sc_spalloc.dma_vaddr)
  85476. + pci_free_consistent(sc->sc_pcidev,
  85477. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  85478. + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
  85479. + if (sc->sc_dpalloc.dma_vaddr)
  85480. + pci_free_consistent(sc->sc_pcidev,
  85481. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  85482. + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
  85483. + sc->sc_irq = -1;
  85484. + sc->sc_ringalloc.dma_vaddr = NULL;
  85485. + sc->sc_spalloc.dma_vaddr = NULL;
  85486. + sc->sc_dpalloc.dma_vaddr = NULL;
  85487. +}
  85488. +
  85489. +static struct pci_device_id safe_pci_tbl[] = {
  85490. + { PCI_VENDOR_SAFENET, PCI_PRODUCT_SAFEXCEL,
  85491. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  85492. + { },
  85493. +};
  85494. +MODULE_DEVICE_TABLE(pci, safe_pci_tbl);
  85495. +
  85496. +static struct pci_driver safe_driver = {
  85497. + .name = "safe",
  85498. + .id_table = safe_pci_tbl,
  85499. + .probe = safe_probe,
  85500. + .remove = safe_remove,
  85501. + /* add PM stuff here one day */
  85502. +};
  85503. +
  85504. +static int __init safe_init (void)
  85505. +{
  85506. + struct safe_softc *sc = NULL;
  85507. + int rc;
  85508. +
  85509. + DPRINTF(("%s(%p)\n", __FUNCTION__, safe_init));
  85510. +
  85511. + rc = pci_register_driver(&safe_driver);
  85512. + pci_register_driver_compat(&safe_driver, rc);
  85513. +
  85514. + return rc;
  85515. +}
  85516. +
  85517. +static void __exit safe_exit (void)
  85518. +{
  85519. + pci_unregister_driver(&safe_driver);
  85520. +}
  85521. +
  85522. +module_init(safe_init);
  85523. +module_exit(safe_exit);
  85524. +
  85525. +MODULE_LICENSE("BSD");
  85526. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  85527. +MODULE_DESCRIPTION("OCF driver for safenet PCI crypto devices");
  85528. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/safereg.h linux-2.6.39/crypto/ocf/safe/safereg.h
  85529. --- linux-2.6.39.orig/crypto/ocf/safe/safereg.h 1970-01-01 01:00:00.000000000 +0100
  85530. +++ linux-2.6.39/crypto/ocf/safe/safereg.h 2011-07-31 11:32:03.353424583 +0200
  85531. @@ -0,0 +1,421 @@
  85532. +/*-
  85533. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  85534. + * Copyright (c) 2003 Global Technology Associates, Inc.
  85535. + * All rights reserved.
  85536. + *
  85537. + * Redistribution and use in source and binary forms, with or without
  85538. + * modification, are permitted provided that the following conditions
  85539. + * are met:
  85540. + * 1. Redistributions of source code must retain the above copyright
  85541. + * notice, this list of conditions and the following disclaimer.
  85542. + * 2. Redistributions in binary form must reproduce the above copyright
  85543. + * notice, this list of conditions and the following disclaimer in the
  85544. + * documentation and/or other materials provided with the distribution.
  85545. + *
  85546. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  85547. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  85548. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  85549. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  85550. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  85551. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  85552. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  85553. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  85554. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  85555. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  85556. + * SUCH DAMAGE.
  85557. + *
  85558. + * $FreeBSD: src/sys/dev/safe/safereg.h,v 1.1 2003/07/21 21:46:07 sam Exp $
  85559. + */
  85560. +#ifndef _SAFE_SAFEREG_H_
  85561. +#define _SAFE_SAFEREG_H_
  85562. +
  85563. +/*
  85564. + * Register definitions for SafeNet SafeXcel-1141 crypto device.
  85565. + * Definitions from revision 1.3 (Nov 6 2002) of the User's Manual.
  85566. + */
  85567. +
  85568. +#define BS_BAR 0x10 /* DMA base address register */
  85569. +#define BS_TRDY_TIMEOUT 0x40 /* TRDY timeout */
  85570. +#define BS_RETRY_TIMEOUT 0x41 /* DMA retry timeout */
  85571. +
  85572. +#define PCI_VENDOR_SAFENET 0x16ae /* SafeNet, Inc. */
  85573. +
  85574. +/* SafeNet */
  85575. +#define PCI_PRODUCT_SAFEXCEL 0x1141 /* 1141 */
  85576. +
  85577. +#define SAFE_PE_CSR 0x0000 /* Packet Enginge Ctrl/Status */
  85578. +#define SAFE_PE_SRC 0x0004 /* Packet Engine Source */
  85579. +#define SAFE_PE_DST 0x0008 /* Packet Engine Destination */
  85580. +#define SAFE_PE_SA 0x000c /* Packet Engine SA */
  85581. +#define SAFE_PE_LEN 0x0010 /* Packet Engine Length */
  85582. +#define SAFE_PE_DMACFG 0x0040 /* Packet Engine DMA Configuration */
  85583. +#define SAFE_PE_DMASTAT 0x0044 /* Packet Engine DMA Status */
  85584. +#define SAFE_PE_PDRBASE 0x0048 /* Packet Engine Descriptor Ring Base */
  85585. +#define SAFE_PE_RDRBASE 0x004c /* Packet Engine Result Ring Base */
  85586. +#define SAFE_PE_RINGCFG 0x0050 /* Packet Engine Ring Configuration */
  85587. +#define SAFE_PE_RINGPOLL 0x0054 /* Packet Engine Ring Poll */
  85588. +#define SAFE_PE_IRNGSTAT 0x0058 /* Packet Engine Internal Ring Status */
  85589. +#define SAFE_PE_ERNGSTAT 0x005c /* Packet Engine External Ring Status */
  85590. +#define SAFE_PE_IOTHRESH 0x0060 /* Packet Engine I/O Threshold */
  85591. +#define SAFE_PE_GRNGBASE 0x0064 /* Packet Engine Gather Ring Base */
  85592. +#define SAFE_PE_SRNGBASE 0x0068 /* Packet Engine Scatter Ring Base */
  85593. +#define SAFE_PE_PARTSIZE 0x006c /* Packet Engine Particlar Ring Size */
  85594. +#define SAFE_PE_PARTCFG 0x0070 /* Packet Engine Particle Ring Config */
  85595. +#define SAFE_CRYPTO_CTRL 0x0080 /* Crypto Control */
  85596. +#define SAFE_DEVID 0x0084 /* Device ID */
  85597. +#define SAFE_DEVINFO 0x0088 /* Device Info */
  85598. +#define SAFE_HU_STAT 0x00a0 /* Host Unmasked Status */
  85599. +#define SAFE_HM_STAT 0x00a4 /* Host Masked Status (read-only) */
  85600. +#define SAFE_HI_CLR 0x00a4 /* Host Clear Interrupt (write-only) */
  85601. +#define SAFE_HI_MASK 0x00a8 /* Host Mask Control */
  85602. +#define SAFE_HI_CFG 0x00ac /* Interrupt Configuration */
  85603. +#define SAFE_HI_RD_DESCR 0x00b4 /* Force Descriptor Read */
  85604. +#define SAFE_HI_DESC_CNT 0x00b8 /* Host Descriptor Done Count */
  85605. +#define SAFE_DMA_ENDIAN 0x00c0 /* Master Endian Status */
  85606. +#define SAFE_DMA_SRCADDR 0x00c4 /* DMA Source Address Status */
  85607. +#define SAFE_DMA_DSTADDR 0x00c8 /* DMA Destination Address Status */
  85608. +#define SAFE_DMA_STAT 0x00cc /* DMA Current Status */
  85609. +#define SAFE_DMA_CFG 0x00d4 /* DMA Configuration/Status */
  85610. +#define SAFE_ENDIAN 0x00e0 /* Endian Configuration */
  85611. +#define SAFE_PK_A_ADDR 0x0800 /* Public Key A Address */
  85612. +#define SAFE_PK_B_ADDR 0x0804 /* Public Key B Address */
  85613. +#define SAFE_PK_C_ADDR 0x0808 /* Public Key C Address */
  85614. +#define SAFE_PK_D_ADDR 0x080c /* Public Key D Address */
  85615. +#define SAFE_PK_A_LEN 0x0810 /* Public Key A Length */
  85616. +#define SAFE_PK_B_LEN 0x0814 /* Public Key B Length */
  85617. +#define SAFE_PK_SHIFT 0x0818 /* Public Key Shift */
  85618. +#define SAFE_PK_FUNC 0x081c /* Public Key Function */
  85619. +#define SAFE_PK_RAM_START 0x1000 /* Public Key RAM start address */
  85620. +#define SAFE_PK_RAM_END 0x1fff /* Public Key RAM end address */
  85621. +
  85622. +#define SAFE_RNG_OUT 0x0100 /* RNG Output */
  85623. +#define SAFE_RNG_STAT 0x0104 /* RNG Status */
  85624. +#define SAFE_RNG_CTRL 0x0108 /* RNG Control */
  85625. +#define SAFE_RNG_A 0x010c /* RNG A */
  85626. +#define SAFE_RNG_B 0x0110 /* RNG B */
  85627. +#define SAFE_RNG_X_LO 0x0114 /* RNG X [31:0] */
  85628. +#define SAFE_RNG_X_MID 0x0118 /* RNG X [63:32] */
  85629. +#define SAFE_RNG_X_HI 0x011c /* RNG X [80:64] */
  85630. +#define SAFE_RNG_X_CNTR 0x0120 /* RNG Counter */
  85631. +#define SAFE_RNG_ALM_CNT 0x0124 /* RNG Alarm Count */
  85632. +#define SAFE_RNG_CNFG 0x0128 /* RNG Configuration */
  85633. +#define SAFE_RNG_LFSR1_LO 0x012c /* RNG LFSR1 [31:0] */
  85634. +#define SAFE_RNG_LFSR1_HI 0x0130 /* RNG LFSR1 [47:32] */
  85635. +#define SAFE_RNG_LFSR2_LO 0x0134 /* RNG LFSR1 [31:0] */
  85636. +#define SAFE_RNG_LFSR2_HI 0x0138 /* RNG LFSR1 [47:32] */
  85637. +
  85638. +#define SAFE_PE_CSR_READY 0x00000001 /* ready for processing */
  85639. +#define SAFE_PE_CSR_DONE 0x00000002 /* h/w completed processing */
  85640. +#define SAFE_PE_CSR_LOADSA 0x00000004 /* load SA digests */
  85641. +#define SAFE_PE_CSR_HASHFINAL 0x00000010 /* do hash pad & write result */
  85642. +#define SAFE_PE_CSR_SABUSID 0x000000c0 /* bus id for SA */
  85643. +#define SAFE_PE_CSR_SAPCI 0x00000040 /* PCI bus id for SA */
  85644. +#define SAFE_PE_CSR_NXTHDR 0x0000ff00 /* next hdr value for IPsec */
  85645. +#define SAFE_PE_CSR_FPAD 0x0000ff00 /* fixed pad for basic ops */
  85646. +#define SAFE_PE_CSR_STATUS 0x00ff0000 /* operation result status */
  85647. +#define SAFE_PE_CSR_AUTH_FAIL 0x00010000 /* ICV mismatch (inbound) */
  85648. +#define SAFE_PE_CSR_PAD_FAIL 0x00020000 /* pad verify fail (inbound) */
  85649. +#define SAFE_PE_CSR_SEQ_FAIL 0x00040000 /* sequence number (inbound) */
  85650. +#define SAFE_PE_CSR_XERROR 0x00080000 /* extended error follows */
  85651. +#define SAFE_PE_CSR_XECODE 0x00f00000 /* extended error code */
  85652. +#define SAFE_PE_CSR_XECODE_S 20
  85653. +#define SAFE_PE_CSR_XECODE_BADCMD 0 /* invalid command */
  85654. +#define SAFE_PE_CSR_XECODE_BADALG 1 /* invalid algorithm */
  85655. +#define SAFE_PE_CSR_XECODE_ALGDIS 2 /* algorithm disabled */
  85656. +#define SAFE_PE_CSR_XECODE_ZEROLEN 3 /* zero packet length */
  85657. +#define SAFE_PE_CSR_XECODE_DMAERR 4 /* bus DMA error */
  85658. +#define SAFE_PE_CSR_XECODE_PIPEABORT 5 /* secondary bus DMA error */
  85659. +#define SAFE_PE_CSR_XECODE_BADSPI 6 /* IPsec SPI mismatch */
  85660. +#define SAFE_PE_CSR_XECODE_TIMEOUT 10 /* failsafe timeout */
  85661. +#define SAFE_PE_CSR_PAD 0xff000000 /* ESP padding control/status */
  85662. +#define SAFE_PE_CSR_PAD_MIN 0x00000000 /* minimum IPsec padding */
  85663. +#define SAFE_PE_CSR_PAD_16 0x08000000 /* pad to 16-byte boundary */
  85664. +#define SAFE_PE_CSR_PAD_32 0x10000000 /* pad to 32-byte boundary */
  85665. +#define SAFE_PE_CSR_PAD_64 0x20000000 /* pad to 64-byte boundary */
  85666. +#define SAFE_PE_CSR_PAD_128 0x40000000 /* pad to 128-byte boundary */
  85667. +#define SAFE_PE_CSR_PAD_256 0x80000000 /* pad to 256-byte boundary */
  85668. +
  85669. +/*
  85670. + * Check the CSR to see if the PE has returned ownership to
  85671. + * the host. Note that before processing a descriptor this
  85672. + * must be done followed by a check of the SAFE_PE_LEN register
  85673. + * status bits to avoid premature processing of a descriptor
  85674. + * on its way back to the host.
  85675. + */
  85676. +#define SAFE_PE_CSR_IS_DONE(_csr) \
  85677. + (((_csr) & (SAFE_PE_CSR_READY | SAFE_PE_CSR_DONE)) == SAFE_PE_CSR_DONE)
  85678. +
  85679. +#define SAFE_PE_LEN_LENGTH 0x000fffff /* total length (bytes) */
  85680. +#define SAFE_PE_LEN_READY 0x00400000 /* ready for processing */
  85681. +#define SAFE_PE_LEN_DONE 0x00800000 /* h/w completed processing */
  85682. +#define SAFE_PE_LEN_BYPASS 0xff000000 /* bypass offset (bytes) */
  85683. +#define SAFE_PE_LEN_BYPASS_S 24
  85684. +
  85685. +#define SAFE_PE_LEN_IS_DONE(_len) \
  85686. + (((_len) & (SAFE_PE_LEN_READY | SAFE_PE_LEN_DONE)) == SAFE_PE_LEN_DONE)
  85687. +
  85688. +/* NB: these apply to HU_STAT, HM_STAT, HI_CLR, and HI_MASK */
  85689. +#define SAFE_INT_PE_CDONE 0x00000002 /* PE context done */
  85690. +#define SAFE_INT_PE_DDONE 0x00000008 /* PE descriptor done */
  85691. +#define SAFE_INT_PE_ERROR 0x00000010 /* PE error */
  85692. +#define SAFE_INT_PE_ODONE 0x00000020 /* PE operation done */
  85693. +
  85694. +#define SAFE_HI_CFG_PULSE 0x00000001 /* use pulse interrupt */
  85695. +#define SAFE_HI_CFG_LEVEL 0x00000000 /* use level interrupt */
  85696. +#define SAFE_HI_CFG_AUTOCLR 0x00000002 /* auto-clear pulse interrupt */
  85697. +
  85698. +#define SAFE_ENDIAN_PASS 0x000000e4 /* straight pass-thru */
  85699. +#define SAFE_ENDIAN_SWAB 0x0000001b /* swap bytes in 32-bit word */
  85700. +
  85701. +#define SAFE_PE_DMACFG_PERESET 0x00000001 /* reset packet engine */
  85702. +#define SAFE_PE_DMACFG_PDRRESET 0x00000002 /* reset PDR counters/ptrs */
  85703. +#define SAFE_PE_DMACFG_SGRESET 0x00000004 /* reset scatter/gather cache */
  85704. +#define SAFE_PE_DMACFG_FSENA 0x00000008 /* enable failsafe reset */
  85705. +#define SAFE_PE_DMACFG_PEMODE 0x00000100 /* packet engine mode */
  85706. +#define SAFE_PE_DMACFG_SAPREC 0x00000200 /* SA precedes packet */
  85707. +#define SAFE_PE_DMACFG_PKFOLL 0x00000400 /* packet follows descriptor */
  85708. +#define SAFE_PE_DMACFG_GPRBID 0x00003000 /* gather particle ring busid */
  85709. +#define SAFE_PE_DMACFG_GPRPCI 0x00001000 /* PCI gather particle ring */
  85710. +#define SAFE_PE_DMACFG_SPRBID 0x0000c000 /* scatter part. ring busid */
  85711. +#define SAFE_PE_DMACFG_SPRPCI 0x00004000 /* PCI scatter part. ring */
  85712. +#define SAFE_PE_DMACFG_ESDESC 0x00010000 /* endian swap descriptors */
  85713. +#define SAFE_PE_DMACFG_ESSA 0x00020000 /* endian swap SA data */
  85714. +#define SAFE_PE_DMACFG_ESPACKET 0x00040000 /* endian swap packet data */
  85715. +#define SAFE_PE_DMACFG_ESPDESC 0x00080000 /* endian swap particle desc. */
  85716. +#define SAFE_PE_DMACFG_NOPDRUP 0x00100000 /* supp. PDR ownership update */
  85717. +#define SAFE_PD_EDMACFG_PCIMODE 0x01000000 /* PCI target mode */
  85718. +
  85719. +#define SAFE_PE_DMASTAT_PEIDONE 0x00000001 /* PE core input done */
  85720. +#define SAFE_PE_DMASTAT_PEODONE 0x00000002 /* PE core output done */
  85721. +#define SAFE_PE_DMASTAT_ENCDONE 0x00000004 /* encryption done */
  85722. +#define SAFE_PE_DMASTAT_IHDONE 0x00000008 /* inner hash done */
  85723. +#define SAFE_PE_DMASTAT_OHDONE 0x00000010 /* outer hash (HMAC) done */
  85724. +#define SAFE_PE_DMASTAT_PADFLT 0x00000020 /* crypto pad fault */
  85725. +#define SAFE_PE_DMASTAT_ICVFLT 0x00000040 /* ICV fault */
  85726. +#define SAFE_PE_DMASTAT_SPIMIS 0x00000080 /* SPI mismatch */
  85727. +#define SAFE_PE_DMASTAT_CRYPTO 0x00000100 /* crypto engine timeout */
  85728. +#define SAFE_PE_DMASTAT_CQACT 0x00000200 /* command queue active */
  85729. +#define SAFE_PE_DMASTAT_IRACT 0x00000400 /* input request active */
  85730. +#define SAFE_PE_DMASTAT_ORACT 0x00000800 /* output request active */
  85731. +#define SAFE_PE_DMASTAT_PEISIZE 0x003ff000 /* PE input size:32-bit words */
  85732. +#define SAFE_PE_DMASTAT_PEOSIZE 0xffc00000 /* PE out. size:32-bit words */
  85733. +
  85734. +#define SAFE_PE_RINGCFG_SIZE 0x000003ff /* ring size (descriptors) */
  85735. +#define SAFE_PE_RINGCFG_OFFSET 0xffff0000 /* offset btw desc's (dwords) */
  85736. +#define SAFE_PE_RINGCFG_OFFSET_S 16
  85737. +
  85738. +#define SAFE_PE_RINGPOLL_POLL 0x00000fff /* polling frequency/divisor */
  85739. +#define SAFE_PE_RINGPOLL_RETRY 0x03ff0000 /* polling frequency/divisor */
  85740. +#define SAFE_PE_RINGPOLL_CONT 0x80000000 /* continuously poll */
  85741. +
  85742. +#define SAFE_PE_IRNGSTAT_CQAVAIL 0x00000001 /* command queue available */
  85743. +
  85744. +#define SAFE_PE_ERNGSTAT_NEXT 0x03ff0000 /* index of next packet desc. */
  85745. +#define SAFE_PE_ERNGSTAT_NEXT_S 16
  85746. +
  85747. +#define SAFE_PE_IOTHRESH_INPUT 0x000003ff /* input threshold (dwords) */
  85748. +#define SAFE_PE_IOTHRESH_OUTPUT 0x03ff0000 /* output threshold (dwords) */
  85749. +
  85750. +#define SAFE_PE_PARTCFG_SIZE 0x0000ffff /* scatter particle size */
  85751. +#define SAFE_PE_PARTCFG_GBURST 0x00030000 /* gather particle burst */
  85752. +#define SAFE_PE_PARTCFG_GBURST_2 0x00000000
  85753. +#define SAFE_PE_PARTCFG_GBURST_4 0x00010000
  85754. +#define SAFE_PE_PARTCFG_GBURST_8 0x00020000
  85755. +#define SAFE_PE_PARTCFG_GBURST_16 0x00030000
  85756. +#define SAFE_PE_PARTCFG_SBURST 0x000c0000 /* scatter particle burst */
  85757. +#define SAFE_PE_PARTCFG_SBURST_2 0x00000000
  85758. +#define SAFE_PE_PARTCFG_SBURST_4 0x00040000
  85759. +#define SAFE_PE_PARTCFG_SBURST_8 0x00080000
  85760. +#define SAFE_PE_PARTCFG_SBURST_16 0x000c0000
  85761. +
  85762. +#define SAFE_PE_PARTSIZE_SCAT 0xffff0000 /* scatter particle ring size */
  85763. +#define SAFE_PE_PARTSIZE_GATH 0x0000ffff /* gather particle ring size */
  85764. +
  85765. +#define SAFE_CRYPTO_CTRL_3DES 0x00000001 /* enable 3DES support */
  85766. +#define SAFE_CRYPTO_CTRL_PKEY 0x00010000 /* enable public key support */
  85767. +#define SAFE_CRYPTO_CTRL_RNG 0x00020000 /* enable RNG support */
  85768. +
  85769. +#define SAFE_DEVINFO_REV_MIN 0x0000000f /* minor rev for chip */
  85770. +#define SAFE_DEVINFO_REV_MAJ 0x000000f0 /* major rev for chip */
  85771. +#define SAFE_DEVINFO_REV_MAJ_S 4
  85772. +#define SAFE_DEVINFO_DES 0x00000100 /* DES/3DES support present */
  85773. +#define SAFE_DEVINFO_ARC4 0x00000200 /* ARC4 support present */
  85774. +#define SAFE_DEVINFO_AES 0x00000400 /* AES support present */
  85775. +#define SAFE_DEVINFO_MD5 0x00001000 /* MD5 support present */
  85776. +#define SAFE_DEVINFO_SHA1 0x00002000 /* SHA-1 support present */
  85777. +#define SAFE_DEVINFO_RIPEMD 0x00004000 /* RIPEMD support present */
  85778. +#define SAFE_DEVINFO_DEFLATE 0x00010000 /* Deflate support present */
  85779. +#define SAFE_DEVINFO_SARAM 0x00100000 /* on-chip SA RAM present */
  85780. +#define SAFE_DEVINFO_EMIBUS 0x00200000 /* EMI bus present */
  85781. +#define SAFE_DEVINFO_PKEY 0x00400000 /* public key support present */
  85782. +#define SAFE_DEVINFO_RNG 0x00800000 /* RNG present */
  85783. +
  85784. +#define SAFE_REV(_maj, _min) (((_maj) << SAFE_DEVINFO_REV_MAJ_S) | (_min))
  85785. +#define SAFE_REV_MAJ(_chiprev) \
  85786. + (((_chiprev) & SAFE_DEVINFO_REV_MAJ) >> SAFE_DEVINFO_REV_MAJ_S)
  85787. +#define SAFE_REV_MIN(_chiprev) ((_chiprev) & SAFE_DEVINFO_REV_MIN)
  85788. +
  85789. +#define SAFE_PK_FUNC_MULT 0x00000001 /* Multiply function */
  85790. +#define SAFE_PK_FUNC_SQUARE 0x00000004 /* Square function */
  85791. +#define SAFE_PK_FUNC_ADD 0x00000010 /* Add function */
  85792. +#define SAFE_PK_FUNC_SUB 0x00000020 /* Subtract function */
  85793. +#define SAFE_PK_FUNC_LSHIFT 0x00000040 /* Left-shift function */
  85794. +#define SAFE_PK_FUNC_RSHIFT 0x00000080 /* Right-shift function */
  85795. +#define SAFE_PK_FUNC_DIV 0x00000100 /* Divide function */
  85796. +#define SAFE_PK_FUNC_CMP 0x00000400 /* Compare function */
  85797. +#define SAFE_PK_FUNC_COPY 0x00000800 /* Copy function */
  85798. +#define SAFE_PK_FUNC_EXP16 0x00002000 /* Exponentiate (4-bit ACT) */
  85799. +#define SAFE_PK_FUNC_EXP4 0x00004000 /* Exponentiate (2-bit ACT) */
  85800. +#define SAFE_PK_FUNC_RUN 0x00008000 /* start/status */
  85801. +
  85802. +#define SAFE_RNG_STAT_BUSY 0x00000001 /* busy, data not valid */
  85803. +
  85804. +#define SAFE_RNG_CTRL_PRE_LFSR 0x00000001 /* enable output pre-LFSR */
  85805. +#define SAFE_RNG_CTRL_TST_MODE 0x00000002 /* enable test mode */
  85806. +#define SAFE_RNG_CTRL_TST_RUN 0x00000004 /* start test state machine */
  85807. +#define SAFE_RNG_CTRL_ENA_RING1 0x00000008 /* test entropy oscillator #1 */
  85808. +#define SAFE_RNG_CTRL_ENA_RING2 0x00000010 /* test entropy oscillator #2 */
  85809. +#define SAFE_RNG_CTRL_DIS_ALARM 0x00000020 /* disable RNG alarm reports */
  85810. +#define SAFE_RNG_CTRL_TST_CLOCK 0x00000040 /* enable test clock */
  85811. +#define SAFE_RNG_CTRL_SHORTEN 0x00000080 /* shorten state timers */
  85812. +#define SAFE_RNG_CTRL_TST_ALARM 0x00000100 /* simulate alarm state */
  85813. +#define SAFE_RNG_CTRL_RST_LFSR 0x00000200 /* reset LFSR */
  85814. +
  85815. +/*
  85816. + * Packet engine descriptor. Note that d_csr is a copy of the
  85817. + * SAFE_PE_CSR register and all definitions apply, and d_len
  85818. + * is a copy of the SAFE_PE_LEN register and all definitions apply.
  85819. + * d_src and d_len may point directly to contiguous data or to a
  85820. + * list of ``particle descriptors'' when using scatter/gather i/o.
  85821. + */
  85822. +struct safe_desc {
  85823. + u_int32_t d_csr; /* per-packet control/status */
  85824. + u_int32_t d_src; /* source address */
  85825. + u_int32_t d_dst; /* destination address */
  85826. + u_int32_t d_sa; /* SA address */
  85827. + u_int32_t d_len; /* length, bypass, status */
  85828. +};
  85829. +
  85830. +/*
  85831. + * Scatter/Gather particle descriptor.
  85832. + *
  85833. + * NB: scatter descriptors do not specify a size; this is fixed
  85834. + * by the setting of the SAFE_PE_PARTCFG register.
  85835. + */
  85836. +struct safe_pdesc {
  85837. + u_int32_t pd_addr; /* particle address */
  85838. +#ifdef __BIG_ENDIAN
  85839. + u_int16_t pd_flags; /* control word */
  85840. + u_int16_t pd_size; /* particle size (bytes) */
  85841. +#else
  85842. + u_int16_t pd_flags; /* control word */
  85843. + u_int16_t pd_size; /* particle size (bytes) */
  85844. +#endif
  85845. +};
  85846. +
  85847. +#define SAFE_PD_READY 0x0001 /* ready for processing */
  85848. +#define SAFE_PD_DONE 0x0002 /* h/w completed processing */
  85849. +
  85850. +/*
  85851. + * Security Association (SA) Record (Rev 1). One of these is
  85852. + * required for each operation processed by the packet engine.
  85853. + */
  85854. +struct safe_sarec {
  85855. + u_int32_t sa_cmd0;
  85856. + u_int32_t sa_cmd1;
  85857. + u_int32_t sa_resv0;
  85858. + u_int32_t sa_resv1;
  85859. + u_int32_t sa_key[8]; /* DES/3DES/AES key */
  85860. + u_int32_t sa_indigest[5]; /* inner digest */
  85861. + u_int32_t sa_outdigest[5]; /* outer digest */
  85862. + u_int32_t sa_spi; /* SPI */
  85863. + u_int32_t sa_seqnum; /* sequence number */
  85864. + u_int32_t sa_seqmask[2]; /* sequence number mask */
  85865. + u_int32_t sa_resv2;
  85866. + u_int32_t sa_staterec; /* address of state record */
  85867. + u_int32_t sa_resv3[2];
  85868. + u_int32_t sa_samgmt0; /* SA management field 0 */
  85869. + u_int32_t sa_samgmt1; /* SA management field 0 */
  85870. +};
  85871. +
  85872. +#define SAFE_SA_CMD0_OP 0x00000007 /* operation code */
  85873. +#define SAFE_SA_CMD0_OP_CRYPT 0x00000000 /* encrypt/decrypt (basic) */
  85874. +#define SAFE_SA_CMD0_OP_BOTH 0x00000001 /* encrypt-hash/hash-decrypto */
  85875. +#define SAFE_SA_CMD0_OP_HASH 0x00000003 /* hash (outbound-only) */
  85876. +#define SAFE_SA_CMD0_OP_ESP 0x00000000 /* ESP in/out (proto) */
  85877. +#define SAFE_SA_CMD0_OP_AH 0x00000001 /* AH in/out (proto) */
  85878. +#define SAFE_SA_CMD0_INBOUND 0x00000008 /* inbound operation */
  85879. +#define SAFE_SA_CMD0_OUTBOUND 0x00000000 /* outbound operation */
  85880. +#define SAFE_SA_CMD0_GROUP 0x00000030 /* operation group */
  85881. +#define SAFE_SA_CMD0_BASIC 0x00000000 /* basic operation */
  85882. +#define SAFE_SA_CMD0_PROTO 0x00000010 /* protocol/packet operation */
  85883. +#define SAFE_SA_CMD0_BUNDLE 0x00000020 /* bundled operation (resvd) */
  85884. +#define SAFE_SA_CMD0_PAD 0x000000c0 /* crypto pad method */
  85885. +#define SAFE_SA_CMD0_PAD_IPSEC 0x00000000 /* IPsec padding */
  85886. +#define SAFE_SA_CMD0_PAD_PKCS7 0x00000040 /* PKCS#7 padding */
  85887. +#define SAFE_SA_CMD0_PAD_CONS 0x00000080 /* constant padding */
  85888. +#define SAFE_SA_CMD0_PAD_ZERO 0x000000c0 /* zero padding */
  85889. +#define SAFE_SA_CMD0_CRYPT_ALG 0x00000f00 /* symmetric crypto algorithm */
  85890. +#define SAFE_SA_CMD0_DES 0x00000000 /* DES crypto algorithm */
  85891. +#define SAFE_SA_CMD0_3DES 0x00000100 /* 3DES crypto algorithm */
  85892. +#define SAFE_SA_CMD0_AES 0x00000300 /* AES crypto algorithm */
  85893. +#define SAFE_SA_CMD0_CRYPT_NULL 0x00000f00 /* null crypto algorithm */
  85894. +#define SAFE_SA_CMD0_HASH_ALG 0x0000f000 /* hash algorithm */
  85895. +#define SAFE_SA_CMD0_MD5 0x00000000 /* MD5 hash algorithm */
  85896. +#define SAFE_SA_CMD0_SHA1 0x00001000 /* SHA-1 hash algorithm */
  85897. +#define SAFE_SA_CMD0_HASH_NULL 0x0000f000 /* null hash algorithm */
  85898. +#define SAFE_SA_CMD0_HDR_PROC 0x00080000 /* header processing */
  85899. +#define SAFE_SA_CMD0_IBUSID 0x00300000 /* input bus id */
  85900. +#define SAFE_SA_CMD0_IPCI 0x00100000 /* PCI input bus id */
  85901. +#define SAFE_SA_CMD0_OBUSID 0x00c00000 /* output bus id */
  85902. +#define SAFE_SA_CMD0_OPCI 0x00400000 /* PCI output bus id */
  85903. +#define SAFE_SA_CMD0_IVLD 0x03000000 /* IV loading */
  85904. +#define SAFE_SA_CMD0_IVLD_NONE 0x00000000 /* IV no load (reuse) */
  85905. +#define SAFE_SA_CMD0_IVLD_IBUF 0x01000000 /* IV load from input buffer */
  85906. +#define SAFE_SA_CMD0_IVLD_STATE 0x02000000 /* IV load from state */
  85907. +#define SAFE_SA_CMD0_HSLD 0x0c000000 /* hash state loading */
  85908. +#define SAFE_SA_CMD0_HSLD_SA 0x00000000 /* hash state load from SA */
  85909. +#define SAFE_SA_CMD0_HSLD_STATE 0x08000000 /* hash state load from state */
  85910. +#define SAFE_SA_CMD0_HSLD_NONE 0x0c000000 /* hash state no load */
  85911. +#define SAFE_SA_CMD0_SAVEIV 0x10000000 /* save IV */
  85912. +#define SAFE_SA_CMD0_SAVEHASH 0x20000000 /* save hash state */
  85913. +#define SAFE_SA_CMD0_IGATHER 0x40000000 /* input gather */
  85914. +#define SAFE_SA_CMD0_OSCATTER 0x80000000 /* output scatter */
  85915. +
  85916. +#define SAFE_SA_CMD1_HDRCOPY 0x00000002 /* copy header to output */
  85917. +#define SAFE_SA_CMD1_PAYCOPY 0x00000004 /* copy payload to output */
  85918. +#define SAFE_SA_CMD1_PADCOPY 0x00000008 /* copy pad to output */
  85919. +#define SAFE_SA_CMD1_IPV4 0x00000000 /* IPv4 protocol */
  85920. +#define SAFE_SA_CMD1_IPV6 0x00000010 /* IPv6 protocol */
  85921. +#define SAFE_SA_CMD1_MUTABLE 0x00000020 /* mutable bit processing */
  85922. +#define SAFE_SA_CMD1_SRBUSID 0x000000c0 /* state record bus id */
  85923. +#define SAFE_SA_CMD1_SRPCI 0x00000040 /* state record from PCI */
  85924. +#define SAFE_SA_CMD1_CRMODE 0x00000300 /* crypto mode */
  85925. +#define SAFE_SA_CMD1_ECB 0x00000000 /* ECB crypto mode */
  85926. +#define SAFE_SA_CMD1_CBC 0x00000100 /* CBC crypto mode */
  85927. +#define SAFE_SA_CMD1_OFB 0x00000200 /* OFB crypto mode */
  85928. +#define SAFE_SA_CMD1_CFB 0x00000300 /* CFB crypto mode */
  85929. +#define SAFE_SA_CMD1_CRFEEDBACK 0x00000c00 /* crypto feedback mode */
  85930. +#define SAFE_SA_CMD1_64BIT 0x00000000 /* 64-bit crypto feedback */
  85931. +#define SAFE_SA_CMD1_8BIT 0x00000400 /* 8-bit crypto feedback */
  85932. +#define SAFE_SA_CMD1_1BIT 0x00000800 /* 1-bit crypto feedback */
  85933. +#define SAFE_SA_CMD1_128BIT 0x00000c00 /* 128-bit crypto feedback */
  85934. +#define SAFE_SA_CMD1_OPTIONS 0x00001000 /* HMAC/options mutable bit */
  85935. +#define SAFE_SA_CMD1_HMAC SAFE_SA_CMD1_OPTIONS
  85936. +#define SAFE_SA_CMD1_SAREV1 0x00008000 /* SA Revision 1 */
  85937. +#define SAFE_SA_CMD1_OFFSET 0x00ff0000 /* hash/crypto offset(dwords) */
  85938. +#define SAFE_SA_CMD1_OFFSET_S 16
  85939. +#define SAFE_SA_CMD1_AESKEYLEN 0x0f000000 /* AES key length */
  85940. +#define SAFE_SA_CMD1_AES128 0x02000000 /* 128-bit AES key */
  85941. +#define SAFE_SA_CMD1_AES192 0x03000000 /* 192-bit AES key */
  85942. +#define SAFE_SA_CMD1_AES256 0x04000000 /* 256-bit AES key */
  85943. +
  85944. +/*
  85945. + * Security Associate State Record (Rev 1).
  85946. + */
  85947. +struct safe_sastate {
  85948. + u_int32_t sa_saved_iv[4]; /* saved IV (DES/3DES/AES) */
  85949. + u_int32_t sa_saved_hashbc; /* saved hash byte count */
  85950. + u_int32_t sa_saved_indigest[5]; /* saved inner digest */
  85951. +};
  85952. +#endif /* _SAFE_SAFEREG_H_ */
  85953. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/safevar.h linux-2.6.39/crypto/ocf/safe/safevar.h
  85954. --- linux-2.6.39.orig/crypto/ocf/safe/safevar.h 1970-01-01 01:00:00.000000000 +0100
  85955. +++ linux-2.6.39/crypto/ocf/safe/safevar.h 2011-07-31 11:32:03.453422685 +0200
  85956. @@ -0,0 +1,230 @@
  85957. +/*-
  85958. + * The linux port of this code done by David McCullough
  85959. + * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
  85960. + * The license and original author are listed below.
  85961. + *
  85962. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  85963. + * Copyright (c) 2003 Global Technology Associates, Inc.
  85964. + * All rights reserved.
  85965. + *
  85966. + * Redistribution and use in source and binary forms, with or without
  85967. + * modification, are permitted provided that the following conditions
  85968. + * are met:
  85969. + * 1. Redistributions of source code must retain the above copyright
  85970. + * notice, this list of conditions and the following disclaimer.
  85971. + * 2. Redistributions in binary form must reproduce the above copyright
  85972. + * notice, this list of conditions and the following disclaimer in the
  85973. + * documentation and/or other materials provided with the distribution.
  85974. + *
  85975. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  85976. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  85977. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  85978. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  85979. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  85980. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  85981. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  85982. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  85983. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  85984. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  85985. + * SUCH DAMAGE.
  85986. + *
  85987. + * $FreeBSD: src/sys/dev/safe/safevar.h,v 1.2 2006/05/17 18:34:26 pjd Exp $
  85988. + */
  85989. +#ifndef _SAFE_SAFEVAR_H_
  85990. +#define _SAFE_SAFEVAR_H_
  85991. +
  85992. +/* Maximum queue length */
  85993. +#ifndef SAFE_MAX_NQUEUE
  85994. +#define SAFE_MAX_NQUEUE 60
  85995. +#endif
  85996. +
  85997. +#define SAFE_MAX_PART 64 /* Maximum scatter/gather depth */
  85998. +#define SAFE_DMA_BOUNDARY 0 /* No boundary for source DMA ops */
  85999. +#define SAFE_MAX_DSIZE 2048 /* MCLBYTES Fixed scatter particle size */
  86000. +#define SAFE_MAX_SSIZE 0x0ffff /* Maximum gather particle size */
  86001. +#define SAFE_MAX_DMA 0xfffff /* Maximum PE operand size (20 bits) */
  86002. +/* total src+dst particle descriptors */
  86003. +#define SAFE_TOTAL_DPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
  86004. +#define SAFE_TOTAL_SPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
  86005. +
  86006. +#define SAFE_RNG_MAXBUFSIZ 128 /* 32-bit words */
  86007. +
  86008. +#define SAFE_CARD(sid) (((sid) & 0xf0000000) >> 28)
  86009. +#define SAFE_SESSION(sid) ( (sid) & 0x0fffffff)
  86010. +#define SAFE_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
  86011. +
  86012. +#define SAFE_DEF_RTY 0xff /* PCI Retry Timeout */
  86013. +#define SAFE_DEF_TOUT 0xff /* PCI TRDY Timeout */
  86014. +#define SAFE_DEF_CACHELINE 0x01 /* Cache Line setting */
  86015. +
  86016. +#ifdef __KERNEL__
  86017. +/*
  86018. + * State associated with the allocation of each chunk
  86019. + * of memory setup for DMA.
  86020. + */
  86021. +struct safe_dma_alloc {
  86022. + dma_addr_t dma_paddr;
  86023. + void *dma_vaddr;
  86024. +};
  86025. +
  86026. +/*
  86027. + * Cryptographic operand state. One of these exists for each
  86028. + * source and destination operand passed in from the crypto
  86029. + * subsystem. When possible source and destination operands
  86030. + * refer to the same memory. More often they are distinct.
  86031. + * We track the virtual address of each operand as well as
  86032. + * where each is mapped for DMA.
  86033. + */
  86034. +struct safe_operand {
  86035. + union {
  86036. + struct sk_buff *skb;
  86037. + struct uio *io;
  86038. + } u;
  86039. + void *map;
  86040. + int mapsize; /* total number of bytes in segs */
  86041. + struct {
  86042. + dma_addr_t ds_addr;
  86043. + int ds_len;
  86044. + int ds_tlen;
  86045. + } segs[SAFE_MAX_PART];
  86046. + int nsegs;
  86047. +};
  86048. +
  86049. +/*
  86050. + * Packet engine ring entry and cryptographic operation state.
  86051. + * The packet engine requires a ring of descriptors that contain
  86052. + * pointers to various cryptographic state. However the ring
  86053. + * configuration register allows you to specify an arbitrary size
  86054. + * for ring entries. We use this feature to collect most of the
  86055. + * state for each cryptographic request into one spot. Other than
  86056. + * ring entries only the ``particle descriptors'' (scatter/gather
  86057. + * lists) and the actual operand data are kept separate. The
  86058. + * particle descriptors must also be organized in rings. The
  86059. + * operand data can be located aribtrarily (modulo alignment constraints).
  86060. + *
  86061. + * Note that the descriptor ring is mapped onto the PCI bus so
  86062. + * the hardware can DMA data. This means the entire ring must be
  86063. + * contiguous.
  86064. + */
  86065. +struct safe_ringentry {
  86066. + struct safe_desc re_desc; /* command descriptor */
  86067. + struct safe_sarec re_sa; /* SA record */
  86068. + struct safe_sastate re_sastate; /* SA state record */
  86069. +
  86070. + struct cryptop *re_crp; /* crypto operation */
  86071. +
  86072. + struct safe_operand re_src; /* source operand */
  86073. + struct safe_operand re_dst; /* destination operand */
  86074. +
  86075. + int re_sesn; /* crypto session ID */
  86076. + int re_flags;
  86077. +#define SAFE_QFLAGS_COPYOUTIV 0x1 /* copy back on completion */
  86078. +#define SAFE_QFLAGS_COPYOUTICV 0x2 /* copy back on completion */
  86079. +};
  86080. +
  86081. +#define re_src_skb re_src.u.skb
  86082. +#define re_src_io re_src.u.io
  86083. +#define re_src_map re_src.map
  86084. +#define re_src_nsegs re_src.nsegs
  86085. +#define re_src_segs re_src.segs
  86086. +#define re_src_mapsize re_src.mapsize
  86087. +
  86088. +#define re_dst_skb re_dst.u.skb
  86089. +#define re_dst_io re_dst.u.io
  86090. +#define re_dst_map re_dst.map
  86091. +#define re_dst_nsegs re_dst.nsegs
  86092. +#define re_dst_segs re_dst.segs
  86093. +#define re_dst_mapsize re_dst.mapsize
  86094. +
  86095. +struct rndstate_test;
  86096. +
  86097. +struct safe_session {
  86098. + u_int32_t ses_used;
  86099. + u_int32_t ses_klen; /* key length in bits */
  86100. + u_int32_t ses_key[8]; /* DES/3DES/AES key */
  86101. + u_int32_t ses_mlen; /* hmac length in bytes */
  86102. + u_int32_t ses_hminner[5]; /* hmac inner state */
  86103. + u_int32_t ses_hmouter[5]; /* hmac outer state */
  86104. + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
  86105. +};
  86106. +
  86107. +struct safe_pkq {
  86108. + struct list_head pkq_list;
  86109. + struct cryptkop *pkq_krp;
  86110. +};
  86111. +
  86112. +struct safe_softc {
  86113. + softc_device_decl sc_dev;
  86114. + u32 sc_irq;
  86115. +
  86116. + struct pci_dev *sc_pcidev;
  86117. + ocf_iomem_t sc_base_addr;
  86118. +
  86119. + u_int sc_chiprev; /* major/minor chip revision */
  86120. + int sc_flags; /* device specific flags */
  86121. +#define SAFE_FLAGS_KEY 0x01 /* has key accelerator */
  86122. +#define SAFE_FLAGS_RNG 0x02 /* hardware rng */
  86123. + int sc_suspended;
  86124. + int sc_needwakeup; /* notify crypto layer */
  86125. + int32_t sc_cid; /* crypto tag */
  86126. +
  86127. + struct safe_dma_alloc sc_ringalloc; /* PE ring allocation state */
  86128. + struct safe_ringentry *sc_ring; /* PE ring */
  86129. + struct safe_ringentry *sc_ringtop; /* PE ring top */
  86130. + struct safe_ringentry *sc_front; /* next free entry */
  86131. + struct safe_ringentry *sc_back; /* next pending entry */
  86132. + int sc_nqchip; /* # passed to chip */
  86133. + spinlock_t sc_ringmtx; /* PE ring lock */
  86134. + struct safe_pdesc *sc_spring; /* src particle ring */
  86135. + struct safe_pdesc *sc_springtop; /* src particle ring top */
  86136. + struct safe_pdesc *sc_spfree; /* next free src particle */
  86137. + struct safe_dma_alloc sc_spalloc; /* src particle ring state */
  86138. + struct safe_pdesc *sc_dpring; /* dest particle ring */
  86139. + struct safe_pdesc *sc_dpringtop; /* dest particle ring top */
  86140. + struct safe_pdesc *sc_dpfree; /* next free dest particle */
  86141. + struct safe_dma_alloc sc_dpalloc; /* dst particle ring state */
  86142. + int sc_nsessions; /* # of sessions */
  86143. + struct safe_session *sc_sessions; /* sessions */
  86144. +
  86145. + struct timer_list sc_pkto; /* PK polling */
  86146. + spinlock_t sc_pkmtx; /* PK lock */
  86147. + struct list_head sc_pkq; /* queue of PK requests */
  86148. + struct safe_pkq *sc_pkq_cur; /* current processing request */
  86149. + u_int32_t sc_pk_reslen, sc_pk_resoff;
  86150. +
  86151. + int sc_max_dsize; /* maximum safe DMA size */
  86152. +};
  86153. +#endif /* __KERNEL__ */
  86154. +
  86155. +struct safe_stats {
  86156. + u_int64_t st_ibytes;
  86157. + u_int64_t st_obytes;
  86158. + u_int32_t st_ipackets;
  86159. + u_int32_t st_opackets;
  86160. + u_int32_t st_invalid; /* invalid argument */
  86161. + u_int32_t st_badsession; /* invalid session id */
  86162. + u_int32_t st_badflags; /* flags indicate !(mbuf | uio) */
  86163. + u_int32_t st_nodesc; /* op submitted w/o descriptors */
  86164. + u_int32_t st_badalg; /* unsupported algorithm */
  86165. + u_int32_t st_ringfull; /* PE descriptor ring full */
  86166. + u_int32_t st_peoperr; /* PE marked error */
  86167. + u_int32_t st_dmaerr; /* PE DMA error */
  86168. + u_int32_t st_bypasstoobig; /* bypass > 96 bytes */
  86169. + u_int32_t st_skipmismatch; /* enc part begins before auth part */
  86170. + u_int32_t st_lenmismatch; /* enc length different auth length */
  86171. + u_int32_t st_coffmisaligned; /* crypto offset not 32-bit aligned */
  86172. + u_int32_t st_cofftoobig; /* crypto offset > 255 words */
  86173. + u_int32_t st_iovmisaligned; /* iov op not aligned */
  86174. + u_int32_t st_iovnotuniform; /* iov op not suitable */
  86175. + u_int32_t st_unaligned; /* unaligned src caused copy */
  86176. + u_int32_t st_notuniform; /* non-uniform src caused copy */
  86177. + u_int32_t st_nomap; /* bus_dmamap_create failed */
  86178. + u_int32_t st_noload; /* bus_dmamap_load_* failed */
  86179. + u_int32_t st_nombuf; /* MGET* failed */
  86180. + u_int32_t st_nomcl; /* MCLGET* failed */
  86181. + u_int32_t st_maxqchip; /* max mcr1 ops out for processing */
  86182. + u_int32_t st_rng; /* RNG requests */
  86183. + u_int32_t st_rngalarm; /* RNG alarm requests */
  86184. + u_int32_t st_noicvcopy; /* ICV data copies suppressed */
  86185. +};
  86186. +#endif /* _SAFE_SAFEVAR_H_ */
  86187. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/sha1.c linux-2.6.39/crypto/ocf/safe/sha1.c
  86188. --- linux-2.6.39.orig/crypto/ocf/safe/sha1.c 1970-01-01 01:00:00.000000000 +0100
  86189. +++ linux-2.6.39/crypto/ocf/safe/sha1.c 2011-07-31 11:32:03.523415629 +0200
  86190. @@ -0,0 +1,279 @@
  86191. +/* $KAME: sha1.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
  86192. +/*
  86193. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  86194. + * All rights reserved.
  86195. + *
  86196. + * Redistribution and use in source and binary forms, with or without
  86197. + * modification, are permitted provided that the following conditions
  86198. + * are met:
  86199. + * 1. Redistributions of source code must retain the above copyright
  86200. + * notice, this list of conditions and the following disclaimer.
  86201. + * 2. Redistributions in binary form must reproduce the above copyright
  86202. + * notice, this list of conditions and the following disclaimer in the
  86203. + * documentation and/or other materials provided with the distribution.
  86204. + * 3. Neither the name of the project nor the names of its contributors
  86205. + * may be used to endorse or promote products derived from this software
  86206. + * without specific prior written permission.
  86207. + *
  86208. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  86209. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  86210. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  86211. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  86212. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  86213. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  86214. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  86215. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  86216. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  86217. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  86218. + * SUCH DAMAGE.
  86219. + */
  86220. +
  86221. +/*
  86222. + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
  86223. + * based on: http://csrc.nist.gov/fips/fip180-1.txt
  86224. + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
  86225. + */
  86226. +
  86227. +#if 0
  86228. +#include <sys/cdefs.h>
  86229. +__FBSDID("$FreeBSD: src/sys/crypto/sha1.c,v 1.9 2003/06/10 21:36:57 obrien Exp $");
  86230. +
  86231. +#include <sys/types.h>
  86232. +#include <sys/cdefs.h>
  86233. +#include <sys/time.h>
  86234. +#include <sys/systm.h>
  86235. +
  86236. +#include <crypto/sha1.h>
  86237. +#endif
  86238. +
  86239. +/* sanity check */
  86240. +#if BYTE_ORDER != BIG_ENDIAN
  86241. +# if BYTE_ORDER != LITTLE_ENDIAN
  86242. +# define unsupported 1
  86243. +# endif
  86244. +#endif
  86245. +
  86246. +#ifndef unsupported
  86247. +
  86248. +/* constant table */
  86249. +static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
  86250. +#define K(t) _K[(t) / 20]
  86251. +
  86252. +#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
  86253. +#define F1(b, c, d) (((b) ^ (c)) ^ (d))
  86254. +#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
  86255. +#define F3(b, c, d) (((b) ^ (c)) ^ (d))
  86256. +
  86257. +#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
  86258. +
  86259. +#undef H
  86260. +#define H(n) (ctxt->h.b32[(n)])
  86261. +#define COUNT (ctxt->count)
  86262. +#define BCOUNT (ctxt->c.b64[0] / 8)
  86263. +#define W(n) (ctxt->m.b32[(n)])
  86264. +
  86265. +#define PUTBYTE(x) { \
  86266. + ctxt->m.b8[(COUNT % 64)] = (x); \
  86267. + COUNT++; \
  86268. + COUNT %= 64; \
  86269. + ctxt->c.b64[0] += 8; \
  86270. + if (COUNT % 64 == 0) \
  86271. + sha1_step(ctxt); \
  86272. + }
  86273. +
  86274. +#define PUTPAD(x) { \
  86275. + ctxt->m.b8[(COUNT % 64)] = (x); \
  86276. + COUNT++; \
  86277. + COUNT %= 64; \
  86278. + if (COUNT % 64 == 0) \
  86279. + sha1_step(ctxt); \
  86280. + }
  86281. +
  86282. +static void sha1_step(struct sha1_ctxt *);
  86283. +
  86284. +static void
  86285. +sha1_step(ctxt)
  86286. + struct sha1_ctxt *ctxt;
  86287. +{
  86288. + u_int32_t a, b, c, d, e;
  86289. + size_t t, s;
  86290. + u_int32_t tmp;
  86291. +
  86292. +#if BYTE_ORDER == LITTLE_ENDIAN
  86293. + struct sha1_ctxt tctxt;
  86294. + bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);
  86295. + ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
  86296. + ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
  86297. + ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
  86298. + ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
  86299. + ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
  86300. + ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
  86301. + ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
  86302. + ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
  86303. + ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
  86304. + ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
  86305. + ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
  86306. + ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
  86307. + ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
  86308. + ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
  86309. + ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
  86310. + ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
  86311. + ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
  86312. + ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
  86313. + ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
  86314. + ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
  86315. + ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
  86316. + ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
  86317. + ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
  86318. + ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
  86319. + ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
  86320. + ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
  86321. + ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
  86322. + ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
  86323. + ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
  86324. + ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
  86325. + ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
  86326. + ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
  86327. +#endif
  86328. +
  86329. + a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
  86330. +
  86331. + for (t = 0; t < 20; t++) {
  86332. + s = t & 0x0f;
  86333. + if (t >= 16) {
  86334. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  86335. + }
  86336. + tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
  86337. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  86338. + }
  86339. + for (t = 20; t < 40; t++) {
  86340. + s = t & 0x0f;
  86341. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  86342. + tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
  86343. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  86344. + }
  86345. + for (t = 40; t < 60; t++) {
  86346. + s = t & 0x0f;
  86347. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  86348. + tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
  86349. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  86350. + }
  86351. + for (t = 60; t < 80; t++) {
  86352. + s = t & 0x0f;
  86353. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  86354. + tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
  86355. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  86356. + }
  86357. +
  86358. + H(0) = H(0) + a;
  86359. + H(1) = H(1) + b;
  86360. + H(2) = H(2) + c;
  86361. + H(3) = H(3) + d;
  86362. + H(4) = H(4) + e;
  86363. +
  86364. + bzero(&ctxt->m.b8[0], 64);
  86365. +}
  86366. +
  86367. +/*------------------------------------------------------------*/
  86368. +
  86369. +void
  86370. +sha1_init(ctxt)
  86371. + struct sha1_ctxt *ctxt;
  86372. +{
  86373. + bzero(ctxt, sizeof(struct sha1_ctxt));
  86374. + H(0) = 0x67452301;
  86375. + H(1) = 0xefcdab89;
  86376. + H(2) = 0x98badcfe;
  86377. + H(3) = 0x10325476;
  86378. + H(4) = 0xc3d2e1f0;
  86379. +}
  86380. +
  86381. +void
  86382. +sha1_pad(ctxt)
  86383. + struct sha1_ctxt *ctxt;
  86384. +{
  86385. + size_t padlen; /*pad length in bytes*/
  86386. + size_t padstart;
  86387. +
  86388. + PUTPAD(0x80);
  86389. +
  86390. + padstart = COUNT % 64;
  86391. + padlen = 64 - padstart;
  86392. + if (padlen < 8) {
  86393. + bzero(&ctxt->m.b8[padstart], padlen);
  86394. + COUNT += padlen;
  86395. + COUNT %= 64;
  86396. + sha1_step(ctxt);
  86397. + padstart = COUNT % 64; /* should be 0 */
  86398. + padlen = 64 - padstart; /* should be 64 */
  86399. + }
  86400. + bzero(&ctxt->m.b8[padstart], padlen - 8);
  86401. + COUNT += (padlen - 8);
  86402. + COUNT %= 64;
  86403. +#if BYTE_ORDER == BIG_ENDIAN
  86404. + PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
  86405. + PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
  86406. + PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
  86407. + PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
  86408. +#else
  86409. + PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
  86410. + PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
  86411. + PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
  86412. + PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
  86413. +#endif
  86414. +}
  86415. +
  86416. +void
  86417. +sha1_loop(ctxt, input, len)
  86418. + struct sha1_ctxt *ctxt;
  86419. + const u_int8_t *input;
  86420. + size_t len;
  86421. +{
  86422. + size_t gaplen;
  86423. + size_t gapstart;
  86424. + size_t off;
  86425. + size_t copysiz;
  86426. +
  86427. + off = 0;
  86428. +
  86429. + while (off < len) {
  86430. + gapstart = COUNT % 64;
  86431. + gaplen = 64 - gapstart;
  86432. +
  86433. + copysiz = (gaplen < len - off) ? gaplen : len - off;
  86434. + bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz);
  86435. + COUNT += copysiz;
  86436. + COUNT %= 64;
  86437. + ctxt->c.b64[0] += copysiz * 8;
  86438. + if (COUNT % 64 == 0)
  86439. + sha1_step(ctxt);
  86440. + off += copysiz;
  86441. + }
  86442. +}
  86443. +
  86444. +void
  86445. +sha1_result(ctxt, digest0)
  86446. + struct sha1_ctxt *ctxt;
  86447. + caddr_t digest0;
  86448. +{
  86449. + u_int8_t *digest;
  86450. +
  86451. + digest = (u_int8_t *)digest0;
  86452. + sha1_pad(ctxt);
  86453. +#if BYTE_ORDER == BIG_ENDIAN
  86454. + bcopy(&ctxt->h.b8[0], digest, 20);
  86455. +#else
  86456. + digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
  86457. + digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
  86458. + digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
  86459. + digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
  86460. + digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
  86461. + digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
  86462. + digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
  86463. + digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
  86464. + digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
  86465. + digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
  86466. +#endif
  86467. +}
  86468. +
  86469. +#endif /*unsupported*/
  86470. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/sha1.h linux-2.6.39/crypto/ocf/safe/sha1.h
  86471. --- linux-2.6.39.orig/crypto/ocf/safe/sha1.h 1970-01-01 01:00:00.000000000 +0100
  86472. +++ linux-2.6.39/crypto/ocf/safe/sha1.h 2011-07-31 11:32:03.573607610 +0200
  86473. @@ -0,0 +1,72 @@
  86474. +/* $FreeBSD: src/sys/crypto/sha1.h,v 1.8 2002/03/20 05:13:50 alfred Exp $ */
  86475. +/* $KAME: sha1.h,v 1.5 2000/03/27 04:36:23 sumikawa Exp $ */
  86476. +
  86477. +/*
  86478. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  86479. + * All rights reserved.
  86480. + *
  86481. + * Redistribution and use in source and binary forms, with or without
  86482. + * modification, are permitted provided that the following conditions
  86483. + * are met:
  86484. + * 1. Redistributions of source code must retain the above copyright
  86485. + * notice, this list of conditions and the following disclaimer.
  86486. + * 2. Redistributions in binary form must reproduce the above copyright
  86487. + * notice, this list of conditions and the following disclaimer in the
  86488. + * documentation and/or other materials provided with the distribution.
  86489. + * 3. Neither the name of the project nor the names of its contributors
  86490. + * may be used to endorse or promote products derived from this software
  86491. + * without specific prior written permission.
  86492. + *
  86493. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  86494. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  86495. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  86496. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  86497. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  86498. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  86499. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  86500. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  86501. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  86502. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  86503. + * SUCH DAMAGE.
  86504. + */
  86505. +/*
  86506. + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
  86507. + * based on: http://csrc.nist.gov/fips/fip180-1.txt
  86508. + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
  86509. + */
  86510. +
  86511. +#ifndef _NETINET6_SHA1_H_
  86512. +#define _NETINET6_SHA1_H_
  86513. +
  86514. +struct sha1_ctxt {
  86515. + union {
  86516. + u_int8_t b8[20];
  86517. + u_int32_t b32[5];
  86518. + } h;
  86519. + union {
  86520. + u_int8_t b8[8];
  86521. + u_int64_t b64[1];
  86522. + } c;
  86523. + union {
  86524. + u_int8_t b8[64];
  86525. + u_int32_t b32[16];
  86526. + } m;
  86527. + u_int8_t count;
  86528. +};
  86529. +
  86530. +#ifdef __KERNEL__
  86531. +extern void sha1_init(struct sha1_ctxt *);
  86532. +extern void sha1_pad(struct sha1_ctxt *);
  86533. +extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);
  86534. +extern void sha1_result(struct sha1_ctxt *, caddr_t);
  86535. +
  86536. +/* compatibilty with other SHA1 source codes */
  86537. +typedef struct sha1_ctxt SHA1_CTX;
  86538. +#define SHA1Init(x) sha1_init((x))
  86539. +#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
  86540. +#define SHA1Final(x, y) sha1_result((y), (x))
  86541. +#endif /* __KERNEL__ */
  86542. +
  86543. +#define SHA1_RESULTLEN (160/8)
  86544. +
  86545. +#endif /*_NETINET6_SHA1_H_*/
  86546. diff -Nur linux-2.6.39.orig/crypto/ocf/talitos/Makefile linux-2.6.39/crypto/ocf/talitos/Makefile
  86547. --- linux-2.6.39.orig/crypto/ocf/talitos/Makefile 1970-01-01 01:00:00.000000000 +0100
  86548. +++ linux-2.6.39/crypto/ocf/talitos/Makefile 2011-07-31 11:32:03.614050367 +0200
  86549. @@ -0,0 +1,12 @@
  86550. +# for SGlinux builds
  86551. +-include $(ROOTDIR)/modules/.config
  86552. +
  86553. +obj-$(CONFIG_OCF_TALITOS) += talitos.o
  86554. +
  86555. +obj ?= .
  86556. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  86557. +
  86558. +ifdef TOPDIR
  86559. +-include $(TOPDIR)/Rules.make
  86560. +endif
  86561. +
  86562. diff -Nur linux-2.6.39.orig/crypto/ocf/talitos/talitos.c linux-2.6.39/crypto/ocf/talitos/talitos.c
  86563. --- linux-2.6.39.orig/crypto/ocf/talitos/talitos.c 1970-01-01 01:00:00.000000000 +0100
  86564. +++ linux-2.6.39/crypto/ocf/talitos/talitos.c 2011-07-31 11:32:03.693425260 +0200
  86565. @@ -0,0 +1,1359 @@
  86566. +/*
  86567. + * crypto/ocf/talitos/talitos.c
  86568. + *
  86569. + * An OCF-Linux module that uses Freescale's SEC to do the crypto.
  86570. + * Based on crypto/ocf/hifn and crypto/ocf/safe OCF drivers
  86571. + *
  86572. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  86573. + *
  86574. + * This code written by Kim A. B. Phillips <kim.phillips@freescale.com>
  86575. + * some code copied from files with the following:
  86576. + * Copyright (C) 2004-2007 David McCullough <david_mccullough@mcafee.com>
  86577. + *
  86578. + * Redistribution and use in source and binary forms, with or without
  86579. + * modification, are permitted provided that the following conditions
  86580. + * are met:
  86581. + *
  86582. + * 1. Redistributions of source code must retain the above copyright
  86583. + * notice, this list of conditions and the following disclaimer.
  86584. + * 2. Redistributions in binary form must reproduce the above copyright
  86585. + * notice, this list of conditions and the following disclaimer in the
  86586. + * documentation and/or other materials provided with the distribution.
  86587. + * 3. The name of the author may not be used to endorse or promote products
  86588. + * derived from this software without specific prior written permission.
  86589. + *
  86590. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  86591. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  86592. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  86593. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  86594. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  86595. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  86596. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  86597. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  86598. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  86599. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  86600. + *
  86601. + * ---------------------------------------------------------------------------
  86602. + *
  86603. + * NOTES:
  86604. + *
  86605. + * The Freescale SEC (also known as 'talitos') resides on the
  86606. + * internal bus, and runs asynchronous to the processor core. It has
  86607. + * a wide gamut of cryptographic acceleration features, including single-
  86608. + * pass IPsec (also known as algorithm chaining). To properly utilize
  86609. + * all of the SEC's performance enhancing features, further reworking
  86610. + * of higher level code (framework, applications) will be necessary.
  86611. + *
  86612. + * The following table shows which SEC version is present in which devices:
  86613. + *
  86614. + * Devices SEC version
  86615. + *
  86616. + * 8272, 8248 SEC 1.0
  86617. + * 885, 875 SEC 1.2
  86618. + * 8555E, 8541E SEC 2.0
  86619. + * 8349E SEC 2.01
  86620. + * 8548E SEC 2.1
  86621. + *
  86622. + * The following table shows the features offered by each SEC version:
  86623. + *
  86624. + * Max. chan-
  86625. + * version Bus I/F Clock nels DEU AESU AFEU MDEU PKEU RNG KEU
  86626. + *
  86627. + * SEC 1.0 internal 64b 100MHz 4 1 1 1 1 1 1 0
  86628. + * SEC 1.2 internal 32b 66MHz 1 1 1 0 1 0 0 0
  86629. + * SEC 2.0 internal 64b 166MHz 4 1 1 1 1 1 1 0
  86630. + * SEC 2.01 internal 64b 166MHz 4 1 1 1 1 1 1 0
  86631. + * SEC 2.1 internal 64b 333MHz 4 1 1 1 1 1 1 1
  86632. + *
  86633. + * Each execution unit in the SEC has two modes of execution; channel and
  86634. + * slave/debug. This driver employs the channel infrastructure in the
  86635. + * device for convenience. Only the RNG is directly accessed due to the
  86636. + * convenience of its random fifo pool. The relationship between the
  86637. + * channels and execution units is depicted in the following diagram:
  86638. + *
  86639. + * ------- ------------
  86640. + * ---| ch0 |---| |
  86641. + * ------- | |
  86642. + * | |------+-------+-------+-------+------------
  86643. + * ------- | | | | | | |
  86644. + * ---| ch1 |---| | | | | | |
  86645. + * ------- | | ------ ------ ------ ------ ------
  86646. + * |controller| |DEU | |AESU| |MDEU| |PKEU| ... |RNG |
  86647. + * ------- | | ------ ------ ------ ------ ------
  86648. + * ---| ch2 |---| | | | | | |
  86649. + * ------- | | | | | | |
  86650. + * | |------+-------+-------+-------+------------
  86651. + * ------- | |
  86652. + * ---| ch3 |---| |
  86653. + * ------- ------------
  86654. + *
  86655. + * Channel ch0 may drive an aes operation to the aes unit (AESU),
  86656. + * and, at the same time, ch1 may drive a message digest operation
  86657. + * to the mdeu. Each channel has an input descriptor FIFO, and the
  86658. + * FIFO can contain, e.g. on the 8541E, up to 24 entries, before a
  86659. + * a buffer overrun error is triggered. The controller is responsible
  86660. + * for fetching the data from descriptor pointers, and passing the
  86661. + * data to the appropriate EUs. The controller also writes the
  86662. + * cryptographic operation's result to memory. The SEC notifies
  86663. + * completion by triggering an interrupt and/or setting the 1st byte
  86664. + * of the hdr field to 0xff.
  86665. + *
  86666. + * TODO:
  86667. + * o support more algorithms
  86668. + * o support more versions of the SEC
  86669. + * o add support for linux 2.4
  86670. + * o scatter-gather (sg) support
  86671. + * o add support for public key ops (PKEU)
  86672. + * o add statistics
  86673. + */
  86674. +
  86675. +#ifndef AUTOCONF_INCLUDED
  86676. +#include <linux/config.h>
  86677. +#endif
  86678. +#include <linux/module.h>
  86679. +#include <linux/init.h>
  86680. +#include <linux/interrupt.h>
  86681. +#include <linux/spinlock.h>
  86682. +#include <linux/random.h>
  86683. +#include <linux/skbuff.h>
  86684. +#include <asm/scatterlist.h>
  86685. +#include <linux/dma-mapping.h> /* dma_map_single() */
  86686. +#include <linux/moduleparam.h>
  86687. +
  86688. +#include <linux/version.h>
  86689. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
  86690. +#include <linux/platform_device.h>
  86691. +#endif
  86692. +
  86693. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  86694. +#include <linux/of_platform.h>
  86695. +#endif
  86696. +
  86697. +#include <cryptodev.h>
  86698. +#include <uio.h>
  86699. +
  86700. +#define DRV_NAME "talitos"
  86701. +
  86702. +#include "talitos_dev.h"
  86703. +#include "talitos_soft.h"
  86704. +
  86705. +#define read_random(p,l) get_random_bytes(p,l)
  86706. +
  86707. +const char talitos_driver_name[] = "Talitos OCF";
  86708. +const char talitos_driver_version[] = "0.2";
  86709. +
  86710. +static int talitos_newsession(device_t dev, u_int32_t *sidp,
  86711. + struct cryptoini *cri);
  86712. +static int talitos_freesession(device_t dev, u_int64_t tid);
  86713. +static int talitos_process(device_t dev, struct cryptop *crp, int hint);
  86714. +static void dump_talitos_status(struct talitos_softc *sc);
  86715. +static int talitos_submit(struct talitos_softc *sc, struct talitos_desc *td,
  86716. + int chsel);
  86717. +static void talitos_doneprocessing(struct talitos_softc *sc);
  86718. +static void talitos_init_device(struct talitos_softc *sc);
  86719. +static void talitos_reset_device_master(struct talitos_softc *sc);
  86720. +static void talitos_reset_device(struct talitos_softc *sc);
  86721. +static void talitos_errorprocessing(struct talitos_softc *sc);
  86722. +#ifdef CONFIG_PPC_MERGE
  86723. +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match);
  86724. +static int talitos_remove(struct of_device *ofdev);
  86725. +#else
  86726. +static int talitos_probe(struct platform_device *pdev);
  86727. +static int talitos_remove(struct platform_device *pdev);
  86728. +#endif
  86729. +#ifdef CONFIG_OCF_RANDOMHARVEST
  86730. +static int talitos_read_random(void *arg, u_int32_t *buf, int maxwords);
  86731. +static void talitos_rng_init(struct talitos_softc *sc);
  86732. +#endif
  86733. +
  86734. +static device_method_t talitos_methods = {
  86735. + /* crypto device methods */
  86736. + DEVMETHOD(cryptodev_newsession, talitos_newsession),
  86737. + DEVMETHOD(cryptodev_freesession,talitos_freesession),
  86738. + DEVMETHOD(cryptodev_process, talitos_process),
  86739. +};
  86740. +
  86741. +#define debug talitos_debug
  86742. +int talitos_debug = 0;
  86743. +module_param(talitos_debug, int, 0644);
  86744. +MODULE_PARM_DESC(talitos_debug, "Enable debug");
  86745. +
  86746. +static inline void talitos_write(volatile unsigned *addr, u32 val)
  86747. +{
  86748. + out_be32(addr, val);
  86749. +}
  86750. +
  86751. +static inline u32 talitos_read(volatile unsigned *addr)
  86752. +{
  86753. + u32 val;
  86754. + val = in_be32(addr);
  86755. + return val;
  86756. +}
  86757. +
  86758. +static void dump_talitos_status(struct talitos_softc *sc)
  86759. +{
  86760. + unsigned int v, v_hi, i, *ptr;
  86761. + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
  86762. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_MCR_HI);
  86763. + printk(KERN_INFO "%s: MCR 0x%08x_%08x\n",
  86764. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  86765. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
  86766. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
  86767. + printk(KERN_INFO "%s: IMR 0x%08x_%08x\n",
  86768. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  86769. + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
  86770. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
  86771. + printk(KERN_INFO "%s: ISR 0x%08x_%08x\n",
  86772. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  86773. + for (i = 0; i < sc->sc_num_channels; i++) {
  86774. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  86775. + TALITOS_CH_CDPR);
  86776. + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  86777. + TALITOS_CH_CDPR_HI);
  86778. + printk(KERN_INFO "%s: CDPR ch%d 0x%08x_%08x\n",
  86779. + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
  86780. + }
  86781. + for (i = 0; i < sc->sc_num_channels; i++) {
  86782. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  86783. + TALITOS_CH_CCPSR);
  86784. + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  86785. + TALITOS_CH_CCPSR_HI);
  86786. + printk(KERN_INFO "%s: CCPSR ch%d 0x%08x_%08x\n",
  86787. + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
  86788. + }
  86789. + ptr = sc->sc_base_addr + TALITOS_CH_DESCBUF;
  86790. + for (i = 0; i < 16; i++) {
  86791. + v = talitos_read(ptr++); v_hi = talitos_read(ptr++);
  86792. + printk(KERN_INFO "%s: DESCBUF ch0 0x%08x_%08x (tdp%02d)\n",
  86793. + device_get_nameunit(sc->sc_cdev), v, v_hi, i);
  86794. + }
  86795. + return;
  86796. +}
  86797. +
  86798. +
  86799. +#ifdef CONFIG_OCF_RANDOMHARVEST
  86800. +/*
  86801. + * pull random numbers off the RNG FIFO, not exceeding amount available
  86802. + */
  86803. +static int
  86804. +talitos_read_random(void *arg, u_int32_t *buf, int maxwords)
  86805. +{
  86806. + struct talitos_softc *sc = (struct talitos_softc *) arg;
  86807. + int rc;
  86808. + u_int32_t v;
  86809. +
  86810. + DPRINTF("%s()\n", __FUNCTION__);
  86811. +
  86812. + /* check for things like FIFO underflow */
  86813. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
  86814. + if (unlikely(v)) {
  86815. + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
  86816. + device_get_nameunit(sc->sc_cdev), v);
  86817. + return 0;
  86818. + }
  86819. + /*
  86820. + * OFL is number of available 64-bit words,
  86821. + * shift and convert to a 32-bit word count
  86822. + */
  86823. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI);
  86824. + v = (v & TALITOS_RNGSR_HI_OFL) >> (16 - 1);
  86825. + if (maxwords > v)
  86826. + maxwords = v;
  86827. + for (rc = 0; rc < maxwords; rc++) {
  86828. + buf[rc] = talitos_read(sc->sc_base_addr +
  86829. + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
  86830. + }
  86831. + if (maxwords & 1) {
  86832. + /*
  86833. + * RNG will complain with an AE in the RNGISR
  86834. + * if we don't complete the pairs of 32-bit reads
  86835. + * to its 64-bit register based FIFO
  86836. + */
  86837. + v = talitos_read(sc->sc_base_addr +
  86838. + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
  86839. + }
  86840. +
  86841. + return rc;
  86842. +}
  86843. +
  86844. +static void
  86845. +talitos_rng_init(struct talitos_softc *sc)
  86846. +{
  86847. + u_int32_t v;
  86848. +
  86849. + DPRINTF("%s()\n", __FUNCTION__);
  86850. + /* reset RNG EU */
  86851. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGRCR_HI);
  86852. + v |= TALITOS_RNGRCR_HI_SR;
  86853. + talitos_write(sc->sc_base_addr + TALITOS_RNGRCR_HI, v);
  86854. + while ((talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI)
  86855. + & TALITOS_RNGSR_HI_RD) == 0)
  86856. + cpu_relax();
  86857. + /*
  86858. + * we tell the RNG to start filling the RNG FIFO
  86859. + * by writing the RNGDSR
  86860. + */
  86861. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGDSR_HI);
  86862. + talitos_write(sc->sc_base_addr + TALITOS_RNGDSR_HI, v);
  86863. + /*
  86864. + * 64 bits of data will be pushed onto the FIFO every
  86865. + * 256 SEC cycles until the FIFO is full. The RNG then
  86866. + * attempts to keep the FIFO full.
  86867. + */
  86868. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
  86869. + if (v) {
  86870. + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
  86871. + device_get_nameunit(sc->sc_cdev), v);
  86872. + return;
  86873. + }
  86874. + /*
  86875. + * n.b. we need to add a FIPS test here - if the RNG is going
  86876. + * to fail, it's going to fail at reset time
  86877. + */
  86878. + return;
  86879. +}
  86880. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  86881. +
  86882. +/*
  86883. + * Generate a new software session.
  86884. + */
  86885. +static int
  86886. +talitos_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  86887. +{
  86888. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  86889. + struct talitos_softc *sc = device_get_softc(dev);
  86890. + struct talitos_session *ses = NULL;
  86891. + int sesn;
  86892. +
  86893. + DPRINTF("%s()\n", __FUNCTION__);
  86894. + if (sidp == NULL || cri == NULL || sc == NULL) {
  86895. + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
  86896. + return EINVAL;
  86897. + }
  86898. + for (c = cri; c != NULL; c = c->cri_next) {
  86899. + if (c->cri_alg == CRYPTO_MD5 ||
  86900. + c->cri_alg == CRYPTO_MD5_HMAC ||
  86901. + c->cri_alg == CRYPTO_SHA1 ||
  86902. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  86903. + c->cri_alg == CRYPTO_NULL_HMAC) {
  86904. + if (macini)
  86905. + return EINVAL;
  86906. + macini = c;
  86907. + } else if (c->cri_alg == CRYPTO_DES_CBC ||
  86908. + c->cri_alg == CRYPTO_3DES_CBC ||
  86909. + c->cri_alg == CRYPTO_AES_CBC ||
  86910. + c->cri_alg == CRYPTO_NULL_CBC) {
  86911. + if (encini)
  86912. + return EINVAL;
  86913. + encini = c;
  86914. + } else {
  86915. + DPRINTF("UNKNOWN c->cri_alg %d\n", encini->cri_alg);
  86916. + return EINVAL;
  86917. + }
  86918. + }
  86919. + if (encini == NULL && macini == NULL)
  86920. + return EINVAL;
  86921. + if (encini) {
  86922. + /* validate key length */
  86923. + switch (encini->cri_alg) {
  86924. + case CRYPTO_DES_CBC:
  86925. + if (encini->cri_klen != 64)
  86926. + return EINVAL;
  86927. + break;
  86928. + case CRYPTO_3DES_CBC:
  86929. + if (encini->cri_klen != 192) {
  86930. + return EINVAL;
  86931. + }
  86932. + break;
  86933. + case CRYPTO_AES_CBC:
  86934. + if (encini->cri_klen != 128 &&
  86935. + encini->cri_klen != 192 &&
  86936. + encini->cri_klen != 256)
  86937. + return EINVAL;
  86938. + break;
  86939. + default:
  86940. + DPRINTF("UNKNOWN encini->cri_alg %d\n",
  86941. + encini->cri_alg);
  86942. + return EINVAL;
  86943. + }
  86944. + }
  86945. +
  86946. + if (sc->sc_sessions == NULL) {
  86947. + ses = sc->sc_sessions = (struct talitos_session *)
  86948. + kmalloc(sizeof(struct talitos_session), SLAB_ATOMIC);
  86949. + if (ses == NULL)
  86950. + return ENOMEM;
  86951. + memset(ses, 0, sizeof(struct talitos_session));
  86952. + sesn = 0;
  86953. + sc->sc_nsessions = 1;
  86954. + } else {
  86955. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  86956. + if (sc->sc_sessions[sesn].ses_used == 0) {
  86957. + ses = &sc->sc_sessions[sesn];
  86958. + break;
  86959. + }
  86960. + }
  86961. +
  86962. + if (ses == NULL) {
  86963. + /* allocating session */
  86964. + sesn = sc->sc_nsessions;
  86965. + ses = (struct talitos_session *) kmalloc(
  86966. + (sesn + 1) * sizeof(struct talitos_session),
  86967. + SLAB_ATOMIC);
  86968. + if (ses == NULL)
  86969. + return ENOMEM;
  86970. + memset(ses, 0,
  86971. + (sesn + 1) * sizeof(struct talitos_session));
  86972. + memcpy(ses, sc->sc_sessions,
  86973. + sesn * sizeof(struct talitos_session));
  86974. + memset(sc->sc_sessions, 0,
  86975. + sesn * sizeof(struct talitos_session));
  86976. + kfree(sc->sc_sessions);
  86977. + sc->sc_sessions = ses;
  86978. + ses = &sc->sc_sessions[sesn];
  86979. + sc->sc_nsessions++;
  86980. + }
  86981. + }
  86982. +
  86983. + ses->ses_used = 1;
  86984. +
  86985. + if (encini) {
  86986. + /* get an IV */
  86987. + /* XXX may read fewer than requested */
  86988. + read_random(ses->ses_iv, sizeof(ses->ses_iv));
  86989. +
  86990. + ses->ses_klen = (encini->cri_klen + 7) / 8;
  86991. + memcpy(ses->ses_key, encini->cri_key, ses->ses_klen);
  86992. + if (macini) {
  86993. + /* doing hash on top of cipher */
  86994. + ses->ses_hmac_len = (macini->cri_klen + 7) / 8;
  86995. + memcpy(ses->ses_hmac, macini->cri_key,
  86996. + ses->ses_hmac_len);
  86997. + }
  86998. + } else if (macini) {
  86999. + /* doing hash */
  87000. + ses->ses_klen = (macini->cri_klen + 7) / 8;
  87001. + memcpy(ses->ses_key, macini->cri_key, ses->ses_klen);
  87002. + }
  87003. +
  87004. + /* back compat way of determining MSC result len */
  87005. + if (macini) {
  87006. + ses->ses_mlen = macini->cri_mlen;
  87007. + if (ses->ses_mlen == 0) {
  87008. + if (macini->cri_alg == CRYPTO_MD5_HMAC)
  87009. + ses->ses_mlen = MD5_HASH_LEN;
  87010. + else
  87011. + ses->ses_mlen = SHA1_HASH_LEN;
  87012. + }
  87013. + }
  87014. +
  87015. + /* really should make up a template td here,
  87016. + * and only fill things like i/o and direction in process() */
  87017. +
  87018. + /* assign session ID */
  87019. + *sidp = TALITOS_SID(sc->sc_num, sesn);
  87020. + return 0;
  87021. +}
  87022. +
  87023. +/*
  87024. + * Deallocate a session.
  87025. + */
  87026. +static int
  87027. +talitos_freesession(device_t dev, u_int64_t tid)
  87028. +{
  87029. + struct talitos_softc *sc = device_get_softc(dev);
  87030. + int session, ret;
  87031. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  87032. +
  87033. + if (sc == NULL)
  87034. + return EINVAL;
  87035. + session = TALITOS_SESSION(sid);
  87036. + if (session < sc->sc_nsessions) {
  87037. + memset(&sc->sc_sessions[session], 0,
  87038. + sizeof(sc->sc_sessions[session]));
  87039. + ret = 0;
  87040. + } else
  87041. + ret = EINVAL;
  87042. + return ret;
  87043. +}
  87044. +
  87045. +/*
  87046. + * launch device processing - it will come back with done notification
  87047. + * in the form of an interrupt and/or HDR_DONE_BITS in header
  87048. + */
  87049. +static int
  87050. +talitos_submit(
  87051. + struct talitos_softc *sc,
  87052. + struct talitos_desc *td,
  87053. + int chsel)
  87054. +{
  87055. + u_int32_t v;
  87056. +
  87057. + v = dma_map_single(NULL, td, sizeof(*td), DMA_TO_DEVICE);
  87058. + talitos_write(sc->sc_base_addr +
  87059. + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF, 0);
  87060. + talitos_write(sc->sc_base_addr +
  87061. + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF_HI, v);
  87062. + return 0;
  87063. +}
  87064. +
  87065. +static int
  87066. +talitos_process(device_t dev, struct cryptop *crp, int hint)
  87067. +{
  87068. + int i, err = 0, ivsize;
  87069. + struct talitos_softc *sc = device_get_softc(dev);
  87070. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  87071. + caddr_t iv;
  87072. + struct talitos_session *ses;
  87073. + struct talitos_desc *td;
  87074. + unsigned long flags;
  87075. + /* descriptor mappings */
  87076. + int hmac_key, hmac_data, cipher_iv, cipher_key,
  87077. + in_fifo, out_fifo, cipher_iv_out;
  87078. + static int chsel = -1;
  87079. +
  87080. + DPRINTF("%s()\n", __FUNCTION__);
  87081. +
  87082. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
  87083. + return EINVAL;
  87084. + }
  87085. + crp->crp_etype = 0;
  87086. + if (TALITOS_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
  87087. + return EINVAL;
  87088. + }
  87089. +
  87090. + ses = &sc->sc_sessions[TALITOS_SESSION(crp->crp_sid)];
  87091. +
  87092. + /* enter the channel scheduler */
  87093. + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  87094. +
  87095. + /* reuse channel that already had/has requests for the required EU */
  87096. + for (i = 0; i < sc->sc_num_channels; i++) {
  87097. + if (sc->sc_chnlastalg[i] == crp->crp_desc->crd_alg)
  87098. + break;
  87099. + }
  87100. + if (i == sc->sc_num_channels) {
  87101. + /*
  87102. + * haven't seen this algo the last sc_num_channels or more
  87103. + * use round robin in this case
  87104. + * nb: sc->sc_num_channels must be power of 2
  87105. + */
  87106. + chsel = (chsel + 1) & (sc->sc_num_channels - 1);
  87107. + } else {
  87108. + /*
  87109. + * matches channel with same target execution unit;
  87110. + * use same channel in this case
  87111. + */
  87112. + chsel = i;
  87113. + }
  87114. + sc->sc_chnlastalg[chsel] = crp->crp_desc->crd_alg;
  87115. +
  87116. + /* release the channel scheduler lock */
  87117. + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  87118. +
  87119. + /* acquire the selected channel fifo lock */
  87120. + spin_lock_irqsave(&sc->sc_chnfifolock[chsel], flags);
  87121. +
  87122. + /* find and reserve next available descriptor-cryptop pair */
  87123. + for (i = 0; i < sc->sc_chfifo_len; i++) {
  87124. + if (sc->sc_chnfifo[chsel][i].cf_desc.hdr == 0) {
  87125. + /*
  87126. + * ensure correct descriptor formation by
  87127. + * avoiding inadvertently setting "optional" entries
  87128. + * e.g. not using "optional" dptr2 for MD/HMAC descs
  87129. + */
  87130. + memset(&sc->sc_chnfifo[chsel][i].cf_desc,
  87131. + 0, sizeof(*td));
  87132. + /* reserve it with done notification request bit */
  87133. + sc->sc_chnfifo[chsel][i].cf_desc.hdr |=
  87134. + TALITOS_DONE_NOTIFY;
  87135. + break;
  87136. + }
  87137. + }
  87138. + spin_unlock_irqrestore(&sc->sc_chnfifolock[chsel], flags);
  87139. +
  87140. + if (i == sc->sc_chfifo_len) {
  87141. + /* fifo full */
  87142. + err = ERESTART;
  87143. + goto errout;
  87144. + }
  87145. +
  87146. + td = &sc->sc_chnfifo[chsel][i].cf_desc;
  87147. + sc->sc_chnfifo[chsel][i].cf_crp = crp;
  87148. +
  87149. + crd1 = crp->crp_desc;
  87150. + if (crd1 == NULL) {
  87151. + err = EINVAL;
  87152. + goto errout;
  87153. + }
  87154. + crd2 = crd1->crd_next;
  87155. + /* prevent compiler warning */
  87156. + hmac_key = 0;
  87157. + hmac_data = 0;
  87158. + if (crd2 == NULL) {
  87159. + td->hdr |= TD_TYPE_COMMON_NONSNOOP_NO_AFEU;
  87160. + /* assign descriptor dword ptr mappings for this desc. type */
  87161. + cipher_iv = 1;
  87162. + cipher_key = 2;
  87163. + in_fifo = 3;
  87164. + cipher_iv_out = 5;
  87165. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  87166. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  87167. + crd1->crd_alg == CRYPTO_SHA1 ||
  87168. + crd1->crd_alg == CRYPTO_MD5) {
  87169. + out_fifo = 5;
  87170. + maccrd = crd1;
  87171. + enccrd = NULL;
  87172. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  87173. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  87174. + crd1->crd_alg == CRYPTO_AES_CBC ||
  87175. + crd1->crd_alg == CRYPTO_ARC4) {
  87176. + out_fifo = 4;
  87177. + maccrd = NULL;
  87178. + enccrd = crd1;
  87179. + } else {
  87180. + DPRINTF("UNKNOWN crd1->crd_alg %d\n", crd1->crd_alg);
  87181. + err = EINVAL;
  87182. + goto errout;
  87183. + }
  87184. + } else {
  87185. + if (sc->sc_desc_types & TALITOS_HAS_DT_IPSEC_ESP) {
  87186. + td->hdr |= TD_TYPE_IPSEC_ESP;
  87187. + } else {
  87188. + DPRINTF("unimplemented: multiple descriptor ipsec\n");
  87189. + err = EINVAL;
  87190. + goto errout;
  87191. + }
  87192. + /* assign descriptor dword ptr mappings for this desc. type */
  87193. + hmac_key = 0;
  87194. + hmac_data = 1;
  87195. + cipher_iv = 2;
  87196. + cipher_key = 3;
  87197. + in_fifo = 4;
  87198. + out_fifo = 5;
  87199. + cipher_iv_out = 6;
  87200. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  87201. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  87202. + crd1->crd_alg == CRYPTO_MD5 ||
  87203. + crd1->crd_alg == CRYPTO_SHA1) &&
  87204. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  87205. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  87206. + crd2->crd_alg == CRYPTO_AES_CBC ||
  87207. + crd2->crd_alg == CRYPTO_ARC4) &&
  87208. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  87209. + maccrd = crd1;
  87210. + enccrd = crd2;
  87211. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  87212. + crd1->crd_alg == CRYPTO_ARC4 ||
  87213. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  87214. + crd1->crd_alg == CRYPTO_AES_CBC) &&
  87215. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  87216. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  87217. + crd2->crd_alg == CRYPTO_MD5 ||
  87218. + crd2->crd_alg == CRYPTO_SHA1) &&
  87219. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  87220. + enccrd = crd1;
  87221. + maccrd = crd2;
  87222. + } else {
  87223. + /* We cannot order the SEC as requested */
  87224. + printk("%s: cannot do the order\n",
  87225. + device_get_nameunit(sc->sc_cdev));
  87226. + err = EINVAL;
  87227. + goto errout;
  87228. + }
  87229. + }
  87230. + /* assign in_fifo and out_fifo based on input/output struct type */
  87231. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  87232. + /* using SKB buffers */
  87233. + struct sk_buff *skb = (struct sk_buff *)crp->crp_buf;
  87234. + if (skb_shinfo(skb)->nr_frags) {
  87235. + printk("%s: skb frags unimplemented\n",
  87236. + device_get_nameunit(sc->sc_cdev));
  87237. + err = EINVAL;
  87238. + goto errout;
  87239. + }
  87240. + td->ptr[in_fifo].ptr = dma_map_single(NULL, skb->data,
  87241. + skb->len, DMA_TO_DEVICE);
  87242. + td->ptr[in_fifo].len = skb->len;
  87243. + td->ptr[out_fifo].ptr = dma_map_single(NULL, skb->data,
  87244. + skb->len, DMA_TO_DEVICE);
  87245. + td->ptr[out_fifo].len = skb->len;
  87246. + td->ptr[hmac_data].ptr = dma_map_single(NULL, skb->data,
  87247. + skb->len, DMA_TO_DEVICE);
  87248. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  87249. + /* using IOV buffers */
  87250. + struct uio *uiop = (struct uio *)crp->crp_buf;
  87251. + if (uiop->uio_iovcnt > 1) {
  87252. + printk("%s: iov frags unimplemented\n",
  87253. + device_get_nameunit(sc->sc_cdev));
  87254. + err = EINVAL;
  87255. + goto errout;
  87256. + }
  87257. + td->ptr[in_fifo].ptr = dma_map_single(NULL,
  87258. + uiop->uio_iov->iov_base, crp->crp_ilen, DMA_TO_DEVICE);
  87259. + td->ptr[in_fifo].len = crp->crp_ilen;
  87260. + /* crp_olen is never set; always use crp_ilen */
  87261. + td->ptr[out_fifo].ptr = dma_map_single(NULL,
  87262. + uiop->uio_iov->iov_base,
  87263. + crp->crp_ilen, DMA_TO_DEVICE);
  87264. + td->ptr[out_fifo].len = crp->crp_ilen;
  87265. + } else {
  87266. + /* using contig buffers */
  87267. + td->ptr[in_fifo].ptr = dma_map_single(NULL,
  87268. + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
  87269. + td->ptr[in_fifo].len = crp->crp_ilen;
  87270. + td->ptr[out_fifo].ptr = dma_map_single(NULL,
  87271. + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
  87272. + td->ptr[out_fifo].len = crp->crp_ilen;
  87273. + }
  87274. + if (enccrd) {
  87275. + switch (enccrd->crd_alg) {
  87276. + case CRYPTO_3DES_CBC:
  87277. + td->hdr |= TALITOS_MODE0_DEU_3DES;
  87278. + /* FALLTHROUGH */
  87279. + case CRYPTO_DES_CBC:
  87280. + td->hdr |= TALITOS_SEL0_DEU
  87281. + | TALITOS_MODE0_DEU_CBC;
  87282. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  87283. + td->hdr |= TALITOS_MODE0_DEU_ENC;
  87284. + ivsize = 2*sizeof(u_int32_t);
  87285. + DPRINTF("%cDES ses %d ch %d len %d\n",
  87286. + (td->hdr & TALITOS_MODE0_DEU_3DES)?'3':'1',
  87287. + (u32)TALITOS_SESSION(crp->crp_sid),
  87288. + chsel, td->ptr[in_fifo].len);
  87289. + break;
  87290. + case CRYPTO_AES_CBC:
  87291. + td->hdr |= TALITOS_SEL0_AESU
  87292. + | TALITOS_MODE0_AESU_CBC;
  87293. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  87294. + td->hdr |= TALITOS_MODE0_AESU_ENC;
  87295. + ivsize = 4*sizeof(u_int32_t);
  87296. + DPRINTF("AES ses %d ch %d len %d\n",
  87297. + (u32)TALITOS_SESSION(crp->crp_sid),
  87298. + chsel, td->ptr[in_fifo].len);
  87299. + break;
  87300. + default:
  87301. + printk("%s: unimplemented enccrd->crd_alg %d\n",
  87302. + device_get_nameunit(sc->sc_cdev), enccrd->crd_alg);
  87303. + err = EINVAL;
  87304. + goto errout;
  87305. + }
  87306. + /*
  87307. + * Setup encrypt/decrypt state. When using basic ops
  87308. + * we can't use an inline IV because hash/crypt offset
  87309. + * must be from the end of the IV to the start of the
  87310. + * crypt data and this leaves out the preceding header
  87311. + * from the hash calculation. Instead we place the IV
  87312. + * in the state record and set the hash/crypt offset to
  87313. + * copy both the header+IV.
  87314. + */
  87315. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  87316. + td->hdr |= TALITOS_DIR_OUTBOUND;
  87317. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  87318. + iv = enccrd->crd_iv;
  87319. + else
  87320. + iv = (caddr_t) ses->ses_iv;
  87321. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  87322. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  87323. + enccrd->crd_inject, ivsize, iv);
  87324. + }
  87325. + } else {
  87326. + td->hdr |= TALITOS_DIR_INBOUND;
  87327. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  87328. + iv = enccrd->crd_iv;
  87329. + bcopy(enccrd->crd_iv, iv, ivsize);
  87330. + } else {
  87331. + iv = (caddr_t) ses->ses_iv;
  87332. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  87333. + enccrd->crd_inject, ivsize, iv);
  87334. + }
  87335. + }
  87336. + td->ptr[cipher_iv].ptr = dma_map_single(NULL, iv, ivsize,
  87337. + DMA_TO_DEVICE);
  87338. + td->ptr[cipher_iv].len = ivsize;
  87339. + /*
  87340. + * we don't need the cipher iv out length/pointer
  87341. + * field to do ESP IPsec. Therefore we set the len field as 0,
  87342. + * which tells the SEC not to do anything with this len/ptr
  87343. + * field. Previously, when length/pointer as pointing to iv,
  87344. + * it gave us corruption of packets.
  87345. + */
  87346. + td->ptr[cipher_iv_out].len = 0;
  87347. + }
  87348. + if (enccrd && maccrd) {
  87349. + /* this is ipsec only for now */
  87350. + td->hdr |= TALITOS_SEL1_MDEU
  87351. + | TALITOS_MODE1_MDEU_INIT
  87352. + | TALITOS_MODE1_MDEU_PAD;
  87353. + switch (maccrd->crd_alg) {
  87354. + case CRYPTO_MD5:
  87355. + td->hdr |= TALITOS_MODE1_MDEU_MD5;
  87356. + break;
  87357. + case CRYPTO_MD5_HMAC:
  87358. + td->hdr |= TALITOS_MODE1_MDEU_MD5_HMAC;
  87359. + break;
  87360. + case CRYPTO_SHA1:
  87361. + td->hdr |= TALITOS_MODE1_MDEU_SHA1;
  87362. + break;
  87363. + case CRYPTO_SHA1_HMAC:
  87364. + td->hdr |= TALITOS_MODE1_MDEU_SHA1_HMAC;
  87365. + break;
  87366. + default:
  87367. + /* We cannot order the SEC as requested */
  87368. + printk("%s: cannot do the order\n",
  87369. + device_get_nameunit(sc->sc_cdev));
  87370. + err = EINVAL;
  87371. + goto errout;
  87372. + }
  87373. + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
  87374. + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
  87375. + /*
  87376. + * The offset from hash data to the start of
  87377. + * crypt data is the difference in the skips.
  87378. + */
  87379. + /* ipsec only for now */
  87380. + td->ptr[hmac_key].ptr = dma_map_single(NULL,
  87381. + ses->ses_hmac, ses->ses_hmac_len, DMA_TO_DEVICE);
  87382. + td->ptr[hmac_key].len = ses->ses_hmac_len;
  87383. + td->ptr[in_fifo].ptr += enccrd->crd_skip;
  87384. + td->ptr[in_fifo].len = enccrd->crd_len;
  87385. + td->ptr[out_fifo].ptr += enccrd->crd_skip;
  87386. + td->ptr[out_fifo].len = enccrd->crd_len;
  87387. + /* bytes of HMAC to postpend to ciphertext */
  87388. + td->ptr[out_fifo].extent = ses->ses_mlen;
  87389. + td->ptr[hmac_data].ptr += maccrd->crd_skip;
  87390. + td->ptr[hmac_data].len = enccrd->crd_skip - maccrd->crd_skip;
  87391. + }
  87392. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  87393. + printk("%s: CRD_F_KEY_EXPLICIT unimplemented\n",
  87394. + device_get_nameunit(sc->sc_cdev));
  87395. + }
  87396. + }
  87397. + if (!enccrd && maccrd) {
  87398. + /* single MD5 or SHA */
  87399. + td->hdr |= TALITOS_SEL0_MDEU
  87400. + | TALITOS_MODE0_MDEU_INIT
  87401. + | TALITOS_MODE0_MDEU_PAD;
  87402. + switch (maccrd->crd_alg) {
  87403. + case CRYPTO_MD5:
  87404. + td->hdr |= TALITOS_MODE0_MDEU_MD5;
  87405. + DPRINTF("MD5 ses %d ch %d len %d\n",
  87406. + (u32)TALITOS_SESSION(crp->crp_sid),
  87407. + chsel, td->ptr[in_fifo].len);
  87408. + break;
  87409. + case CRYPTO_MD5_HMAC:
  87410. + td->hdr |= TALITOS_MODE0_MDEU_MD5_HMAC;
  87411. + break;
  87412. + case CRYPTO_SHA1:
  87413. + td->hdr |= TALITOS_MODE0_MDEU_SHA1;
  87414. + DPRINTF("SHA1 ses %d ch %d len %d\n",
  87415. + (u32)TALITOS_SESSION(crp->crp_sid),
  87416. + chsel, td->ptr[in_fifo].len);
  87417. + break;
  87418. + case CRYPTO_SHA1_HMAC:
  87419. + td->hdr |= TALITOS_MODE0_MDEU_SHA1_HMAC;
  87420. + break;
  87421. + default:
  87422. + /* We cannot order the SEC as requested */
  87423. + DPRINTF("cannot do the order\n");
  87424. + err = EINVAL;
  87425. + goto errout;
  87426. + }
  87427. +
  87428. + if (crp->crp_flags & CRYPTO_F_IOV)
  87429. + td->ptr[out_fifo].ptr += maccrd->crd_inject;
  87430. +
  87431. + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
  87432. + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
  87433. + td->ptr[hmac_key].ptr = dma_map_single(NULL,
  87434. + ses->ses_hmac, ses->ses_hmac_len,
  87435. + DMA_TO_DEVICE);
  87436. + td->ptr[hmac_key].len = ses->ses_hmac_len;
  87437. + }
  87438. + }
  87439. + else {
  87440. + /* using process key (session data has duplicate) */
  87441. + td->ptr[cipher_key].ptr = dma_map_single(NULL,
  87442. + enccrd->crd_key, (enccrd->crd_klen + 7) / 8,
  87443. + DMA_TO_DEVICE);
  87444. + td->ptr[cipher_key].len = (enccrd->crd_klen + 7) / 8;
  87445. + }
  87446. + /* descriptor complete - GO! */
  87447. + return talitos_submit(sc, td, chsel);
  87448. +
  87449. +errout:
  87450. + if (err != ERESTART) {
  87451. + crp->crp_etype = err;
  87452. + crypto_done(crp);
  87453. + }
  87454. + return err;
  87455. +}
  87456. +
  87457. +/* go through all channels descriptors, notifying OCF what has
  87458. + * _and_hasn't_ successfully completed and reset the device
  87459. + * (otherwise it's up to decoding desc hdrs!)
  87460. + */
  87461. +static void talitos_errorprocessing(struct talitos_softc *sc)
  87462. +{
  87463. + unsigned long flags;
  87464. + int i, j;
  87465. +
  87466. + /* disable further scheduling until under control */
  87467. + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  87468. +
  87469. + if (debug) dump_talitos_status(sc);
  87470. + /* go through descriptors, try and salvage those successfully done,
  87471. + * and EIO those that weren't
  87472. + */
  87473. + for (i = 0; i < sc->sc_num_channels; i++) {
  87474. + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
  87475. + for (j = 0; j < sc->sc_chfifo_len; j++) {
  87476. + if (sc->sc_chnfifo[i][j].cf_desc.hdr) {
  87477. + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
  87478. + & TALITOS_HDR_DONE_BITS)
  87479. + != TALITOS_HDR_DONE_BITS) {
  87480. + /* this one didn't finish */
  87481. + /* signify in crp->etype */
  87482. + sc->sc_chnfifo[i][j].cf_crp->crp_etype
  87483. + = EIO;
  87484. + }
  87485. + } else
  87486. + continue; /* free entry */
  87487. + /* either way, notify ocf */
  87488. + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
  87489. + /* and tag it available again
  87490. + *
  87491. + * memset to ensure correct descriptor formation by
  87492. + * avoiding inadvertently setting "optional" entries
  87493. + * e.g. not using "optional" dptr2 MD/HMAC processing
  87494. + */
  87495. + memset(&sc->sc_chnfifo[i][j].cf_desc,
  87496. + 0, sizeof(struct talitos_desc));
  87497. + }
  87498. + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
  87499. + }
  87500. + /* reset and initialize the SEC h/w device */
  87501. + talitos_reset_device(sc);
  87502. + talitos_init_device(sc);
  87503. +#ifdef CONFIG_OCF_RANDOMHARVEST
  87504. + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG)
  87505. + talitos_rng_init(sc);
  87506. +#endif
  87507. +
  87508. + /* Okay. Stand by. */
  87509. + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  87510. +
  87511. + return;
  87512. +}
  87513. +
  87514. +/* go through all channels descriptors, notifying OCF what's been done */
  87515. +static void talitos_doneprocessing(struct talitos_softc *sc)
  87516. +{
  87517. + unsigned long flags;
  87518. + int i, j;
  87519. +
  87520. + /* go through descriptors looking for done bits */
  87521. + for (i = 0; i < sc->sc_num_channels; i++) {
  87522. + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
  87523. + for (j = 0; j < sc->sc_chfifo_len; j++) {
  87524. + /* descriptor has done bits set? */
  87525. + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
  87526. + & TALITOS_HDR_DONE_BITS)
  87527. + == TALITOS_HDR_DONE_BITS) {
  87528. + /* notify ocf */
  87529. + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
  87530. + /* and tag it available again
  87531. + *
  87532. + * memset to ensure correct descriptor formation by
  87533. + * avoiding inadvertently setting "optional" entries
  87534. + * e.g. not using "optional" dptr2 MD/HMAC processing
  87535. + */
  87536. + memset(&sc->sc_chnfifo[i][j].cf_desc,
  87537. + 0, sizeof(struct talitos_desc));
  87538. + }
  87539. + }
  87540. + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
  87541. + }
  87542. + return;
  87543. +}
  87544. +
  87545. +static irqreturn_t
  87546. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  87547. +talitos_intr(int irq, void *arg)
  87548. +#else
  87549. +talitos_intr(int irq, void *arg, struct pt_regs *regs)
  87550. +#endif
  87551. +{
  87552. + struct talitos_softc *sc = arg;
  87553. + u_int32_t v, v_hi;
  87554. +
  87555. + /* ack */
  87556. + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
  87557. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
  87558. + talitos_write(sc->sc_base_addr + TALITOS_ICR, v);
  87559. + talitos_write(sc->sc_base_addr + TALITOS_ICR_HI, v_hi);
  87560. +
  87561. + if (unlikely(v & TALITOS_ISR_ERROR)) {
  87562. + /* Okay, Houston, we've had a problem here. */
  87563. + printk(KERN_DEBUG "%s: got error interrupt - ISR 0x%08x_%08x\n",
  87564. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  87565. + talitos_errorprocessing(sc);
  87566. + } else
  87567. + if (likely(v & TALITOS_ISR_DONE)) {
  87568. + talitos_doneprocessing(sc);
  87569. + }
  87570. + return IRQ_HANDLED;
  87571. +}
  87572. +
  87573. +/*
  87574. + * Initialize registers we need to touch only once.
  87575. + */
  87576. +static void
  87577. +talitos_init_device(struct talitos_softc *sc)
  87578. +{
  87579. + u_int32_t v;
  87580. + int i;
  87581. +
  87582. + DPRINTF("%s()\n", __FUNCTION__);
  87583. +
  87584. + /* init all channels */
  87585. + for (i = 0; i < sc->sc_num_channels; i++) {
  87586. + v = talitos_read(sc->sc_base_addr +
  87587. + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI);
  87588. + v |= TALITOS_CH_CCCR_HI_CDWE
  87589. + | TALITOS_CH_CCCR_HI_CDIE; /* invoke interrupt if done */
  87590. + talitos_write(sc->sc_base_addr +
  87591. + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI, v);
  87592. + }
  87593. + /* enable all interrupts */
  87594. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
  87595. + v |= TALITOS_IMR_ALL;
  87596. + talitos_write(sc->sc_base_addr + TALITOS_IMR, v);
  87597. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
  87598. + v |= TALITOS_IMR_HI_ERRONLY;
  87599. + talitos_write(sc->sc_base_addr + TALITOS_IMR_HI, v);
  87600. + return;
  87601. +}
  87602. +
  87603. +/*
  87604. + * set the master reset bit on the device.
  87605. + */
  87606. +static void
  87607. +talitos_reset_device_master(struct talitos_softc *sc)
  87608. +{
  87609. + u_int32_t v;
  87610. +
  87611. + /* Reset the device by writing 1 to MCR:SWR and waiting 'til cleared */
  87612. + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
  87613. + talitos_write(sc->sc_base_addr + TALITOS_MCR, v | TALITOS_MCR_SWR);
  87614. +
  87615. + while (talitos_read(sc->sc_base_addr + TALITOS_MCR) & TALITOS_MCR_SWR)
  87616. + cpu_relax();
  87617. +
  87618. + return;
  87619. +}
  87620. +
  87621. +/*
  87622. + * Resets the device. Values in the registers are left as is
  87623. + * from the reset (i.e. initial values are assigned elsewhere).
  87624. + */
  87625. +static void
  87626. +talitos_reset_device(struct talitos_softc *sc)
  87627. +{
  87628. + u_int32_t v;
  87629. + int i;
  87630. +
  87631. + DPRINTF("%s()\n", __FUNCTION__);
  87632. +
  87633. + /*
  87634. + * Master reset
  87635. + * errata documentation: warning: certain SEC interrupts
  87636. + * are not fully cleared by writing the MCR:SWR bit,
  87637. + * set bit twice to completely reset
  87638. + */
  87639. + talitos_reset_device_master(sc); /* once */
  87640. + talitos_reset_device_master(sc); /* and once again */
  87641. +
  87642. + /* reset all channels */
  87643. + for (i = 0; i < sc->sc_num_channels; i++) {
  87644. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  87645. + TALITOS_CH_CCCR);
  87646. + talitos_write(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  87647. + TALITOS_CH_CCCR, v | TALITOS_CH_CCCR_RESET);
  87648. + }
  87649. +}
  87650. +
  87651. +/* Set up the crypto device structure, private data,
  87652. + * and anything else we need before we start */
  87653. +#ifdef CONFIG_PPC_MERGE
  87654. +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match)
  87655. +#else
  87656. +static int talitos_probe(struct platform_device *pdev)
  87657. +#endif
  87658. +{
  87659. + struct talitos_softc *sc = NULL;
  87660. + struct resource *r;
  87661. +#ifdef CONFIG_PPC_MERGE
  87662. + struct device *device = &ofdev->dev;
  87663. + struct device_node *np = ofdev->node;
  87664. + const unsigned int *prop;
  87665. + int err;
  87666. + struct resource res;
  87667. +#endif
  87668. + static int num_chips = 0;
  87669. + int rc;
  87670. + int i;
  87671. +
  87672. + DPRINTF("%s()\n", __FUNCTION__);
  87673. +
  87674. + sc = (struct talitos_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  87675. + if (!sc)
  87676. + return -ENOMEM;
  87677. + memset(sc, 0, sizeof(*sc));
  87678. +
  87679. + softc_device_init(sc, DRV_NAME, num_chips, talitos_methods);
  87680. +
  87681. + sc->sc_irq = -1;
  87682. + sc->sc_cid = -1;
  87683. +#ifndef CONFIG_PPC_MERGE
  87684. + sc->sc_dev = pdev;
  87685. +#endif
  87686. + sc->sc_num = num_chips++;
  87687. +
  87688. +#ifdef CONFIG_PPC_MERGE
  87689. + dev_set_drvdata(device, sc);
  87690. +#else
  87691. + platform_set_drvdata(sc->sc_dev, sc);
  87692. +#endif
  87693. +
  87694. + /* get the irq line */
  87695. +#ifdef CONFIG_PPC_MERGE
  87696. + err = of_address_to_resource(np, 0, &res);
  87697. + if (err)
  87698. + return -EINVAL;
  87699. + r = &res;
  87700. +
  87701. + sc->sc_irq = irq_of_parse_and_map(np, 0);
  87702. +#else
  87703. + /* get a pointer to the register memory */
  87704. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  87705. +
  87706. + sc->sc_irq = platform_get_irq(pdev, 0);
  87707. +#endif
  87708. + rc = request_irq(sc->sc_irq, talitos_intr, 0,
  87709. + device_get_nameunit(sc->sc_cdev), sc);
  87710. + if (rc) {
  87711. + printk(KERN_ERR "%s: failed to hook irq %d\n",
  87712. + device_get_nameunit(sc->sc_cdev), sc->sc_irq);
  87713. + sc->sc_irq = -1;
  87714. + goto out;
  87715. + }
  87716. +
  87717. + sc->sc_base_addr = (ocf_iomem_t) ioremap(r->start, (r->end - r->start));
  87718. + if (!sc->sc_base_addr) {
  87719. + printk(KERN_ERR "%s: failed to ioremap\n",
  87720. + device_get_nameunit(sc->sc_cdev));
  87721. + goto out;
  87722. + }
  87723. +
  87724. + /* figure out our SEC's properties and capabilities */
  87725. + sc->sc_chiprev = (u64)talitos_read(sc->sc_base_addr + TALITOS_ID) << 32
  87726. + | talitos_read(sc->sc_base_addr + TALITOS_ID_HI);
  87727. + DPRINTF("sec id 0x%llx\n", sc->sc_chiprev);
  87728. +
  87729. +#ifdef CONFIG_PPC_MERGE
  87730. + /* get SEC properties from device tree, defaulting to SEC 2.0 */
  87731. +
  87732. + prop = of_get_property(np, "num-channels", NULL);
  87733. + sc->sc_num_channels = prop ? *prop : TALITOS_NCHANNELS_SEC_2_0;
  87734. +
  87735. + prop = of_get_property(np, "channel-fifo-len", NULL);
  87736. + sc->sc_chfifo_len = prop ? *prop : TALITOS_CHFIFOLEN_SEC_2_0;
  87737. +
  87738. + prop = of_get_property(np, "exec-units-mask", NULL);
  87739. + sc->sc_exec_units = prop ? *prop : TALITOS_HAS_EUS_SEC_2_0;
  87740. +
  87741. + prop = of_get_property(np, "descriptor-types-mask", NULL);
  87742. + sc->sc_desc_types = prop ? *prop : TALITOS_HAS_DESCTYPES_SEC_2_0;
  87743. +#else
  87744. + /* bulk should go away with openfirmware flat device tree support */
  87745. + if (sc->sc_chiprev & TALITOS_ID_SEC_2_0) {
  87746. + sc->sc_num_channels = TALITOS_NCHANNELS_SEC_2_0;
  87747. + sc->sc_chfifo_len = TALITOS_CHFIFOLEN_SEC_2_0;
  87748. + sc->sc_exec_units = TALITOS_HAS_EUS_SEC_2_0;
  87749. + sc->sc_desc_types = TALITOS_HAS_DESCTYPES_SEC_2_0;
  87750. + } else {
  87751. + printk(KERN_ERR "%s: failed to id device\n",
  87752. + device_get_nameunit(sc->sc_cdev));
  87753. + goto out;
  87754. + }
  87755. +#endif
  87756. +
  87757. + /* + 1 is for the meta-channel lock used by the channel scheduler */
  87758. + sc->sc_chnfifolock = (spinlock_t *) kmalloc(
  87759. + (sc->sc_num_channels + 1) * sizeof(spinlock_t), GFP_KERNEL);
  87760. + if (!sc->sc_chnfifolock)
  87761. + goto out;
  87762. + for (i = 0; i < sc->sc_num_channels + 1; i++) {
  87763. + spin_lock_init(&sc->sc_chnfifolock[i]);
  87764. + }
  87765. +
  87766. + sc->sc_chnlastalg = (int *) kmalloc(
  87767. + sc->sc_num_channels * sizeof(int), GFP_KERNEL);
  87768. + if (!sc->sc_chnlastalg)
  87769. + goto out;
  87770. + memset(sc->sc_chnlastalg, 0, sc->sc_num_channels * sizeof(int));
  87771. +
  87772. + sc->sc_chnfifo = (struct desc_cryptop_pair **) kmalloc(
  87773. + sc->sc_num_channels * sizeof(struct desc_cryptop_pair *),
  87774. + GFP_KERNEL);
  87775. + if (!sc->sc_chnfifo)
  87776. + goto out;
  87777. + for (i = 0; i < sc->sc_num_channels; i++) {
  87778. + sc->sc_chnfifo[i] = (struct desc_cryptop_pair *) kmalloc(
  87779. + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair),
  87780. + GFP_KERNEL);
  87781. + if (!sc->sc_chnfifo[i])
  87782. + goto out;
  87783. + memset(sc->sc_chnfifo[i], 0,
  87784. + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair));
  87785. + }
  87786. +
  87787. + /* reset and initialize the SEC h/w device */
  87788. + talitos_reset_device(sc);
  87789. + talitos_init_device(sc);
  87790. +
  87791. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  87792. + if (sc->sc_cid < 0) {
  87793. + printk(KERN_ERR "%s: could not get crypto driver id\n",
  87794. + device_get_nameunit(sc->sc_cdev));
  87795. + goto out;
  87796. + }
  87797. +
  87798. + /* register algorithms with the framework */
  87799. + printk("%s:", device_get_nameunit(sc->sc_cdev));
  87800. +
  87801. + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG) {
  87802. + printk(" rng");
  87803. +#ifdef CONFIG_OCF_RANDOMHARVEST
  87804. + talitos_rng_init(sc);
  87805. + crypto_rregister(sc->sc_cid, talitos_read_random, sc);
  87806. +#endif
  87807. + }
  87808. + if (sc->sc_exec_units & TALITOS_HAS_EU_DEU) {
  87809. + printk(" des/3des");
  87810. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  87811. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  87812. + }
  87813. + if (sc->sc_exec_units & TALITOS_HAS_EU_AESU) {
  87814. + printk(" aes");
  87815. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  87816. + }
  87817. + if (sc->sc_exec_units & TALITOS_HAS_EU_MDEU) {
  87818. + printk(" md5");
  87819. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  87820. + /* HMAC support only with IPsec for now */
  87821. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  87822. + printk(" sha1");
  87823. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  87824. + /* HMAC support only with IPsec for now */
  87825. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  87826. + }
  87827. + printk("\n");
  87828. + return 0;
  87829. +
  87830. +out:
  87831. +#ifndef CONFIG_PPC_MERGE
  87832. + talitos_remove(pdev);
  87833. +#endif
  87834. + return -ENOMEM;
  87835. +}
  87836. +
  87837. +#ifdef CONFIG_PPC_MERGE
  87838. +static int talitos_remove(struct of_device *ofdev)
  87839. +#else
  87840. +static int talitos_remove(struct platform_device *pdev)
  87841. +#endif
  87842. +{
  87843. +#ifdef CONFIG_PPC_MERGE
  87844. + struct talitos_softc *sc = dev_get_drvdata(&ofdev->dev);
  87845. +#else
  87846. + struct talitos_softc *sc = platform_get_drvdata(pdev);
  87847. +#endif
  87848. + int i;
  87849. +
  87850. + DPRINTF("%s()\n", __FUNCTION__);
  87851. + if (sc->sc_cid >= 0)
  87852. + crypto_unregister_all(sc->sc_cid);
  87853. + if (sc->sc_chnfifo) {
  87854. + for (i = 0; i < sc->sc_num_channels; i++)
  87855. + if (sc->sc_chnfifo[i])
  87856. + kfree(sc->sc_chnfifo[i]);
  87857. + kfree(sc->sc_chnfifo);
  87858. + }
  87859. + if (sc->sc_chnlastalg)
  87860. + kfree(sc->sc_chnlastalg);
  87861. + if (sc->sc_chnfifolock)
  87862. + kfree(sc->sc_chnfifolock);
  87863. + if (sc->sc_irq != -1)
  87864. + free_irq(sc->sc_irq, sc);
  87865. + if (sc->sc_base_addr)
  87866. + iounmap((void *) sc->sc_base_addr);
  87867. + kfree(sc);
  87868. + return 0;
  87869. +}
  87870. +
  87871. +#ifdef CONFIG_PPC_MERGE
  87872. +static struct of_device_id talitos_match[] = {
  87873. + {
  87874. + .type = "crypto",
  87875. + .compatible = "talitos",
  87876. + },
  87877. + {},
  87878. +};
  87879. +
  87880. +MODULE_DEVICE_TABLE(of, talitos_match);
  87881. +
  87882. +static struct of_platform_driver talitos_driver = {
  87883. + .name = DRV_NAME,
  87884. + .match_table = talitos_match,
  87885. + .probe = talitos_probe,
  87886. + .remove = talitos_remove,
  87887. +};
  87888. +
  87889. +static int __init talitos_init(void)
  87890. +{
  87891. + return of_register_platform_driver(&talitos_driver);
  87892. +}
  87893. +
  87894. +static void __exit talitos_exit(void)
  87895. +{
  87896. + of_unregister_platform_driver(&talitos_driver);
  87897. +}
  87898. +#else
  87899. +/* Structure for a platform device driver */
  87900. +static struct platform_driver talitos_driver = {
  87901. + .probe = talitos_probe,
  87902. + .remove = talitos_remove,
  87903. + .driver = {
  87904. + .name = "fsl-sec2",
  87905. + }
  87906. +};
  87907. +
  87908. +static int __init talitos_init(void)
  87909. +{
  87910. + return platform_driver_register(&talitos_driver);
  87911. +}
  87912. +
  87913. +static void __exit talitos_exit(void)
  87914. +{
  87915. + platform_driver_unregister(&talitos_driver);
  87916. +}
  87917. +#endif
  87918. +
  87919. +module_init(talitos_init);
  87920. +module_exit(talitos_exit);
  87921. +
  87922. +MODULE_LICENSE("Dual BSD/GPL");
  87923. +MODULE_AUTHOR("kim.phillips@freescale.com");
  87924. +MODULE_DESCRIPTION("OCF driver for Freescale SEC (talitos)");
  87925. diff -Nur linux-2.6.39.orig/crypto/ocf/talitos/talitos_dev.h linux-2.6.39/crypto/ocf/talitos/talitos_dev.h
  87926. --- linux-2.6.39.orig/crypto/ocf/talitos/talitos_dev.h 1970-01-01 01:00:00.000000000 +0100
  87927. +++ linux-2.6.39/crypto/ocf/talitos/talitos_dev.h 2011-07-31 11:32:03.743425080 +0200
  87928. @@ -0,0 +1,277 @@
  87929. +/*
  87930. + * Freescale SEC (talitos) device dependent data structures
  87931. + *
  87932. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  87933. + *
  87934. + * Redistribution and use in source and binary forms, with or without
  87935. + * modification, are permitted provided that the following conditions
  87936. + * are met:
  87937. + *
  87938. + * 1. Redistributions of source code must retain the above copyright
  87939. + * notice, this list of conditions and the following disclaimer.
  87940. + * 2. Redistributions in binary form must reproduce the above copyright
  87941. + * notice, this list of conditions and the following disclaimer in the
  87942. + * documentation and/or other materials provided with the distribution.
  87943. + * 3. The name of the author may not be used to endorse or promote products
  87944. + * derived from this software without specific prior written permission.
  87945. + *
  87946. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  87947. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  87948. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  87949. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  87950. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  87951. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  87952. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  87953. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  87954. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  87955. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  87956. + *
  87957. + */
  87958. +
  87959. +/* device ID register values */
  87960. +#define TALITOS_ID_SEC_2_0 0x40
  87961. +#define TALITOS_ID_SEC_2_1 0x40 /* cross ref with IP block revision reg */
  87962. +
  87963. +/*
  87964. + * following num_channels, channel-fifo-depth, exec-unit-mask, and
  87965. + * descriptor-types-mask are for forward-compatibility with openfirmware
  87966. + * flat device trees
  87967. + */
  87968. +
  87969. +/*
  87970. + * num_channels : the number of channels available in each SEC version.
  87971. + */
  87972. +
  87973. +/* n.b. this driver requires these values be a power of 2 */
  87974. +#define TALITOS_NCHANNELS_SEC_1_0 4
  87975. +#define TALITOS_NCHANNELS_SEC_1_2 1
  87976. +#define TALITOS_NCHANNELS_SEC_2_0 4
  87977. +#define TALITOS_NCHANNELS_SEC_2_01 4
  87978. +#define TALITOS_NCHANNELS_SEC_2_1 4
  87979. +#define TALITOS_NCHANNELS_SEC_2_4 4
  87980. +
  87981. +/*
  87982. + * channel-fifo-depth : The number of descriptor
  87983. + * pointers a channel fetch fifo can hold.
  87984. + */
  87985. +#define TALITOS_CHFIFOLEN_SEC_1_0 1
  87986. +#define TALITOS_CHFIFOLEN_SEC_1_2 1
  87987. +#define TALITOS_CHFIFOLEN_SEC_2_0 24
  87988. +#define TALITOS_CHFIFOLEN_SEC_2_01 24
  87989. +#define TALITOS_CHFIFOLEN_SEC_2_1 24
  87990. +#define TALITOS_CHFIFOLEN_SEC_2_4 24
  87991. +
  87992. +/*
  87993. + * exec-unit-mask : The bitmask representing what Execution Units (EUs)
  87994. + * are available. EU information should be encoded following the SEC's
  87995. + * EU_SEL0 bitfield documentation, i.e. as follows:
  87996. + *
  87997. + * bit 31 = set if SEC permits no-EU selection (should be always set)
  87998. + * bit 30 = set if SEC has the ARC4 EU (AFEU)
  87999. + * bit 29 = set if SEC has the des/3des EU (DEU)
  88000. + * bit 28 = set if SEC has the message digest EU (MDEU)
  88001. + * bit 27 = set if SEC has the random number generator EU (RNG)
  88002. + * bit 26 = set if SEC has the public key EU (PKEU)
  88003. + * bit 25 = set if SEC has the aes EU (AESU)
  88004. + * bit 24 = set if SEC has the Kasumi EU (KEU)
  88005. + *
  88006. + */
  88007. +#define TALITOS_HAS_EU_NONE (1<<0)
  88008. +#define TALITOS_HAS_EU_AFEU (1<<1)
  88009. +#define TALITOS_HAS_EU_DEU (1<<2)
  88010. +#define TALITOS_HAS_EU_MDEU (1<<3)
  88011. +#define TALITOS_HAS_EU_RNG (1<<4)
  88012. +#define TALITOS_HAS_EU_PKEU (1<<5)
  88013. +#define TALITOS_HAS_EU_AESU (1<<6)
  88014. +#define TALITOS_HAS_EU_KEU (1<<7)
  88015. +
  88016. +/* the corresponding masks for each SEC version */
  88017. +#define TALITOS_HAS_EUS_SEC_1_0 0x7f
  88018. +#define TALITOS_HAS_EUS_SEC_1_2 0x4d
  88019. +#define TALITOS_HAS_EUS_SEC_2_0 0x7f
  88020. +#define TALITOS_HAS_EUS_SEC_2_01 0x7f
  88021. +#define TALITOS_HAS_EUS_SEC_2_1 0xff
  88022. +#define TALITOS_HAS_EUS_SEC_2_4 0x7f
  88023. +
  88024. +/*
  88025. + * descriptor-types-mask : The bitmask representing what descriptors
  88026. + * are available. Descriptor type information should be encoded
  88027. + * following the SEC's Descriptor Header Dword DESC_TYPE field
  88028. + * documentation, i.e. as follows:
  88029. + *
  88030. + * bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type
  88031. + * bit 1 = set if SEC supports the ipsec_esp descriptor type
  88032. + * bit 2 = set if SEC supports the common_nonsnoop desc. type
  88033. + * bit 3 = set if SEC supports the 802.11i AES ccmp desc. type
  88034. + * bit 4 = set if SEC supports the hmac_snoop_no_afeu desc. type
  88035. + * bit 5 = set if SEC supports the srtp descriptor type
  88036. + * bit 6 = set if SEC supports the non_hmac_snoop_no_afeu desc.type
  88037. + * bit 7 = set if SEC supports the pkeu_assemble descriptor type
  88038. + * bit 8 = set if SEC supports the aesu_key_expand_output desc.type
  88039. + * bit 9 = set if SEC supports the pkeu_ptmul descriptor type
  88040. + * bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type
  88041. + * bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type
  88042. + *
  88043. + * ..and so on and so forth.
  88044. + */
  88045. +#define TALITOS_HAS_DT_AESU_CTR_NONSNOOP (1<<0)
  88046. +#define TALITOS_HAS_DT_IPSEC_ESP (1<<1)
  88047. +#define TALITOS_HAS_DT_COMMON_NONSNOOP (1<<2)
  88048. +
  88049. +/* the corresponding masks for each SEC version */
  88050. +#define TALITOS_HAS_DESCTYPES_SEC_2_0 0x01010ebf
  88051. +#define TALITOS_HAS_DESCTYPES_SEC_2_1 0x012b0ebf
  88052. +
  88053. +/*
  88054. + * a TALITOS_xxx_HI address points to the low data bits (32-63) of the register
  88055. + */
  88056. +
  88057. +/* global register offset addresses */
  88058. +#define TALITOS_ID 0x1020
  88059. +#define TALITOS_ID_HI 0x1024
  88060. +#define TALITOS_MCR 0x1030 /* master control register */
  88061. +#define TALITOS_MCR_HI 0x1038 /* master control register */
  88062. +#define TALITOS_MCR_SWR 0x1
  88063. +#define TALITOS_IMR 0x1008 /* interrupt mask register */
  88064. +#define TALITOS_IMR_ALL 0x00010fff /* enable all interrupts mask */
  88065. +#define TALITOS_IMR_ERRONLY 0x00010aaa /* enable error interrupts */
  88066. +#define TALITOS_IMR_HI 0x100C /* interrupt mask register */
  88067. +#define TALITOS_IMR_HI_ALL 0x00323333 /* enable all interrupts mask */
  88068. +#define TALITOS_IMR_HI_ERRONLY 0x00222222 /* enable error interrupts */
  88069. +#define TALITOS_ISR 0x1010 /* interrupt status register */
  88070. +#define TALITOS_ISR_ERROR 0x00010faa /* errors mask */
  88071. +#define TALITOS_ISR_DONE 0x00000055 /* channel(s) done mask */
  88072. +#define TALITOS_ISR_HI 0x1014 /* interrupt status register */
  88073. +#define TALITOS_ICR 0x1018 /* interrupt clear register */
  88074. +#define TALITOS_ICR_HI 0x101C /* interrupt clear register */
  88075. +
  88076. +/* channel register address stride */
  88077. +#define TALITOS_CH_OFFSET 0x100
  88078. +
  88079. +/* channel register offset addresses and bits */
  88080. +#define TALITOS_CH_CCCR 0x1108 /* Crypto-Channel Config Register */
  88081. +#define TALITOS_CH_CCCR_RESET 0x1 /* Channel Reset bit */
  88082. +#define TALITOS_CH_CCCR_HI 0x110c /* Crypto-Channel Config Register */
  88083. +#define TALITOS_CH_CCCR_HI_CDWE 0x10 /* Channel done writeback enable bit */
  88084. +#define TALITOS_CH_CCCR_HI_NT 0x4 /* Notification type bit */
  88085. +#define TALITOS_CH_CCCR_HI_CDIE 0x2 /* Channel Done Interrupt Enable bit */
  88086. +#define TALITOS_CH_CCPSR 0x1110 /* Crypto-Channel Pointer Status Reg */
  88087. +#define TALITOS_CH_CCPSR_HI 0x1114 /* Crypto-Channel Pointer Status Reg */
  88088. +#define TALITOS_CH_FF 0x1148 /* Fetch FIFO */
  88089. +#define TALITOS_CH_FF_HI 0x114c /* Fetch FIFO's FETCH_ADRS */
  88090. +#define TALITOS_CH_CDPR 0x1140 /* Crypto-Channel Pointer Status Reg */
  88091. +#define TALITOS_CH_CDPR_HI 0x1144 /* Crypto-Channel Pointer Status Reg */
  88092. +#define TALITOS_CH_DESCBUF 0x1180 /* (thru 11bf) Crypto-Channel
  88093. + * Descriptor Buffer (debug) */
  88094. +
  88095. +/* execution unit register offset addresses and bits */
  88096. +#define TALITOS_DEUSR 0x2028 /* DEU status register */
  88097. +#define TALITOS_DEUSR_HI 0x202c /* DEU status register */
  88098. +#define TALITOS_DEUISR 0x2030 /* DEU interrupt status register */
  88099. +#define TALITOS_DEUISR_HI 0x2034 /* DEU interrupt status register */
  88100. +#define TALITOS_DEUICR 0x2038 /* DEU interrupt control register */
  88101. +#define TALITOS_DEUICR_HI 0x203c /* DEU interrupt control register */
  88102. +#define TALITOS_AESUISR 0x4030 /* AESU interrupt status register */
  88103. +#define TALITOS_AESUISR_HI 0x4034 /* AESU interrupt status register */
  88104. +#define TALITOS_AESUICR 0x4038 /* AESU interrupt control register */
  88105. +#define TALITOS_AESUICR_HI 0x403c /* AESU interrupt control register */
  88106. +#define TALITOS_MDEUISR 0x6030 /* MDEU interrupt status register */
  88107. +#define TALITOS_MDEUISR_HI 0x6034 /* MDEU interrupt status register */
  88108. +#define TALITOS_RNGSR 0xa028 /* RNG status register */
  88109. +#define TALITOS_RNGSR_HI 0xa02c /* RNG status register */
  88110. +#define TALITOS_RNGSR_HI_RD 0x1 /* RNG Reset done */
  88111. +#define TALITOS_RNGSR_HI_OFL 0xff0000/* number of dwords in RNG output FIFO*/
  88112. +#define TALITOS_RNGDSR 0xa010 /* RNG data size register */
  88113. +#define TALITOS_RNGDSR_HI 0xa014 /* RNG data size register */
  88114. +#define TALITOS_RNG_FIFO 0xa800 /* RNG FIFO - pool of random numbers */
  88115. +#define TALITOS_RNGISR 0xa030 /* RNG Interrupt status register */
  88116. +#define TALITOS_RNGISR_HI 0xa034 /* RNG Interrupt status register */
  88117. +#define TALITOS_RNGRCR 0xa018 /* RNG Reset control register */
  88118. +#define TALITOS_RNGRCR_HI 0xa01c /* RNG Reset control register */
  88119. +#define TALITOS_RNGRCR_HI_SR 0x1 /* RNG RNGRCR:Software Reset */
  88120. +
  88121. +/* descriptor pointer entry */
  88122. +struct talitos_desc_ptr {
  88123. + u16 len; /* length */
  88124. + u8 extent; /* jump (to s/g link table) and extent */
  88125. + u8 res; /* reserved */
  88126. + u32 ptr; /* pointer */
  88127. +};
  88128. +
  88129. +/* descriptor */
  88130. +struct talitos_desc {
  88131. + u32 hdr; /* header */
  88132. + u32 res; /* reserved */
  88133. + struct talitos_desc_ptr ptr[7]; /* ptr/len pair array */
  88134. +};
  88135. +
  88136. +/* talitos descriptor header (hdr) bits */
  88137. +
  88138. +/* primary execution unit select */
  88139. +#define TALITOS_SEL0_AFEU 0x10000000
  88140. +#define TALITOS_SEL0_DEU 0x20000000
  88141. +#define TALITOS_SEL0_MDEU 0x30000000
  88142. +#define TALITOS_SEL0_RNG 0x40000000
  88143. +#define TALITOS_SEL0_PKEU 0x50000000
  88144. +#define TALITOS_SEL0_AESU 0x60000000
  88145. +
  88146. +/* primary execution unit mode (MODE0) and derivatives */
  88147. +#define TALITOS_MODE0_AESU_CBC 0x00200000
  88148. +#define TALITOS_MODE0_AESU_ENC 0x00100000
  88149. +#define TALITOS_MODE0_DEU_CBC 0x00400000
  88150. +#define TALITOS_MODE0_DEU_3DES 0x00200000
  88151. +#define TALITOS_MODE0_DEU_ENC 0x00100000
  88152. +#define TALITOS_MODE0_MDEU_INIT 0x01000000 /* init starting regs */
  88153. +#define TALITOS_MODE0_MDEU_HMAC 0x00800000
  88154. +#define TALITOS_MODE0_MDEU_PAD 0x00400000 /* PD */
  88155. +#define TALITOS_MODE0_MDEU_MD5 0x00200000
  88156. +#define TALITOS_MODE0_MDEU_SHA256 0x00100000
  88157. +#define TALITOS_MODE0_MDEU_SHA1 0x00000000 /* SHA-160 */
  88158. +#define TALITOS_MODE0_MDEU_MD5_HMAC \
  88159. + (TALITOS_MODE0_MDEU_MD5 | TALITOS_MODE0_MDEU_HMAC)
  88160. +#define TALITOS_MODE0_MDEU_SHA256_HMAC \
  88161. + (TALITOS_MODE0_MDEU_SHA256 | TALITOS_MODE0_MDEU_HMAC)
  88162. +#define TALITOS_MODE0_MDEU_SHA1_HMAC \
  88163. + (TALITOS_MODE0_MDEU_SHA1 | TALITOS_MODE0_MDEU_HMAC)
  88164. +
  88165. +/* secondary execution unit select (SEL1) */
  88166. +/* it's MDEU or nothing */
  88167. +#define TALITOS_SEL1_MDEU 0x00030000
  88168. +
  88169. +/* secondary execution unit mode (MODE1) and derivatives */
  88170. +#define TALITOS_MODE1_MDEU_INIT 0x00001000 /* init starting regs */
  88171. +#define TALITOS_MODE1_MDEU_HMAC 0x00000800
  88172. +#define TALITOS_MODE1_MDEU_PAD 0x00000400 /* PD */
  88173. +#define TALITOS_MODE1_MDEU_MD5 0x00000200
  88174. +#define TALITOS_MODE1_MDEU_SHA256 0x00000100
  88175. +#define TALITOS_MODE1_MDEU_SHA1 0x00000000 /* SHA-160 */
  88176. +#define TALITOS_MODE1_MDEU_MD5_HMAC \
  88177. + (TALITOS_MODE1_MDEU_MD5 | TALITOS_MODE1_MDEU_HMAC)
  88178. +#define TALITOS_MODE1_MDEU_SHA256_HMAC \
  88179. + (TALITOS_MODE1_MDEU_SHA256 | TALITOS_MODE1_MDEU_HMAC)
  88180. +#define TALITOS_MODE1_MDEU_SHA1_HMAC \
  88181. + (TALITOS_MODE1_MDEU_SHA1 | TALITOS_MODE1_MDEU_HMAC)
  88182. +
  88183. +/* direction of overall data flow (DIR) */
  88184. +#define TALITOS_DIR_OUTBOUND 0x00000000
  88185. +#define TALITOS_DIR_INBOUND 0x00000002
  88186. +
  88187. +/* done notification (DN) */
  88188. +#define TALITOS_DONE_NOTIFY 0x00000001
  88189. +
  88190. +/* descriptor types */
  88191. +/* odd numbers here are valid on SEC2 and greater only (e.g. ipsec_esp) */
  88192. +#define TD_TYPE_AESU_CTR_NONSNOOP (0 << 3)
  88193. +#define TD_TYPE_IPSEC_ESP (1 << 3)
  88194. +#define TD_TYPE_COMMON_NONSNOOP_NO_AFEU (2 << 3)
  88195. +#define TD_TYPE_HMAC_SNOOP_NO_AFEU (4 << 3)
  88196. +
  88197. +#define TALITOS_HDR_DONE_BITS 0xff000000
  88198. +
  88199. +#define DPRINTF(a...) do { \
  88200. + if (debug) { \
  88201. + printk("%s: ", sc ? \
  88202. + device_get_nameunit(sc->sc_cdev) : "talitos"); \
  88203. + printk(a); \
  88204. + } \
  88205. + } while (0)
  88206. diff -Nur linux-2.6.39.orig/crypto/ocf/talitos/talitos_soft.h linux-2.6.39/crypto/ocf/talitos/talitos_soft.h
  88207. --- linux-2.6.39.orig/crypto/ocf/talitos/talitos_soft.h 1970-01-01 01:00:00.000000000 +0100
  88208. +++ linux-2.6.39/crypto/ocf/talitos/talitos_soft.h 2011-07-31 11:32:03.783415616 +0200
  88209. @@ -0,0 +1,77 @@
  88210. +/*
  88211. + * Freescale SEC data structures for integration with ocf-linux
  88212. + *
  88213. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  88214. + *
  88215. + * Redistribution and use in source and binary forms, with or without
  88216. + * modification, are permitted provided that the following conditions
  88217. + * are met:
  88218. + *
  88219. + * 1. Redistributions of source code must retain the above copyright
  88220. + * notice, this list of conditions and the following disclaimer.
  88221. + * 2. Redistributions in binary form must reproduce the above copyright
  88222. + * notice, this list of conditions and the following disclaimer in the
  88223. + * documentation and/or other materials provided with the distribution.
  88224. + * 3. The name of the author may not be used to endorse or promote products
  88225. + * derived from this software without specific prior written permission.
  88226. + *
  88227. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  88228. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  88229. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  88230. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  88231. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  88232. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  88233. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  88234. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  88235. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  88236. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  88237. + */
  88238. +
  88239. +/*
  88240. + * paired descriptor and associated crypto operation
  88241. + */
  88242. +struct desc_cryptop_pair {
  88243. + struct talitos_desc cf_desc; /* descriptor ptr */
  88244. + struct cryptop *cf_crp; /* cryptop ptr */
  88245. +};
  88246. +
  88247. +/*
  88248. + * Holds data specific to a single talitos device.
  88249. + */
  88250. +struct talitos_softc {
  88251. + softc_device_decl sc_cdev;
  88252. + struct platform_device *sc_dev; /* device backpointer */
  88253. + ocf_iomem_t sc_base_addr;
  88254. + int sc_irq;
  88255. + int sc_num; /* if we have multiple chips */
  88256. + int32_t sc_cid; /* crypto tag */
  88257. + u64 sc_chiprev; /* major/minor chip revision */
  88258. + int sc_nsessions;
  88259. + struct talitos_session *sc_sessions;
  88260. + int sc_num_channels;/* number of crypto channels */
  88261. + int sc_chfifo_len; /* channel fetch fifo len */
  88262. + int sc_exec_units; /* execution units mask */
  88263. + int sc_desc_types; /* descriptor types mask */
  88264. + /*
  88265. + * mutual exclusion for intra-channel resources, e.g. fetch fifos
  88266. + * the last entry is a meta-channel lock used by the channel scheduler
  88267. + */
  88268. + spinlock_t *sc_chnfifolock;
  88269. + /* sc_chnlastalgo contains last algorithm for that channel */
  88270. + int *sc_chnlastalg;
  88271. + /* sc_chnfifo holds pending descriptor--crypto operation pairs */
  88272. + struct desc_cryptop_pair **sc_chnfifo;
  88273. +};
  88274. +
  88275. +struct talitos_session {
  88276. + u_int32_t ses_used;
  88277. + u_int32_t ses_klen; /* key length in bits */
  88278. + u_int32_t ses_key[8]; /* DES/3DES/AES key */
  88279. + u_int32_t ses_hmac[5]; /* hmac inner state */
  88280. + u_int32_t ses_hmac_len; /* hmac length */
  88281. + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
  88282. + u_int32_t ses_mlen; /* desired hash result len (12=ipsec or 16) */
  88283. +};
  88284. +
  88285. +#define TALITOS_SESSION(sid) ((sid) & 0x0fffffff)
  88286. +#define TALITOS_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
  88287. diff -Nur linux-2.6.39.orig/crypto/ocf/uio.h linux-2.6.39/crypto/ocf/uio.h
  88288. --- linux-2.6.39.orig/crypto/ocf/uio.h 1970-01-01 01:00:00.000000000 +0100
  88289. +++ linux-2.6.39/crypto/ocf/uio.h 2011-07-31 11:32:03.813424426 +0200
  88290. @@ -0,0 +1,54 @@
  88291. +#ifndef _OCF_UIO_H_
  88292. +#define _OCF_UIO_H_
  88293. +
  88294. +#include <linux/uio.h>
  88295. +
  88296. +/*
  88297. + * The linux uio.h doesn't have all we need. To be fully api compatible
  88298. + * with the BSD cryptodev, we need to keep this around. Perhaps this can
  88299. + * be moved back into the linux/uio.h
  88300. + *
  88301. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  88302. + * Copyright (C) 2006-2010 David McCullough
  88303. + * Copyright (C) 2004-2005 Intel Corporation.
  88304. + *
  88305. + * LICENSE TERMS
  88306. + *
  88307. + * The free distribution and use of this software in both source and binary
  88308. + * form is allowed (with or without changes) provided that:
  88309. + *
  88310. + * 1. distributions of this source code include the above copyright
  88311. + * notice, this list of conditions and the following disclaimer;
  88312. + *
  88313. + * 2. distributions in binary form include the above copyright
  88314. + * notice, this list of conditions and the following disclaimer
  88315. + * in the documentation and/or other associated materials;
  88316. + *
  88317. + * 3. the copyright holder's name is not used to endorse products
  88318. + * built using this software without specific written permission.
  88319. + *
  88320. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  88321. + * may be distributed under the terms of the GNU General Public License (GPL),
  88322. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  88323. + *
  88324. + * DISCLAIMER
  88325. + *
  88326. + * This software is provided 'as is' with no explicit or implied warranties
  88327. + * in respect of its properties, including, but not limited to, correctness
  88328. + * and/or fitness for purpose.
  88329. + * ---------------------------------------------------------------------------
  88330. + */
  88331. +
  88332. +struct uio {
  88333. + struct iovec *uio_iov;
  88334. + int uio_iovcnt;
  88335. + off_t uio_offset;
  88336. + int uio_resid;
  88337. +#if 0
  88338. + enum uio_seg uio_segflg;
  88339. + enum uio_rw uio_rw;
  88340. + struct thread *uio_td;
  88341. +#endif
  88342. +};
  88343. +
  88344. +#endif
  88345. diff -Nur linux-2.6.39.orig/drivers/char/random.c linux-2.6.39/drivers/char/random.c
  88346. --- linux-2.6.39.orig/drivers/char/random.c 2011-05-19 06:06:34.000000000 +0200
  88347. +++ linux-2.6.39/drivers/char/random.c 2011-07-31 11:32:03.873423431 +0200
  88348. @@ -130,6 +130,9 @@
  88349. * void add_interrupt_randomness(int irq);
  88350. * void add_disk_randomness(struct gendisk *disk);
  88351. *
  88352. + * void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
  88353. + * int random_input_wait(void);
  88354. + *
  88355. * add_input_randomness() uses the input layer interrupt timing, as well as
  88356. * the event type information from the hardware.
  88357. *
  88358. @@ -147,6 +150,13 @@
  88359. * seek times do not make for good sources of entropy, as their seek
  88360. * times are usually fairly consistent.
  88361. *
  88362. + * random_input_words() just provides a raw block of entropy to the input
  88363. + * pool, such as from a hardware entropy generator.
  88364. + *
  88365. + * random_input_wait() suspends the caller until such time as the
  88366. + * entropy pool falls below the write threshold, and returns a count of how
  88367. + * much entropy (in bits) is needed to sustain the pool.
  88368. + *
  88369. * All of these routines try to estimate how many bits of randomness a
  88370. * particular randomness source. They do this by keeping track of the
  88371. * first and second order deltas of the event timings.
  88372. @@ -266,6 +276,7 @@
  88373. #define SEC_XFER_SIZE 512
  88374. #define EXTRACT_SIZE 10
  88375. +
  88376. /*
  88377. * The minimum number of bits of entropy before we wake up a read on
  88378. * /dev/random. Should be enough to do a significant reseed.
  88379. @@ -559,6 +570,60 @@
  88380. spin_unlock_irqrestore(&r->lock, flags);
  88381. }
  88382. +/*
  88383. + * random_input_words - add bulk entropy to pool
  88384. + *
  88385. + * @buf: buffer to add
  88386. + * @wordcount: number of __u32 words to add
  88387. + * @ent_count: total amount of entropy (in bits) to credit
  88388. + *
  88389. + * this provides bulk input of entropy to the input pool
  88390. + *
  88391. + */
  88392. +void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
  88393. +{
  88394. + mix_pool_bytes(&input_pool, buf, wordcount*4);
  88395. +
  88396. + credit_entropy_bits(&input_pool, ent_count);
  88397. +
  88398. + DEBUG_ENT("crediting %d bits => %d\n",
  88399. + ent_count, input_pool.entropy_count);
  88400. + /*
  88401. + * Wake up waiting processes if we have enough
  88402. + * entropy.
  88403. + */
  88404. + if (input_pool.entropy_count >= random_read_wakeup_thresh)
  88405. + wake_up_interruptible(&random_read_wait);
  88406. +}
  88407. +EXPORT_SYMBOL(random_input_words);
  88408. +
  88409. +/*
  88410. + * random_input_wait - wait until random needs entropy
  88411. + *
  88412. + * this function sleeps until the /dev/random subsystem actually
  88413. + * needs more entropy, and then return the amount of entropy
  88414. + * that it would be nice to have added to the system.
  88415. + */
  88416. +int random_input_wait(void)
  88417. +{
  88418. + int count;
  88419. +
  88420. + wait_event_interruptible(random_write_wait,
  88421. + input_pool.entropy_count < random_write_wakeup_thresh);
  88422. +
  88423. + count = random_write_wakeup_thresh - input_pool.entropy_count;
  88424. +
  88425. + /* likely we got woken up due to a signal */
  88426. + if (count <= 0) count = random_read_wakeup_thresh;
  88427. +
  88428. + DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
  88429. + count,
  88430. + input_pool.entropy_count, random_write_wakeup_thresh);
  88431. +
  88432. + return count;
  88433. +}
  88434. +EXPORT_SYMBOL(random_input_wait);
  88435. +
  88436. /*********************************************************************
  88437. *
  88438. * Entropy input management
  88439. diff -Nur linux-2.6.39.orig/drivers/char/random.c.orig linux-2.6.39/drivers/char/random.c.orig
  88440. --- linux-2.6.39.orig/drivers/char/random.c.orig 1970-01-01 01:00:00.000000000 +0100
  88441. +++ linux-2.6.39/drivers/char/random.c.orig 2011-05-19 06:06:34.000000000 +0200
  88442. @@ -0,0 +1,1667 @@
  88443. +/*
  88444. + * random.c -- A strong random number generator
  88445. + *
  88446. + * Copyright Matt Mackall <mpm@selenic.com>, 2003, 2004, 2005
  88447. + *
  88448. + * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All
  88449. + * rights reserved.
  88450. + *
  88451. + * Redistribution and use in source and binary forms, with or without
  88452. + * modification, are permitted provided that the following conditions
  88453. + * are met:
  88454. + * 1. Redistributions of source code must retain the above copyright
  88455. + * notice, and the entire permission notice in its entirety,
  88456. + * including the disclaimer of warranties.
  88457. + * 2. Redistributions in binary form must reproduce the above copyright
  88458. + * notice, this list of conditions and the following disclaimer in the
  88459. + * documentation and/or other materials provided with the distribution.
  88460. + * 3. The name of the author may not be used to endorse or promote
  88461. + * products derived from this software without specific prior
  88462. + * written permission.
  88463. + *
  88464. + * ALTERNATIVELY, this product may be distributed under the terms of
  88465. + * the GNU General Public License, in which case the provisions of the GPL are
  88466. + * required INSTEAD OF the above restrictions. (This clause is
  88467. + * necessary due to a potential bad interaction between the GPL and
  88468. + * the restrictions contained in a BSD-style copyright.)
  88469. + *
  88470. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  88471. + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  88472. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
  88473. + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
  88474. + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  88475. + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  88476. + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  88477. + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  88478. + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  88479. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  88480. + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
  88481. + * DAMAGE.
  88482. + */
  88483. +
  88484. +/*
  88485. + * (now, with legal B.S. out of the way.....)
  88486. + *
  88487. + * This routine gathers environmental noise from device drivers, etc.,
  88488. + * and returns good random numbers, suitable for cryptographic use.
  88489. + * Besides the obvious cryptographic uses, these numbers are also good
  88490. + * for seeding TCP sequence numbers, and other places where it is
  88491. + * desirable to have numbers which are not only random, but hard to
  88492. + * predict by an attacker.
  88493. + *
  88494. + * Theory of operation
  88495. + * ===================
  88496. + *
  88497. + * Computers are very predictable devices. Hence it is extremely hard
  88498. + * to produce truly random numbers on a computer --- as opposed to
  88499. + * pseudo-random numbers, which can easily generated by using a
  88500. + * algorithm. Unfortunately, it is very easy for attackers to guess
  88501. + * the sequence of pseudo-random number generators, and for some
  88502. + * applications this is not acceptable. So instead, we must try to
  88503. + * gather "environmental noise" from the computer's environment, which
  88504. + * must be hard for outside attackers to observe, and use that to
  88505. + * generate random numbers. In a Unix environment, this is best done
  88506. + * from inside the kernel.
  88507. + *
  88508. + * Sources of randomness from the environment include inter-keyboard
  88509. + * timings, inter-interrupt timings from some interrupts, and other
  88510. + * events which are both (a) non-deterministic and (b) hard for an
  88511. + * outside observer to measure. Randomness from these sources are
  88512. + * added to an "entropy pool", which is mixed using a CRC-like function.
  88513. + * This is not cryptographically strong, but it is adequate assuming
  88514. + * the randomness is not chosen maliciously, and it is fast enough that
  88515. + * the overhead of doing it on every interrupt is very reasonable.
  88516. + * As random bytes are mixed into the entropy pool, the routines keep
  88517. + * an *estimate* of how many bits of randomness have been stored into
  88518. + * the random number generator's internal state.
  88519. + *
  88520. + * When random bytes are desired, they are obtained by taking the SHA
  88521. + * hash of the contents of the "entropy pool". The SHA hash avoids
  88522. + * exposing the internal state of the entropy pool. It is believed to
  88523. + * be computationally infeasible to derive any useful information
  88524. + * about the input of SHA from its output. Even if it is possible to
  88525. + * analyze SHA in some clever way, as long as the amount of data
  88526. + * returned from the generator is less than the inherent entropy in
  88527. + * the pool, the output data is totally unpredictable. For this
  88528. + * reason, the routine decreases its internal estimate of how many
  88529. + * bits of "true randomness" are contained in the entropy pool as it
  88530. + * outputs random numbers.
  88531. + *
  88532. + * If this estimate goes to zero, the routine can still generate
  88533. + * random numbers; however, an attacker may (at least in theory) be
  88534. + * able to infer the future output of the generator from prior
  88535. + * outputs. This requires successful cryptanalysis of SHA, which is
  88536. + * not believed to be feasible, but there is a remote possibility.
  88537. + * Nonetheless, these numbers should be useful for the vast majority
  88538. + * of purposes.
  88539. + *
  88540. + * Exported interfaces ---- output
  88541. + * ===============================
  88542. + *
  88543. + * There are three exported interfaces; the first is one designed to
  88544. + * be used from within the kernel:
  88545. + *
  88546. + * void get_random_bytes(void *buf, int nbytes);
  88547. + *
  88548. + * This interface will return the requested number of random bytes,
  88549. + * and place it in the requested buffer.
  88550. + *
  88551. + * The two other interfaces are two character devices /dev/random and
  88552. + * /dev/urandom. /dev/random is suitable for use when very high
  88553. + * quality randomness is desired (for example, for key generation or
  88554. + * one-time pads), as it will only return a maximum of the number of
  88555. + * bits of randomness (as estimated by the random number generator)
  88556. + * contained in the entropy pool.
  88557. + *
  88558. + * The /dev/urandom device does not have this limit, and will return
  88559. + * as many bytes as are requested. As more and more random bytes are
  88560. + * requested without giving time for the entropy pool to recharge,
  88561. + * this will result in random numbers that are merely cryptographically
  88562. + * strong. For many applications, however, this is acceptable.
  88563. + *
  88564. + * Exported interfaces ---- input
  88565. + * ==============================
  88566. + *
  88567. + * The current exported interfaces for gathering environmental noise
  88568. + * from the devices are:
  88569. + *
  88570. + * void add_input_randomness(unsigned int type, unsigned int code,
  88571. + * unsigned int value);
  88572. + * void add_interrupt_randomness(int irq);
  88573. + * void add_disk_randomness(struct gendisk *disk);
  88574. + *
  88575. + * add_input_randomness() uses the input layer interrupt timing, as well as
  88576. + * the event type information from the hardware.
  88577. + *
  88578. + * add_interrupt_randomness() uses the inter-interrupt timing as random
  88579. + * inputs to the entropy pool. Note that not all interrupts are good
  88580. + * sources of randomness! For example, the timer interrupts is not a
  88581. + * good choice, because the periodicity of the interrupts is too
  88582. + * regular, and hence predictable to an attacker. Network Interface
  88583. + * Controller interrupts are a better measure, since the timing of the
  88584. + * NIC interrupts are more unpredictable.
  88585. + *
  88586. + * add_disk_randomness() uses what amounts to the seek time of block
  88587. + * layer request events, on a per-disk_devt basis, as input to the
  88588. + * entropy pool. Note that high-speed solid state drives with very low
  88589. + * seek times do not make for good sources of entropy, as their seek
  88590. + * times are usually fairly consistent.
  88591. + *
  88592. + * All of these routines try to estimate how many bits of randomness a
  88593. + * particular randomness source. They do this by keeping track of the
  88594. + * first and second order deltas of the event timings.
  88595. + *
  88596. + * Ensuring unpredictability at system startup
  88597. + * ============================================
  88598. + *
  88599. + * When any operating system starts up, it will go through a sequence
  88600. + * of actions that are fairly predictable by an adversary, especially
  88601. + * if the start-up does not involve interaction with a human operator.
  88602. + * This reduces the actual number of bits of unpredictability in the
  88603. + * entropy pool below the value in entropy_count. In order to
  88604. + * counteract this effect, it helps to carry information in the
  88605. + * entropy pool across shut-downs and start-ups. To do this, put the
  88606. + * following lines an appropriate script which is run during the boot
  88607. + * sequence:
  88608. + *
  88609. + * echo "Initializing random number generator..."
  88610. + * random_seed=/var/run/random-seed
  88611. + * # Carry a random seed from start-up to start-up
  88612. + * # Load and then save the whole entropy pool
  88613. + * if [ -f $random_seed ]; then
  88614. + * cat $random_seed >/dev/urandom
  88615. + * else
  88616. + * touch $random_seed
  88617. + * fi
  88618. + * chmod 600 $random_seed
  88619. + * dd if=/dev/urandom of=$random_seed count=1 bs=512
  88620. + *
  88621. + * and the following lines in an appropriate script which is run as
  88622. + * the system is shutdown:
  88623. + *
  88624. + * # Carry a random seed from shut-down to start-up
  88625. + * # Save the whole entropy pool
  88626. + * echo "Saving random seed..."
  88627. + * random_seed=/var/run/random-seed
  88628. + * touch $random_seed
  88629. + * chmod 600 $random_seed
  88630. + * dd if=/dev/urandom of=$random_seed count=1 bs=512
  88631. + *
  88632. + * For example, on most modern systems using the System V init
  88633. + * scripts, such code fragments would be found in
  88634. + * /etc/rc.d/init.d/random. On older Linux systems, the correct script
  88635. + * location might be in /etc/rcb.d/rc.local or /etc/rc.d/rc.0.
  88636. + *
  88637. + * Effectively, these commands cause the contents of the entropy pool
  88638. + * to be saved at shut-down time and reloaded into the entropy pool at
  88639. + * start-up. (The 'dd' in the addition to the bootup script is to
  88640. + * make sure that /etc/random-seed is different for every start-up,
  88641. + * even if the system crashes without executing rc.0.) Even with
  88642. + * complete knowledge of the start-up activities, predicting the state
  88643. + * of the entropy pool requires knowledge of the previous history of
  88644. + * the system.
  88645. + *
  88646. + * Configuring the /dev/random driver under Linux
  88647. + * ==============================================
  88648. + *
  88649. + * The /dev/random driver under Linux uses minor numbers 8 and 9 of
  88650. + * the /dev/mem major number (#1). So if your system does not have
  88651. + * /dev/random and /dev/urandom created already, they can be created
  88652. + * by using the commands:
  88653. + *
  88654. + * mknod /dev/random c 1 8
  88655. + * mknod /dev/urandom c 1 9
  88656. + *
  88657. + * Acknowledgements:
  88658. + * =================
  88659. + *
  88660. + * Ideas for constructing this random number generator were derived
  88661. + * from Pretty Good Privacy's random number generator, and from private
  88662. + * discussions with Phil Karn. Colin Plumb provided a faster random
  88663. + * number generator, which speed up the mixing function of the entropy
  88664. + * pool, taken from PGPfone. Dale Worley has also contributed many
  88665. + * useful ideas and suggestions to improve this driver.
  88666. + *
  88667. + * Any flaws in the design are solely my responsibility, and should
  88668. + * not be attributed to the Phil, Colin, or any of authors of PGP.
  88669. + *
  88670. + * Further background information on this topic may be obtained from
  88671. + * RFC 1750, "Randomness Recommendations for Security", by Donald
  88672. + * Eastlake, Steve Crocker, and Jeff Schiller.
  88673. + */
  88674. +
  88675. +#include <linux/utsname.h>
  88676. +#include <linux/module.h>
  88677. +#include <linux/kernel.h>
  88678. +#include <linux/major.h>
  88679. +#include <linux/string.h>
  88680. +#include <linux/fcntl.h>
  88681. +#include <linux/slab.h>
  88682. +#include <linux/random.h>
  88683. +#include <linux/poll.h>
  88684. +#include <linux/init.h>
  88685. +#include <linux/fs.h>
  88686. +#include <linux/genhd.h>
  88687. +#include <linux/interrupt.h>
  88688. +#include <linux/mm.h>
  88689. +#include <linux/spinlock.h>
  88690. +#include <linux/percpu.h>
  88691. +#include <linux/cryptohash.h>
  88692. +#include <linux/fips.h>
  88693. +
  88694. +#ifdef CONFIG_GENERIC_HARDIRQS
  88695. +# include <linux/irq.h>
  88696. +#endif
  88697. +
  88698. +#include <asm/processor.h>
  88699. +#include <asm/uaccess.h>
  88700. +#include <asm/irq.h>
  88701. +#include <asm/io.h>
  88702. +
  88703. +/*
  88704. + * Configuration information
  88705. + */
  88706. +#define INPUT_POOL_WORDS 128
  88707. +#define OUTPUT_POOL_WORDS 32
  88708. +#define SEC_XFER_SIZE 512
  88709. +#define EXTRACT_SIZE 10
  88710. +
  88711. +/*
  88712. + * The minimum number of bits of entropy before we wake up a read on
  88713. + * /dev/random. Should be enough to do a significant reseed.
  88714. + */
  88715. +static int random_read_wakeup_thresh = 64;
  88716. +
  88717. +/*
  88718. + * If the entropy count falls under this number of bits, then we
  88719. + * should wake up processes which are selecting or polling on write
  88720. + * access to /dev/random.
  88721. + */
  88722. +static int random_write_wakeup_thresh = 128;
  88723. +
  88724. +/*
  88725. + * When the input pool goes over trickle_thresh, start dropping most
  88726. + * samples to avoid wasting CPU time and reduce lock contention.
  88727. + */
  88728. +
  88729. +static int trickle_thresh __read_mostly = INPUT_POOL_WORDS * 28;
  88730. +
  88731. +static DEFINE_PER_CPU(int, trickle_count);
  88732. +
  88733. +/*
  88734. + * A pool of size .poolwords is stirred with a primitive polynomial
  88735. + * of degree .poolwords over GF(2). The taps for various sizes are
  88736. + * defined below. They are chosen to be evenly spaced (minimum RMS
  88737. + * distance from evenly spaced; the numbers in the comments are a
  88738. + * scaled squared error sum) except for the last tap, which is 1 to
  88739. + * get the twisting happening as fast as possible.
  88740. + */
  88741. +static struct poolinfo {
  88742. + int poolwords;
  88743. + int tap1, tap2, tap3, tap4, tap5;
  88744. +} poolinfo_table[] = {
  88745. + /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
  88746. + { 128, 103, 76, 51, 25, 1 },
  88747. + /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
  88748. + { 32, 26, 20, 14, 7, 1 },
  88749. +#if 0
  88750. + /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
  88751. + { 2048, 1638, 1231, 819, 411, 1 },
  88752. +
  88753. + /* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */
  88754. + { 1024, 817, 615, 412, 204, 1 },
  88755. +
  88756. + /* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */
  88757. + { 1024, 819, 616, 410, 207, 2 },
  88758. +
  88759. + /* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */
  88760. + { 512, 411, 308, 208, 104, 1 },
  88761. +
  88762. + /* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */
  88763. + { 512, 409, 307, 206, 102, 2 },
  88764. + /* x^512 + x^409 + x^309 + x^205 + x^103 + x^2 + 1 -- 95 */
  88765. + { 512, 409, 309, 205, 103, 2 },
  88766. +
  88767. + /* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */
  88768. + { 256, 205, 155, 101, 52, 1 },
  88769. +
  88770. + /* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */
  88771. + { 128, 103, 78, 51, 27, 2 },
  88772. +
  88773. + /* x^64 + x^52 + x^39 + x^26 + x^14 + x + 1 -- 15 */
  88774. + { 64, 52, 39, 26, 14, 1 },
  88775. +#endif
  88776. +};
  88777. +
  88778. +#define POOLBITS poolwords*32
  88779. +#define POOLBYTES poolwords*4
  88780. +
  88781. +/*
  88782. + * For the purposes of better mixing, we use the CRC-32 polynomial as
  88783. + * well to make a twisted Generalized Feedback Shift Reigster
  88784. + *
  88785. + * (See M. Matsumoto & Y. Kurita, 1992. Twisted GFSR generators. ACM
  88786. + * Transactions on Modeling and Computer Simulation 2(3):179-194.
  88787. + * Also see M. Matsumoto & Y. Kurita, 1994. Twisted GFSR generators
  88788. + * II. ACM Transactions on Mdeling and Computer Simulation 4:254-266)
  88789. + *
  88790. + * Thanks to Colin Plumb for suggesting this.
  88791. + *
  88792. + * We have not analyzed the resultant polynomial to prove it primitive;
  88793. + * in fact it almost certainly isn't. Nonetheless, the irreducible factors
  88794. + * of a random large-degree polynomial over GF(2) are more than large enough
  88795. + * that periodicity is not a concern.
  88796. + *
  88797. + * The input hash is much less sensitive than the output hash. All
  88798. + * that we want of it is that it be a good non-cryptographic hash;
  88799. + * i.e. it not produce collisions when fed "random" data of the sort
  88800. + * we expect to see. As long as the pool state differs for different
  88801. + * inputs, we have preserved the input entropy and done a good job.
  88802. + * The fact that an intelligent attacker can construct inputs that
  88803. + * will produce controlled alterations to the pool's state is not
  88804. + * important because we don't consider such inputs to contribute any
  88805. + * randomness. The only property we need with respect to them is that
  88806. + * the attacker can't increase his/her knowledge of the pool's state.
  88807. + * Since all additions are reversible (knowing the final state and the
  88808. + * input, you can reconstruct the initial state), if an attacker has
  88809. + * any uncertainty about the initial state, he/she can only shuffle
  88810. + * that uncertainty about, but never cause any collisions (which would
  88811. + * decrease the uncertainty).
  88812. + *
  88813. + * The chosen system lets the state of the pool be (essentially) the input
  88814. + * modulo the generator polymnomial. Now, for random primitive polynomials,
  88815. + * this is a universal class of hash functions, meaning that the chance
  88816. + * of a collision is limited by the attacker's knowledge of the generator
  88817. + * polynomail, so if it is chosen at random, an attacker can never force
  88818. + * a collision. Here, we use a fixed polynomial, but we *can* assume that
  88819. + * ###--> it is unknown to the processes generating the input entropy. <-###
  88820. + * Because of this important property, this is a good, collision-resistant
  88821. + * hash; hash collisions will occur no more often than chance.
  88822. + */
  88823. +
  88824. +/*
  88825. + * Static global variables
  88826. + */
  88827. +static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
  88828. +static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
  88829. +static struct fasync_struct *fasync;
  88830. +
  88831. +#if 0
  88832. +static int debug;
  88833. +module_param(debug, bool, 0644);
  88834. +#define DEBUG_ENT(fmt, arg...) do { \
  88835. + if (debug) \
  88836. + printk(KERN_DEBUG "random %04d %04d %04d: " \
  88837. + fmt,\
  88838. + input_pool.entropy_count,\
  88839. + blocking_pool.entropy_count,\
  88840. + nonblocking_pool.entropy_count,\
  88841. + ## arg); } while (0)
  88842. +#else
  88843. +#define DEBUG_ENT(fmt, arg...) do {} while (0)
  88844. +#endif
  88845. +
  88846. +/**********************************************************************
  88847. + *
  88848. + * OS independent entropy store. Here are the functions which handle
  88849. + * storing entropy in an entropy pool.
  88850. + *
  88851. + **********************************************************************/
  88852. +
  88853. +struct entropy_store;
  88854. +struct entropy_store {
  88855. + /* read-only data: */
  88856. + struct poolinfo *poolinfo;
  88857. + __u32 *pool;
  88858. + const char *name;
  88859. + struct entropy_store *pull;
  88860. + int limit;
  88861. +
  88862. + /* read-write data: */
  88863. + spinlock_t lock;
  88864. + unsigned add_ptr;
  88865. + int entropy_count;
  88866. + int input_rotate;
  88867. + __u8 last_data[EXTRACT_SIZE];
  88868. +};
  88869. +
  88870. +static __u32 input_pool_data[INPUT_POOL_WORDS];
  88871. +static __u32 blocking_pool_data[OUTPUT_POOL_WORDS];
  88872. +static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS];
  88873. +
  88874. +static struct entropy_store input_pool = {
  88875. + .poolinfo = &poolinfo_table[0],
  88876. + .name = "input",
  88877. + .limit = 1,
  88878. + .lock = __SPIN_LOCK_UNLOCKED(&input_pool.lock),
  88879. + .pool = input_pool_data
  88880. +};
  88881. +
  88882. +static struct entropy_store blocking_pool = {
  88883. + .poolinfo = &poolinfo_table[1],
  88884. + .name = "blocking",
  88885. + .limit = 1,
  88886. + .pull = &input_pool,
  88887. + .lock = __SPIN_LOCK_UNLOCKED(&blocking_pool.lock),
  88888. + .pool = blocking_pool_data
  88889. +};
  88890. +
  88891. +static struct entropy_store nonblocking_pool = {
  88892. + .poolinfo = &poolinfo_table[1],
  88893. + .name = "nonblocking",
  88894. + .pull = &input_pool,
  88895. + .lock = __SPIN_LOCK_UNLOCKED(&nonblocking_pool.lock),
  88896. + .pool = nonblocking_pool_data
  88897. +};
  88898. +
  88899. +/*
  88900. + * This function adds bytes into the entropy "pool". It does not
  88901. + * update the entropy estimate. The caller should call
  88902. + * credit_entropy_bits if this is appropriate.
  88903. + *
  88904. + * The pool is stirred with a primitive polynomial of the appropriate
  88905. + * degree, and then twisted. We twist by three bits at a time because
  88906. + * it's cheap to do so and helps slightly in the expected case where
  88907. + * the entropy is concentrated in the low-order bits.
  88908. + */
  88909. +static void mix_pool_bytes_extract(struct entropy_store *r, const void *in,
  88910. + int nbytes, __u8 out[64])
  88911. +{
  88912. + static __u32 const twist_table[8] = {
  88913. + 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
  88914. + 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
  88915. + unsigned long i, j, tap1, tap2, tap3, tap4, tap5;
  88916. + int input_rotate;
  88917. + int wordmask = r->poolinfo->poolwords - 1;
  88918. + const char *bytes = in;
  88919. + __u32 w;
  88920. + unsigned long flags;
  88921. +
  88922. + /* Taps are constant, so we can load them without holding r->lock. */
  88923. + tap1 = r->poolinfo->tap1;
  88924. + tap2 = r->poolinfo->tap2;
  88925. + tap3 = r->poolinfo->tap3;
  88926. + tap4 = r->poolinfo->tap4;
  88927. + tap5 = r->poolinfo->tap5;
  88928. +
  88929. + spin_lock_irqsave(&r->lock, flags);
  88930. + input_rotate = r->input_rotate;
  88931. + i = r->add_ptr;
  88932. +
  88933. + /* mix one byte at a time to simplify size handling and churn faster */
  88934. + while (nbytes--) {
  88935. + w = rol32(*bytes++, input_rotate & 31);
  88936. + i = (i - 1) & wordmask;
  88937. +
  88938. + /* XOR in the various taps */
  88939. + w ^= r->pool[i];
  88940. + w ^= r->pool[(i + tap1) & wordmask];
  88941. + w ^= r->pool[(i + tap2) & wordmask];
  88942. + w ^= r->pool[(i + tap3) & wordmask];
  88943. + w ^= r->pool[(i + tap4) & wordmask];
  88944. + w ^= r->pool[(i + tap5) & wordmask];
  88945. +
  88946. + /* Mix the result back in with a twist */
  88947. + r->pool[i] = (w >> 3) ^ twist_table[w & 7];
  88948. +
  88949. + /*
  88950. + * Normally, we add 7 bits of rotation to the pool.
  88951. + * At the beginning of the pool, add an extra 7 bits
  88952. + * rotation, so that successive passes spread the
  88953. + * input bits across the pool evenly.
  88954. + */
  88955. + input_rotate += i ? 7 : 14;
  88956. + }
  88957. +
  88958. + r->input_rotate = input_rotate;
  88959. + r->add_ptr = i;
  88960. +
  88961. + if (out)
  88962. + for (j = 0; j < 16; j++)
  88963. + ((__u32 *)out)[j] = r->pool[(i - j) & wordmask];
  88964. +
  88965. + spin_unlock_irqrestore(&r->lock, flags);
  88966. +}
  88967. +
  88968. +static void mix_pool_bytes(struct entropy_store *r, const void *in, int bytes)
  88969. +{
  88970. + mix_pool_bytes_extract(r, in, bytes, NULL);
  88971. +}
  88972. +
  88973. +/*
  88974. + * Credit (or debit) the entropy store with n bits of entropy
  88975. + */
  88976. +static void credit_entropy_bits(struct entropy_store *r, int nbits)
  88977. +{
  88978. + unsigned long flags;
  88979. + int entropy_count;
  88980. +
  88981. + if (!nbits)
  88982. + return;
  88983. +
  88984. + spin_lock_irqsave(&r->lock, flags);
  88985. +
  88986. + DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name);
  88987. + entropy_count = r->entropy_count;
  88988. + entropy_count += nbits;
  88989. + if (entropy_count < 0) {
  88990. + DEBUG_ENT("negative entropy/overflow\n");
  88991. + entropy_count = 0;
  88992. + } else if (entropy_count > r->poolinfo->POOLBITS)
  88993. + entropy_count = r->poolinfo->POOLBITS;
  88994. + r->entropy_count = entropy_count;
  88995. +
  88996. + /* should we wake readers? */
  88997. + if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) {
  88998. + wake_up_interruptible(&random_read_wait);
  88999. + kill_fasync(&fasync, SIGIO, POLL_IN);
  89000. + }
  89001. + spin_unlock_irqrestore(&r->lock, flags);
  89002. +}
  89003. +
  89004. +/*********************************************************************
  89005. + *
  89006. + * Entropy input management
  89007. + *
  89008. + *********************************************************************/
  89009. +
  89010. +/* There is one of these per entropy source */
  89011. +struct timer_rand_state {
  89012. + cycles_t last_time;
  89013. + long last_delta, last_delta2;
  89014. + unsigned dont_count_entropy:1;
  89015. +};
  89016. +
  89017. +#ifndef CONFIG_GENERIC_HARDIRQS
  89018. +
  89019. +static struct timer_rand_state *irq_timer_state[NR_IRQS];
  89020. +
  89021. +static struct timer_rand_state *get_timer_rand_state(unsigned int irq)
  89022. +{
  89023. + return irq_timer_state[irq];
  89024. +}
  89025. +
  89026. +static void set_timer_rand_state(unsigned int irq,
  89027. + struct timer_rand_state *state)
  89028. +{
  89029. + irq_timer_state[irq] = state;
  89030. +}
  89031. +
  89032. +#else
  89033. +
  89034. +static struct timer_rand_state *get_timer_rand_state(unsigned int irq)
  89035. +{
  89036. + struct irq_desc *desc;
  89037. +
  89038. + desc = irq_to_desc(irq);
  89039. +
  89040. + return desc->timer_rand_state;
  89041. +}
  89042. +
  89043. +static void set_timer_rand_state(unsigned int irq,
  89044. + struct timer_rand_state *state)
  89045. +{
  89046. + struct irq_desc *desc;
  89047. +
  89048. + desc = irq_to_desc(irq);
  89049. +
  89050. + desc->timer_rand_state = state;
  89051. +}
  89052. +#endif
  89053. +
  89054. +static struct timer_rand_state input_timer_state;
  89055. +
  89056. +/*
  89057. + * This function adds entropy to the entropy "pool" by using timing
  89058. + * delays. It uses the timer_rand_state structure to make an estimate
  89059. + * of how many bits of entropy this call has added to the pool.
  89060. + *
  89061. + * The number "num" is also added to the pool - it should somehow describe
  89062. + * the type of event which just happened. This is currently 0-255 for
  89063. + * keyboard scan codes, and 256 upwards for interrupts.
  89064. + *
  89065. + */
  89066. +static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
  89067. +{
  89068. + struct {
  89069. + cycles_t cycles;
  89070. + long jiffies;
  89071. + unsigned num;
  89072. + } sample;
  89073. + long delta, delta2, delta3;
  89074. +
  89075. + preempt_disable();
  89076. + /* if over the trickle threshold, use only 1 in 4096 samples */
  89077. + if (input_pool.entropy_count > trickle_thresh &&
  89078. + ((__this_cpu_inc_return(trickle_count) - 1) & 0xfff))
  89079. + goto out;
  89080. +
  89081. + sample.jiffies = jiffies;
  89082. + sample.cycles = get_cycles();
  89083. + sample.num = num;
  89084. + mix_pool_bytes(&input_pool, &sample, sizeof(sample));
  89085. +
  89086. + /*
  89087. + * Calculate number of bits of randomness we probably added.
  89088. + * We take into account the first, second and third-order deltas
  89089. + * in order to make our estimate.
  89090. + */
  89091. +
  89092. + if (!state->dont_count_entropy) {
  89093. + delta = sample.jiffies - state->last_time;
  89094. + state->last_time = sample.jiffies;
  89095. +
  89096. + delta2 = delta - state->last_delta;
  89097. + state->last_delta = delta;
  89098. +
  89099. + delta3 = delta2 - state->last_delta2;
  89100. + state->last_delta2 = delta2;
  89101. +
  89102. + if (delta < 0)
  89103. + delta = -delta;
  89104. + if (delta2 < 0)
  89105. + delta2 = -delta2;
  89106. + if (delta3 < 0)
  89107. + delta3 = -delta3;
  89108. + if (delta > delta2)
  89109. + delta = delta2;
  89110. + if (delta > delta3)
  89111. + delta = delta3;
  89112. +
  89113. + /*
  89114. + * delta is now minimum absolute delta.
  89115. + * Round down by 1 bit on general principles,
  89116. + * and limit entropy entimate to 12 bits.
  89117. + */
  89118. + credit_entropy_bits(&input_pool,
  89119. + min_t(int, fls(delta>>1), 11));
  89120. + }
  89121. +out:
  89122. + preempt_enable();
  89123. +}
  89124. +
  89125. +void add_input_randomness(unsigned int type, unsigned int code,
  89126. + unsigned int value)
  89127. +{
  89128. + static unsigned char last_value;
  89129. +
  89130. + /* ignore autorepeat and the like */
  89131. + if (value == last_value)
  89132. + return;
  89133. +
  89134. + DEBUG_ENT("input event\n");
  89135. + last_value = value;
  89136. + add_timer_randomness(&input_timer_state,
  89137. + (type << 4) ^ code ^ (code >> 4) ^ value);
  89138. +}
  89139. +EXPORT_SYMBOL_GPL(add_input_randomness);
  89140. +
  89141. +void add_interrupt_randomness(int irq)
  89142. +{
  89143. + struct timer_rand_state *state;
  89144. +
  89145. + state = get_timer_rand_state(irq);
  89146. +
  89147. + if (state == NULL)
  89148. + return;
  89149. +
  89150. + DEBUG_ENT("irq event %d\n", irq);
  89151. + add_timer_randomness(state, 0x100 + irq);
  89152. +}
  89153. +
  89154. +#ifdef CONFIG_BLOCK
  89155. +void add_disk_randomness(struct gendisk *disk)
  89156. +{
  89157. + if (!disk || !disk->random)
  89158. + return;
  89159. + /* first major is 1, so we get >= 0x200 here */
  89160. + DEBUG_ENT("disk event %d:%d\n",
  89161. + MAJOR(disk_devt(disk)), MINOR(disk_devt(disk)));
  89162. +
  89163. + add_timer_randomness(disk->random, 0x100 + disk_devt(disk));
  89164. +}
  89165. +#endif
  89166. +
  89167. +/*********************************************************************
  89168. + *
  89169. + * Entropy extraction routines
  89170. + *
  89171. + *********************************************************************/
  89172. +
  89173. +static ssize_t extract_entropy(struct entropy_store *r, void *buf,
  89174. + size_t nbytes, int min, int rsvd);
  89175. +
  89176. +/*
  89177. + * This utility inline function is responsible for transferring entropy
  89178. + * from the primary pool to the secondary extraction pool. We make
  89179. + * sure we pull enough for a 'catastrophic reseed'.
  89180. + */
  89181. +static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
  89182. +{
  89183. + __u32 tmp[OUTPUT_POOL_WORDS];
  89184. +
  89185. + if (r->pull && r->entropy_count < nbytes * 8 &&
  89186. + r->entropy_count < r->poolinfo->POOLBITS) {
  89187. + /* If we're limited, always leave two wakeup worth's BITS */
  89188. + int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4;
  89189. + int bytes = nbytes;
  89190. +
  89191. + /* pull at least as many as BYTES as wakeup BITS */
  89192. + bytes = max_t(int, bytes, random_read_wakeup_thresh / 8);
  89193. + /* but never more than the buffer size */
  89194. + bytes = min_t(int, bytes, sizeof(tmp));
  89195. +
  89196. + DEBUG_ENT("going to reseed %s with %d bits "
  89197. + "(%d of %d requested)\n",
  89198. + r->name, bytes * 8, nbytes * 8, r->entropy_count);
  89199. +
  89200. + bytes = extract_entropy(r->pull, tmp, bytes,
  89201. + random_read_wakeup_thresh / 8, rsvd);
  89202. + mix_pool_bytes(r, tmp, bytes);
  89203. + credit_entropy_bits(r, bytes*8);
  89204. + }
  89205. +}
  89206. +
  89207. +/*
  89208. + * These functions extracts randomness from the "entropy pool", and
  89209. + * returns it in a buffer.
  89210. + *
  89211. + * The min parameter specifies the minimum amount we can pull before
  89212. + * failing to avoid races that defeat catastrophic reseeding while the
  89213. + * reserved parameter indicates how much entropy we must leave in the
  89214. + * pool after each pull to avoid starving other readers.
  89215. + *
  89216. + * Note: extract_entropy() assumes that .poolwords is a multiple of 16 words.
  89217. + */
  89218. +
  89219. +static size_t account(struct entropy_store *r, size_t nbytes, int min,
  89220. + int reserved)
  89221. +{
  89222. + unsigned long flags;
  89223. +
  89224. + /* Hold lock while accounting */
  89225. + spin_lock_irqsave(&r->lock, flags);
  89226. +
  89227. + BUG_ON(r->entropy_count > r->poolinfo->POOLBITS);
  89228. + DEBUG_ENT("trying to extract %d bits from %s\n",
  89229. + nbytes * 8, r->name);
  89230. +
  89231. + /* Can we pull enough? */
  89232. + if (r->entropy_count / 8 < min + reserved) {
  89233. + nbytes = 0;
  89234. + } else {
  89235. + /* If limited, never pull more than available */
  89236. + if (r->limit && nbytes + reserved >= r->entropy_count / 8)
  89237. + nbytes = r->entropy_count/8 - reserved;
  89238. +
  89239. + if (r->entropy_count / 8 >= nbytes + reserved)
  89240. + r->entropy_count -= nbytes*8;
  89241. + else
  89242. + r->entropy_count = reserved;
  89243. +
  89244. + if (r->entropy_count < random_write_wakeup_thresh) {
  89245. + wake_up_interruptible(&random_write_wait);
  89246. + kill_fasync(&fasync, SIGIO, POLL_OUT);
  89247. + }
  89248. + }
  89249. +
  89250. + DEBUG_ENT("debiting %d entropy credits from %s%s\n",
  89251. + nbytes * 8, r->name, r->limit ? "" : " (unlimited)");
  89252. +
  89253. + spin_unlock_irqrestore(&r->lock, flags);
  89254. +
  89255. + return nbytes;
  89256. +}
  89257. +
  89258. +static void extract_buf(struct entropy_store *r, __u8 *out)
  89259. +{
  89260. + int i;
  89261. + __u32 hash[5], workspace[SHA_WORKSPACE_WORDS];
  89262. + __u8 extract[64];
  89263. +
  89264. + /* Generate a hash across the pool, 16 words (512 bits) at a time */
  89265. + sha_init(hash);
  89266. + for (i = 0; i < r->poolinfo->poolwords; i += 16)
  89267. + sha_transform(hash, (__u8 *)(r->pool + i), workspace);
  89268. +
  89269. + /*
  89270. + * We mix the hash back into the pool to prevent backtracking
  89271. + * attacks (where the attacker knows the state of the pool
  89272. + * plus the current outputs, and attempts to find previous
  89273. + * ouputs), unless the hash function can be inverted. By
  89274. + * mixing at least a SHA1 worth of hash data back, we make
  89275. + * brute-forcing the feedback as hard as brute-forcing the
  89276. + * hash.
  89277. + */
  89278. + mix_pool_bytes_extract(r, hash, sizeof(hash), extract);
  89279. +
  89280. + /*
  89281. + * To avoid duplicates, we atomically extract a portion of the
  89282. + * pool while mixing, and hash one final time.
  89283. + */
  89284. + sha_transform(hash, extract, workspace);
  89285. + memset(extract, 0, sizeof(extract));
  89286. + memset(workspace, 0, sizeof(workspace));
  89287. +
  89288. + /*
  89289. + * In case the hash function has some recognizable output
  89290. + * pattern, we fold it in half. Thus, we always feed back
  89291. + * twice as much data as we output.
  89292. + */
  89293. + hash[0] ^= hash[3];
  89294. + hash[1] ^= hash[4];
  89295. + hash[2] ^= rol32(hash[2], 16);
  89296. + memcpy(out, hash, EXTRACT_SIZE);
  89297. + memset(hash, 0, sizeof(hash));
  89298. +}
  89299. +
  89300. +static ssize_t extract_entropy(struct entropy_store *r, void *buf,
  89301. + size_t nbytes, int min, int reserved)
  89302. +{
  89303. + ssize_t ret = 0, i;
  89304. + __u8 tmp[EXTRACT_SIZE];
  89305. + unsigned long flags;
  89306. +
  89307. + xfer_secondary_pool(r, nbytes);
  89308. + nbytes = account(r, nbytes, min, reserved);
  89309. +
  89310. + while (nbytes) {
  89311. + extract_buf(r, tmp);
  89312. +
  89313. + if (fips_enabled) {
  89314. + spin_lock_irqsave(&r->lock, flags);
  89315. + if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
  89316. + panic("Hardware RNG duplicated output!\n");
  89317. + memcpy(r->last_data, tmp, EXTRACT_SIZE);
  89318. + spin_unlock_irqrestore(&r->lock, flags);
  89319. + }
  89320. + i = min_t(int, nbytes, EXTRACT_SIZE);
  89321. + memcpy(buf, tmp, i);
  89322. + nbytes -= i;
  89323. + buf += i;
  89324. + ret += i;
  89325. + }
  89326. +
  89327. + /* Wipe data just returned from memory */
  89328. + memset(tmp, 0, sizeof(tmp));
  89329. +
  89330. + return ret;
  89331. +}
  89332. +
  89333. +static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
  89334. + size_t nbytes)
  89335. +{
  89336. + ssize_t ret = 0, i;
  89337. + __u8 tmp[EXTRACT_SIZE];
  89338. +
  89339. + xfer_secondary_pool(r, nbytes);
  89340. + nbytes = account(r, nbytes, 0, 0);
  89341. +
  89342. + while (nbytes) {
  89343. + if (need_resched()) {
  89344. + if (signal_pending(current)) {
  89345. + if (ret == 0)
  89346. + ret = -ERESTARTSYS;
  89347. + break;
  89348. + }
  89349. + schedule();
  89350. + }
  89351. +
  89352. + extract_buf(r, tmp);
  89353. + i = min_t(int, nbytes, EXTRACT_SIZE);
  89354. + if (copy_to_user(buf, tmp, i)) {
  89355. + ret = -EFAULT;
  89356. + break;
  89357. + }
  89358. +
  89359. + nbytes -= i;
  89360. + buf += i;
  89361. + ret += i;
  89362. + }
  89363. +
  89364. + /* Wipe data just returned from memory */
  89365. + memset(tmp, 0, sizeof(tmp));
  89366. +
  89367. + return ret;
  89368. +}
  89369. +
  89370. +/*
  89371. + * This function is the exported kernel interface. It returns some
  89372. + * number of good random numbers, suitable for seeding TCP sequence
  89373. + * numbers, etc.
  89374. + */
  89375. +void get_random_bytes(void *buf, int nbytes)
  89376. +{
  89377. + extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0);
  89378. +}
  89379. +EXPORT_SYMBOL(get_random_bytes);
  89380. +
  89381. +/*
  89382. + * init_std_data - initialize pool with system data
  89383. + *
  89384. + * @r: pool to initialize
  89385. + *
  89386. + * This function clears the pool's entropy count and mixes some system
  89387. + * data into the pool to prepare it for use. The pool is not cleared
  89388. + * as that can only decrease the entropy in the pool.
  89389. + */
  89390. +static void init_std_data(struct entropy_store *r)
  89391. +{
  89392. + ktime_t now;
  89393. + unsigned long flags;
  89394. +
  89395. + spin_lock_irqsave(&r->lock, flags);
  89396. + r->entropy_count = 0;
  89397. + spin_unlock_irqrestore(&r->lock, flags);
  89398. +
  89399. + now = ktime_get_real();
  89400. + mix_pool_bytes(r, &now, sizeof(now));
  89401. + mix_pool_bytes(r, utsname(), sizeof(*(utsname())));
  89402. +}
  89403. +
  89404. +static int rand_initialize(void)
  89405. +{
  89406. + init_std_data(&input_pool);
  89407. + init_std_data(&blocking_pool);
  89408. + init_std_data(&nonblocking_pool);
  89409. + return 0;
  89410. +}
  89411. +module_init(rand_initialize);
  89412. +
  89413. +void rand_initialize_irq(int irq)
  89414. +{
  89415. + struct timer_rand_state *state;
  89416. +
  89417. + state = get_timer_rand_state(irq);
  89418. +
  89419. + if (state)
  89420. + return;
  89421. +
  89422. + /*
  89423. + * If kzalloc returns null, we just won't use that entropy
  89424. + * source.
  89425. + */
  89426. + state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
  89427. + if (state)
  89428. + set_timer_rand_state(irq, state);
  89429. +}
  89430. +
  89431. +#ifdef CONFIG_BLOCK
  89432. +void rand_initialize_disk(struct gendisk *disk)
  89433. +{
  89434. + struct timer_rand_state *state;
  89435. +
  89436. + /*
  89437. + * If kzalloc returns null, we just won't use that entropy
  89438. + * source.
  89439. + */
  89440. + state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
  89441. + if (state)
  89442. + disk->random = state;
  89443. +}
  89444. +#endif
  89445. +
  89446. +static ssize_t
  89447. +random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
  89448. +{
  89449. + ssize_t n, retval = 0, count = 0;
  89450. +
  89451. + if (nbytes == 0)
  89452. + return 0;
  89453. +
  89454. + while (nbytes > 0) {
  89455. + n = nbytes;
  89456. + if (n > SEC_XFER_SIZE)
  89457. + n = SEC_XFER_SIZE;
  89458. +
  89459. + DEBUG_ENT("reading %d bits\n", n*8);
  89460. +
  89461. + n = extract_entropy_user(&blocking_pool, buf, n);
  89462. +
  89463. + DEBUG_ENT("read got %d bits (%d still needed)\n",
  89464. + n*8, (nbytes-n)*8);
  89465. +
  89466. + if (n == 0) {
  89467. + if (file->f_flags & O_NONBLOCK) {
  89468. + retval = -EAGAIN;
  89469. + break;
  89470. + }
  89471. +
  89472. + DEBUG_ENT("sleeping?\n");
  89473. +
  89474. + wait_event_interruptible(random_read_wait,
  89475. + input_pool.entropy_count >=
  89476. + random_read_wakeup_thresh);
  89477. +
  89478. + DEBUG_ENT("awake\n");
  89479. +
  89480. + if (signal_pending(current)) {
  89481. + retval = -ERESTARTSYS;
  89482. + break;
  89483. + }
  89484. +
  89485. + continue;
  89486. + }
  89487. +
  89488. + if (n < 0) {
  89489. + retval = n;
  89490. + break;
  89491. + }
  89492. + count += n;
  89493. + buf += n;
  89494. + nbytes -= n;
  89495. + break; /* This break makes the device work */
  89496. + /* like a named pipe */
  89497. + }
  89498. +
  89499. + return (count ? count : retval);
  89500. +}
  89501. +
  89502. +static ssize_t
  89503. +urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
  89504. +{
  89505. + return extract_entropy_user(&nonblocking_pool, buf, nbytes);
  89506. +}
  89507. +
  89508. +static unsigned int
  89509. +random_poll(struct file *file, poll_table * wait)
  89510. +{
  89511. + unsigned int mask;
  89512. +
  89513. + poll_wait(file, &random_read_wait, wait);
  89514. + poll_wait(file, &random_write_wait, wait);
  89515. + mask = 0;
  89516. + if (input_pool.entropy_count >= random_read_wakeup_thresh)
  89517. + mask |= POLLIN | POLLRDNORM;
  89518. + if (input_pool.entropy_count < random_write_wakeup_thresh)
  89519. + mask |= POLLOUT | POLLWRNORM;
  89520. + return mask;
  89521. +}
  89522. +
  89523. +static int
  89524. +write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
  89525. +{
  89526. + size_t bytes;
  89527. + __u32 buf[16];
  89528. + const char __user *p = buffer;
  89529. +
  89530. + while (count > 0) {
  89531. + bytes = min(count, sizeof(buf));
  89532. + if (copy_from_user(&buf, p, bytes))
  89533. + return -EFAULT;
  89534. +
  89535. + count -= bytes;
  89536. + p += bytes;
  89537. +
  89538. + mix_pool_bytes(r, buf, bytes);
  89539. + cond_resched();
  89540. + }
  89541. +
  89542. + return 0;
  89543. +}
  89544. +
  89545. +static ssize_t random_write(struct file *file, const char __user *buffer,
  89546. + size_t count, loff_t *ppos)
  89547. +{
  89548. + size_t ret;
  89549. +
  89550. + ret = write_pool(&blocking_pool, buffer, count);
  89551. + if (ret)
  89552. + return ret;
  89553. + ret = write_pool(&nonblocking_pool, buffer, count);
  89554. + if (ret)
  89555. + return ret;
  89556. +
  89557. + return (ssize_t)count;
  89558. +}
  89559. +
  89560. +static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
  89561. +{
  89562. + int size, ent_count;
  89563. + int __user *p = (int __user *)arg;
  89564. + int retval;
  89565. +
  89566. + switch (cmd) {
  89567. + case RNDGETENTCNT:
  89568. + /* inherently racy, no point locking */
  89569. + if (put_user(input_pool.entropy_count, p))
  89570. + return -EFAULT;
  89571. + return 0;
  89572. + case RNDADDTOENTCNT:
  89573. + if (!capable(CAP_SYS_ADMIN))
  89574. + return -EPERM;
  89575. + if (get_user(ent_count, p))
  89576. + return -EFAULT;
  89577. + credit_entropy_bits(&input_pool, ent_count);
  89578. + return 0;
  89579. + case RNDADDENTROPY:
  89580. + if (!capable(CAP_SYS_ADMIN))
  89581. + return -EPERM;
  89582. + if (get_user(ent_count, p++))
  89583. + return -EFAULT;
  89584. + if (ent_count < 0)
  89585. + return -EINVAL;
  89586. + if (get_user(size, p++))
  89587. + return -EFAULT;
  89588. + retval = write_pool(&input_pool, (const char __user *)p,
  89589. + size);
  89590. + if (retval < 0)
  89591. + return retval;
  89592. + credit_entropy_bits(&input_pool, ent_count);
  89593. + return 0;
  89594. + case RNDZAPENTCNT:
  89595. + case RNDCLEARPOOL:
  89596. + /* Clear the entropy pool counters. */
  89597. + if (!capable(CAP_SYS_ADMIN))
  89598. + return -EPERM;
  89599. + rand_initialize();
  89600. + return 0;
  89601. + default:
  89602. + return -EINVAL;
  89603. + }
  89604. +}
  89605. +
  89606. +static int random_fasync(int fd, struct file *filp, int on)
  89607. +{
  89608. + return fasync_helper(fd, filp, on, &fasync);
  89609. +}
  89610. +
  89611. +const struct file_operations random_fops = {
  89612. + .read = random_read,
  89613. + .write = random_write,
  89614. + .poll = random_poll,
  89615. + .unlocked_ioctl = random_ioctl,
  89616. + .fasync = random_fasync,
  89617. + .llseek = noop_llseek,
  89618. +};
  89619. +
  89620. +const struct file_operations urandom_fops = {
  89621. + .read = urandom_read,
  89622. + .write = random_write,
  89623. + .unlocked_ioctl = random_ioctl,
  89624. + .fasync = random_fasync,
  89625. + .llseek = noop_llseek,
  89626. +};
  89627. +
  89628. +/***************************************************************
  89629. + * Random UUID interface
  89630. + *
  89631. + * Used here for a Boot ID, but can be useful for other kernel
  89632. + * drivers.
  89633. + ***************************************************************/
  89634. +
  89635. +/*
  89636. + * Generate random UUID
  89637. + */
  89638. +void generate_random_uuid(unsigned char uuid_out[16])
  89639. +{
  89640. + get_random_bytes(uuid_out, 16);
  89641. + /* Set UUID version to 4 --- truly random generation */
  89642. + uuid_out[6] = (uuid_out[6] & 0x0F) | 0x40;
  89643. + /* Set the UUID variant to DCE */
  89644. + uuid_out[8] = (uuid_out[8] & 0x3F) | 0x80;
  89645. +}
  89646. +EXPORT_SYMBOL(generate_random_uuid);
  89647. +
  89648. +/********************************************************************
  89649. + *
  89650. + * Sysctl interface
  89651. + *
  89652. + ********************************************************************/
  89653. +
  89654. +#ifdef CONFIG_SYSCTL
  89655. +
  89656. +#include <linux/sysctl.h>
  89657. +
  89658. +static int min_read_thresh = 8, min_write_thresh;
  89659. +static int max_read_thresh = INPUT_POOL_WORDS * 32;
  89660. +static int max_write_thresh = INPUT_POOL_WORDS * 32;
  89661. +static char sysctl_bootid[16];
  89662. +
  89663. +/*
  89664. + * These functions is used to return both the bootid UUID, and random
  89665. + * UUID. The difference is in whether table->data is NULL; if it is,
  89666. + * then a new UUID is generated and returned to the user.
  89667. + *
  89668. + * If the user accesses this via the proc interface, it will be returned
  89669. + * as an ASCII string in the standard UUID format. If accesses via the
  89670. + * sysctl system call, it is returned as 16 bytes of binary data.
  89671. + */
  89672. +static int proc_do_uuid(ctl_table *table, int write,
  89673. + void __user *buffer, size_t *lenp, loff_t *ppos)
  89674. +{
  89675. + ctl_table fake_table;
  89676. + unsigned char buf[64], tmp_uuid[16], *uuid;
  89677. +
  89678. + uuid = table->data;
  89679. + if (!uuid) {
  89680. + uuid = tmp_uuid;
  89681. + uuid[8] = 0;
  89682. + }
  89683. + if (uuid[8] == 0)
  89684. + generate_random_uuid(uuid);
  89685. +
  89686. + sprintf(buf, "%pU", uuid);
  89687. +
  89688. + fake_table.data = buf;
  89689. + fake_table.maxlen = sizeof(buf);
  89690. +
  89691. + return proc_dostring(&fake_table, write, buffer, lenp, ppos);
  89692. +}
  89693. +
  89694. +static int sysctl_poolsize = INPUT_POOL_WORDS * 32;
  89695. +ctl_table random_table[] = {
  89696. + {
  89697. + .procname = "poolsize",
  89698. + .data = &sysctl_poolsize,
  89699. + .maxlen = sizeof(int),
  89700. + .mode = 0444,
  89701. + .proc_handler = proc_dointvec,
  89702. + },
  89703. + {
  89704. + .procname = "entropy_avail",
  89705. + .maxlen = sizeof(int),
  89706. + .mode = 0444,
  89707. + .proc_handler = proc_dointvec,
  89708. + .data = &input_pool.entropy_count,
  89709. + },
  89710. + {
  89711. + .procname = "read_wakeup_threshold",
  89712. + .data = &random_read_wakeup_thresh,
  89713. + .maxlen = sizeof(int),
  89714. + .mode = 0644,
  89715. + .proc_handler = proc_dointvec_minmax,
  89716. + .extra1 = &min_read_thresh,
  89717. + .extra2 = &max_read_thresh,
  89718. + },
  89719. + {
  89720. + .procname = "write_wakeup_threshold",
  89721. + .data = &random_write_wakeup_thresh,
  89722. + .maxlen = sizeof(int),
  89723. + .mode = 0644,
  89724. + .proc_handler = proc_dointvec_minmax,
  89725. + .extra1 = &min_write_thresh,
  89726. + .extra2 = &max_write_thresh,
  89727. + },
  89728. + {
  89729. + .procname = "boot_id",
  89730. + .data = &sysctl_bootid,
  89731. + .maxlen = 16,
  89732. + .mode = 0444,
  89733. + .proc_handler = proc_do_uuid,
  89734. + },
  89735. + {
  89736. + .procname = "uuid",
  89737. + .maxlen = 16,
  89738. + .mode = 0444,
  89739. + .proc_handler = proc_do_uuid,
  89740. + },
  89741. + { }
  89742. +};
  89743. +#endif /* CONFIG_SYSCTL */
  89744. +
  89745. +/********************************************************************
  89746. + *
  89747. + * Random functions for networking
  89748. + *
  89749. + ********************************************************************/
  89750. +
  89751. +/*
  89752. + * TCP initial sequence number picking. This uses the random number
  89753. + * generator to pick an initial secret value. This value is hashed
  89754. + * along with the TCP endpoint information to provide a unique
  89755. + * starting point for each pair of TCP endpoints. This defeats
  89756. + * attacks which rely on guessing the initial TCP sequence number.
  89757. + * This algorithm was suggested by Steve Bellovin.
  89758. + *
  89759. + * Using a very strong hash was taking an appreciable amount of the total
  89760. + * TCP connection establishment time, so this is a weaker hash,
  89761. + * compensated for by changing the secret periodically.
  89762. + */
  89763. +
  89764. +/* F, G and H are basic MD4 functions: selection, majority, parity */
  89765. +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
  89766. +#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
  89767. +#define H(x, y, z) ((x) ^ (y) ^ (z))
  89768. +
  89769. +/*
  89770. + * The generic round function. The application is so specific that
  89771. + * we don't bother protecting all the arguments with parens, as is generally
  89772. + * good macro practice, in favor of extra legibility.
  89773. + * Rotation is separate from addition to prevent recomputation
  89774. + */
  89775. +#define ROUND(f, a, b, c, d, x, s) \
  89776. + (a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s)))
  89777. +#define K1 0
  89778. +#define K2 013240474631UL
  89779. +#define K3 015666365641UL
  89780. +
  89781. +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
  89782. +
  89783. +static __u32 twothirdsMD4Transform(__u32 const buf[4], __u32 const in[12])
  89784. +{
  89785. + __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
  89786. +
  89787. + /* Round 1 */
  89788. + ROUND(F, a, b, c, d, in[ 0] + K1, 3);
  89789. + ROUND(F, d, a, b, c, in[ 1] + K1, 7);
  89790. + ROUND(F, c, d, a, b, in[ 2] + K1, 11);
  89791. + ROUND(F, b, c, d, a, in[ 3] + K1, 19);
  89792. + ROUND(F, a, b, c, d, in[ 4] + K1, 3);
  89793. + ROUND(F, d, a, b, c, in[ 5] + K1, 7);
  89794. + ROUND(F, c, d, a, b, in[ 6] + K1, 11);
  89795. + ROUND(F, b, c, d, a, in[ 7] + K1, 19);
  89796. + ROUND(F, a, b, c, d, in[ 8] + K1, 3);
  89797. + ROUND(F, d, a, b, c, in[ 9] + K1, 7);
  89798. + ROUND(F, c, d, a, b, in[10] + K1, 11);
  89799. + ROUND(F, b, c, d, a, in[11] + K1, 19);
  89800. +
  89801. + /* Round 2 */
  89802. + ROUND(G, a, b, c, d, in[ 1] + K2, 3);
  89803. + ROUND(G, d, a, b, c, in[ 3] + K2, 5);
  89804. + ROUND(G, c, d, a, b, in[ 5] + K2, 9);
  89805. + ROUND(G, b, c, d, a, in[ 7] + K2, 13);
  89806. + ROUND(G, a, b, c, d, in[ 9] + K2, 3);
  89807. + ROUND(G, d, a, b, c, in[11] + K2, 5);
  89808. + ROUND(G, c, d, a, b, in[ 0] + K2, 9);
  89809. + ROUND(G, b, c, d, a, in[ 2] + K2, 13);
  89810. + ROUND(G, a, b, c, d, in[ 4] + K2, 3);
  89811. + ROUND(G, d, a, b, c, in[ 6] + K2, 5);
  89812. + ROUND(G, c, d, a, b, in[ 8] + K2, 9);
  89813. + ROUND(G, b, c, d, a, in[10] + K2, 13);
  89814. +
  89815. + /* Round 3 */
  89816. + ROUND(H, a, b, c, d, in[ 3] + K3, 3);
  89817. + ROUND(H, d, a, b, c, in[ 7] + K3, 9);
  89818. + ROUND(H, c, d, a, b, in[11] + K3, 11);
  89819. + ROUND(H, b, c, d, a, in[ 2] + K3, 15);
  89820. + ROUND(H, a, b, c, d, in[ 6] + K3, 3);
  89821. + ROUND(H, d, a, b, c, in[10] + K3, 9);
  89822. + ROUND(H, c, d, a, b, in[ 1] + K3, 11);
  89823. + ROUND(H, b, c, d, a, in[ 5] + K3, 15);
  89824. + ROUND(H, a, b, c, d, in[ 9] + K3, 3);
  89825. + ROUND(H, d, a, b, c, in[ 0] + K3, 9);
  89826. + ROUND(H, c, d, a, b, in[ 4] + K3, 11);
  89827. + ROUND(H, b, c, d, a, in[ 8] + K3, 15);
  89828. +
  89829. + return buf[1] + b; /* "most hashed" word */
  89830. + /* Alternative: return sum of all words? */
  89831. +}
  89832. +#endif
  89833. +
  89834. +#undef ROUND
  89835. +#undef F
  89836. +#undef G
  89837. +#undef H
  89838. +#undef K1
  89839. +#undef K2
  89840. +#undef K3
  89841. +
  89842. +/* This should not be decreased so low that ISNs wrap too fast. */
  89843. +#define REKEY_INTERVAL (300 * HZ)
  89844. +/*
  89845. + * Bit layout of the tcp sequence numbers (before adding current time):
  89846. + * bit 24-31: increased after every key exchange
  89847. + * bit 0-23: hash(source,dest)
  89848. + *
  89849. + * The implementation is similar to the algorithm described
  89850. + * in the Appendix of RFC 1185, except that
  89851. + * - it uses a 1 MHz clock instead of a 250 kHz clock
  89852. + * - it performs a rekey every 5 minutes, which is equivalent
  89853. + * to a (source,dest) tulple dependent forward jump of the
  89854. + * clock by 0..2^(HASH_BITS+1)
  89855. + *
  89856. + * Thus the average ISN wraparound time is 68 minutes instead of
  89857. + * 4.55 hours.
  89858. + *
  89859. + * SMP cleanup and lock avoidance with poor man's RCU.
  89860. + * Manfred Spraul <manfred@colorfullife.com>
  89861. + *
  89862. + */
  89863. +#define COUNT_BITS 8
  89864. +#define COUNT_MASK ((1 << COUNT_BITS) - 1)
  89865. +#define HASH_BITS 24
  89866. +#define HASH_MASK ((1 << HASH_BITS) - 1)
  89867. +
  89868. +static struct keydata {
  89869. + __u32 count; /* already shifted to the final position */
  89870. + __u32 secret[12];
  89871. +} ____cacheline_aligned ip_keydata[2];
  89872. +
  89873. +static unsigned int ip_cnt;
  89874. +
  89875. +static void rekey_seq_generator(struct work_struct *work);
  89876. +
  89877. +static DECLARE_DELAYED_WORK(rekey_work, rekey_seq_generator);
  89878. +
  89879. +/*
  89880. + * Lock avoidance:
  89881. + * The ISN generation runs lockless - it's just a hash over random data.
  89882. + * State changes happen every 5 minutes when the random key is replaced.
  89883. + * Synchronization is performed by having two copies of the hash function
  89884. + * state and rekey_seq_generator always updates the inactive copy.
  89885. + * The copy is then activated by updating ip_cnt.
  89886. + * The implementation breaks down if someone blocks the thread
  89887. + * that processes SYN requests for more than 5 minutes. Should never
  89888. + * happen, and even if that happens only a not perfectly compliant
  89889. + * ISN is generated, nothing fatal.
  89890. + */
  89891. +static void rekey_seq_generator(struct work_struct *work)
  89892. +{
  89893. + struct keydata *keyptr = &ip_keydata[1 ^ (ip_cnt & 1)];
  89894. +
  89895. + get_random_bytes(keyptr->secret, sizeof(keyptr->secret));
  89896. + keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS;
  89897. + smp_wmb();
  89898. + ip_cnt++;
  89899. + schedule_delayed_work(&rekey_work,
  89900. + round_jiffies_relative(REKEY_INTERVAL));
  89901. +}
  89902. +
  89903. +static inline struct keydata *get_keyptr(void)
  89904. +{
  89905. + struct keydata *keyptr = &ip_keydata[ip_cnt & 1];
  89906. +
  89907. + smp_rmb();
  89908. +
  89909. + return keyptr;
  89910. +}
  89911. +
  89912. +static __init int seqgen_init(void)
  89913. +{
  89914. + rekey_seq_generator(NULL);
  89915. + return 0;
  89916. +}
  89917. +late_initcall(seqgen_init);
  89918. +
  89919. +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
  89920. +__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr,
  89921. + __be16 sport, __be16 dport)
  89922. +{
  89923. + __u32 seq;
  89924. + __u32 hash[12];
  89925. + struct keydata *keyptr = get_keyptr();
  89926. +
  89927. + /* The procedure is the same as for IPv4, but addresses are longer.
  89928. + * Thus we must use twothirdsMD4Transform.
  89929. + */
  89930. +
  89931. + memcpy(hash, saddr, 16);
  89932. + hash[4] = ((__force u16)sport << 16) + (__force u16)dport;
  89933. + memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7);
  89934. +
  89935. + seq = twothirdsMD4Transform((const __u32 *)daddr, hash) & HASH_MASK;
  89936. + seq += keyptr->count;
  89937. +
  89938. + seq += ktime_to_ns(ktime_get_real());
  89939. +
  89940. + return seq;
  89941. +}
  89942. +EXPORT_SYMBOL(secure_tcpv6_sequence_number);
  89943. +#endif
  89944. +
  89945. +/* The code below is shamelessly stolen from secure_tcp_sequence_number().
  89946. + * All blames to Andrey V. Savochkin <saw@msu.ru>.
  89947. + */
  89948. +__u32 secure_ip_id(__be32 daddr)
  89949. +{
  89950. + struct keydata *keyptr;
  89951. + __u32 hash[4];
  89952. +
  89953. + keyptr = get_keyptr();
  89954. +
  89955. + /*
  89956. + * Pick a unique starting offset for each IP destination.
  89957. + * The dest ip address is placed in the starting vector,
  89958. + * which is then hashed with random data.
  89959. + */
  89960. + hash[0] = (__force __u32)daddr;
  89961. + hash[1] = keyptr->secret[9];
  89962. + hash[2] = keyptr->secret[10];
  89963. + hash[3] = keyptr->secret[11];
  89964. +
  89965. + return half_md4_transform(hash, keyptr->secret);
  89966. +}
  89967. +
  89968. +#ifdef CONFIG_INET
  89969. +
  89970. +__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
  89971. + __be16 sport, __be16 dport)
  89972. +{
  89973. + __u32 seq;
  89974. + __u32 hash[4];
  89975. + struct keydata *keyptr = get_keyptr();
  89976. +
  89977. + /*
  89978. + * Pick a unique starting offset for each TCP connection endpoints
  89979. + * (saddr, daddr, sport, dport).
  89980. + * Note that the words are placed into the starting vector, which is
  89981. + * then mixed with a partial MD4 over random data.
  89982. + */
  89983. + hash[0] = (__force u32)saddr;
  89984. + hash[1] = (__force u32)daddr;
  89985. + hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
  89986. + hash[3] = keyptr->secret[11];
  89987. +
  89988. + seq = half_md4_transform(hash, keyptr->secret) & HASH_MASK;
  89989. + seq += keyptr->count;
  89990. + /*
  89991. + * As close as possible to RFC 793, which
  89992. + * suggests using a 250 kHz clock.
  89993. + * Further reading shows this assumes 2 Mb/s networks.
  89994. + * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate.
  89995. + * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but
  89996. + * we also need to limit the resolution so that the u32 seq
  89997. + * overlaps less than one time per MSL (2 minutes).
  89998. + * Choosing a clock of 64 ns period is OK. (period of 274 s)
  89999. + */
  90000. + seq += ktime_to_ns(ktime_get_real()) >> 6;
  90001. +
  90002. + return seq;
  90003. +}
  90004. +
  90005. +/* Generate secure starting point for ephemeral IPV4 transport port search */
  90006. +u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
  90007. +{
  90008. + struct keydata *keyptr = get_keyptr();
  90009. + u32 hash[4];
  90010. +
  90011. + /*
  90012. + * Pick a unique starting offset for each ephemeral port search
  90013. + * (saddr, daddr, dport) and 48bits of random data.
  90014. + */
  90015. + hash[0] = (__force u32)saddr;
  90016. + hash[1] = (__force u32)daddr;
  90017. + hash[2] = (__force u32)dport ^ keyptr->secret[10];
  90018. + hash[3] = keyptr->secret[11];
  90019. +
  90020. + return half_md4_transform(hash, keyptr->secret);
  90021. +}
  90022. +EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral);
  90023. +
  90024. +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
  90025. +u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
  90026. + __be16 dport)
  90027. +{
  90028. + struct keydata *keyptr = get_keyptr();
  90029. + u32 hash[12];
  90030. +
  90031. + memcpy(hash, saddr, 16);
  90032. + hash[4] = (__force u32)dport;
  90033. + memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7);
  90034. +
  90035. + return twothirdsMD4Transform((const __u32 *)daddr, hash);
  90036. +}
  90037. +#endif
  90038. +
  90039. +#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
  90040. +/* Similar to secure_tcp_sequence_number but generate a 48 bit value
  90041. + * bit's 32-47 increase every key exchange
  90042. + * 0-31 hash(source, dest)
  90043. + */
  90044. +u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
  90045. + __be16 sport, __be16 dport)
  90046. +{
  90047. + u64 seq;
  90048. + __u32 hash[4];
  90049. + struct keydata *keyptr = get_keyptr();
  90050. +
  90051. + hash[0] = (__force u32)saddr;
  90052. + hash[1] = (__force u32)daddr;
  90053. + hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
  90054. + hash[3] = keyptr->secret[11];
  90055. +
  90056. + seq = half_md4_transform(hash, keyptr->secret);
  90057. + seq |= ((u64)keyptr->count) << (32 - HASH_BITS);
  90058. +
  90059. + seq += ktime_to_ns(ktime_get_real());
  90060. + seq &= (1ull << 48) - 1;
  90061. +
  90062. + return seq;
  90063. +}
  90064. +EXPORT_SYMBOL(secure_dccp_sequence_number);
  90065. +#endif
  90066. +
  90067. +#endif /* CONFIG_INET */
  90068. +
  90069. +
  90070. +/*
  90071. + * Get a random word for internal kernel use only. Similar to urandom but
  90072. + * with the goal of minimal entropy pool depletion. As a result, the random
  90073. + * value is not cryptographically secure but for several uses the cost of
  90074. + * depleting entropy is too high
  90075. + */
  90076. +DEFINE_PER_CPU(__u32 [4], get_random_int_hash);
  90077. +unsigned int get_random_int(void)
  90078. +{
  90079. + struct keydata *keyptr;
  90080. + __u32 *hash = get_cpu_var(get_random_int_hash);
  90081. + int ret;
  90082. +
  90083. + keyptr = get_keyptr();
  90084. + hash[0] += current->pid + jiffies + get_cycles();
  90085. +
  90086. + ret = half_md4_transform(hash, keyptr->secret);
  90087. + put_cpu_var(get_random_int_hash);
  90088. +
  90089. + return ret;
  90090. +}
  90091. +
  90092. +/*
  90093. + * randomize_range() returns a start address such that
  90094. + *
  90095. + * [...... <range> .....]
  90096. + * start end
  90097. + *
  90098. + * a <range> with size "len" starting at the return value is inside in the
  90099. + * area defined by [start, end], but is otherwise randomized.
  90100. + */
  90101. +unsigned long
  90102. +randomize_range(unsigned long start, unsigned long end, unsigned long len)
  90103. +{
  90104. + unsigned long range = end - len - start;
  90105. +
  90106. + if (end <= start + len)
  90107. + return 0;
  90108. + return PAGE_ALIGN(get_random_int() % range + start);
  90109. +}
  90110. diff -Nur linux-2.6.39.orig/fs/fcntl.c linux-2.6.39/fs/fcntl.c
  90111. --- linux-2.6.39.orig/fs/fcntl.c 2011-05-19 06:06:34.000000000 +0200
  90112. +++ linux-2.6.39/fs/fcntl.c 2011-07-31 11:32:03.933651501 +0200
  90113. @@ -142,6 +142,7 @@
  90114. }
  90115. return ret;
  90116. }
  90117. +EXPORT_SYMBOL(sys_dup);
  90118. #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
  90119. diff -Nur linux-2.6.39.orig/include/linux/miscdevice.h linux-2.6.39/include/linux/miscdevice.h
  90120. --- linux-2.6.39.orig/include/linux/miscdevice.h 2011-05-19 06:06:34.000000000 +0200
  90121. +++ linux-2.6.39/include/linux/miscdevice.h 2011-07-31 11:32:04.003425404 +0200
  90122. @@ -18,6 +18,7 @@
  90123. #define APOLLO_MOUSE_MINOR 7
  90124. #define PC110PAD_MINOR 9
  90125. /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
  90126. +#define CRYPTODEV_MINOR 70 /* /dev/crypto */
  90127. #define WATCHDOG_MINOR 130 /* Watchdog timer */
  90128. #define TEMP_MINOR 131 /* Temperature Sensor */
  90129. #define RTC_MINOR 135
  90130. diff -Nur linux-2.6.39.orig/include/linux/random.h linux-2.6.39/include/linux/random.h
  90131. --- linux-2.6.39.orig/include/linux/random.h 2011-05-19 06:06:34.000000000 +0200
  90132. +++ linux-2.6.39/include/linux/random.h 2011-07-31 11:32:04.053424915 +0200
  90133. @@ -9,6 +9,7 @@
  90134. #include <linux/types.h>
  90135. #include <linux/ioctl.h>
  90136. +#include <linux/types.h> /* for __u32 in user space */
  90137. #include <linux/irqnr.h>
  90138. /* ioctl()'s for the random number generator */
  90139. @@ -34,6 +35,30 @@
  90140. /* Clear the entropy pool and associated counters. (Superuser only.) */
  90141. #define RNDCLEARPOOL _IO( 'R', 0x06 )
  90142. +#ifdef CONFIG_FIPS_RNG
  90143. +
  90144. +/* Size of seed value - equal to AES blocksize */
  90145. +#define AES_BLOCK_SIZE_BYTES 16
  90146. +#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
  90147. +/* Size of AES key */
  90148. +#define KEY_SIZE_BYTES 16
  90149. +
  90150. +/* ioctl() structure used by FIPS 140-2 Tests */
  90151. +struct rand_fips_test {
  90152. + unsigned char key[KEY_SIZE_BYTES]; /* Input */
  90153. + unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
  90154. + unsigned char seed[SEED_SIZE_BYTES]; /* Input */
  90155. + unsigned char result[SEED_SIZE_BYTES]; /* Output */
  90156. +};
  90157. +
  90158. +/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
  90159. +#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
  90160. +
  90161. +/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
  90162. +#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
  90163. +
  90164. +#endif /* #ifdef CONFIG_FIPS_RNG */
  90165. +
  90166. struct rand_pool_info {
  90167. int entropy_count;
  90168. int buf_size;
  90169. @@ -54,6 +79,10 @@
  90170. unsigned int value);
  90171. extern void add_interrupt_randomness(int irq);
  90172. +extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
  90173. +extern int random_input_wait(void);
  90174. +#define HAS_RANDOM_INPUT_WAIT 1
  90175. +
  90176. extern void get_random_bytes(void *buf, int nbytes);
  90177. void generate_random_uuid(unsigned char uuid_out[16]);