ocf-20100325.patch 2.9 MB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048350493505035051350523505335054350553505635057350583505935060350613506235063350643506535066350673506835069350703507135072350733507435075350763507735078350793508035081350823508335084350853508635087350883508935090350913509235093350943509535096350973509835099351003510135102351033510435105351063510735108351093511035111351123511335114351153511635117351183511935120351213512235123351243512535126351273512835129351303513135132351333513435135351363513735138351393514035141351423514335144351453514635147351483514935150351513515235153351543515535156351573515835159351603516135162351633516435165351663516735168351693517035171351723517335174351753517635177351783517935180351813518235183351843518535186351873518835189351903519135192351933519435195351963519735198351993520035201352023520335204352053520635207352083520935210352113521235213352143521535216352173521835219352203522135222352233522435225352263522735228352293523035231352323523335234352353523635237352383523935240352413524235243352443524535246352473524835249352503525135252352533525435255352563525735258352593526035261352623526335264352653526635267352683526935270352713527235273352743527535276352773527835279352803528135282352833528435285352863528735288352893529035291352923529335294352953529635297352983529935300353013530235303353043530535306353073530835309353103531135312353133531435315353163531735318353193532035321353223532335324353253532635327353283532935330353313533235333353343533535336353373533835339353403534135342353433534435345353463534735348353493535035351353523535335354353553535635357353583535935360353613536235363353643536535366353673536835369353703537135372353733537435375353763537735378353793538035381353823538335384353853538635387353883538935390353913539235393353943539535396353973539835399354003540135402354033540435405354063540735408354093541035411354123541335414354153541635417354183541935420354213542235423354243542535426354273542835429354303543135432354333543435435354363543735438354393544035441354423544335444354453544635447354483544935450354513545235453354543545535456354573545835459354603546135462354633546435465354663546735468354693547035471354723547335474354753547635477354783547935480354813548235483354843548535486354873548835489354903549135492354933549435495354963549735498354993550035501355023550335504355053550635507355083550935510355113551235513355143551535516355173551835519355203552135522355233552435525355263552735528355293553035531355323553335534355353553635537355383553935540355413554235543355443554535546355473554835549355503555135552355533555435555355563555735558355593556035561355623556335564355653556635567355683556935570355713557235573355743557535576355773557835579355803558135582355833558435585355863558735588355893559035591355923559335594355953559635597355983559935600356013560235603356043560535606356073560835609356103561135612356133561435615356163561735618356193562035621356223562335624356253562635627356283562935630356313563235633356343563535636356373563835639356403564135642356433564435645356463564735648356493565035651356523565335654356553565635657356583565935660356613566235663356643566535666356673566835669356703567135672356733567435675356763567735678356793568035681356823568335684356853568635687356883568935690356913569235693356943569535696356973569835699357003570135702357033570435705357063570735708357093571035711357123571335714357153571635717357183571935720357213572235723357243572535726357273572835729357303573135732357333573435735357363573735738357393574035741357423574335744357453574635747357483574935750357513575235753357543575535756357573575835759357603576135762357633576435765357663576735768357693577035771357723577335774357753577635777357783577935780357813578235783357843578535786357873578835789357903579135792357933579435795357963579735798357993580035801358023580335804358053580635807358083580935810358113581235813358143581535816358173581835819358203582135822358233582435825358263582735828358293583035831358323583335834358353583635837358383583935840358413584235843358443584535846358473584835849358503585135852358533585435855358563585735858358593586035861358623586335864358653586635867358683586935870358713587235873358743587535876358773587835879358803588135882358833588435885358863588735888358893589035891358923589335894358953589635897358983589935900359013590235903359043590535906359073590835909359103591135912359133591435915359163591735918359193592035921359223592335924359253592635927359283592935930359313593235933359343593535936359373593835939359403594135942359433594435945359463594735948359493595035951359523595335954359553595635957359583595935960359613596235963359643596535966359673596835969359703597135972359733597435975359763597735978359793598035981359823598335984359853598635987359883598935990359913599235993359943599535996359973599835999360003600136002360033600436005360063600736008360093601036011360123601336014360153601636017360183601936020360213602236023360243602536026360273602836029360303603136032360333603436035360363603736038360393604036041360423604336044360453604636047360483604936050360513605236053360543605536056360573605836059360603606136062360633606436065360663606736068360693607036071360723607336074360753607636077360783607936080360813608236083360843608536086360873608836089360903609136092360933609436095360963609736098360993610036101361023610336104361053610636107361083610936110361113611236113361143611536116361173611836119361203612136122361233612436125361263612736128361293613036131361323613336134361353613636137361383613936140361413614236143361443614536146361473614836149361503615136152361533615436155361563615736158361593616036161361623616336164361653616636167361683616936170361713617236173361743617536176361773617836179361803618136182361833618436185361863618736188361893619036191361923619336194361953619636197361983619936200362013620236203362043620536206362073620836209362103621136212362133621436215362163621736218362193622036221362223622336224362253622636227362283622936230362313623236233362343623536236362373623836239362403624136242362433624436245362463624736248362493625036251362523625336254362553625636257362583625936260362613626236263362643626536266362673626836269362703627136272362733627436275362763627736278362793628036281362823628336284362853628636287362883628936290362913629236293362943629536296362973629836299363003630136302363033630436305363063630736308363093631036311363123631336314363153631636317363183631936320363213632236323363243632536326363273632836329363303633136332363333633436335363363633736338363393634036341363423634336344363453634636347363483634936350363513635236353363543635536356363573635836359363603636136362363633636436365363663636736368363693637036371363723637336374363753637636377363783637936380363813638236383363843638536386363873638836389363903639136392363933639436395363963639736398363993640036401364023640336404364053640636407364083640936410364113641236413364143641536416364173641836419364203642136422364233642436425364263642736428364293643036431364323643336434364353643636437364383643936440364413644236443364443644536446364473644836449364503645136452364533645436455364563645736458364593646036461364623646336464364653646636467364683646936470364713647236473364743647536476364773647836479364803648136482364833648436485364863648736488364893649036491364923649336494364953649636497364983649936500365013650236503365043650536506365073650836509365103651136512365133651436515365163651736518365193652036521365223652336524365253652636527365283652936530365313653236533365343653536536365373653836539365403654136542365433654436545365463654736548365493655036551365523655336554365553655636557365583655936560365613656236563365643656536566365673656836569365703657136572365733657436575365763657736578365793658036581365823658336584365853658636587365883658936590365913659236593365943659536596365973659836599366003660136602366033660436605366063660736608366093661036611366123661336614366153661636617366183661936620366213662236623366243662536626366273662836629366303663136632366333663436635366363663736638366393664036641366423664336644366453664636647366483664936650366513665236653366543665536656366573665836659366603666136662366633666436665366663666736668366693667036671366723667336674366753667636677366783667936680366813668236683366843668536686366873668836689366903669136692366933669436695366963669736698366993670036701367023670336704367053670636707367083670936710367113671236713367143671536716367173671836719367203672136722367233672436725367263672736728367293673036731367323673336734367353673636737367383673936740367413674236743367443674536746367473674836749367503675136752367533675436755367563675736758367593676036761367623676336764367653676636767367683676936770367713677236773367743677536776367773677836779367803678136782367833678436785367863678736788367893679036791367923679336794367953679636797367983679936800368013680236803368043680536806368073680836809368103681136812368133681436815368163681736818368193682036821368223682336824368253682636827368283682936830368313683236833368343683536836368373683836839368403684136842368433684436845368463684736848368493685036851368523685336854368553685636857368583685936860368613686236863368643686536866368673686836869368703687136872368733687436875368763687736878368793688036881368823688336884368853688636887368883688936890368913689236893368943689536896368973689836899369003690136902369033690436905369063690736908369093691036911369123691336914369153691636917369183691936920369213692236923369243692536926369273692836929369303693136932369333693436935369363693736938369393694036941369423694336944369453694636947369483694936950369513695236953369543695536956369573695836959369603696136962369633696436965369663696736968369693697036971369723697336974369753697636977369783697936980369813698236983369843698536986369873698836989369903699136992369933699436995369963699736998369993700037001370023700337004370053700637007370083700937010370113701237013370143701537016370173701837019370203702137022370233702437025370263702737028370293703037031370323703337034370353703637037370383703937040370413704237043370443704537046370473704837049370503705137052370533705437055370563705737058370593706037061370623706337064370653706637067370683706937070370713707237073370743707537076370773707837079370803708137082370833708437085370863708737088370893709037091370923709337094370953709637097370983709937100371013710237103371043710537106371073710837109371103711137112371133711437115371163711737118371193712037121371223712337124371253712637127371283712937130371313713237133371343713537136371373713837139371403714137142371433714437145371463714737148371493715037151371523715337154371553715637157371583715937160371613716237163371643716537166371673716837169371703717137172371733717437175371763717737178371793718037181371823718337184371853718637187371883718937190371913719237193371943719537196371973719837199372003720137202372033720437205372063720737208372093721037211372123721337214372153721637217372183721937220372213722237223372243722537226372273722837229372303723137232372333723437235372363723737238372393724037241372423724337244372453724637247372483724937250372513725237253372543725537256372573725837259372603726137262372633726437265372663726737268372693727037271372723727337274372753727637277372783727937280372813728237283372843728537286372873728837289372903729137292372933729437295372963729737298372993730037301373023730337304373053730637307373083730937310373113731237313373143731537316373173731837319373203732137322373233732437325373263732737328373293733037331373323733337334373353733637337373383733937340373413734237343373443734537346373473734837349373503735137352373533735437355373563735737358373593736037361373623736337364373653736637367373683736937370373713737237373373743737537376373773737837379373803738137382373833738437385373863738737388373893739037391373923739337394373953739637397373983739937400374013740237403374043740537406374073740837409374103741137412374133741437415374163741737418374193742037421374223742337424374253742637427374283742937430374313743237433374343743537436374373743837439374403744137442374433744437445374463744737448374493745037451374523745337454374553745637457374583745937460374613746237463374643746537466374673746837469374703747137472374733747437475374763747737478374793748037481374823748337484374853748637487374883748937490374913749237493374943749537496374973749837499375003750137502375033750437505375063750737508375093751037511375123751337514375153751637517375183751937520375213752237523375243752537526375273752837529375303753137532375333753437535375363753737538375393754037541375423754337544375453754637547375483754937550375513755237553375543755537556375573755837559375603756137562375633756437565375663756737568375693757037571375723757337574375753757637577375783757937580375813758237583375843758537586375873758837589375903759137592375933759437595375963759737598375993760037601376023760337604376053760637607376083760937610376113761237613376143761537616376173761837619376203762137622376233762437625376263762737628376293763037631376323763337634376353763637637376383763937640376413764237643376443764537646376473764837649376503765137652376533765437655376563765737658376593766037661376623766337664376653766637667376683766937670376713767237673376743767537676376773767837679376803768137682376833768437685376863768737688376893769037691376923769337694376953769637697376983769937700377013770237703377043770537706377073770837709377103771137712377133771437715377163771737718377193772037721377223772337724377253772637727377283772937730377313773237733377343773537736377373773837739377403774137742377433774437745377463774737748377493775037751377523775337754377553775637757377583775937760377613776237763377643776537766377673776837769377703777137772377733777437775377763777737778377793778037781377823778337784377853778637787377883778937790377913779237793377943779537796377973779837799378003780137802378033780437805378063780737808378093781037811378123781337814378153781637817378183781937820378213782237823378243782537826378273782837829378303783137832378333783437835378363783737838378393784037841378423784337844378453784637847378483784937850378513785237853378543785537856378573785837859378603786137862378633786437865378663786737868378693787037871378723787337874378753787637877378783787937880378813788237883378843788537886378873788837889378903789137892378933789437895378963789737898378993790037901379023790337904379053790637907379083790937910379113791237913379143791537916379173791837919379203792137922379233792437925379263792737928379293793037931379323793337934379353793637937379383793937940379413794237943379443794537946379473794837949379503795137952379533795437955379563795737958379593796037961379623796337964379653796637967379683796937970379713797237973379743797537976379773797837979379803798137982379833798437985379863798737988379893799037991379923799337994379953799637997379983799938000380013800238003380043800538006380073800838009380103801138012380133801438015380163801738018380193802038021380223802338024380253802638027380283802938030380313803238033380343803538036380373803838039380403804138042380433804438045380463804738048380493805038051380523805338054380553805638057380583805938060380613806238063380643806538066380673806838069380703807138072380733807438075380763807738078380793808038081380823808338084380853808638087380883808938090380913809238093380943809538096380973809838099381003810138102381033810438105381063810738108381093811038111381123811338114381153811638117381183811938120381213812238123381243812538126381273812838129381303813138132381333813438135381363813738138381393814038141381423814338144381453814638147381483814938150381513815238153381543815538156381573815838159381603816138162381633816438165381663816738168381693817038171381723817338174381753817638177381783817938180381813818238183381843818538186381873818838189381903819138192381933819438195381963819738198381993820038201382023820338204382053820638207382083820938210382113821238213382143821538216382173821838219382203822138222382233822438225382263822738228382293823038231382323823338234382353823638237382383823938240382413824238243382443824538246382473824838249382503825138252382533825438255382563825738258382593826038261382623826338264382653826638267382683826938270382713827238273382743827538276382773827838279382803828138282382833828438285382863828738288382893829038291382923829338294382953829638297382983829938300383013830238303383043830538306383073830838309383103831138312383133831438315383163831738318383193832038321383223832338324383253832638327383283832938330383313833238333383343833538336383373833838339383403834138342383433834438345383463834738348383493835038351383523835338354383553835638357383583835938360383613836238363383643836538366383673836838369383703837138372383733837438375383763837738378383793838038381383823838338384383853838638387383883838938390383913839238393383943839538396383973839838399384003840138402384033840438405384063840738408384093841038411384123841338414384153841638417384183841938420384213842238423384243842538426384273842838429384303843138432384333843438435384363843738438384393844038441384423844338444384453844638447384483844938450384513845238453384543845538456384573845838459384603846138462384633846438465384663846738468384693847038471384723847338474384753847638477384783847938480384813848238483384843848538486384873848838489384903849138492384933849438495384963849738498384993850038501385023850338504385053850638507385083850938510385113851238513385143851538516385173851838519385203852138522385233852438525385263852738528385293853038531385323853338534385353853638537385383853938540385413854238543385443854538546385473854838549385503855138552385533855438555385563855738558385593856038561385623856338564385653856638567385683856938570385713857238573385743857538576385773857838579385803858138582385833858438585385863858738588385893859038591385923859338594385953859638597385983859938600386013860238603386043860538606386073860838609386103861138612386133861438615386163861738618386193862038621386223862338624386253862638627386283862938630386313863238633386343863538636386373863838639386403864138642386433864438645386463864738648386493865038651386523865338654386553865638657386583865938660386613866238663386643866538666386673866838669386703867138672386733867438675386763867738678386793868038681386823868338684386853868638687386883868938690386913869238693386943869538696386973869838699387003870138702387033870438705387063870738708387093871038711387123871338714387153871638717387183871938720387213872238723387243872538726387273872838729387303873138732387333873438735387363873738738387393874038741387423874338744387453874638747387483874938750387513875238753387543875538756387573875838759387603876138762387633876438765387663876738768387693877038771387723877338774387753877638777387783877938780387813878238783387843878538786387873878838789387903879138792387933879438795387963879738798387993880038801388023880338804388053880638807388083880938810388113881238813388143881538816388173881838819388203882138822388233882438825388263882738828388293883038831388323883338834388353883638837388383883938840388413884238843388443884538846388473884838849388503885138852388533885438855388563885738858388593886038861388623886338864388653886638867388683886938870388713887238873388743887538876388773887838879388803888138882388833888438885388863888738888388893889038891388923889338894388953889638897388983889938900389013890238903389043890538906389073890838909389103891138912389133891438915389163891738918389193892038921389223892338924389253892638927389283892938930389313893238933389343893538936389373893838939389403894138942389433894438945389463894738948389493895038951389523895338954389553895638957389583895938960389613896238963389643896538966389673896838969389703897138972389733897438975389763897738978389793898038981389823898338984389853898638987389883898938990389913899238993389943899538996389973899838999390003900139002390033900439005390063900739008390093901039011390123901339014390153901639017390183901939020390213902239023390243902539026390273902839029390303903139032390333903439035390363903739038390393904039041390423904339044390453904639047390483904939050390513905239053390543905539056390573905839059390603906139062390633906439065390663906739068390693907039071390723907339074390753907639077390783907939080390813908239083390843908539086390873908839089390903909139092390933909439095390963909739098390993910039101391023910339104391053910639107391083910939110391113911239113391143911539116391173911839119391203912139122391233912439125391263912739128391293913039131391323913339134391353913639137391383913939140391413914239143391443914539146391473914839149391503915139152391533915439155391563915739158391593916039161391623916339164391653916639167391683916939170391713917239173391743917539176391773917839179391803918139182391833918439185391863918739188391893919039191391923919339194391953919639197391983919939200392013920239203392043920539206392073920839209392103921139212392133921439215392163921739218392193922039221392223922339224392253922639227392283922939230392313923239233392343923539236392373923839239392403924139242392433924439245392463924739248392493925039251392523925339254392553925639257392583925939260392613926239263392643926539266392673926839269392703927139272392733927439275392763927739278392793928039281392823928339284392853928639287392883928939290392913929239293392943929539296392973929839299393003930139302393033930439305393063930739308393093931039311393123931339314393153931639317393183931939320393213932239323393243932539326393273932839329393303933139332393333933439335393363933739338393393934039341393423934339344393453934639347393483934939350393513935239353393543935539356393573935839359393603936139362393633936439365393663936739368393693937039371393723937339374393753937639377393783937939380393813938239383393843938539386393873938839389393903939139392393933939439395393963939739398393993940039401394023940339404394053940639407394083940939410394113941239413394143941539416394173941839419394203942139422394233942439425394263942739428394293943039431394323943339434394353943639437394383943939440394413944239443394443944539446394473944839449394503945139452394533945439455394563945739458394593946039461394623946339464394653946639467394683946939470394713947239473394743947539476394773947839479394803948139482394833948439485394863948739488394893949039491394923949339494394953949639497394983949939500395013950239503395043950539506395073950839509395103951139512395133951439515395163951739518395193952039521395223952339524395253952639527395283952939530395313953239533395343953539536395373953839539395403954139542395433954439545395463954739548395493955039551395523955339554395553955639557395583955939560395613956239563395643956539566395673956839569395703957139572395733957439575395763957739578395793958039581395823958339584395853958639587395883958939590395913959239593395943959539596395973959839599396003960139602396033960439605396063960739608396093961039611396123961339614396153961639617396183961939620396213962239623396243962539626396273962839629396303963139632396333963439635396363963739638396393964039641396423964339644396453964639647396483964939650396513965239653396543965539656396573965839659396603966139662396633966439665396663966739668396693967039671396723967339674396753967639677396783967939680396813968239683396843968539686396873968839689396903969139692396933969439695396963969739698396993970039701397023970339704397053970639707397083970939710397113971239713397143971539716397173971839719397203972139722397233972439725397263972739728397293973039731397323973339734397353973639737397383973939740397413974239743397443974539746397473974839749397503975139752397533975439755397563975739758397593976039761397623976339764397653976639767397683976939770397713977239773397743977539776397773977839779397803978139782397833978439785397863978739788397893979039791397923979339794397953979639797397983979939800398013980239803398043980539806398073980839809398103981139812398133981439815398163981739818398193982039821398223982339824398253982639827398283982939830398313983239833398343983539836398373983839839398403984139842398433984439845398463984739848398493985039851398523985339854398553985639857398583985939860398613986239863398643986539866398673986839869398703987139872398733987439875398763987739878398793988039881398823988339884398853988639887398883988939890398913989239893398943989539896398973989839899399003990139902399033990439905399063990739908399093991039911399123991339914399153991639917399183991939920399213992239923399243992539926399273992839929399303993139932399333993439935399363993739938399393994039941399423994339944399453994639947399483994939950399513995239953399543995539956399573995839959399603996139962399633996439965399663996739968399693997039971399723997339974399753997639977399783997939980399813998239983399843998539986399873998839989399903999139992399933999439995399963999739998399994000040001400024000340004400054000640007400084000940010400114001240013400144001540016400174001840019400204002140022400234002440025400264002740028400294003040031400324003340034400354003640037400384003940040400414004240043400444004540046400474004840049400504005140052400534005440055400564005740058400594006040061400624006340064400654006640067400684006940070400714007240073400744007540076400774007840079400804008140082400834008440085400864008740088400894009040091400924009340094400954009640097400984009940100401014010240103401044010540106401074010840109401104011140112401134011440115401164011740118401194012040121401224012340124401254012640127401284012940130401314013240133401344013540136401374013840139401404014140142401434014440145401464014740148401494015040151401524015340154401554015640157401584015940160401614016240163401644016540166401674016840169401704017140172401734017440175401764017740178401794018040181401824018340184401854018640187401884018940190401914019240193401944019540196401974019840199402004020140202402034020440205402064020740208402094021040211402124021340214402154021640217402184021940220402214022240223402244022540226402274022840229402304023140232402334023440235402364023740238402394024040241402424024340244402454024640247402484024940250402514025240253402544025540256402574025840259402604026140262402634026440265402664026740268402694027040271402724027340274402754027640277402784027940280402814028240283402844028540286402874028840289402904029140292402934029440295402964029740298402994030040301403024030340304403054030640307403084030940310403114031240313403144031540316403174031840319403204032140322403234032440325403264032740328403294033040331403324033340334403354033640337403384033940340403414034240343403444034540346403474034840349403504035140352403534035440355403564035740358403594036040361403624036340364403654036640367403684036940370403714037240373403744037540376403774037840379403804038140382403834038440385403864038740388403894039040391403924039340394403954039640397403984039940400404014040240403404044040540406404074040840409404104041140412404134041440415404164041740418404194042040421404224042340424404254042640427404284042940430404314043240433404344043540436404374043840439404404044140442404434044440445404464044740448404494045040451404524045340454404554045640457404584045940460404614046240463404644046540466404674046840469404704047140472404734047440475404764047740478404794048040481404824048340484404854048640487404884048940490404914049240493404944049540496404974049840499405004050140502405034050440505405064050740508405094051040511405124051340514405154051640517405184051940520405214052240523405244052540526405274052840529405304053140532405334053440535405364053740538405394054040541405424054340544405454054640547405484054940550405514055240553405544055540556405574055840559405604056140562405634056440565405664056740568405694057040571405724057340574405754057640577405784057940580405814058240583405844058540586405874058840589405904059140592405934059440595405964059740598405994060040601406024060340604406054060640607406084060940610406114061240613406144061540616406174061840619406204062140622406234062440625406264062740628406294063040631406324063340634406354063640637406384063940640406414064240643406444064540646406474064840649406504065140652406534065440655406564065740658406594066040661406624066340664406654066640667406684066940670406714067240673406744067540676406774067840679406804068140682406834068440685406864068740688406894069040691406924069340694406954069640697406984069940700407014070240703407044070540706407074070840709407104071140712407134071440715407164071740718407194072040721407224072340724407254072640727407284072940730407314073240733407344073540736407374073840739407404074140742407434074440745407464074740748407494075040751407524075340754407554075640757407584075940760407614076240763407644076540766407674076840769407704077140772407734077440775407764077740778407794078040781407824078340784407854078640787407884078940790407914079240793407944079540796407974079840799408004080140802408034080440805408064080740808408094081040811408124081340814408154081640817408184081940820408214082240823408244082540826408274082840829408304083140832408334083440835408364083740838408394084040841408424084340844408454084640847408484084940850408514085240853408544085540856408574085840859408604086140862408634086440865408664086740868408694087040871408724087340874408754087640877408784087940880408814088240883408844088540886408874088840889408904089140892408934089440895408964089740898408994090040901409024090340904409054090640907409084090940910409114091240913409144091540916409174091840919409204092140922409234092440925409264092740928409294093040931409324093340934409354093640937409384093940940409414094240943409444094540946409474094840949409504095140952409534095440955409564095740958409594096040961409624096340964409654096640967409684096940970409714097240973409744097540976409774097840979409804098140982409834098440985409864098740988409894099040991409924099340994409954099640997409984099941000410014100241003410044100541006410074100841009410104101141012410134101441015410164101741018410194102041021410224102341024410254102641027410284102941030410314103241033410344103541036410374103841039410404104141042410434104441045410464104741048410494105041051410524105341054410554105641057410584105941060410614106241063410644106541066410674106841069410704107141072410734107441075410764107741078410794108041081410824108341084410854108641087410884108941090410914109241093410944109541096410974109841099411004110141102411034110441105411064110741108411094111041111411124111341114411154111641117411184111941120411214112241123411244112541126411274112841129411304113141132411334113441135411364113741138411394114041141411424114341144411454114641147411484114941150411514115241153411544115541156411574115841159411604116141162411634116441165411664116741168411694117041171411724117341174411754117641177411784117941180411814118241183411844118541186411874118841189411904119141192411934119441195411964119741198411994120041201412024120341204412054120641207412084120941210412114121241213412144121541216412174121841219412204122141222412234122441225412264122741228412294123041231412324123341234412354123641237412384123941240412414124241243412444124541246412474124841249412504125141252412534125441255412564125741258412594126041261412624126341264412654126641267412684126941270412714127241273412744127541276412774127841279412804128141282412834128441285412864128741288412894129041291412924129341294412954129641297412984129941300413014130241303413044130541306413074130841309413104131141312413134131441315413164131741318413194132041321413224132341324413254132641327413284132941330413314133241333413344133541336413374133841339413404134141342413434134441345413464134741348413494135041351413524135341354413554135641357413584135941360413614136241363413644136541366413674136841369413704137141372413734137441375413764137741378413794138041381413824138341384413854138641387413884138941390413914139241393413944139541396413974139841399414004140141402414034140441405414064140741408414094141041411414124141341414414154141641417414184141941420414214142241423414244142541426414274142841429414304143141432414334143441435414364143741438414394144041441414424144341444414454144641447414484144941450414514145241453414544145541456414574145841459414604146141462414634146441465414664146741468414694147041471414724147341474414754147641477414784147941480414814148241483414844148541486414874148841489414904149141492414934149441495414964149741498414994150041501415024150341504415054150641507415084150941510415114151241513415144151541516415174151841519415204152141522415234152441525415264152741528415294153041531415324153341534415354153641537415384153941540415414154241543415444154541546415474154841549415504155141552415534155441555415564155741558415594156041561415624156341564415654156641567415684156941570415714157241573415744157541576415774157841579415804158141582415834158441585415864158741588415894159041591415924159341594415954159641597415984159941600416014160241603416044160541606416074160841609416104161141612416134161441615416164161741618416194162041621416224162341624416254162641627416284162941630416314163241633416344163541636416374163841639416404164141642416434164441645416464164741648416494165041651416524165341654416554165641657416584165941660416614166241663416644166541666416674166841669416704167141672416734167441675416764167741678416794168041681416824168341684416854168641687416884168941690416914169241693416944169541696416974169841699417004170141702417034170441705417064170741708417094171041711417124171341714417154171641717417184171941720417214172241723417244172541726417274172841729417304173141732417334173441735417364173741738417394174041741417424174341744417454174641747417484174941750417514175241753417544175541756417574175841759417604176141762417634176441765417664176741768417694177041771417724177341774417754177641777417784177941780417814178241783417844178541786417874178841789417904179141792417934179441795417964179741798417994180041801418024180341804418054180641807418084180941810418114181241813418144181541816418174181841819418204182141822418234182441825418264182741828418294183041831418324183341834418354183641837418384183941840418414184241843418444184541846418474184841849418504185141852418534185441855418564185741858418594186041861418624186341864418654186641867418684186941870418714187241873418744187541876418774187841879418804188141882418834188441885418864188741888418894189041891418924189341894418954189641897418984189941900419014190241903419044190541906419074190841909419104191141912419134191441915419164191741918419194192041921419224192341924419254192641927419284192941930419314193241933419344193541936419374193841939419404194141942419434194441945419464194741948419494195041951419524195341954419554195641957419584195941960419614196241963419644196541966419674196841969419704197141972419734197441975419764197741978419794198041981419824198341984419854198641987419884198941990419914199241993419944199541996419974199841999420004200142002420034200442005420064200742008420094201042011420124201342014420154201642017420184201942020420214202242023420244202542026420274202842029420304203142032420334203442035420364203742038420394204042041420424204342044420454204642047420484204942050420514205242053420544205542056420574205842059420604206142062420634206442065420664206742068420694207042071420724207342074420754207642077420784207942080420814208242083420844208542086420874208842089420904209142092420934209442095420964209742098420994210042101421024210342104421054210642107421084210942110421114211242113421144211542116421174211842119421204212142122421234212442125421264212742128421294213042131421324213342134421354213642137421384213942140421414214242143421444214542146421474214842149421504215142152421534215442155421564215742158421594216042161421624216342164421654216642167421684216942170421714217242173421744217542176421774217842179421804218142182421834218442185421864218742188421894219042191421924219342194421954219642197421984219942200422014220242203422044220542206422074220842209422104221142212422134221442215422164221742218422194222042221422224222342224422254222642227422284222942230422314223242233422344223542236422374223842239422404224142242422434224442245422464224742248422494225042251422524225342254422554225642257422584225942260422614226242263422644226542266422674226842269422704227142272422734227442275422764227742278422794228042281422824228342284422854228642287422884228942290422914229242293422944229542296422974229842299423004230142302423034230442305423064230742308423094231042311423124231342314423154231642317423184231942320423214232242323423244232542326423274232842329423304233142332423334233442335423364233742338423394234042341423424234342344423454234642347423484234942350423514235242353423544235542356423574235842359423604236142362423634236442365423664236742368423694237042371423724237342374423754237642377423784237942380423814238242383423844238542386423874238842389423904239142392423934239442395423964239742398423994240042401424024240342404424054240642407424084240942410424114241242413424144241542416424174241842419424204242142422424234242442425424264242742428424294243042431424324243342434424354243642437424384243942440424414244242443424444244542446424474244842449424504245142452424534245442455424564245742458424594246042461424624246342464424654246642467424684246942470424714247242473424744247542476424774247842479424804248142482424834248442485424864248742488424894249042491424924249342494424954249642497424984249942500425014250242503425044250542506425074250842509425104251142512425134251442515425164251742518425194252042521425224252342524425254252642527425284252942530425314253242533425344253542536425374253842539425404254142542425434254442545425464254742548425494255042551425524255342554425554255642557425584255942560425614256242563425644256542566425674256842569425704257142572425734257442575425764257742578425794258042581425824258342584425854258642587425884258942590425914259242593425944259542596425974259842599426004260142602426034260442605426064260742608426094261042611426124261342614426154261642617426184261942620426214262242623426244262542626426274262842629426304263142632426334263442635426364263742638426394264042641426424264342644426454264642647426484264942650426514265242653426544265542656426574265842659426604266142662426634266442665426664266742668426694267042671426724267342674426754267642677426784267942680426814268242683426844268542686426874268842689426904269142692426934269442695426964269742698426994270042701427024270342704427054270642707427084270942710427114271242713427144271542716427174271842719427204272142722427234272442725427264272742728427294273042731427324273342734427354273642737427384273942740427414274242743427444274542746427474274842749427504275142752427534275442755427564275742758427594276042761427624276342764427654276642767427684276942770427714277242773427744277542776427774277842779427804278142782427834278442785427864278742788427894279042791427924279342794427954279642797427984279942800428014280242803428044280542806428074280842809428104281142812428134281442815428164281742818428194282042821428224282342824428254282642827428284282942830428314283242833428344283542836428374283842839428404284142842428434284442845428464284742848428494285042851428524285342854428554285642857428584285942860428614286242863428644286542866428674286842869428704287142872428734287442875428764287742878428794288042881428824288342884428854288642887428884288942890428914289242893428944289542896428974289842899429004290142902429034290442905429064290742908429094291042911429124291342914429154291642917429184291942920429214292242923429244292542926429274292842929429304293142932429334293442935429364293742938429394294042941429424294342944429454294642947429484294942950429514295242953429544295542956429574295842959429604296142962429634296442965429664296742968429694297042971429724297342974429754297642977429784297942980429814298242983429844298542986429874298842989429904299142992429934299442995429964299742998429994300043001430024300343004430054300643007430084300943010430114301243013430144301543016430174301843019430204302143022430234302443025430264302743028430294303043031430324303343034430354303643037430384303943040430414304243043430444304543046430474304843049430504305143052430534305443055430564305743058430594306043061430624306343064430654306643067430684306943070430714307243073430744307543076430774307843079430804308143082430834308443085430864308743088430894309043091430924309343094430954309643097430984309943100431014310243103431044310543106431074310843109431104311143112431134311443115431164311743118431194312043121431224312343124431254312643127431284312943130431314313243133431344313543136431374313843139431404314143142431434314443145431464314743148431494315043151431524315343154431554315643157431584315943160431614316243163431644316543166431674316843169431704317143172431734317443175431764317743178431794318043181431824318343184431854318643187431884318943190431914319243193431944319543196431974319843199432004320143202432034320443205432064320743208432094321043211432124321343214432154321643217432184321943220432214322243223432244322543226432274322843229432304323143232432334323443235432364323743238432394324043241432424324343244432454324643247432484324943250432514325243253432544325543256432574325843259432604326143262432634326443265432664326743268432694327043271432724327343274432754327643277432784327943280432814328243283432844328543286432874328843289432904329143292432934329443295432964329743298432994330043301433024330343304433054330643307433084330943310433114331243313433144331543316433174331843319433204332143322433234332443325433264332743328433294333043331433324333343334433354333643337433384333943340433414334243343433444334543346433474334843349433504335143352433534335443355433564335743358433594336043361433624336343364433654336643367433684336943370433714337243373433744337543376433774337843379433804338143382433834338443385433864338743388433894339043391433924339343394433954339643397433984339943400434014340243403434044340543406434074340843409434104341143412434134341443415434164341743418434194342043421434224342343424434254342643427434284342943430434314343243433434344343543436434374343843439434404344143442434434344443445434464344743448434494345043451434524345343454434554345643457434584345943460434614346243463434644346543466434674346843469434704347143472434734347443475434764347743478434794348043481434824348343484434854348643487434884348943490434914349243493434944349543496434974349843499435004350143502435034350443505435064350743508435094351043511435124351343514435154351643517435184351943520435214352243523435244352543526435274352843529435304353143532435334353443535435364353743538435394354043541435424354343544435454354643547435484354943550435514355243553435544355543556435574355843559435604356143562435634356443565435664356743568435694357043571435724357343574435754357643577435784357943580435814358243583435844358543586435874358843589435904359143592435934359443595435964359743598435994360043601436024360343604436054360643607436084360943610436114361243613436144361543616436174361843619436204362143622436234362443625436264362743628436294363043631436324363343634436354363643637436384363943640436414364243643436444364543646436474364843649436504365143652436534365443655436564365743658436594366043661436624366343664436654366643667436684366943670436714367243673436744367543676436774367843679436804368143682436834368443685436864368743688436894369043691436924369343694436954369643697436984369943700437014370243703437044370543706437074370843709437104371143712437134371443715437164371743718437194372043721437224372343724437254372643727437284372943730437314373243733437344373543736437374373843739437404374143742437434374443745437464374743748437494375043751437524375343754437554375643757437584375943760437614376243763437644376543766437674376843769437704377143772437734377443775437764377743778437794378043781437824378343784437854378643787437884378943790437914379243793437944379543796437974379843799438004380143802438034380443805438064380743808438094381043811438124381343814438154381643817438184381943820438214382243823438244382543826438274382843829438304383143832438334383443835438364383743838438394384043841438424384343844438454384643847438484384943850438514385243853438544385543856438574385843859438604386143862438634386443865438664386743868438694387043871438724387343874438754387643877438784387943880438814388243883438844388543886438874388843889438904389143892438934389443895438964389743898438994390043901439024390343904439054390643907439084390943910439114391243913439144391543916439174391843919439204392143922439234392443925439264392743928439294393043931439324393343934439354393643937439384393943940439414394243943439444394543946439474394843949439504395143952439534395443955439564395743958439594396043961439624396343964439654396643967439684396943970439714397243973439744397543976439774397843979439804398143982439834398443985439864398743988439894399043991439924399343994439954399643997439984399944000440014400244003440044400544006440074400844009440104401144012440134401444015440164401744018440194402044021440224402344024440254402644027440284402944030440314403244033440344403544036440374403844039440404404144042440434404444045440464404744048440494405044051440524405344054440554405644057440584405944060440614406244063440644406544066440674406844069440704407144072440734407444075440764407744078440794408044081440824408344084440854408644087440884408944090440914409244093440944409544096440974409844099441004410144102441034410444105441064410744108441094411044111441124411344114441154411644117441184411944120441214412244123441244412544126441274412844129441304413144132441334413444135441364413744138441394414044141441424414344144441454414644147441484414944150441514415244153441544415544156441574415844159441604416144162441634416444165441664416744168441694417044171441724417344174441754417644177441784417944180441814418244183441844418544186441874418844189441904419144192441934419444195441964419744198441994420044201442024420344204442054420644207442084420944210442114421244213442144421544216442174421844219442204422144222442234422444225442264422744228442294423044231442324423344234442354423644237442384423944240442414424244243442444424544246442474424844249442504425144252442534425444255442564425744258442594426044261442624426344264442654426644267442684426944270442714427244273442744427544276442774427844279442804428144282442834428444285442864428744288442894429044291442924429344294442954429644297442984429944300443014430244303443044430544306443074430844309443104431144312443134431444315443164431744318443194432044321443224432344324443254432644327443284432944330443314433244333443344433544336443374433844339443404434144342443434434444345443464434744348443494435044351443524435344354443554435644357443584435944360443614436244363443644436544366443674436844369443704437144372443734437444375443764437744378443794438044381443824438344384443854438644387443884438944390443914439244393443944439544396443974439844399444004440144402444034440444405444064440744408444094441044411444124441344414444154441644417444184441944420444214442244423444244442544426444274442844429444304443144432444334443444435444364443744438444394444044441444424444344444444454444644447444484444944450444514445244453444544445544456444574445844459444604446144462444634446444465444664446744468444694447044471444724447344474444754447644477444784447944480444814448244483444844448544486444874448844489444904449144492444934449444495444964449744498444994450044501445024450344504445054450644507445084450944510445114451244513445144451544516445174451844519445204452144522445234452444525445264452744528445294453044531445324453344534445354453644537445384453944540445414454244543445444454544546445474454844549445504455144552445534455444555445564455744558445594456044561445624456344564445654456644567445684456944570445714457244573445744457544576445774457844579445804458144582445834458444585445864458744588445894459044591445924459344594445954459644597445984459944600446014460244603446044460544606446074460844609446104461144612446134461444615446164461744618446194462044621446224462344624446254462644627446284462944630446314463244633446344463544636446374463844639446404464144642446434464444645446464464744648446494465044651446524465344654446554465644657446584465944660446614466244663446644466544666446674466844669446704467144672446734467444675446764467744678446794468044681446824468344684446854468644687446884468944690446914469244693446944469544696446974469844699447004470144702447034470444705447064470744708447094471044711447124471344714447154471644717447184471944720447214472244723447244472544726447274472844729447304473144732447334473444735447364473744738447394474044741447424474344744447454474644747447484474944750447514475244753447544475544756447574475844759447604476144762447634476444765447664476744768447694477044771447724477344774447754477644777447784477944780447814478244783447844478544786447874478844789447904479144792447934479444795447964479744798447994480044801448024480344804448054480644807448084480944810448114481244813448144481544816448174481844819448204482144822448234482444825448264482744828448294483044831448324483344834448354483644837448384483944840448414484244843448444484544846448474484844849448504485144852448534485444855448564485744858448594486044861448624486344864448654486644867448684486944870448714487244873448744487544876448774487844879448804488144882448834488444885448864488744888448894489044891448924489344894448954489644897448984489944900449014490244903449044490544906449074490844909449104491144912449134491444915449164491744918449194492044921449224492344924449254492644927449284492944930449314493244933449344493544936449374493844939449404494144942449434494444945449464494744948449494495044951449524495344954449554495644957449584495944960449614496244963449644496544966449674496844969449704497144972449734497444975449764497744978449794498044981449824498344984449854498644987449884498944990449914499244993449944499544996449974499844999450004500145002450034500445005450064500745008450094501045011450124501345014450154501645017450184501945020450214502245023450244502545026450274502845029450304503145032450334503445035450364503745038450394504045041450424504345044450454504645047450484504945050450514505245053450544505545056450574505845059450604506145062450634506445065450664506745068450694507045071450724507345074450754507645077450784507945080450814508245083450844508545086450874508845089450904509145092450934509445095450964509745098450994510045101451024510345104451054510645107451084510945110451114511245113451144511545116451174511845119451204512145122451234512445125451264512745128451294513045131451324513345134451354513645137451384513945140451414514245143451444514545146451474514845149451504515145152451534515445155451564515745158451594516045161451624516345164451654516645167451684516945170451714517245173451744517545176451774517845179451804518145182451834518445185451864518745188451894519045191451924519345194451954519645197451984519945200452014520245203452044520545206452074520845209452104521145212452134521445215452164521745218452194522045221452224522345224452254522645227452284522945230452314523245233452344523545236452374523845239452404524145242452434524445245452464524745248452494525045251452524525345254452554525645257452584525945260452614526245263452644526545266452674526845269452704527145272452734527445275452764527745278452794528045281452824528345284452854528645287452884528945290452914529245293452944529545296452974529845299453004530145302453034530445305453064530745308453094531045311453124531345314453154531645317453184531945320453214532245323453244532545326453274532845329453304533145332453334533445335453364533745338453394534045341453424534345344453454534645347453484534945350453514535245353453544535545356453574535845359453604536145362453634536445365453664536745368453694537045371453724537345374453754537645377453784537945380453814538245383453844538545386453874538845389453904539145392453934539445395453964539745398453994540045401454024540345404454054540645407454084540945410454114541245413454144541545416454174541845419454204542145422454234542445425454264542745428454294543045431454324543345434454354543645437454384543945440454414544245443454444544545446454474544845449454504545145452454534545445455454564545745458454594546045461454624546345464454654546645467454684546945470454714547245473454744547545476454774547845479454804548145482454834548445485454864548745488454894549045491454924549345494454954549645497454984549945500455014550245503455044550545506455074550845509455104551145512455134551445515455164551745518455194552045521455224552345524455254552645527455284552945530455314553245533455344553545536455374553845539455404554145542455434554445545455464554745548455494555045551455524555345554455554555645557455584555945560455614556245563455644556545566455674556845569455704557145572455734557445575455764557745578455794558045581455824558345584455854558645587455884558945590455914559245593455944559545596455974559845599456004560145602456034560445605456064560745608456094561045611456124561345614456154561645617456184561945620456214562245623456244562545626456274562845629456304563145632456334563445635456364563745638456394564045641456424564345644456454564645647456484564945650456514565245653456544565545656456574565845659456604566145662456634566445665456664566745668456694567045671456724567345674456754567645677456784567945680456814568245683456844568545686456874568845689456904569145692456934569445695456964569745698456994570045701457024570345704457054570645707457084570945710457114571245713457144571545716457174571845719457204572145722457234572445725457264572745728457294573045731457324573345734457354573645737457384573945740457414574245743457444574545746457474574845749457504575145752457534575445755457564575745758457594576045761457624576345764457654576645767457684576945770457714577245773457744577545776457774577845779457804578145782457834578445785457864578745788457894579045791457924579345794457954579645797457984579945800458014580245803458044580545806458074580845809458104581145812458134581445815458164581745818458194582045821458224582345824458254582645827458284582945830458314583245833458344583545836458374583845839458404584145842458434584445845458464584745848458494585045851458524585345854458554585645857458584585945860458614586245863458644586545866458674586845869458704587145872458734587445875458764587745878458794588045881458824588345884458854588645887458884588945890458914589245893458944589545896458974589845899459004590145902459034590445905459064590745908459094591045911459124591345914459154591645917459184591945920459214592245923459244592545926459274592845929459304593145932459334593445935459364593745938459394594045941459424594345944459454594645947459484594945950459514595245953459544595545956459574595845959459604596145962459634596445965459664596745968459694597045971459724597345974459754597645977459784597945980459814598245983459844598545986459874598845989459904599145992459934599445995459964599745998459994600046001460024600346004460054600646007460084600946010460114601246013460144601546016460174601846019460204602146022460234602446025460264602746028460294603046031460324603346034460354603646037460384603946040460414604246043460444604546046460474604846049460504605146052460534605446055460564605746058460594606046061460624606346064460654606646067460684606946070460714607246073460744607546076460774607846079460804608146082460834608446085460864608746088460894609046091460924609346094460954609646097460984609946100461014610246103461044610546106461074610846109461104611146112461134611446115461164611746118461194612046121461224612346124461254612646127461284612946130461314613246133461344613546136461374613846139461404614146142461434614446145461464614746148461494615046151461524615346154461554615646157461584615946160461614616246163461644616546166461674616846169461704617146172461734617446175461764617746178461794618046181461824618346184461854618646187461884618946190461914619246193461944619546196461974619846199462004620146202462034620446205462064620746208462094621046211462124621346214462154621646217462184621946220462214622246223462244622546226462274622846229462304623146232462334623446235462364623746238462394624046241462424624346244462454624646247462484624946250462514625246253462544625546256462574625846259462604626146262462634626446265462664626746268462694627046271462724627346274462754627646277462784627946280462814628246283462844628546286462874628846289462904629146292462934629446295462964629746298462994630046301463024630346304463054630646307463084630946310463114631246313463144631546316463174631846319463204632146322463234632446325463264632746328463294633046331463324633346334463354633646337463384633946340463414634246343463444634546346463474634846349463504635146352463534635446355463564635746358463594636046361463624636346364463654636646367463684636946370463714637246373463744637546376463774637846379463804638146382463834638446385463864638746388463894639046391463924639346394463954639646397463984639946400464014640246403464044640546406464074640846409464104641146412464134641446415464164641746418464194642046421464224642346424464254642646427464284642946430464314643246433464344643546436464374643846439464404644146442464434644446445464464644746448464494645046451464524645346454464554645646457464584645946460464614646246463464644646546466464674646846469464704647146472464734647446475464764647746478464794648046481464824648346484464854648646487464884648946490464914649246493464944649546496464974649846499465004650146502465034650446505465064650746508465094651046511465124651346514465154651646517465184651946520465214652246523465244652546526465274652846529465304653146532465334653446535465364653746538465394654046541465424654346544465454654646547465484654946550465514655246553465544655546556465574655846559465604656146562465634656446565465664656746568465694657046571465724657346574465754657646577465784657946580465814658246583465844658546586465874658846589465904659146592465934659446595465964659746598465994660046601466024660346604466054660646607466084660946610466114661246613466144661546616466174661846619466204662146622466234662446625466264662746628466294663046631466324663346634466354663646637466384663946640466414664246643466444664546646466474664846649466504665146652466534665446655466564665746658466594666046661466624666346664466654666646667466684666946670466714667246673466744667546676466774667846679466804668146682466834668446685466864668746688466894669046691466924669346694466954669646697466984669946700467014670246703467044670546706467074670846709467104671146712467134671446715467164671746718467194672046721467224672346724467254672646727467284672946730467314673246733467344673546736467374673846739467404674146742467434674446745467464674746748467494675046751467524675346754467554675646757467584675946760467614676246763467644676546766467674676846769467704677146772467734677446775467764677746778467794678046781467824678346784467854678646787467884678946790467914679246793467944679546796467974679846799468004680146802468034680446805468064680746808468094681046811468124681346814468154681646817468184681946820468214682246823468244682546826468274682846829468304683146832468334683446835468364683746838468394684046841468424684346844468454684646847468484684946850468514685246853468544685546856468574685846859468604686146862468634686446865468664686746868468694687046871468724687346874468754687646877468784687946880468814688246883468844688546886468874688846889468904689146892468934689446895468964689746898468994690046901469024690346904469054690646907469084690946910469114691246913469144691546916469174691846919469204692146922469234692446925469264692746928469294693046931469324693346934469354693646937469384693946940469414694246943469444694546946469474694846949469504695146952469534695446955469564695746958469594696046961469624696346964469654696646967469684696946970469714697246973469744697546976469774697846979469804698146982469834698446985469864698746988469894699046991469924699346994469954699646997469984699947000470014700247003470044700547006470074700847009470104701147012470134701447015470164701747018470194702047021470224702347024470254702647027470284702947030470314703247033470344703547036470374703847039470404704147042470434704447045470464704747048470494705047051470524705347054470554705647057470584705947060470614706247063470644706547066470674706847069470704707147072470734707447075470764707747078470794708047081470824708347084470854708647087470884708947090470914709247093470944709547096470974709847099471004710147102471034710447105471064710747108471094711047111471124711347114471154711647117471184711947120471214712247123471244712547126471274712847129471304713147132471334713447135471364713747138471394714047141471424714347144471454714647147471484714947150471514715247153471544715547156471574715847159471604716147162471634716447165471664716747168471694717047171471724717347174471754717647177471784717947180471814718247183471844718547186471874718847189471904719147192471934719447195471964719747198471994720047201472024720347204472054720647207472084720947210472114721247213472144721547216472174721847219472204722147222472234722447225472264722747228472294723047231472324723347234472354723647237472384723947240472414724247243472444724547246472474724847249472504725147252472534725447255472564725747258472594726047261472624726347264472654726647267472684726947270472714727247273472744727547276472774727847279472804728147282472834728447285472864728747288472894729047291472924729347294472954729647297472984729947300473014730247303473044730547306473074730847309473104731147312473134731447315473164731747318473194732047321473224732347324473254732647327473284732947330473314733247333473344733547336473374733847339473404734147342473434734447345473464734747348473494735047351473524735347354473554735647357473584735947360473614736247363473644736547366473674736847369473704737147372473734737447375473764737747378473794738047381473824738347384473854738647387473884738947390473914739247393473944739547396473974739847399474004740147402474034740447405474064740747408474094741047411474124741347414474154741647417474184741947420474214742247423474244742547426474274742847429474304743147432474334743447435474364743747438474394744047441474424744347444474454744647447474484744947450474514745247453474544745547456474574745847459474604746147462474634746447465474664746747468474694747047471474724747347474474754747647477474784747947480474814748247483474844748547486474874748847489474904749147492474934749447495474964749747498474994750047501475024750347504475054750647507475084750947510475114751247513475144751547516475174751847519475204752147522475234752447525475264752747528475294753047531475324753347534475354753647537475384753947540475414754247543475444754547546475474754847549475504755147552475534755447555475564755747558475594756047561475624756347564475654756647567475684756947570475714757247573475744757547576475774757847579475804758147582475834758447585475864758747588475894759047591475924759347594475954759647597475984759947600476014760247603476044760547606476074760847609476104761147612476134761447615476164761747618476194762047621476224762347624476254762647627476284762947630476314763247633476344763547636476374763847639476404764147642476434764447645476464764747648476494765047651476524765347654476554765647657476584765947660476614766247663476644766547666476674766847669476704767147672476734767447675476764767747678476794768047681476824768347684476854768647687476884768947690476914769247693476944769547696476974769847699477004770147702477034770447705477064770747708477094771047711477124771347714477154771647717477184771947720477214772247723477244772547726477274772847729477304773147732477334773447735477364773747738477394774047741477424774347744477454774647747477484774947750477514775247753477544775547756477574775847759477604776147762477634776447765477664776747768477694777047771477724777347774477754777647777477784777947780477814778247783477844778547786477874778847789477904779147792477934779447795477964779747798477994780047801478024780347804478054780647807478084780947810478114781247813478144781547816478174781847819478204782147822478234782447825478264782747828478294783047831478324783347834478354783647837478384783947840478414784247843478444784547846478474784847849478504785147852478534785447855478564785747858478594786047861478624786347864478654786647867478684786947870478714787247873478744787547876478774787847879478804788147882478834788447885478864788747888478894789047891478924789347894478954789647897478984789947900479014790247903479044790547906479074790847909479104791147912479134791447915479164791747918479194792047921479224792347924479254792647927479284792947930479314793247933479344793547936479374793847939479404794147942479434794447945479464794747948479494795047951479524795347954479554795647957479584795947960479614796247963479644796547966479674796847969479704797147972479734797447975479764797747978479794798047981479824798347984479854798647987479884798947990479914799247993479944799547996479974799847999480004800148002480034800448005480064800748008480094801048011480124801348014480154801648017480184801948020480214802248023480244802548026480274802848029480304803148032480334803448035480364803748038480394804048041480424804348044480454804648047480484804948050480514805248053480544805548056480574805848059480604806148062480634806448065480664806748068480694807048071480724807348074480754807648077480784807948080480814808248083480844808548086480874808848089480904809148092480934809448095480964809748098480994810048101481024810348104481054810648107481084810948110481114811248113481144811548116481174811848119481204812148122481234812448125481264812748128481294813048131481324813348134481354813648137481384813948140481414814248143481444814548146481474814848149481504815148152481534815448155481564815748158481594816048161481624816348164481654816648167481684816948170481714817248173481744817548176481774817848179481804818148182481834818448185481864818748188481894819048191481924819348194481954819648197481984819948200482014820248203482044820548206482074820848209482104821148212482134821448215482164821748218482194822048221482224822348224482254822648227482284822948230482314823248233482344823548236482374823848239482404824148242482434824448245482464824748248482494825048251482524825348254482554825648257482584825948260482614826248263482644826548266482674826848269482704827148272482734827448275482764827748278482794828048281482824828348284482854828648287482884828948290482914829248293482944829548296482974829848299483004830148302483034830448305483064830748308483094831048311483124831348314483154831648317483184831948320483214832248323483244832548326483274832848329483304833148332483334833448335483364833748338483394834048341483424834348344483454834648347483484834948350483514835248353483544835548356483574835848359483604836148362483634836448365483664836748368483694837048371483724837348374483754837648377483784837948380483814838248383483844838548386483874838848389483904839148392483934839448395483964839748398483994840048401484024840348404484054840648407484084840948410484114841248413484144841548416484174841848419484204842148422484234842448425484264842748428484294843048431484324843348434484354843648437484384843948440484414844248443484444844548446484474844848449484504845148452484534845448455484564845748458484594846048461484624846348464484654846648467484684846948470484714847248473484744847548476484774847848479484804848148482484834848448485484864848748488484894849048491484924849348494484954849648497484984849948500485014850248503485044850548506485074850848509485104851148512485134851448515485164851748518485194852048521485224852348524485254852648527485284852948530485314853248533485344853548536485374853848539485404854148542485434854448545485464854748548485494855048551485524855348554485554855648557485584855948560485614856248563485644856548566485674856848569485704857148572485734857448575485764857748578485794858048581485824858348584485854858648587485884858948590485914859248593485944859548596485974859848599486004860148602486034860448605486064860748608486094861048611486124861348614486154861648617486184861948620486214862248623486244862548626486274862848629486304863148632486334863448635486364863748638486394864048641486424864348644486454864648647486484864948650486514865248653486544865548656486574865848659486604866148662486634866448665486664866748668486694867048671486724867348674486754867648677486784867948680486814868248683486844868548686486874868848689486904869148692486934869448695486964869748698486994870048701487024870348704487054870648707487084870948710487114871248713487144871548716487174871848719487204872148722487234872448725487264872748728487294873048731487324873348734487354873648737487384873948740487414874248743487444874548746487474874848749487504875148752487534875448755487564875748758487594876048761487624876348764487654876648767487684876948770487714877248773487744877548776487774877848779487804878148782487834878448785487864878748788487894879048791487924879348794487954879648797487984879948800488014880248803488044880548806488074880848809488104881148812488134881448815488164881748818488194882048821488224882348824488254882648827488284882948830488314883248833488344883548836488374883848839488404884148842488434884448845488464884748848488494885048851488524885348854488554885648857488584885948860488614886248863488644886548866488674886848869488704887148872488734887448875488764887748878488794888048881488824888348884488854888648887488884888948890488914889248893488944889548896488974889848899489004890148902489034890448905489064890748908489094891048911489124891348914489154891648917489184891948920489214892248923489244892548926489274892848929489304893148932489334893448935489364893748938489394894048941489424894348944489454894648947489484894948950489514895248953489544895548956489574895848959489604896148962489634896448965489664896748968489694897048971489724897348974489754897648977489784897948980489814898248983489844898548986489874898848989489904899148992489934899448995489964899748998489994900049001490024900349004490054900649007490084900949010490114901249013490144901549016490174901849019490204902149022490234902449025490264902749028490294903049031490324903349034490354903649037490384903949040490414904249043490444904549046490474904849049490504905149052490534905449055490564905749058490594906049061490624906349064490654906649067490684906949070490714907249073490744907549076490774907849079490804908149082490834908449085490864908749088490894909049091490924909349094490954909649097490984909949100491014910249103491044910549106491074910849109491104911149112491134911449115491164911749118491194912049121491224912349124491254912649127491284912949130491314913249133491344913549136491374913849139491404914149142491434914449145491464914749148491494915049151491524915349154491554915649157491584915949160491614916249163491644916549166491674916849169491704917149172491734917449175491764917749178491794918049181491824918349184491854918649187491884918949190491914919249193491944919549196491974919849199492004920149202492034920449205492064920749208492094921049211492124921349214492154921649217492184921949220492214922249223492244922549226492274922849229492304923149232492334923449235492364923749238492394924049241492424924349244492454924649247492484924949250492514925249253492544925549256492574925849259492604926149262492634926449265492664926749268492694927049271492724927349274492754927649277492784927949280492814928249283492844928549286492874928849289492904929149292492934929449295492964929749298492994930049301493024930349304493054930649307493084930949310493114931249313493144931549316493174931849319493204932149322493234932449325493264932749328493294933049331493324933349334493354933649337493384933949340493414934249343493444934549346493474934849349493504935149352493534935449355493564935749358493594936049361493624936349364493654936649367493684936949370493714937249373493744937549376493774937849379493804938149382493834938449385493864938749388493894939049391493924939349394493954939649397493984939949400494014940249403494044940549406494074940849409494104941149412494134941449415494164941749418494194942049421494224942349424494254942649427494284942949430494314943249433494344943549436494374943849439494404944149442494434944449445494464944749448494494945049451494524945349454494554945649457494584945949460494614946249463494644946549466494674946849469494704947149472494734947449475494764947749478494794948049481494824948349484494854948649487494884948949490494914949249493494944949549496494974949849499495004950149502495034950449505495064950749508495094951049511495124951349514495154951649517495184951949520495214952249523495244952549526495274952849529495304953149532495334953449535495364953749538495394954049541495424954349544495454954649547495484954949550495514955249553495544955549556495574955849559495604956149562495634956449565495664956749568495694957049571495724957349574495754957649577495784957949580495814958249583495844958549586495874958849589495904959149592495934959449595495964959749598495994960049601496024960349604496054960649607496084960949610496114961249613496144961549616496174961849619496204962149622496234962449625496264962749628496294963049631496324963349634496354963649637496384963949640496414964249643496444964549646496474964849649496504965149652496534965449655496564965749658496594966049661496624966349664496654966649667496684966949670496714967249673496744967549676496774967849679496804968149682496834968449685496864968749688496894969049691496924969349694496954969649697496984969949700497014970249703497044970549706497074970849709497104971149712497134971449715497164971749718497194972049721497224972349724497254972649727497284972949730497314973249733497344973549736497374973849739497404974149742497434974449745497464974749748497494975049751497524975349754497554975649757497584975949760497614976249763497644976549766497674976849769497704977149772497734977449775497764977749778497794978049781497824978349784497854978649787497884978949790497914979249793497944979549796497974979849799498004980149802498034980449805498064980749808498094981049811498124981349814498154981649817498184981949820498214982249823498244982549826498274982849829498304983149832498334983449835498364983749838498394984049841498424984349844498454984649847498484984949850498514985249853498544985549856498574985849859498604986149862498634986449865498664986749868498694987049871498724987349874498754987649877498784987949880498814988249883498844988549886498874988849889498904989149892498934989449895498964989749898498994990049901499024990349904499054990649907499084990949910499114991249913499144991549916499174991849919499204992149922499234992449925499264992749928499294993049931499324993349934499354993649937499384993949940499414994249943499444994549946499474994849949499504995149952499534995449955499564995749958499594996049961499624996349964499654996649967499684996949970499714997249973499744997549976499774997849979499804998149982499834998449985499864998749988499894999049991499924999349994499954999649997499984999950000500015000250003500045000550006500075000850009500105001150012500135001450015500165001750018500195002050021500225002350024500255002650027500285002950030500315003250033500345003550036500375003850039500405004150042500435004450045500465004750048500495005050051500525005350054500555005650057500585005950060500615006250063500645006550066500675006850069500705007150072500735007450075500765007750078500795008050081500825008350084500855008650087500885008950090500915009250093500945009550096500975009850099501005010150102501035010450105501065010750108501095011050111501125011350114501155011650117501185011950120501215012250123501245012550126501275012850129501305013150132501335013450135501365013750138501395014050141501425014350144501455014650147501485014950150501515015250153501545015550156501575015850159501605016150162501635016450165501665016750168501695017050171501725017350174501755017650177501785017950180501815018250183501845018550186501875018850189501905019150192501935019450195501965019750198501995020050201502025020350204502055020650207502085020950210502115021250213502145021550216502175021850219502205022150222502235022450225502265022750228502295023050231502325023350234502355023650237502385023950240502415024250243502445024550246502475024850249502505025150252502535025450255502565025750258502595026050261502625026350264502655026650267502685026950270502715027250273502745027550276502775027850279502805028150282502835028450285502865028750288502895029050291502925029350294502955029650297502985029950300503015030250303503045030550306503075030850309503105031150312503135031450315503165031750318503195032050321503225032350324503255032650327503285032950330503315033250333503345033550336503375033850339503405034150342503435034450345503465034750348503495035050351503525035350354503555035650357503585035950360503615036250363503645036550366503675036850369503705037150372503735037450375503765037750378503795038050381503825038350384503855038650387503885038950390503915039250393503945039550396503975039850399504005040150402504035040450405504065040750408504095041050411504125041350414504155041650417504185041950420504215042250423504245042550426504275042850429504305043150432504335043450435504365043750438504395044050441504425044350444504455044650447504485044950450504515045250453504545045550456504575045850459504605046150462504635046450465504665046750468504695047050471504725047350474504755047650477504785047950480504815048250483504845048550486504875048850489504905049150492504935049450495504965049750498504995050050501505025050350504505055050650507505085050950510505115051250513505145051550516505175051850519505205052150522505235052450525505265052750528505295053050531505325053350534505355053650537505385053950540505415054250543505445054550546505475054850549505505055150552505535055450555505565055750558505595056050561505625056350564505655056650567505685056950570505715057250573505745057550576505775057850579505805058150582505835058450585505865058750588505895059050591505925059350594505955059650597505985059950600506015060250603506045060550606506075060850609506105061150612506135061450615506165061750618506195062050621506225062350624506255062650627506285062950630506315063250633506345063550636506375063850639506405064150642506435064450645506465064750648506495065050651506525065350654506555065650657506585065950660506615066250663506645066550666506675066850669506705067150672506735067450675506765067750678506795068050681506825068350684506855068650687506885068950690506915069250693506945069550696506975069850699507005070150702507035070450705507065070750708507095071050711507125071350714507155071650717507185071950720507215072250723507245072550726507275072850729507305073150732507335073450735507365073750738507395074050741507425074350744507455074650747507485074950750507515075250753507545075550756507575075850759507605076150762507635076450765507665076750768507695077050771507725077350774507755077650777507785077950780507815078250783507845078550786507875078850789507905079150792507935079450795507965079750798507995080050801508025080350804508055080650807508085080950810508115081250813508145081550816508175081850819508205082150822508235082450825508265082750828508295083050831508325083350834508355083650837508385083950840508415084250843508445084550846508475084850849508505085150852508535085450855508565085750858508595086050861508625086350864508655086650867508685086950870508715087250873508745087550876508775087850879508805088150882508835088450885508865088750888508895089050891508925089350894508955089650897508985089950900509015090250903509045090550906509075090850909509105091150912509135091450915509165091750918509195092050921509225092350924509255092650927509285092950930509315093250933509345093550936509375093850939509405094150942509435094450945509465094750948509495095050951509525095350954509555095650957509585095950960509615096250963509645096550966509675096850969509705097150972509735097450975509765097750978509795098050981509825098350984509855098650987509885098950990509915099250993509945099550996509975099850999510005100151002510035100451005510065100751008510095101051011510125101351014510155101651017510185101951020510215102251023510245102551026510275102851029510305103151032510335103451035510365103751038510395104051041510425104351044510455104651047510485104951050510515105251053510545105551056510575105851059510605106151062510635106451065510665106751068510695107051071510725107351074510755107651077510785107951080510815108251083510845108551086510875108851089510905109151092510935109451095510965109751098510995110051101511025110351104511055110651107511085110951110511115111251113511145111551116511175111851119511205112151122511235112451125511265112751128511295113051131511325113351134511355113651137511385113951140511415114251143511445114551146511475114851149511505115151152511535115451155511565115751158511595116051161511625116351164511655116651167511685116951170511715117251173511745117551176511775117851179511805118151182511835118451185511865118751188511895119051191511925119351194511955119651197511985119951200512015120251203512045120551206512075120851209512105121151212512135121451215512165121751218512195122051221512225122351224512255122651227512285122951230512315123251233512345123551236512375123851239512405124151242512435124451245512465124751248512495125051251512525125351254512555125651257512585125951260512615126251263512645126551266512675126851269512705127151272512735127451275512765127751278512795128051281512825128351284512855128651287512885128951290512915129251293512945129551296512975129851299513005130151302513035130451305513065130751308513095131051311513125131351314513155131651317513185131951320513215132251323513245132551326513275132851329513305133151332513335133451335513365133751338513395134051341513425134351344513455134651347513485134951350513515135251353513545135551356513575135851359513605136151362513635136451365513665136751368513695137051371513725137351374513755137651377513785137951380513815138251383513845138551386513875138851389513905139151392513935139451395513965139751398513995140051401514025140351404514055140651407514085140951410514115141251413514145141551416514175141851419514205142151422514235142451425514265142751428514295143051431514325143351434514355143651437514385143951440514415144251443514445144551446514475144851449514505145151452514535145451455514565145751458514595146051461514625146351464514655146651467514685146951470514715147251473514745147551476514775147851479514805148151482514835148451485514865148751488514895149051491514925149351494514955149651497514985149951500515015150251503515045150551506515075150851509515105151151512515135151451515515165151751518515195152051521515225152351524515255152651527515285152951530515315153251533515345153551536515375153851539515405154151542515435154451545515465154751548515495155051551515525155351554515555155651557515585155951560515615156251563515645156551566515675156851569515705157151572515735157451575515765157751578515795158051581515825158351584515855158651587515885158951590515915159251593515945159551596515975159851599516005160151602516035160451605516065160751608516095161051611516125161351614516155161651617516185161951620516215162251623516245162551626516275162851629516305163151632516335163451635516365163751638516395164051641516425164351644516455164651647516485164951650516515165251653516545165551656516575165851659516605166151662516635166451665516665166751668516695167051671516725167351674516755167651677516785167951680516815168251683516845168551686516875168851689516905169151692516935169451695516965169751698516995170051701517025170351704517055170651707517085170951710517115171251713517145171551716517175171851719517205172151722517235172451725517265172751728517295173051731517325173351734517355173651737517385173951740517415174251743517445174551746517475174851749517505175151752517535175451755517565175751758517595176051761517625176351764517655176651767517685176951770517715177251773517745177551776517775177851779517805178151782517835178451785517865178751788517895179051791517925179351794517955179651797517985179951800518015180251803518045180551806518075180851809518105181151812518135181451815518165181751818518195182051821518225182351824518255182651827518285182951830518315183251833518345183551836518375183851839518405184151842518435184451845518465184751848518495185051851518525185351854518555185651857518585185951860518615186251863518645186551866518675186851869518705187151872518735187451875518765187751878518795188051881518825188351884518855188651887518885188951890518915189251893518945189551896518975189851899519005190151902519035190451905519065190751908519095191051911519125191351914519155191651917519185191951920519215192251923519245192551926519275192851929519305193151932519335193451935519365193751938519395194051941519425194351944519455194651947519485194951950519515195251953519545195551956519575195851959519605196151962519635196451965519665196751968519695197051971519725197351974519755197651977519785197951980519815198251983519845198551986519875198851989519905199151992519935199451995519965199751998519995200052001520025200352004520055200652007520085200952010520115201252013520145201552016520175201852019520205202152022520235202452025520265202752028520295203052031520325203352034520355203652037520385203952040520415204252043520445204552046520475204852049520505205152052520535205452055520565205752058520595206052061520625206352064520655206652067520685206952070520715207252073520745207552076520775207852079520805208152082520835208452085520865208752088520895209052091520925209352094520955209652097520985209952100521015210252103521045210552106521075210852109521105211152112521135211452115521165211752118521195212052121521225212352124521255212652127521285212952130521315213252133521345213552136521375213852139521405214152142521435214452145521465214752148521495215052151521525215352154521555215652157521585215952160521615216252163521645216552166521675216852169521705217152172521735217452175521765217752178521795218052181521825218352184521855218652187521885218952190521915219252193521945219552196521975219852199522005220152202522035220452205522065220752208522095221052211522125221352214522155221652217522185221952220522215222252223522245222552226522275222852229522305223152232522335223452235522365223752238522395224052241522425224352244522455224652247522485224952250522515225252253522545225552256522575225852259522605226152262522635226452265522665226752268522695227052271522725227352274522755227652277522785227952280522815228252283522845228552286522875228852289522905229152292522935229452295522965229752298522995230052301523025230352304523055230652307523085230952310523115231252313523145231552316523175231852319523205232152322523235232452325523265232752328523295233052331523325233352334523355233652337523385233952340523415234252343523445234552346523475234852349523505235152352523535235452355523565235752358523595236052361523625236352364523655236652367523685236952370523715237252373523745237552376523775237852379523805238152382523835238452385523865238752388523895239052391523925239352394523955239652397523985239952400524015240252403524045240552406524075240852409524105241152412524135241452415524165241752418524195242052421524225242352424524255242652427524285242952430524315243252433524345243552436524375243852439524405244152442524435244452445524465244752448524495245052451524525245352454524555245652457524585245952460524615246252463524645246552466524675246852469524705247152472524735247452475524765247752478524795248052481524825248352484524855248652487524885248952490524915249252493524945249552496524975249852499525005250152502525035250452505525065250752508525095251052511525125251352514525155251652517525185251952520525215252252523525245252552526525275252852529525305253152532525335253452535525365253752538525395254052541525425254352544525455254652547525485254952550525515255252553525545255552556525575255852559525605256152562525635256452565525665256752568525695257052571525725257352574525755257652577525785257952580525815258252583525845258552586525875258852589525905259152592525935259452595525965259752598525995260052601526025260352604526055260652607526085260952610526115261252613526145261552616526175261852619526205262152622526235262452625526265262752628526295263052631526325263352634526355263652637526385263952640526415264252643526445264552646526475264852649526505265152652526535265452655526565265752658526595266052661526625266352664526655266652667526685266952670526715267252673526745267552676526775267852679526805268152682526835268452685526865268752688526895269052691526925269352694526955269652697526985269952700527015270252703527045270552706527075270852709527105271152712527135271452715527165271752718527195272052721527225272352724527255272652727527285272952730527315273252733527345273552736527375273852739527405274152742527435274452745527465274752748527495275052751527525275352754527555275652757527585275952760527615276252763527645276552766527675276852769527705277152772527735277452775527765277752778527795278052781527825278352784527855278652787527885278952790527915279252793527945279552796527975279852799528005280152802528035280452805528065280752808528095281052811528125281352814528155281652817528185281952820528215282252823528245282552826528275282852829528305283152832528335283452835528365283752838528395284052841528425284352844528455284652847528485284952850528515285252853528545285552856528575285852859528605286152862528635286452865528665286752868528695287052871528725287352874528755287652877528785287952880528815288252883528845288552886528875288852889528905289152892528935289452895528965289752898528995290052901529025290352904529055290652907529085290952910529115291252913529145291552916529175291852919529205292152922529235292452925529265292752928529295293052931529325293352934529355293652937529385293952940529415294252943529445294552946529475294852949529505295152952529535295452955529565295752958529595296052961529625296352964529655296652967529685296952970529715297252973529745297552976529775297852979529805298152982529835298452985529865298752988529895299052991529925299352994529955299652997529985299953000530015300253003530045300553006530075300853009530105301153012530135301453015530165301753018530195302053021530225302353024530255302653027530285302953030530315303253033530345303553036530375303853039530405304153042530435304453045530465304753048530495305053051530525305353054530555305653057530585305953060530615306253063530645306553066530675306853069530705307153072530735307453075530765307753078530795308053081530825308353084530855308653087530885308953090530915309253093530945309553096530975309853099531005310153102531035310453105531065310753108531095311053111531125311353114531155311653117531185311953120531215312253123531245312553126531275312853129531305313153132531335313453135531365313753138531395314053141531425314353144531455314653147531485314953150531515315253153531545315553156531575315853159531605316153162531635316453165531665316753168531695317053171531725317353174531755317653177531785317953180531815318253183531845318553186531875318853189531905319153192531935319453195531965319753198531995320053201532025320353204532055320653207532085320953210532115321253213532145321553216532175321853219532205322153222532235322453225532265322753228532295323053231532325323353234532355323653237532385323953240532415324253243532445324553246532475324853249532505325153252532535325453255532565325753258532595326053261532625326353264532655326653267532685326953270532715327253273532745327553276532775327853279532805328153282532835328453285532865328753288532895329053291532925329353294532955329653297532985329953300533015330253303533045330553306533075330853309533105331153312533135331453315533165331753318533195332053321533225332353324533255332653327533285332953330533315333253333533345333553336533375333853339533405334153342533435334453345533465334753348533495335053351533525335353354533555335653357533585335953360533615336253363533645336553366533675336853369533705337153372533735337453375533765337753378533795338053381533825338353384533855338653387533885338953390533915339253393533945339553396533975339853399534005340153402534035340453405534065340753408534095341053411534125341353414534155341653417534185341953420534215342253423534245342553426534275342853429534305343153432534335343453435534365343753438534395344053441534425344353444534455344653447534485344953450534515345253453534545345553456534575345853459534605346153462534635346453465534665346753468534695347053471534725347353474534755347653477534785347953480534815348253483534845348553486534875348853489534905349153492534935349453495534965349753498534995350053501535025350353504535055350653507535085350953510535115351253513535145351553516535175351853519535205352153522535235352453525535265352753528535295353053531535325353353534535355353653537535385353953540535415354253543535445354553546535475354853549535505355153552535535355453555535565355753558535595356053561535625356353564535655356653567535685356953570535715357253573535745357553576535775357853579535805358153582535835358453585535865358753588535895359053591535925359353594535955359653597535985359953600536015360253603536045360553606536075360853609536105361153612536135361453615536165361753618536195362053621536225362353624536255362653627536285362953630536315363253633536345363553636536375363853639536405364153642536435364453645536465364753648536495365053651536525365353654536555365653657536585365953660536615366253663536645366553666536675366853669536705367153672536735367453675536765367753678536795368053681536825368353684536855368653687536885368953690536915369253693536945369553696536975369853699537005370153702537035370453705537065370753708537095371053711537125371353714537155371653717537185371953720537215372253723537245372553726537275372853729537305373153732537335373453735537365373753738537395374053741537425374353744537455374653747537485374953750537515375253753537545375553756537575375853759537605376153762537635376453765537665376753768537695377053771537725377353774537755377653777537785377953780537815378253783537845378553786537875378853789537905379153792537935379453795537965379753798537995380053801538025380353804538055380653807538085380953810538115381253813538145381553816538175381853819538205382153822538235382453825538265382753828538295383053831538325383353834538355383653837538385383953840538415384253843538445384553846538475384853849538505385153852538535385453855538565385753858538595386053861538625386353864538655386653867538685386953870538715387253873538745387553876538775387853879538805388153882538835388453885538865388753888538895389053891538925389353894538955389653897538985389953900539015390253903539045390553906539075390853909539105391153912539135391453915539165391753918539195392053921539225392353924539255392653927539285392953930539315393253933539345393553936539375393853939539405394153942539435394453945539465394753948539495395053951539525395353954539555395653957539585395953960539615396253963539645396553966539675396853969539705397153972539735397453975539765397753978539795398053981539825398353984539855398653987539885398953990539915399253993539945399553996539975399853999540005400154002540035400454005540065400754008540095401054011540125401354014540155401654017540185401954020540215402254023540245402554026540275402854029540305403154032540335403454035540365403754038540395404054041540425404354044540455404654047540485404954050540515405254053540545405554056540575405854059540605406154062540635406454065540665406754068540695407054071540725407354074540755407654077540785407954080540815408254083540845408554086540875408854089540905409154092540935409454095540965409754098540995410054101541025410354104541055410654107541085410954110541115411254113541145411554116541175411854119541205412154122541235412454125541265412754128541295413054131541325413354134541355413654137541385413954140541415414254143541445414554146541475414854149541505415154152541535415454155541565415754158541595416054161541625416354164541655416654167541685416954170541715417254173541745417554176541775417854179541805418154182541835418454185541865418754188541895419054191541925419354194541955419654197541985419954200542015420254203542045420554206542075420854209542105421154212542135421454215542165421754218542195422054221542225422354224542255422654227542285422954230542315423254233542345423554236542375423854239542405424154242542435424454245542465424754248542495425054251542525425354254542555425654257542585425954260542615426254263542645426554266542675426854269542705427154272542735427454275542765427754278542795428054281542825428354284542855428654287542885428954290542915429254293542945429554296542975429854299543005430154302543035430454305543065430754308543095431054311543125431354314543155431654317543185431954320543215432254323543245432554326543275432854329543305433154332543335433454335543365433754338543395434054341543425434354344543455434654347543485434954350543515435254353543545435554356543575435854359543605436154362543635436454365543665436754368543695437054371543725437354374543755437654377543785437954380543815438254383543845438554386543875438854389543905439154392543935439454395543965439754398543995440054401544025440354404544055440654407544085440954410544115441254413544145441554416544175441854419544205442154422544235442454425544265442754428544295443054431544325443354434544355443654437544385443954440544415444254443544445444554446544475444854449544505445154452544535445454455544565445754458544595446054461544625446354464544655446654467544685446954470544715447254473544745447554476544775447854479544805448154482544835448454485544865448754488544895449054491544925449354494544955449654497544985449954500545015450254503545045450554506545075450854509545105451154512545135451454515545165451754518545195452054521545225452354524545255452654527545285452954530545315453254533545345453554536545375453854539545405454154542545435454454545545465454754548545495455054551545525455354554545555455654557545585455954560545615456254563545645456554566545675456854569545705457154572545735457454575545765457754578545795458054581545825458354584545855458654587545885458954590545915459254593545945459554596545975459854599546005460154602546035460454605546065460754608546095461054611546125461354614546155461654617546185461954620546215462254623546245462554626546275462854629546305463154632546335463454635546365463754638546395464054641546425464354644546455464654647546485464954650546515465254653546545465554656546575465854659546605466154662546635466454665546665466754668546695467054671546725467354674546755467654677546785467954680546815468254683546845468554686546875468854689546905469154692546935469454695546965469754698546995470054701547025470354704547055470654707547085470954710547115471254713547145471554716547175471854719547205472154722547235472454725547265472754728547295473054731547325473354734547355473654737547385473954740547415474254743547445474554746547475474854749547505475154752547535475454755547565475754758547595476054761547625476354764547655476654767547685476954770547715477254773547745477554776547775477854779547805478154782547835478454785547865478754788547895479054791547925479354794547955479654797547985479954800548015480254803548045480554806548075480854809548105481154812548135481454815548165481754818548195482054821548225482354824548255482654827548285482954830548315483254833548345483554836548375483854839548405484154842548435484454845548465484754848548495485054851548525485354854548555485654857548585485954860548615486254863548645486554866548675486854869548705487154872548735487454875548765487754878548795488054881548825488354884548855488654887548885488954890548915489254893548945489554896548975489854899549005490154902549035490454905549065490754908549095491054911549125491354914549155491654917549185491954920549215492254923549245492554926549275492854929549305493154932549335493454935549365493754938549395494054941549425494354944549455494654947549485494954950549515495254953549545495554956549575495854959549605496154962549635496454965549665496754968549695497054971549725497354974549755497654977549785497954980549815498254983549845498554986549875498854989549905499154992549935499454995549965499754998549995500055001550025500355004550055500655007550085500955010550115501255013550145501555016550175501855019550205502155022550235502455025550265502755028550295503055031550325503355034550355503655037550385503955040550415504255043550445504555046550475504855049550505505155052550535505455055550565505755058550595506055061550625506355064550655506655067550685506955070550715507255073550745507555076550775507855079550805508155082550835508455085550865508755088550895509055091550925509355094550955509655097550985509955100551015510255103551045510555106551075510855109551105511155112551135511455115551165511755118551195512055121551225512355124551255512655127551285512955130551315513255133551345513555136551375513855139551405514155142551435514455145551465514755148551495515055151551525515355154551555515655157551585515955160551615516255163551645516555166551675516855169551705517155172551735517455175551765517755178551795518055181551825518355184551855518655187551885518955190551915519255193551945519555196551975519855199552005520155202552035520455205552065520755208552095521055211552125521355214552155521655217552185521955220552215522255223552245522555226552275522855229552305523155232552335523455235552365523755238552395524055241552425524355244552455524655247552485524955250552515525255253552545525555256552575525855259552605526155262552635526455265552665526755268552695527055271552725527355274552755527655277552785527955280552815528255283552845528555286552875528855289552905529155292552935529455295552965529755298552995530055301553025530355304553055530655307553085530955310553115531255313553145531555316553175531855319553205532155322553235532455325553265532755328553295533055331553325533355334553355533655337553385533955340553415534255343553445534555346553475534855349553505535155352553535535455355553565535755358553595536055361553625536355364553655536655367553685536955370553715537255373553745537555376553775537855379553805538155382553835538455385553865538755388553895539055391553925539355394553955539655397553985539955400554015540255403554045540555406554075540855409554105541155412554135541455415554165541755418554195542055421554225542355424554255542655427554285542955430554315543255433554345543555436554375543855439554405544155442554435544455445554465544755448554495545055451554525545355454554555545655457554585545955460554615546255463554645546555466554675546855469554705547155472554735547455475554765547755478554795548055481554825548355484554855548655487554885548955490554915549255493554945549555496554975549855499555005550155502555035550455505555065550755508555095551055511555125551355514555155551655517555185551955520555215552255523555245552555526555275552855529555305553155532555335553455535555365553755538555395554055541555425554355544555455554655547555485554955550555515555255553555545555555556555575555855559555605556155562555635556455565555665556755568555695557055571555725557355574555755557655577555785557955580555815558255583555845558555586555875558855589555905559155592555935559455595555965559755598555995560055601556025560355604556055560655607556085560955610556115561255613556145561555616556175561855619556205562155622556235562455625556265562755628556295563055631556325563355634556355563655637556385563955640556415564255643556445564555646556475564855649556505565155652556535565455655556565565755658556595566055661556625566355664556655566655667556685566955670556715567255673556745567555676556775567855679556805568155682556835568455685556865568755688556895569055691556925569355694556955569655697556985569955700557015570255703557045570555706557075570855709557105571155712557135571455715557165571755718557195572055721557225572355724557255572655727557285572955730557315573255733557345573555736557375573855739557405574155742557435574455745557465574755748557495575055751557525575355754557555575655757557585575955760557615576255763557645576555766557675576855769557705577155772557735577455775557765577755778557795578055781557825578355784557855578655787557885578955790557915579255793557945579555796557975579855799558005580155802558035580455805558065580755808558095581055811558125581355814558155581655817558185581955820558215582255823558245582555826558275582855829558305583155832558335583455835558365583755838558395584055841558425584355844558455584655847558485584955850558515585255853558545585555856558575585855859558605586155862558635586455865558665586755868558695587055871558725587355874558755587655877558785587955880558815588255883558845588555886558875588855889558905589155892558935589455895558965589755898558995590055901559025590355904559055590655907559085590955910559115591255913559145591555916559175591855919559205592155922559235592455925559265592755928559295593055931559325593355934559355593655937559385593955940559415594255943559445594555946559475594855949559505595155952559535595455955559565595755958559595596055961559625596355964559655596655967559685596955970559715597255973559745597555976559775597855979559805598155982559835598455985559865598755988559895599055991559925599355994559955599655997559985599956000560015600256003560045600556006560075600856009560105601156012560135601456015560165601756018560195602056021560225602356024560255602656027560285602956030560315603256033560345603556036560375603856039560405604156042560435604456045560465604756048560495605056051560525605356054560555605656057560585605956060560615606256063560645606556066560675606856069560705607156072560735607456075560765607756078560795608056081560825608356084560855608656087560885608956090560915609256093560945609556096560975609856099561005610156102561035610456105561065610756108561095611056111561125611356114561155611656117561185611956120561215612256123561245612556126561275612856129561305613156132561335613456135561365613756138561395614056141561425614356144561455614656147561485614956150561515615256153561545615556156561575615856159561605616156162561635616456165561665616756168561695617056171561725617356174561755617656177561785617956180561815618256183561845618556186561875618856189561905619156192561935619456195561965619756198561995620056201562025620356204562055620656207562085620956210562115621256213562145621556216562175621856219562205622156222562235622456225562265622756228562295623056231562325623356234562355623656237562385623956240562415624256243562445624556246562475624856249562505625156252562535625456255562565625756258562595626056261562625626356264562655626656267562685626956270562715627256273562745627556276562775627856279562805628156282562835628456285562865628756288562895629056291562925629356294562955629656297562985629956300563015630256303563045630556306563075630856309563105631156312563135631456315563165631756318563195632056321563225632356324563255632656327563285632956330563315633256333563345633556336563375633856339563405634156342563435634456345563465634756348563495635056351563525635356354563555635656357563585635956360563615636256363563645636556366563675636856369563705637156372563735637456375563765637756378563795638056381563825638356384563855638656387563885638956390563915639256393563945639556396563975639856399564005640156402564035640456405564065640756408564095641056411564125641356414564155641656417564185641956420564215642256423564245642556426564275642856429564305643156432564335643456435564365643756438564395644056441564425644356444564455644656447564485644956450564515645256453564545645556456564575645856459564605646156462564635646456465564665646756468564695647056471564725647356474564755647656477564785647956480564815648256483564845648556486564875648856489564905649156492564935649456495564965649756498564995650056501565025650356504565055650656507565085650956510565115651256513565145651556516565175651856519565205652156522565235652456525565265652756528565295653056531565325653356534565355653656537565385653956540565415654256543565445654556546565475654856549565505655156552565535655456555565565655756558565595656056561565625656356564565655656656567565685656956570565715657256573565745657556576565775657856579565805658156582565835658456585565865658756588565895659056591565925659356594565955659656597565985659956600566015660256603566045660556606566075660856609566105661156612566135661456615566165661756618566195662056621566225662356624566255662656627566285662956630566315663256633566345663556636566375663856639566405664156642566435664456645566465664756648566495665056651566525665356654566555665656657566585665956660566615666256663566645666556666566675666856669566705667156672566735667456675566765667756678566795668056681566825668356684566855668656687566885668956690566915669256693566945669556696566975669856699567005670156702567035670456705567065670756708567095671056711567125671356714567155671656717567185671956720567215672256723567245672556726567275672856729567305673156732567335673456735567365673756738567395674056741567425674356744567455674656747567485674956750567515675256753567545675556756567575675856759567605676156762567635676456765567665676756768567695677056771567725677356774567755677656777567785677956780567815678256783567845678556786567875678856789567905679156792567935679456795567965679756798567995680056801568025680356804568055680656807568085680956810568115681256813568145681556816568175681856819568205682156822568235682456825568265682756828568295683056831568325683356834568355683656837568385683956840568415684256843568445684556846568475684856849568505685156852568535685456855568565685756858568595686056861568625686356864568655686656867568685686956870568715687256873568745687556876568775687856879568805688156882568835688456885568865688756888568895689056891568925689356894568955689656897568985689956900569015690256903569045690556906569075690856909569105691156912569135691456915569165691756918569195692056921569225692356924569255692656927569285692956930569315693256933569345693556936569375693856939569405694156942569435694456945569465694756948569495695056951569525695356954569555695656957569585695956960569615696256963569645696556966569675696856969569705697156972569735697456975569765697756978569795698056981569825698356984569855698656987569885698956990569915699256993569945699556996569975699856999570005700157002570035700457005570065700757008570095701057011570125701357014570155701657017570185701957020570215702257023570245702557026570275702857029570305703157032570335703457035570365703757038570395704057041570425704357044570455704657047570485704957050570515705257053570545705557056570575705857059570605706157062570635706457065570665706757068570695707057071570725707357074570755707657077570785707957080570815708257083570845708557086570875708857089570905709157092570935709457095570965709757098570995710057101571025710357104571055710657107571085710957110571115711257113571145711557116571175711857119571205712157122571235712457125571265712757128571295713057131571325713357134571355713657137571385713957140571415714257143571445714557146571475714857149571505715157152571535715457155571565715757158571595716057161571625716357164571655716657167571685716957170571715717257173571745717557176571775717857179571805718157182571835718457185571865718757188571895719057191571925719357194571955719657197571985719957200572015720257203572045720557206572075720857209572105721157212572135721457215572165721757218572195722057221572225722357224572255722657227572285722957230572315723257233572345723557236572375723857239572405724157242572435724457245572465724757248572495725057251572525725357254572555725657257572585725957260572615726257263572645726557266572675726857269572705727157272572735727457275572765727757278572795728057281572825728357284572855728657287572885728957290572915729257293572945729557296572975729857299573005730157302573035730457305573065730757308573095731057311573125731357314573155731657317573185731957320573215732257323573245732557326573275732857329573305733157332573335733457335573365733757338573395734057341573425734357344573455734657347573485734957350573515735257353573545735557356573575735857359573605736157362573635736457365573665736757368573695737057371573725737357374573755737657377573785737957380573815738257383573845738557386573875738857389573905739157392573935739457395573965739757398573995740057401574025740357404574055740657407574085740957410574115741257413574145741557416574175741857419574205742157422574235742457425574265742757428574295743057431574325743357434574355743657437574385743957440574415744257443574445744557446574475744857449574505745157452574535745457455574565745757458574595746057461574625746357464574655746657467574685746957470574715747257473574745747557476574775747857479574805748157482574835748457485574865748757488574895749057491574925749357494574955749657497574985749957500575015750257503575045750557506575075750857509575105751157512575135751457515575165751757518575195752057521575225752357524575255752657527575285752957530575315753257533575345753557536575375753857539575405754157542575435754457545575465754757548575495755057551575525755357554575555755657557575585755957560575615756257563575645756557566575675756857569575705757157572575735757457575575765757757578575795758057581575825758357584575855758657587575885758957590575915759257593575945759557596575975759857599576005760157602576035760457605576065760757608576095761057611576125761357614576155761657617576185761957620576215762257623576245762557626576275762857629576305763157632576335763457635576365763757638576395764057641576425764357644576455764657647576485764957650576515765257653576545765557656576575765857659576605766157662576635766457665576665766757668576695767057671576725767357674576755767657677576785767957680576815768257683576845768557686576875768857689576905769157692576935769457695576965769757698576995770057701577025770357704577055770657707577085770957710577115771257713577145771557716577175771857719577205772157722577235772457725577265772757728577295773057731577325773357734577355773657737577385773957740577415774257743577445774557746577475774857749577505775157752577535775457755577565775757758577595776057761577625776357764577655776657767577685776957770577715777257773577745777557776577775777857779577805778157782577835778457785577865778757788577895779057791577925779357794577955779657797577985779957800578015780257803578045780557806578075780857809578105781157812578135781457815578165781757818578195782057821578225782357824578255782657827578285782957830578315783257833578345783557836578375783857839578405784157842578435784457845578465784757848578495785057851578525785357854578555785657857578585785957860578615786257863578645786557866578675786857869578705787157872578735787457875578765787757878578795788057881578825788357884578855788657887578885788957890578915789257893578945789557896578975789857899579005790157902579035790457905579065790757908579095791057911579125791357914579155791657917579185791957920579215792257923579245792557926579275792857929579305793157932579335793457935579365793757938579395794057941579425794357944579455794657947579485794957950579515795257953579545795557956579575795857959579605796157962579635796457965579665796757968579695797057971579725797357974579755797657977579785797957980579815798257983579845798557986579875798857989579905799157992579935799457995579965799757998579995800058001580025800358004580055800658007580085800958010580115801258013580145801558016580175801858019580205802158022580235802458025580265802758028580295803058031580325803358034580355803658037580385803958040580415804258043580445804558046580475804858049580505805158052580535805458055580565805758058580595806058061580625806358064580655806658067580685806958070580715807258073580745807558076580775807858079580805808158082580835808458085580865808758088580895809058091580925809358094580955809658097580985809958100581015810258103581045810558106581075810858109581105811158112581135811458115581165811758118581195812058121581225812358124581255812658127581285812958130581315813258133581345813558136581375813858139581405814158142581435814458145581465814758148581495815058151581525815358154581555815658157581585815958160581615816258163581645816558166581675816858169581705817158172581735817458175581765817758178581795818058181581825818358184581855818658187581885818958190581915819258193581945819558196581975819858199582005820158202582035820458205582065820758208582095821058211582125821358214582155821658217582185821958220582215822258223582245822558226582275822858229582305823158232582335823458235582365823758238582395824058241582425824358244582455824658247582485824958250582515825258253582545825558256582575825858259582605826158262582635826458265582665826758268582695827058271582725827358274582755827658277582785827958280582815828258283582845828558286582875828858289582905829158292582935829458295582965829758298582995830058301583025830358304583055830658307583085830958310583115831258313583145831558316583175831858319583205832158322583235832458325583265832758328583295833058331583325833358334583355833658337583385833958340583415834258343583445834558346583475834858349583505835158352583535835458355583565835758358583595836058361583625836358364583655836658367583685836958370583715837258373583745837558376583775837858379583805838158382583835838458385583865838758388583895839058391583925839358394583955839658397583985839958400584015840258403584045840558406584075840858409584105841158412584135841458415584165841758418584195842058421584225842358424584255842658427584285842958430584315843258433584345843558436584375843858439584405844158442584435844458445584465844758448584495845058451584525845358454584555845658457584585845958460584615846258463584645846558466584675846858469584705847158472584735847458475584765847758478584795848058481584825848358484584855848658487584885848958490584915849258493584945849558496584975849858499585005850158502585035850458505585065850758508585095851058511585125851358514585155851658517585185851958520585215852258523585245852558526585275852858529585305853158532585335853458535585365853758538585395854058541585425854358544585455854658547585485854958550585515855258553585545855558556585575855858559585605856158562585635856458565585665856758568585695857058571585725857358574585755857658577585785857958580585815858258583585845858558586585875858858589585905859158592585935859458595585965859758598585995860058601586025860358604586055860658607586085860958610586115861258613586145861558616586175861858619586205862158622586235862458625586265862758628586295863058631586325863358634586355863658637586385863958640586415864258643586445864558646586475864858649586505865158652586535865458655586565865758658586595866058661586625866358664586655866658667586685866958670586715867258673586745867558676586775867858679586805868158682586835868458685586865868758688586895869058691586925869358694586955869658697586985869958700587015870258703587045870558706587075870858709587105871158712587135871458715587165871758718587195872058721587225872358724587255872658727587285872958730587315873258733587345873558736587375873858739587405874158742587435874458745587465874758748587495875058751587525875358754587555875658757587585875958760587615876258763587645876558766587675876858769587705877158772587735877458775587765877758778587795878058781587825878358784587855878658787587885878958790587915879258793587945879558796587975879858799588005880158802588035880458805588065880758808588095881058811588125881358814588155881658817588185881958820588215882258823588245882558826588275882858829588305883158832588335883458835588365883758838588395884058841588425884358844588455884658847588485884958850588515885258853588545885558856588575885858859588605886158862588635886458865588665886758868588695887058871588725887358874588755887658877588785887958880588815888258883588845888558886588875888858889588905889158892588935889458895588965889758898588995890058901589025890358904589055890658907589085890958910589115891258913589145891558916589175891858919589205892158922589235892458925589265892758928589295893058931589325893358934589355893658937589385893958940589415894258943589445894558946589475894858949589505895158952589535895458955589565895758958589595896058961589625896358964589655896658967589685896958970589715897258973589745897558976589775897858979589805898158982589835898458985589865898758988589895899058991589925899358994589955899658997589985899959000590015900259003590045900559006590075900859009590105901159012590135901459015590165901759018590195902059021590225902359024590255902659027590285902959030590315903259033590345903559036590375903859039590405904159042590435904459045590465904759048590495905059051590525905359054590555905659057590585905959060590615906259063590645906559066590675906859069590705907159072590735907459075590765907759078590795908059081590825908359084590855908659087590885908959090590915909259093590945909559096590975909859099591005910159102591035910459105591065910759108591095911059111591125911359114591155911659117591185911959120591215912259123591245912559126591275912859129591305913159132591335913459135591365913759138591395914059141591425914359144591455914659147591485914959150591515915259153591545915559156591575915859159591605916159162591635916459165591665916759168591695917059171591725917359174591755917659177591785917959180591815918259183591845918559186591875918859189591905919159192591935919459195591965919759198591995920059201592025920359204592055920659207592085920959210592115921259213592145921559216592175921859219592205922159222592235922459225592265922759228592295923059231592325923359234592355923659237592385923959240592415924259243592445924559246592475924859249592505925159252592535925459255592565925759258592595926059261592625926359264592655926659267592685926959270592715927259273592745927559276592775927859279592805928159282592835928459285592865928759288592895929059291592925929359294592955929659297592985929959300593015930259303593045930559306593075930859309593105931159312593135931459315593165931759318593195932059321593225932359324593255932659327593285932959330593315933259333593345933559336593375933859339593405934159342593435934459345593465934759348593495935059351593525935359354593555935659357593585935959360593615936259363593645936559366593675936859369593705937159372593735937459375593765937759378593795938059381593825938359384593855938659387593885938959390593915939259393593945939559396593975939859399594005940159402594035940459405594065940759408594095941059411594125941359414594155941659417594185941959420594215942259423594245942559426594275942859429594305943159432594335943459435594365943759438594395944059441594425944359444594455944659447594485944959450594515945259453594545945559456594575945859459594605946159462594635946459465594665946759468594695947059471594725947359474594755947659477594785947959480594815948259483594845948559486594875948859489594905949159492594935949459495594965949759498594995950059501595025950359504595055950659507595085950959510595115951259513595145951559516595175951859519595205952159522595235952459525595265952759528595295953059531595325953359534595355953659537595385953959540595415954259543595445954559546595475954859549595505955159552595535955459555595565955759558595595956059561595625956359564595655956659567595685956959570595715957259573595745957559576595775957859579595805958159582595835958459585595865958759588595895959059591595925959359594595955959659597595985959959600596015960259603596045960559606596075960859609596105961159612596135961459615596165961759618596195962059621596225962359624596255962659627596285962959630596315963259633596345963559636596375963859639596405964159642596435964459645596465964759648596495965059651596525965359654596555965659657596585965959660596615966259663596645966559666596675966859669596705967159672596735967459675596765967759678596795968059681596825968359684596855968659687596885968959690596915969259693596945969559696596975969859699597005970159702597035970459705597065970759708597095971059711597125971359714597155971659717597185971959720597215972259723597245972559726597275972859729597305973159732597335973459735597365973759738597395974059741597425974359744597455974659747597485974959750597515975259753597545975559756597575975859759597605976159762597635976459765597665976759768597695977059771597725977359774597755977659777597785977959780597815978259783597845978559786597875978859789597905979159792597935979459795597965979759798597995980059801598025980359804598055980659807598085980959810598115981259813598145981559816598175981859819598205982159822598235982459825598265982759828598295983059831598325983359834598355983659837598385983959840598415984259843598445984559846598475984859849598505985159852598535985459855598565985759858598595986059861598625986359864598655986659867598685986959870598715987259873598745987559876598775987859879598805988159882598835988459885598865988759888598895989059891598925989359894598955989659897598985989959900599015990259903599045990559906599075990859909599105991159912599135991459915599165991759918599195992059921599225992359924599255992659927599285992959930599315993259933599345993559936599375993859939599405994159942599435994459945599465994759948599495995059951599525995359954599555995659957599585995959960599615996259963599645996559966599675996859969599705997159972599735997459975599765997759978599795998059981599825998359984599855998659987599885998959990599915999259993599945999559996599975999859999600006000160002600036000460005600066000760008600096001060011600126001360014600156001660017600186001960020600216002260023600246002560026600276002860029600306003160032600336003460035600366003760038600396004060041600426004360044600456004660047600486004960050600516005260053600546005560056600576005860059600606006160062600636006460065600666006760068600696007060071600726007360074600756007660077600786007960080600816008260083600846008560086600876008860089600906009160092600936009460095600966009760098600996010060101601026010360104601056010660107601086010960110601116011260113601146011560116601176011860119601206012160122601236012460125601266012760128601296013060131601326013360134601356013660137601386013960140601416014260143601446014560146601476014860149601506015160152601536015460155601566015760158601596016060161601626016360164601656016660167601686016960170601716017260173601746017560176601776017860179601806018160182601836018460185601866018760188601896019060191601926019360194601956019660197601986019960200602016020260203602046020560206602076020860209602106021160212602136021460215602166021760218602196022060221602226022360224602256022660227602286022960230602316023260233602346023560236602376023860239602406024160242602436024460245602466024760248602496025060251602526025360254602556025660257602586025960260602616026260263602646026560266602676026860269602706027160272602736027460275602766027760278602796028060281602826028360284602856028660287602886028960290602916029260293602946029560296602976029860299603006030160302603036030460305603066030760308603096031060311603126031360314603156031660317603186031960320603216032260323603246032560326603276032860329603306033160332603336033460335603366033760338603396034060341603426034360344603456034660347603486034960350603516035260353603546035560356603576035860359603606036160362603636036460365603666036760368603696037060371603726037360374603756037660377603786037960380603816038260383603846038560386603876038860389603906039160392603936039460395603966039760398603996040060401604026040360404604056040660407604086040960410604116041260413604146041560416604176041860419604206042160422604236042460425604266042760428604296043060431604326043360434604356043660437604386043960440604416044260443604446044560446604476044860449604506045160452604536045460455604566045760458604596046060461604626046360464604656046660467604686046960470604716047260473604746047560476604776047860479604806048160482604836048460485604866048760488604896049060491604926049360494604956049660497604986049960500605016050260503605046050560506605076050860509605106051160512605136051460515605166051760518605196052060521605226052360524605256052660527605286052960530605316053260533605346053560536605376053860539605406054160542605436054460545605466054760548605496055060551605526055360554605556055660557605586055960560605616056260563605646056560566605676056860569605706057160572605736057460575605766057760578605796058060581605826058360584605856058660587605886058960590605916059260593605946059560596605976059860599606006060160602606036060460605606066060760608606096061060611606126061360614606156061660617606186061960620606216062260623606246062560626606276062860629606306063160632606336063460635606366063760638606396064060641606426064360644606456064660647606486064960650606516065260653606546065560656606576065860659606606066160662606636066460665606666066760668606696067060671606726067360674606756067660677606786067960680606816068260683606846068560686606876068860689606906069160692606936069460695606966069760698606996070060701607026070360704607056070660707607086070960710607116071260713607146071560716607176071860719607206072160722607236072460725607266072760728607296073060731607326073360734607356073660737607386073960740607416074260743607446074560746607476074860749607506075160752607536075460755607566075760758607596076060761607626076360764607656076660767607686076960770607716077260773607746077560776607776077860779607806078160782607836078460785607866078760788607896079060791607926079360794607956079660797607986079960800608016080260803608046080560806608076080860809608106081160812608136081460815608166081760818608196082060821608226082360824608256082660827608286082960830608316083260833608346083560836608376083860839608406084160842608436084460845608466084760848608496085060851608526085360854608556085660857608586085960860608616086260863608646086560866608676086860869608706087160872608736087460875608766087760878608796088060881608826088360884608856088660887608886088960890608916089260893608946089560896608976089860899609006090160902609036090460905609066090760908609096091060911609126091360914609156091660917609186091960920609216092260923609246092560926609276092860929609306093160932609336093460935609366093760938609396094060941609426094360944609456094660947609486094960950609516095260953609546095560956609576095860959609606096160962609636096460965609666096760968609696097060971609726097360974609756097660977609786097960980609816098260983609846098560986609876098860989609906099160992609936099460995609966099760998609996100061001610026100361004610056100661007610086100961010610116101261013610146101561016610176101861019610206102161022610236102461025610266102761028610296103061031610326103361034610356103661037610386103961040610416104261043610446104561046610476104861049610506105161052610536105461055610566105761058610596106061061610626106361064610656106661067610686106961070610716107261073610746107561076610776107861079610806108161082610836108461085610866108761088610896109061091610926109361094610956109661097610986109961100611016110261103611046110561106611076110861109611106111161112611136111461115611166111761118611196112061121611226112361124611256112661127611286112961130611316113261133611346113561136611376113861139611406114161142611436114461145611466114761148611496115061151611526115361154611556115661157611586115961160611616116261163611646116561166611676116861169611706117161172611736117461175611766117761178611796118061181611826118361184611856118661187611886118961190611916119261193611946119561196611976119861199612006120161202612036120461205612066120761208612096121061211612126121361214612156121661217612186121961220612216122261223612246122561226612276122861229612306123161232612336123461235612366123761238612396124061241612426124361244612456124661247612486124961250612516125261253612546125561256612576125861259612606126161262612636126461265612666126761268612696127061271612726127361274612756127661277612786127961280612816128261283612846128561286612876128861289612906129161292612936129461295612966129761298612996130061301613026130361304613056130661307613086130961310613116131261313613146131561316613176131861319613206132161322613236132461325613266132761328613296133061331613326133361334613356133661337613386133961340613416134261343613446134561346613476134861349613506135161352613536135461355613566135761358613596136061361613626136361364613656136661367613686136961370613716137261373613746137561376613776137861379613806138161382613836138461385613866138761388613896139061391613926139361394613956139661397613986139961400614016140261403614046140561406614076140861409614106141161412614136141461415614166141761418614196142061421614226142361424614256142661427614286142961430614316143261433614346143561436614376143861439614406144161442614436144461445614466144761448614496145061451614526145361454614556145661457614586145961460614616146261463614646146561466614676146861469614706147161472614736147461475614766147761478614796148061481614826148361484614856148661487614886148961490614916149261493614946149561496614976149861499615006150161502615036150461505615066150761508615096151061511615126151361514615156151661517615186151961520615216152261523615246152561526615276152861529615306153161532615336153461535615366153761538615396154061541615426154361544615456154661547615486154961550615516155261553615546155561556615576155861559615606156161562615636156461565615666156761568615696157061571615726157361574615756157661577615786157961580615816158261583615846158561586615876158861589615906159161592615936159461595615966159761598615996160061601616026160361604616056160661607616086160961610616116161261613616146161561616616176161861619616206162161622616236162461625616266162761628616296163061631616326163361634616356163661637616386163961640616416164261643616446164561646616476164861649616506165161652616536165461655616566165761658616596166061661616626166361664616656166661667616686166961670616716167261673616746167561676616776167861679616806168161682616836168461685616866168761688616896169061691616926169361694616956169661697616986169961700617016170261703617046170561706617076170861709617106171161712617136171461715617166171761718617196172061721617226172361724617256172661727617286172961730617316173261733617346173561736617376173861739617406174161742617436174461745617466174761748617496175061751617526175361754617556175661757617586175961760617616176261763617646176561766617676176861769617706177161772617736177461775617766177761778617796178061781617826178361784617856178661787617886178961790617916179261793617946179561796617976179861799618006180161802618036180461805618066180761808618096181061811618126181361814618156181661817618186181961820618216182261823618246182561826618276182861829618306183161832618336183461835618366183761838618396184061841618426184361844618456184661847618486184961850618516185261853618546185561856618576185861859618606186161862618636186461865618666186761868618696187061871618726187361874618756187661877618786187961880618816188261883618846188561886618876188861889618906189161892618936189461895618966189761898618996190061901619026190361904619056190661907619086190961910619116191261913619146191561916619176191861919619206192161922619236192461925619266192761928619296193061931619326193361934619356193661937619386193961940619416194261943619446194561946619476194861949619506195161952619536195461955619566195761958619596196061961619626196361964619656196661967619686196961970619716197261973619746197561976619776197861979619806198161982619836198461985619866198761988619896199061991619926199361994619956199661997619986199962000620016200262003620046200562006620076200862009620106201162012620136201462015620166201762018620196202062021620226202362024620256202662027620286202962030620316203262033620346203562036620376203862039620406204162042620436204462045620466204762048620496205062051620526205362054620556205662057620586205962060620616206262063620646206562066620676206862069620706207162072620736207462075620766207762078620796208062081620826208362084620856208662087620886208962090620916209262093620946209562096620976209862099621006210162102621036210462105621066210762108621096211062111621126211362114621156211662117621186211962120621216212262123621246212562126621276212862129621306213162132621336213462135621366213762138621396214062141621426214362144621456214662147621486214962150621516215262153621546215562156621576215862159621606216162162621636216462165621666216762168621696217062171621726217362174621756217662177621786217962180621816218262183621846218562186621876218862189621906219162192621936219462195621966219762198621996220062201622026220362204622056220662207622086220962210622116221262213622146221562216622176221862219622206222162222622236222462225622266222762228622296223062231622326223362234622356223662237622386223962240622416224262243622446224562246622476224862249622506225162252622536225462255622566225762258622596226062261622626226362264622656226662267622686226962270622716227262273622746227562276622776227862279622806228162282622836228462285622866228762288622896229062291622926229362294622956229662297622986229962300623016230262303623046230562306623076230862309623106231162312623136231462315623166231762318623196232062321623226232362324623256232662327623286232962330623316233262333623346233562336623376233862339623406234162342623436234462345623466234762348623496235062351623526235362354623556235662357623586235962360623616236262363623646236562366623676236862369623706237162372623736237462375623766237762378623796238062381623826238362384623856238662387623886238962390623916239262393623946239562396623976239862399624006240162402624036240462405624066240762408624096241062411624126241362414624156241662417624186241962420624216242262423624246242562426624276242862429624306243162432624336243462435624366243762438624396244062441624426244362444624456244662447624486244962450624516245262453624546245562456624576245862459624606246162462624636246462465624666246762468624696247062471624726247362474624756247662477624786247962480624816248262483624846248562486624876248862489624906249162492624936249462495624966249762498624996250062501625026250362504625056250662507625086250962510625116251262513625146251562516625176251862519625206252162522625236252462525625266252762528625296253062531625326253362534625356253662537625386253962540625416254262543625446254562546625476254862549625506255162552625536255462555625566255762558625596256062561625626256362564625656256662567625686256962570625716257262573625746257562576625776257862579625806258162582625836258462585625866258762588625896259062591625926259362594625956259662597625986259962600626016260262603626046260562606626076260862609626106261162612626136261462615626166261762618626196262062621626226262362624626256262662627626286262962630626316263262633626346263562636626376263862639626406264162642626436264462645626466264762648626496265062651626526265362654626556265662657626586265962660626616266262663626646266562666626676266862669626706267162672626736267462675626766267762678626796268062681626826268362684626856268662687626886268962690626916269262693626946269562696626976269862699627006270162702627036270462705627066270762708627096271062711627126271362714627156271662717627186271962720627216272262723627246272562726627276272862729627306273162732627336273462735627366273762738627396274062741627426274362744627456274662747627486274962750627516275262753627546275562756627576275862759627606276162762627636276462765627666276762768627696277062771627726277362774627756277662777627786277962780627816278262783627846278562786627876278862789627906279162792627936279462795627966279762798627996280062801628026280362804628056280662807628086280962810628116281262813628146281562816628176281862819628206282162822628236282462825628266282762828628296283062831628326283362834628356283662837628386283962840628416284262843628446284562846628476284862849628506285162852628536285462855628566285762858628596286062861628626286362864628656286662867628686286962870628716287262873628746287562876628776287862879628806288162882628836288462885628866288762888628896289062891628926289362894628956289662897628986289962900629016290262903629046290562906629076290862909629106291162912629136291462915629166291762918629196292062921629226292362924629256292662927629286292962930629316293262933629346293562936629376293862939629406294162942629436294462945629466294762948629496295062951629526295362954629556295662957629586295962960629616296262963629646296562966629676296862969629706297162972629736297462975629766297762978629796298062981629826298362984629856298662987629886298962990629916299262993629946299562996629976299862999630006300163002630036300463005630066300763008630096301063011630126301363014630156301663017630186301963020630216302263023630246302563026630276302863029630306303163032630336303463035630366303763038630396304063041630426304363044630456304663047630486304963050630516305263053630546305563056630576305863059630606306163062630636306463065630666306763068630696307063071630726307363074630756307663077630786307963080630816308263083630846308563086630876308863089630906309163092630936309463095630966309763098630996310063101631026310363104631056310663107631086310963110631116311263113631146311563116631176311863119631206312163122631236312463125631266312763128631296313063131631326313363134631356313663137631386313963140631416314263143631446314563146631476314863149631506315163152631536315463155631566315763158631596316063161631626316363164631656316663167631686316963170631716317263173631746317563176631776317863179631806318163182631836318463185631866318763188631896319063191631926319363194631956319663197631986319963200632016320263203632046320563206632076320863209632106321163212632136321463215632166321763218632196322063221632226322363224632256322663227632286322963230632316323263233632346323563236632376323863239632406324163242632436324463245632466324763248632496325063251632526325363254632556325663257632586325963260632616326263263632646326563266632676326863269632706327163272632736327463275632766327763278632796328063281632826328363284632856328663287632886328963290632916329263293632946329563296632976329863299633006330163302633036330463305633066330763308633096331063311633126331363314633156331663317633186331963320633216332263323633246332563326633276332863329633306333163332633336333463335633366333763338633396334063341633426334363344633456334663347633486334963350633516335263353633546335563356633576335863359633606336163362633636336463365633666336763368633696337063371633726337363374633756337663377633786337963380633816338263383633846338563386633876338863389633906339163392633936339463395633966339763398633996340063401634026340363404634056340663407634086340963410634116341263413634146341563416634176341863419634206342163422634236342463425634266342763428634296343063431634326343363434634356343663437634386343963440634416344263443634446344563446634476344863449634506345163452634536345463455634566345763458634596346063461634626346363464634656346663467634686346963470634716347263473634746347563476634776347863479634806348163482634836348463485634866348763488634896349063491634926349363494634956349663497634986349963500635016350263503635046350563506635076350863509635106351163512635136351463515635166351763518635196352063521635226352363524635256352663527635286352963530635316353263533635346353563536635376353863539635406354163542635436354463545635466354763548635496355063551635526355363554635556355663557635586355963560635616356263563635646356563566635676356863569635706357163572635736357463575635766357763578635796358063581635826358363584635856358663587635886358963590635916359263593635946359563596635976359863599636006360163602636036360463605636066360763608636096361063611636126361363614636156361663617636186361963620636216362263623636246362563626636276362863629636306363163632636336363463635636366363763638636396364063641636426364363644636456364663647636486364963650636516365263653636546365563656636576365863659636606366163662636636366463665636666366763668636696367063671636726367363674636756367663677636786367963680636816368263683636846368563686636876368863689636906369163692636936369463695636966369763698636996370063701637026370363704637056370663707637086370963710637116371263713637146371563716637176371863719637206372163722637236372463725637266372763728637296373063731637326373363734637356373663737637386373963740637416374263743637446374563746637476374863749637506375163752637536375463755637566375763758637596376063761637626376363764637656376663767637686376963770637716377263773637746377563776637776377863779637806378163782637836378463785637866378763788637896379063791637926379363794637956379663797637986379963800638016380263803638046380563806638076380863809638106381163812638136381463815638166381763818638196382063821638226382363824638256382663827638286382963830638316383263833638346383563836638376383863839638406384163842638436384463845638466384763848638496385063851638526385363854638556385663857638586385963860638616386263863638646386563866638676386863869638706387163872638736387463875638766387763878638796388063881638826388363884638856388663887638886388963890638916389263893638946389563896638976389863899639006390163902639036390463905639066390763908639096391063911639126391363914639156391663917639186391963920639216392263923639246392563926639276392863929639306393163932639336393463935639366393763938639396394063941639426394363944639456394663947639486394963950639516395263953639546395563956639576395863959639606396163962639636396463965639666396763968639696397063971639726397363974639756397663977639786397963980639816398263983639846398563986639876398863989639906399163992639936399463995639966399763998639996400064001640026400364004640056400664007640086400964010640116401264013640146401564016640176401864019640206402164022640236402464025640266402764028640296403064031640326403364034640356403664037640386403964040640416404264043640446404564046640476404864049640506405164052640536405464055640566405764058640596406064061640626406364064640656406664067640686406964070640716407264073640746407564076640776407864079640806408164082640836408464085640866408764088640896409064091640926409364094640956409664097640986409964100641016410264103641046410564106641076410864109641106411164112641136411464115641166411764118641196412064121641226412364124641256412664127641286412964130641316413264133641346413564136641376413864139641406414164142641436414464145641466414764148641496415064151641526415364154641556415664157641586415964160641616416264163641646416564166641676416864169641706417164172641736417464175641766417764178641796418064181641826418364184641856418664187641886418964190641916419264193641946419564196641976419864199642006420164202642036420464205642066420764208642096421064211642126421364214642156421664217642186421964220642216422264223642246422564226642276422864229642306423164232642336423464235642366423764238642396424064241642426424364244642456424664247642486424964250642516425264253642546425564256642576425864259642606426164262642636426464265642666426764268642696427064271642726427364274642756427664277642786427964280642816428264283642846428564286642876428864289642906429164292642936429464295642966429764298642996430064301643026430364304643056430664307643086430964310643116431264313643146431564316643176431864319643206432164322643236432464325643266432764328643296433064331643326433364334643356433664337643386433964340643416434264343643446434564346643476434864349643506435164352643536435464355643566435764358643596436064361643626436364364643656436664367643686436964370643716437264373643746437564376643776437864379643806438164382643836438464385643866438764388643896439064391643926439364394643956439664397643986439964400644016440264403644046440564406644076440864409644106441164412644136441464415644166441764418644196442064421644226442364424644256442664427644286442964430644316443264433644346443564436644376443864439644406444164442644436444464445644466444764448644496445064451644526445364454644556445664457644586445964460644616446264463644646446564466644676446864469644706447164472644736447464475644766447764478644796448064481644826448364484644856448664487644886448964490644916449264493644946449564496644976449864499645006450164502645036450464505645066450764508645096451064511645126451364514645156451664517645186451964520645216452264523645246452564526645276452864529645306453164532645336453464535645366453764538645396454064541645426454364544645456454664547645486454964550645516455264553645546455564556645576455864559645606456164562645636456464565645666456764568645696457064571645726457364574645756457664577645786457964580645816458264583645846458564586645876458864589645906459164592645936459464595645966459764598645996460064601646026460364604646056460664607646086460964610646116461264613646146461564616646176461864619646206462164622646236462464625646266462764628646296463064631646326463364634646356463664637646386463964640646416464264643646446464564646646476464864649646506465164652646536465464655646566465764658646596466064661646626466364664646656466664667646686466964670646716467264673646746467564676646776467864679646806468164682646836468464685646866468764688646896469064691646926469364694646956469664697646986469964700647016470264703647046470564706647076470864709647106471164712647136471464715647166471764718647196472064721647226472364724647256472664727647286472964730647316473264733647346473564736647376473864739647406474164742647436474464745647466474764748647496475064751647526475364754647556475664757647586475964760647616476264763647646476564766647676476864769647706477164772647736477464775647766477764778647796478064781647826478364784647856478664787647886478964790647916479264793647946479564796647976479864799648006480164802648036480464805648066480764808648096481064811648126481364814648156481664817648186481964820648216482264823648246482564826648276482864829648306483164832648336483464835648366483764838648396484064841648426484364844648456484664847648486484964850648516485264853648546485564856648576485864859648606486164862648636486464865648666486764868648696487064871648726487364874648756487664877648786487964880648816488264883648846488564886648876488864889648906489164892648936489464895648966489764898648996490064901649026490364904649056490664907649086490964910649116491264913649146491564916649176491864919649206492164922649236492464925649266492764928649296493064931649326493364934649356493664937649386493964940649416494264943649446494564946649476494864949649506495164952649536495464955649566495764958649596496064961649626496364964649656496664967649686496964970649716497264973649746497564976649776497864979649806498164982649836498464985649866498764988649896499064991649926499364994649956499664997649986499965000650016500265003650046500565006650076500865009650106501165012650136501465015650166501765018650196502065021650226502365024650256502665027650286502965030650316503265033650346503565036650376503865039650406504165042650436504465045650466504765048650496505065051650526505365054650556505665057650586505965060650616506265063650646506565066650676506865069650706507165072650736507465075650766507765078650796508065081650826508365084650856508665087650886508965090650916509265093650946509565096650976509865099651006510165102651036510465105651066510765108651096511065111651126511365114651156511665117651186511965120651216512265123651246512565126651276512865129651306513165132651336513465135651366513765138651396514065141651426514365144651456514665147651486514965150651516515265153651546515565156651576515865159651606516165162651636516465165651666516765168651696517065171651726517365174651756517665177651786517965180651816518265183651846518565186651876518865189651906519165192651936519465195651966519765198651996520065201652026520365204652056520665207652086520965210652116521265213652146521565216652176521865219652206522165222652236522465225652266522765228652296523065231652326523365234652356523665237652386523965240652416524265243652446524565246652476524865249652506525165252652536525465255652566525765258652596526065261652626526365264652656526665267652686526965270652716527265273652746527565276652776527865279652806528165282652836528465285652866528765288652896529065291652926529365294652956529665297652986529965300653016530265303653046530565306653076530865309653106531165312653136531465315653166531765318653196532065321653226532365324653256532665327653286532965330653316533265333653346533565336653376533865339653406534165342653436534465345653466534765348653496535065351653526535365354653556535665357653586535965360653616536265363653646536565366653676536865369653706537165372653736537465375653766537765378653796538065381653826538365384653856538665387653886538965390653916539265393653946539565396653976539865399654006540165402654036540465405654066540765408654096541065411654126541365414654156541665417654186541965420654216542265423654246542565426654276542865429654306543165432654336543465435654366543765438654396544065441654426544365444654456544665447654486544965450654516545265453654546545565456654576545865459654606546165462654636546465465654666546765468654696547065471654726547365474654756547665477654786547965480654816548265483654846548565486654876548865489654906549165492654936549465495654966549765498654996550065501655026550365504655056550665507655086550965510655116551265513655146551565516655176551865519655206552165522655236552465525655266552765528655296553065531655326553365534655356553665537655386553965540655416554265543655446554565546655476554865549655506555165552655536555465555655566555765558655596556065561655626556365564655656556665567655686556965570655716557265573655746557565576655776557865579655806558165582655836558465585655866558765588655896559065591655926559365594655956559665597655986559965600656016560265603656046560565606656076560865609656106561165612656136561465615656166561765618656196562065621656226562365624656256562665627656286562965630656316563265633656346563565636656376563865639656406564165642656436564465645656466564765648656496565065651656526565365654656556565665657656586565965660656616566265663656646566565666656676566865669656706567165672656736567465675656766567765678656796568065681656826568365684656856568665687656886568965690656916569265693656946569565696656976569865699657006570165702657036570465705657066570765708657096571065711657126571365714657156571665717657186571965720657216572265723657246572565726657276572865729657306573165732657336573465735657366573765738657396574065741657426574365744657456574665747657486574965750657516575265753657546575565756657576575865759657606576165762657636576465765657666576765768657696577065771657726577365774657756577665777657786577965780657816578265783657846578565786657876578865789657906579165792657936579465795657966579765798657996580065801658026580365804658056580665807658086580965810658116581265813658146581565816658176581865819658206582165822658236582465825658266582765828658296583065831658326583365834658356583665837658386583965840658416584265843658446584565846658476584865849658506585165852658536585465855658566585765858658596586065861658626586365864658656586665867658686586965870658716587265873658746587565876658776587865879658806588165882658836588465885658866588765888658896589065891658926589365894658956589665897658986589965900659016590265903659046590565906659076590865909659106591165912659136591465915659166591765918659196592065921659226592365924659256592665927659286592965930659316593265933659346593565936659376593865939659406594165942659436594465945659466594765948659496595065951659526595365954659556595665957659586595965960659616596265963659646596565966659676596865969659706597165972659736597465975659766597765978659796598065981659826598365984659856598665987659886598965990659916599265993659946599565996659976599865999660006600166002660036600466005660066600766008660096601066011660126601366014660156601666017660186601966020660216602266023660246602566026660276602866029660306603166032660336603466035660366603766038660396604066041660426604366044660456604666047660486604966050660516605266053660546605566056660576605866059660606606166062660636606466065660666606766068660696607066071660726607366074660756607666077660786607966080660816608266083660846608566086660876608866089660906609166092660936609466095660966609766098660996610066101661026610366104661056610666107661086610966110661116611266113661146611566116661176611866119661206612166122661236612466125661266612766128661296613066131661326613366134661356613666137661386613966140661416614266143661446614566146661476614866149661506615166152661536615466155661566615766158661596616066161661626616366164661656616666167661686616966170661716617266173661746617566176661776617866179661806618166182661836618466185661866618766188661896619066191661926619366194661956619666197661986619966200662016620266203662046620566206662076620866209662106621166212662136621466215662166621766218662196622066221662226622366224662256622666227662286622966230662316623266233662346623566236662376623866239662406624166242662436624466245662466624766248662496625066251662526625366254662556625666257662586625966260662616626266263662646626566266662676626866269662706627166272662736627466275662766627766278662796628066281662826628366284662856628666287662886628966290662916629266293662946629566296662976629866299663006630166302663036630466305663066630766308663096631066311663126631366314663156631666317663186631966320663216632266323663246632566326663276632866329663306633166332663336633466335663366633766338663396634066341663426634366344663456634666347663486634966350663516635266353663546635566356663576635866359663606636166362663636636466365663666636766368663696637066371663726637366374663756637666377663786637966380663816638266383663846638566386663876638866389663906639166392663936639466395663966639766398663996640066401664026640366404664056640666407664086640966410664116641266413664146641566416664176641866419664206642166422664236642466425664266642766428664296643066431664326643366434664356643666437664386643966440664416644266443664446644566446664476644866449664506645166452664536645466455664566645766458664596646066461664626646366464664656646666467664686646966470664716647266473664746647566476664776647866479664806648166482664836648466485664866648766488664896649066491664926649366494664956649666497664986649966500665016650266503665046650566506665076650866509665106651166512665136651466515665166651766518665196652066521665226652366524665256652666527665286652966530665316653266533665346653566536665376653866539665406654166542665436654466545665466654766548665496655066551665526655366554665556655666557665586655966560665616656266563665646656566566665676656866569665706657166572665736657466575665766657766578665796658066581665826658366584665856658666587665886658966590665916659266593665946659566596665976659866599666006660166602666036660466605666066660766608666096661066611666126661366614666156661666617666186661966620666216662266623666246662566626666276662866629666306663166632666336663466635666366663766638666396664066641666426664366644666456664666647666486664966650666516665266653666546665566656666576665866659666606666166662666636666466665666666666766668666696667066671666726667366674666756667666677666786667966680666816668266683666846668566686666876668866689666906669166692666936669466695666966669766698666996670066701667026670366704667056670666707667086670966710667116671266713667146671566716667176671866719667206672166722667236672466725667266672766728667296673066731667326673366734667356673666737667386673966740667416674266743667446674566746667476674866749667506675166752667536675466755667566675766758667596676066761667626676366764667656676666767667686676966770667716677266773667746677566776667776677866779667806678166782667836678466785667866678766788667896679066791667926679366794667956679666797667986679966800668016680266803668046680566806668076680866809668106681166812668136681466815668166681766818668196682066821668226682366824668256682666827668286682966830668316683266833668346683566836668376683866839668406684166842668436684466845668466684766848668496685066851668526685366854668556685666857668586685966860668616686266863668646686566866668676686866869668706687166872668736687466875668766687766878668796688066881668826688366884668856688666887668886688966890668916689266893668946689566896668976689866899669006690166902669036690466905669066690766908669096691066911669126691366914669156691666917669186691966920669216692266923669246692566926669276692866929669306693166932669336693466935669366693766938669396694066941669426694366944669456694666947669486694966950669516695266953669546695566956669576695866959669606696166962669636696466965669666696766968669696697066971669726697366974669756697666977669786697966980669816698266983669846698566986669876698866989669906699166992669936699466995669966699766998669996700067001670026700367004670056700667007670086700967010670116701267013670146701567016670176701867019670206702167022670236702467025670266702767028670296703067031670326703367034670356703667037670386703967040670416704267043670446704567046670476704867049670506705167052670536705467055670566705767058670596706067061670626706367064670656706667067670686706967070670716707267073670746707567076670776707867079670806708167082670836708467085670866708767088670896709067091670926709367094670956709667097670986709967100671016710267103671046710567106671076710867109671106711167112671136711467115671166711767118671196712067121671226712367124671256712667127671286712967130671316713267133671346713567136671376713867139671406714167142671436714467145671466714767148671496715067151671526715367154671556715667157671586715967160671616716267163671646716567166671676716867169671706717167172671736717467175671766717767178671796718067181671826718367184671856718667187671886718967190671916719267193671946719567196671976719867199672006720167202672036720467205672066720767208672096721067211672126721367214672156721667217672186721967220672216722267223672246722567226672276722867229672306723167232672336723467235672366723767238672396724067241672426724367244672456724667247672486724967250672516725267253672546725567256672576725867259672606726167262672636726467265672666726767268672696727067271672726727367274672756727667277672786727967280672816728267283672846728567286672876728867289672906729167292672936729467295672966729767298672996730067301673026730367304673056730667307673086730967310673116731267313673146731567316673176731867319673206732167322673236732467325673266732767328673296733067331673326733367334673356733667337673386733967340673416734267343673446734567346673476734867349673506735167352673536735467355673566735767358673596736067361673626736367364673656736667367673686736967370673716737267373673746737567376673776737867379673806738167382673836738467385673866738767388673896739067391673926739367394673956739667397673986739967400674016740267403674046740567406674076740867409674106741167412674136741467415674166741767418674196742067421674226742367424674256742667427674286742967430674316743267433674346743567436674376743867439674406744167442674436744467445674466744767448674496745067451674526745367454674556745667457674586745967460674616746267463674646746567466674676746867469674706747167472674736747467475674766747767478674796748067481674826748367484674856748667487674886748967490674916749267493674946749567496674976749867499675006750167502675036750467505675066750767508675096751067511675126751367514675156751667517675186751967520675216752267523675246752567526675276752867529675306753167532675336753467535675366753767538675396754067541675426754367544675456754667547675486754967550675516755267553675546755567556675576755867559675606756167562675636756467565675666756767568675696757067571675726757367574675756757667577675786757967580675816758267583675846758567586675876758867589675906759167592675936759467595675966759767598675996760067601676026760367604676056760667607676086760967610676116761267613676146761567616676176761867619676206762167622676236762467625676266762767628676296763067631676326763367634676356763667637676386763967640676416764267643676446764567646676476764867649676506765167652676536765467655676566765767658676596766067661676626766367664676656766667667676686766967670676716767267673676746767567676676776767867679676806768167682676836768467685676866768767688676896769067691676926769367694676956769667697676986769967700677016770267703677046770567706677076770867709677106771167712677136771467715677166771767718677196772067721677226772367724677256772667727677286772967730677316773267733677346773567736677376773867739677406774167742677436774467745677466774767748677496775067751677526775367754677556775667757677586775967760677616776267763677646776567766677676776867769677706777167772677736777467775677766777767778677796778067781677826778367784677856778667787677886778967790677916779267793677946779567796677976779867799678006780167802678036780467805678066780767808678096781067811678126781367814678156781667817678186781967820678216782267823678246782567826678276782867829678306783167832678336783467835678366783767838678396784067841678426784367844678456784667847678486784967850678516785267853678546785567856678576785867859678606786167862678636786467865678666786767868678696787067871678726787367874678756787667877678786787967880678816788267883678846788567886678876788867889678906789167892678936789467895678966789767898678996790067901679026790367904679056790667907679086790967910679116791267913679146791567916679176791867919679206792167922679236792467925679266792767928679296793067931679326793367934679356793667937679386793967940679416794267943679446794567946679476794867949679506795167952679536795467955679566795767958679596796067961679626796367964679656796667967679686796967970679716797267973679746797567976679776797867979679806798167982679836798467985679866798767988679896799067991679926799367994679956799667997679986799968000680016800268003680046800568006680076800868009680106801168012680136801468015680166801768018680196802068021680226802368024680256802668027680286802968030680316803268033680346803568036680376803868039680406804168042680436804468045680466804768048680496805068051680526805368054680556805668057680586805968060680616806268063680646806568066680676806868069680706807168072680736807468075680766807768078680796808068081680826808368084680856808668087680886808968090680916809268093680946809568096680976809868099681006810168102681036810468105681066810768108681096811068111681126811368114681156811668117681186811968120681216812268123681246812568126681276812868129681306813168132681336813468135681366813768138681396814068141681426814368144681456814668147681486814968150681516815268153681546815568156681576815868159681606816168162681636816468165681666816768168681696817068171681726817368174681756817668177681786817968180681816818268183681846818568186681876818868189681906819168192681936819468195681966819768198681996820068201682026820368204682056820668207682086820968210682116821268213682146821568216682176821868219682206822168222682236822468225682266822768228682296823068231682326823368234682356823668237682386823968240682416824268243682446824568246682476824868249682506825168252682536825468255682566825768258682596826068261682626826368264682656826668267682686826968270682716827268273682746827568276682776827868279682806828168282682836828468285682866828768288682896829068291682926829368294682956829668297682986829968300683016830268303683046830568306683076830868309683106831168312683136831468315683166831768318683196832068321683226832368324683256832668327683286832968330683316833268333683346833568336683376833868339683406834168342683436834468345683466834768348683496835068351683526835368354683556835668357683586835968360683616836268363683646836568366683676836868369683706837168372683736837468375683766837768378683796838068381683826838368384683856838668387683886838968390683916839268393683946839568396683976839868399684006840168402684036840468405684066840768408684096841068411684126841368414684156841668417684186841968420684216842268423684246842568426684276842868429684306843168432684336843468435684366843768438684396844068441684426844368444684456844668447684486844968450684516845268453684546845568456684576845868459684606846168462684636846468465684666846768468684696847068471684726847368474684756847668477684786847968480684816848268483684846848568486684876848868489684906849168492684936849468495684966849768498684996850068501685026850368504685056850668507685086850968510685116851268513685146851568516685176851868519685206852168522685236852468525685266852768528685296853068531685326853368534685356853668537685386853968540685416854268543685446854568546685476854868549685506855168552685536855468555685566855768558685596856068561685626856368564685656856668567685686856968570685716857268573685746857568576685776857868579685806858168582685836858468585685866858768588685896859068591685926859368594685956859668597685986859968600686016860268603686046860568606686076860868609686106861168612686136861468615686166861768618686196862068621686226862368624686256862668627686286862968630686316863268633686346863568636686376863868639686406864168642686436864468645686466864768648686496865068651686526865368654686556865668657686586865968660686616866268663686646866568666686676866868669686706867168672686736867468675686766867768678686796868068681686826868368684686856868668687686886868968690686916869268693686946869568696686976869868699687006870168702687036870468705687066870768708687096871068711687126871368714687156871668717687186871968720687216872268723687246872568726687276872868729687306873168732687336873468735687366873768738687396874068741687426874368744687456874668747687486874968750687516875268753687546875568756687576875868759687606876168762687636876468765687666876768768687696877068771687726877368774687756877668777687786877968780687816878268783687846878568786687876878868789687906879168792687936879468795687966879768798687996880068801688026880368804688056880668807688086880968810688116881268813688146881568816688176881868819688206882168822688236882468825688266882768828688296883068831688326883368834688356883668837688386883968840688416884268843688446884568846688476884868849688506885168852688536885468855688566885768858688596886068861688626886368864688656886668867688686886968870688716887268873688746887568876688776887868879688806888168882688836888468885688866888768888688896889068891688926889368894688956889668897688986889968900689016890268903689046890568906689076890868909689106891168912689136891468915689166891768918689196892068921689226892368924689256892668927689286892968930689316893268933689346893568936689376893868939689406894168942689436894468945689466894768948689496895068951689526895368954689556895668957689586895968960689616896268963689646896568966689676896868969689706897168972689736897468975689766897768978689796898068981689826898368984689856898668987689886898968990689916899268993689946899568996689976899868999690006900169002690036900469005690066900769008690096901069011690126901369014690156901669017690186901969020690216902269023690246902569026690276902869029690306903169032690336903469035690366903769038690396904069041690426904369044690456904669047690486904969050690516905269053690546905569056690576905869059690606906169062690636906469065690666906769068690696907069071690726907369074690756907669077690786907969080690816908269083690846908569086690876908869089690906909169092690936909469095690966909769098690996910069101691026910369104691056910669107691086910969110691116911269113691146911569116691176911869119691206912169122691236912469125691266912769128691296913069131691326913369134691356913669137691386913969140691416914269143691446914569146691476914869149691506915169152691536915469155691566915769158691596916069161691626916369164691656916669167691686916969170691716917269173691746917569176691776917869179691806918169182691836918469185691866918769188691896919069191691926919369194691956919669197691986919969200692016920269203692046920569206692076920869209692106921169212692136921469215692166921769218692196922069221692226922369224692256922669227692286922969230692316923269233692346923569236692376923869239692406924169242692436924469245692466924769248692496925069251692526925369254692556925669257692586925969260692616926269263692646926569266692676926869269692706927169272692736927469275692766927769278692796928069281692826928369284692856928669287692886928969290692916929269293692946929569296692976929869299693006930169302693036930469305693066930769308693096931069311693126931369314693156931669317693186931969320693216932269323693246932569326693276932869329693306933169332693336933469335693366933769338693396934069341693426934369344693456934669347693486934969350693516935269353693546935569356693576935869359693606936169362693636936469365693666936769368693696937069371693726937369374693756937669377693786937969380693816938269383693846938569386693876938869389693906939169392693936939469395693966939769398693996940069401694026940369404694056940669407694086940969410694116941269413694146941569416694176941869419694206942169422694236942469425694266942769428694296943069431694326943369434694356943669437694386943969440694416944269443694446944569446694476944869449694506945169452694536945469455694566945769458694596946069461694626946369464694656946669467694686946969470694716947269473694746947569476694776947869479694806948169482694836948469485694866948769488694896949069491694926949369494694956949669497694986949969500695016950269503695046950569506695076950869509695106951169512695136951469515695166951769518695196952069521695226952369524695256952669527695286952969530695316953269533695346953569536695376953869539695406954169542695436954469545695466954769548695496955069551695526955369554695556955669557695586955969560695616956269563695646956569566695676956869569695706957169572695736957469575695766957769578695796958069581695826958369584695856958669587695886958969590695916959269593695946959569596695976959869599696006960169602696036960469605696066960769608696096961069611696126961369614696156961669617696186961969620696216962269623696246962569626696276962869629696306963169632696336963469635696366963769638696396964069641696426964369644696456964669647696486964969650696516965269653696546965569656696576965869659696606966169662696636966469665696666966769668696696967069671696726967369674696756967669677696786967969680696816968269683696846968569686696876968869689696906969169692696936969469695696966969769698696996970069701697026970369704697056970669707697086970969710697116971269713697146971569716697176971869719697206972169722697236972469725697266972769728697296973069731697326973369734697356973669737697386973969740697416974269743697446974569746697476974869749697506975169752697536975469755697566975769758697596976069761697626976369764697656976669767697686976969770697716977269773697746977569776697776977869779697806978169782697836978469785697866978769788697896979069791697926979369794697956979669797697986979969800698016980269803698046980569806698076980869809698106981169812698136981469815698166981769818698196982069821698226982369824698256982669827698286982969830698316983269833698346983569836698376983869839698406984169842698436984469845698466984769848698496985069851698526985369854698556985669857698586985969860698616986269863698646986569866698676986869869698706987169872698736987469875698766987769878698796988069881698826988369884698856988669887698886988969890698916989269893698946989569896698976989869899699006990169902699036990469905699066990769908699096991069911699126991369914699156991669917699186991969920699216992269923699246992569926699276992869929699306993169932699336993469935699366993769938699396994069941699426994369944699456994669947699486994969950699516995269953699546995569956699576995869959699606996169962699636996469965699666996769968699696997069971699726997369974699756997669977699786997969980699816998269983699846998569986699876998869989699906999169992699936999469995699966999769998699997000070001700027000370004700057000670007700087000970010700117001270013700147001570016700177001870019700207002170022700237002470025700267002770028700297003070031700327003370034700357003670037700387003970040700417004270043700447004570046700477004870049700507005170052700537005470055700567005770058700597006070061700627006370064700657006670067700687006970070700717007270073700747007570076700777007870079700807008170082700837008470085700867008770088700897009070091700927009370094700957009670097700987009970100701017010270103701047010570106701077010870109701107011170112701137011470115701167011770118701197012070121701227012370124701257012670127701287012970130701317013270133701347013570136701377013870139701407014170142701437014470145701467014770148701497015070151701527015370154701557015670157701587015970160701617016270163701647016570166701677016870169701707017170172701737017470175701767017770178701797018070181701827018370184701857018670187701887018970190701917019270193701947019570196701977019870199702007020170202702037020470205702067020770208702097021070211702127021370214702157021670217702187021970220702217022270223702247022570226702277022870229702307023170232702337023470235702367023770238702397024070241702427024370244702457024670247702487024970250702517025270253702547025570256702577025870259702607026170262702637026470265702667026770268702697027070271702727027370274702757027670277702787027970280702817028270283702847028570286702877028870289702907029170292702937029470295702967029770298702997030070301703027030370304703057030670307703087030970310703117031270313703147031570316703177031870319703207032170322703237032470325703267032770328703297033070331703327033370334703357033670337703387033970340703417034270343703447034570346703477034870349703507035170352703537035470355703567035770358703597036070361703627036370364703657036670367703687036970370703717037270373703747037570376703777037870379703807038170382703837038470385703867038770388703897039070391703927039370394703957039670397703987039970400704017040270403704047040570406704077040870409704107041170412704137041470415704167041770418704197042070421704227042370424704257042670427704287042970430704317043270433704347043570436704377043870439704407044170442704437044470445704467044770448704497045070451704527045370454704557045670457704587045970460704617046270463704647046570466704677046870469704707047170472704737047470475704767047770478704797048070481704827048370484704857048670487704887048970490704917049270493704947049570496704977049870499705007050170502705037050470505705067050770508705097051070511705127051370514705157051670517705187051970520705217052270523705247052570526705277052870529705307053170532705337053470535705367053770538705397054070541705427054370544705457054670547705487054970550705517055270553705547055570556705577055870559705607056170562705637056470565705667056770568705697057070571705727057370574705757057670577705787057970580705817058270583705847058570586705877058870589705907059170592705937059470595705967059770598705997060070601706027060370604706057060670607706087060970610706117061270613706147061570616706177061870619706207062170622706237062470625706267062770628706297063070631706327063370634706357063670637706387063970640706417064270643706447064570646706477064870649706507065170652706537065470655706567065770658706597066070661706627066370664706657066670667706687066970670706717067270673706747067570676706777067870679706807068170682706837068470685706867068770688706897069070691706927069370694706957069670697706987069970700707017070270703707047070570706707077070870709707107071170712707137071470715707167071770718707197072070721707227072370724707257072670727707287072970730707317073270733707347073570736707377073870739707407074170742707437074470745707467074770748707497075070751707527075370754707557075670757707587075970760707617076270763707647076570766707677076870769707707077170772707737077470775707767077770778707797078070781707827078370784707857078670787707887078970790707917079270793707947079570796707977079870799708007080170802708037080470805708067080770808708097081070811708127081370814708157081670817708187081970820708217082270823708247082570826708277082870829708307083170832708337083470835708367083770838708397084070841708427084370844708457084670847708487084970850708517085270853708547085570856708577085870859708607086170862708637086470865708667086770868708697087070871708727087370874708757087670877708787087970880708817088270883708847088570886708877088870889708907089170892708937089470895708967089770898708997090070901709027090370904709057090670907709087090970910709117091270913709147091570916709177091870919709207092170922709237092470925709267092770928709297093070931709327093370934709357093670937709387093970940709417094270943709447094570946709477094870949709507095170952709537095470955709567095770958709597096070961709627096370964709657096670967709687096970970709717097270973709747097570976709777097870979709807098170982709837098470985709867098770988709897099070991709927099370994709957099670997709987099971000710017100271003710047100571006710077100871009710107101171012710137101471015710167101771018710197102071021710227102371024710257102671027710287102971030710317103271033710347103571036710377103871039710407104171042710437104471045710467104771048710497105071051710527105371054710557105671057710587105971060710617106271063710647106571066710677106871069710707107171072710737107471075710767107771078710797108071081710827108371084710857108671087710887108971090710917109271093710947109571096710977109871099711007110171102711037110471105711067110771108711097111071111711127111371114711157111671117711187111971120711217112271123711247112571126711277112871129711307113171132711337113471135711367113771138711397114071141711427114371144711457114671147711487114971150711517115271153711547115571156711577115871159711607116171162711637116471165711667116771168711697117071171711727117371174711757117671177711787117971180711817118271183711847118571186711877118871189711907119171192711937119471195711967119771198711997120071201712027120371204712057120671207712087120971210712117121271213712147121571216712177121871219712207122171222712237122471225712267122771228712297123071231712327123371234712357123671237712387123971240712417124271243712447124571246712477124871249712507125171252712537125471255712567125771258712597126071261712627126371264712657126671267712687126971270712717127271273712747127571276712777127871279712807128171282712837128471285712867128771288712897129071291712927129371294712957129671297712987129971300713017130271303713047130571306713077130871309713107131171312713137131471315713167131771318713197132071321713227132371324713257132671327713287132971330713317133271333713347133571336713377133871339713407134171342713437134471345713467134771348713497135071351713527135371354713557135671357713587135971360713617136271363713647136571366713677136871369713707137171372713737137471375713767137771378713797138071381713827138371384713857138671387713887138971390713917139271393713947139571396713977139871399714007140171402714037140471405714067140771408714097141071411714127141371414714157141671417714187141971420714217142271423714247142571426714277142871429714307143171432714337143471435714367143771438714397144071441714427144371444714457144671447714487144971450714517145271453714547145571456714577145871459714607146171462714637146471465714667146771468714697147071471714727147371474714757147671477714787147971480714817148271483714847148571486714877148871489714907149171492714937149471495714967149771498714997150071501715027150371504715057150671507715087150971510715117151271513715147151571516715177151871519715207152171522715237152471525715267152771528715297153071531715327153371534715357153671537715387153971540715417154271543715447154571546715477154871549715507155171552715537155471555715567155771558715597156071561715627156371564715657156671567715687156971570715717157271573715747157571576715777157871579715807158171582715837158471585715867158771588715897159071591715927159371594715957159671597715987159971600716017160271603716047160571606716077160871609716107161171612716137161471615716167161771618716197162071621716227162371624716257162671627716287162971630716317163271633716347163571636716377163871639716407164171642716437164471645716467164771648716497165071651716527165371654716557165671657716587165971660716617166271663716647166571666716677166871669716707167171672716737167471675716767167771678716797168071681716827168371684716857168671687716887168971690716917169271693716947169571696716977169871699717007170171702717037170471705717067170771708717097171071711717127171371714717157171671717717187171971720717217172271723717247172571726717277172871729717307173171732717337173471735717367173771738717397174071741717427174371744717457174671747717487174971750717517175271753717547175571756717577175871759717607176171762717637176471765717667176771768717697177071771717727177371774717757177671777717787177971780717817178271783717847178571786717877178871789717907179171792717937179471795717967179771798717997180071801718027180371804718057180671807718087180971810718117181271813718147181571816718177181871819718207182171822718237182471825718267182771828718297183071831718327183371834718357183671837718387183971840718417184271843718447184571846718477184871849718507185171852718537185471855718567185771858718597186071861718627186371864718657186671867718687186971870718717187271873718747187571876718777187871879718807188171882718837188471885718867188771888718897189071891718927189371894718957189671897718987189971900719017190271903719047190571906719077190871909719107191171912719137191471915719167191771918719197192071921719227192371924719257192671927719287192971930719317193271933719347193571936719377193871939719407194171942719437194471945719467194771948719497195071951719527195371954719557195671957719587195971960719617196271963719647196571966719677196871969719707197171972719737197471975719767197771978719797198071981719827198371984719857198671987719887198971990719917199271993719947199571996719977199871999720007200172002720037200472005720067200772008720097201072011720127201372014720157201672017720187201972020720217202272023720247202572026720277202872029720307203172032720337203472035720367203772038720397204072041720427204372044720457204672047720487204972050720517205272053720547205572056720577205872059720607206172062720637206472065720667206772068720697207072071720727207372074720757207672077720787207972080720817208272083720847208572086720877208872089720907209172092720937209472095720967209772098720997210072101721027210372104721057210672107721087210972110721117211272113721147211572116721177211872119721207212172122721237212472125721267212772128721297213072131721327213372134721357213672137721387213972140721417214272143721447214572146721477214872149721507215172152721537215472155721567215772158721597216072161721627216372164721657216672167721687216972170721717217272173721747217572176721777217872179721807218172182721837218472185721867218772188721897219072191721927219372194721957219672197721987219972200722017220272203722047220572206722077220872209722107221172212722137221472215722167221772218722197222072221722227222372224722257222672227722287222972230722317223272233722347223572236722377223872239722407224172242722437224472245722467224772248722497225072251722527225372254722557225672257722587225972260722617226272263722647226572266722677226872269722707227172272722737227472275722767227772278722797228072281722827228372284722857228672287722887228972290722917229272293722947229572296722977229872299723007230172302723037230472305723067230772308723097231072311723127231372314723157231672317723187231972320723217232272323723247232572326723277232872329723307233172332723337233472335723367233772338723397234072341723427234372344723457234672347723487234972350723517235272353723547235572356723577235872359723607236172362723637236472365723667236772368723697237072371723727237372374723757237672377723787237972380723817238272383723847238572386723877238872389723907239172392723937239472395723967239772398723997240072401724027240372404724057240672407724087240972410724117241272413724147241572416724177241872419724207242172422724237242472425724267242772428724297243072431724327243372434724357243672437724387243972440724417244272443724447244572446724477244872449724507245172452724537245472455724567245772458724597246072461724627246372464724657246672467724687246972470724717247272473724747247572476724777247872479724807248172482724837248472485724867248772488724897249072491724927249372494724957249672497724987249972500725017250272503725047250572506725077250872509725107251172512725137251472515725167251772518725197252072521725227252372524725257252672527725287252972530725317253272533725347253572536725377253872539725407254172542725437254472545725467254772548725497255072551725527255372554725557255672557725587255972560725617256272563725647256572566725677256872569725707257172572725737257472575725767257772578725797258072581725827258372584725857258672587725887258972590725917259272593725947259572596725977259872599726007260172602726037260472605726067260772608726097261072611726127261372614726157261672617726187261972620726217262272623726247262572626726277262872629726307263172632726337263472635726367263772638726397264072641726427264372644726457264672647726487264972650726517265272653726547265572656726577265872659726607266172662726637266472665726667266772668726697267072671726727267372674726757267672677726787267972680726817268272683726847268572686726877268872689726907269172692726937269472695726967269772698726997270072701727027270372704727057270672707727087270972710727117271272713727147271572716727177271872719727207272172722727237272472725727267272772728727297273072731727327273372734727357273672737727387273972740727417274272743727447274572746727477274872749727507275172752727537275472755727567275772758727597276072761727627276372764727657276672767727687276972770727717277272773727747277572776727777277872779727807278172782727837278472785727867278772788727897279072791727927279372794727957279672797727987279972800728017280272803728047280572806728077280872809728107281172812728137281472815728167281772818728197282072821728227282372824728257282672827728287282972830728317283272833728347283572836728377283872839728407284172842728437284472845728467284772848728497285072851728527285372854728557285672857728587285972860728617286272863728647286572866728677286872869728707287172872728737287472875728767287772878728797288072881728827288372884728857288672887728887288972890728917289272893728947289572896728977289872899729007290172902729037290472905729067290772908729097291072911729127291372914729157291672917729187291972920729217292272923729247292572926729277292872929729307293172932729337293472935729367293772938729397294072941729427294372944729457294672947729487294972950729517295272953729547295572956729577295872959729607296172962729637296472965729667296772968729697297072971729727297372974729757297672977729787297972980729817298272983729847298572986729877298872989729907299172992729937299472995729967299772998729997300073001730027300373004730057300673007730087300973010730117301273013730147301573016730177301873019730207302173022730237302473025730267302773028730297303073031730327303373034730357303673037730387303973040730417304273043730447304573046730477304873049730507305173052730537305473055730567305773058730597306073061730627306373064730657306673067730687306973070730717307273073730747307573076730777307873079730807308173082730837308473085730867308773088730897309073091730927309373094730957309673097730987309973100731017310273103731047310573106731077310873109731107311173112731137311473115731167311773118731197312073121731227312373124731257312673127731287312973130731317313273133731347313573136731377313873139731407314173142731437314473145731467314773148731497315073151731527315373154731557315673157731587315973160731617316273163731647316573166731677316873169731707317173172731737317473175731767317773178731797318073181731827318373184731857318673187731887318973190731917319273193731947319573196731977319873199732007320173202732037320473205732067320773208732097321073211732127321373214732157321673217732187321973220732217322273223732247322573226732277322873229732307323173232732337323473235732367323773238732397324073241732427324373244732457324673247732487324973250732517325273253732547325573256732577325873259732607326173262732637326473265732667326773268732697327073271732727327373274732757327673277732787327973280732817328273283732847328573286732877328873289732907329173292732937329473295732967329773298732997330073301733027330373304733057330673307733087330973310733117331273313733147331573316733177331873319733207332173322733237332473325733267332773328733297333073331733327333373334733357333673337733387333973340733417334273343733447334573346733477334873349733507335173352733537335473355733567335773358733597336073361733627336373364733657336673367733687336973370733717337273373733747337573376733777337873379733807338173382733837338473385733867338773388733897339073391733927339373394733957339673397733987339973400734017340273403734047340573406734077340873409734107341173412734137341473415734167341773418734197342073421734227342373424734257342673427734287342973430734317343273433734347343573436734377343873439734407344173442734437344473445734467344773448734497345073451734527345373454734557345673457734587345973460734617346273463734647346573466734677346873469734707347173472734737347473475734767347773478734797348073481734827348373484734857348673487734887348973490734917349273493734947349573496734977349873499735007350173502735037350473505735067350773508735097351073511735127351373514735157351673517735187351973520735217352273523735247352573526735277352873529735307353173532735337353473535735367353773538735397354073541735427354373544735457354673547735487354973550735517355273553735547355573556735577355873559735607356173562735637356473565735667356773568735697357073571735727357373574735757357673577735787357973580735817358273583735847358573586735877358873589735907359173592735937359473595735967359773598735997360073601736027360373604736057360673607736087360973610736117361273613736147361573616736177361873619736207362173622736237362473625736267362773628736297363073631736327363373634736357363673637736387363973640736417364273643736447364573646736477364873649736507365173652736537365473655736567365773658736597366073661736627366373664736657366673667736687366973670736717367273673736747367573676736777367873679736807368173682736837368473685736867368773688736897369073691736927369373694736957369673697736987369973700737017370273703737047370573706737077370873709737107371173712737137371473715737167371773718737197372073721737227372373724737257372673727737287372973730737317373273733737347373573736737377373873739737407374173742737437374473745737467374773748737497375073751737527375373754737557375673757737587375973760737617376273763737647376573766737677376873769737707377173772737737377473775737767377773778737797378073781737827378373784737857378673787737887378973790737917379273793737947379573796737977379873799738007380173802738037380473805738067380773808738097381073811738127381373814738157381673817738187381973820738217382273823738247382573826738277382873829738307383173832738337383473835738367383773838738397384073841738427384373844738457384673847738487384973850738517385273853738547385573856738577385873859738607386173862738637386473865738667386773868738697387073871738727387373874738757387673877738787387973880738817388273883738847388573886738877388873889738907389173892738937389473895738967389773898738997390073901739027390373904739057390673907739087390973910739117391273913739147391573916739177391873919739207392173922739237392473925739267392773928739297393073931739327393373934739357393673937739387393973940739417394273943739447394573946739477394873949739507395173952739537395473955739567395773958739597396073961739627396373964739657396673967739687396973970739717397273973739747397573976739777397873979739807398173982739837398473985739867398773988739897399073991739927399373994739957399673997739987399974000740017400274003740047400574006740077400874009740107401174012740137401474015740167401774018740197402074021740227402374024740257402674027740287402974030740317403274033740347403574036740377403874039740407404174042740437404474045740467404774048740497405074051740527405374054740557405674057740587405974060740617406274063740647406574066740677406874069740707407174072740737407474075740767407774078740797408074081740827408374084740857408674087740887408974090740917409274093740947409574096740977409874099741007410174102741037410474105741067410774108741097411074111741127411374114741157411674117741187411974120741217412274123741247412574126741277412874129741307413174132741337413474135741367413774138741397414074141741427414374144741457414674147741487414974150741517415274153741547415574156741577415874159741607416174162741637416474165741667416774168741697417074171741727417374174741757417674177741787417974180741817418274183741847418574186741877418874189741907419174192741937419474195741967419774198741997420074201742027420374204742057420674207742087420974210742117421274213742147421574216742177421874219742207422174222742237422474225742267422774228742297423074231742327423374234742357423674237742387423974240742417424274243742447424574246742477424874249742507425174252742537425474255742567425774258742597426074261742627426374264742657426674267742687426974270742717427274273742747427574276742777427874279742807428174282742837428474285742867428774288742897429074291742927429374294742957429674297742987429974300743017430274303743047430574306743077430874309743107431174312743137431474315743167431774318743197432074321743227432374324743257432674327743287432974330743317433274333743347433574336743377433874339743407434174342743437434474345743467434774348743497435074351743527435374354743557435674357743587435974360743617436274363743647436574366743677436874369743707437174372743737437474375743767437774378743797438074381743827438374384743857438674387743887438974390743917439274393743947439574396743977439874399744007440174402744037440474405744067440774408744097441074411744127441374414744157441674417744187441974420744217442274423744247442574426744277442874429744307443174432744337443474435744367443774438744397444074441744427444374444744457444674447744487444974450744517445274453744547445574456744577445874459744607446174462744637446474465744667446774468744697447074471744727447374474744757447674477744787447974480744817448274483744847448574486744877448874489744907449174492744937449474495744967449774498744997450074501745027450374504745057450674507745087450974510745117451274513745147451574516745177451874519745207452174522745237452474525745267452774528745297453074531745327453374534745357453674537745387453974540745417454274543745447454574546745477454874549745507455174552745537455474555745567455774558745597456074561745627456374564745657456674567745687456974570745717457274573745747457574576745777457874579745807458174582745837458474585745867458774588745897459074591745927459374594745957459674597745987459974600746017460274603746047460574606746077460874609746107461174612746137461474615746167461774618746197462074621746227462374624746257462674627746287462974630746317463274633746347463574636746377463874639746407464174642746437464474645746467464774648746497465074651746527465374654746557465674657746587465974660746617466274663746647466574666746677466874669746707467174672746737467474675746767467774678746797468074681746827468374684746857468674687746887468974690746917469274693746947469574696746977469874699747007470174702747037470474705747067470774708747097471074711747127471374714747157471674717747187471974720747217472274723747247472574726747277472874729747307473174732747337473474735747367473774738747397474074741747427474374744747457474674747747487474974750747517475274753747547475574756747577475874759747607476174762747637476474765747667476774768747697477074771747727477374774747757477674777747787477974780747817478274783747847478574786747877478874789747907479174792747937479474795747967479774798747997480074801748027480374804748057480674807748087480974810748117481274813748147481574816748177481874819748207482174822748237482474825748267482774828748297483074831748327483374834748357483674837748387483974840748417484274843748447484574846748477484874849748507485174852748537485474855748567485774858748597486074861748627486374864748657486674867748687486974870748717487274873748747487574876748777487874879748807488174882748837488474885748867488774888748897489074891748927489374894748957489674897748987489974900749017490274903749047490574906749077490874909749107491174912749137491474915749167491774918749197492074921749227492374924749257492674927749287492974930749317493274933749347493574936749377493874939749407494174942749437494474945749467494774948749497495074951749527495374954749557495674957749587495974960749617496274963749647496574966749677496874969749707497174972749737497474975749767497774978749797498074981749827498374984749857498674987749887498974990749917499274993749947499574996749977499874999750007500175002750037500475005750067500775008750097501075011750127501375014750157501675017750187501975020750217502275023750247502575026750277502875029750307503175032750337503475035750367503775038750397504075041750427504375044750457504675047750487504975050750517505275053750547505575056750577505875059750607506175062750637506475065750667506775068750697507075071750727507375074750757507675077750787507975080750817508275083750847508575086750877508875089750907509175092750937509475095750967509775098750997510075101751027510375104751057510675107751087510975110751117511275113751147511575116751177511875119751207512175122751237512475125751267512775128751297513075131751327513375134751357513675137751387513975140751417514275143751447514575146751477514875149751507515175152751537515475155751567515775158751597516075161751627516375164751657516675167751687516975170751717517275173751747517575176751777517875179751807518175182751837518475185751867518775188751897519075191751927519375194751957519675197751987519975200752017520275203752047520575206752077520875209752107521175212752137521475215752167521775218752197522075221752227522375224752257522675227752287522975230752317523275233752347523575236752377523875239752407524175242752437524475245752467524775248752497525075251752527525375254752557525675257752587525975260752617526275263752647526575266752677526875269752707527175272752737527475275752767527775278752797528075281752827528375284752857528675287752887528975290752917529275293752947529575296752977529875299753007530175302753037530475305753067530775308753097531075311753127531375314753157531675317753187531975320753217532275323753247532575326753277532875329753307533175332753337533475335753367533775338753397534075341753427534375344753457534675347753487534975350753517535275353753547535575356753577535875359753607536175362753637536475365753667536775368753697537075371753727537375374753757537675377753787537975380753817538275383753847538575386753877538875389753907539175392753937539475395753967539775398753997540075401754027540375404754057540675407754087540975410754117541275413754147541575416754177541875419754207542175422754237542475425754267542775428754297543075431754327543375434754357543675437754387543975440754417544275443754447544575446754477544875449754507545175452754537545475455754567545775458754597546075461754627546375464754657546675467754687546975470754717547275473754747547575476754777547875479754807548175482754837548475485754867548775488754897549075491754927549375494754957549675497754987549975500755017550275503755047550575506755077550875509755107551175512755137551475515755167551775518755197552075521755227552375524755257552675527755287552975530755317553275533755347553575536755377553875539755407554175542755437554475545755467554775548755497555075551755527555375554755557555675557755587555975560755617556275563755647556575566755677556875569755707557175572755737557475575755767557775578755797558075581755827558375584755857558675587755887558975590755917559275593755947559575596755977559875599756007560175602756037560475605756067560775608756097561075611756127561375614756157561675617756187561975620756217562275623756247562575626756277562875629756307563175632756337563475635756367563775638756397564075641756427564375644756457564675647756487564975650756517565275653756547565575656756577565875659756607566175662756637566475665756667566775668756697567075671756727567375674756757567675677756787567975680756817568275683756847568575686756877568875689756907569175692756937569475695756967569775698756997570075701757027570375704757057570675707757087570975710757117571275713757147571575716757177571875719757207572175722757237572475725757267572775728757297573075731757327573375734757357573675737757387573975740757417574275743757447574575746757477574875749757507575175752757537575475755757567575775758757597576075761757627576375764757657576675767757687576975770757717577275773757747577575776757777577875779757807578175782757837578475785757867578775788757897579075791757927579375794757957579675797757987579975800758017580275803758047580575806758077580875809758107581175812758137581475815758167581775818758197582075821758227582375824758257582675827758287582975830758317583275833758347583575836758377583875839758407584175842758437584475845758467584775848758497585075851758527585375854758557585675857758587585975860758617586275863758647586575866758677586875869758707587175872758737587475875758767587775878758797588075881758827588375884758857588675887758887588975890758917589275893758947589575896758977589875899759007590175902759037590475905759067590775908759097591075911759127591375914759157591675917759187591975920759217592275923759247592575926759277592875929759307593175932759337593475935759367593775938759397594075941759427594375944759457594675947759487594975950759517595275953759547595575956759577595875959759607596175962759637596475965759667596775968759697597075971759727597375974759757597675977759787597975980759817598275983759847598575986759877598875989759907599175992759937599475995759967599775998759997600076001760027600376004760057600676007760087600976010760117601276013760147601576016760177601876019760207602176022760237602476025760267602776028760297603076031760327603376034760357603676037760387603976040760417604276043760447604576046760477604876049760507605176052760537605476055760567605776058760597606076061760627606376064760657606676067760687606976070760717607276073760747607576076760777607876079760807608176082760837608476085760867608776088760897609076091760927609376094760957609676097760987609976100761017610276103761047610576106761077610876109761107611176112761137611476115761167611776118761197612076121761227612376124761257612676127761287612976130761317613276133761347613576136761377613876139761407614176142761437614476145761467614776148761497615076151761527615376154761557615676157761587615976160761617616276163761647616576166761677616876169761707617176172761737617476175761767617776178761797618076181761827618376184761857618676187761887618976190761917619276193761947619576196761977619876199762007620176202762037620476205762067620776208762097621076211762127621376214762157621676217762187621976220762217622276223762247622576226762277622876229762307623176232762337623476235762367623776238762397624076241762427624376244762457624676247762487624976250762517625276253762547625576256762577625876259762607626176262762637626476265762667626776268762697627076271762727627376274762757627676277762787627976280762817628276283762847628576286762877628876289762907629176292762937629476295762967629776298762997630076301763027630376304763057630676307763087630976310763117631276313763147631576316763177631876319763207632176322763237632476325763267632776328763297633076331763327633376334763357633676337763387633976340763417634276343763447634576346763477634876349763507635176352763537635476355763567635776358763597636076361763627636376364763657636676367763687636976370763717637276373763747637576376763777637876379763807638176382763837638476385763867638776388763897639076391763927639376394763957639676397763987639976400764017640276403764047640576406764077640876409764107641176412764137641476415764167641776418764197642076421764227642376424764257642676427764287642976430764317643276433764347643576436764377643876439764407644176442764437644476445764467644776448764497645076451764527645376454764557645676457764587645976460764617646276463764647646576466764677646876469764707647176472764737647476475764767647776478764797648076481764827648376484764857648676487764887648976490764917649276493764947649576496764977649876499765007650176502765037650476505765067650776508765097651076511765127651376514765157651676517765187651976520765217652276523765247652576526765277652876529765307653176532765337653476535765367653776538765397654076541765427654376544765457654676547765487654976550765517655276553765547655576556765577655876559765607656176562765637656476565765667656776568765697657076571765727657376574765757657676577765787657976580765817658276583765847658576586765877658876589765907659176592765937659476595765967659776598765997660076601766027660376604766057660676607766087660976610766117661276613766147661576616766177661876619766207662176622766237662476625766267662776628766297663076631766327663376634766357663676637766387663976640766417664276643766447664576646766477664876649766507665176652766537665476655766567665776658766597666076661766627666376664766657666676667766687666976670766717667276673766747667576676766777667876679766807668176682766837668476685766867668776688766897669076691766927669376694766957669676697766987669976700767017670276703767047670576706767077670876709767107671176712767137671476715767167671776718767197672076721767227672376724767257672676727767287672976730767317673276733767347673576736767377673876739767407674176742767437674476745767467674776748767497675076751767527675376754767557675676757767587675976760767617676276763767647676576766767677676876769767707677176772767737677476775767767677776778767797678076781767827678376784767857678676787767887678976790767917679276793767947679576796767977679876799768007680176802768037680476805768067680776808768097681076811768127681376814768157681676817768187681976820768217682276823768247682576826768277682876829768307683176832768337683476835768367683776838768397684076841768427684376844768457684676847768487684976850768517685276853768547685576856768577685876859768607686176862768637686476865768667686776868768697687076871768727687376874768757687676877768787687976880768817688276883768847688576886768877688876889768907689176892768937689476895768967689776898768997690076901769027690376904769057690676907769087690976910769117691276913769147691576916769177691876919769207692176922769237692476925769267692776928769297693076931769327693376934769357693676937769387693976940769417694276943769447694576946769477694876949769507695176952769537695476955769567695776958769597696076961769627696376964769657696676967769687696976970769717697276973769747697576976769777697876979769807698176982769837698476985769867698776988769897699076991769927699376994769957699676997769987699977000770017700277003770047700577006770077700877009770107701177012770137701477015770167701777018770197702077021770227702377024770257702677027770287702977030770317703277033770347703577036770377703877039770407704177042770437704477045770467704777048770497705077051770527705377054770557705677057770587705977060770617706277063770647706577066770677706877069770707707177072770737707477075770767707777078770797708077081770827708377084770857708677087770887708977090770917709277093770947709577096770977709877099771007710177102771037710477105771067710777108771097711077111771127711377114771157711677117771187711977120771217712277123771247712577126771277712877129771307713177132771337713477135771367713777138771397714077141771427714377144771457714677147771487714977150771517715277153771547715577156771577715877159771607716177162771637716477165771667716777168771697717077171771727717377174771757717677177771787717977180771817718277183771847718577186771877718877189771907719177192771937719477195771967719777198771997720077201772027720377204772057720677207772087720977210772117721277213772147721577216772177721877219772207722177222772237722477225772267722777228772297723077231772327723377234772357723677237772387723977240772417724277243772447724577246772477724877249772507725177252772537725477255772567725777258772597726077261772627726377264772657726677267772687726977270772717727277273772747727577276772777727877279772807728177282772837728477285772867728777288772897729077291772927729377294772957729677297772987729977300773017730277303773047730577306773077730877309773107731177312773137731477315773167731777318773197732077321773227732377324773257732677327773287732977330773317733277333773347733577336773377733877339773407734177342773437734477345773467734777348773497735077351773527735377354773557735677357773587735977360773617736277363773647736577366773677736877369773707737177372773737737477375773767737777378773797738077381773827738377384773857738677387773887738977390773917739277393773947739577396773977739877399774007740177402774037740477405774067740777408774097741077411774127741377414774157741677417774187741977420774217742277423774247742577426774277742877429774307743177432774337743477435774367743777438774397744077441774427744377444774457744677447774487744977450774517745277453774547745577456774577745877459774607746177462774637746477465774667746777468774697747077471774727747377474774757747677477774787747977480774817748277483774847748577486774877748877489774907749177492774937749477495774967749777498774997750077501775027750377504775057750677507775087750977510775117751277513775147751577516775177751877519775207752177522775237752477525775267752777528775297753077531775327753377534775357753677537775387753977540775417754277543775447754577546775477754877549775507755177552775537755477555775567755777558775597756077561775627756377564775657756677567775687756977570775717757277573775747757577576775777757877579775807758177582775837758477585775867758777588775897759077591775927759377594775957759677597775987759977600776017760277603776047760577606776077760877609776107761177612776137761477615776167761777618776197762077621776227762377624776257762677627776287762977630776317763277633776347763577636776377763877639776407764177642776437764477645776467764777648776497765077651776527765377654776557765677657776587765977660776617766277663776647766577666776677766877669776707767177672776737767477675776767767777678776797768077681776827768377684776857768677687776887768977690776917769277693776947769577696776977769877699777007770177702777037770477705777067770777708777097771077711777127771377714777157771677717777187771977720777217772277723777247772577726777277772877729777307773177732777337773477735777367773777738777397774077741777427774377744777457774677747777487774977750777517775277753777547775577756777577775877759777607776177762777637776477765777667776777768777697777077771777727777377774777757777677777777787777977780777817778277783777847778577786777877778877789777907779177792777937779477795777967779777798777997780077801778027780377804778057780677807778087780977810778117781277813778147781577816778177781877819778207782177822778237782477825778267782777828778297783077831778327783377834778357783677837778387783977840778417784277843778447784577846778477784877849778507785177852778537785477855778567785777858778597786077861778627786377864778657786677867778687786977870778717787277873778747787577876778777787877879778807788177882778837788477885778867788777888778897789077891778927789377894778957789677897778987789977900779017790277903779047790577906779077790877909779107791177912779137791477915779167791777918779197792077921779227792377924779257792677927779287792977930779317793277933779347793577936779377793877939779407794177942779437794477945779467794777948779497795077951779527795377954779557795677957779587795977960779617796277963779647796577966779677796877969779707797177972779737797477975779767797777978779797798077981779827798377984779857798677987779887798977990779917799277993779947799577996779977799877999780007800178002780037800478005780067800778008780097801078011780127801378014780157801678017780187801978020780217802278023780247802578026780277802878029780307803178032780337803478035780367803778038780397804078041780427804378044780457804678047780487804978050780517805278053780547805578056780577805878059780607806178062780637806478065780667806778068780697807078071780727807378074780757807678077780787807978080780817808278083780847808578086780877808878089780907809178092780937809478095780967809778098780997810078101781027810378104781057810678107781087810978110781117811278113781147811578116781177811878119781207812178122781237812478125781267812778128781297813078131781327813378134781357813678137781387813978140781417814278143781447814578146781477814878149781507815178152781537815478155781567815778158781597816078161781627816378164781657816678167781687816978170781717817278173781747817578176781777817878179781807818178182781837818478185781867818778188781897819078191781927819378194781957819678197781987819978200782017820278203782047820578206782077820878209782107821178212782137821478215782167821778218782197822078221782227822378224782257822678227782287822978230782317823278233782347823578236782377823878239782407824178242782437824478245782467824778248782497825078251782527825378254782557825678257782587825978260782617826278263782647826578266782677826878269782707827178272782737827478275782767827778278782797828078281782827828378284782857828678287782887828978290782917829278293782947829578296782977829878299783007830178302783037830478305783067830778308783097831078311783127831378314783157831678317783187831978320783217832278323783247832578326783277832878329783307833178332783337833478335783367833778338783397834078341783427834378344783457834678347783487834978350783517835278353783547835578356783577835878359783607836178362783637836478365783667836778368783697837078371783727837378374783757837678377783787837978380783817838278383783847838578386783877838878389783907839178392783937839478395783967839778398783997840078401784027840378404784057840678407784087840978410784117841278413784147841578416784177841878419784207842178422784237842478425784267842778428784297843078431784327843378434784357843678437784387843978440784417844278443784447844578446784477844878449784507845178452784537845478455784567845778458784597846078461784627846378464784657846678467784687846978470784717847278473784747847578476784777847878479784807848178482784837848478485784867848778488784897849078491784927849378494784957849678497784987849978500785017850278503785047850578506785077850878509785107851178512785137851478515785167851778518785197852078521785227852378524785257852678527785287852978530785317853278533785347853578536785377853878539785407854178542785437854478545785467854778548785497855078551785527855378554785557855678557785587855978560785617856278563785647856578566785677856878569785707857178572785737857478575785767857778578785797858078581785827858378584785857858678587785887858978590785917859278593785947859578596785977859878599786007860178602786037860478605786067860778608786097861078611786127861378614786157861678617786187861978620786217862278623786247862578626786277862878629786307863178632786337863478635786367863778638786397864078641786427864378644786457864678647786487864978650786517865278653786547865578656786577865878659786607866178662786637866478665786667866778668786697867078671786727867378674786757867678677786787867978680786817868278683786847868578686786877868878689786907869178692786937869478695786967869778698786997870078701787027870378704787057870678707787087870978710787117871278713787147871578716787177871878719787207872178722787237872478725787267872778728787297873078731787327873378734787357873678737787387873978740787417874278743787447874578746787477874878749787507875178752787537875478755787567875778758787597876078761787627876378764787657876678767787687876978770787717877278773787747877578776787777877878779787807878178782787837878478785787867878778788787897879078791787927879378794787957879678797787987879978800788017880278803788047880578806788077880878809788107881178812788137881478815788167881778818788197882078821788227882378824788257882678827788287882978830788317883278833788347883578836788377883878839788407884178842788437884478845788467884778848788497885078851788527885378854788557885678857788587885978860788617886278863788647886578866788677886878869788707887178872788737887478875788767887778878788797888078881788827888378884788857888678887788887888978890788917889278893788947889578896788977889878899789007890178902789037890478905789067890778908789097891078911789127891378914789157891678917789187891978920789217892278923789247892578926789277892878929789307893178932789337893478935789367893778938789397894078941789427894378944789457894678947789487894978950789517895278953789547895578956789577895878959789607896178962789637896478965789667896778968789697897078971789727897378974789757897678977789787897978980789817898278983789847898578986789877898878989789907899178992789937899478995789967899778998789997900079001790027900379004790057900679007790087900979010790117901279013790147901579016790177901879019790207902179022790237902479025790267902779028790297903079031790327903379034790357903679037790387903979040790417904279043790447904579046790477904879049790507905179052790537905479055790567905779058790597906079061790627906379064790657906679067790687906979070790717907279073790747907579076790777907879079790807908179082790837908479085790867908779088790897909079091790927909379094790957909679097790987909979100791017910279103791047910579106791077910879109791107911179112791137911479115791167911779118791197912079121791227912379124791257912679127791287912979130791317913279133791347913579136791377913879139791407914179142791437914479145791467914779148791497915079151791527915379154791557915679157791587915979160791617916279163791647916579166791677916879169791707917179172791737917479175791767917779178791797918079181791827918379184791857918679187791887918979190791917919279193791947919579196791977919879199792007920179202792037920479205792067920779208792097921079211792127921379214792157921679217792187921979220792217922279223792247922579226792277922879229792307923179232792337923479235792367923779238792397924079241792427924379244792457924679247792487924979250792517925279253792547925579256792577925879259792607926179262792637926479265792667926779268792697927079271792727927379274792757927679277792787927979280792817928279283792847928579286792877928879289792907929179292792937929479295792967929779298792997930079301793027930379304793057930679307793087930979310793117931279313793147931579316793177931879319793207932179322793237932479325793267932779328793297933079331793327933379334793357933679337793387933979340793417934279343793447934579346793477934879349793507935179352793537935479355793567935779358793597936079361793627936379364793657936679367793687936979370793717937279373793747937579376793777937879379793807938179382793837938479385793867938779388793897939079391793927939379394793957939679397793987939979400794017940279403794047940579406794077940879409794107941179412794137941479415794167941779418794197942079421794227942379424794257942679427794287942979430794317943279433794347943579436794377943879439794407944179442794437944479445794467944779448794497945079451794527945379454794557945679457794587945979460794617946279463794647946579466794677946879469794707947179472794737947479475794767947779478794797948079481794827948379484794857948679487794887948979490794917949279493794947949579496794977949879499795007950179502795037950479505795067950779508795097951079511795127951379514795157951679517795187951979520795217952279523795247952579526795277952879529795307953179532795337953479535795367953779538795397954079541795427954379544795457954679547795487954979550795517955279553795547955579556795577955879559795607956179562795637956479565795667956779568795697957079571795727957379574795757957679577795787957979580795817958279583795847958579586795877958879589795907959179592795937959479595795967959779598795997960079601796027960379604796057960679607796087960979610796117961279613796147961579616796177961879619796207962179622796237962479625796267962779628796297963079631796327963379634796357963679637796387963979640796417964279643796447964579646796477964879649796507965179652796537965479655796567965779658796597966079661796627966379664796657966679667796687966979670796717967279673796747967579676796777967879679796807968179682796837968479685796867968779688796897969079691796927969379694796957969679697796987969979700797017970279703797047970579706797077970879709797107971179712797137971479715797167971779718797197972079721797227972379724797257972679727797287972979730797317973279733797347973579736797377973879739797407974179742797437974479745797467974779748797497975079751797527975379754797557975679757797587975979760797617976279763797647976579766797677976879769797707977179772797737977479775797767977779778797797978079781797827978379784797857978679787797887978979790797917979279793797947979579796797977979879799798007980179802798037980479805798067980779808798097981079811798127981379814798157981679817798187981979820798217982279823798247982579826798277982879829798307983179832798337983479835798367983779838798397984079841798427984379844798457984679847798487984979850798517985279853798547985579856798577985879859798607986179862798637986479865798667986779868798697987079871798727987379874798757987679877798787987979880798817988279883798847988579886798877988879889798907989179892798937989479895798967989779898798997990079901799027990379904799057990679907799087990979910799117991279913799147991579916799177991879919799207992179922799237992479925799267992779928799297993079931799327993379934799357993679937799387993979940799417994279943799447994579946799477994879949799507995179952799537995479955799567995779958799597996079961799627996379964799657996679967799687996979970799717997279973799747997579976799777997879979799807998179982799837998479985799867998779988799897999079991799927999379994799957999679997799987999980000800018000280003800048000580006800078000880009800108001180012800138001480015800168001780018800198002080021800228002380024800258002680027800288002980030800318003280033800348003580036800378003880039800408004180042800438004480045800468004780048800498005080051800528005380054800558005680057800588005980060800618006280063800648006580066800678006880069800708007180072800738007480075800768007780078800798008080081800828008380084800858008680087800888008980090800918009280093800948009580096800978009880099801008010180102801038010480105801068010780108801098011080111801128011380114801158011680117801188011980120801218012280123801248012580126801278012880129801308013180132801338013480135801368013780138801398014080141801428014380144801458014680147801488014980150801518015280153801548015580156801578015880159801608016180162801638016480165801668016780168801698017080171801728017380174801758017680177801788017980180801818018280183801848018580186801878018880189801908019180192801938019480195801968019780198801998020080201802028020380204802058020680207802088020980210802118021280213802148021580216802178021880219802208022180222802238022480225802268022780228802298023080231802328023380234802358023680237802388023980240802418024280243802448024580246802478024880249802508025180252802538025480255802568025780258802598026080261802628026380264802658026680267802688026980270802718027280273802748027580276802778027880279802808028180282802838028480285802868028780288802898029080291802928029380294802958029680297802988029980300803018030280303803048030580306803078030880309803108031180312803138031480315803168031780318803198032080321803228032380324803258032680327803288032980330803318033280333803348033580336803378033880339803408034180342803438034480345803468034780348803498035080351803528035380354803558035680357803588035980360803618036280363803648036580366803678036880369803708037180372803738037480375803768037780378803798038080381803828038380384803858038680387803888038980390803918039280393803948039580396803978039880399804008040180402804038040480405804068040780408804098041080411804128041380414804158041680417804188041980420804218042280423804248042580426804278042880429804308043180432804338043480435804368043780438804398044080441804428044380444804458044680447804488044980450804518045280453804548045580456804578045880459804608046180462804638046480465804668046780468804698047080471804728047380474804758047680477804788047980480804818048280483804848048580486804878048880489804908049180492804938049480495804968049780498804998050080501805028050380504805058050680507805088050980510805118051280513805148051580516805178051880519805208052180522805238052480525805268052780528805298053080531805328053380534805358053680537805388053980540805418054280543805448054580546805478054880549805508055180552805538055480555805568055780558805598056080561805628056380564805658056680567805688056980570805718057280573805748057580576805778057880579805808058180582805838058480585805868058780588805898059080591805928059380594805958059680597805988059980600806018060280603806048060580606806078060880609806108061180612806138061480615806168061780618806198062080621806228062380624806258062680627806288062980630806318063280633806348063580636806378063880639806408064180642806438064480645806468064780648806498065080651806528065380654806558065680657806588065980660806618066280663806648066580666806678066880669806708067180672806738067480675806768067780678806798068080681806828068380684806858068680687806888068980690806918069280693806948069580696806978069880699807008070180702807038070480705807068070780708807098071080711807128071380714807158071680717807188071980720807218072280723807248072580726807278072880729807308073180732807338073480735807368073780738807398074080741807428074380744807458074680747807488074980750807518075280753807548075580756807578075880759807608076180762807638076480765807668076780768807698077080771807728077380774807758077680777807788077980780807818078280783807848078580786807878078880789807908079180792807938079480795807968079780798807998080080801808028080380804808058080680807808088080980810808118081280813808148081580816808178081880819808208082180822808238082480825808268082780828808298083080831808328083380834808358083680837808388083980840808418084280843808448084580846808478084880849808508085180852808538085480855808568085780858808598086080861808628086380864808658086680867808688086980870808718087280873808748087580876808778087880879808808088180882808838088480885808868088780888808898089080891808928089380894808958089680897808988089980900809018090280903809048090580906809078090880909809108091180912809138091480915809168091780918809198092080921809228092380924809258092680927809288092980930809318093280933809348093580936809378093880939809408094180942809438094480945809468094780948809498095080951809528095380954809558095680957809588095980960809618096280963809648096580966809678096880969809708097180972809738097480975809768097780978809798098080981809828098380984809858098680987809888098980990809918099280993809948099580996809978099880999810008100181002810038100481005810068100781008810098101081011810128101381014810158101681017810188101981020810218102281023810248102581026810278102881029810308103181032810338103481035810368103781038810398104081041810428104381044810458104681047810488104981050810518105281053810548105581056810578105881059810608106181062810638106481065810668106781068810698107081071810728107381074810758107681077810788107981080810818108281083810848108581086810878108881089810908109181092810938109481095810968109781098810998110081101811028110381104811058110681107811088110981110811118111281113811148111581116811178111881119811208112181122811238112481125811268112781128811298113081131811328113381134811358113681137811388113981140811418114281143811448114581146811478114881149811508115181152811538115481155811568115781158811598116081161811628116381164811658116681167811688116981170811718117281173811748117581176811778117881179811808118181182811838118481185811868118781188811898119081191811928119381194811958119681197811988119981200812018120281203812048120581206812078120881209812108121181212812138121481215812168121781218812198122081221812228122381224812258122681227812288122981230812318123281233812348123581236812378123881239812408124181242812438124481245812468124781248812498125081251812528125381254812558125681257812588125981260812618126281263812648126581266812678126881269812708127181272812738127481275812768127781278812798128081281812828128381284812858128681287812888128981290812918129281293812948129581296812978129881299813008130181302813038130481305813068130781308813098131081311813128131381314813158131681317813188131981320813218132281323813248132581326813278132881329813308133181332813338133481335813368133781338813398134081341813428134381344813458134681347813488134981350813518135281353813548135581356813578135881359813608136181362813638136481365813668136781368813698137081371813728137381374813758137681377813788137981380813818138281383813848138581386813878138881389813908139181392813938139481395813968139781398813998140081401814028140381404814058140681407814088140981410814118141281413814148141581416814178141881419814208142181422814238142481425814268142781428814298143081431814328143381434814358143681437814388143981440814418144281443814448144581446814478144881449814508145181452814538145481455814568145781458814598146081461814628146381464814658146681467814688146981470814718147281473814748147581476814778147881479814808148181482814838148481485814868148781488814898149081491814928149381494814958149681497814988149981500815018150281503815048150581506815078150881509815108151181512815138151481515815168151781518815198152081521815228152381524815258152681527815288152981530815318153281533815348153581536815378153881539815408154181542815438154481545815468154781548815498155081551815528155381554815558155681557815588155981560815618156281563815648156581566815678156881569815708157181572815738157481575815768157781578815798158081581815828158381584815858158681587815888158981590815918159281593815948159581596815978159881599816008160181602816038160481605816068160781608816098161081611816128161381614816158161681617816188161981620816218162281623816248162581626816278162881629816308163181632816338163481635816368163781638816398164081641816428164381644816458164681647816488164981650816518165281653816548165581656816578165881659816608166181662816638166481665816668166781668816698167081671816728167381674816758167681677816788167981680816818168281683816848168581686816878168881689816908169181692816938169481695816968169781698816998170081701817028170381704817058170681707817088170981710817118171281713817148171581716817178171881719817208172181722817238172481725817268172781728817298173081731817328173381734817358173681737817388173981740817418174281743817448174581746817478174881749817508175181752817538175481755817568175781758817598176081761817628176381764817658176681767817688176981770817718177281773817748177581776817778177881779817808178181782817838178481785817868178781788817898179081791817928179381794817958179681797817988179981800818018180281803818048180581806818078180881809818108181181812818138181481815818168181781818818198182081821818228182381824818258182681827818288182981830818318183281833818348183581836818378183881839818408184181842818438184481845818468184781848818498185081851818528185381854818558185681857818588185981860818618186281863818648186581866818678186881869818708187181872818738187481875818768187781878818798188081881818828188381884818858188681887818888188981890818918189281893818948189581896818978189881899819008190181902819038190481905819068190781908819098191081911819128191381914819158191681917819188191981920819218192281923819248192581926819278192881929819308193181932819338193481935819368193781938819398194081941819428194381944819458194681947819488194981950819518195281953819548195581956819578195881959819608196181962819638196481965819668196781968819698197081971819728197381974819758197681977819788197981980819818198281983819848198581986819878198881989819908199181992819938199481995819968199781998819998200082001820028200382004820058200682007820088200982010820118201282013820148201582016820178201882019820208202182022820238202482025820268202782028820298203082031820328203382034820358203682037820388203982040820418204282043820448204582046820478204882049820508205182052820538205482055820568205782058820598206082061820628206382064820658206682067820688206982070820718207282073820748207582076820778207882079820808208182082820838208482085820868208782088820898209082091820928209382094820958209682097820988209982100821018210282103821048210582106821078210882109821108211182112821138211482115821168211782118821198212082121821228212382124821258212682127821288212982130821318213282133821348213582136821378213882139821408214182142821438214482145821468214782148821498215082151821528215382154821558215682157821588215982160821618216282163821648216582166821678216882169821708217182172821738217482175821768217782178821798218082181821828218382184821858218682187821888218982190821918219282193821948219582196821978219882199822008220182202822038220482205822068220782208822098221082211822128221382214822158221682217822188221982220822218222282223822248222582226822278222882229822308223182232822338223482235822368223782238822398224082241822428224382244822458224682247822488224982250822518225282253822548225582256822578225882259822608226182262822638226482265822668226782268822698227082271822728227382274822758227682277822788227982280822818228282283822848228582286822878228882289822908229182292822938229482295822968229782298822998230082301823028230382304823058230682307823088230982310823118231282313823148231582316823178231882319823208232182322823238232482325823268232782328823298233082331823328233382334823358233682337823388233982340823418234282343823448234582346823478234882349823508235182352823538235482355823568235782358823598236082361823628236382364823658236682367823688236982370823718237282373823748237582376823778237882379823808238182382823838238482385823868238782388823898239082391823928239382394823958239682397823988239982400824018240282403824048240582406824078240882409824108241182412824138241482415824168241782418824198242082421824228242382424824258242682427824288242982430824318243282433824348243582436824378243882439824408244182442824438244482445824468244782448824498245082451824528245382454824558245682457824588245982460824618246282463824648246582466824678246882469824708247182472824738247482475824768247782478824798248082481824828248382484824858248682487824888248982490824918249282493824948249582496824978249882499825008250182502825038250482505825068250782508825098251082511825128251382514825158251682517825188251982520825218252282523825248252582526825278252882529825308253182532825338253482535825368253782538825398254082541825428254382544825458254682547825488254982550825518255282553825548255582556825578255882559825608256182562825638256482565825668256782568825698257082571825728257382574825758257682577825788257982580825818258282583825848258582586825878258882589825908259182592825938259482595825968259782598825998260082601826028260382604826058260682607826088260982610826118261282613826148261582616826178261882619826208262182622826238262482625826268262782628826298263082631826328263382634826358263682637826388263982640826418264282643826448264582646826478264882649826508265182652826538265482655826568265782658826598266082661826628266382664826658266682667826688266982670826718267282673826748267582676826778267882679826808268182682826838268482685826868268782688826898269082691826928269382694826958269682697826988269982700827018270282703827048270582706827078270882709827108271182712827138271482715827168271782718827198272082721827228272382724827258272682727827288272982730827318273282733827348273582736827378273882739827408274182742827438274482745827468274782748827498275082751827528275382754827558275682757827588275982760827618276282763827648276582766827678276882769827708277182772827738277482775827768277782778827798278082781827828278382784827858278682787827888278982790827918279282793827948279582796827978279882799828008280182802828038280482805828068280782808828098281082811828128281382814828158281682817828188281982820828218282282823828248282582826828278282882829828308283182832828338283482835828368283782838828398284082841828428284382844828458284682847828488284982850828518285282853828548285582856828578285882859828608286182862828638286482865828668286782868828698287082871828728287382874828758287682877828788287982880828818288282883828848288582886828878288882889828908289182892828938289482895828968289782898828998290082901829028290382904829058290682907829088290982910829118291282913829148291582916829178291882919829208292182922829238292482925829268292782928829298293082931829328293382934829358293682937829388293982940829418294282943829448294582946829478294882949829508295182952829538295482955829568295782958829598296082961829628296382964829658296682967829688296982970829718297282973829748297582976829778297882979829808298182982829838298482985829868298782988829898299082991829928299382994829958299682997829988299983000830018300283003830048300583006830078300883009830108301183012830138301483015830168301783018830198302083021830228302383024830258302683027830288302983030830318303283033830348303583036830378303883039830408304183042830438304483045830468304783048830498305083051830528305383054830558305683057830588305983060830618306283063830648306583066830678306883069830708307183072830738307483075830768307783078830798308083081830828308383084830858308683087830888308983090830918309283093830948309583096830978309883099831008310183102831038310483105831068310783108831098311083111831128311383114831158311683117831188311983120831218312283123831248312583126831278312883129831308313183132831338313483135831368313783138831398314083141831428314383144831458314683147831488314983150831518315283153831548315583156831578315883159831608316183162831638316483165831668316783168831698317083171831728317383174831758317683177831788317983180831818318283183831848318583186831878318883189831908319183192831938319483195831968319783198831998320083201832028320383204832058320683207832088320983210832118321283213832148321583216832178321883219832208322183222832238322483225832268322783228832298323083231832328323383234832358323683237832388323983240832418324283243832448324583246832478324883249832508325183252832538325483255832568325783258832598326083261832628326383264832658326683267832688326983270832718327283273832748327583276832778327883279832808328183282832838328483285832868328783288832898329083291832928329383294832958329683297832988329983300833018330283303833048330583306833078330883309833108331183312833138331483315833168331783318833198332083321833228332383324833258332683327833288332983330833318333283333833348333583336833378333883339833408334183342833438334483345833468334783348833498335083351833528335383354833558335683357833588335983360833618336283363833648336583366833678336883369833708337183372833738337483375833768337783378833798338083381833828338383384833858338683387833888338983390833918339283393833948339583396833978339883399834008340183402834038340483405834068340783408834098341083411834128341383414834158341683417834188341983420834218342283423834248342583426834278342883429834308343183432834338343483435834368343783438834398344083441834428344383444834458344683447834488344983450834518345283453834548345583456834578345883459834608346183462834638346483465834668346783468834698347083471834728347383474834758347683477834788347983480834818348283483834848348583486834878348883489834908349183492834938349483495834968349783498834998350083501835028350383504835058350683507835088350983510835118351283513835148351583516835178351883519835208352183522835238352483525835268352783528835298353083531835328353383534835358353683537835388353983540835418354283543835448354583546835478354883549835508355183552835538355483555835568355783558835598356083561835628356383564835658356683567835688356983570835718357283573835748357583576835778357883579835808358183582835838358483585835868358783588835898359083591835928359383594835958359683597835988359983600836018360283603836048360583606836078360883609836108361183612836138361483615836168361783618836198362083621836228362383624836258362683627836288362983630836318363283633836348363583636836378363883639836408364183642836438364483645836468364783648836498365083651836528365383654836558365683657836588365983660836618366283663836648366583666836678366883669836708367183672836738367483675836768367783678836798368083681836828368383684836858368683687836888368983690836918369283693836948369583696836978369883699837008370183702837038370483705837068370783708837098371083711837128371383714837158371683717837188371983720837218372283723837248372583726837278372883729837308373183732837338373483735837368373783738837398374083741837428374383744837458374683747837488374983750837518375283753837548375583756837578375883759837608376183762837638376483765837668376783768837698377083771837728377383774837758377683777837788377983780837818378283783837848378583786837878378883789837908379183792837938379483795837968379783798837998380083801838028380383804838058380683807838088380983810838118381283813838148381583816838178381883819838208382183822838238382483825838268382783828838298383083831838328383383834838358383683837838388383983840838418384283843838448384583846838478384883849838508385183852838538385483855838568385783858838598386083861838628386383864838658386683867838688386983870838718387283873838748387583876838778387883879838808388183882838838388483885838868388783888838898389083891838928389383894838958389683897838988389983900839018390283903839048390583906839078390883909839108391183912839138391483915839168391783918839198392083921839228392383924839258392683927839288392983930839318393283933839348393583936839378393883939839408394183942839438394483945839468394783948839498395083951839528395383954839558395683957839588395983960839618396283963839648396583966839678396883969839708397183972839738397483975839768397783978839798398083981839828398383984839858398683987839888398983990839918399283993839948399583996839978399883999840008400184002840038400484005840068400784008840098401084011840128401384014840158401684017840188401984020840218402284023840248402584026840278402884029840308403184032840338403484035840368403784038840398404084041840428404384044840458404684047840488404984050840518405284053840548405584056840578405884059840608406184062840638406484065840668406784068840698407084071840728407384074840758407684077840788407984080840818408284083840848408584086840878408884089840908409184092840938409484095840968409784098840998410084101841028410384104841058410684107841088410984110841118411284113841148411584116841178411884119841208412184122841238412484125841268412784128841298413084131841328413384134841358413684137841388413984140841418414284143841448414584146841478414884149841508415184152841538415484155841568415784158841598416084161841628416384164841658416684167841688416984170841718417284173841748417584176841778417884179841808418184182841838418484185841868418784188841898419084191841928419384194841958419684197841988419984200842018420284203842048420584206842078420884209842108421184212842138421484215842168421784218842198422084221842228422384224842258422684227842288422984230842318423284233842348423584236842378423884239842408424184242842438424484245842468424784248842498425084251842528425384254842558425684257842588425984260842618426284263842648426584266842678426884269842708427184272842738427484275842768427784278842798428084281842828428384284842858428684287842888428984290842918429284293842948429584296842978429884299843008430184302843038430484305843068430784308843098431084311843128431384314843158431684317843188431984320843218432284323843248432584326843278432884329843308433184332843338433484335843368433784338843398434084341843428434384344843458434684347843488434984350843518435284353843548435584356843578435884359843608436184362843638436484365843668436784368843698437084371843728437384374843758437684377843788437984380843818438284383843848438584386843878438884389843908439184392843938439484395843968439784398843998440084401844028440384404844058440684407844088440984410844118441284413844148441584416844178441884419844208442184422844238442484425844268442784428844298443084431844328443384434844358443684437844388443984440844418444284443844448444584446844478444884449844508445184452844538445484455844568445784458844598446084461844628446384464844658446684467844688446984470844718447284473844748447584476844778447884479844808448184482844838448484485844868448784488844898449084491844928449384494844958449684497844988449984500845018450284503845048450584506845078450884509845108451184512845138451484515845168451784518845198452084521845228452384524845258452684527845288452984530845318453284533845348453584536845378453884539845408454184542845438454484545845468454784548845498455084551845528455384554845558455684557845588455984560845618456284563845648456584566845678456884569845708457184572845738457484575845768457784578845798458084581845828458384584845858458684587845888458984590845918459284593845948459584596845978459884599846008460184602846038460484605846068460784608846098461084611846128461384614846158461684617846188461984620846218462284623846248462584626846278462884629846308463184632846338463484635846368463784638846398464084641846428464384644846458464684647846488464984650846518465284653846548465584656846578465884659846608466184662846638466484665846668466784668846698467084671846728467384674846758467684677846788467984680846818468284683846848468584686846878468884689846908469184692846938469484695846968469784698846998470084701847028470384704847058470684707847088470984710847118471284713847148471584716847178471884719847208472184722847238472484725847268472784728847298473084731847328473384734847358473684737847388473984740847418474284743847448474584746847478474884749847508475184752847538475484755847568475784758847598476084761847628476384764847658476684767847688476984770847718477284773847748477584776847778477884779847808478184782847838478484785847868478784788847898479084791847928479384794847958479684797847988479984800848018480284803848048480584806848078480884809848108481184812848138481484815848168481784818848198482084821848228482384824848258482684827848288482984830848318483284833848348483584836848378483884839848408484184842848438484484845848468484784848848498485084851848528485384854848558485684857848588485984860848618486284863848648486584866848678486884869848708487184872848738487484875848768487784878848798488084881848828488384884848858488684887848888488984890848918489284893848948489584896848978489884899849008490184902849038490484905849068490784908849098491084911849128491384914849158491684917849188491984920849218492284923849248492584926849278492884929849308493184932849338493484935849368493784938849398494084941849428494384944849458494684947849488494984950849518495284953849548495584956849578495884959849608496184962849638496484965849668496784968849698497084971849728497384974849758497684977849788497984980849818498284983849848498584986849878498884989849908499184992849938499484995849968499784998849998500085001850028500385004850058500685007850088500985010850118501285013850148501585016850178501885019850208502185022850238502485025850268502785028850298503085031850328503385034850358503685037850388503985040850418504285043850448504585046850478504885049850508505185052850538505485055850568505785058850598506085061850628506385064850658506685067850688506985070850718507285073850748507585076850778507885079850808508185082850838508485085850868508785088850898509085091850928509385094850958509685097850988509985100851018510285103851048510585106851078510885109851108511185112851138511485115851168511785118851198512085121851228512385124851258512685127851288512985130851318513285133851348513585136851378513885139851408514185142851438514485145851468514785148851498515085151851528515385154851558515685157851588515985160851618516285163851648516585166851678516885169851708517185172851738517485175851768517785178851798518085181851828518385184851858518685187851888518985190851918519285193851948519585196851978519885199852008520185202852038520485205852068520785208852098521085211852128521385214852158521685217852188521985220852218522285223852248522585226852278522885229852308523185232852338523485235852368523785238852398524085241852428524385244852458524685247852488524985250852518525285253852548525585256852578525885259852608526185262852638526485265852668526785268852698527085271852728527385274852758527685277852788527985280852818528285283852848528585286852878528885289852908529185292852938529485295852968529785298852998530085301853028530385304853058530685307853088530985310853118531285313853148531585316853178531885319853208532185322853238532485325853268532785328853298533085331853328533385334853358533685337853388533985340853418534285343853448534585346853478534885349853508535185352853538535485355853568535785358853598536085361853628536385364853658536685367853688536985370853718537285373853748537585376853778537885379853808538185382853838538485385853868538785388853898539085391853928539385394853958539685397853988539985400854018540285403854048540585406854078540885409854108541185412854138541485415854168541785418854198542085421854228542385424854258542685427854288542985430854318543285433854348543585436854378543885439854408544185442854438544485445854468544785448854498545085451854528545385454854558545685457854588545985460854618546285463854648546585466854678546885469854708547185472854738547485475854768547785478854798548085481854828548385484854858548685487854888548985490854918549285493854948549585496854978549885499855008550185502855038550485505855068550785508855098551085511855128551385514855158551685517855188551985520855218552285523855248552585526855278552885529855308553185532855338553485535855368553785538855398554085541855428554385544855458554685547855488554985550855518555285553855548555585556855578555885559855608556185562855638556485565855668556785568855698557085571855728557385574855758557685577855788557985580855818558285583855848558585586855878558885589855908559185592855938559485595855968559785598855998560085601856028560385604856058560685607856088560985610856118561285613856148561585616856178561885619856208562185622856238562485625856268562785628856298563085631856328563385634856358563685637856388563985640856418564285643856448564585646856478564885649856508565185652856538565485655856568565785658856598566085661856628566385664856658566685667856688566985670856718567285673856748567585676856778567885679856808568185682856838568485685856868568785688856898569085691856928569385694856958569685697856988569985700857018570285703857048570585706857078570885709857108571185712857138571485715857168571785718857198572085721857228572385724857258572685727857288572985730857318573285733857348573585736857378573885739857408574185742857438574485745857468574785748857498575085751857528575385754857558575685757857588575985760857618576285763857648576585766857678576885769857708577185772857738577485775857768577785778857798578085781857828578385784857858578685787857888578985790857918579285793857948579585796857978579885799858008580185802858038580485805858068580785808858098581085811858128581385814858158581685817858188581985820858218582285823858248582585826858278582885829858308583185832858338583485835858368583785838858398584085841858428584385844858458584685847858488584985850858518585285853858548585585856858578585885859858608586185862858638586485865858668586785868858698587085871858728587385874858758587685877858788587985880858818588285883858848588585886858878588885889858908589185892858938589485895858968589785898858998590085901859028590385904859058590685907859088590985910859118591285913859148591585916859178591885919859208592185922859238592485925859268592785928859298593085931859328593385934859358593685937859388593985940859418594285943859448594585946859478594885949859508595185952859538595485955859568595785958859598596085961859628596385964859658596685967859688596985970859718597285973859748597585976859778597885979859808598185982859838598485985859868598785988859898599085991859928599385994859958599685997859988599986000860018600286003860048600586006860078600886009860108601186012860138601486015860168601786018860198602086021860228602386024860258602686027860288602986030860318603286033860348603586036860378603886039860408604186042860438604486045860468604786048860498605086051860528605386054860558605686057860588605986060860618606286063860648606586066860678606886069860708607186072860738607486075860768607786078860798608086081860828608386084860858608686087860888608986090860918609286093860948609586096860978609886099861008610186102861038610486105861068610786108861098611086111861128611386114861158611686117861188611986120861218612286123861248612586126861278612886129861308613186132861338613486135861368613786138861398614086141861428614386144861458614686147861488614986150861518615286153861548615586156861578615886159861608616186162861638616486165861668616786168861698617086171861728617386174861758617686177861788617986180861818618286183861848618586186861878618886189861908619186192861938619486195861968619786198861998620086201862028620386204862058620686207862088620986210862118621286213862148621586216862178621886219862208622186222862238622486225862268622786228862298623086231862328623386234862358623686237862388623986240862418624286243862448624586246862478624886249862508625186252862538625486255862568625786258862598626086261862628626386264862658626686267862688626986270862718627286273862748627586276862778627886279862808628186282862838628486285862868628786288862898629086291862928629386294862958629686297862988629986300863018630286303863048630586306863078630886309863108631186312863138631486315863168631786318863198632086321863228632386324863258632686327863288632986330863318633286333863348633586336863378633886339863408634186342863438634486345863468634786348863498635086351863528635386354863558635686357863588635986360863618636286363863648636586366863678636886369863708637186372863738637486375863768637786378863798638086381863828638386384863858638686387863888638986390863918639286393863948639586396863978639886399864008640186402864038640486405864068640786408864098641086411864128641386414864158641686417864188641986420864218642286423864248642586426864278642886429864308643186432864338643486435864368643786438864398644086441864428644386444864458644686447864488644986450864518645286453864548645586456864578645886459864608646186462864638646486465864668646786468864698647086471864728647386474864758647686477864788647986480864818648286483864848648586486864878648886489864908649186492864938649486495864968649786498864998650086501865028650386504865058650686507865088650986510865118651286513865148651586516865178651886519865208652186522865238652486525865268652786528865298653086531865328653386534865358653686537865388653986540865418654286543865448654586546865478654886549865508655186552865538655486555865568655786558865598656086561865628656386564865658656686567865688656986570865718657286573865748657586576865778657886579865808658186582865838658486585865868658786588865898659086591865928659386594865958659686597865988659986600866018660286603866048660586606866078660886609866108661186612866138661486615866168661786618866198662086621866228662386624866258662686627866288662986630866318663286633866348663586636866378663886639866408664186642866438664486645866468664786648866498665086651866528665386654866558665686657866588665986660866618666286663866648666586666866678666886669866708667186672866738667486675866768667786678866798668086681866828668386684866858668686687866888668986690866918669286693866948669586696866978669886699867008670186702867038670486705867068670786708867098671086711867128671386714867158671686717867188671986720867218672286723867248672586726867278672886729867308673186732867338673486735867368673786738867398674086741867428674386744867458674686747867488674986750867518675286753867548675586756867578675886759867608676186762867638676486765867668676786768867698677086771867728677386774867758677686777867788677986780867818678286783867848678586786867878678886789867908679186792867938679486795867968679786798867998680086801868028680386804868058680686807868088680986810868118681286813868148681586816868178681886819868208682186822868238682486825868268682786828868298683086831868328683386834868358683686837868388683986840868418684286843868448684586846868478684886849868508685186852868538685486855868568685786858868598686086861868628686386864868658686686867868688686986870868718687286873868748687586876868778687886879868808688186882868838688486885868868688786888868898689086891868928689386894868958689686897868988689986900869018690286903869048690586906869078690886909869108691186912869138691486915869168691786918869198692086921869228692386924869258692686927869288692986930869318693286933869348693586936869378693886939869408694186942869438694486945869468694786948869498695086951869528695386954869558695686957869588695986960869618696286963869648696586966869678696886969869708697186972869738697486975869768697786978869798698086981869828698386984869858698686987869888698986990869918699286993869948699586996869978699886999870008700187002870038700487005870068700787008870098701087011870128701387014870158701687017870188701987020870218702287023870248702587026870278702887029870308703187032870338703487035870368703787038870398704087041870428704387044870458704687047870488704987050870518705287053870548705587056870578705887059870608706187062870638706487065870668706787068870698707087071870728707387074870758707687077870788707987080870818708287083870848708587086870878708887089870908709187092870938709487095870968709787098870998710087101871028710387104871058710687107871088710987110871118711287113871148711587116871178711887119871208712187122871238712487125871268712787128871298713087131871328713387134871358713687137871388713987140871418714287143871448714587146871478714887149871508715187152871538715487155871568715787158871598716087161871628716387164871658716687167871688716987170871718717287173871748717587176871778717887179871808718187182871838718487185871868718787188871898719087191871928719387194871958719687197871988719987200872018720287203872048720587206872078720887209872108721187212872138721487215872168721787218872198722087221872228722387224872258722687227872288722987230872318723287233872348723587236872378723887239872408724187242872438724487245872468724787248872498725087251872528725387254872558725687257872588725987260872618726287263872648726587266872678726887269872708727187272872738727487275872768727787278872798728087281872828728387284872858728687287872888728987290872918729287293872948729587296872978729887299873008730187302873038730487305873068730787308873098731087311873128731387314873158731687317873188731987320873218732287323873248732587326873278732887329873308733187332873338733487335873368733787338873398734087341873428734387344873458734687347873488734987350873518735287353873548735587356873578735887359873608736187362873638736487365873668736787368873698737087371873728737387374873758737687377873788737987380873818738287383873848738587386873878738887389873908739187392873938739487395873968739787398873998740087401874028740387404874058740687407874088740987410874118741287413874148741587416874178741887419874208742187422874238742487425874268742787428874298743087431874328743387434874358743687437874388743987440874418744287443874448744587446874478744887449874508745187452874538745487455874568745787458874598746087461874628746387464874658746687467874688746987470874718747287473874748747587476874778747887479874808748187482874838748487485874868748787488874898749087491874928749387494874958749687497874988749987500875018750287503875048750587506875078750887509875108751187512875138751487515875168751787518875198752087521875228752387524875258752687527875288752987530875318753287533875348753587536875378753887539875408754187542875438754487545
  1. diff -Nur linux-2.6.36.orig/crypto/Kconfig linux-2.6.36/crypto/Kconfig
  2. --- linux-2.6.36.orig/crypto/Kconfig 2010-10-20 22:30:22.000000000 +0200
  3. +++ linux-2.6.36/crypto/Kconfig 2010-11-09 20:28:04.004996902 +0100
  4. @@ -845,3 +845,6 @@
  5. source "drivers/crypto/Kconfig"
  6. endif # if CRYPTO
  7. +
  8. +source "crypto/ocf/Kconfig"
  9. +
  10. diff -Nur linux-2.6.36.orig/crypto/Makefile linux-2.6.36/crypto/Makefile
  11. --- linux-2.6.36.orig/crypto/Makefile 2010-10-20 22:30:22.000000000 +0200
  12. +++ linux-2.6.36/crypto/Makefile 2010-11-09 20:28:04.014995662 +0100
  13. @@ -86,6 +86,8 @@
  14. obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
  15. obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
  16. +obj-$(CONFIG_OCF_OCF) += ocf/
  17. +
  18. #
  19. # generic algorithms and the async_tx api
  20. #
  21. diff -Nur linux-2.6.36.orig/crypto/ocf/c7108/aes-7108.c linux-2.6.36/crypto/ocf/c7108/aes-7108.c
  22. --- linux-2.6.36.orig/crypto/ocf/c7108/aes-7108.c 1970-01-01 01:00:00.000000000 +0100
  23. +++ linux-2.6.36/crypto/ocf/c7108/aes-7108.c 2010-11-09 20:28:04.061247304 +0100
  24. @@ -0,0 +1,839 @@
  25. +/*
  26. + * Copyright (C) 2006 Micronas USA
  27. + *
  28. + * 1. Redistributions of source code must retain the above copyright
  29. + * notice, this list of conditions and the following disclaimer.
  30. + * 2. Redistributions in binary form must reproduce the above copyright
  31. + * notice, this list of conditions and the following disclaimer in the
  32. + * documentation and/or other materials provided with the distribution.
  33. + * 3. The name of the author may not be used to endorse or promote products
  34. + * derived from this software without specific prior written permission.
  35. + *
  36. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  37. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  39. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  40. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  42. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  43. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  44. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  45. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  46. + *
  47. + * Effort sponsored in part by the Defense Advanced Research Projects
  48. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  49. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  50. + *
  51. + */
  52. +
  53. +//#include <linux/config.h>
  54. +#include <linux/module.h>
  55. +#include <linux/init.h>
  56. +#include <linux/list.h>
  57. +#include <linux/slab.h>
  58. +#include <linux/sched.h>
  59. +#include <linux/wait.h>
  60. +#include <linux/crypto.h>
  61. +#include <linux/mm.h>
  62. +#include <linux/skbuff.h>
  63. +#include <linux/random.h>
  64. +#include <asm/io.h>
  65. +#include <asm/delay.h>
  66. +//#include <asm/scatterlist.h>
  67. +#include <linux/scatterlist.h>
  68. +#include <linux/dma-mapping.h>
  69. +#include <linux/highmem.h>
  70. +#include <cryptodev.h>
  71. +#include <uio.h>
  72. +#include <aes-7108.h>
  73. +
  74. +/* Runtime mode */
  75. +static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR;
  76. +//static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC;
  77. +
  78. +static int32_t c7108_id = -1;
  79. +static struct cipher_7108 **c7108_sessions = NULL;
  80. +static u_int32_t c7108_sesnum = 0;
  81. +static unsigned long iobar;
  82. +
  83. +/* Crypto entry points */
  84. +static int c7108_process(void *, struct cryptop *, int);
  85. +static int c7108_newsession(void *, u_int32_t *, struct cryptoini *);
  86. +static int c7108_freesession(void *, u_int64_t);
  87. +
  88. +/* Globals */
  89. +static int debug = 0;
  90. +static spinlock_t csr_mutex;
  91. +
  92. +/* Generic controller-based lock */
  93. +#define AES_LOCK()\
  94. + spin_lock(&csr_mutex)
  95. +#define AES_UNLOCK()\
  96. + spin_unlock(&csr_mutex)
  97. +
  98. +/* 7108 AES register access */
  99. +#define c7108_reg_wr8(a,d) iowrite8(d, (void*)(iobar+(a)))
  100. +#define c7108_reg_wr16(a,d) iowrite16(d, (void*)(iobar+(a)))
  101. +#define c7108_reg_wr32(a,d) iowrite32(d, (void*)(iobar+(a)))
  102. +#define c7108_reg_rd8(a) ioread8((void*)(iobar+(a)))
  103. +#define c7108_reg_rd16(a) ioread16((void*)(iobar+(a)))
  104. +#define c7108_reg_rd32(a) ioread32((void*)(iobar+(a)))
  105. +
  106. +static int
  107. +c7108_xlate_key(int klen, u8* k8ptr, u32* k32ptr)
  108. +{
  109. + int i, nw=0;
  110. + nw = ((klen >= 256) ? 8 : (klen >= 192) ? 6 : 4);
  111. + for ( i = 0; i < nw; i++) {
  112. + k32ptr[i] = (k8ptr[i+3] << 24) | (k8ptr[i+2] << 16) |
  113. + (k8ptr[i+1] << 8) | k8ptr[i];
  114. +
  115. + }
  116. + return 0;
  117. +}
  118. +
  119. +static int
  120. +c7108_cache_key(int klen, u32* k32ptr, u8* k8ptr)
  121. +{
  122. + int i, nb=0;
  123. + u8* ptr = (u8*)k32ptr;
  124. + nb = ((klen >= 256) ? 32 : (klen >= 192) ? 24 : 16);
  125. + for ( i = 0; i < nb; i++)
  126. + k8ptr[i] = ptr[i];
  127. + return 0;
  128. +}
  129. +
  130. +static int
  131. +c7108_aes_setup_dma(u32 src, u32 dst, u32 len)
  132. +{
  133. + if (len < 16) {
  134. + printk("len < 16\n");
  135. + return -10;
  136. + }
  137. + if (len % 16) {
  138. + printk("len not multiple of 16\n");
  139. + return -11;
  140. + }
  141. + c7108_reg_wr16(C7108_AES_DMA_SRC0_LO, (u16) src);
  142. + c7108_reg_wr16(C7108_AES_DMA_SRC0_HI, (u16)((src & 0xffff0000) >> 16));
  143. + c7108_reg_wr16(C7108_AES_DMA_DST0_LO, (u16) dst);
  144. + c7108_reg_wr16(C7108_AES_DMA_DST0_HI, (u16)((dst & 0xffff0000) >> 16));
  145. + c7108_reg_wr16(C7108_AES_DMA_LEN, (u16) ((len / 16) - 1));
  146. +
  147. + return 0;
  148. +}
  149. +
  150. +static int
  151. +c7108_aes_set_hw_iv(u8 iv[16])
  152. +{
  153. + c7108_reg_wr16(C7108_AES_IV0_LO, (u16) ((iv[1] << 8) | iv[0]));
  154. + c7108_reg_wr16(C7108_AES_IV0_HI, (u16) ((iv[3] << 8) | iv[2]));
  155. + c7108_reg_wr16(C7108_AES_IV1_LO, (u16) ((iv[5] << 8) | iv[4]));
  156. + c7108_reg_wr16(C7108_AES_IV1_HI, (u16) ((iv[7] << 8) | iv[6]));
  157. + c7108_reg_wr16(C7108_AES_IV2_LO, (u16) ((iv[9] << 8) | iv[8]));
  158. + c7108_reg_wr16(C7108_AES_IV2_HI, (u16) ((iv[11] << 8) | iv[10]));
  159. + c7108_reg_wr16(C7108_AES_IV3_LO, (u16) ((iv[13] << 8) | iv[12]));
  160. + c7108_reg_wr16(C7108_AES_IV3_HI, (u16) ((iv[15] << 8) | iv[14]));
  161. +
  162. + return 0;
  163. +}
  164. +
  165. +static void
  166. +c7108_aes_read_dkey(u32 * dkey)
  167. +{
  168. + dkey[0] = (c7108_reg_rd16(C7108_AES_EKEY0_HI) << 16) |
  169. + c7108_reg_rd16(C7108_AES_EKEY0_LO);
  170. + dkey[1] = (c7108_reg_rd16(C7108_AES_EKEY1_HI) << 16) |
  171. + c7108_reg_rd16(C7108_AES_EKEY1_LO);
  172. + dkey[2] = (c7108_reg_rd16(C7108_AES_EKEY2_HI) << 16) |
  173. + c7108_reg_rd16(C7108_AES_EKEY2_LO);
  174. + dkey[3] = (c7108_reg_rd16(C7108_AES_EKEY3_HI) << 16) |
  175. + c7108_reg_rd16(C7108_AES_EKEY3_LO);
  176. + dkey[4] = (c7108_reg_rd16(C7108_AES_EKEY4_HI) << 16) |
  177. + c7108_reg_rd16(C7108_AES_EKEY4_LO);
  178. + dkey[5] = (c7108_reg_rd16(C7108_AES_EKEY5_HI) << 16) |
  179. + c7108_reg_rd16(C7108_AES_EKEY5_LO);
  180. + dkey[6] = (c7108_reg_rd16(C7108_AES_EKEY6_HI) << 16) |
  181. + c7108_reg_rd16(C7108_AES_EKEY6_LO);
  182. + dkey[7] = (c7108_reg_rd16(C7108_AES_EKEY7_HI) << 16) |
  183. + c7108_reg_rd16(C7108_AES_EKEY7_LO);
  184. +}
  185. +
  186. +static int
  187. +c7108_aes_cipher(int op,
  188. + u32 dst,
  189. + u32 src,
  190. + u32 len,
  191. + int klen,
  192. + u16 mode,
  193. + u32 key[8],
  194. + u8 iv[16])
  195. +{
  196. + int rv = 0, cnt=0;
  197. + u16 ctrl = 0, stat = 0;
  198. +
  199. + AES_LOCK();
  200. +
  201. + /* Setup key length */
  202. + if (klen == 128) {
  203. + ctrl |= C7108_AES_KEY_LEN_128;
  204. + } else if (klen == 192) {
  205. + ctrl |= C7108_AES_KEY_LEN_192;
  206. + } else if (klen == 256) {
  207. + ctrl |= C7108_AES_KEY_LEN_256;
  208. + } else {
  209. + AES_UNLOCK();
  210. + return -3;
  211. + }
  212. +
  213. + /* Check opcode */
  214. + if (C7108_AES_ENCRYPT == op) {
  215. + ctrl |= C7108_AES_ENCRYPT;
  216. + } else if (C7108_AES_DECRYPT == op) {
  217. + ctrl |= C7108_AES_DECRYPT;
  218. + } else {
  219. + AES_UNLOCK();
  220. + return -4;
  221. + }
  222. +
  223. + /* check mode */
  224. + if ( (mode != C7108_AES_CTRL_MODE_CBC) &&
  225. + (mode != C7108_AES_CTRL_MODE_CFB) &&
  226. + (mode != C7108_AES_CTRL_MODE_OFB) &&
  227. + (mode != C7108_AES_CTRL_MODE_CTR) &&
  228. + (mode != C7108_AES_CTRL_MODE_ECB) ) {
  229. + AES_UNLOCK();
  230. + return -5;
  231. + }
  232. +
  233. + /* Now set mode */
  234. + ctrl |= mode;
  235. +
  236. + /* For CFB, OFB, and CTR, neither backward key
  237. + * expansion nor key inversion is required.
  238. + */
  239. + if ( (C7108_AES_DECRYPT == op) &&
  240. + (C7108_AES_CTRL_MODE_CBC == mode ||
  241. + C7108_AES_CTRL_MODE_ECB == mode ) ){
  242. +
  243. + /* Program Key */
  244. + c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[4]);
  245. + c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[4] >> 16));
  246. + c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[5]);
  247. + c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[5] >> 16));
  248. + c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[6]);
  249. + c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[6] >> 16));
  250. + c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[7]);
  251. + c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[7] >> 16));
  252. + c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[2]);
  253. + c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[2] >> 16));
  254. + c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[3]);
  255. + c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[3] >> 16));
  256. +
  257. +
  258. + if (192 == klen) {
  259. + c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[7]);
  260. + c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[7] >> 16));
  261. + c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[7]);
  262. + c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[7] >> 16));
  263. +
  264. + } else if (256 == klen) {
  265. + /* 256 */
  266. + c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[0]);
  267. + c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[0] >> 16));
  268. + c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[1]);
  269. + c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[1] >> 16));
  270. +
  271. + }
  272. +
  273. + } else {
  274. + /* Program Key */
  275. + c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[0]);
  276. + c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[0] >> 16));
  277. + c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[1]);
  278. + c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[1] >> 16));
  279. + c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[2]);
  280. + c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[2] >> 16));
  281. + c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[3]);
  282. + c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[3] >> 16));
  283. + c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[4]);
  284. + c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[4] >> 16));
  285. + c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[5]);
  286. + c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[5] >> 16));
  287. + c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[6]);
  288. + c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[6] >> 16));
  289. + c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[7]);
  290. + c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[7] >> 16));
  291. +
  292. + }
  293. +
  294. + /* Set IV always */
  295. + c7108_aes_set_hw_iv(iv);
  296. +
  297. + /* Program DMA addresses */
  298. + if ((rv = c7108_aes_setup_dma(src, dst, len)) < 0) {
  299. + AES_UNLOCK();
  300. + return rv;
  301. + }
  302. +
  303. +
  304. + /* Start AES cipher */
  305. + c7108_reg_wr16(C7108_AES_CTRL, ctrl | C7108_AES_GO);
  306. +
  307. + //printk("Ctrl: 0x%x\n", ctrl | C7108_AES_GO);
  308. + do {
  309. + /* TODO: interrupt mode */
  310. + // printk("aes_stat=0x%x\n", stat);
  311. + //udelay(100);
  312. + } while ((cnt++ < 1000000) &&
  313. + !((stat=c7108_reg_rd16(C7108_AES_CTRL))&C7108_AES_OP_DONE));
  314. +
  315. +
  316. + if ((mode == C7108_AES_CTRL_MODE_ECB)||
  317. + (mode == C7108_AES_CTRL_MODE_CBC)) {
  318. + /* Save out key when the lock is held ... */
  319. + c7108_aes_read_dkey(key);
  320. + }
  321. +
  322. + AES_UNLOCK();
  323. + return 0;
  324. +
  325. +}
  326. +
  327. +/*
  328. + * Generate a new crypto device session.
  329. + */
  330. +static int
  331. +c7108_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
  332. +{
  333. + struct cipher_7108 **swd;
  334. + u_int32_t i;
  335. + char *algo;
  336. + int mode, xfm_type;
  337. +
  338. + dprintk("%s()\n", __FUNCTION__);
  339. + if (sid == NULL || cri == NULL) {
  340. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  341. + return EINVAL;
  342. + }
  343. +
  344. + if (c7108_sessions) {
  345. + for (i = 1; i < c7108_sesnum; i++)
  346. + if (c7108_sessions[i] == NULL)
  347. + break;
  348. + } else
  349. + i = 1; /* NB: to silence compiler warning */
  350. +
  351. + if (c7108_sessions == NULL || i == c7108_sesnum) {
  352. + if (c7108_sessions == NULL) {
  353. + i = 1; /* We leave c7108_sessions[0] empty */
  354. + c7108_sesnum = CRYPTO_SW_SESSIONS;
  355. + } else
  356. + c7108_sesnum *= 2;
  357. +
  358. + swd = kmalloc(c7108_sesnum * sizeof(struct cipher_7108 *),
  359. + GFP_ATOMIC);
  360. + if (swd == NULL) {
  361. + /* Reset session number */
  362. + if (c7108_sesnum == CRYPTO_SW_SESSIONS)
  363. + c7108_sesnum = 0;
  364. + else
  365. + c7108_sesnum /= 2;
  366. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  367. + return ENOBUFS;
  368. + }
  369. + memset(swd, 0, c7108_sesnum * sizeof(struct cipher_7108 *));
  370. +
  371. + /* Copy existing sessions */
  372. + if (c7108_sessions) {
  373. + memcpy(swd, c7108_sessions,
  374. + (c7108_sesnum / 2) * sizeof(struct cipher_7108 *));
  375. + kfree(c7108_sessions);
  376. + }
  377. +
  378. + c7108_sessions = swd;
  379. +
  380. + }
  381. +
  382. + swd = &c7108_sessions[i];
  383. + *sid = i;
  384. +
  385. + while (cri) {
  386. + *swd = (struct cipher_7108 *)
  387. + kmalloc(sizeof(struct cipher_7108), GFP_ATOMIC);
  388. + if (*swd == NULL) {
  389. + c7108_freesession(NULL, i);
  390. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  391. + return ENOBUFS;
  392. + }
  393. + memset(*swd, 0, sizeof(struct cipher_7108));
  394. +
  395. + algo = NULL;
  396. + mode = 0;
  397. + xfm_type = HW_TYPE_CIPHER;
  398. +
  399. + switch (cri->cri_alg) {
  400. +
  401. + case CRYPTO_AES_CBC:
  402. + algo = "aes";
  403. + mode = CRYPTO_TFM_MODE_CBC;
  404. + c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC;
  405. + break;
  406. +#if 0
  407. + case CRYPTO_AES_CTR:
  408. + algo = "aes_ctr";
  409. + mode = CRYPTO_TFM_MODE_CBC;
  410. + c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR;
  411. + break;
  412. + case CRYPTO_AES_ECB:
  413. + algo = "aes_ecb";
  414. + mode = CRYPTO_TFM_MODE_CBC;
  415. + c7108_crypto_mode = C7108_AES_CTRL_MODE_ECB;
  416. + break;
  417. + case CRYPTO_AES_OFB:
  418. + algo = "aes_ofb";
  419. + mode = CRYPTO_TFM_MODE_CBC;
  420. + c7108_crypto_mode = C7108_AES_CTRL_MODE_OFB;
  421. + break;
  422. + case CRYPTO_AES_CFB:
  423. + algo = "aes_cfb";
  424. + mode = CRYPTO_TFM_MODE_CBC;
  425. + c7108_crypto_mode = C7108_AES_CTRL_MODE_CFB;
  426. + break;
  427. +#endif
  428. + default:
  429. + printk("unsupported crypto algorithm: %d\n",
  430. + cri->cri_alg);
  431. + return -EINVAL;
  432. + break;
  433. + }
  434. +
  435. +
  436. + if (!algo || !*algo) {
  437. + printk("cypher_7108_crypto: Unknown algo 0x%x\n",
  438. + cri->cri_alg);
  439. + c7108_freesession(NULL, i);
  440. + return EINVAL;
  441. + }
  442. +
  443. + if (xfm_type == HW_TYPE_CIPHER) {
  444. + if (debug) {
  445. + dprintk("%s key:", __FUNCTION__);
  446. + for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
  447. + dprintk("%s0x%02x", (i % 8) ? " " : "\n ",
  448. + cri->cri_key[i]);
  449. + dprintk("\n");
  450. + }
  451. +
  452. + } else if (xfm_type == SW_TYPE_HMAC ||
  453. + xfm_type == SW_TYPE_HASH) {
  454. + printk("cypher_7108_crypto: HMAC unsupported!\n");
  455. + return -EINVAL;
  456. + c7108_freesession(NULL, i);
  457. + } else {
  458. + printk("cypher_7108_crypto: "
  459. + "Unhandled xfm_type %d\n", xfm_type);
  460. + c7108_freesession(NULL, i);
  461. + return EINVAL;
  462. + }
  463. +
  464. + (*swd)->cri_alg = cri->cri_alg;
  465. + (*swd)->xfm_type = xfm_type;
  466. +
  467. + cri = cri->cri_next;
  468. + swd = &((*swd)->next);
  469. + }
  470. + return 0;
  471. +}
  472. +
  473. +/*
  474. + * Free a session.
  475. + */
  476. +static int
  477. +c7108_freesession(void *arg, u_int64_t tid)
  478. +{
  479. + struct cipher_7108 *swd;
  480. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  481. +
  482. + dprintk("%s()\n", __FUNCTION__);
  483. + if (sid > c7108_sesnum || c7108_sessions == NULL ||
  484. + c7108_sessions[sid] == NULL) {
  485. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  486. + return(EINVAL);
  487. + }
  488. +
  489. + /* Silently accept and return */
  490. + if (sid == 0)
  491. + return(0);
  492. +
  493. + while ((swd = c7108_sessions[sid]) != NULL) {
  494. + c7108_sessions[sid] = swd->next;
  495. + kfree(swd);
  496. + }
  497. + return 0;
  498. +}
  499. +
  500. +/*
  501. + * Process a hardware request.
  502. + */
  503. +static int
  504. +c7108_process(void *arg, struct cryptop *crp, int hint)
  505. +{
  506. + struct cryptodesc *crd;
  507. + struct cipher_7108 *sw;
  508. + u_int32_t lid;
  509. + int type;
  510. + u32 hwkey[8];
  511. +
  512. +#define SCATTERLIST_MAX 16
  513. + struct scatterlist sg[SCATTERLIST_MAX];
  514. + int sg_num, sg_len, skip;
  515. + struct sk_buff *skb = NULL;
  516. + struct uio *uiop = NULL;
  517. +
  518. + dprintk("%s()\n", __FUNCTION__);
  519. + /* Sanity check */
  520. + if (crp == NULL) {
  521. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  522. + return EINVAL;
  523. + }
  524. +
  525. + crp->crp_etype = 0;
  526. +
  527. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  528. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  529. + crp->crp_etype = EINVAL;
  530. + goto done;
  531. + }
  532. +
  533. + lid = crp->crp_sid & 0xffffffff;
  534. + if (lid >= c7108_sesnum || lid == 0 || c7108_sessions == NULL ||
  535. + c7108_sessions[lid] == NULL) {
  536. + crp->crp_etype = ENOENT;
  537. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  538. + goto done;
  539. + }
  540. +
  541. + /*
  542. + * do some error checking outside of the loop for SKB and IOV
  543. + * processing this leaves us with valid skb or uiop pointers
  544. + * for later
  545. + */
  546. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  547. + skb = (struct sk_buff *) crp->crp_buf;
  548. + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
  549. + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX",
  550. + __FILE__, __LINE__,
  551. + skb_shinfo(skb)->nr_frags);
  552. + goto done;
  553. + }
  554. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  555. + uiop = (struct uio *) crp->crp_buf;
  556. + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
  557. + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX",
  558. + __FILE__, __LINE__,
  559. + uiop->uio_iovcnt);
  560. + goto done;
  561. + }
  562. + }
  563. +
  564. + /* Go through crypto descriptors, processing as we go */
  565. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  566. + /*
  567. + * Find the crypto context.
  568. + *
  569. + * XXX Note that the logic here prevents us from having
  570. + * XXX the same algorithm multiple times in a session
  571. + * XXX (or rather, we can but it won't give us the right
  572. + * XXX results). To do that, we'd need some way of differentiating
  573. + * XXX between the various instances of an algorithm (so we can
  574. + * XXX locate the correct crypto context).
  575. + */
  576. + for (sw = c7108_sessions[lid];
  577. + sw && sw->cri_alg != crd->crd_alg;
  578. + sw = sw->next)
  579. + ;
  580. +
  581. + /* No such context ? */
  582. + if (sw == NULL) {
  583. + crp->crp_etype = EINVAL;
  584. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  585. + goto done;
  586. + }
  587. +
  588. + skip = crd->crd_skip;
  589. +
  590. + /*
  591. + * setup the SG list skip from the start of the buffer
  592. + */
  593. + memset(sg, 0, sizeof(sg));
  594. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  595. + int i, len;
  596. + type = CRYPTO_BUF_SKBUF;
  597. +
  598. + sg_num = 0;
  599. + sg_len = 0;
  600. +
  601. + if (skip < skb_headlen(skb)) {
  602. + //sg[sg_num].page = virt_to_page(skb->data + skip);
  603. + //sg[sg_num].offset = offset_in_page(skb->data + skip);
  604. + len = skb_headlen(skb) - skip;
  605. + if (len + sg_len > crd->crd_len)
  606. + len = crd->crd_len - sg_len;
  607. + //sg[sg_num].length = len;
  608. + sg_set_page(&sg[sg_num], virt_to_page(skb->data + skip), len, offset_in_page(skb->data + skip));
  609. + sg_len += sg[sg_num].length;
  610. + sg_num++;
  611. + skip = 0;
  612. + } else
  613. + skip -= skb_headlen(skb);
  614. +
  615. + for (i = 0; sg_len < crd->crd_len &&
  616. + i < skb_shinfo(skb)->nr_frags &&
  617. + sg_num < SCATTERLIST_MAX; i++) {
  618. + if (skip < skb_shinfo(skb)->frags[i].size) {
  619. + //sg[sg_num].page = skb_shinfo(skb)->frags[i].page;
  620. + //sg[sg_num].offset = skb_shinfo(skb)->frags[i].page_offset + skip;
  621. + len = skb_shinfo(skb)->frags[i].size - skip;
  622. + if (len + sg_len > crd->crd_len)
  623. + len = crd->crd_len - sg_len;
  624. + //sg[sg_num].length = len;
  625. + sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page, len, skb_shinfo(skb)->frags[i].page_offset + skip);
  626. + sg_len += sg[sg_num].length;
  627. + sg_num++;
  628. + skip = 0;
  629. + } else
  630. + skip -= skb_shinfo(skb)->frags[i].size;
  631. + }
  632. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  633. + int len;
  634. + type = CRYPTO_BUF_IOV;
  635. + sg_len = 0;
  636. + for (sg_num = 0; sg_len < crd->crd_len &&
  637. + sg_num < uiop->uio_iovcnt &&
  638. + sg_num < SCATTERLIST_MAX; sg_num++) {
  639. + if (skip < uiop->uio_iov[sg_num].iov_len) {
  640. + //sg[sg_num].page = virt_to_page(uiop->uio_iov[sg_num].iov_base+skip);
  641. + //sg[sg_num].offset = offset_in_page(uiop->uio_iov[sg_num].iov_base+skip);
  642. + len = uiop->uio_iov[sg_num].iov_len - skip;
  643. + if (len + sg_len > crd->crd_len)
  644. + len = crd->crd_len - sg_len;
  645. + //sg[sg_num].length = len;
  646. + 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));
  647. + sg_len += sg[sg_num].length;
  648. + skip = 0;
  649. + } else
  650. + skip -= uiop->uio_iov[sg_num].iov_len;
  651. + }
  652. + } else {
  653. + type = CRYPTO_BUF_CONTIG;
  654. + //sg[0].page = virt_to_page(crp->crp_buf + skip);
  655. + //sg[0].offset = offset_in_page(crp->crp_buf + skip);
  656. + sg_len = (crp->crp_ilen - skip);
  657. + if (sg_len > crd->crd_len)
  658. + sg_len = crd->crd_len;
  659. + //sg[0].length = sg_len;
  660. + sg_set_page(&sg[0], virt_to_page(crp->crp_buf + skip), sg_len, offset_in_page(crp->crp_buf + skip));
  661. + sg_num = 1;
  662. + }
  663. +
  664. +
  665. + switch (sw->xfm_type) {
  666. +
  667. + case HW_TYPE_CIPHER: {
  668. +
  669. + unsigned char iv[64];
  670. + unsigned char *ivp = iv;
  671. + int i;
  672. + int ivsize = 16; /* fixed for AES */
  673. + int blocksize = 16; /* fixed for AES */
  674. +
  675. + if (sg_len < blocksize) {
  676. + crp->crp_etype = EINVAL;
  677. + dprintk("%s,%d: EINVAL len %d < %d\n",
  678. + __FILE__, __LINE__,
  679. + sg_len,
  680. + blocksize);
  681. + goto done;
  682. + }
  683. +
  684. + if (ivsize > sizeof(iv)) {
  685. + crp->crp_etype = EINVAL;
  686. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  687. + goto done;
  688. + }
  689. +
  690. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  691. +
  692. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  693. + ivp = crd->crd_iv;
  694. + } else {
  695. + get_random_bytes(ivp, ivsize);
  696. + }
  697. + /*
  698. + * do we have to copy the IV back to the buffer ?
  699. + */
  700. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  701. + crypto_copyback(crp->crp_buf,
  702. + crd->crd_inject,
  703. + ivsize,
  704. + (caddr_t)ivp);
  705. + }
  706. +
  707. + c7108_xlate_key(crd->crd_klen,
  708. + (u8*)crd->crd_key, (u32*)hwkey);
  709. +
  710. + /* Encrypt SG list */
  711. + for (i = 0; i < sg_num; i++) {
  712. + sg[i].dma_address =
  713. + dma_map_single(NULL,
  714. + kmap(sg_page(&sg[i])) + sg[i].offset, sg_len, DMA_BIDIRECTIONAL);
  715. +#if 0
  716. + printk("sg[%d]:0x%08x, off 0x%08x "
  717. + "kmap 0x%08x phys 0x%08x\n",
  718. + i, sg[i].page, sg[i].offset,
  719. + kmap(sg[i].page) + sg[i].offset,
  720. + sg[i].dma_address);
  721. +#endif
  722. + c7108_aes_cipher(C7108_AES_ENCRYPT,
  723. + sg[i].dma_address,
  724. + sg[i].dma_address,
  725. + sg_len,
  726. + crd->crd_klen,
  727. + c7108_crypto_mode,
  728. + hwkey,
  729. + ivp);
  730. +
  731. + if ((c7108_crypto_mode == C7108_AES_CTRL_MODE_CBC)||
  732. + (c7108_crypto_mode == C7108_AES_CTRL_MODE_ECB)) {
  733. + /* Read back expanded key and cache it in key
  734. + * context.
  735. + * NOTE: for ECB/CBC modes only (not CTR, CFB, OFB)
  736. + * where you set the key once.
  737. + */
  738. + c7108_cache_key(crd->crd_klen,
  739. + (u32*)hwkey, (u8*)crd->crd_key);
  740. +#if 0
  741. + printk("%s expanded key:", __FUNCTION__);
  742. + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
  743. + printk("%s0x%02x", (i % 8) ? " " : "\n ",
  744. + crd->crd_key[i]);
  745. + printk("\n");
  746. +#endif
  747. + }
  748. + }
  749. + }
  750. + else { /*decrypt */
  751. +
  752. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  753. + ivp = crd->crd_iv;
  754. + } else {
  755. + crypto_copydata(crp->crp_buf, crd->crd_inject,
  756. + ivsize, (caddr_t)ivp);
  757. + }
  758. +
  759. + c7108_xlate_key(crd->crd_klen,
  760. + (u8*)crd->crd_key, (u32*)hwkey);
  761. +
  762. + /* Decrypt SG list */
  763. + for (i = 0; i < sg_num; i++) {
  764. + sg[i].dma_address =
  765. + dma_map_single(NULL,
  766. + kmap(sg_page(&sg[i])) + sg[i].offset,
  767. + sg_len, DMA_BIDIRECTIONAL);
  768. +
  769. +#if 0
  770. + printk("sg[%d]:0x%08x, off 0x%08x "
  771. + "kmap 0x%08x phys 0x%08x\n",
  772. + i, sg[i].page, sg[i].offset,
  773. + kmap(sg[i].page) + sg[i].offset,
  774. + sg[i].dma_address);
  775. +#endif
  776. + c7108_aes_cipher(C7108_AES_DECRYPT,
  777. + sg[i].dma_address,
  778. + sg[i].dma_address,
  779. + sg_len,
  780. + crd->crd_klen,
  781. + c7108_crypto_mode,
  782. + hwkey,
  783. + ivp);
  784. + }
  785. + }
  786. + } break;
  787. + case SW_TYPE_HMAC:
  788. + case SW_TYPE_HASH:
  789. + crp->crp_etype = EINVAL;
  790. + goto done;
  791. + break;
  792. +
  793. + case SW_TYPE_COMP:
  794. + crp->crp_etype = EINVAL;
  795. + goto done;
  796. + break;
  797. +
  798. + default:
  799. + /* Unknown/unsupported algorithm */
  800. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  801. + crp->crp_etype = EINVAL;
  802. + goto done;
  803. + }
  804. + }
  805. +
  806. +done:
  807. + crypto_done(crp);
  808. + return 0;
  809. +}
  810. +
  811. +static struct {
  812. + softc_device_decl sc_dev;
  813. +} a7108dev;
  814. +
  815. +static device_method_t a7108_methods = {
  816. +/* crypto device methods */
  817. + DEVMETHOD(cryptodev_newsession, c7108_newsession),
  818. + DEVMETHOD(cryptodev_freesession, c7108_freesession),
  819. + DEVMETHOD(cryptodev_process, c7108_process),
  820. + DEVMETHOD(cryptodev_kprocess, NULL)
  821. +};
  822. +
  823. +static int
  824. +cypher_7108_crypto_init(void)
  825. +{
  826. + dprintk("%s(%p)\n", __FUNCTION__, cypher_7108_crypto_init);
  827. +
  828. + iobar = (unsigned long)ioremap(CCU_AES_REG_BASE, 0x4000);
  829. + printk("7108: AES @ 0x%08x (0x%08x phys) %s mode\n",
  830. + iobar, CCU_AES_REG_BASE,
  831. + c7108_crypto_mode & C7108_AES_CTRL_MODE_CBC ? "CBC" :
  832. + c7108_crypto_mode & C7108_AES_CTRL_MODE_ECB ? "ECB" :
  833. + c7108_crypto_mode & C7108_AES_CTRL_MODE_CTR ? "CTR" :
  834. + c7108_crypto_mode & C7108_AES_CTRL_MODE_CFB ? "CFB" :
  835. + c7108_crypto_mode & C7108_AES_CTRL_MODE_OFB ? "OFB" : "???");
  836. + csr_mutex = SPIN_LOCK_UNLOCKED;
  837. +
  838. + memset(&a7108dev, 0, sizeof(a7108dev));
  839. + softc_device_init(&a7108dev, "aes7108", 0, a7108_methods);
  840. +
  841. + c7108_id = crypto_get_driverid(softc_get_device(&a7108dev), CRYPTOCAP_F_HARDWARE);
  842. + if (c7108_id < 0)
  843. + panic("7108: crypto device cannot initialize!");
  844. +
  845. +// crypto_register(c7108_id, CRYPTO_AES_CBC, 0, 0, c7108_newsession, c7108_freesession, c7108_process, NULL);
  846. + crypto_register(c7108_id, CRYPTO_AES_CBC, 0, 0);
  847. +
  848. + return(0);
  849. +}
  850. +
  851. +static void
  852. +cypher_7108_crypto_exit(void)
  853. +{
  854. + dprintk("%s()\n", __FUNCTION__);
  855. + crypto_unregister_all(c7108_id);
  856. + c7108_id = -1;
  857. +}
  858. +
  859. +module_init(cypher_7108_crypto_init);
  860. +module_exit(cypher_7108_crypto_exit);
  861. +
  862. +MODULE_LICENSE("Dual BSD/GPL");
  863. +MODULE_DESCRIPTION("Cypher 7108 Crypto (OCF module for kernel crypto)");
  864. diff -Nur linux-2.6.36.orig/crypto/ocf/c7108/aes-7108.h linux-2.6.36/crypto/ocf/c7108/aes-7108.h
  865. --- linux-2.6.36.orig/crypto/ocf/c7108/aes-7108.h 1970-01-01 01:00:00.000000000 +0100
  866. +++ linux-2.6.36/crypto/ocf/c7108/aes-7108.h 2010-11-09 20:28:04.102495305 +0100
  867. @@ -0,0 +1,134 @@
  868. +/*
  869. + * Copyright (C) 2006 Micronas USA
  870. + *
  871. + * 1. Redistributions of source code must retain the above copyright
  872. + * notice, this list of conditions and the following disclaimer.
  873. + * 2. Redistributions in binary form must reproduce the above copyright
  874. + * notice, this list of conditions and the following disclaimer in the
  875. + * documentation and/or other materials provided with the distribution.
  876. + * 3. The name of the author may not be used to endorse or promote products
  877. + * derived from this software without specific prior written permission.
  878. + *
  879. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  880. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  881. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  882. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  883. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  884. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  885. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  886. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  887. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  888. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  889. + *
  890. + * Effort sponsored in part by the Defense Advanced Research Projects
  891. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  892. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  893. + *
  894. + */
  895. +
  896. +#ifndef __AES_7108_H__
  897. +#define __AES_7108_H__
  898. +
  899. +/* Cypher 7108 AES Controller Hardware */
  900. +#define CCU_REG_BASE 0x1b500000
  901. +#define CCU_AES_REG_BASE (CCU_REG_BASE + 0x100)
  902. +#define C7108_AES_KEY0_LO (0x0000)
  903. +#define C7108_AES_KEY0_HI (0x0004)
  904. +#define C7108_AES_KEY1_LO (0x0008)
  905. +#define C7108_AES_KEY1_HI (0x000c)
  906. +#define C7108_AES_KEY2_LO (0x0010)
  907. +#define C7108_AES_KEY2_HI (0x0014)
  908. +#define C7108_AES_KEY3_LO (0x0018)
  909. +#define C7108_AES_KEY3_HI (0x001c)
  910. +#define C7108_AES_KEY4_LO (0x0020)
  911. +#define C7108_AES_KEY4_HI (0x0024)
  912. +#define C7108_AES_KEY5_LO (0x0028)
  913. +#define C7108_AES_KEY5_HI (0x002c)
  914. +#define C7108_AES_KEY6_LO (0x0030)
  915. +#define C7108_AES_KEY6_HI (0x0034)
  916. +#define C7108_AES_KEY7_LO (0x0038)
  917. +#define C7108_AES_KEY7_HI (0x003c)
  918. +#define C7108_AES_IV0_LO (0x0040)
  919. +#define C7108_AES_IV0_HI (0x0044)
  920. +#define C7108_AES_IV1_LO (0x0048)
  921. +#define C7108_AES_IV1_HI (0x004c)
  922. +#define C7108_AES_IV2_LO (0x0050)
  923. +#define C7108_AES_IV2_HI (0x0054)
  924. +#define C7108_AES_IV3_LO (0x0058)
  925. +#define C7108_AES_IV3_HI (0x005c)
  926. +
  927. +#define C7108_AES_DMA_SRC0_LO (0x0068) /* Bits 0:15 */
  928. +#define C7108_AES_DMA_SRC0_HI (0x006c) /* Bits 27:16 */
  929. +#define C7108_AES_DMA_DST0_LO (0x0070) /* Bits 0:15 */
  930. +#define C7108_AES_DMA_DST0_HI (0x0074) /* Bits 27:16 */
  931. +#define C7108_AES_DMA_LEN (0x0078) /*Bytes:(Count+1)x16 */
  932. +
  933. +/* AES/Copy engine control register */
  934. +#define C7108_AES_CTRL (0x007c) /* AES control */
  935. +#define C7108_AES_CTRL_RS (1<<0) /* Which set of src/dst to use */
  936. +
  937. +/* AES Cipher mode, controlled by setting Bits 2:0 */
  938. +#define C7108_AES_CTRL_MODE_CBC 0
  939. +#define C7108_AES_CTRL_MODE_CFB (1<<0)
  940. +#define C7108_AES_CTRL_MODE_OFB (1<<1)
  941. +#define C7108_AES_CTRL_MODE_CTR ((1<<0)|(1<<1))
  942. +#define C7108_AES_CTRL_MODE_ECB (1<<2)
  943. +
  944. +/* AES Key length , Bits 5:4 */
  945. +#define C7108_AES_KEY_LEN_128 0 /* 00 */
  946. +#define C7108_AES_KEY_LEN_192 (1<<4) /* 01 */
  947. +#define C7108_AES_KEY_LEN_256 (1<<5) /* 10 */
  948. +
  949. +/* AES Operation (crypt/decrypt), Bit 3 */
  950. +#define C7108_AES_DECRYPT (1<<3) /* Clear for encrypt */
  951. +#define C7108_AES_ENCRYPT 0
  952. +#define C7108_AES_INTR (1<<13) /* Set on done trans from 0->1*/
  953. +#define C7108_AES_GO (1<<14) /* Run */
  954. +#define C7108_AES_OP_DONE (1<<15) /* Set when complete */
  955. +
  956. +
  957. +/* Expanded key registers */
  958. +#define C7108_AES_EKEY0_LO (0x0080)
  959. +#define C7108_AES_EKEY0_HI (0x0084)
  960. +#define C7108_AES_EKEY1_LO (0x0088)
  961. +#define C7108_AES_EKEY1_HI (0x008c)
  962. +#define C7108_AES_EKEY2_LO (0x0090)
  963. +#define C7108_AES_EKEY2_HI (0x0094)
  964. +#define C7108_AES_EKEY3_LO (0x0098)
  965. +#define C7108_AES_EKEY3_HI (0x009c)
  966. +#define C7108_AES_EKEY4_LO (0x00a0)
  967. +#define C7108_AES_EKEY4_HI (0x00a4)
  968. +#define C7108_AES_EKEY5_LO (0x00a8)
  969. +#define C7108_AES_EKEY5_HI (0x00ac)
  970. +#define C7108_AES_EKEY6_LO (0x00b0)
  971. +#define C7108_AES_EKEY6_HI (0x00b4)
  972. +#define C7108_AES_EKEY7_LO (0x00b8)
  973. +#define C7108_AES_EKEY7_HI (0x00bc)
  974. +#define C7108_AES_OK (0x00fc) /* Reset: "OK" */
  975. +
  976. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  977. +
  978. +/* Software session entry */
  979. +
  980. +#define HW_TYPE_CIPHER 0
  981. +#define SW_TYPE_HMAC 1
  982. +#define SW_TYPE_AUTH2 2
  983. +#define SW_TYPE_HASH 3
  984. +#define SW_TYPE_COMP 4
  985. +
  986. +struct cipher_7108 {
  987. + int xfm_type;
  988. + int cri_alg;
  989. + union {
  990. + struct {
  991. + char sw_key[HMAC_BLOCK_LEN];
  992. + int sw_klen;
  993. + int sw_authlen;
  994. + } hmac;
  995. + } u;
  996. + struct cipher_7108 *next;
  997. +};
  998. +
  999. +
  1000. +
  1001. +#endif /* __C7108_AES_7108_H__ */
  1002. diff -Nur linux-2.6.36.orig/crypto/ocf/c7108/Makefile linux-2.6.36/crypto/ocf/c7108/Makefile
  1003. --- linux-2.6.36.orig/crypto/ocf/c7108/Makefile 1970-01-01 01:00:00.000000000 +0100
  1004. +++ linux-2.6.36/crypto/ocf/c7108/Makefile 2010-11-09 20:28:04.152495478 +0100
  1005. @@ -0,0 +1,12 @@
  1006. +# for SGlinux builds
  1007. +-include $(ROOTDIR)/modules/.config
  1008. +
  1009. +obj-$(CONFIG_OCF_C7108) += aes-7108.o
  1010. +
  1011. +obj ?= .
  1012. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  1013. +
  1014. +ifdef TOPDIR
  1015. +-include $(TOPDIR)/Rules.make
  1016. +endif
  1017. +
  1018. diff -Nur linux-2.6.36.orig/crypto/ocf/Config.in linux-2.6.36/crypto/ocf/Config.in
  1019. --- linux-2.6.36.orig/crypto/ocf/Config.in 1970-01-01 01:00:00.000000000 +0100
  1020. +++ linux-2.6.36/crypto/ocf/Config.in 2010-11-09 20:28:04.191247583 +0100
  1021. @@ -0,0 +1,36 @@
  1022. +#############################################################################
  1023. +
  1024. +mainmenu_option next_comment
  1025. +comment 'OCF Configuration'
  1026. +tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF
  1027. +dep_mbool ' enable fips RNG checks (fips check on RNG data before use)' \
  1028. + CONFIG_OCF_FIPS $CONFIG_OCF_OCF
  1029. +dep_mbool ' enable harvesting entropy for /dev/random' \
  1030. + CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF
  1031. +dep_tristate ' cryptodev (user space support)' \
  1032. + CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF
  1033. +dep_tristate ' cryptosoft (software crypto engine)' \
  1034. + CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF
  1035. +dep_tristate ' safenet (HW crypto engine)' \
  1036. + CONFIG_OCF_SAFE $CONFIG_OCF_OCF
  1037. +dep_tristate ' IXP4xx (HW crypto engine)' \
  1038. + CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF
  1039. +dep_mbool ' Enable IXP4xx HW to perform SHA1 and MD5 hashing (very slow)' \
  1040. + CONFIG_OCF_IXP4XX_SHA1_MD5 $CONFIG_OCF_IXP4XX
  1041. +dep_tristate ' hifn (HW crypto engine)' \
  1042. + CONFIG_OCF_HIFN $CONFIG_OCF_OCF
  1043. +dep_tristate ' talitos (HW crypto engine)' \
  1044. + CONFIG_OCF_TALITOS $CONFIG_OCF_OCF
  1045. +dep_tristate ' pasemi (HW crypto engine)' \
  1046. + CONFIG_OCF_PASEMI $CONFIG_OCF_OCF
  1047. +dep_tristate ' ep80579 (HW crypto engine)' \
  1048. + CONFIG_OCF_EP80579 $CONFIG_OCF_OCF
  1049. +dep_tristate ' Micronas c7108 (HW crypto engine)' \
  1050. + CONFIG_OCF_C7108 $CONFIG_OCF_OCF
  1051. +dep_tristate ' ocfnull (does no crypto)' \
  1052. + CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF
  1053. +dep_tristate ' ocf-bench (HW crypto in-kernel benchmark)' \
  1054. + CONFIG_OCF_BENCH $CONFIG_OCF_OCF
  1055. +endmenu
  1056. +
  1057. +#############################################################################
  1058. diff -Nur linux-2.6.36.orig/crypto/ocf/criov.c linux-2.6.36/crypto/ocf/criov.c
  1059. --- linux-2.6.36.orig/crypto/ocf/criov.c 1970-01-01 01:00:00.000000000 +0100
  1060. +++ linux-2.6.36/crypto/ocf/criov.c 2010-11-09 20:28:04.232050075 +0100
  1061. @@ -0,0 +1,215 @@
  1062. +/* $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $ */
  1063. +
  1064. +/*
  1065. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  1066. + * Copyright (C) 2006-2010 David McCullough
  1067. + * Copyright (C) 2004-2005 Intel Corporation.
  1068. + * The license and original author are listed below.
  1069. + *
  1070. + * Copyright (c) 1999 Theo de Raadt
  1071. + *
  1072. + * Redistribution and use in source and binary forms, with or without
  1073. + * modification, are permitted provided that the following conditions
  1074. + * are met:
  1075. + *
  1076. + * 1. Redistributions of source code must retain the above copyright
  1077. + * notice, this list of conditions and the following disclaimer.
  1078. + * 2. Redistributions in binary form must reproduce the above copyright
  1079. + * notice, this list of conditions and the following disclaimer in the
  1080. + * documentation and/or other materials provided with the distribution.
  1081. + * 3. The name of the author may not be used to endorse or promote products
  1082. + * derived from this software without specific prior written permission.
  1083. + *
  1084. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  1085. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  1086. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  1087. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  1088. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  1089. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  1090. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  1091. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1092. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  1093. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1094. + *
  1095. +__FBSDID("$FreeBSD: src/sys/opencrypto/criov.c,v 1.5 2006/06/04 22:15:13 pjd Exp $");
  1096. + */
  1097. +
  1098. +#ifndef AUTOCONF_INCLUDED
  1099. +#include <linux/config.h>
  1100. +#endif
  1101. +#include <linux/module.h>
  1102. +#include <linux/init.h>
  1103. +#include <linux/slab.h>
  1104. +#include <linux/uio.h>
  1105. +#include <linux/skbuff.h>
  1106. +#include <linux/kernel.h>
  1107. +#include <linux/mm.h>
  1108. +#include <asm/io.h>
  1109. +
  1110. +#include <uio.h>
  1111. +#include <cryptodev.h>
  1112. +
  1113. +/*
  1114. + * This macro is only for avoiding code duplication, as we need to skip
  1115. + * given number of bytes in the same way in three functions below.
  1116. + */
  1117. +#define CUIO_SKIP() do { \
  1118. + KASSERT(off >= 0, ("%s: off %d < 0", __func__, off)); \
  1119. + KASSERT(len >= 0, ("%s: len %d < 0", __func__, len)); \
  1120. + while (off > 0) { \
  1121. + KASSERT(iol >= 0, ("%s: empty in skip", __func__)); \
  1122. + if (off < iov->iov_len) \
  1123. + break; \
  1124. + off -= iov->iov_len; \
  1125. + iol--; \
  1126. + iov++; \
  1127. + } \
  1128. +} while (0)
  1129. +
  1130. +void
  1131. +cuio_copydata(struct uio* uio, int off, int len, caddr_t cp)
  1132. +{
  1133. + struct iovec *iov = uio->uio_iov;
  1134. + int iol = uio->uio_iovcnt;
  1135. + unsigned count;
  1136. +
  1137. + CUIO_SKIP();
  1138. + while (len > 0) {
  1139. + KASSERT(iol >= 0, ("%s: empty", __func__));
  1140. + count = min((int)(iov->iov_len - off), len);
  1141. + memcpy(cp, ((caddr_t)iov->iov_base) + off, count);
  1142. + len -= count;
  1143. + cp += count;
  1144. + off = 0;
  1145. + iol--;
  1146. + iov++;
  1147. + }
  1148. +}
  1149. +
  1150. +void
  1151. +cuio_copyback(struct uio* uio, int off, int len, caddr_t cp)
  1152. +{
  1153. + struct iovec *iov = uio->uio_iov;
  1154. + int iol = uio->uio_iovcnt;
  1155. + unsigned count;
  1156. +
  1157. + CUIO_SKIP();
  1158. + while (len > 0) {
  1159. + KASSERT(iol >= 0, ("%s: empty", __func__));
  1160. + count = min((int)(iov->iov_len - off), len);
  1161. + memcpy(((caddr_t)iov->iov_base) + off, cp, count);
  1162. + len -= count;
  1163. + cp += count;
  1164. + off = 0;
  1165. + iol--;
  1166. + iov++;
  1167. + }
  1168. +}
  1169. +
  1170. +/*
  1171. + * Return a pointer to iov/offset of location in iovec list.
  1172. + */
  1173. +struct iovec *
  1174. +cuio_getptr(struct uio *uio, int loc, int *off)
  1175. +{
  1176. + struct iovec *iov = uio->uio_iov;
  1177. + int iol = uio->uio_iovcnt;
  1178. +
  1179. + while (loc >= 0) {
  1180. + /* Normal end of search */
  1181. + if (loc < iov->iov_len) {
  1182. + *off = loc;
  1183. + return (iov);
  1184. + }
  1185. +
  1186. + loc -= iov->iov_len;
  1187. + if (iol == 0) {
  1188. + if (loc == 0) {
  1189. + /* Point at the end of valid data */
  1190. + *off = iov->iov_len;
  1191. + return (iov);
  1192. + } else
  1193. + return (NULL);
  1194. + } else {
  1195. + iov++, iol--;
  1196. + }
  1197. + }
  1198. +
  1199. + return (NULL);
  1200. +}
  1201. +
  1202. +EXPORT_SYMBOL(cuio_copyback);
  1203. +EXPORT_SYMBOL(cuio_copydata);
  1204. +EXPORT_SYMBOL(cuio_getptr);
  1205. +
  1206. +
  1207. +static void
  1208. +skb_copy_bits_back(struct sk_buff *skb, int offset, caddr_t cp, int len)
  1209. +{
  1210. + int i;
  1211. + if (offset < skb_headlen(skb)) {
  1212. + memcpy(skb->data + offset, cp, min_t(int, skb_headlen(skb), len));
  1213. + len -= skb_headlen(skb);
  1214. + cp += skb_headlen(skb);
  1215. + }
  1216. + offset -= skb_headlen(skb);
  1217. + for (i = 0; len > 0 && i < skb_shinfo(skb)->nr_frags; i++) {
  1218. + if (offset < skb_shinfo(skb)->frags[i].size) {
  1219. + memcpy(page_address(skb_shinfo(skb)->frags[i].page) +
  1220. + skb_shinfo(skb)->frags[i].page_offset,
  1221. + cp, min_t(int, skb_shinfo(skb)->frags[i].size, len));
  1222. + len -= skb_shinfo(skb)->frags[i].size;
  1223. + cp += skb_shinfo(skb)->frags[i].size;
  1224. + }
  1225. + offset -= skb_shinfo(skb)->frags[i].size;
  1226. + }
  1227. +}
  1228. +
  1229. +void
  1230. +crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in)
  1231. +{
  1232. +
  1233. + if ((flags & CRYPTO_F_SKBUF) != 0)
  1234. + skb_copy_bits_back((struct sk_buff *)buf, off, in, size);
  1235. + else if ((flags & CRYPTO_F_IOV) != 0)
  1236. + cuio_copyback((struct uio *)buf, off, size, in);
  1237. + else
  1238. + bcopy(in, buf + off, size);
  1239. +}
  1240. +
  1241. +void
  1242. +crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out)
  1243. +{
  1244. +
  1245. + if ((flags & CRYPTO_F_SKBUF) != 0)
  1246. + skb_copy_bits((struct sk_buff *)buf, off, out, size);
  1247. + else if ((flags & CRYPTO_F_IOV) != 0)
  1248. + cuio_copydata((struct uio *)buf, off, size, out);
  1249. + else
  1250. + bcopy(buf + off, out, size);
  1251. +}
  1252. +
  1253. +int
  1254. +crypto_apply(int flags, caddr_t buf, int off, int len,
  1255. + int (*f)(void *, void *, u_int), void *arg)
  1256. +{
  1257. +#if 0
  1258. + int error;
  1259. +
  1260. + if ((flags & CRYPTO_F_SKBUF) != 0)
  1261. + error = XXXXXX((struct mbuf *)buf, off, len, f, arg);
  1262. + else if ((flags & CRYPTO_F_IOV) != 0)
  1263. + error = cuio_apply((struct uio *)buf, off, len, f, arg);
  1264. + else
  1265. + error = (*f)(arg, buf + off, len);
  1266. + return (error);
  1267. +#else
  1268. + KASSERT(0, ("crypto_apply not implemented!\n"));
  1269. +#endif
  1270. + return 0;
  1271. +}
  1272. +
  1273. +EXPORT_SYMBOL(crypto_copyback);
  1274. +EXPORT_SYMBOL(crypto_copydata);
  1275. +EXPORT_SYMBOL(crypto_apply);
  1276. +
  1277. diff -Nur linux-2.6.36.orig/crypto/ocf/crypto.c linux-2.6.36/crypto/ocf/crypto.c
  1278. --- linux-2.6.36.orig/crypto/ocf/crypto.c 1970-01-01 01:00:00.000000000 +0100
  1279. +++ linux-2.6.36/crypto/ocf/crypto.c 2010-11-09 20:28:04.272495385 +0100
  1280. @@ -0,0 +1,1784 @@
  1281. +/*-
  1282. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  1283. + * Copyright (C) 2006-2010 David McCullough
  1284. + * Copyright (C) 2004-2005 Intel Corporation.
  1285. + * The license and original author are listed below.
  1286. + *
  1287. + * Redistribution and use in source and binary forms, with or without
  1288. + * Copyright (c) 2002-2006 Sam Leffler. All rights reserved.
  1289. + *
  1290. + * modification, are permitted provided that the following conditions
  1291. + * are met:
  1292. + * 1. Redistributions of source code must retain the above copyright
  1293. + * notice, this list of conditions and the following disclaimer.
  1294. + * 2. Redistributions in binary form must reproduce the above copyright
  1295. + * notice, this list of conditions and the following disclaimer in the
  1296. + * documentation and/or other materials provided with the distribution.
  1297. + *
  1298. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  1299. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  1300. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  1301. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  1302. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  1303. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  1304. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  1305. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1306. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  1307. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1308. + */
  1309. +
  1310. +#if 0
  1311. +#include <sys/cdefs.h>
  1312. +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.27 2007/03/21 03:42:51 sam Exp $");
  1313. +#endif
  1314. +
  1315. +/*
  1316. + * Cryptographic Subsystem.
  1317. + *
  1318. + * This code is derived from the Openbsd Cryptographic Framework (OCF)
  1319. + * that has the copyright shown below. Very little of the original
  1320. + * code remains.
  1321. + */
  1322. +/*-
  1323. + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
  1324. + *
  1325. + * This code was written by Angelos D. Keromytis in Athens, Greece, in
  1326. + * February 2000. Network Security Technologies Inc. (NSTI) kindly
  1327. + * supported the development of this code.
  1328. + *
  1329. + * Copyright (c) 2000, 2001 Angelos D. Keromytis
  1330. + *
  1331. + * Permission to use, copy, and modify this software with or without fee
  1332. + * is hereby granted, provided that this entire notice is included in
  1333. + * all source code copies of any software which is or includes a copy or
  1334. + * modification of this software.
  1335. + *
  1336. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
  1337. + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
  1338. + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
  1339. + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
  1340. + * PURPOSE.
  1341. + *
  1342. +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp Exp $");
  1343. + */
  1344. +
  1345. +
  1346. +#ifndef AUTOCONF_INCLUDED
  1347. +#include <linux/config.h>
  1348. +#endif
  1349. +#include <linux/module.h>
  1350. +#include <linux/init.h>
  1351. +#include <linux/list.h>
  1352. +#include <linux/slab.h>
  1353. +#include <linux/wait.h>
  1354. +#include <linux/sched.h>
  1355. +#include <linux/spinlock.h>
  1356. +#include <linux/version.h>
  1357. +#include <cryptodev.h>
  1358. +
  1359. +/*
  1360. + * keep track of whether or not we have been initialised, a big
  1361. + * issue if we are linked into the kernel and a driver gets started before
  1362. + * us
  1363. + */
  1364. +static int crypto_initted = 0;
  1365. +
  1366. +/*
  1367. + * Crypto drivers register themselves by allocating a slot in the
  1368. + * crypto_drivers table with crypto_get_driverid() and then registering
  1369. + * each algorithm they support with crypto_register() and crypto_kregister().
  1370. + */
  1371. +
  1372. +/*
  1373. + * lock on driver table
  1374. + * we track its state as spin_is_locked does not do anything on non-SMP boxes
  1375. + */
  1376. +static spinlock_t crypto_drivers_lock;
  1377. +static int crypto_drivers_locked; /* for non-SMP boxes */
  1378. +
  1379. +#define CRYPTO_DRIVER_LOCK() \
  1380. + ({ \
  1381. + spin_lock_irqsave(&crypto_drivers_lock, d_flags); \
  1382. + crypto_drivers_locked = 1; \
  1383. + dprintk("%s,%d: DRIVER_LOCK()\n", __FILE__, __LINE__); \
  1384. + })
  1385. +#define CRYPTO_DRIVER_UNLOCK() \
  1386. + ({ \
  1387. + dprintk("%s,%d: DRIVER_UNLOCK()\n", __FILE__, __LINE__); \
  1388. + crypto_drivers_locked = 0; \
  1389. + spin_unlock_irqrestore(&crypto_drivers_lock, d_flags); \
  1390. + })
  1391. +#define CRYPTO_DRIVER_ASSERT() \
  1392. + ({ \
  1393. + if (!crypto_drivers_locked) { \
  1394. + dprintk("%s,%d: DRIVER_ASSERT!\n", __FILE__, __LINE__); \
  1395. + } \
  1396. + })
  1397. +
  1398. +/*
  1399. + * Crypto device/driver capabilities structure.
  1400. + *
  1401. + * Synchronization:
  1402. + * (d) - protected by CRYPTO_DRIVER_LOCK()
  1403. + * (q) - protected by CRYPTO_Q_LOCK()
  1404. + * Not tagged fields are read-only.
  1405. + */
  1406. +struct cryptocap {
  1407. + device_t cc_dev; /* (d) device/driver */
  1408. + u_int32_t cc_sessions; /* (d) # of sessions */
  1409. + u_int32_t cc_koperations; /* (d) # os asym operations */
  1410. + /*
  1411. + * Largest possible operator length (in bits) for each type of
  1412. + * encryption algorithm. XXX not used
  1413. + */
  1414. + u_int16_t cc_max_op_len[CRYPTO_ALGORITHM_MAX + 1];
  1415. + u_int8_t cc_alg[CRYPTO_ALGORITHM_MAX + 1];
  1416. + u_int8_t cc_kalg[CRK_ALGORITHM_MAX + 1];
  1417. +
  1418. + int cc_flags; /* (d) flags */
  1419. +#define CRYPTOCAP_F_CLEANUP 0x80000000 /* needs resource cleanup */
  1420. + int cc_qblocked; /* (q) symmetric q blocked */
  1421. + int cc_kqblocked; /* (q) asymmetric q blocked */
  1422. +
  1423. + int cc_unqblocked; /* (q) symmetric q blocked */
  1424. + int cc_unkqblocked; /* (q) asymmetric q blocked */
  1425. +};
  1426. +static struct cryptocap *crypto_drivers = NULL;
  1427. +static int crypto_drivers_num = 0;
  1428. +
  1429. +/*
  1430. + * There are two queues for crypto requests; one for symmetric (e.g.
  1431. + * cipher) operations and one for asymmetric (e.g. MOD)operations.
  1432. + * A single mutex is used to lock access to both queues. We could
  1433. + * have one per-queue but having one simplifies handling of block/unblock
  1434. + * operations.
  1435. + */
  1436. +static int crp_sleep = 0;
  1437. +static LIST_HEAD(crp_q); /* request queues */
  1438. +static LIST_HEAD(crp_kq);
  1439. +
  1440. +static spinlock_t crypto_q_lock;
  1441. +
  1442. +int crypto_all_qblocked = 0; /* protect with Q_LOCK */
  1443. +module_param(crypto_all_qblocked, int, 0444);
  1444. +MODULE_PARM_DESC(crypto_all_qblocked, "Are all crypto queues blocked");
  1445. +
  1446. +int crypto_all_kqblocked = 0; /* protect with Q_LOCK */
  1447. +module_param(crypto_all_kqblocked, int, 0444);
  1448. +MODULE_PARM_DESC(crypto_all_kqblocked, "Are all asym crypto queues blocked");
  1449. +
  1450. +#define CRYPTO_Q_LOCK() \
  1451. + ({ \
  1452. + spin_lock_irqsave(&crypto_q_lock, q_flags); \
  1453. + dprintk("%s,%d: Q_LOCK()\n", __FILE__, __LINE__); \
  1454. + })
  1455. +#define CRYPTO_Q_UNLOCK() \
  1456. + ({ \
  1457. + dprintk("%s,%d: Q_UNLOCK()\n", __FILE__, __LINE__); \
  1458. + spin_unlock_irqrestore(&crypto_q_lock, q_flags); \
  1459. + })
  1460. +
  1461. +/*
  1462. + * There are two queues for processing completed crypto requests; one
  1463. + * for the symmetric and one for the asymmetric ops. We only need one
  1464. + * but have two to avoid type futzing (cryptop vs. cryptkop). A single
  1465. + * mutex is used to lock access to both queues. Note that this lock
  1466. + * must be separate from the lock on request queues to insure driver
  1467. + * callbacks don't generate lock order reversals.
  1468. + */
  1469. +static LIST_HEAD(crp_ret_q); /* callback queues */
  1470. +static LIST_HEAD(crp_ret_kq);
  1471. +
  1472. +static spinlock_t crypto_ret_q_lock;
  1473. +#define CRYPTO_RETQ_LOCK() \
  1474. + ({ \
  1475. + spin_lock_irqsave(&crypto_ret_q_lock, r_flags); \
  1476. + dprintk("%s,%d: RETQ_LOCK\n", __FILE__, __LINE__); \
  1477. + })
  1478. +#define CRYPTO_RETQ_UNLOCK() \
  1479. + ({ \
  1480. + dprintk("%s,%d: RETQ_UNLOCK\n", __FILE__, __LINE__); \
  1481. + spin_unlock_irqrestore(&crypto_ret_q_lock, r_flags); \
  1482. + })
  1483. +#define CRYPTO_RETQ_EMPTY() (list_empty(&crp_ret_q) && list_empty(&crp_ret_kq))
  1484. +
  1485. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  1486. +static kmem_cache_t *cryptop_zone;
  1487. +static kmem_cache_t *cryptodesc_zone;
  1488. +#else
  1489. +static struct kmem_cache *cryptop_zone;
  1490. +static struct kmem_cache *cryptodesc_zone;
  1491. +#endif
  1492. +
  1493. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
  1494. +#include <linux/sched.h>
  1495. +#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
  1496. +#endif
  1497. +
  1498. +#define debug crypto_debug
  1499. +int crypto_debug = 0;
  1500. +module_param(crypto_debug, int, 0644);
  1501. +MODULE_PARM_DESC(crypto_debug, "Enable debug");
  1502. +EXPORT_SYMBOL(crypto_debug);
  1503. +
  1504. +/*
  1505. + * Maximum number of outstanding crypto requests before we start
  1506. + * failing requests. We need this to prevent DOS when too many
  1507. + * requests are arriving for us to keep up. Otherwise we will
  1508. + * run the system out of memory. Since crypto is slow, we are
  1509. + * usually the bottleneck that needs to say, enough is enough.
  1510. + *
  1511. + * We cannot print errors when this condition occurs, we are already too
  1512. + * slow, printing anything will just kill us
  1513. + */
  1514. +
  1515. +static int crypto_q_cnt = 0;
  1516. +module_param(crypto_q_cnt, int, 0444);
  1517. +MODULE_PARM_DESC(crypto_q_cnt,
  1518. + "Current number of outstanding crypto requests");
  1519. +
  1520. +static int crypto_q_max = 1000;
  1521. +module_param(crypto_q_max, int, 0644);
  1522. +MODULE_PARM_DESC(crypto_q_max,
  1523. + "Maximum number of outstanding crypto requests");
  1524. +
  1525. +#define bootverbose crypto_verbose
  1526. +static int crypto_verbose = 0;
  1527. +module_param(crypto_verbose, int, 0644);
  1528. +MODULE_PARM_DESC(crypto_verbose,
  1529. + "Enable verbose crypto startup");
  1530. +
  1531. +int crypto_usercrypto = 1; /* userland may do crypto reqs */
  1532. +module_param(crypto_usercrypto, int, 0644);
  1533. +MODULE_PARM_DESC(crypto_usercrypto,
  1534. + "Enable/disable user-mode access to crypto support");
  1535. +
  1536. +int crypto_userasymcrypto = 1; /* userland may do asym crypto reqs */
  1537. +module_param(crypto_userasymcrypto, int, 0644);
  1538. +MODULE_PARM_DESC(crypto_userasymcrypto,
  1539. + "Enable/disable user-mode access to asymmetric crypto support");
  1540. +
  1541. +int crypto_devallowsoft = 0; /* only use hardware crypto */
  1542. +module_param(crypto_devallowsoft, int, 0644);
  1543. +MODULE_PARM_DESC(crypto_devallowsoft,
  1544. + "Enable/disable use of software crypto support");
  1545. +
  1546. +/*
  1547. + * This parameter controls the maximum number of crypto operations to
  1548. + * do consecutively in the crypto kernel thread before scheduling to allow
  1549. + * other processes to run. Without it, it is possible to get into a
  1550. + * situation where the crypto thread never allows any other processes to run.
  1551. + * Default to 1000 which should be less than one second.
  1552. + */
  1553. +static int crypto_max_loopcount = 1000;
  1554. +module_param(crypto_max_loopcount, int, 0644);
  1555. +MODULE_PARM_DESC(crypto_max_loopcount,
  1556. + "Maximum number of crypto ops to do before yielding to other processes");
  1557. +
  1558. +static pid_t cryptoproc = (pid_t) -1;
  1559. +static struct completion cryptoproc_exited;
  1560. +static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait);
  1561. +static pid_t cryptoretproc = (pid_t) -1;
  1562. +static struct completion cryptoretproc_exited;
  1563. +static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait);
  1564. +
  1565. +static int crypto_proc(void *arg);
  1566. +static int crypto_ret_proc(void *arg);
  1567. +static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);
  1568. +static int crypto_kinvoke(struct cryptkop *krp, int flags);
  1569. +static void crypto_exit(void);
  1570. +static int crypto_init(void);
  1571. +
  1572. +static struct cryptostats cryptostats;
  1573. +
  1574. +static struct cryptocap *
  1575. +crypto_checkdriver(u_int32_t hid)
  1576. +{
  1577. + if (crypto_drivers == NULL)
  1578. + return NULL;
  1579. + return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]);
  1580. +}
  1581. +
  1582. +/*
  1583. + * Compare a driver's list of supported algorithms against another
  1584. + * list; return non-zero if all algorithms are supported.
  1585. + */
  1586. +static int
  1587. +driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri)
  1588. +{
  1589. + const struct cryptoini *cr;
  1590. +
  1591. + /* See if all the algorithms are supported. */
  1592. + for (cr = cri; cr; cr = cr->cri_next)
  1593. + if (cap->cc_alg[cr->cri_alg] == 0)
  1594. + return 0;
  1595. + return 1;
  1596. +}
  1597. +
  1598. +/*
  1599. + * Select a driver for a new session that supports the specified
  1600. + * algorithms and, optionally, is constrained according to the flags.
  1601. + * The algorithm we use here is pretty stupid; just use the
  1602. + * first driver that supports all the algorithms we need. If there
  1603. + * are multiple drivers we choose the driver with the fewest active
  1604. + * sessions. We prefer hardware-backed drivers to software ones.
  1605. + *
  1606. + * XXX We need more smarts here (in real life too, but that's
  1607. + * XXX another story altogether).
  1608. + */
  1609. +static struct cryptocap *
  1610. +crypto_select_driver(const struct cryptoini *cri, int flags)
  1611. +{
  1612. + struct cryptocap *cap, *best;
  1613. + int match, hid;
  1614. +
  1615. + CRYPTO_DRIVER_ASSERT();
  1616. +
  1617. + /*
  1618. + * Look first for hardware crypto devices if permitted.
  1619. + */
  1620. + if (flags & CRYPTOCAP_F_HARDWARE)
  1621. + match = CRYPTOCAP_F_HARDWARE;
  1622. + else
  1623. + match = CRYPTOCAP_F_SOFTWARE;
  1624. + best = NULL;
  1625. +again:
  1626. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  1627. + cap = &crypto_drivers[hid];
  1628. + /*
  1629. + * If it's not initialized, is in the process of
  1630. + * going away, or is not appropriate (hardware
  1631. + * or software based on match), then skip.
  1632. + */
  1633. + if (cap->cc_dev == NULL ||
  1634. + (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
  1635. + (cap->cc_flags & match) == 0)
  1636. + continue;
  1637. +
  1638. + /* verify all the algorithms are supported. */
  1639. + if (driver_suitable(cap, cri)) {
  1640. + if (best == NULL ||
  1641. + cap->cc_sessions < best->cc_sessions)
  1642. + best = cap;
  1643. + }
  1644. + }
  1645. + if (best != NULL)
  1646. + return best;
  1647. + if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
  1648. + /* sort of an Algol 68-style for loop */
  1649. + match = CRYPTOCAP_F_SOFTWARE;
  1650. + goto again;
  1651. + }
  1652. + return best;
  1653. +}
  1654. +
  1655. +/*
  1656. + * Create a new session. The crid argument specifies a crypto
  1657. + * driver to use or constraints on a driver to select (hardware
  1658. + * only, software only, either). Whatever driver is selected
  1659. + * must be capable of the requested crypto algorithms.
  1660. + */
  1661. +int
  1662. +crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid)
  1663. +{
  1664. + struct cryptocap *cap;
  1665. + u_int32_t hid, lid;
  1666. + int err;
  1667. + unsigned long d_flags;
  1668. +
  1669. + CRYPTO_DRIVER_LOCK();
  1670. + if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  1671. + /*
  1672. + * Use specified driver; verify it is capable.
  1673. + */
  1674. + cap = crypto_checkdriver(crid);
  1675. + if (cap != NULL && !driver_suitable(cap, cri))
  1676. + cap = NULL;
  1677. + } else {
  1678. + /*
  1679. + * No requested driver; select based on crid flags.
  1680. + */
  1681. + cap = crypto_select_driver(cri, crid);
  1682. + /*
  1683. + * if NULL then can't do everything in one session.
  1684. + * XXX Fix this. We need to inject a "virtual" session
  1685. + * XXX layer right about here.
  1686. + */
  1687. + }
  1688. + if (cap != NULL) {
  1689. + /* Call the driver initialization routine. */
  1690. + hid = cap - crypto_drivers;
  1691. + lid = hid; /* Pass the driver ID. */
  1692. + cap->cc_sessions++;
  1693. + CRYPTO_DRIVER_UNLOCK();
  1694. + err = CRYPTODEV_NEWSESSION(cap->cc_dev, &lid, cri);
  1695. + CRYPTO_DRIVER_LOCK();
  1696. + if (err == 0) {
  1697. + (*sid) = (cap->cc_flags & 0xff000000)
  1698. + | (hid & 0x00ffffff);
  1699. + (*sid) <<= 32;
  1700. + (*sid) |= (lid & 0xffffffff);
  1701. + } else
  1702. + cap->cc_sessions--;
  1703. + } else
  1704. + err = EINVAL;
  1705. + CRYPTO_DRIVER_UNLOCK();
  1706. + return err;
  1707. +}
  1708. +
  1709. +static void
  1710. +crypto_remove(struct cryptocap *cap)
  1711. +{
  1712. + CRYPTO_DRIVER_ASSERT();
  1713. + if (cap->cc_sessions == 0 && cap->cc_koperations == 0)
  1714. + bzero(cap, sizeof(*cap));
  1715. +}
  1716. +
  1717. +/*
  1718. + * Delete an existing session (or a reserved session on an unregistered
  1719. + * driver).
  1720. + */
  1721. +int
  1722. +crypto_freesession(u_int64_t sid)
  1723. +{
  1724. + struct cryptocap *cap;
  1725. + u_int32_t hid;
  1726. + int err = 0;
  1727. + unsigned long d_flags;
  1728. +
  1729. + dprintk("%s()\n", __FUNCTION__);
  1730. + CRYPTO_DRIVER_LOCK();
  1731. +
  1732. + if (crypto_drivers == NULL) {
  1733. + err = EINVAL;
  1734. + goto done;
  1735. + }
  1736. +
  1737. + /* Determine two IDs. */
  1738. + hid = CRYPTO_SESID2HID(sid);
  1739. +
  1740. + if (hid >= crypto_drivers_num) {
  1741. + dprintk("%s - INVALID DRIVER NUM %d\n", __FUNCTION__, hid);
  1742. + err = ENOENT;
  1743. + goto done;
  1744. + }
  1745. + cap = &crypto_drivers[hid];
  1746. +
  1747. + if (cap->cc_dev) {
  1748. + CRYPTO_DRIVER_UNLOCK();
  1749. + /* Call the driver cleanup routine, if available, unlocked. */
  1750. + err = CRYPTODEV_FREESESSION(cap->cc_dev, sid);
  1751. + CRYPTO_DRIVER_LOCK();
  1752. + }
  1753. +
  1754. + if (cap->cc_sessions)
  1755. + cap->cc_sessions--;
  1756. +
  1757. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
  1758. + crypto_remove(cap);
  1759. +
  1760. +done:
  1761. + CRYPTO_DRIVER_UNLOCK();
  1762. + return err;
  1763. +}
  1764. +
  1765. +/*
  1766. + * Return an unused driver id. Used by drivers prior to registering
  1767. + * support for the algorithms they handle.
  1768. + */
  1769. +int32_t
  1770. +crypto_get_driverid(device_t dev, int flags)
  1771. +{
  1772. + struct cryptocap *newdrv;
  1773. + int i;
  1774. + unsigned long d_flags;
  1775. +
  1776. + if ((flags & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  1777. + printf("%s: no flags specified when registering driver\n",
  1778. + device_get_nameunit(dev));
  1779. + return -1;
  1780. + }
  1781. +
  1782. + CRYPTO_DRIVER_LOCK();
  1783. +
  1784. + for (i = 0; i < crypto_drivers_num; i++) {
  1785. + if (crypto_drivers[i].cc_dev == NULL &&
  1786. + (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0) {
  1787. + break;
  1788. + }
  1789. + }
  1790. +
  1791. + /* Out of entries, allocate some more. */
  1792. + if (i == crypto_drivers_num) {
  1793. + /* Be careful about wrap-around. */
  1794. + if (2 * crypto_drivers_num <= crypto_drivers_num) {
  1795. + CRYPTO_DRIVER_UNLOCK();
  1796. + printk("crypto: driver count wraparound!\n");
  1797. + return -1;
  1798. + }
  1799. +
  1800. + newdrv = kmalloc(2 * crypto_drivers_num * sizeof(struct cryptocap),
  1801. + GFP_KERNEL);
  1802. + if (newdrv == NULL) {
  1803. + CRYPTO_DRIVER_UNLOCK();
  1804. + printk("crypto: no space to expand driver table!\n");
  1805. + return -1;
  1806. + }
  1807. +
  1808. + memcpy(newdrv, crypto_drivers,
  1809. + crypto_drivers_num * sizeof(struct cryptocap));
  1810. + memset(&newdrv[crypto_drivers_num], 0,
  1811. + crypto_drivers_num * sizeof(struct cryptocap));
  1812. +
  1813. + crypto_drivers_num *= 2;
  1814. +
  1815. + kfree(crypto_drivers);
  1816. + crypto_drivers = newdrv;
  1817. + }
  1818. +
  1819. + /* NB: state is zero'd on free */
  1820. + crypto_drivers[i].cc_sessions = 1; /* Mark */
  1821. + crypto_drivers[i].cc_dev = dev;
  1822. + crypto_drivers[i].cc_flags = flags;
  1823. + if (bootverbose)
  1824. + printf("crypto: assign %s driver id %u, flags %u\n",
  1825. + device_get_nameunit(dev), i, flags);
  1826. +
  1827. + CRYPTO_DRIVER_UNLOCK();
  1828. +
  1829. + return i;
  1830. +}
  1831. +
  1832. +/*
  1833. + * Lookup a driver by name. We match against the full device
  1834. + * name and unit, and against just the name. The latter gives
  1835. + * us a simple widlcarding by device name. On success return the
  1836. + * driver/hardware identifier; otherwise return -1.
  1837. + */
  1838. +int
  1839. +crypto_find_driver(const char *match)
  1840. +{
  1841. + int i, len = strlen(match);
  1842. + unsigned long d_flags;
  1843. +
  1844. + CRYPTO_DRIVER_LOCK();
  1845. + for (i = 0; i < crypto_drivers_num; i++) {
  1846. + device_t dev = crypto_drivers[i].cc_dev;
  1847. + if (dev == NULL ||
  1848. + (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP))
  1849. + continue;
  1850. + if (strncmp(match, device_get_nameunit(dev), len) == 0 ||
  1851. + strncmp(match, device_get_name(dev), len) == 0)
  1852. + break;
  1853. + }
  1854. + CRYPTO_DRIVER_UNLOCK();
  1855. + return i < crypto_drivers_num ? i : -1;
  1856. +}
  1857. +
  1858. +/*
  1859. + * Return the device_t for the specified driver or NULL
  1860. + * if the driver identifier is invalid.
  1861. + */
  1862. +device_t
  1863. +crypto_find_device_byhid(int hid)
  1864. +{
  1865. + struct cryptocap *cap = crypto_checkdriver(hid);
  1866. + return cap != NULL ? cap->cc_dev : NULL;
  1867. +}
  1868. +
  1869. +/*
  1870. + * Return the device/driver capabilities.
  1871. + */
  1872. +int
  1873. +crypto_getcaps(int hid)
  1874. +{
  1875. + struct cryptocap *cap = crypto_checkdriver(hid);
  1876. + return cap != NULL ? cap->cc_flags : 0;
  1877. +}
  1878. +
  1879. +/*
  1880. + * Register support for a key-related algorithm. This routine
  1881. + * is called once for each algorithm supported a driver.
  1882. + */
  1883. +int
  1884. +crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags)
  1885. +{
  1886. + struct cryptocap *cap;
  1887. + int err;
  1888. + unsigned long d_flags;
  1889. +
  1890. + dprintk("%s()\n", __FUNCTION__);
  1891. + CRYPTO_DRIVER_LOCK();
  1892. +
  1893. + cap = crypto_checkdriver(driverid);
  1894. + if (cap != NULL &&
  1895. + (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {
  1896. + /*
  1897. + * XXX Do some performance testing to determine placing.
  1898. + * XXX We probably need an auxiliary data structure that
  1899. + * XXX describes relative performances.
  1900. + */
  1901. +
  1902. + cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
  1903. + if (bootverbose)
  1904. + printf("crypto: %s registers key alg %u flags %u\n"
  1905. + , device_get_nameunit(cap->cc_dev)
  1906. + , kalg
  1907. + , flags
  1908. + );
  1909. + err = 0;
  1910. + } else
  1911. + err = EINVAL;
  1912. +
  1913. + CRYPTO_DRIVER_UNLOCK();
  1914. + return err;
  1915. +}
  1916. +
  1917. +/*
  1918. + * Register support for a non-key-related algorithm. This routine
  1919. + * is called once for each such algorithm supported by a driver.
  1920. + */
  1921. +int
  1922. +crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
  1923. + u_int32_t flags)
  1924. +{
  1925. + struct cryptocap *cap;
  1926. + int err;
  1927. + unsigned long d_flags;
  1928. +
  1929. + dprintk("%s(id=0x%x, alg=%d, maxoplen=%d, flags=0x%x)\n", __FUNCTION__,
  1930. + driverid, alg, maxoplen, flags);
  1931. +
  1932. + CRYPTO_DRIVER_LOCK();
  1933. +
  1934. + cap = crypto_checkdriver(driverid);
  1935. + /* NB: algorithms are in the range [1..max] */
  1936. + if (cap != NULL &&
  1937. + (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) {
  1938. + /*
  1939. + * XXX Do some performance testing to determine placing.
  1940. + * XXX We probably need an auxiliary data structure that
  1941. + * XXX describes relative performances.
  1942. + */
  1943. +
  1944. + cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
  1945. + cap->cc_max_op_len[alg] = maxoplen;
  1946. + if (bootverbose)
  1947. + printf("crypto: %s registers alg %u flags %u maxoplen %u\n"
  1948. + , device_get_nameunit(cap->cc_dev)
  1949. + , alg
  1950. + , flags
  1951. + , maxoplen
  1952. + );
  1953. + cap->cc_sessions = 0; /* Unmark */
  1954. + err = 0;
  1955. + } else
  1956. + err = EINVAL;
  1957. +
  1958. + CRYPTO_DRIVER_UNLOCK();
  1959. + return err;
  1960. +}
  1961. +
  1962. +static void
  1963. +driver_finis(struct cryptocap *cap)
  1964. +{
  1965. + u_int32_t ses, kops;
  1966. +
  1967. + CRYPTO_DRIVER_ASSERT();
  1968. +
  1969. + ses = cap->cc_sessions;
  1970. + kops = cap->cc_koperations;
  1971. + bzero(cap, sizeof(*cap));
  1972. + if (ses != 0 || kops != 0) {
  1973. + /*
  1974. + * If there are pending sessions,
  1975. + * just mark as invalid.
  1976. + */
  1977. + cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
  1978. + cap->cc_sessions = ses;
  1979. + cap->cc_koperations = kops;
  1980. + }
  1981. +}
  1982. +
  1983. +/*
  1984. + * Unregister a crypto driver. If there are pending sessions using it,
  1985. + * leave enough information around so that subsequent calls using those
  1986. + * sessions will correctly detect the driver has been unregistered and
  1987. + * reroute requests.
  1988. + */
  1989. +int
  1990. +crypto_unregister(u_int32_t driverid, int alg)
  1991. +{
  1992. + struct cryptocap *cap;
  1993. + int i, err;
  1994. + unsigned long d_flags;
  1995. +
  1996. + dprintk("%s()\n", __FUNCTION__);
  1997. + CRYPTO_DRIVER_LOCK();
  1998. +
  1999. + cap = crypto_checkdriver(driverid);
  2000. + if (cap != NULL &&
  2001. + (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) &&
  2002. + cap->cc_alg[alg] != 0) {
  2003. + cap->cc_alg[alg] = 0;
  2004. + cap->cc_max_op_len[alg] = 0;
  2005. +
  2006. + /* Was this the last algorithm ? */
  2007. + for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
  2008. + if (cap->cc_alg[i] != 0)
  2009. + break;
  2010. +
  2011. + if (i == CRYPTO_ALGORITHM_MAX + 1)
  2012. + driver_finis(cap);
  2013. + err = 0;
  2014. + } else
  2015. + err = EINVAL;
  2016. + CRYPTO_DRIVER_UNLOCK();
  2017. + return err;
  2018. +}
  2019. +
  2020. +/*
  2021. + * Unregister all algorithms associated with a crypto driver.
  2022. + * If there are pending sessions using it, leave enough information
  2023. + * around so that subsequent calls using those sessions will
  2024. + * correctly detect the driver has been unregistered and reroute
  2025. + * requests.
  2026. + */
  2027. +int
  2028. +crypto_unregister_all(u_int32_t driverid)
  2029. +{
  2030. + struct cryptocap *cap;
  2031. + int err;
  2032. + unsigned long d_flags;
  2033. +
  2034. + dprintk("%s()\n", __FUNCTION__);
  2035. + CRYPTO_DRIVER_LOCK();
  2036. + cap = crypto_checkdriver(driverid);
  2037. + if (cap != NULL) {
  2038. + driver_finis(cap);
  2039. + err = 0;
  2040. + } else
  2041. + err = EINVAL;
  2042. + CRYPTO_DRIVER_UNLOCK();
  2043. +
  2044. + return err;
  2045. +}
  2046. +
  2047. +/*
  2048. + * Clear blockage on a driver. The what parameter indicates whether
  2049. + * the driver is now ready for cryptop's and/or cryptokop's.
  2050. + */
  2051. +int
  2052. +crypto_unblock(u_int32_t driverid, int what)
  2053. +{
  2054. + struct cryptocap *cap;
  2055. + int err;
  2056. + unsigned long q_flags;
  2057. +
  2058. + CRYPTO_Q_LOCK();
  2059. + cap = crypto_checkdriver(driverid);
  2060. + if (cap != NULL) {
  2061. + if (what & CRYPTO_SYMQ) {
  2062. + cap->cc_qblocked = 0;
  2063. + cap->cc_unqblocked = 0;
  2064. + crypto_all_qblocked = 0;
  2065. + }
  2066. + if (what & CRYPTO_ASYMQ) {
  2067. + cap->cc_kqblocked = 0;
  2068. + cap->cc_unkqblocked = 0;
  2069. + crypto_all_kqblocked = 0;
  2070. + }
  2071. + if (crp_sleep)
  2072. + wake_up_interruptible(&cryptoproc_wait);
  2073. + err = 0;
  2074. + } else
  2075. + err = EINVAL;
  2076. + CRYPTO_Q_UNLOCK(); //DAVIDM should this be a driver lock
  2077. +
  2078. + return err;
  2079. +}
  2080. +
  2081. +/*
  2082. + * Add a crypto request to a queue, to be processed by the kernel thread.
  2083. + */
  2084. +int
  2085. +crypto_dispatch(struct cryptop *crp)
  2086. +{
  2087. + struct cryptocap *cap;
  2088. + int result = -1;
  2089. + unsigned long q_flags;
  2090. +
  2091. + dprintk("%s()\n", __FUNCTION__);
  2092. +
  2093. + cryptostats.cs_ops++;
  2094. +
  2095. + CRYPTO_Q_LOCK();
  2096. + if (crypto_q_cnt >= crypto_q_max) {
  2097. + CRYPTO_Q_UNLOCK();
  2098. + cryptostats.cs_drops++;
  2099. + return ENOMEM;
  2100. + }
  2101. + crypto_q_cnt++;
  2102. +
  2103. + /* make sure we are starting a fresh run on this crp. */
  2104. + crp->crp_flags &= ~CRYPTO_F_DONE;
  2105. + crp->crp_etype = 0;
  2106. +
  2107. + /*
  2108. + * Caller marked the request to be processed immediately; dispatch
  2109. + * it directly to the driver unless the driver is currently blocked.
  2110. + */
  2111. + if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
  2112. + int hid = CRYPTO_SESID2HID(crp->crp_sid);
  2113. + cap = crypto_checkdriver(hid);
  2114. + /* Driver cannot disappear when there is an active session. */
  2115. + KASSERT(cap != NULL, ("%s: Driver disappeared.", __func__));
  2116. + if (!cap->cc_qblocked) {
  2117. + crypto_all_qblocked = 0;
  2118. + crypto_drivers[hid].cc_unqblocked = 1;
  2119. + CRYPTO_Q_UNLOCK();
  2120. + result = crypto_invoke(cap, crp, 0);
  2121. + CRYPTO_Q_LOCK();
  2122. + if (result == ERESTART)
  2123. + if (crypto_drivers[hid].cc_unqblocked)
  2124. + crypto_drivers[hid].cc_qblocked = 1;
  2125. + crypto_drivers[hid].cc_unqblocked = 0;
  2126. + }
  2127. + }
  2128. + if (result == ERESTART) {
  2129. + /*
  2130. + * The driver ran out of resources, mark the
  2131. + * driver ``blocked'' for cryptop's and put
  2132. + * the request back in the queue. It would
  2133. + * best to put the request back where we got
  2134. + * it but that's hard so for now we put it
  2135. + * at the front. This should be ok; putting
  2136. + * it at the end does not work.
  2137. + */
  2138. + list_add(&crp->crp_next, &crp_q);
  2139. + cryptostats.cs_blocks++;
  2140. + result = 0;
  2141. + } else if (result == -1) {
  2142. + TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
  2143. + result = 0;
  2144. + }
  2145. + if (crp_sleep)
  2146. + wake_up_interruptible(&cryptoproc_wait);
  2147. + CRYPTO_Q_UNLOCK();
  2148. + return result;
  2149. +}
  2150. +
  2151. +/*
  2152. + * Add an asymetric crypto request to a queue,
  2153. + * to be processed by the kernel thread.
  2154. + */
  2155. +int
  2156. +crypto_kdispatch(struct cryptkop *krp)
  2157. +{
  2158. + int error;
  2159. + unsigned long q_flags;
  2160. +
  2161. + cryptostats.cs_kops++;
  2162. +
  2163. + error = crypto_kinvoke(krp, krp->krp_crid);
  2164. + if (error == ERESTART) {
  2165. + CRYPTO_Q_LOCK();
  2166. + TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
  2167. + if (crp_sleep)
  2168. + wake_up_interruptible(&cryptoproc_wait);
  2169. + CRYPTO_Q_UNLOCK();
  2170. + error = 0;
  2171. + }
  2172. + return error;
  2173. +}
  2174. +
  2175. +/*
  2176. + * Verify a driver is suitable for the specified operation.
  2177. + */
  2178. +static __inline int
  2179. +kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp)
  2180. +{
  2181. + return (cap->cc_kalg[krp->krp_op] & CRYPTO_ALG_FLAG_SUPPORTED) != 0;
  2182. +}
  2183. +
  2184. +/*
  2185. + * Select a driver for an asym operation. The driver must
  2186. + * support the necessary algorithm. The caller can constrain
  2187. + * which device is selected with the flags parameter. The
  2188. + * algorithm we use here is pretty stupid; just use the first
  2189. + * driver that supports the algorithms we need. If there are
  2190. + * multiple suitable drivers we choose the driver with the
  2191. + * fewest active operations. We prefer hardware-backed
  2192. + * drivers to software ones when either may be used.
  2193. + */
  2194. +static struct cryptocap *
  2195. +crypto_select_kdriver(const struct cryptkop *krp, int flags)
  2196. +{
  2197. + struct cryptocap *cap, *best, *blocked;
  2198. + int match, hid;
  2199. +
  2200. + CRYPTO_DRIVER_ASSERT();
  2201. +
  2202. + /*
  2203. + * Look first for hardware crypto devices if permitted.
  2204. + */
  2205. + if (flags & CRYPTOCAP_F_HARDWARE)
  2206. + match = CRYPTOCAP_F_HARDWARE;
  2207. + else
  2208. + match = CRYPTOCAP_F_SOFTWARE;
  2209. + best = NULL;
  2210. + blocked = NULL;
  2211. +again:
  2212. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  2213. + cap = &crypto_drivers[hid];
  2214. + /*
  2215. + * If it's not initialized, is in the process of
  2216. + * going away, or is not appropriate (hardware
  2217. + * or software based on match), then skip.
  2218. + */
  2219. + if (cap->cc_dev == NULL ||
  2220. + (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
  2221. + (cap->cc_flags & match) == 0)
  2222. + continue;
  2223. +
  2224. + /* verify all the algorithms are supported. */
  2225. + if (kdriver_suitable(cap, krp)) {
  2226. + if (best == NULL ||
  2227. + cap->cc_koperations < best->cc_koperations)
  2228. + best = cap;
  2229. + }
  2230. + }
  2231. + if (best != NULL)
  2232. + return best;
  2233. + if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
  2234. + /* sort of an Algol 68-style for loop */
  2235. + match = CRYPTOCAP_F_SOFTWARE;
  2236. + goto again;
  2237. + }
  2238. + return best;
  2239. +}
  2240. +
  2241. +/*
  2242. + * Dispatch an assymetric crypto request.
  2243. + */
  2244. +static int
  2245. +crypto_kinvoke(struct cryptkop *krp, int crid)
  2246. +{
  2247. + struct cryptocap *cap = NULL;
  2248. + int error;
  2249. + unsigned long d_flags;
  2250. +
  2251. + KASSERT(krp != NULL, ("%s: krp == NULL", __func__));
  2252. + KASSERT(krp->krp_callback != NULL,
  2253. + ("%s: krp->crp_callback == NULL", __func__));
  2254. +
  2255. + CRYPTO_DRIVER_LOCK();
  2256. + if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  2257. + cap = crypto_checkdriver(crid);
  2258. + if (cap != NULL) {
  2259. + /*
  2260. + * Driver present, it must support the necessary
  2261. + * algorithm and, if s/w drivers are excluded,
  2262. + * it must be registered as hardware-backed.
  2263. + */
  2264. + if (!kdriver_suitable(cap, krp) ||
  2265. + (!crypto_devallowsoft &&
  2266. + (cap->cc_flags & CRYPTOCAP_F_HARDWARE) == 0))
  2267. + cap = NULL;
  2268. + }
  2269. + } else {
  2270. + /*
  2271. + * No requested driver; select based on crid flags.
  2272. + */
  2273. + if (!crypto_devallowsoft) /* NB: disallow s/w drivers */
  2274. + crid &= ~CRYPTOCAP_F_SOFTWARE;
  2275. + cap = crypto_select_kdriver(krp, crid);
  2276. + }
  2277. + if (cap != NULL && !cap->cc_kqblocked) {
  2278. + krp->krp_hid = cap - crypto_drivers;
  2279. + cap->cc_koperations++;
  2280. + CRYPTO_DRIVER_UNLOCK();
  2281. + error = CRYPTODEV_KPROCESS(cap->cc_dev, krp, 0);
  2282. + CRYPTO_DRIVER_LOCK();
  2283. + if (error == ERESTART) {
  2284. + cap->cc_koperations--;
  2285. + CRYPTO_DRIVER_UNLOCK();
  2286. + return (error);
  2287. + }
  2288. + /* return the actual device used */
  2289. + krp->krp_crid = krp->krp_hid;
  2290. + } else {
  2291. + /*
  2292. + * NB: cap is !NULL if device is blocked; in
  2293. + * that case return ERESTART so the operation
  2294. + * is resubmitted if possible.
  2295. + */
  2296. + error = (cap == NULL) ? ENODEV : ERESTART;
  2297. + }
  2298. + CRYPTO_DRIVER_UNLOCK();
  2299. +
  2300. + if (error) {
  2301. + krp->krp_status = error;
  2302. + crypto_kdone(krp);
  2303. + }
  2304. + return 0;
  2305. +}
  2306. +
  2307. +
  2308. +/*
  2309. + * Dispatch a crypto request to the appropriate crypto devices.
  2310. + */
  2311. +static int
  2312. +crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint)
  2313. +{
  2314. + KASSERT(crp != NULL, ("%s: crp == NULL", __func__));
  2315. + KASSERT(crp->crp_callback != NULL,
  2316. + ("%s: crp->crp_callback == NULL", __func__));
  2317. + KASSERT(crp->crp_desc != NULL, ("%s: crp->crp_desc == NULL", __func__));
  2318. +
  2319. + dprintk("%s()\n", __FUNCTION__);
  2320. +
  2321. +#ifdef CRYPTO_TIMING
  2322. + if (crypto_timing)
  2323. + crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);
  2324. +#endif
  2325. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) {
  2326. + struct cryptodesc *crd;
  2327. + u_int64_t nid;
  2328. +
  2329. + /*
  2330. + * Driver has unregistered; migrate the session and return
  2331. + * an error to the caller so they'll resubmit the op.
  2332. + *
  2333. + * XXX: What if there are more already queued requests for this
  2334. + * session?
  2335. + */
  2336. + crypto_freesession(crp->crp_sid);
  2337. +
  2338. + for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
  2339. + crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
  2340. +
  2341. + /* XXX propagate flags from initial session? */
  2342. + if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI),
  2343. + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE) == 0)
  2344. + crp->crp_sid = nid;
  2345. +
  2346. + crp->crp_etype = EAGAIN;
  2347. + crypto_done(crp);
  2348. + return 0;
  2349. + } else {
  2350. + /*
  2351. + * Invoke the driver to process the request.
  2352. + */
  2353. + return CRYPTODEV_PROCESS(cap->cc_dev, crp, hint);
  2354. + }
  2355. +}
  2356. +
  2357. +/*
  2358. + * Release a set of crypto descriptors.
  2359. + */
  2360. +void
  2361. +crypto_freereq(struct cryptop *crp)
  2362. +{
  2363. + struct cryptodesc *crd;
  2364. +
  2365. + if (crp == NULL)
  2366. + return;
  2367. +
  2368. +#ifdef DIAGNOSTIC
  2369. + {
  2370. + struct cryptop *crp2;
  2371. + unsigned long q_flags;
  2372. +
  2373. + CRYPTO_Q_LOCK();
  2374. + TAILQ_FOREACH(crp2, &crp_q, crp_next) {
  2375. + KASSERT(crp2 != crp,
  2376. + ("Freeing cryptop from the crypto queue (%p).",
  2377. + crp));
  2378. + }
  2379. + CRYPTO_Q_UNLOCK();
  2380. + CRYPTO_RETQ_LOCK();
  2381. + TAILQ_FOREACH(crp2, &crp_ret_q, crp_next) {
  2382. + KASSERT(crp2 != crp,
  2383. + ("Freeing cryptop from the return queue (%p).",
  2384. + crp));
  2385. + }
  2386. + CRYPTO_RETQ_UNLOCK();
  2387. + }
  2388. +#endif
  2389. +
  2390. + while ((crd = crp->crp_desc) != NULL) {
  2391. + crp->crp_desc = crd->crd_next;
  2392. + kmem_cache_free(cryptodesc_zone, crd);
  2393. + }
  2394. + kmem_cache_free(cryptop_zone, crp);
  2395. +}
  2396. +
  2397. +/*
  2398. + * Acquire a set of crypto descriptors.
  2399. + */
  2400. +struct cryptop *
  2401. +crypto_getreq(int num)
  2402. +{
  2403. + struct cryptodesc *crd;
  2404. + struct cryptop *crp;
  2405. +
  2406. + crp = kmem_cache_alloc(cryptop_zone, SLAB_ATOMIC);
  2407. + if (crp != NULL) {
  2408. + memset(crp, 0, sizeof(*crp));
  2409. + INIT_LIST_HEAD(&crp->crp_next);
  2410. + init_waitqueue_head(&crp->crp_waitq);
  2411. + while (num--) {
  2412. + crd = kmem_cache_alloc(cryptodesc_zone, SLAB_ATOMIC);
  2413. + if (crd == NULL) {
  2414. + crypto_freereq(crp);
  2415. + return NULL;
  2416. + }
  2417. + memset(crd, 0, sizeof(*crd));
  2418. + crd->crd_next = crp->crp_desc;
  2419. + crp->crp_desc = crd;
  2420. + }
  2421. + }
  2422. + return crp;
  2423. +}
  2424. +
  2425. +/*
  2426. + * Invoke the callback on behalf of the driver.
  2427. + */
  2428. +void
  2429. +crypto_done(struct cryptop *crp)
  2430. +{
  2431. + unsigned long q_flags;
  2432. +
  2433. + dprintk("%s()\n", __FUNCTION__);
  2434. + if ((crp->crp_flags & CRYPTO_F_DONE) == 0) {
  2435. + crp->crp_flags |= CRYPTO_F_DONE;
  2436. + CRYPTO_Q_LOCK();
  2437. + crypto_q_cnt--;
  2438. + CRYPTO_Q_UNLOCK();
  2439. + } else
  2440. + printk("crypto: crypto_done op already done, flags 0x%x",
  2441. + crp->crp_flags);
  2442. + if (crp->crp_etype != 0)
  2443. + cryptostats.cs_errs++;
  2444. + /*
  2445. + * CBIMM means unconditionally do the callback immediately;
  2446. + * CBIFSYNC means do the callback immediately only if the
  2447. + * operation was done synchronously. Both are used to avoid
  2448. + * doing extraneous context switches; the latter is mostly
  2449. + * used with the software crypto driver.
  2450. + */
  2451. + if ((crp->crp_flags & CRYPTO_F_CBIMM) ||
  2452. + ((crp->crp_flags & CRYPTO_F_CBIFSYNC) &&
  2453. + (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC))) {
  2454. + /*
  2455. + * Do the callback directly. This is ok when the
  2456. + * callback routine does very little (e.g. the
  2457. + * /dev/crypto callback method just does a wakeup).
  2458. + */
  2459. + crp->crp_callback(crp);
  2460. + } else {
  2461. + unsigned long r_flags;
  2462. + /*
  2463. + * Normal case; queue the callback for the thread.
  2464. + */
  2465. + CRYPTO_RETQ_LOCK();
  2466. + if (CRYPTO_RETQ_EMPTY())
  2467. + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
  2468. + TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
  2469. + CRYPTO_RETQ_UNLOCK();
  2470. + }
  2471. +}
  2472. +
  2473. +/*
  2474. + * Invoke the callback on behalf of the driver.
  2475. + */
  2476. +void
  2477. +crypto_kdone(struct cryptkop *krp)
  2478. +{
  2479. + struct cryptocap *cap;
  2480. + unsigned long d_flags;
  2481. +
  2482. + if ((krp->krp_flags & CRYPTO_KF_DONE) != 0)
  2483. + printk("crypto: crypto_kdone op already done, flags 0x%x",
  2484. + krp->krp_flags);
  2485. + krp->krp_flags |= CRYPTO_KF_DONE;
  2486. + if (krp->krp_status != 0)
  2487. + cryptostats.cs_kerrs++;
  2488. +
  2489. + CRYPTO_DRIVER_LOCK();
  2490. + /* XXX: What if driver is loaded in the meantime? */
  2491. + if (krp->krp_hid < crypto_drivers_num) {
  2492. + cap = &crypto_drivers[krp->krp_hid];
  2493. + cap->cc_koperations--;
  2494. + KASSERT(cap->cc_koperations >= 0, ("cc_koperations < 0"));
  2495. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
  2496. + crypto_remove(cap);
  2497. + }
  2498. + CRYPTO_DRIVER_UNLOCK();
  2499. +
  2500. + /*
  2501. + * CBIMM means unconditionally do the callback immediately;
  2502. + * This is used to avoid doing extraneous context switches
  2503. + */
  2504. + if ((krp->krp_flags & CRYPTO_KF_CBIMM)) {
  2505. + /*
  2506. + * Do the callback directly. This is ok when the
  2507. + * callback routine does very little (e.g. the
  2508. + * /dev/crypto callback method just does a wakeup).
  2509. + */
  2510. + krp->krp_callback(krp);
  2511. + } else {
  2512. + unsigned long r_flags;
  2513. + /*
  2514. + * Normal case; queue the callback for the thread.
  2515. + */
  2516. + CRYPTO_RETQ_LOCK();
  2517. + if (CRYPTO_RETQ_EMPTY())
  2518. + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
  2519. + TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
  2520. + CRYPTO_RETQ_UNLOCK();
  2521. + }
  2522. +}
  2523. +
  2524. +int
  2525. +crypto_getfeat(int *featp)
  2526. +{
  2527. + int hid, kalg, feat = 0;
  2528. + unsigned long d_flags;
  2529. +
  2530. + CRYPTO_DRIVER_LOCK();
  2531. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  2532. + const struct cryptocap *cap = &crypto_drivers[hid];
  2533. +
  2534. + if ((cap->cc_flags & CRYPTOCAP_F_SOFTWARE) &&
  2535. + !crypto_devallowsoft) {
  2536. + continue;
  2537. + }
  2538. + for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
  2539. + if (cap->cc_kalg[kalg] & CRYPTO_ALG_FLAG_SUPPORTED)
  2540. + feat |= 1 << kalg;
  2541. + }
  2542. + CRYPTO_DRIVER_UNLOCK();
  2543. + *featp = feat;
  2544. + return (0);
  2545. +}
  2546. +
  2547. +/*
  2548. + * Crypto thread, dispatches crypto requests.
  2549. + */
  2550. +static int
  2551. +crypto_proc(void *arg)
  2552. +{
  2553. + struct cryptop *crp, *submit;
  2554. + struct cryptkop *krp, *krpp;
  2555. + struct cryptocap *cap;
  2556. + u_int32_t hid;
  2557. + int result, hint;
  2558. + unsigned long q_flags;
  2559. + int loopcount = 0;
  2560. +
  2561. + ocf_daemonize("crypto");
  2562. +
  2563. + CRYPTO_Q_LOCK();
  2564. + for (;;) {
  2565. + /*
  2566. + * we need to make sure we don't get into a busy loop with nothing
  2567. + * to do, the two crypto_all_*blocked vars help us find out when
  2568. + * we are all full and can do nothing on any driver or Q. If so we
  2569. + * wait for an unblock.
  2570. + */
  2571. + crypto_all_qblocked = !list_empty(&crp_q);
  2572. +
  2573. + /*
  2574. + * Find the first element in the queue that can be
  2575. + * processed and look-ahead to see if multiple ops
  2576. + * are ready for the same driver.
  2577. + */
  2578. + submit = NULL;
  2579. + hint = 0;
  2580. + list_for_each_entry(crp, &crp_q, crp_next) {
  2581. + hid = CRYPTO_SESID2HID(crp->crp_sid);
  2582. + cap = crypto_checkdriver(hid);
  2583. + /*
  2584. + * Driver cannot disappear when there is an active
  2585. + * session.
  2586. + */
  2587. + KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
  2588. + __func__, __LINE__));
  2589. + if (cap == NULL || cap->cc_dev == NULL) {
  2590. + /* Op needs to be migrated, process it. */
  2591. + if (submit == NULL)
  2592. + submit = crp;
  2593. + break;
  2594. + }
  2595. + if (!cap->cc_qblocked) {
  2596. + if (submit != NULL) {
  2597. + /*
  2598. + * We stop on finding another op,
  2599. + * regardless whether its for the same
  2600. + * driver or not. We could keep
  2601. + * searching the queue but it might be
  2602. + * better to just use a per-driver
  2603. + * queue instead.
  2604. + */
  2605. + if (CRYPTO_SESID2HID(submit->crp_sid) == hid)
  2606. + hint = CRYPTO_HINT_MORE;
  2607. + break;
  2608. + } else {
  2609. + submit = crp;
  2610. + if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)
  2611. + break;
  2612. + /* keep scanning for more are q'd */
  2613. + }
  2614. + }
  2615. + }
  2616. + if (submit != NULL) {
  2617. + hid = CRYPTO_SESID2HID(submit->crp_sid);
  2618. + crypto_all_qblocked = 0;
  2619. + list_del(&submit->crp_next);
  2620. + crypto_drivers[hid].cc_unqblocked = 1;
  2621. + cap = crypto_checkdriver(hid);
  2622. + CRYPTO_Q_UNLOCK();
  2623. + KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
  2624. + __func__, __LINE__));
  2625. + result = crypto_invoke(cap, submit, hint);
  2626. + CRYPTO_Q_LOCK();
  2627. + if (result == ERESTART) {
  2628. + /*
  2629. + * The driver ran out of resources, mark the
  2630. + * driver ``blocked'' for cryptop's and put
  2631. + * the request back in the queue. It would
  2632. + * best to put the request back where we got
  2633. + * it but that's hard so for now we put it
  2634. + * at the front. This should be ok; putting
  2635. + * it at the end does not work.
  2636. + */
  2637. + /* XXX validate sid again? */
  2638. + list_add(&submit->crp_next, &crp_q);
  2639. + cryptostats.cs_blocks++;
  2640. + if (crypto_drivers[hid].cc_unqblocked)
  2641. + crypto_drivers[hid].cc_qblocked=0;
  2642. + crypto_drivers[hid].cc_unqblocked=0;
  2643. + }
  2644. + crypto_drivers[hid].cc_unqblocked = 0;
  2645. + }
  2646. +
  2647. + crypto_all_kqblocked = !list_empty(&crp_kq);
  2648. +
  2649. + /* As above, but for key ops */
  2650. + krp = NULL;
  2651. + list_for_each_entry(krpp, &crp_kq, krp_next) {
  2652. + cap = crypto_checkdriver(krpp->krp_hid);
  2653. + if (cap == NULL || cap->cc_dev == NULL) {
  2654. + /*
  2655. + * Operation needs to be migrated, invalidate
  2656. + * the assigned device so it will reselect a
  2657. + * new one below. Propagate the original
  2658. + * crid selection flags if supplied.
  2659. + */
  2660. + krp->krp_hid = krp->krp_crid &
  2661. + (CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE);
  2662. + if (krp->krp_hid == 0)
  2663. + krp->krp_hid =
  2664. + CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE;
  2665. + break;
  2666. + }
  2667. + if (!cap->cc_kqblocked) {
  2668. + krp = krpp;
  2669. + break;
  2670. + }
  2671. + }
  2672. + if (krp != NULL) {
  2673. + crypto_all_kqblocked = 0;
  2674. + list_del(&krp->krp_next);
  2675. + crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
  2676. + CRYPTO_Q_UNLOCK();
  2677. + result = crypto_kinvoke(krp, krp->krp_hid);
  2678. + CRYPTO_Q_LOCK();
  2679. + if (result == ERESTART) {
  2680. + /*
  2681. + * The driver ran out of resources, mark the
  2682. + * driver ``blocked'' for cryptkop's and put
  2683. + * the request back in the queue. It would
  2684. + * best to put the request back where we got
  2685. + * it but that's hard so for now we put it
  2686. + * at the front. This should be ok; putting
  2687. + * it at the end does not work.
  2688. + */
  2689. + /* XXX validate sid again? */
  2690. + list_add(&krp->krp_next, &crp_kq);
  2691. + cryptostats.cs_kblocks++;
  2692. + } else
  2693. + crypto_drivers[krp->krp_hid].cc_kqblocked = 0;
  2694. + }
  2695. +
  2696. + if (submit == NULL && krp == NULL) {
  2697. + /*
  2698. + * Nothing more to be processed. Sleep until we're
  2699. + * woken because there are more ops to process.
  2700. + * This happens either by submission or by a driver
  2701. + * becoming unblocked and notifying us through
  2702. + * crypto_unblock. Note that when we wakeup we
  2703. + * start processing each queue again from the
  2704. + * front. It's not clear that it's important to
  2705. + * preserve this ordering since ops may finish
  2706. + * out of order if dispatched to different devices
  2707. + * and some become blocked while others do not.
  2708. + */
  2709. + dprintk("%s - sleeping (qe=%d qb=%d kqe=%d kqb=%d)\n",
  2710. + __FUNCTION__,
  2711. + list_empty(&crp_q), crypto_all_qblocked,
  2712. + list_empty(&crp_kq), crypto_all_kqblocked);
  2713. + loopcount = 0;
  2714. + CRYPTO_Q_UNLOCK();
  2715. + crp_sleep = 1;
  2716. + wait_event_interruptible(cryptoproc_wait,
  2717. + !(list_empty(&crp_q) || crypto_all_qblocked) ||
  2718. + !(list_empty(&crp_kq) || crypto_all_kqblocked) ||
  2719. + cryptoproc == (pid_t) -1);
  2720. + crp_sleep = 0;
  2721. + if (signal_pending (current)) {
  2722. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  2723. + spin_lock_irq(&current->sigmask_lock);
  2724. +#endif
  2725. + flush_signals(current);
  2726. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  2727. + spin_unlock_irq(&current->sigmask_lock);
  2728. +#endif
  2729. + }
  2730. + CRYPTO_Q_LOCK();
  2731. + dprintk("%s - awake\n", __FUNCTION__);
  2732. + if (cryptoproc == (pid_t) -1)
  2733. + break;
  2734. + cryptostats.cs_intrs++;
  2735. + } else if (loopcount > crypto_max_loopcount) {
  2736. + /*
  2737. + * Give other processes a chance to run if we've
  2738. + * been using the CPU exclusively for a while.
  2739. + */
  2740. + loopcount = 0;
  2741. + schedule();
  2742. + }
  2743. + loopcount++;
  2744. + }
  2745. + CRYPTO_Q_UNLOCK();
  2746. + complete_and_exit(&cryptoproc_exited, 0);
  2747. +}
  2748. +
  2749. +/*
  2750. + * Crypto returns thread, does callbacks for processed crypto requests.
  2751. + * Callbacks are done here, rather than in the crypto drivers, because
  2752. + * callbacks typically are expensive and would slow interrupt handling.
  2753. + */
  2754. +static int
  2755. +crypto_ret_proc(void *arg)
  2756. +{
  2757. + struct cryptop *crpt;
  2758. + struct cryptkop *krpt;
  2759. + unsigned long r_flags;
  2760. +
  2761. + ocf_daemonize("crypto_ret");
  2762. +
  2763. + CRYPTO_RETQ_LOCK();
  2764. + for (;;) {
  2765. + /* Harvest return q's for completed ops */
  2766. + crpt = NULL;
  2767. + if (!list_empty(&crp_ret_q))
  2768. + crpt = list_entry(crp_ret_q.next, typeof(*crpt), crp_next);
  2769. + if (crpt != NULL)
  2770. + list_del(&crpt->crp_next);
  2771. +
  2772. + krpt = NULL;
  2773. + if (!list_empty(&crp_ret_kq))
  2774. + krpt = list_entry(crp_ret_kq.next, typeof(*krpt), krp_next);
  2775. + if (krpt != NULL)
  2776. + list_del(&krpt->krp_next);
  2777. +
  2778. + if (crpt != NULL || krpt != NULL) {
  2779. + CRYPTO_RETQ_UNLOCK();
  2780. + /*
  2781. + * Run callbacks unlocked.
  2782. + */
  2783. + if (crpt != NULL)
  2784. + crpt->crp_callback(crpt);
  2785. + if (krpt != NULL)
  2786. + krpt->krp_callback(krpt);
  2787. + CRYPTO_RETQ_LOCK();
  2788. + } else {
  2789. + /*
  2790. + * Nothing more to be processed. Sleep until we're
  2791. + * woken because there are more returns to process.
  2792. + */
  2793. + dprintk("%s - sleeping\n", __FUNCTION__);
  2794. + CRYPTO_RETQ_UNLOCK();
  2795. + wait_event_interruptible(cryptoretproc_wait,
  2796. + cryptoretproc == (pid_t) -1 ||
  2797. + !list_empty(&crp_ret_q) ||
  2798. + !list_empty(&crp_ret_kq));
  2799. + if (signal_pending (current)) {
  2800. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  2801. + spin_lock_irq(&current->sigmask_lock);
  2802. +#endif
  2803. + flush_signals(current);
  2804. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  2805. + spin_unlock_irq(&current->sigmask_lock);
  2806. +#endif
  2807. + }
  2808. + CRYPTO_RETQ_LOCK();
  2809. + dprintk("%s - awake\n", __FUNCTION__);
  2810. + if (cryptoretproc == (pid_t) -1) {
  2811. + dprintk("%s - EXITING!\n", __FUNCTION__);
  2812. + break;
  2813. + }
  2814. + cryptostats.cs_rets++;
  2815. + }
  2816. + }
  2817. + CRYPTO_RETQ_UNLOCK();
  2818. + complete_and_exit(&cryptoretproc_exited, 0);
  2819. +}
  2820. +
  2821. +
  2822. +#if 0 /* should put this into /proc or something */
  2823. +static void
  2824. +db_show_drivers(void)
  2825. +{
  2826. + int hid;
  2827. +
  2828. + db_printf("%12s %4s %4s %8s %2s %2s\n"
  2829. + , "Device"
  2830. + , "Ses"
  2831. + , "Kops"
  2832. + , "Flags"
  2833. + , "QB"
  2834. + , "KB"
  2835. + );
  2836. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  2837. + const struct cryptocap *cap = &crypto_drivers[hid];
  2838. + if (cap->cc_dev == NULL)
  2839. + continue;
  2840. + db_printf("%-12s %4u %4u %08x %2u %2u\n"
  2841. + , device_get_nameunit(cap->cc_dev)
  2842. + , cap->cc_sessions
  2843. + , cap->cc_koperations
  2844. + , cap->cc_flags
  2845. + , cap->cc_qblocked
  2846. + , cap->cc_kqblocked
  2847. + );
  2848. + }
  2849. +}
  2850. +
  2851. +DB_SHOW_COMMAND(crypto, db_show_crypto)
  2852. +{
  2853. + struct cryptop *crp;
  2854. +
  2855. + db_show_drivers();
  2856. + db_printf("\n");
  2857. +
  2858. + db_printf("%4s %8s %4s %4s %4s %4s %8s %8s\n",
  2859. + "HID", "Caps", "Ilen", "Olen", "Etype", "Flags",
  2860. + "Desc", "Callback");
  2861. + TAILQ_FOREACH(crp, &crp_q, crp_next) {
  2862. + db_printf("%4u %08x %4u %4u %4u %04x %8p %8p\n"
  2863. + , (int) CRYPTO_SESID2HID(crp->crp_sid)
  2864. + , (int) CRYPTO_SESID2CAPS(crp->crp_sid)
  2865. + , crp->crp_ilen, crp->crp_olen
  2866. + , crp->crp_etype
  2867. + , crp->crp_flags
  2868. + , crp->crp_desc
  2869. + , crp->crp_callback
  2870. + );
  2871. + }
  2872. + if (!TAILQ_EMPTY(&crp_ret_q)) {
  2873. + db_printf("\n%4s %4s %4s %8s\n",
  2874. + "HID", "Etype", "Flags", "Callback");
  2875. + TAILQ_FOREACH(crp, &crp_ret_q, crp_next) {
  2876. + db_printf("%4u %4u %04x %8p\n"
  2877. + , (int) CRYPTO_SESID2HID(crp->crp_sid)
  2878. + , crp->crp_etype
  2879. + , crp->crp_flags
  2880. + , crp->crp_callback
  2881. + );
  2882. + }
  2883. + }
  2884. +}
  2885. +
  2886. +DB_SHOW_COMMAND(kcrypto, db_show_kcrypto)
  2887. +{
  2888. + struct cryptkop *krp;
  2889. +
  2890. + db_show_drivers();
  2891. + db_printf("\n");
  2892. +
  2893. + db_printf("%4s %5s %4s %4s %8s %4s %8s\n",
  2894. + "Op", "Status", "#IP", "#OP", "CRID", "HID", "Callback");
  2895. + TAILQ_FOREACH(krp, &crp_kq, krp_next) {
  2896. + db_printf("%4u %5u %4u %4u %08x %4u %8p\n"
  2897. + , krp->krp_op
  2898. + , krp->krp_status
  2899. + , krp->krp_iparams, krp->krp_oparams
  2900. + , krp->krp_crid, krp->krp_hid
  2901. + , krp->krp_callback
  2902. + );
  2903. + }
  2904. + if (!TAILQ_EMPTY(&crp_ret_q)) {
  2905. + db_printf("%4s %5s %8s %4s %8s\n",
  2906. + "Op", "Status", "CRID", "HID", "Callback");
  2907. + TAILQ_FOREACH(krp, &crp_ret_kq, krp_next) {
  2908. + db_printf("%4u %5u %08x %4u %8p\n"
  2909. + , krp->krp_op
  2910. + , krp->krp_status
  2911. + , krp->krp_crid, krp->krp_hid
  2912. + , krp->krp_callback
  2913. + );
  2914. + }
  2915. + }
  2916. +}
  2917. +#endif
  2918. +
  2919. +
  2920. +static int
  2921. +crypto_init(void)
  2922. +{
  2923. + int error;
  2924. +
  2925. + dprintk("%s(%p)\n", __FUNCTION__, (void *) crypto_init);
  2926. +
  2927. + if (crypto_initted)
  2928. + return 0;
  2929. + crypto_initted = 1;
  2930. +
  2931. + spin_lock_init(&crypto_drivers_lock);
  2932. + spin_lock_init(&crypto_q_lock);
  2933. + spin_lock_init(&crypto_ret_q_lock);
  2934. +
  2935. + cryptop_zone = kmem_cache_create("cryptop", sizeof(struct cryptop),
  2936. + 0, SLAB_HWCACHE_ALIGN, NULL
  2937. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  2938. + , NULL
  2939. +#endif
  2940. + );
  2941. +
  2942. + cryptodesc_zone = kmem_cache_create("cryptodesc", sizeof(struct cryptodesc),
  2943. + 0, SLAB_HWCACHE_ALIGN, NULL
  2944. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  2945. + , NULL
  2946. +#endif
  2947. + );
  2948. +
  2949. + if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
  2950. + printk("crypto: crypto_init cannot setup crypto zones\n");
  2951. + error = ENOMEM;
  2952. + goto bad;
  2953. + }
  2954. +
  2955. + crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
  2956. + crypto_drivers = kmalloc(crypto_drivers_num * sizeof(struct cryptocap),
  2957. + GFP_KERNEL);
  2958. + if (crypto_drivers == NULL) {
  2959. + printk("crypto: crypto_init cannot setup crypto drivers\n");
  2960. + error = ENOMEM;
  2961. + goto bad;
  2962. + }
  2963. +
  2964. + memset(crypto_drivers, 0, crypto_drivers_num * sizeof(struct cryptocap));
  2965. +
  2966. + init_completion(&cryptoproc_exited);
  2967. + init_completion(&cryptoretproc_exited);
  2968. +
  2969. + cryptoproc = 0; /* to avoid race condition where proc runs first */
  2970. + cryptoproc = kernel_thread(crypto_proc, NULL, CLONE_FS|CLONE_FILES);
  2971. + if (cryptoproc < 0) {
  2972. + error = cryptoproc;
  2973. + printk("crypto: crypto_init cannot start crypto thread; error %d",
  2974. + error);
  2975. + goto bad;
  2976. + }
  2977. +
  2978. + cryptoretproc = 0; /* to avoid race condition where proc runs first */
  2979. + cryptoretproc = kernel_thread(crypto_ret_proc, NULL, CLONE_FS|CLONE_FILES);
  2980. + if (cryptoretproc < 0) {
  2981. + error = cryptoretproc;
  2982. + printk("crypto: crypto_init cannot start cryptoret thread; error %d",
  2983. + error);
  2984. + goto bad;
  2985. + }
  2986. +
  2987. + return 0;
  2988. +bad:
  2989. + crypto_exit();
  2990. + return error;
  2991. +}
  2992. +
  2993. +
  2994. +static void
  2995. +crypto_exit(void)
  2996. +{
  2997. + pid_t p;
  2998. + unsigned long d_flags;
  2999. +
  3000. + dprintk("%s()\n", __FUNCTION__);
  3001. +
  3002. + /*
  3003. + * Terminate any crypto threads.
  3004. + */
  3005. +
  3006. + CRYPTO_DRIVER_LOCK();
  3007. + p = cryptoproc;
  3008. + cryptoproc = (pid_t) -1;
  3009. + kill_proc(p, SIGTERM, 1);
  3010. + wake_up_interruptible(&cryptoproc_wait);
  3011. + CRYPTO_DRIVER_UNLOCK();
  3012. +
  3013. + wait_for_completion(&cryptoproc_exited);
  3014. +
  3015. + CRYPTO_DRIVER_LOCK();
  3016. + p = cryptoretproc;
  3017. + cryptoretproc = (pid_t) -1;
  3018. + kill_proc(p, SIGTERM, 1);
  3019. + wake_up_interruptible(&cryptoretproc_wait);
  3020. + CRYPTO_DRIVER_UNLOCK();
  3021. +
  3022. + wait_for_completion(&cryptoretproc_exited);
  3023. +
  3024. + /* XXX flush queues??? */
  3025. +
  3026. + /*
  3027. + * Reclaim dynamically allocated resources.
  3028. + */
  3029. + if (crypto_drivers != NULL)
  3030. + kfree(crypto_drivers);
  3031. +
  3032. + if (cryptodesc_zone != NULL)
  3033. + kmem_cache_destroy(cryptodesc_zone);
  3034. + if (cryptop_zone != NULL)
  3035. + kmem_cache_destroy(cryptop_zone);
  3036. +}
  3037. +
  3038. +
  3039. +EXPORT_SYMBOL(crypto_newsession);
  3040. +EXPORT_SYMBOL(crypto_freesession);
  3041. +EXPORT_SYMBOL(crypto_get_driverid);
  3042. +EXPORT_SYMBOL(crypto_kregister);
  3043. +EXPORT_SYMBOL(crypto_register);
  3044. +EXPORT_SYMBOL(crypto_unregister);
  3045. +EXPORT_SYMBOL(crypto_unregister_all);
  3046. +EXPORT_SYMBOL(crypto_unblock);
  3047. +EXPORT_SYMBOL(crypto_dispatch);
  3048. +EXPORT_SYMBOL(crypto_kdispatch);
  3049. +EXPORT_SYMBOL(crypto_freereq);
  3050. +EXPORT_SYMBOL(crypto_getreq);
  3051. +EXPORT_SYMBOL(crypto_done);
  3052. +EXPORT_SYMBOL(crypto_kdone);
  3053. +EXPORT_SYMBOL(crypto_getfeat);
  3054. +EXPORT_SYMBOL(crypto_userasymcrypto);
  3055. +EXPORT_SYMBOL(crypto_getcaps);
  3056. +EXPORT_SYMBOL(crypto_find_driver);
  3057. +EXPORT_SYMBOL(crypto_find_device_byhid);
  3058. +
  3059. +module_init(crypto_init);
  3060. +module_exit(crypto_exit);
  3061. +
  3062. +MODULE_LICENSE("BSD");
  3063. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  3064. +MODULE_DESCRIPTION("OCF (OpenBSD Cryptographic Framework)");
  3065. diff -Nur linux-2.6.36.orig/crypto/ocf/cryptocteon/cavium_crypto.c linux-2.6.36/crypto/ocf/cryptocteon/cavium_crypto.c
  3066. --- linux-2.6.36.orig/crypto/ocf/cryptocteon/cavium_crypto.c 1970-01-01 01:00:00.000000000 +0100
  3067. +++ linux-2.6.36/crypto/ocf/cryptocteon/cavium_crypto.c 2010-11-09 20:28:04.311245450 +0100
  3068. @@ -0,0 +1,2283 @@
  3069. +/*
  3070. + * Copyright (c) 2009 David McCullough <david.mccullough@securecomputing.com>
  3071. + *
  3072. + * Copyright (c) 2003-2007 Cavium Networks (support@cavium.com). All rights
  3073. + * reserved.
  3074. + *
  3075. + * Redistribution and use in source and binary forms, with or without
  3076. + * modification, are permitted provided that the following conditions are met:
  3077. + * 1. Redistributions of source code must retain the above copyright notice,
  3078. + * this list of conditions and the following disclaimer.
  3079. + * 2. Redistributions in binary form must reproduce the above copyright notice,
  3080. + * this list of conditions and the following disclaimer in the documentation
  3081. + * and/or other materials provided with the distribution.
  3082. + * 3. All advertising materials mentioning features or use of this software
  3083. + * must display the following acknowledgement:
  3084. + * This product includes software developed by Cavium Networks
  3085. + * 4. Cavium Networks' name may not be used to endorse or promote products
  3086. + * derived from this software without specific prior written permission.
  3087. + *
  3088. + * This Software, including technical data, may be subject to U.S. export
  3089. + * control laws, including the U.S. Export Administration Act and its
  3090. + * associated regulations, and may be subject to export or import regulations
  3091. + * in other countries. You warrant that You will comply strictly in all
  3092. + * respects with all such regulations and acknowledge that you have the
  3093. + * responsibility to obtain licenses to export, re-export or import the
  3094. + * Software.
  3095. + *
  3096. + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" AND
  3097. + * WITH ALL FAULTS AND CAVIUM MAKES NO PROMISES, REPRESENTATIONS OR WARRANTIES,
  3098. + * EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE
  3099. + * SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
  3100. + * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
  3101. + * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
  3102. + * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
  3103. + * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
  3104. + * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
  3105. + * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
  3106. +*/
  3107. +/****************************************************************************/
  3108. +
  3109. +#include <linux/scatterlist.h>
  3110. +#include <asm/octeon/octeon.h>
  3111. +#include "octeon-asm.h"
  3112. +
  3113. +/****************************************************************************/
  3114. +
  3115. +extern unsigned long octeon_crypto_enable(struct octeon_cop2_state *);
  3116. +extern void octeon_crypto_disable(struct octeon_cop2_state *, unsigned long);
  3117. +
  3118. +#define SG_INIT(s, p, i, l) \
  3119. + { \
  3120. + (i) = 0; \
  3121. + (l) = (s)[0].length; \
  3122. + (p) = (typeof(p)) sg_virt((s)); \
  3123. + CVMX_PREFETCH0((p)); \
  3124. + }
  3125. +
  3126. +#define SG_CONSUME(s, p, i, l) \
  3127. + { \
  3128. + (p)++; \
  3129. + (l) -= sizeof(*(p)); \
  3130. + if ((l) < 0) { \
  3131. + dprintk("%s, %d: l = %d\n", __FILE__, __LINE__, l); \
  3132. + } else if ((l) == 0) { \
  3133. + (i)++; \
  3134. + (l) = (s)[0].length; \
  3135. + (p) = (typeof(p)) sg_virt(s); \
  3136. + CVMX_PREFETCH0((p)); \
  3137. + } \
  3138. + }
  3139. +
  3140. +#define ESP_HEADER_LENGTH 8
  3141. +#define DES_CBC_IV_LENGTH 8
  3142. +#define AES_CBC_IV_LENGTH 16
  3143. +#define ESP_HMAC_LEN 12
  3144. +
  3145. +#define ESP_HEADER_LENGTH 8
  3146. +#define DES_CBC_IV_LENGTH 8
  3147. +
  3148. +/****************************************************************************/
  3149. +
  3150. +#define CVM_LOAD_SHA_UNIT(dat, next) { \
  3151. + if (next == 0) { \
  3152. + next = 1; \
  3153. + CVMX_MT_HSH_DAT (dat, 0); \
  3154. + } else if (next == 1) { \
  3155. + next = 2; \
  3156. + CVMX_MT_HSH_DAT (dat, 1); \
  3157. + } else if (next == 2) { \
  3158. + next = 3; \
  3159. + CVMX_MT_HSH_DAT (dat, 2); \
  3160. + } else if (next == 3) { \
  3161. + next = 4; \
  3162. + CVMX_MT_HSH_DAT (dat, 3); \
  3163. + } else if (next == 4) { \
  3164. + next = 5; \
  3165. + CVMX_MT_HSH_DAT (dat, 4); \
  3166. + } else if (next == 5) { \
  3167. + next = 6; \
  3168. + CVMX_MT_HSH_DAT (dat, 5); \
  3169. + } else if (next == 6) { \
  3170. + next = 7; \
  3171. + CVMX_MT_HSH_DAT (dat, 6); \
  3172. + } else { \
  3173. + CVMX_MT_HSH_STARTSHA (dat); \
  3174. + next = 0; \
  3175. + } \
  3176. +}
  3177. +
  3178. +#define CVM_LOAD2_SHA_UNIT(dat1, dat2, next) { \
  3179. + if (next == 0) { \
  3180. + CVMX_MT_HSH_DAT (dat1, 0); \
  3181. + CVMX_MT_HSH_DAT (dat2, 1); \
  3182. + next = 2; \
  3183. + } else if (next == 1) { \
  3184. + CVMX_MT_HSH_DAT (dat1, 1); \
  3185. + CVMX_MT_HSH_DAT (dat2, 2); \
  3186. + next = 3; \
  3187. + } else if (next == 2) { \
  3188. + CVMX_MT_HSH_DAT (dat1, 2); \
  3189. + CVMX_MT_HSH_DAT (dat2, 3); \
  3190. + next = 4; \
  3191. + } else if (next == 3) { \
  3192. + CVMX_MT_HSH_DAT (dat1, 3); \
  3193. + CVMX_MT_HSH_DAT (dat2, 4); \
  3194. + next = 5; \
  3195. + } else if (next == 4) { \
  3196. + CVMX_MT_HSH_DAT (dat1, 4); \
  3197. + CVMX_MT_HSH_DAT (dat2, 5); \
  3198. + next = 6; \
  3199. + } else if (next == 5) { \
  3200. + CVMX_MT_HSH_DAT (dat1, 5); \
  3201. + CVMX_MT_HSH_DAT (dat2, 6); \
  3202. + next = 7; \
  3203. + } else if (next == 6) { \
  3204. + CVMX_MT_HSH_DAT (dat1, 6); \
  3205. + CVMX_MT_HSH_STARTSHA (dat2); \
  3206. + next = 0; \
  3207. + } else { \
  3208. + CVMX_MT_HSH_STARTSHA (dat1); \
  3209. + CVMX_MT_HSH_DAT (dat2, 0); \
  3210. + next = 1; \
  3211. + } \
  3212. +}
  3213. +
  3214. +/****************************************************************************/
  3215. +
  3216. +#define CVM_LOAD_MD5_UNIT(dat, next) { \
  3217. + if (next == 0) { \
  3218. + next = 1; \
  3219. + CVMX_MT_HSH_DAT (dat, 0); \
  3220. + } else if (next == 1) { \
  3221. + next = 2; \
  3222. + CVMX_MT_HSH_DAT (dat, 1); \
  3223. + } else if (next == 2) { \
  3224. + next = 3; \
  3225. + CVMX_MT_HSH_DAT (dat, 2); \
  3226. + } else if (next == 3) { \
  3227. + next = 4; \
  3228. + CVMX_MT_HSH_DAT (dat, 3); \
  3229. + } else if (next == 4) { \
  3230. + next = 5; \
  3231. + CVMX_MT_HSH_DAT (dat, 4); \
  3232. + } else if (next == 5) { \
  3233. + next = 6; \
  3234. + CVMX_MT_HSH_DAT (dat, 5); \
  3235. + } else if (next == 6) { \
  3236. + next = 7; \
  3237. + CVMX_MT_HSH_DAT (dat, 6); \
  3238. + } else { \
  3239. + CVMX_MT_HSH_STARTMD5 (dat); \
  3240. + next = 0; \
  3241. + } \
  3242. +}
  3243. +
  3244. +#define CVM_LOAD2_MD5_UNIT(dat1, dat2, next) { \
  3245. + if (next == 0) { \
  3246. + CVMX_MT_HSH_DAT (dat1, 0); \
  3247. + CVMX_MT_HSH_DAT (dat2, 1); \
  3248. + next = 2; \
  3249. + } else if (next == 1) { \
  3250. + CVMX_MT_HSH_DAT (dat1, 1); \
  3251. + CVMX_MT_HSH_DAT (dat2, 2); \
  3252. + next = 3; \
  3253. + } else if (next == 2) { \
  3254. + CVMX_MT_HSH_DAT (dat1, 2); \
  3255. + CVMX_MT_HSH_DAT (dat2, 3); \
  3256. + next = 4; \
  3257. + } else if (next == 3) { \
  3258. + CVMX_MT_HSH_DAT (dat1, 3); \
  3259. + CVMX_MT_HSH_DAT (dat2, 4); \
  3260. + next = 5; \
  3261. + } else if (next == 4) { \
  3262. + CVMX_MT_HSH_DAT (dat1, 4); \
  3263. + CVMX_MT_HSH_DAT (dat2, 5); \
  3264. + next = 6; \
  3265. + } else if (next == 5) { \
  3266. + CVMX_MT_HSH_DAT (dat1, 5); \
  3267. + CVMX_MT_HSH_DAT (dat2, 6); \
  3268. + next = 7; \
  3269. + } else if (next == 6) { \
  3270. + CVMX_MT_HSH_DAT (dat1, 6); \
  3271. + CVMX_MT_HSH_STARTMD5 (dat2); \
  3272. + next = 0; \
  3273. + } else { \
  3274. + CVMX_MT_HSH_STARTMD5 (dat1); \
  3275. + CVMX_MT_HSH_DAT (dat2, 0); \
  3276. + next = 1; \
  3277. + } \
  3278. +}
  3279. +
  3280. +/****************************************************************************/
  3281. +
  3282. +static inline uint64_t
  3283. +swap64(uint64_t a)
  3284. +{
  3285. + return ((a >> 56) |
  3286. + (((a >> 48) & 0xfful) << 8) |
  3287. + (((a >> 40) & 0xfful) << 16) |
  3288. + (((a >> 32) & 0xfful) << 24) |
  3289. + (((a >> 24) & 0xfful) << 32) |
  3290. + (((a >> 16) & 0xfful) << 40) |
  3291. + (((a >> 8) & 0xfful) << 48) | (((a >> 0) & 0xfful) << 56));
  3292. +}
  3293. +
  3294. +/****************************************************************************/
  3295. +
  3296. +void
  3297. +octo_calc_hash(__u8 auth, unsigned char *key, uint64_t *inner, uint64_t *outer)
  3298. +{
  3299. + uint8_t hash_key[64];
  3300. + uint64_t *key1;
  3301. + register uint64_t xor1 = 0x3636363636363636ULL;
  3302. + register uint64_t xor2 = 0x5c5c5c5c5c5c5c5cULL;
  3303. + struct octeon_cop2_state state;
  3304. + unsigned long flags;
  3305. +
  3306. + dprintk("%s()\n", __FUNCTION__);
  3307. +
  3308. + memset(hash_key, 0, sizeof(hash_key));
  3309. + memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));
  3310. + key1 = (uint64_t *) hash_key;
  3311. + flags = octeon_crypto_enable(&state);
  3312. + if (auth) {
  3313. + CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);
  3314. + CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);
  3315. + CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);
  3316. + } else {
  3317. + CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);
  3318. + CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);
  3319. + }
  3320. +
  3321. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 0);
  3322. + key1++;
  3323. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 1);
  3324. + key1++;
  3325. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 2);
  3326. + key1++;
  3327. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 3);
  3328. + key1++;
  3329. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 4);
  3330. + key1++;
  3331. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 5);
  3332. + key1++;
  3333. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 6);
  3334. + key1++;
  3335. + if (auth)
  3336. + CVMX_MT_HSH_STARTSHA((*key1 ^ xor1));
  3337. + else
  3338. + CVMX_MT_HSH_STARTMD5((*key1 ^ xor1));
  3339. +
  3340. + CVMX_MF_HSH_IV(inner[0], 0);
  3341. + CVMX_MF_HSH_IV(inner[1], 1);
  3342. + if (auth) {
  3343. + inner[2] = 0;
  3344. + CVMX_MF_HSH_IV(((uint64_t *) inner)[2], 2);
  3345. + }
  3346. +
  3347. + memset(hash_key, 0, sizeof(hash_key));
  3348. + memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));
  3349. + key1 = (uint64_t *) hash_key;
  3350. + if (auth) {
  3351. + CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);
  3352. + CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);
  3353. + CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);
  3354. + } else {
  3355. + CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);
  3356. + CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);
  3357. + }
  3358. +
  3359. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 0);
  3360. + key1++;
  3361. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 1);
  3362. + key1++;
  3363. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 2);
  3364. + key1++;
  3365. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 3);
  3366. + key1++;
  3367. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 4);
  3368. + key1++;
  3369. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 5);
  3370. + key1++;
  3371. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 6);
  3372. + key1++;
  3373. + if (auth)
  3374. + CVMX_MT_HSH_STARTSHA((*key1 ^ xor2));
  3375. + else
  3376. + CVMX_MT_HSH_STARTMD5((*key1 ^ xor2));
  3377. +
  3378. + CVMX_MF_HSH_IV(outer[0], 0);
  3379. + CVMX_MF_HSH_IV(outer[1], 1);
  3380. + if (auth) {
  3381. + outer[2] = 0;
  3382. + CVMX_MF_HSH_IV(outer[2], 2);
  3383. + }
  3384. + octeon_crypto_disable(&state, flags);
  3385. + return;
  3386. +}
  3387. +
  3388. +/****************************************************************************/
  3389. +/* DES functions */
  3390. +
  3391. +int
  3392. +octo_des_cbc_encrypt(
  3393. + struct octo_sess *od,
  3394. + struct scatterlist *sg, int sg_len,
  3395. + int auth_off, int auth_len,
  3396. + int crypt_off, int crypt_len,
  3397. + int icv_off, uint8_t *ivp)
  3398. +{
  3399. + uint64_t *data;
  3400. + int data_i, data_l;
  3401. + struct octeon_cop2_state state;
  3402. + unsigned long flags;
  3403. +
  3404. + dprintk("%s()\n", __FUNCTION__);
  3405. +
  3406. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  3407. + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
  3408. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  3409. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  3410. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  3411. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  3412. + return -EINVAL;
  3413. + }
  3414. +
  3415. + SG_INIT(sg, data, data_i, data_l);
  3416. +
  3417. + CVMX_PREFETCH0(ivp);
  3418. + CVMX_PREFETCH0(od->octo_enckey);
  3419. +
  3420. + flags = octeon_crypto_enable(&state);
  3421. +
  3422. + /* load 3DES Key */
  3423. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  3424. + if (od->octo_encklen == 24) {
  3425. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  3426. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  3427. + } else if (od->octo_encklen == 8) {
  3428. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  3429. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  3430. + } else {
  3431. + octeon_crypto_disable(&state, flags);
  3432. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  3433. + return -EINVAL;
  3434. + }
  3435. +
  3436. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  3437. +
  3438. + while (crypt_off > 0) {
  3439. + SG_CONSUME(sg, data, data_i, data_l);
  3440. + crypt_off -= 8;
  3441. + }
  3442. +
  3443. + while (crypt_len > 0) {
  3444. + CVMX_MT_3DES_ENC_CBC(*data);
  3445. + CVMX_MF_3DES_RESULT(*data);
  3446. + SG_CONSUME(sg, data, data_i, data_l);
  3447. + crypt_len -= 8;
  3448. + }
  3449. +
  3450. + octeon_crypto_disable(&state, flags);
  3451. + return 0;
  3452. +}
  3453. +
  3454. +
  3455. +int
  3456. +octo_des_cbc_decrypt(
  3457. + struct octo_sess *od,
  3458. + struct scatterlist *sg, int sg_len,
  3459. + int auth_off, int auth_len,
  3460. + int crypt_off, int crypt_len,
  3461. + int icv_off, uint8_t *ivp)
  3462. +{
  3463. + uint64_t *data;
  3464. + int data_i, data_l;
  3465. + struct octeon_cop2_state state;
  3466. + unsigned long flags;
  3467. +
  3468. + dprintk("%s()\n", __FUNCTION__);
  3469. +
  3470. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  3471. + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
  3472. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  3473. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  3474. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  3475. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  3476. + return -EINVAL;
  3477. + }
  3478. +
  3479. + SG_INIT(sg, data, data_i, data_l);
  3480. +
  3481. + CVMX_PREFETCH0(ivp);
  3482. + CVMX_PREFETCH0(od->octo_enckey);
  3483. +
  3484. + flags = octeon_crypto_enable(&state);
  3485. +
  3486. + /* load 3DES Key */
  3487. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  3488. + if (od->octo_encklen == 24) {
  3489. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  3490. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  3491. + } else if (od->octo_encklen == 8) {
  3492. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  3493. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  3494. + } else {
  3495. + octeon_crypto_disable(&state, flags);
  3496. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  3497. + return -EINVAL;
  3498. + }
  3499. +
  3500. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  3501. +
  3502. + while (crypt_off > 0) {
  3503. + SG_CONSUME(sg, data, data_i, data_l);
  3504. + crypt_off -= 8;
  3505. + }
  3506. +
  3507. + while (crypt_len > 0) {
  3508. + CVMX_MT_3DES_DEC_CBC(*data);
  3509. + CVMX_MF_3DES_RESULT(*data);
  3510. + SG_CONSUME(sg, data, data_i, data_l);
  3511. + crypt_len -= 8;
  3512. + }
  3513. +
  3514. + octeon_crypto_disable(&state, flags);
  3515. + return 0;
  3516. +}
  3517. +
  3518. +/****************************************************************************/
  3519. +/* AES functions */
  3520. +
  3521. +int
  3522. +octo_aes_cbc_encrypt(
  3523. + struct octo_sess *od,
  3524. + struct scatterlist *sg, int sg_len,
  3525. + int auth_off, int auth_len,
  3526. + int crypt_off, int crypt_len,
  3527. + int icv_off, uint8_t *ivp)
  3528. +{
  3529. + uint64_t *data, *pdata;
  3530. + int data_i, data_l;
  3531. + struct octeon_cop2_state state;
  3532. + unsigned long flags;
  3533. +
  3534. + dprintk("%s()\n", __FUNCTION__);
  3535. +
  3536. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  3537. + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
  3538. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  3539. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  3540. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  3541. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  3542. + return -EINVAL;
  3543. + }
  3544. +
  3545. + SG_INIT(sg, data, data_i, data_l);
  3546. +
  3547. + CVMX_PREFETCH0(ivp);
  3548. + CVMX_PREFETCH0(od->octo_enckey);
  3549. +
  3550. + flags = octeon_crypto_enable(&state);
  3551. +
  3552. + /* load AES Key */
  3553. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  3554. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  3555. +
  3556. + if (od->octo_encklen == 16) {
  3557. + CVMX_MT_AES_KEY(0x0, 2);
  3558. + CVMX_MT_AES_KEY(0x0, 3);
  3559. + } else if (od->octo_encklen == 24) {
  3560. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  3561. + CVMX_MT_AES_KEY(0x0, 3);
  3562. + } else if (od->octo_encklen == 32) {
  3563. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  3564. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  3565. + } else {
  3566. + octeon_crypto_disable(&state, flags);
  3567. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  3568. + return -EINVAL;
  3569. + }
  3570. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  3571. +
  3572. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  3573. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  3574. +
  3575. + while (crypt_off > 0) {
  3576. + SG_CONSUME(sg, data, data_i, data_l);
  3577. + crypt_off -= 8;
  3578. + }
  3579. +
  3580. + while (crypt_len > 0) {
  3581. + pdata = data;
  3582. + CVMX_MT_AES_ENC_CBC0(*data);
  3583. + SG_CONSUME(sg, data, data_i, data_l);
  3584. + CVMX_MT_AES_ENC_CBC1(*data);
  3585. + CVMX_MF_AES_RESULT(*pdata, 0);
  3586. + CVMX_MF_AES_RESULT(*data, 1);
  3587. + SG_CONSUME(sg, data, data_i, data_l);
  3588. + crypt_len -= 16;
  3589. + }
  3590. +
  3591. + octeon_crypto_disable(&state, flags);
  3592. + return 0;
  3593. +}
  3594. +
  3595. +
  3596. +int
  3597. +octo_aes_cbc_decrypt(
  3598. + struct octo_sess *od,
  3599. + struct scatterlist *sg, int sg_len,
  3600. + int auth_off, int auth_len,
  3601. + int crypt_off, int crypt_len,
  3602. + int icv_off, uint8_t *ivp)
  3603. +{
  3604. + uint64_t *data, *pdata;
  3605. + int data_i, data_l;
  3606. + struct octeon_cop2_state state;
  3607. + unsigned long flags;
  3608. +
  3609. + dprintk("%s()\n", __FUNCTION__);
  3610. +
  3611. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  3612. + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
  3613. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  3614. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  3615. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  3616. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  3617. + return -EINVAL;
  3618. + }
  3619. +
  3620. + SG_INIT(sg, data, data_i, data_l);
  3621. +
  3622. + CVMX_PREFETCH0(ivp);
  3623. + CVMX_PREFETCH0(od->octo_enckey);
  3624. +
  3625. + flags = octeon_crypto_enable(&state);
  3626. +
  3627. + /* load AES Key */
  3628. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  3629. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  3630. +
  3631. + if (od->octo_encklen == 16) {
  3632. + CVMX_MT_AES_KEY(0x0, 2);
  3633. + CVMX_MT_AES_KEY(0x0, 3);
  3634. + } else if (od->octo_encklen == 24) {
  3635. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  3636. + CVMX_MT_AES_KEY(0x0, 3);
  3637. + } else if (od->octo_encklen == 32) {
  3638. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  3639. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  3640. + } else {
  3641. + octeon_crypto_disable(&state, flags);
  3642. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  3643. + return -EINVAL;
  3644. + }
  3645. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  3646. +
  3647. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  3648. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  3649. +
  3650. + while (crypt_off > 0) {
  3651. + SG_CONSUME(sg, data, data_i, data_l);
  3652. + crypt_off -= 8;
  3653. + }
  3654. +
  3655. + while (crypt_len > 0) {
  3656. + pdata = data;
  3657. + CVMX_MT_AES_DEC_CBC0(*data);
  3658. + SG_CONSUME(sg, data, data_i, data_l);
  3659. + CVMX_MT_AES_DEC_CBC1(*data);
  3660. + CVMX_MF_AES_RESULT(*pdata, 0);
  3661. + CVMX_MF_AES_RESULT(*data, 1);
  3662. + SG_CONSUME(sg, data, data_i, data_l);
  3663. + crypt_len -= 16;
  3664. + }
  3665. +
  3666. + octeon_crypto_disable(&state, flags);
  3667. + return 0;
  3668. +}
  3669. +
  3670. +/****************************************************************************/
  3671. +/* MD5 */
  3672. +
  3673. +int
  3674. +octo_null_md5_encrypt(
  3675. + struct octo_sess *od,
  3676. + struct scatterlist *sg, int sg_len,
  3677. + int auth_off, int auth_len,
  3678. + int crypt_off, int crypt_len,
  3679. + int icv_off, uint8_t *ivp)
  3680. +{
  3681. + register int next = 0;
  3682. + uint64_t *data;
  3683. + uint64_t tmp1, tmp2;
  3684. + int data_i, data_l, alen = auth_len;
  3685. + struct octeon_cop2_state state;
  3686. + unsigned long flags;
  3687. +
  3688. + dprintk("%s()\n", __FUNCTION__);
  3689. +
  3690. + if (unlikely(od == NULL || sg==NULL || sg_len==0 ||
  3691. + (auth_off & 0x7) || (auth_off + auth_len > sg_len))) {
  3692. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  3693. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  3694. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  3695. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  3696. + return -EINVAL;
  3697. + }
  3698. +
  3699. + SG_INIT(sg, data, data_i, data_l);
  3700. +
  3701. + flags = octeon_crypto_enable(&state);
  3702. +
  3703. + /* Load MD5 IV */
  3704. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  3705. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  3706. +
  3707. + while (auth_off > 0) {
  3708. + SG_CONSUME(sg, data, data_i, data_l);
  3709. + auth_off -= 8;
  3710. + }
  3711. +
  3712. + while (auth_len > 0) {
  3713. + CVM_LOAD_MD5_UNIT(*data, next);
  3714. + auth_len -= 8;
  3715. + SG_CONSUME(sg, data, data_i, data_l);
  3716. + }
  3717. +
  3718. + /* finish the hash */
  3719. + CVMX_PREFETCH0(od->octo_hmouter);
  3720. +#if 0
  3721. + if (unlikely(inplen)) {
  3722. + uint64_t tmp = 0;
  3723. + uint8_t *p = (uint8_t *) & tmp;
  3724. + p[inplen] = 0x80;
  3725. + do {
  3726. + inplen--;
  3727. + p[inplen] = ((uint8_t *) data)[inplen];
  3728. + } while (inplen);
  3729. + CVM_LOAD_MD5_UNIT(tmp, next);
  3730. + } else {
  3731. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  3732. + }
  3733. +#else
  3734. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  3735. +#endif
  3736. +
  3737. + /* Finish Inner hash */
  3738. + while (next != 7) {
  3739. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  3740. + }
  3741. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  3742. + CVM_LOAD_MD5_UNIT(tmp1, next);
  3743. +
  3744. + /* Get the inner hash of HMAC */
  3745. + CVMX_MF_HSH_IV(tmp1, 0);
  3746. + CVMX_MF_HSH_IV(tmp2, 1);
  3747. +
  3748. + /* Initialize hash unit */
  3749. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  3750. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  3751. +
  3752. + CVMX_MT_HSH_DAT(tmp1, 0);
  3753. + CVMX_MT_HSH_DAT(tmp2, 1);
  3754. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  3755. + CVMX_MT_HSH_DATZ(3);
  3756. + CVMX_MT_HSH_DATZ(4);
  3757. + CVMX_MT_HSH_DATZ(5);
  3758. + CVMX_MT_HSH_DATZ(6);
  3759. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  3760. + CVMX_MT_HSH_STARTMD5(tmp1);
  3761. +
  3762. + /* save the HMAC */
  3763. + SG_INIT(sg, data, data_i, data_l);
  3764. + while (icv_off > 0) {
  3765. + SG_CONSUME(sg, data, data_i, data_l);
  3766. + icv_off -= 8;
  3767. + }
  3768. + CVMX_MF_HSH_IV(*data, 0);
  3769. + SG_CONSUME(sg, data, data_i, data_l);
  3770. + CVMX_MF_HSH_IV(tmp1, 1);
  3771. + *(uint32_t *)data = (uint32_t) (tmp1 >> 32);
  3772. +
  3773. + octeon_crypto_disable(&state, flags);
  3774. + return 0;
  3775. +}
  3776. +
  3777. +/****************************************************************************/
  3778. +/* SHA1 */
  3779. +
  3780. +int
  3781. +octo_null_sha1_encrypt(
  3782. + struct octo_sess *od,
  3783. + struct scatterlist *sg, int sg_len,
  3784. + int auth_off, int auth_len,
  3785. + int crypt_off, int crypt_len,
  3786. + int icv_off, uint8_t *ivp)
  3787. +{
  3788. + register int next = 0;
  3789. + uint64_t *data;
  3790. + uint64_t tmp1, tmp2, tmp3;
  3791. + int data_i, data_l, alen = auth_len;
  3792. + struct octeon_cop2_state state;
  3793. + unsigned long flags;
  3794. +
  3795. + dprintk("%s()\n", __FUNCTION__);
  3796. +
  3797. + if (unlikely(od == NULL || sg==NULL || sg_len==0 ||
  3798. + (auth_off & 0x7) || (auth_off + auth_len > sg_len))) {
  3799. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  3800. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  3801. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  3802. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  3803. + return -EINVAL;
  3804. + }
  3805. +
  3806. + SG_INIT(sg, data, data_i, data_l);
  3807. +
  3808. + flags = octeon_crypto_enable(&state);
  3809. +
  3810. + /* Load SHA1 IV */
  3811. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  3812. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  3813. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  3814. +
  3815. + while (auth_off > 0) {
  3816. + SG_CONSUME(sg, data, data_i, data_l);
  3817. + auth_off -= 8;
  3818. + }
  3819. +
  3820. + while (auth_len > 0) {
  3821. + CVM_LOAD_SHA_UNIT(*data, next);
  3822. + auth_len -= 8;
  3823. + SG_CONSUME(sg, data, data_i, data_l);
  3824. + }
  3825. +
  3826. + /* finish the hash */
  3827. + CVMX_PREFETCH0(od->octo_hmouter);
  3828. +#if 0
  3829. + if (unlikely(inplen)) {
  3830. + uint64_t tmp = 0;
  3831. + uint8_t *p = (uint8_t *) & tmp;
  3832. + p[inplen] = 0x80;
  3833. + do {
  3834. + inplen--;
  3835. + p[inplen] = ((uint8_t *) data)[inplen];
  3836. + } while (inplen);
  3837. + CVM_LOAD_MD5_UNIT(tmp, next);
  3838. + } else {
  3839. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  3840. + }
  3841. +#else
  3842. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  3843. +#endif
  3844. +
  3845. + /* Finish Inner hash */
  3846. + while (next != 7) {
  3847. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  3848. + }
  3849. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  3850. +
  3851. + /* Get the inner hash of HMAC */
  3852. + CVMX_MF_HSH_IV(tmp1, 0);
  3853. + CVMX_MF_HSH_IV(tmp2, 1);
  3854. + tmp3 = 0;
  3855. + CVMX_MF_HSH_IV(tmp3, 2);
  3856. +
  3857. + /* Initialize hash unit */
  3858. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  3859. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  3860. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  3861. +
  3862. + CVMX_MT_HSH_DAT(tmp1, 0);
  3863. + CVMX_MT_HSH_DAT(tmp2, 1);
  3864. + tmp3 |= 0x0000000080000000;
  3865. + CVMX_MT_HSH_DAT(tmp3, 2);
  3866. + CVMX_MT_HSH_DATZ(3);
  3867. + CVMX_MT_HSH_DATZ(4);
  3868. + CVMX_MT_HSH_DATZ(5);
  3869. + CVMX_MT_HSH_DATZ(6);
  3870. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  3871. +
  3872. + /* save the HMAC */
  3873. + SG_INIT(sg, data, data_i, data_l);
  3874. + while (icv_off > 0) {
  3875. + SG_CONSUME(sg, data, data_i, data_l);
  3876. + icv_off -= 8;
  3877. + }
  3878. + CVMX_MF_HSH_IV(*data, 0);
  3879. + SG_CONSUME(sg, data, data_i, data_l);
  3880. + CVMX_MF_HSH_IV(tmp1, 1);
  3881. + *(uint32_t *)data = (uint32_t) (tmp1 >> 32);
  3882. +
  3883. + octeon_crypto_disable(&state, flags);
  3884. + return 0;
  3885. +}
  3886. +
  3887. +/****************************************************************************/
  3888. +/* DES MD5 */
  3889. +
  3890. +int
  3891. +octo_des_cbc_md5_encrypt(
  3892. + struct octo_sess *od,
  3893. + struct scatterlist *sg, int sg_len,
  3894. + int auth_off, int auth_len,
  3895. + int crypt_off, int crypt_len,
  3896. + int icv_off, uint8_t *ivp)
  3897. +{
  3898. + register int next = 0;
  3899. + union {
  3900. + uint32_t data32[2];
  3901. + uint64_t data64[1];
  3902. + } mydata;
  3903. + uint64_t *data = &mydata.data64[0];
  3904. + uint32_t *data32;
  3905. + uint64_t tmp1, tmp2;
  3906. + int data_i, data_l, alen = auth_len;
  3907. + struct octeon_cop2_state state;
  3908. + unsigned long flags;
  3909. +
  3910. + dprintk("%s()\n", __FUNCTION__);
  3911. +
  3912. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  3913. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  3914. + (crypt_len & 0x7) ||
  3915. + (auth_len & 0x7) ||
  3916. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  3917. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  3918. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  3919. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  3920. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  3921. + return -EINVAL;
  3922. + }
  3923. +
  3924. + SG_INIT(sg, data32, data_i, data_l);
  3925. +
  3926. + CVMX_PREFETCH0(ivp);
  3927. + CVMX_PREFETCH0(od->octo_enckey);
  3928. +
  3929. + flags = octeon_crypto_enable(&state);
  3930. +
  3931. + /* load 3DES Key */
  3932. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  3933. + if (od->octo_encklen == 24) {
  3934. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  3935. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  3936. + } else if (od->octo_encklen == 8) {
  3937. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  3938. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  3939. + } else {
  3940. + octeon_crypto_disable(&state, flags);
  3941. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  3942. + return -EINVAL;
  3943. + }
  3944. +
  3945. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  3946. +
  3947. + /* Load MD5 IV */
  3948. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  3949. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  3950. +
  3951. + while (crypt_off > 0 && auth_off > 0) {
  3952. + SG_CONSUME(sg, data32, data_i, data_l);
  3953. + crypt_off -= 4;
  3954. + auth_off -= 4;
  3955. + }
  3956. +
  3957. + while (crypt_len > 0 || auth_len > 0) {
  3958. + uint32_t *first = data32;
  3959. + mydata.data32[0] = *first;
  3960. + SG_CONSUME(sg, data32, data_i, data_l);
  3961. + mydata.data32[1] = *data32;
  3962. + if (crypt_off <= 0) {
  3963. + if (crypt_len > 0) {
  3964. + CVMX_MT_3DES_ENC_CBC(*data);
  3965. + CVMX_MF_3DES_RESULT(*data);
  3966. + crypt_len -= 8;
  3967. + }
  3968. + } else
  3969. + crypt_off -= 8;
  3970. + if (auth_off <= 0) {
  3971. + if (auth_len > 0) {
  3972. + CVM_LOAD_MD5_UNIT(*data, next);
  3973. + auth_len -= 8;
  3974. + }
  3975. + } else
  3976. + auth_off -= 8;
  3977. + *first = mydata.data32[0];
  3978. + *data32 = mydata.data32[1];
  3979. + SG_CONSUME(sg, data32, data_i, data_l);
  3980. + }
  3981. +
  3982. + /* finish the hash */
  3983. + CVMX_PREFETCH0(od->octo_hmouter);
  3984. +#if 0
  3985. + if (unlikely(inplen)) {
  3986. + uint64_t tmp = 0;
  3987. + uint8_t *p = (uint8_t *) & tmp;
  3988. + p[inplen] = 0x80;
  3989. + do {
  3990. + inplen--;
  3991. + p[inplen] = ((uint8_t *) data)[inplen];
  3992. + } while (inplen);
  3993. + CVM_LOAD_MD5_UNIT(tmp, next);
  3994. + } else {
  3995. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  3996. + }
  3997. +#else
  3998. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  3999. +#endif
  4000. +
  4001. + /* Finish Inner hash */
  4002. + while (next != 7) {
  4003. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  4004. + }
  4005. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  4006. + CVM_LOAD_MD5_UNIT(tmp1, next);
  4007. +
  4008. + /* Get the inner hash of HMAC */
  4009. + CVMX_MF_HSH_IV(tmp1, 0);
  4010. + CVMX_MF_HSH_IV(tmp2, 1);
  4011. +
  4012. + /* Initialize hash unit */
  4013. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  4014. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  4015. +
  4016. + CVMX_MT_HSH_DAT(tmp1, 0);
  4017. + CVMX_MT_HSH_DAT(tmp2, 1);
  4018. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  4019. + CVMX_MT_HSH_DATZ(3);
  4020. + CVMX_MT_HSH_DATZ(4);
  4021. + CVMX_MT_HSH_DATZ(5);
  4022. + CVMX_MT_HSH_DATZ(6);
  4023. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  4024. + CVMX_MT_HSH_STARTMD5(tmp1);
  4025. +
  4026. + /* save the HMAC */
  4027. + SG_INIT(sg, data32, data_i, data_l);
  4028. + while (icv_off > 0) {
  4029. + SG_CONSUME(sg, data32, data_i, data_l);
  4030. + icv_off -= 4;
  4031. + }
  4032. + CVMX_MF_HSH_IV(tmp1, 0);
  4033. + *data32 = (uint32_t) (tmp1 >> 32);
  4034. + SG_CONSUME(sg, data32, data_i, data_l);
  4035. + *data32 = (uint32_t) tmp1;
  4036. + SG_CONSUME(sg, data32, data_i, data_l);
  4037. + CVMX_MF_HSH_IV(tmp1, 1);
  4038. + *data32 = (uint32_t) (tmp1 >> 32);
  4039. +
  4040. + octeon_crypto_disable(&state, flags);
  4041. + return 0;
  4042. +}
  4043. +
  4044. +int
  4045. +octo_des_cbc_md5_decrypt(
  4046. + struct octo_sess *od,
  4047. + struct scatterlist *sg, int sg_len,
  4048. + int auth_off, int auth_len,
  4049. + int crypt_off, int crypt_len,
  4050. + int icv_off, uint8_t *ivp)
  4051. +{
  4052. + register int next = 0;
  4053. + union {
  4054. + uint32_t data32[2];
  4055. + uint64_t data64[1];
  4056. + } mydata;
  4057. + uint64_t *data = &mydata.data64[0];
  4058. + uint32_t *data32;
  4059. + uint64_t tmp1, tmp2;
  4060. + int data_i, data_l, alen = auth_len;
  4061. + struct octeon_cop2_state state;
  4062. + unsigned long flags;
  4063. +
  4064. + dprintk("%s()\n", __FUNCTION__);
  4065. +
  4066. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4067. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  4068. + (crypt_len & 0x7) ||
  4069. + (auth_len & 0x7) ||
  4070. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  4071. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4072. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4073. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4074. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4075. + return -EINVAL;
  4076. + }
  4077. +
  4078. + SG_INIT(sg, data32, data_i, data_l);
  4079. +
  4080. + CVMX_PREFETCH0(ivp);
  4081. + CVMX_PREFETCH0(od->octo_enckey);
  4082. +
  4083. + flags = octeon_crypto_enable(&state);
  4084. +
  4085. + /* load 3DES Key */
  4086. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4087. + if (od->octo_encklen == 24) {
  4088. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4089. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4090. + } else if (od->octo_encklen == 8) {
  4091. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  4092. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  4093. + } else {
  4094. + octeon_crypto_disable(&state, flags);
  4095. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4096. + return -EINVAL;
  4097. + }
  4098. +
  4099. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  4100. +
  4101. + /* Load MD5 IV */
  4102. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  4103. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  4104. +
  4105. + while (crypt_off > 0 && auth_off > 0) {
  4106. + SG_CONSUME(sg, data32, data_i, data_l);
  4107. + crypt_off -= 4;
  4108. + auth_off -= 4;
  4109. + }
  4110. +
  4111. + while (crypt_len > 0 || auth_len > 0) {
  4112. + uint32_t *first = data32;
  4113. + mydata.data32[0] = *first;
  4114. + SG_CONSUME(sg, data32, data_i, data_l);
  4115. + mydata.data32[1] = *data32;
  4116. + if (auth_off <= 0) {
  4117. + if (auth_len > 0) {
  4118. + CVM_LOAD_MD5_UNIT(*data, next);
  4119. + auth_len -= 8;
  4120. + }
  4121. + } else
  4122. + auth_off -= 8;
  4123. + if (crypt_off <= 0) {
  4124. + if (crypt_len > 0) {
  4125. + CVMX_MT_3DES_DEC_CBC(*data);
  4126. + CVMX_MF_3DES_RESULT(*data);
  4127. + crypt_len -= 8;
  4128. + }
  4129. + } else
  4130. + crypt_off -= 8;
  4131. + *first = mydata.data32[0];
  4132. + *data32 = mydata.data32[1];
  4133. + SG_CONSUME(sg, data32, data_i, data_l);
  4134. + }
  4135. +
  4136. + /* finish the hash */
  4137. + CVMX_PREFETCH0(od->octo_hmouter);
  4138. +#if 0
  4139. + if (unlikely(inplen)) {
  4140. + uint64_t tmp = 0;
  4141. + uint8_t *p = (uint8_t *) & tmp;
  4142. + p[inplen] = 0x80;
  4143. + do {
  4144. + inplen--;
  4145. + p[inplen] = ((uint8_t *) data)[inplen];
  4146. + } while (inplen);
  4147. + CVM_LOAD_MD5_UNIT(tmp, next);
  4148. + } else {
  4149. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  4150. + }
  4151. +#else
  4152. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  4153. +#endif
  4154. +
  4155. + /* Finish Inner hash */
  4156. + while (next != 7) {
  4157. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  4158. + }
  4159. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  4160. + CVM_LOAD_MD5_UNIT(tmp1, next);
  4161. +
  4162. + /* Get the inner hash of HMAC */
  4163. + CVMX_MF_HSH_IV(tmp1, 0);
  4164. + CVMX_MF_HSH_IV(tmp2, 1);
  4165. +
  4166. + /* Initialize hash unit */
  4167. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  4168. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  4169. +
  4170. + CVMX_MT_HSH_DAT(tmp1, 0);
  4171. + CVMX_MT_HSH_DAT(tmp2, 1);
  4172. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  4173. + CVMX_MT_HSH_DATZ(3);
  4174. + CVMX_MT_HSH_DATZ(4);
  4175. + CVMX_MT_HSH_DATZ(5);
  4176. + CVMX_MT_HSH_DATZ(6);
  4177. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  4178. + CVMX_MT_HSH_STARTMD5(tmp1);
  4179. +
  4180. + /* save the HMAC */
  4181. + SG_INIT(sg, data32, data_i, data_l);
  4182. + while (icv_off > 0) {
  4183. + SG_CONSUME(sg, data32, data_i, data_l);
  4184. + icv_off -= 4;
  4185. + }
  4186. + CVMX_MF_HSH_IV(tmp1, 0);
  4187. + *data32 = (uint32_t) (tmp1 >> 32);
  4188. + SG_CONSUME(sg, data32, data_i, data_l);
  4189. + *data32 = (uint32_t) tmp1;
  4190. + SG_CONSUME(sg, data32, data_i, data_l);
  4191. + CVMX_MF_HSH_IV(tmp1, 1);
  4192. + *data32 = (uint32_t) (tmp1 >> 32);
  4193. +
  4194. + octeon_crypto_disable(&state, flags);
  4195. + return 0;
  4196. +}
  4197. +
  4198. +/****************************************************************************/
  4199. +/* DES SHA */
  4200. +
  4201. +int
  4202. +octo_des_cbc_sha1_encrypt(
  4203. + struct octo_sess *od,
  4204. + struct scatterlist *sg, int sg_len,
  4205. + int auth_off, int auth_len,
  4206. + int crypt_off, int crypt_len,
  4207. + int icv_off, uint8_t *ivp)
  4208. +{
  4209. + register int next = 0;
  4210. + union {
  4211. + uint32_t data32[2];
  4212. + uint64_t data64[1];
  4213. + } mydata;
  4214. + uint64_t *data = &mydata.data64[0];
  4215. + uint32_t *data32;
  4216. + uint64_t tmp1, tmp2, tmp3;
  4217. + int data_i, data_l, alen = auth_len;
  4218. + struct octeon_cop2_state state;
  4219. + unsigned long flags;
  4220. +
  4221. + dprintk("%s()\n", __FUNCTION__);
  4222. +
  4223. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4224. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  4225. + (crypt_len & 0x7) ||
  4226. + (auth_len & 0x7) ||
  4227. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  4228. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4229. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4230. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4231. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4232. + return -EINVAL;
  4233. + }
  4234. +
  4235. + SG_INIT(sg, data32, data_i, data_l);
  4236. +
  4237. + CVMX_PREFETCH0(ivp);
  4238. + CVMX_PREFETCH0(od->octo_enckey);
  4239. +
  4240. + flags = octeon_crypto_enable(&state);
  4241. +
  4242. + /* load 3DES Key */
  4243. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4244. + if (od->octo_encklen == 24) {
  4245. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4246. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4247. + } else if (od->octo_encklen == 8) {
  4248. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  4249. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  4250. + } else {
  4251. + octeon_crypto_disable(&state, flags);
  4252. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4253. + return -EINVAL;
  4254. + }
  4255. +
  4256. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  4257. +
  4258. + /* Load SHA1 IV */
  4259. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  4260. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  4261. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  4262. +
  4263. + while (crypt_off > 0 && auth_off > 0) {
  4264. + SG_CONSUME(sg, data32, data_i, data_l);
  4265. + crypt_off -= 4;
  4266. + auth_off -= 4;
  4267. + }
  4268. +
  4269. + while (crypt_len > 0 || auth_len > 0) {
  4270. + uint32_t *first = data32;
  4271. + mydata.data32[0] = *first;
  4272. + SG_CONSUME(sg, data32, data_i, data_l);
  4273. + mydata.data32[1] = *data32;
  4274. + if (crypt_off <= 0) {
  4275. + if (crypt_len > 0) {
  4276. + CVMX_MT_3DES_ENC_CBC(*data);
  4277. + CVMX_MF_3DES_RESULT(*data);
  4278. + crypt_len -= 8;
  4279. + }
  4280. + } else
  4281. + crypt_off -= 8;
  4282. + if (auth_off <= 0) {
  4283. + if (auth_len > 0) {
  4284. + CVM_LOAD_SHA_UNIT(*data, next);
  4285. + auth_len -= 8;
  4286. + }
  4287. + } else
  4288. + auth_off -= 8;
  4289. + *first = mydata.data32[0];
  4290. + *data32 = mydata.data32[1];
  4291. + SG_CONSUME(sg, data32, data_i, data_l);
  4292. + }
  4293. +
  4294. + /* finish the hash */
  4295. + CVMX_PREFETCH0(od->octo_hmouter);
  4296. +#if 0
  4297. + if (unlikely(inplen)) {
  4298. + uint64_t tmp = 0;
  4299. + uint8_t *p = (uint8_t *) & tmp;
  4300. + p[inplen] = 0x80;
  4301. + do {
  4302. + inplen--;
  4303. + p[inplen] = ((uint8_t *) data)[inplen];
  4304. + } while (inplen);
  4305. + CVM_LOAD_SHA_UNIT(tmp, next);
  4306. + } else {
  4307. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  4308. + }
  4309. +#else
  4310. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  4311. +#endif
  4312. +
  4313. + /* Finish Inner hash */
  4314. + while (next != 7) {
  4315. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  4316. + }
  4317. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  4318. +
  4319. + /* Get the inner hash of HMAC */
  4320. + CVMX_MF_HSH_IV(tmp1, 0);
  4321. + CVMX_MF_HSH_IV(tmp2, 1);
  4322. + tmp3 = 0;
  4323. + CVMX_MF_HSH_IV(tmp3, 2);
  4324. +
  4325. + /* Initialize hash unit */
  4326. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  4327. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  4328. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  4329. +
  4330. + CVMX_MT_HSH_DAT(tmp1, 0);
  4331. + CVMX_MT_HSH_DAT(tmp2, 1);
  4332. + tmp3 |= 0x0000000080000000;
  4333. + CVMX_MT_HSH_DAT(tmp3, 2);
  4334. + CVMX_MT_HSH_DATZ(3);
  4335. + CVMX_MT_HSH_DATZ(4);
  4336. + CVMX_MT_HSH_DATZ(5);
  4337. + CVMX_MT_HSH_DATZ(6);
  4338. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  4339. +
  4340. + /* save the HMAC */
  4341. + SG_INIT(sg, data32, data_i, data_l);
  4342. + while (icv_off > 0) {
  4343. + SG_CONSUME(sg, data32, data_i, data_l);
  4344. + icv_off -= 4;
  4345. + }
  4346. + CVMX_MF_HSH_IV(tmp1, 0);
  4347. + *data32 = (uint32_t) (tmp1 >> 32);
  4348. + SG_CONSUME(sg, data32, data_i, data_l);
  4349. + *data32 = (uint32_t) tmp1;
  4350. + SG_CONSUME(sg, data32, data_i, data_l);
  4351. + CVMX_MF_HSH_IV(tmp1, 1);
  4352. + *data32 = (uint32_t) (tmp1 >> 32);
  4353. +
  4354. + octeon_crypto_disable(&state, flags);
  4355. + return 0;
  4356. +}
  4357. +
  4358. +int
  4359. +octo_des_cbc_sha1_decrypt(
  4360. + struct octo_sess *od,
  4361. + struct scatterlist *sg, int sg_len,
  4362. + int auth_off, int auth_len,
  4363. + int crypt_off, int crypt_len,
  4364. + int icv_off, uint8_t *ivp)
  4365. +{
  4366. + register int next = 0;
  4367. + union {
  4368. + uint32_t data32[2];
  4369. + uint64_t data64[1];
  4370. + } mydata;
  4371. + uint64_t *data = &mydata.data64[0];
  4372. + uint32_t *data32;
  4373. + uint64_t tmp1, tmp2, tmp3;
  4374. + int data_i, data_l, alen = auth_len;
  4375. + struct octeon_cop2_state state;
  4376. + unsigned long flags;
  4377. +
  4378. + dprintk("%s()\n", __FUNCTION__);
  4379. +
  4380. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4381. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  4382. + (crypt_len & 0x7) ||
  4383. + (auth_len & 0x7) ||
  4384. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  4385. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4386. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4387. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4388. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4389. + return -EINVAL;
  4390. + }
  4391. +
  4392. + SG_INIT(sg, data32, data_i, data_l);
  4393. +
  4394. + CVMX_PREFETCH0(ivp);
  4395. + CVMX_PREFETCH0(od->octo_enckey);
  4396. +
  4397. + flags = octeon_crypto_enable(&state);
  4398. +
  4399. + /* load 3DES Key */
  4400. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4401. + if (od->octo_encklen == 24) {
  4402. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4403. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4404. + } else if (od->octo_encklen == 8) {
  4405. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  4406. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  4407. + } else {
  4408. + octeon_crypto_disable(&state, flags);
  4409. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4410. + return -EINVAL;
  4411. + }
  4412. +
  4413. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  4414. +
  4415. + /* Load SHA1 IV */
  4416. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  4417. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  4418. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  4419. +
  4420. + while (crypt_off > 0 && auth_off > 0) {
  4421. + SG_CONSUME(sg, data32, data_i, data_l);
  4422. + crypt_off -= 4;
  4423. + auth_off -= 4;
  4424. + }
  4425. +
  4426. + while (crypt_len > 0 || auth_len > 0) {
  4427. + uint32_t *first = data32;
  4428. + mydata.data32[0] = *first;
  4429. + SG_CONSUME(sg, data32, data_i, data_l);
  4430. + mydata.data32[1] = *data32;
  4431. + if (auth_off <= 0) {
  4432. + if (auth_len > 0) {
  4433. + CVM_LOAD_SHA_UNIT(*data, next);
  4434. + auth_len -= 8;
  4435. + }
  4436. + } else
  4437. + auth_off -= 8;
  4438. + if (crypt_off <= 0) {
  4439. + if (crypt_len > 0) {
  4440. + CVMX_MT_3DES_DEC_CBC(*data);
  4441. + CVMX_MF_3DES_RESULT(*data);
  4442. + crypt_len -= 8;
  4443. + }
  4444. + } else
  4445. + crypt_off -= 8;
  4446. + *first = mydata.data32[0];
  4447. + *data32 = mydata.data32[1];
  4448. + SG_CONSUME(sg, data32, data_i, data_l);
  4449. + }
  4450. +
  4451. + /* finish the hash */
  4452. + CVMX_PREFETCH0(od->octo_hmouter);
  4453. +#if 0
  4454. + if (unlikely(inplen)) {
  4455. + uint64_t tmp = 0;
  4456. + uint8_t *p = (uint8_t *) & tmp;
  4457. + p[inplen] = 0x80;
  4458. + do {
  4459. + inplen--;
  4460. + p[inplen] = ((uint8_t *) data)[inplen];
  4461. + } while (inplen);
  4462. + CVM_LOAD_SHA_UNIT(tmp, next);
  4463. + } else {
  4464. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  4465. + }
  4466. +#else
  4467. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  4468. +#endif
  4469. +
  4470. + /* Finish Inner hash */
  4471. + while (next != 7) {
  4472. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  4473. + }
  4474. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  4475. +
  4476. + /* Get the inner hash of HMAC */
  4477. + CVMX_MF_HSH_IV(tmp1, 0);
  4478. + CVMX_MF_HSH_IV(tmp2, 1);
  4479. + tmp3 = 0;
  4480. + CVMX_MF_HSH_IV(tmp3, 2);
  4481. +
  4482. + /* Initialize hash unit */
  4483. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  4484. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  4485. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  4486. +
  4487. + CVMX_MT_HSH_DAT(tmp1, 0);
  4488. + CVMX_MT_HSH_DAT(tmp2, 1);
  4489. + tmp3 |= 0x0000000080000000;
  4490. + CVMX_MT_HSH_DAT(tmp3, 2);
  4491. + CVMX_MT_HSH_DATZ(3);
  4492. + CVMX_MT_HSH_DATZ(4);
  4493. + CVMX_MT_HSH_DATZ(5);
  4494. + CVMX_MT_HSH_DATZ(6);
  4495. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  4496. + /* save the HMAC */
  4497. + SG_INIT(sg, data32, data_i, data_l);
  4498. + while (icv_off > 0) {
  4499. + SG_CONSUME(sg, data32, data_i, data_l);
  4500. + icv_off -= 4;
  4501. + }
  4502. + CVMX_MF_HSH_IV(tmp1, 0);
  4503. + *data32 = (uint32_t) (tmp1 >> 32);
  4504. + SG_CONSUME(sg, data32, data_i, data_l);
  4505. + *data32 = (uint32_t) tmp1;
  4506. + SG_CONSUME(sg, data32, data_i, data_l);
  4507. + CVMX_MF_HSH_IV(tmp1, 1);
  4508. + *data32 = (uint32_t) (tmp1 >> 32);
  4509. +
  4510. + octeon_crypto_disable(&state, flags);
  4511. + return 0;
  4512. +}
  4513. +
  4514. +/****************************************************************************/
  4515. +/* AES MD5 */
  4516. +
  4517. +int
  4518. +octo_aes_cbc_md5_encrypt(
  4519. + struct octo_sess *od,
  4520. + struct scatterlist *sg, int sg_len,
  4521. + int auth_off, int auth_len,
  4522. + int crypt_off, int crypt_len,
  4523. + int icv_off, uint8_t *ivp)
  4524. +{
  4525. + register int next = 0;
  4526. + union {
  4527. + uint32_t data32[2];
  4528. + uint64_t data64[1];
  4529. + } mydata[2];
  4530. + uint64_t *pdata = &mydata[0].data64[0];
  4531. + uint64_t *data = &mydata[1].data64[0];
  4532. + uint32_t *data32;
  4533. + uint64_t tmp1, tmp2;
  4534. + int data_i, data_l, alen = auth_len;
  4535. + struct octeon_cop2_state state;
  4536. + unsigned long flags;
  4537. +
  4538. + dprintk("%s()\n", __FUNCTION__);
  4539. +
  4540. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4541. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  4542. + (crypt_len & 0x7) ||
  4543. + (auth_len & 0x7) ||
  4544. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  4545. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4546. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4547. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4548. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4549. + return -EINVAL;
  4550. + }
  4551. +
  4552. + SG_INIT(sg, data32, data_i, data_l);
  4553. +
  4554. + CVMX_PREFETCH0(ivp);
  4555. + CVMX_PREFETCH0(od->octo_enckey);
  4556. +
  4557. + flags = octeon_crypto_enable(&state);
  4558. +
  4559. + /* load AES Key */
  4560. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4561. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4562. +
  4563. + if (od->octo_encklen == 16) {
  4564. + CVMX_MT_AES_KEY(0x0, 2);
  4565. + CVMX_MT_AES_KEY(0x0, 3);
  4566. + } else if (od->octo_encklen == 24) {
  4567. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4568. + CVMX_MT_AES_KEY(0x0, 3);
  4569. + } else if (od->octo_encklen == 32) {
  4570. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4571. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  4572. + } else {
  4573. + octeon_crypto_disable(&state, flags);
  4574. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4575. + return -EINVAL;
  4576. + }
  4577. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  4578. +
  4579. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  4580. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  4581. +
  4582. + /* Load MD5 IV */
  4583. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  4584. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  4585. +
  4586. + while (crypt_off > 0 && auth_off > 0) {
  4587. + SG_CONSUME(sg, data32, data_i, data_l);
  4588. + crypt_off -= 4;
  4589. + auth_off -= 4;
  4590. + }
  4591. +
  4592. + /* align auth and crypt */
  4593. + while (crypt_off > 0 && auth_len > 0) {
  4594. + mydata[0].data32[0] = *data32;
  4595. + SG_CONSUME(sg, data32, data_i, data_l);
  4596. + mydata[0].data32[1] = *data32;
  4597. + SG_CONSUME(sg, data32, data_i, data_l);
  4598. + CVM_LOAD_MD5_UNIT(*pdata, next);
  4599. + crypt_off -= 8;
  4600. + auth_len -= 8;
  4601. + }
  4602. +
  4603. + while (crypt_len > 0) {
  4604. + uint32_t *pdata32[3];
  4605. +
  4606. + pdata32[0] = data32;
  4607. + mydata[0].data32[0] = *data32;
  4608. + SG_CONSUME(sg, data32, data_i, data_l);
  4609. +
  4610. + pdata32[1] = data32;
  4611. + mydata[0].data32[1] = *data32;
  4612. + SG_CONSUME(sg, data32, data_i, data_l);
  4613. +
  4614. + pdata32[2] = data32;
  4615. + mydata[1].data32[0] = *data32;
  4616. + SG_CONSUME(sg, data32, data_i, data_l);
  4617. +
  4618. + mydata[1].data32[1] = *data32;
  4619. +
  4620. + CVMX_MT_AES_ENC_CBC0(*pdata);
  4621. + CVMX_MT_AES_ENC_CBC1(*data);
  4622. + CVMX_MF_AES_RESULT(*pdata, 0);
  4623. + CVMX_MF_AES_RESULT(*data, 1);
  4624. + crypt_len -= 16;
  4625. +
  4626. + if (auth_len > 0) {
  4627. + CVM_LOAD_MD5_UNIT(*pdata, next);
  4628. + auth_len -= 8;
  4629. + }
  4630. + if (auth_len > 0) {
  4631. + CVM_LOAD_MD5_UNIT(*data, next);
  4632. + auth_len -= 8;
  4633. + }
  4634. +
  4635. + *pdata32[0] = mydata[0].data32[0];
  4636. + *pdata32[1] = mydata[0].data32[1];
  4637. + *pdata32[2] = mydata[1].data32[0];
  4638. + *data32 = mydata[1].data32[1];
  4639. +
  4640. + SG_CONSUME(sg, data32, data_i, data_l);
  4641. + }
  4642. +
  4643. + /* finish any left over hashing */
  4644. + while (auth_len > 0) {
  4645. + mydata[0].data32[0] = *data32;
  4646. + SG_CONSUME(sg, data32, data_i, data_l);
  4647. + mydata[0].data32[1] = *data32;
  4648. + SG_CONSUME(sg, data32, data_i, data_l);
  4649. + CVM_LOAD_MD5_UNIT(*pdata, next);
  4650. + auth_len -= 8;
  4651. + }
  4652. +
  4653. + /* finish the hash */
  4654. + CVMX_PREFETCH0(od->octo_hmouter);
  4655. +#if 0
  4656. + if (unlikely(inplen)) {
  4657. + uint64_t tmp = 0;
  4658. + uint8_t *p = (uint8_t *) & tmp;
  4659. + p[inplen] = 0x80;
  4660. + do {
  4661. + inplen--;
  4662. + p[inplen] = ((uint8_t *) data)[inplen];
  4663. + } while (inplen);
  4664. + CVM_LOAD_MD5_UNIT(tmp, next);
  4665. + } else {
  4666. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  4667. + }
  4668. +#else
  4669. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  4670. +#endif
  4671. +
  4672. + /* Finish Inner hash */
  4673. + while (next != 7) {
  4674. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  4675. + }
  4676. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  4677. + CVM_LOAD_MD5_UNIT(tmp1, next);
  4678. +
  4679. + /* Get the inner hash of HMAC */
  4680. + CVMX_MF_HSH_IV(tmp1, 0);
  4681. + CVMX_MF_HSH_IV(tmp2, 1);
  4682. +
  4683. + /* Initialize hash unit */
  4684. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  4685. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  4686. +
  4687. + CVMX_MT_HSH_DAT(tmp1, 0);
  4688. + CVMX_MT_HSH_DAT(tmp2, 1);
  4689. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  4690. + CVMX_MT_HSH_DATZ(3);
  4691. + CVMX_MT_HSH_DATZ(4);
  4692. + CVMX_MT_HSH_DATZ(5);
  4693. + CVMX_MT_HSH_DATZ(6);
  4694. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  4695. + CVMX_MT_HSH_STARTMD5(tmp1);
  4696. +
  4697. + /* save the HMAC */
  4698. + SG_INIT(sg, data32, data_i, data_l);
  4699. + while (icv_off > 0) {
  4700. + SG_CONSUME(sg, data32, data_i, data_l);
  4701. + icv_off -= 4;
  4702. + }
  4703. + CVMX_MF_HSH_IV(tmp1, 0);
  4704. + *data32 = (uint32_t) (tmp1 >> 32);
  4705. + SG_CONSUME(sg, data32, data_i, data_l);
  4706. + *data32 = (uint32_t) tmp1;
  4707. + SG_CONSUME(sg, data32, data_i, data_l);
  4708. + CVMX_MF_HSH_IV(tmp1, 1);
  4709. + *data32 = (uint32_t) (tmp1 >> 32);
  4710. +
  4711. + octeon_crypto_disable(&state, flags);
  4712. + return 0;
  4713. +}
  4714. +
  4715. +int
  4716. +octo_aes_cbc_md5_decrypt(
  4717. + struct octo_sess *od,
  4718. + struct scatterlist *sg, int sg_len,
  4719. + int auth_off, int auth_len,
  4720. + int crypt_off, int crypt_len,
  4721. + int icv_off, uint8_t *ivp)
  4722. +{
  4723. + register int next = 0;
  4724. + union {
  4725. + uint32_t data32[2];
  4726. + uint64_t data64[1];
  4727. + } mydata[2];
  4728. + uint64_t *pdata = &mydata[0].data64[0];
  4729. + uint64_t *data = &mydata[1].data64[0];
  4730. + uint32_t *data32;
  4731. + uint64_t tmp1, tmp2;
  4732. + int data_i, data_l, alen = auth_len;
  4733. + struct octeon_cop2_state state;
  4734. + unsigned long flags;
  4735. +
  4736. + dprintk("%s()\n", __FUNCTION__);
  4737. +
  4738. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4739. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  4740. + (crypt_len & 0x7) ||
  4741. + (auth_len & 0x7) ||
  4742. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  4743. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4744. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4745. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4746. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4747. + return -EINVAL;
  4748. + }
  4749. +
  4750. + SG_INIT(sg, data32, data_i, data_l);
  4751. +
  4752. + CVMX_PREFETCH0(ivp);
  4753. + CVMX_PREFETCH0(od->octo_enckey);
  4754. +
  4755. + flags = octeon_crypto_enable(&state);
  4756. +
  4757. + /* load AES Key */
  4758. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4759. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4760. +
  4761. + if (od->octo_encklen == 16) {
  4762. + CVMX_MT_AES_KEY(0x0, 2);
  4763. + CVMX_MT_AES_KEY(0x0, 3);
  4764. + } else if (od->octo_encklen == 24) {
  4765. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4766. + CVMX_MT_AES_KEY(0x0, 3);
  4767. + } else if (od->octo_encklen == 32) {
  4768. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4769. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  4770. + } else {
  4771. + octeon_crypto_disable(&state, flags);
  4772. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4773. + return -EINVAL;
  4774. + }
  4775. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  4776. +
  4777. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  4778. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  4779. +
  4780. + /* Load MD5 IV */
  4781. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  4782. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  4783. +
  4784. + while (crypt_off > 0 && auth_off > 0) {
  4785. + SG_CONSUME(sg, data32, data_i, data_l);
  4786. + crypt_off -= 4;
  4787. + auth_off -= 4;
  4788. + }
  4789. +
  4790. + /* align auth and crypt */
  4791. + while (crypt_off > 0 && auth_len > 0) {
  4792. + mydata[0].data32[0] = *data32;
  4793. + SG_CONSUME(sg, data32, data_i, data_l);
  4794. + mydata[0].data32[1] = *data32;
  4795. + SG_CONSUME(sg, data32, data_i, data_l);
  4796. + CVM_LOAD_MD5_UNIT(*pdata, next);
  4797. + crypt_off -= 8;
  4798. + auth_len -= 8;
  4799. + }
  4800. +
  4801. + while (crypt_len > 0) {
  4802. + uint32_t *pdata32[3];
  4803. +
  4804. + pdata32[0] = data32;
  4805. + mydata[0].data32[0] = *data32;
  4806. + SG_CONSUME(sg, data32, data_i, data_l);
  4807. + pdata32[1] = data32;
  4808. + mydata[0].data32[1] = *data32;
  4809. + SG_CONSUME(sg, data32, data_i, data_l);
  4810. + pdata32[2] = data32;
  4811. + mydata[1].data32[0] = *data32;
  4812. + SG_CONSUME(sg, data32, data_i, data_l);
  4813. + mydata[1].data32[1] = *data32;
  4814. +
  4815. + if (auth_len > 0) {
  4816. + CVM_LOAD_MD5_UNIT(*pdata, next);
  4817. + auth_len -= 8;
  4818. + }
  4819. +
  4820. + if (auth_len > 0) {
  4821. + CVM_LOAD_MD5_UNIT(*data, next);
  4822. + auth_len -= 8;
  4823. + }
  4824. +
  4825. + CVMX_MT_AES_DEC_CBC0(*pdata);
  4826. + CVMX_MT_AES_DEC_CBC1(*data);
  4827. + CVMX_MF_AES_RESULT(*pdata, 0);
  4828. + CVMX_MF_AES_RESULT(*data, 1);
  4829. + crypt_len -= 16;
  4830. +
  4831. + *pdata32[0] = mydata[0].data32[0];
  4832. + *pdata32[1] = mydata[0].data32[1];
  4833. + *pdata32[2] = mydata[1].data32[0];
  4834. + *data32 = mydata[1].data32[1];
  4835. +
  4836. + SG_CONSUME(sg, data32, data_i, data_l);
  4837. + }
  4838. +
  4839. + /* finish left over hash if any */
  4840. + while (auth_len > 0) {
  4841. + mydata[0].data32[0] = *data32;
  4842. + SG_CONSUME(sg, data32, data_i, data_l);
  4843. + mydata[0].data32[1] = *data32;
  4844. + SG_CONSUME(sg, data32, data_i, data_l);
  4845. + CVM_LOAD_MD5_UNIT(*pdata, next);
  4846. + auth_len -= 8;
  4847. + }
  4848. +
  4849. +
  4850. + /* finish the hash */
  4851. + CVMX_PREFETCH0(od->octo_hmouter);
  4852. +#if 0
  4853. + if (unlikely(inplen)) {
  4854. + uint64_t tmp = 0;
  4855. + uint8_t *p = (uint8_t *) & tmp;
  4856. + p[inplen] = 0x80;
  4857. + do {
  4858. + inplen--;
  4859. + p[inplen] = ((uint8_t *) data)[inplen];
  4860. + } while (inplen);
  4861. + CVM_LOAD_MD5_UNIT(tmp, next);
  4862. + } else {
  4863. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  4864. + }
  4865. +#else
  4866. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  4867. +#endif
  4868. +
  4869. + /* Finish Inner hash */
  4870. + while (next != 7) {
  4871. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  4872. + }
  4873. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  4874. + CVM_LOAD_MD5_UNIT(tmp1, next);
  4875. +
  4876. + /* Get the inner hash of HMAC */
  4877. + CVMX_MF_HSH_IV(tmp1, 0);
  4878. + CVMX_MF_HSH_IV(tmp2, 1);
  4879. +
  4880. + /* Initialize hash unit */
  4881. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  4882. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  4883. +
  4884. + CVMX_MT_HSH_DAT(tmp1, 0);
  4885. + CVMX_MT_HSH_DAT(tmp2, 1);
  4886. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  4887. + CVMX_MT_HSH_DATZ(3);
  4888. + CVMX_MT_HSH_DATZ(4);
  4889. + CVMX_MT_HSH_DATZ(5);
  4890. + CVMX_MT_HSH_DATZ(6);
  4891. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  4892. + CVMX_MT_HSH_STARTMD5(tmp1);
  4893. +
  4894. + /* save the HMAC */
  4895. + SG_INIT(sg, data32, data_i, data_l);
  4896. + while (icv_off > 0) {
  4897. + SG_CONSUME(sg, data32, data_i, data_l);
  4898. + icv_off -= 4;
  4899. + }
  4900. + CVMX_MF_HSH_IV(tmp1, 0);
  4901. + *data32 = (uint32_t) (tmp1 >> 32);
  4902. + SG_CONSUME(sg, data32, data_i, data_l);
  4903. + *data32 = (uint32_t) tmp1;
  4904. + SG_CONSUME(sg, data32, data_i, data_l);
  4905. + CVMX_MF_HSH_IV(tmp1, 1);
  4906. + *data32 = (uint32_t) (tmp1 >> 32);
  4907. +
  4908. + octeon_crypto_disable(&state, flags);
  4909. + return 0;
  4910. +}
  4911. +
  4912. +/****************************************************************************/
  4913. +/* AES SHA1 */
  4914. +
  4915. +int
  4916. +octo_aes_cbc_sha1_encrypt(
  4917. + struct octo_sess *od,
  4918. + struct scatterlist *sg, int sg_len,
  4919. + int auth_off, int auth_len,
  4920. + int crypt_off, int crypt_len,
  4921. + int icv_off, uint8_t *ivp)
  4922. +{
  4923. + register int next = 0;
  4924. + union {
  4925. + uint32_t data32[2];
  4926. + uint64_t data64[1];
  4927. + } mydata[2];
  4928. + uint64_t *pdata = &mydata[0].data64[0];
  4929. + uint64_t *data = &mydata[1].data64[0];
  4930. + uint32_t *data32;
  4931. + uint64_t tmp1, tmp2, tmp3;
  4932. + int data_i, data_l, alen = auth_len;
  4933. + struct octeon_cop2_state state;
  4934. + unsigned long flags;
  4935. +
  4936. + dprintk("%s(a_off=%d a_len=%d c_off=%d c_len=%d icv_off=%d)\n",
  4937. + __FUNCTION__, auth_off, auth_len, crypt_off, crypt_len, icv_off);
  4938. +
  4939. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4940. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  4941. + (crypt_len & 0x7) ||
  4942. + (auth_len & 0x7) ||
  4943. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  4944. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4945. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4946. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4947. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4948. + return -EINVAL;
  4949. + }
  4950. +
  4951. + SG_INIT(sg, data32, data_i, data_l);
  4952. +
  4953. + CVMX_PREFETCH0(ivp);
  4954. + CVMX_PREFETCH0(od->octo_enckey);
  4955. +
  4956. + flags = octeon_crypto_enable(&state);
  4957. +
  4958. + /* load AES Key */
  4959. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4960. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4961. +
  4962. + if (od->octo_encklen == 16) {
  4963. + CVMX_MT_AES_KEY(0x0, 2);
  4964. + CVMX_MT_AES_KEY(0x0, 3);
  4965. + } else if (od->octo_encklen == 24) {
  4966. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4967. + CVMX_MT_AES_KEY(0x0, 3);
  4968. + } else if (od->octo_encklen == 32) {
  4969. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4970. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  4971. + } else {
  4972. + octeon_crypto_disable(&state, flags);
  4973. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4974. + return -EINVAL;
  4975. + }
  4976. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  4977. +
  4978. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  4979. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  4980. +
  4981. + /* Load SHA IV */
  4982. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  4983. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  4984. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  4985. +
  4986. + while (crypt_off > 0 && auth_off > 0) {
  4987. + SG_CONSUME(sg, data32, data_i, data_l);
  4988. + crypt_off -= 4;
  4989. + auth_off -= 4;
  4990. + }
  4991. +
  4992. + /* align auth and crypt */
  4993. + while (crypt_off > 0 && auth_len > 0) {
  4994. + mydata[0].data32[0] = *data32;
  4995. + SG_CONSUME(sg, data32, data_i, data_l);
  4996. + mydata[0].data32[1] = *data32;
  4997. + SG_CONSUME(sg, data32, data_i, data_l);
  4998. + CVM_LOAD_SHA_UNIT(*pdata, next);
  4999. + crypt_off -= 8;
  5000. + auth_len -= 8;
  5001. + }
  5002. +
  5003. + while (crypt_len > 0) {
  5004. + uint32_t *pdata32[3];
  5005. +
  5006. + pdata32[0] = data32;
  5007. + mydata[0].data32[0] = *data32;
  5008. + SG_CONSUME(sg, data32, data_i, data_l);
  5009. + pdata32[1] = data32;
  5010. + mydata[0].data32[1] = *data32;
  5011. + SG_CONSUME(sg, data32, data_i, data_l);
  5012. + pdata32[2] = data32;
  5013. + mydata[1].data32[0] = *data32;
  5014. + SG_CONSUME(sg, data32, data_i, data_l);
  5015. + mydata[1].data32[1] = *data32;
  5016. +
  5017. + CVMX_MT_AES_ENC_CBC0(*pdata);
  5018. + CVMX_MT_AES_ENC_CBC1(*data);
  5019. + CVMX_MF_AES_RESULT(*pdata, 0);
  5020. + CVMX_MF_AES_RESULT(*data, 1);
  5021. + crypt_len -= 16;
  5022. +
  5023. + if (auth_len > 0) {
  5024. + CVM_LOAD_SHA_UNIT(*pdata, next);
  5025. + auth_len -= 8;
  5026. + }
  5027. + if (auth_len > 0) {
  5028. + CVM_LOAD_SHA_UNIT(*data, next);
  5029. + auth_len -= 8;
  5030. + }
  5031. +
  5032. + *pdata32[0] = mydata[0].data32[0];
  5033. + *pdata32[1] = mydata[0].data32[1];
  5034. + *pdata32[2] = mydata[1].data32[0];
  5035. + *data32 = mydata[1].data32[1];
  5036. +
  5037. + SG_CONSUME(sg, data32, data_i, data_l);
  5038. + }
  5039. +
  5040. + /* finish and hashing */
  5041. + while (auth_len > 0) {
  5042. + mydata[0].data32[0] = *data32;
  5043. + SG_CONSUME(sg, data32, data_i, data_l);
  5044. + mydata[0].data32[1] = *data32;
  5045. + SG_CONSUME(sg, data32, data_i, data_l);
  5046. + CVM_LOAD_SHA_UNIT(*pdata, next);
  5047. + auth_len -= 8;
  5048. + }
  5049. +
  5050. + /* finish the hash */
  5051. + CVMX_PREFETCH0(od->octo_hmouter);
  5052. +#if 0
  5053. + if (unlikely(inplen)) {
  5054. + uint64_t tmp = 0;
  5055. + uint8_t *p = (uint8_t *) & tmp;
  5056. + p[inplen] = 0x80;
  5057. + do {
  5058. + inplen--;
  5059. + p[inplen] = ((uint8_t *) data)[inplen];
  5060. + } while (inplen);
  5061. + CVM_LOAD_SHA_UNIT(tmp, next);
  5062. + } else {
  5063. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  5064. + }
  5065. +#else
  5066. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  5067. +#endif
  5068. +
  5069. + /* Finish Inner hash */
  5070. + while (next != 7) {
  5071. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  5072. + }
  5073. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  5074. +
  5075. + /* Get the inner hash of HMAC */
  5076. + CVMX_MF_HSH_IV(tmp1, 0);
  5077. + CVMX_MF_HSH_IV(tmp2, 1);
  5078. + tmp3 = 0;
  5079. + CVMX_MF_HSH_IV(tmp3, 2);
  5080. +
  5081. + /* Initialize hash unit */
  5082. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  5083. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  5084. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  5085. +
  5086. + CVMX_MT_HSH_DAT(tmp1, 0);
  5087. + CVMX_MT_HSH_DAT(tmp2, 1);
  5088. + tmp3 |= 0x0000000080000000;
  5089. + CVMX_MT_HSH_DAT(tmp3, 2);
  5090. + CVMX_MT_HSH_DATZ(3);
  5091. + CVMX_MT_HSH_DATZ(4);
  5092. + CVMX_MT_HSH_DATZ(5);
  5093. + CVMX_MT_HSH_DATZ(6);
  5094. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  5095. +
  5096. + /* finish the hash */
  5097. + CVMX_PREFETCH0(od->octo_hmouter);
  5098. +#if 0
  5099. + if (unlikely(inplen)) {
  5100. + uint64_t tmp = 0;
  5101. + uint8_t *p = (uint8_t *) & tmp;
  5102. + p[inplen] = 0x80;
  5103. + do {
  5104. + inplen--;
  5105. + p[inplen] = ((uint8_t *) data)[inplen];
  5106. + } while (inplen);
  5107. + CVM_LOAD_MD5_UNIT(tmp, next);
  5108. + } else {
  5109. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5110. + }
  5111. +#else
  5112. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5113. +#endif
  5114. +
  5115. + /* save the HMAC */
  5116. + SG_INIT(sg, data32, data_i, data_l);
  5117. + while (icv_off > 0) {
  5118. + SG_CONSUME(sg, data32, data_i, data_l);
  5119. + icv_off -= 4;
  5120. + }
  5121. + CVMX_MF_HSH_IV(tmp1, 0);
  5122. + *data32 = (uint32_t) (tmp1 >> 32);
  5123. + SG_CONSUME(sg, data32, data_i, data_l);
  5124. + *data32 = (uint32_t) tmp1;
  5125. + SG_CONSUME(sg, data32, data_i, data_l);
  5126. + CVMX_MF_HSH_IV(tmp1, 1);
  5127. + *data32 = (uint32_t) (tmp1 >> 32);
  5128. +
  5129. + octeon_crypto_disable(&state, flags);
  5130. + return 0;
  5131. +}
  5132. +
  5133. +int
  5134. +octo_aes_cbc_sha1_decrypt(
  5135. + struct octo_sess *od,
  5136. + struct scatterlist *sg, int sg_len,
  5137. + int auth_off, int auth_len,
  5138. + int crypt_off, int crypt_len,
  5139. + int icv_off, uint8_t *ivp)
  5140. +{
  5141. + register int next = 0;
  5142. + union {
  5143. + uint32_t data32[2];
  5144. + uint64_t data64[1];
  5145. + } mydata[2];
  5146. + uint64_t *pdata = &mydata[0].data64[0];
  5147. + uint64_t *data = &mydata[1].data64[0];
  5148. + uint32_t *data32;
  5149. + uint64_t tmp1, tmp2, tmp3;
  5150. + int data_i, data_l, alen = auth_len;
  5151. + struct octeon_cop2_state state;
  5152. + unsigned long flags;
  5153. +
  5154. + dprintk("%s(a_off=%d a_len=%d c_off=%d c_len=%d icv_off=%d)\n",
  5155. + __FUNCTION__, auth_off, auth_len, crypt_off, crypt_len, icv_off);
  5156. +
  5157. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  5158. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  5159. + (crypt_len & 0x7) ||
  5160. + (auth_len & 0x7) ||
  5161. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  5162. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5163. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5164. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5165. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5166. + return -EINVAL;
  5167. + }
  5168. +
  5169. + SG_INIT(sg, data32, data_i, data_l);
  5170. +
  5171. + CVMX_PREFETCH0(ivp);
  5172. + CVMX_PREFETCH0(od->octo_enckey);
  5173. +
  5174. + flags = octeon_crypto_enable(&state);
  5175. +
  5176. + /* load AES Key */
  5177. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  5178. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  5179. +
  5180. + if (od->octo_encklen == 16) {
  5181. + CVMX_MT_AES_KEY(0x0, 2);
  5182. + CVMX_MT_AES_KEY(0x0, 3);
  5183. + } else if (od->octo_encklen == 24) {
  5184. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5185. + CVMX_MT_AES_KEY(0x0, 3);
  5186. + } else if (od->octo_encklen == 32) {
  5187. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5188. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  5189. + } else {
  5190. + octeon_crypto_disable(&state, flags);
  5191. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  5192. + return -EINVAL;
  5193. + }
  5194. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  5195. +
  5196. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  5197. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  5198. +
  5199. + /* Load SHA1 IV */
  5200. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5201. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5202. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  5203. +
  5204. + while (crypt_off > 0 && auth_off > 0) {
  5205. + SG_CONSUME(sg, data32, data_i, data_l);
  5206. + crypt_off -= 4;
  5207. + auth_off -= 4;
  5208. + }
  5209. +
  5210. + /* align auth and crypt */
  5211. + while (crypt_off > 0 && auth_len > 0) {
  5212. + mydata[0].data32[0] = *data32;
  5213. + SG_CONSUME(sg, data32, data_i, data_l);
  5214. + mydata[0].data32[1] = *data32;
  5215. + SG_CONSUME(sg, data32, data_i, data_l);
  5216. + CVM_LOAD_SHA_UNIT(*pdata, next);
  5217. + crypt_off -= 8;
  5218. + auth_len -= 8;
  5219. + }
  5220. +
  5221. + while (crypt_len > 0) {
  5222. + uint32_t *pdata32[3];
  5223. +
  5224. + pdata32[0] = data32;
  5225. + mydata[0].data32[0] = *data32;
  5226. + SG_CONSUME(sg, data32, data_i, data_l);
  5227. + pdata32[1] = data32;
  5228. + mydata[0].data32[1] = *data32;
  5229. + SG_CONSUME(sg, data32, data_i, data_l);
  5230. + pdata32[2] = data32;
  5231. + mydata[1].data32[0] = *data32;
  5232. + SG_CONSUME(sg, data32, data_i, data_l);
  5233. + mydata[1].data32[1] = *data32;
  5234. +
  5235. + if (auth_len > 0) {
  5236. + CVM_LOAD_SHA_UNIT(*pdata, next);
  5237. + auth_len -= 8;
  5238. + }
  5239. + if (auth_len > 0) {
  5240. + CVM_LOAD_SHA_UNIT(*data, next);
  5241. + auth_len -= 8;
  5242. + }
  5243. +
  5244. + CVMX_MT_AES_DEC_CBC0(*pdata);
  5245. + CVMX_MT_AES_DEC_CBC1(*data);
  5246. + CVMX_MF_AES_RESULT(*pdata, 0);
  5247. + CVMX_MF_AES_RESULT(*data, 1);
  5248. + crypt_len -= 16;
  5249. +
  5250. + *pdata32[0] = mydata[0].data32[0];
  5251. + *pdata32[1] = mydata[0].data32[1];
  5252. + *pdata32[2] = mydata[1].data32[0];
  5253. + *data32 = mydata[1].data32[1];
  5254. +
  5255. + SG_CONSUME(sg, data32, data_i, data_l);
  5256. + }
  5257. +
  5258. + /* finish and leftover hashing */
  5259. + while (auth_len > 0) {
  5260. + mydata[0].data32[0] = *data32;
  5261. + SG_CONSUME(sg, data32, data_i, data_l);
  5262. + mydata[0].data32[1] = *data32;
  5263. + SG_CONSUME(sg, data32, data_i, data_l);
  5264. + CVM_LOAD_SHA_UNIT(*pdata, next);
  5265. + auth_len -= 8;
  5266. + }
  5267. +
  5268. + /* finish the hash */
  5269. + CVMX_PREFETCH0(od->octo_hmouter);
  5270. +#if 0
  5271. + if (unlikely(inplen)) {
  5272. + uint64_t tmp = 0;
  5273. + uint8_t *p = (uint8_t *) & tmp;
  5274. + p[inplen] = 0x80;
  5275. + do {
  5276. + inplen--;
  5277. + p[inplen] = ((uint8_t *) data)[inplen];
  5278. + } while (inplen);
  5279. + CVM_LOAD_SHA_UNIT(tmp, next);
  5280. + } else {
  5281. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  5282. + }
  5283. +#else
  5284. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  5285. +#endif
  5286. +
  5287. + /* Finish Inner hash */
  5288. + while (next != 7) {
  5289. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  5290. + }
  5291. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  5292. +
  5293. + /* Get the inner hash of HMAC */
  5294. + CVMX_MF_HSH_IV(tmp1, 0);
  5295. + CVMX_MF_HSH_IV(tmp2, 1);
  5296. + tmp3 = 0;
  5297. + CVMX_MF_HSH_IV(tmp3, 2);
  5298. +
  5299. + /* Initialize hash unit */
  5300. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  5301. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  5302. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  5303. +
  5304. + CVMX_MT_HSH_DAT(tmp1, 0);
  5305. + CVMX_MT_HSH_DAT(tmp2, 1);
  5306. + tmp3 |= 0x0000000080000000;
  5307. + CVMX_MT_HSH_DAT(tmp3, 2);
  5308. + CVMX_MT_HSH_DATZ(3);
  5309. + CVMX_MT_HSH_DATZ(4);
  5310. + CVMX_MT_HSH_DATZ(5);
  5311. + CVMX_MT_HSH_DATZ(6);
  5312. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  5313. +
  5314. + /* finish the hash */
  5315. + CVMX_PREFETCH0(od->octo_hmouter);
  5316. +#if 0
  5317. + if (unlikely(inplen)) {
  5318. + uint64_t tmp = 0;
  5319. + uint8_t *p = (uint8_t *) & tmp;
  5320. + p[inplen] = 0x80;
  5321. + do {
  5322. + inplen--;
  5323. + p[inplen] = ((uint8_t *) data)[inplen];
  5324. + } while (inplen);
  5325. + CVM_LOAD_MD5_UNIT(tmp, next);
  5326. + } else {
  5327. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5328. + }
  5329. +#else
  5330. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5331. +#endif
  5332. +
  5333. + /* save the HMAC */
  5334. + SG_INIT(sg, data32, data_i, data_l);
  5335. + while (icv_off > 0) {
  5336. + SG_CONSUME(sg, data32, data_i, data_l);
  5337. + icv_off -= 4;
  5338. + }
  5339. + CVMX_MF_HSH_IV(tmp1, 0);
  5340. + *data32 = (uint32_t) (tmp1 >> 32);
  5341. + SG_CONSUME(sg, data32, data_i, data_l);
  5342. + *data32 = (uint32_t) tmp1;
  5343. + SG_CONSUME(sg, data32, data_i, data_l);
  5344. + CVMX_MF_HSH_IV(tmp1, 1);
  5345. + *data32 = (uint32_t) (tmp1 >> 32);
  5346. +
  5347. + octeon_crypto_disable(&state, flags);
  5348. + return 0;
  5349. +}
  5350. +
  5351. +/****************************************************************************/
  5352. diff -Nur linux-2.6.36.orig/crypto/ocf/cryptocteon/cryptocteon.c linux-2.6.36/crypto/ocf/cryptocteon/cryptocteon.c
  5353. --- linux-2.6.36.orig/crypto/ocf/cryptocteon/cryptocteon.c 1970-01-01 01:00:00.000000000 +0100
  5354. +++ linux-2.6.36/crypto/ocf/cryptocteon/cryptocteon.c 2010-11-09 20:28:04.371247488 +0100
  5355. @@ -0,0 +1,574 @@
  5356. +/*
  5357. + * Octeon Crypto for OCF
  5358. + *
  5359. + * Written by David McCullough <david_mccullough@mcafee.com>
  5360. + * Copyright (C) 2009-2010 David McCullough
  5361. + *
  5362. + * LICENSE TERMS
  5363. + *
  5364. + * The free distribution and use of this software in both source and binary
  5365. + * form is allowed (with or without changes) provided that:
  5366. + *
  5367. + * 1. distributions of this source code include the above copyright
  5368. + * notice, this list of conditions and the following disclaimer;
  5369. + *
  5370. + * 2. distributions in binary form include the above copyright
  5371. + * notice, this list of conditions and the following disclaimer
  5372. + * in the documentation and/or other associated materials;
  5373. + *
  5374. + * 3. the copyright holder's name is not used to endorse products
  5375. + * built using this software without specific written permission.
  5376. + *
  5377. + * DISCLAIMER
  5378. + *
  5379. + * This software is provided 'as is' with no explicit or implied warranties
  5380. + * in respect of its properties, including, but not limited to, correctness
  5381. + * and/or fitness for purpose.
  5382. + * ---------------------------------------------------------------------------
  5383. + */
  5384. +
  5385. +#ifndef AUTOCONF_INCLUDED
  5386. +#include <linux/config.h>
  5387. +#endif
  5388. +#include <linux/module.h>
  5389. +#include <linux/init.h>
  5390. +#include <linux/list.h>
  5391. +#include <linux/slab.h>
  5392. +#include <linux/sched.h>
  5393. +#include <linux/wait.h>
  5394. +#include <linux/crypto.h>
  5395. +#include <linux/mm.h>
  5396. +#include <linux/skbuff.h>
  5397. +#include <linux/random.h>
  5398. +#include <linux/scatterlist.h>
  5399. +
  5400. +#include <cryptodev.h>
  5401. +#include <uio.h>
  5402. +
  5403. +struct {
  5404. + softc_device_decl sc_dev;
  5405. +} octo_softc;
  5406. +
  5407. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  5408. +
  5409. +struct octo_sess {
  5410. + int octo_encalg;
  5411. + #define MAX_CIPHER_KEYLEN 64
  5412. + char octo_enckey[MAX_CIPHER_KEYLEN];
  5413. + int octo_encklen;
  5414. +
  5415. + int octo_macalg;
  5416. + #define MAX_HASH_KEYLEN 64
  5417. + char octo_mackey[MAX_HASH_KEYLEN];
  5418. + int octo_macklen;
  5419. + int octo_mackey_set;
  5420. +
  5421. + int octo_mlen;
  5422. + int octo_ivsize;
  5423. +
  5424. +#if 0
  5425. + int (*octo_decrypt)(struct scatterlist *sg, int sg_len,
  5426. + uint8_t *key, int key_len, uint8_t * iv,
  5427. + uint64_t *hminner, uint64_t *hmouter);
  5428. +
  5429. + int (*octo_encrypt)(struct scatterlist *sg, int sg_len,
  5430. + uint8_t *key, int key_len, uint8_t * iv,
  5431. + uint64_t *hminner, uint64_t *hmouter);
  5432. +#else
  5433. + int (*octo_encrypt)(struct octo_sess *od,
  5434. + struct scatterlist *sg, int sg_len,
  5435. + int auth_off, int auth_len,
  5436. + int crypt_off, int crypt_len,
  5437. + int icv_off, uint8_t *ivp);
  5438. + int (*octo_decrypt)(struct octo_sess *od,
  5439. + struct scatterlist *sg, int sg_len,
  5440. + int auth_off, int auth_len,
  5441. + int crypt_off, int crypt_len,
  5442. + int icv_off, uint8_t *ivp);
  5443. +#endif
  5444. +
  5445. + uint64_t octo_hminner[3];
  5446. + uint64_t octo_hmouter[3];
  5447. +};
  5448. +
  5449. +int32_t octo_id = -1;
  5450. +module_param(octo_id, int, 0444);
  5451. +MODULE_PARM_DESC(octo_id, "Read-Only OCF ID for cryptocteon driver");
  5452. +
  5453. +static struct octo_sess **octo_sessions = NULL;
  5454. +static u_int32_t octo_sesnum = 0;
  5455. +
  5456. +static int octo_process(device_t, struct cryptop *, int);
  5457. +static int octo_newsession(device_t, u_int32_t *, struct cryptoini *);
  5458. +static int octo_freesession(device_t, u_int64_t);
  5459. +
  5460. +static device_method_t octo_methods = {
  5461. + /* crypto device methods */
  5462. + DEVMETHOD(cryptodev_newsession, octo_newsession),
  5463. + DEVMETHOD(cryptodev_freesession,octo_freesession),
  5464. + DEVMETHOD(cryptodev_process, octo_process),
  5465. +};
  5466. +
  5467. +#define debug octo_debug
  5468. +int octo_debug = 0;
  5469. +module_param(octo_debug, int, 0644);
  5470. +MODULE_PARM_DESC(octo_debug, "Enable debug");
  5471. +
  5472. +
  5473. +#include "cavium_crypto.c"
  5474. +
  5475. +
  5476. +/*
  5477. + * Generate a new octo session. We artifically limit it to a single
  5478. + * hash/cipher or hash-cipher combo just to make it easier, most callers
  5479. + * do not expect more than this anyway.
  5480. + */
  5481. +static int
  5482. +octo_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  5483. +{
  5484. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  5485. + struct octo_sess **ocd;
  5486. + int i;
  5487. +
  5488. + dprintk("%s()\n", __FUNCTION__);
  5489. + if (sid == NULL || cri == NULL) {
  5490. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  5491. + return EINVAL;
  5492. + }
  5493. +
  5494. + /*
  5495. + * To keep it simple, we only handle hash, cipher or hash/cipher in a
  5496. + * session, you cannot currently do multiple ciphers/hashes in one
  5497. + * session even though it would be possibel to code this driver to
  5498. + * handle it.
  5499. + */
  5500. + for (i = 0, c = cri; c && i < 2; i++) {
  5501. + if (c->cri_alg == CRYPTO_MD5_HMAC ||
  5502. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  5503. + c->cri_alg == CRYPTO_NULL_HMAC) {
  5504. + if (macini) {
  5505. + break;
  5506. + }
  5507. + macini = c;
  5508. + }
  5509. + if (c->cri_alg == CRYPTO_DES_CBC ||
  5510. + c->cri_alg == CRYPTO_3DES_CBC ||
  5511. + c->cri_alg == CRYPTO_AES_CBC ||
  5512. + c->cri_alg == CRYPTO_NULL_CBC) {
  5513. + if (encini) {
  5514. + break;
  5515. + }
  5516. + encini = c;
  5517. + }
  5518. + c = c->cri_next;
  5519. + }
  5520. + if (!macini && !encini) {
  5521. + dprintk("%s,%d - EINVAL bad cipher/hash or combination\n",
  5522. + __FILE__, __LINE__);
  5523. + return EINVAL;
  5524. + }
  5525. + if (c) {
  5526. + dprintk("%s,%d - EINVAL cannot handle chained cipher/hash combos\n",
  5527. + __FILE__, __LINE__);
  5528. + return EINVAL;
  5529. + }
  5530. +
  5531. + /*
  5532. + * So we have something we can do, lets setup the session
  5533. + */
  5534. +
  5535. + if (octo_sessions) {
  5536. + for (i = 1; i < octo_sesnum; i++)
  5537. + if (octo_sessions[i] == NULL)
  5538. + break;
  5539. + } else
  5540. + i = 1; /* NB: to silence compiler warning */
  5541. +
  5542. + if (octo_sessions == NULL || i == octo_sesnum) {
  5543. + if (octo_sessions == NULL) {
  5544. + i = 1; /* We leave octo_sessions[0] empty */
  5545. + octo_sesnum = CRYPTO_SW_SESSIONS;
  5546. + } else
  5547. + octo_sesnum *= 2;
  5548. +
  5549. + ocd = kmalloc(octo_sesnum * sizeof(struct octo_sess *), SLAB_ATOMIC);
  5550. + if (ocd == NULL) {
  5551. + /* Reset session number */
  5552. + if (octo_sesnum == CRYPTO_SW_SESSIONS)
  5553. + octo_sesnum = 0;
  5554. + else
  5555. + octo_sesnum /= 2;
  5556. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  5557. + return ENOBUFS;
  5558. + }
  5559. + memset(ocd, 0, octo_sesnum * sizeof(struct octo_sess *));
  5560. +
  5561. + /* Copy existing sessions */
  5562. + if (octo_sessions) {
  5563. + memcpy(ocd, octo_sessions,
  5564. + (octo_sesnum / 2) * sizeof(struct octo_sess *));
  5565. + kfree(octo_sessions);
  5566. + }
  5567. +
  5568. + octo_sessions = ocd;
  5569. + }
  5570. +
  5571. + ocd = &octo_sessions[i];
  5572. + *sid = i;
  5573. +
  5574. +
  5575. + *ocd = (struct octo_sess *) kmalloc(sizeof(struct octo_sess), SLAB_ATOMIC);
  5576. + if (*ocd == NULL) {
  5577. + octo_freesession(NULL, i);
  5578. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  5579. + return ENOBUFS;
  5580. + }
  5581. + memset(*ocd, 0, sizeof(struct octo_sess));
  5582. +
  5583. + if (encini && encini->cri_key) {
  5584. + (*ocd)->octo_encklen = (encini->cri_klen + 7) / 8;
  5585. + memcpy((*ocd)->octo_enckey, encini->cri_key, (*ocd)->octo_encklen);
  5586. + }
  5587. +
  5588. + if (macini && macini->cri_key) {
  5589. + (*ocd)->octo_macklen = (macini->cri_klen + 7) / 8;
  5590. + memcpy((*ocd)->octo_mackey, macini->cri_key, (*ocd)->octo_macklen);
  5591. + }
  5592. +
  5593. + (*ocd)->octo_mlen = 0;
  5594. + if (encini && encini->cri_mlen)
  5595. + (*ocd)->octo_mlen = encini->cri_mlen;
  5596. + else if (macini && macini->cri_mlen)
  5597. + (*ocd)->octo_mlen = macini->cri_mlen;
  5598. + else
  5599. + (*ocd)->octo_mlen = 12;
  5600. +
  5601. + /*
  5602. + * point c at the enc if it exists, otherwise the mac
  5603. + */
  5604. + c = encini ? encini : macini;
  5605. +
  5606. + switch (c->cri_alg) {
  5607. + case CRYPTO_DES_CBC:
  5608. + case CRYPTO_3DES_CBC:
  5609. + (*ocd)->octo_ivsize = 8;
  5610. + switch (macini ? macini->cri_alg : -1) {
  5611. + case CRYPTO_MD5_HMAC:
  5612. + (*ocd)->octo_encrypt = octo_des_cbc_md5_encrypt;
  5613. + (*ocd)->octo_decrypt = octo_des_cbc_md5_decrypt;
  5614. + octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
  5615. + (*ocd)->octo_hmouter);
  5616. + break;
  5617. + case CRYPTO_SHA1_HMAC:
  5618. + (*ocd)->octo_encrypt = octo_des_cbc_sha1_encrypt;
  5619. + (*ocd)->octo_decrypt = octo_des_cbc_sha1_encrypt;
  5620. + octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
  5621. + (*ocd)->octo_hmouter);
  5622. + break;
  5623. + case -1:
  5624. + (*ocd)->octo_encrypt = octo_des_cbc_encrypt;
  5625. + (*ocd)->octo_decrypt = octo_des_cbc_decrypt;
  5626. + break;
  5627. + default:
  5628. + octo_freesession(NULL, i);
  5629. + dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
  5630. + return EINVAL;
  5631. + }
  5632. + break;
  5633. + case CRYPTO_AES_CBC:
  5634. + (*ocd)->octo_ivsize = 16;
  5635. + switch (macini ? macini->cri_alg : -1) {
  5636. + case CRYPTO_MD5_HMAC:
  5637. + (*ocd)->octo_encrypt = octo_aes_cbc_md5_encrypt;
  5638. + (*ocd)->octo_decrypt = octo_aes_cbc_md5_decrypt;
  5639. + octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
  5640. + (*ocd)->octo_hmouter);
  5641. + break;
  5642. + case CRYPTO_SHA1_HMAC:
  5643. + (*ocd)->octo_encrypt = octo_aes_cbc_sha1_encrypt;
  5644. + (*ocd)->octo_decrypt = octo_aes_cbc_sha1_decrypt;
  5645. + octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
  5646. + (*ocd)->octo_hmouter);
  5647. + break;
  5648. + case -1:
  5649. + (*ocd)->octo_encrypt = octo_aes_cbc_encrypt;
  5650. + (*ocd)->octo_decrypt = octo_aes_cbc_decrypt;
  5651. + break;
  5652. + default:
  5653. + octo_freesession(NULL, i);
  5654. + dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
  5655. + return EINVAL;
  5656. + }
  5657. + break;
  5658. + case CRYPTO_MD5_HMAC:
  5659. + (*ocd)->octo_encrypt = octo_null_md5_encrypt;
  5660. + (*ocd)->octo_decrypt = octo_null_md5_encrypt;
  5661. + octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
  5662. + (*ocd)->octo_hmouter);
  5663. + break;
  5664. + case CRYPTO_SHA1_HMAC:
  5665. + (*ocd)->octo_encrypt = octo_null_sha1_encrypt;
  5666. + (*ocd)->octo_decrypt = octo_null_sha1_encrypt;
  5667. + octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
  5668. + (*ocd)->octo_hmouter);
  5669. + break;
  5670. + default:
  5671. + octo_freesession(NULL, i);
  5672. + dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
  5673. + return EINVAL;
  5674. + }
  5675. +
  5676. + (*ocd)->octo_encalg = encini ? encini->cri_alg : -1;
  5677. + (*ocd)->octo_macalg = macini ? macini->cri_alg : -1;
  5678. +
  5679. + return 0;
  5680. +}
  5681. +
  5682. +/*
  5683. + * Free a session.
  5684. + */
  5685. +static int
  5686. +octo_freesession(device_t dev, u_int64_t tid)
  5687. +{
  5688. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  5689. +
  5690. + dprintk("%s()\n", __FUNCTION__);
  5691. + if (sid > octo_sesnum || octo_sessions == NULL ||
  5692. + octo_sessions[sid] == NULL) {
  5693. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  5694. + return(EINVAL);
  5695. + }
  5696. +
  5697. + /* Silently accept and return */
  5698. + if (sid == 0)
  5699. + return(0);
  5700. +
  5701. + if (octo_sessions[sid])
  5702. + kfree(octo_sessions[sid]);
  5703. + octo_sessions[sid] = NULL;
  5704. + return 0;
  5705. +}
  5706. +
  5707. +/*
  5708. + * Process a request.
  5709. + */
  5710. +static int
  5711. +octo_process(device_t dev, struct cryptop *crp, int hint)
  5712. +{
  5713. + struct cryptodesc *crd;
  5714. + struct octo_sess *od;
  5715. + u_int32_t lid;
  5716. +#define SCATTERLIST_MAX 16
  5717. + struct scatterlist sg[SCATTERLIST_MAX];
  5718. + int sg_num, sg_len;
  5719. + struct sk_buff *skb = NULL;
  5720. + struct uio *uiop = NULL;
  5721. + struct cryptodesc *enccrd = NULL, *maccrd = NULL;
  5722. + unsigned char *ivp = NULL;
  5723. + unsigned char iv_data[HASH_MAX_LEN];
  5724. + int auth_off = 0, auth_len = 0, crypt_off = 0, crypt_len = 0, icv_off = 0;
  5725. +
  5726. + dprintk("%s()\n", __FUNCTION__);
  5727. + /* Sanity check */
  5728. + if (crp == NULL) {
  5729. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  5730. + return EINVAL;
  5731. + }
  5732. +
  5733. + crp->crp_etype = 0;
  5734. +
  5735. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  5736. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  5737. + crp->crp_etype = EINVAL;
  5738. + goto done;
  5739. + }
  5740. +
  5741. + lid = crp->crp_sid & 0xffffffff;
  5742. + if (lid >= octo_sesnum || lid == 0 || octo_sessions == NULL ||
  5743. + octo_sessions[lid] == NULL) {
  5744. + crp->crp_etype = ENOENT;
  5745. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  5746. + goto done;
  5747. + }
  5748. + od = octo_sessions[lid];
  5749. +
  5750. + /*
  5751. + * do some error checking outside of the loop for SKB and IOV processing
  5752. + * this leaves us with valid skb or uiop pointers for later
  5753. + */
  5754. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  5755. + skb = (struct sk_buff *) crp->crp_buf;
  5756. + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
  5757. + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
  5758. + skb_shinfo(skb)->nr_frags);
  5759. + goto done;
  5760. + }
  5761. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  5762. + uiop = (struct uio *) crp->crp_buf;
  5763. + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
  5764. + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
  5765. + uiop->uio_iovcnt);
  5766. + goto done;
  5767. + }
  5768. + }
  5769. +
  5770. + /* point our enccrd and maccrd appropriately */
  5771. + crd = crp->crp_desc;
  5772. + if (crd->crd_alg == od->octo_encalg) enccrd = crd;
  5773. + if (crd->crd_alg == od->octo_macalg) maccrd = crd;
  5774. + crd = crd->crd_next;
  5775. + if (crd) {
  5776. + if (crd->crd_alg == od->octo_encalg) enccrd = crd;
  5777. + if (crd->crd_alg == od->octo_macalg) maccrd = crd;
  5778. + crd = crd->crd_next;
  5779. + }
  5780. + if (crd) {
  5781. + crp->crp_etype = EINVAL;
  5782. + dprintk("%s,%d: ENOENT - descriptors do not match session\n",
  5783. + __FILE__, __LINE__);
  5784. + goto done;
  5785. + }
  5786. +
  5787. + if (enccrd) {
  5788. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  5789. + ivp = enccrd->crd_iv;
  5790. + } else {
  5791. + ivp = iv_data;
  5792. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  5793. + enccrd->crd_inject, od->octo_ivsize, (caddr_t) ivp);
  5794. + }
  5795. +
  5796. + if (maccrd) {
  5797. + auth_off = maccrd->crd_skip;
  5798. + auth_len = maccrd->crd_len;
  5799. + icv_off = maccrd->crd_inject;
  5800. + }
  5801. +
  5802. + crypt_off = enccrd->crd_skip;
  5803. + crypt_len = enccrd->crd_len;
  5804. + } else { /* if (maccrd) */
  5805. + auth_off = maccrd->crd_skip;
  5806. + auth_len = maccrd->crd_len;
  5807. + icv_off = maccrd->crd_inject;
  5808. + }
  5809. +
  5810. +
  5811. + /*
  5812. + * setup the SG list to cover the buffer
  5813. + */
  5814. + memset(sg, 0, sizeof(sg));
  5815. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  5816. + int i, len;
  5817. +
  5818. + sg_num = 0;
  5819. + sg_len = 0;
  5820. +
  5821. + len = skb_headlen(skb);
  5822. + sg_set_page(&sg[sg_num], virt_to_page(skb->data), len,
  5823. + offset_in_page(skb->data));
  5824. + sg_len += len;
  5825. + sg_num++;
  5826. +
  5827. + for (i = 0; i < skb_shinfo(skb)->nr_frags && sg_num < SCATTERLIST_MAX;
  5828. + i++) {
  5829. + len = skb_shinfo(skb)->frags[i].size;
  5830. + sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page,
  5831. + len, skb_shinfo(skb)->frags[i].page_offset);
  5832. + sg_len += len;
  5833. + sg_num++;
  5834. + }
  5835. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  5836. + int len;
  5837. +
  5838. + sg_len = 0;
  5839. + for (sg_num = 0; sg_len < crp->crp_ilen &&
  5840. + sg_num < uiop->uio_iovcnt &&
  5841. + sg_num < SCATTERLIST_MAX; sg_num++) {
  5842. + len = uiop->uio_iov[sg_num].iov_len;
  5843. + sg_set_page(&sg[sg_num],
  5844. + virt_to_page(uiop->uio_iov[sg_num].iov_base), len,
  5845. + offset_in_page(uiop->uio_iov[sg_num].iov_base));
  5846. + sg_len += len;
  5847. + }
  5848. + } else {
  5849. + sg_len = crp->crp_ilen;
  5850. + sg_set_page(&sg[0], virt_to_page(crp->crp_buf), sg_len,
  5851. + offset_in_page(crp->crp_buf));
  5852. + sg_num = 1;
  5853. + }
  5854. +
  5855. +
  5856. + /*
  5857. + * setup a new explicit key
  5858. + */
  5859. + if (enccrd) {
  5860. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  5861. + od->octo_encklen = (enccrd->crd_klen + 7) / 8;
  5862. + memcpy(od->octo_enckey, enccrd->crd_key, od->octo_encklen);
  5863. + }
  5864. + }
  5865. + if (maccrd) {
  5866. + if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  5867. + od->octo_macklen = (maccrd->crd_klen + 7) / 8;
  5868. + memcpy(od->octo_mackey, maccrd->crd_key, od->octo_macklen);
  5869. + od->octo_mackey_set = 0;
  5870. + }
  5871. + if (!od->octo_mackey_set) {
  5872. + octo_calc_hash(maccrd->crd_alg == CRYPTO_MD5_HMAC ? 0 : 1,
  5873. + maccrd->crd_key, od->octo_hminner, od->octo_hmouter);
  5874. + od->octo_mackey_set = 1;
  5875. + }
  5876. + }
  5877. +
  5878. +
  5879. + if (!enccrd || (enccrd->crd_flags & CRD_F_ENCRYPT))
  5880. + (*od->octo_encrypt)(od, sg, sg_len,
  5881. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5882. + else
  5883. + (*od->octo_decrypt)(od, sg, sg_len,
  5884. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5885. +
  5886. +done:
  5887. + crypto_done(crp);
  5888. + return 0;
  5889. +}
  5890. +
  5891. +static int
  5892. +cryptocteon_init(void)
  5893. +{
  5894. + dprintk("%s(%p)\n", __FUNCTION__, cryptocteon_init);
  5895. +
  5896. + softc_device_init(&octo_softc, "cryptocteon", 0, octo_methods);
  5897. +
  5898. + octo_id = crypto_get_driverid(softc_get_device(&octo_softc),
  5899. + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SYNC);
  5900. + if (octo_id < 0) {
  5901. + printk("Cryptocteon device cannot initialize!");
  5902. + return -ENODEV;
  5903. + }
  5904. +
  5905. + crypto_register(octo_id, CRYPTO_MD5_HMAC, 0,0);
  5906. + crypto_register(octo_id, CRYPTO_SHA1_HMAC, 0,0);
  5907. + //crypto_register(octo_id, CRYPTO_MD5, 0,0);
  5908. + //crypto_register(octo_id, CRYPTO_SHA1, 0,0);
  5909. + crypto_register(octo_id, CRYPTO_DES_CBC, 0,0);
  5910. + crypto_register(octo_id, CRYPTO_3DES_CBC, 0,0);
  5911. + crypto_register(octo_id, CRYPTO_AES_CBC, 0,0);
  5912. +
  5913. + return(0);
  5914. +}
  5915. +
  5916. +static void
  5917. +cryptocteon_exit(void)
  5918. +{
  5919. + dprintk("%s()\n", __FUNCTION__);
  5920. + crypto_unregister_all(octo_id);
  5921. + octo_id = -1;
  5922. +}
  5923. +
  5924. +module_init(cryptocteon_init);
  5925. +module_exit(cryptocteon_exit);
  5926. +
  5927. +MODULE_LICENSE("BSD");
  5928. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  5929. +MODULE_DESCRIPTION("Cryptocteon (OCF module for Cavium OCTEON crypto)");
  5930. diff -Nur linux-2.6.36.orig/crypto/ocf/cryptocteon/Makefile linux-2.6.36/crypto/ocf/cryptocteon/Makefile
  5931. --- linux-2.6.36.orig/crypto/ocf/cryptocteon/Makefile 1970-01-01 01:00:00.000000000 +0100
  5932. +++ linux-2.6.36/crypto/ocf/cryptocteon/Makefile 2010-11-09 20:28:04.411246358 +0100
  5933. @@ -0,0 +1,17 @@
  5934. +# for SGlinux builds
  5935. +-include $(ROOTDIR)/modules/.config
  5936. +
  5937. +obj-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon.o
  5938. +
  5939. +obj ?= .
  5940. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  5941. +
  5942. +ifdef CONFIG_OCF_CRYPTOCTEON
  5943. +# you need the cavium crypto component installed
  5944. +EXTRA_CFLAGS += -I$(ROOTDIR)/prop/include
  5945. +endif
  5946. +
  5947. +ifdef TOPDIR
  5948. +-include $(TOPDIR)/Rules.make
  5949. +endif
  5950. +
  5951. diff -Nur linux-2.6.36.orig/crypto/ocf/cryptodev.c linux-2.6.36/crypto/ocf/cryptodev.c
  5952. --- linux-2.6.36.orig/crypto/ocf/cryptodev.c 1970-01-01 01:00:00.000000000 +0100
  5953. +++ linux-2.6.36/crypto/ocf/cryptodev.c 2010-11-09 20:29:09.284996310 +0100
  5954. @@ -0,0 +1,1060 @@
  5955. +/* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */
  5956. +
  5957. +/*-
  5958. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  5959. + * Copyright (C) 2006-2010 David McCullough
  5960. + * Copyright (C) 2004-2005 Intel Corporation.
  5961. + * The license and original author are listed below.
  5962. + *
  5963. + * Copyright (c) 2001 Theo de Raadt
  5964. + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
  5965. + *
  5966. + * Redistribution and use in source and binary forms, with or without
  5967. + * modification, are permitted provided that the following conditions
  5968. + * are met:
  5969. + *
  5970. + * 1. Redistributions of source code must retain the above copyright
  5971. + * notice, this list of conditions and the following disclaimer.
  5972. + * 2. Redistributions in binary form must reproduce the above copyright
  5973. + * notice, this list of conditions and the following disclaimer in the
  5974. + * documentation and/or other materials provided with the distribution.
  5975. + * 3. The name of the author may not be used to endorse or promote products
  5976. + * derived from this software without specific prior written permission.
  5977. + *
  5978. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  5979. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  5980. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  5981. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  5982. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  5983. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  5984. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  5985. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  5986. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  5987. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  5988. + *
  5989. + * Effort sponsored in part by the Defense Advanced Research Projects
  5990. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  5991. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  5992. + *
  5993. +__FBSDID("$FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.34 2007/05/09 19:37:02 gnn Exp $");
  5994. + */
  5995. +
  5996. +#ifndef AUTOCONF_INCLUDED
  5997. +#include <linux/config.h>
  5998. +#endif
  5999. +#include <linux/types.h>
  6000. +#include <linux/time.h>
  6001. +#include <linux/delay.h>
  6002. +#include <linux/list.h>
  6003. +#include <linux/init.h>
  6004. +#include <linux/sched.h>
  6005. +#include <linux/unistd.h>
  6006. +#include <linux/module.h>
  6007. +#include <linux/wait.h>
  6008. +#include <linux/slab.h>
  6009. +#include <linux/fs.h>
  6010. +#include <linux/dcache.h>
  6011. +#include <linux/file.h>
  6012. +#include <linux/mount.h>
  6013. +#include <linux/miscdevice.h>
  6014. +#include <linux/version.h>
  6015. +#include <asm/uaccess.h>
  6016. +
  6017. +#include <cryptodev.h>
  6018. +#include <uio.h>
  6019. +
  6020. +extern asmlinkage long sys_dup(unsigned int fildes);
  6021. +
  6022. +#define debug cryptodev_debug
  6023. +int cryptodev_debug = 0;
  6024. +module_param(cryptodev_debug, int, 0644);
  6025. +MODULE_PARM_DESC(cryptodev_debug, "Enable cryptodev debug");
  6026. +
  6027. +struct csession_info {
  6028. + u_int16_t blocksize;
  6029. + u_int16_t minkey, maxkey;
  6030. +
  6031. + u_int16_t keysize;
  6032. + /* u_int16_t hashsize; */
  6033. + u_int16_t authsize;
  6034. + u_int16_t authkey;
  6035. + /* u_int16_t ctxsize; */
  6036. +};
  6037. +
  6038. +struct csession {
  6039. + struct list_head list;
  6040. + u_int64_t sid;
  6041. + u_int32_t ses;
  6042. +
  6043. + wait_queue_head_t waitq;
  6044. +
  6045. + u_int32_t cipher;
  6046. +
  6047. + u_int32_t mac;
  6048. +
  6049. + caddr_t key;
  6050. + int keylen;
  6051. + u_char tmp_iv[EALG_MAX_BLOCK_LEN];
  6052. +
  6053. + caddr_t mackey;
  6054. + int mackeylen;
  6055. +
  6056. + struct csession_info info;
  6057. +
  6058. + struct iovec iovec;
  6059. + struct uio uio;
  6060. + int error;
  6061. +};
  6062. +
  6063. +struct fcrypt {
  6064. + struct list_head csessions;
  6065. + int sesn;
  6066. +};
  6067. +
  6068. +static struct csession *csefind(struct fcrypt *, u_int);
  6069. +static int csedelete(struct fcrypt *, struct csession *);
  6070. +static struct csession *cseadd(struct fcrypt *, struct csession *);
  6071. +static struct csession *csecreate(struct fcrypt *, u_int64_t,
  6072. + struct cryptoini *crie, struct cryptoini *cria, struct csession_info *);
  6073. +static int csefree(struct csession *);
  6074. +
  6075. +static int cryptodev_op(struct csession *, struct crypt_op *);
  6076. +static int cryptodev_key(struct crypt_kop *);
  6077. +static int cryptodev_find(struct crypt_find_op *);
  6078. +
  6079. +static int cryptodev_cb(void *);
  6080. +static int cryptodev_open(struct inode *inode, struct file *filp);
  6081. +
  6082. +/*
  6083. + * Check a crypto identifier to see if it requested
  6084. + * a valid crid and it's capabilities match.
  6085. + */
  6086. +static int
  6087. +checkcrid(int crid)
  6088. +{
  6089. + int hid = crid & ~(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
  6090. + int typ = crid & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
  6091. + int caps = 0;
  6092. +
  6093. + /* if the user hasn't selected a driver, then just call newsession */
  6094. + if (hid == 0 && typ != 0)
  6095. + return 0;
  6096. +
  6097. + caps = crypto_getcaps(hid);
  6098. +
  6099. + /* didn't find anything with capabilities */
  6100. + if (caps == 0) {
  6101. + dprintk("%s: hid=%x typ=%x not matched\n", __FUNCTION__, hid, typ);
  6102. + return EINVAL;
  6103. + }
  6104. +
  6105. + /* the user didn't specify SW or HW, so the driver is ok */
  6106. + if (typ == 0)
  6107. + return 0;
  6108. +
  6109. + /* if the type specified didn't match */
  6110. + if (typ != (caps & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE))) {
  6111. + dprintk("%s: hid=%x typ=%x caps=%x not matched\n", __FUNCTION__,
  6112. + hid, typ, caps);
  6113. + return EINVAL;
  6114. + }
  6115. +
  6116. + return 0;
  6117. +}
  6118. +
  6119. +static int
  6120. +cryptodev_op(struct csession *cse, struct crypt_op *cop)
  6121. +{
  6122. + struct cryptop *crp = NULL;
  6123. + struct cryptodesc *crde = NULL, *crda = NULL;
  6124. + int error = 0;
  6125. +
  6126. + dprintk("%s()\n", __FUNCTION__);
  6127. + if (cop->len > CRYPTO_MAX_DATA_LEN) {
  6128. + dprintk("%s: %d > %d\n", __FUNCTION__, cop->len, CRYPTO_MAX_DATA_LEN);
  6129. + return (E2BIG);
  6130. + }
  6131. +
  6132. + if (cse->info.blocksize && (cop->len % cse->info.blocksize) != 0) {
  6133. + dprintk("%s: blocksize=%d len=%d\n", __FUNCTION__, cse->info.blocksize,
  6134. + cop->len);
  6135. + return (EINVAL);
  6136. + }
  6137. +
  6138. + cse->uio.uio_iov = &cse->iovec;
  6139. + cse->uio.uio_iovcnt = 1;
  6140. + cse->uio.uio_offset = 0;
  6141. +#if 0
  6142. + cse->uio.uio_resid = cop->len;
  6143. + cse->uio.uio_segflg = UIO_SYSSPACE;
  6144. + cse->uio.uio_rw = UIO_WRITE;
  6145. + cse->uio.uio_td = td;
  6146. +#endif
  6147. + cse->uio.uio_iov[0].iov_len = cop->len;
  6148. + if (cse->info.authsize)
  6149. + cse->uio.uio_iov[0].iov_len += cse->info.authsize;
  6150. + cse->uio.uio_iov[0].iov_base = kmalloc(cse->uio.uio_iov[0].iov_len,
  6151. + GFP_KERNEL);
  6152. +
  6153. + if (cse->uio.uio_iov[0].iov_base == NULL) {
  6154. + dprintk("%s: iov_base kmalloc(%d) failed\n", __FUNCTION__,
  6155. + (int)cse->uio.uio_iov[0].iov_len);
  6156. + return (ENOMEM);
  6157. + }
  6158. +
  6159. + crp = crypto_getreq((cse->info.blocksize != 0) + (cse->info.authsize != 0));
  6160. + if (crp == NULL) {
  6161. + dprintk("%s: ENOMEM\n", __FUNCTION__);
  6162. + error = ENOMEM;
  6163. + goto bail;
  6164. + }
  6165. +
  6166. + if (cse->info.authsize && cse->info.blocksize) {
  6167. + if (cop->op == COP_ENCRYPT) {
  6168. + crde = crp->crp_desc;
  6169. + crda = crde->crd_next;
  6170. + } else {
  6171. + crda = crp->crp_desc;
  6172. + crde = crda->crd_next;
  6173. + }
  6174. + } else if (cse->info.authsize) {
  6175. + crda = crp->crp_desc;
  6176. + } else if (cse->info.blocksize) {
  6177. + crde = crp->crp_desc;
  6178. + } else {
  6179. + dprintk("%s: bad request\n", __FUNCTION__);
  6180. + error = EINVAL;
  6181. + goto bail;
  6182. + }
  6183. +
  6184. + if ((error = copy_from_user(cse->uio.uio_iov[0].iov_base, cop->src,
  6185. + cop->len))) {
  6186. + dprintk("%s: bad copy\n", __FUNCTION__);
  6187. + goto bail;
  6188. + }
  6189. +
  6190. + if (crda) {
  6191. + crda->crd_skip = 0;
  6192. + crda->crd_len = cop->len;
  6193. + crda->crd_inject = cop->len;
  6194. +
  6195. + crda->crd_alg = cse->mac;
  6196. + crda->crd_key = cse->mackey;
  6197. + crda->crd_klen = cse->mackeylen * 8;
  6198. + }
  6199. +
  6200. + if (crde) {
  6201. + if (cop->op == COP_ENCRYPT)
  6202. + crde->crd_flags |= CRD_F_ENCRYPT;
  6203. + else
  6204. + crde->crd_flags &= ~CRD_F_ENCRYPT;
  6205. + crde->crd_len = cop->len;
  6206. + crde->crd_inject = 0;
  6207. +
  6208. + crde->crd_alg = cse->cipher;
  6209. + crde->crd_key = cse->key;
  6210. + crde->crd_klen = cse->keylen * 8;
  6211. + }
  6212. +
  6213. + crp->crp_ilen = cse->uio.uio_iov[0].iov_len;
  6214. + crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
  6215. + | (cop->flags & COP_F_BATCH);
  6216. + crp->crp_buf = (caddr_t)&cse->uio;
  6217. + crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;
  6218. + crp->crp_sid = cse->sid;
  6219. + crp->crp_opaque = (void *)cse;
  6220. +
  6221. + if (cop->iv) {
  6222. + if (crde == NULL) {
  6223. + error = EINVAL;
  6224. + dprintk("%s no crde\n", __FUNCTION__);
  6225. + goto bail;
  6226. + }
  6227. + if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  6228. + error = EINVAL;
  6229. + dprintk("%s arc4 with IV\n", __FUNCTION__);
  6230. + goto bail;
  6231. + }
  6232. + if ((error = copy_from_user(cse->tmp_iv, cop->iv,
  6233. + cse->info.blocksize))) {
  6234. + dprintk("%s bad iv copy\n", __FUNCTION__);
  6235. + goto bail;
  6236. + }
  6237. + memcpy(crde->crd_iv, cse->tmp_iv, cse->info.blocksize);
  6238. + crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
  6239. + crde->crd_skip = 0;
  6240. + } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  6241. + crde->crd_skip = 0;
  6242. + } else if (crde) {
  6243. + crde->crd_flags |= CRD_F_IV_PRESENT;
  6244. + crde->crd_skip = cse->info.blocksize;
  6245. + crde->crd_len -= cse->info.blocksize;
  6246. + }
  6247. +
  6248. + if (cop->mac && crda == NULL) {
  6249. + error = EINVAL;
  6250. + dprintk("%s no crda\n", __FUNCTION__);
  6251. + goto bail;
  6252. + }
  6253. +
  6254. + /*
  6255. + * Let the dispatch run unlocked, then, interlock against the
  6256. + * callback before checking if the operation completed and going
  6257. + * to sleep. This insures drivers don't inherit our lock which
  6258. + * results in a lock order reversal between crypto_dispatch forced
  6259. + * entry and the crypto_done callback into us.
  6260. + */
  6261. + error = crypto_dispatch(crp);
  6262. + if (error) {
  6263. + dprintk("%s error in crypto_dispatch\n", __FUNCTION__);
  6264. + goto bail;
  6265. + }
  6266. +
  6267. + dprintk("%s about to WAIT\n", __FUNCTION__);
  6268. + /*
  6269. + * we really need to wait for driver to complete to maintain
  6270. + * state, luckily interrupts will be remembered
  6271. + */
  6272. + do {
  6273. + error = wait_event_interruptible(crp->crp_waitq,
  6274. + ((crp->crp_flags & CRYPTO_F_DONE) != 0));
  6275. + /*
  6276. + * we can't break out of this loop or we will leave behind
  6277. + * a huge mess, however, staying here means if your driver
  6278. + * is broken user applications can hang and not be killed.
  6279. + * The solution, fix your driver :-)
  6280. + */
  6281. + if (error) {
  6282. + schedule();
  6283. + error = 0;
  6284. + }
  6285. + } while ((crp->crp_flags & CRYPTO_F_DONE) == 0);
  6286. + dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
  6287. +
  6288. + if (crp->crp_etype != 0) {
  6289. + error = crp->crp_etype;
  6290. + dprintk("%s error in crp processing\n", __FUNCTION__);
  6291. + goto bail;
  6292. + }
  6293. +
  6294. + if (cse->error) {
  6295. + error = cse->error;
  6296. + dprintk("%s error in cse processing\n", __FUNCTION__);
  6297. + goto bail;
  6298. + }
  6299. +
  6300. + if (cop->dst && (error = copy_to_user(cop->dst,
  6301. + cse->uio.uio_iov[0].iov_base, cop->len))) {
  6302. + dprintk("%s bad dst copy\n", __FUNCTION__);
  6303. + goto bail;
  6304. + }
  6305. +
  6306. + if (cop->mac &&
  6307. + (error=copy_to_user(cop->mac,
  6308. + (caddr_t)cse->uio.uio_iov[0].iov_base + cop->len,
  6309. + cse->info.authsize))) {
  6310. + dprintk("%s bad mac copy\n", __FUNCTION__);
  6311. + goto bail;
  6312. + }
  6313. +
  6314. +bail:
  6315. + if (crp)
  6316. + crypto_freereq(crp);
  6317. + if (cse->uio.uio_iov[0].iov_base)
  6318. + kfree(cse->uio.uio_iov[0].iov_base);
  6319. +
  6320. + return (error);
  6321. +}
  6322. +
  6323. +static int
  6324. +cryptodev_cb(void *op)
  6325. +{
  6326. + struct cryptop *crp = (struct cryptop *) op;
  6327. + struct csession *cse = (struct csession *)crp->crp_opaque;
  6328. + int error;
  6329. +
  6330. + dprintk("%s()\n", __FUNCTION__);
  6331. + error = crp->crp_etype;
  6332. + if (error == EAGAIN) {
  6333. + crp->crp_flags &= ~CRYPTO_F_DONE;
  6334. +#ifdef NOTYET
  6335. + /*
  6336. + * DAVIDM I am fairly sure that we should turn this into a batch
  6337. + * request to stop bad karma/lockup, revisit
  6338. + */
  6339. + crp->crp_flags |= CRYPTO_F_BATCH;
  6340. +#endif
  6341. + return crypto_dispatch(crp);
  6342. + }
  6343. + if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
  6344. + cse->error = error;
  6345. + wake_up_interruptible(&crp->crp_waitq);
  6346. + }
  6347. + return (0);
  6348. +}
  6349. +
  6350. +static int
  6351. +cryptodevkey_cb(void *op)
  6352. +{
  6353. + struct cryptkop *krp = (struct cryptkop *) op;
  6354. + dprintk("%s()\n", __FUNCTION__);
  6355. + wake_up_interruptible(&krp->krp_waitq);
  6356. + return (0);
  6357. +}
  6358. +
  6359. +static int
  6360. +cryptodev_key(struct crypt_kop *kop)
  6361. +{
  6362. + struct cryptkop *krp = NULL;
  6363. + int error = EINVAL;
  6364. + int in, out, size, i;
  6365. +
  6366. + dprintk("%s()\n", __FUNCTION__);
  6367. + if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
  6368. + dprintk("%s params too big\n", __FUNCTION__);
  6369. + return (EFBIG);
  6370. + }
  6371. +
  6372. + in = kop->crk_iparams;
  6373. + out = kop->crk_oparams;
  6374. + switch (kop->crk_op) {
  6375. + case CRK_MOD_EXP:
  6376. + if (in == 3 && out == 1)
  6377. + break;
  6378. + return (EINVAL);
  6379. + case CRK_MOD_EXP_CRT:
  6380. + if (in == 6 && out == 1)
  6381. + break;
  6382. + return (EINVAL);
  6383. + case CRK_DSA_SIGN:
  6384. + if (in == 5 && out == 2)
  6385. + break;
  6386. + return (EINVAL);
  6387. + case CRK_DSA_VERIFY:
  6388. + if (in == 7 && out == 0)
  6389. + break;
  6390. + return (EINVAL);
  6391. + case CRK_DH_COMPUTE_KEY:
  6392. + if (in == 3 && out == 1)
  6393. + break;
  6394. + return (EINVAL);
  6395. + default:
  6396. + return (EINVAL);
  6397. + }
  6398. +
  6399. + krp = (struct cryptkop *)kmalloc(sizeof *krp, GFP_KERNEL);
  6400. + if (!krp)
  6401. + return (ENOMEM);
  6402. + bzero(krp, sizeof *krp);
  6403. + krp->krp_op = kop->crk_op;
  6404. + krp->krp_status = kop->crk_status;
  6405. + krp->krp_iparams = kop->crk_iparams;
  6406. + krp->krp_oparams = kop->crk_oparams;
  6407. + krp->krp_crid = kop->crk_crid;
  6408. + krp->krp_status = 0;
  6409. + krp->krp_flags = CRYPTO_KF_CBIMM;
  6410. + krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
  6411. + init_waitqueue_head(&krp->krp_waitq);
  6412. +
  6413. + for (i = 0; i < CRK_MAXPARAM; i++)
  6414. + krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
  6415. + for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
  6416. + size = (krp->krp_param[i].crp_nbits + 7) / 8;
  6417. + if (size == 0)
  6418. + continue;
  6419. + krp->krp_param[i].crp_p = (caddr_t) kmalloc(size, GFP_KERNEL);
  6420. + if (i >= krp->krp_iparams)
  6421. + continue;
  6422. + error = copy_from_user(krp->krp_param[i].crp_p,
  6423. + kop->crk_param[i].crp_p, size);
  6424. + if (error)
  6425. + goto fail;
  6426. + }
  6427. +
  6428. + error = crypto_kdispatch(krp);
  6429. + if (error)
  6430. + goto fail;
  6431. +
  6432. + do {
  6433. + error = wait_event_interruptible(krp->krp_waitq,
  6434. + ((krp->krp_flags & CRYPTO_KF_DONE) != 0));
  6435. + /*
  6436. + * we can't break out of this loop or we will leave behind
  6437. + * a huge mess, however, staying here means if your driver
  6438. + * is broken user applications can hang and not be killed.
  6439. + * The solution, fix your driver :-)
  6440. + */
  6441. + if (error) {
  6442. + schedule();
  6443. + error = 0;
  6444. + }
  6445. + } while ((krp->krp_flags & CRYPTO_KF_DONE) == 0);
  6446. +
  6447. + dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
  6448. +
  6449. + kop->crk_crid = krp->krp_crid; /* device that did the work */
  6450. + if (krp->krp_status != 0) {
  6451. + error = krp->krp_status;
  6452. + goto fail;
  6453. + }
  6454. +
  6455. + for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
  6456. + size = (krp->krp_param[i].crp_nbits + 7) / 8;
  6457. + if (size == 0)
  6458. + continue;
  6459. + error = copy_to_user(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p,
  6460. + size);
  6461. + if (error)
  6462. + goto fail;
  6463. + }
  6464. +
  6465. +fail:
  6466. + if (krp) {
  6467. + kop->crk_status = krp->krp_status;
  6468. + for (i = 0; i < CRK_MAXPARAM; i++) {
  6469. + if (krp->krp_param[i].crp_p)
  6470. + kfree(krp->krp_param[i].crp_p);
  6471. + }
  6472. + kfree(krp);
  6473. + }
  6474. + return (error);
  6475. +}
  6476. +
  6477. +static int
  6478. +cryptodev_find(struct crypt_find_op *find)
  6479. +{
  6480. + device_t dev;
  6481. +
  6482. + if (find->crid != -1) {
  6483. + dev = crypto_find_device_byhid(find->crid);
  6484. + if (dev == NULL)
  6485. + return (ENOENT);
  6486. + strlcpy(find->name, device_get_nameunit(dev),
  6487. + sizeof(find->name));
  6488. + } else {
  6489. + find->crid = crypto_find_driver(find->name);
  6490. + if (find->crid == -1)
  6491. + return (ENOENT);
  6492. + }
  6493. + return (0);
  6494. +}
  6495. +
  6496. +static struct csession *
  6497. +csefind(struct fcrypt *fcr, u_int ses)
  6498. +{
  6499. + struct csession *cse;
  6500. +
  6501. + dprintk("%s()\n", __FUNCTION__);
  6502. + list_for_each_entry(cse, &fcr->csessions, list)
  6503. + if (cse->ses == ses)
  6504. + return (cse);
  6505. + return (NULL);
  6506. +}
  6507. +
  6508. +static int
  6509. +csedelete(struct fcrypt *fcr, struct csession *cse_del)
  6510. +{
  6511. + struct csession *cse;
  6512. +
  6513. + dprintk("%s()\n", __FUNCTION__);
  6514. + list_for_each_entry(cse, &fcr->csessions, list) {
  6515. + if (cse == cse_del) {
  6516. + list_del(&cse->list);
  6517. + return (1);
  6518. + }
  6519. + }
  6520. + return (0);
  6521. +}
  6522. +
  6523. +static struct csession *
  6524. +cseadd(struct fcrypt *fcr, struct csession *cse)
  6525. +{
  6526. + dprintk("%s()\n", __FUNCTION__);
  6527. + list_add_tail(&cse->list, &fcr->csessions);
  6528. + cse->ses = fcr->sesn++;
  6529. + return (cse);
  6530. +}
  6531. +
  6532. +static struct csession *
  6533. +csecreate(struct fcrypt *fcr, u_int64_t sid, struct cryptoini *crie,
  6534. + struct cryptoini *cria, struct csession_info *info)
  6535. +{
  6536. + struct csession *cse;
  6537. +
  6538. + dprintk("%s()\n", __FUNCTION__);
  6539. + cse = (struct csession *) kmalloc(sizeof(struct csession), GFP_KERNEL);
  6540. + if (cse == NULL)
  6541. + return NULL;
  6542. + memset(cse, 0, sizeof(struct csession));
  6543. +
  6544. + INIT_LIST_HEAD(&cse->list);
  6545. + init_waitqueue_head(&cse->waitq);
  6546. +
  6547. + cse->key = crie->cri_key;
  6548. + cse->keylen = crie->cri_klen/8;
  6549. + cse->mackey = cria->cri_key;
  6550. + cse->mackeylen = cria->cri_klen/8;
  6551. + cse->sid = sid;
  6552. + cse->cipher = crie->cri_alg;
  6553. + cse->mac = cria->cri_alg;
  6554. + cse->info = *info;
  6555. + cseadd(fcr, cse);
  6556. + return (cse);
  6557. +}
  6558. +
  6559. +static int
  6560. +csefree(struct csession *cse)
  6561. +{
  6562. + int error;
  6563. +
  6564. + dprintk("%s()\n", __FUNCTION__);
  6565. + error = crypto_freesession(cse->sid);
  6566. + if (cse->key)
  6567. + kfree(cse->key);
  6568. + if (cse->mackey)
  6569. + kfree(cse->mackey);
  6570. + kfree(cse);
  6571. + return(error);
  6572. +}
  6573. +
  6574. +static int
  6575. +cryptodev_ioctl(
  6576. + struct inode *inode,
  6577. + struct file *filp,
  6578. + unsigned int cmd,
  6579. + unsigned long arg)
  6580. +{
  6581. + struct cryptoini cria, crie;
  6582. + struct fcrypt *fcr = filp->private_data;
  6583. + struct csession *cse;
  6584. + struct csession_info info;
  6585. + struct session2_op sop;
  6586. + struct crypt_op cop;
  6587. + struct crypt_kop kop;
  6588. + struct crypt_find_op fop;
  6589. + u_int64_t sid;
  6590. + u_int32_t ses = 0;
  6591. + int feat, fd, error = 0, crid;
  6592. + mm_segment_t fs;
  6593. +
  6594. + dprintk("%s(cmd=%x arg=%lx)\n", __FUNCTION__, cmd, arg);
  6595. +
  6596. + switch (cmd) {
  6597. +
  6598. + case CRIOGET: {
  6599. + dprintk("%s(CRIOGET)\n", __FUNCTION__);
  6600. + fs = get_fs();
  6601. + set_fs(get_ds());
  6602. + for (fd = 0; fd < files_fdtable(current->files)->max_fds; fd++)
  6603. + if (files_fdtable(current->files)->fd[fd] == filp)
  6604. + break;
  6605. + fd = sys_dup(fd);
  6606. + set_fs(fs);
  6607. + put_user(fd, (int *) arg);
  6608. + return IS_ERR_VALUE(fd) ? fd : 0;
  6609. + }
  6610. +
  6611. +#define CIOCGSESSSTR (cmd == CIOCGSESSION ? "CIOCGSESSION" : "CIOCGSESSION2")
  6612. + case CIOCGSESSION:
  6613. + case CIOCGSESSION2:
  6614. + dprintk("%s(%s)\n", __FUNCTION__, CIOCGSESSSTR);
  6615. + memset(&crie, 0, sizeof(crie));
  6616. + memset(&cria, 0, sizeof(cria));
  6617. + memset(&info, 0, sizeof(info));
  6618. + memset(&sop, 0, sizeof(sop));
  6619. +
  6620. + if (copy_from_user(&sop, (void*)arg, (cmd == CIOCGSESSION) ?
  6621. + sizeof(struct session_op) : sizeof(sop))) {
  6622. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  6623. + error = EFAULT;
  6624. + goto bail;
  6625. + }
  6626. +
  6627. + switch (sop.cipher) {
  6628. + case 0:
  6629. + dprintk("%s(%s) - no cipher\n", __FUNCTION__, CIOCGSESSSTR);
  6630. + break;
  6631. + case CRYPTO_NULL_CBC:
  6632. + info.blocksize = NULL_BLOCK_LEN;
  6633. + info.minkey = NULL_MIN_KEY_LEN;
  6634. + info.maxkey = NULL_MAX_KEY_LEN;
  6635. + break;
  6636. + case CRYPTO_DES_CBC:
  6637. + info.blocksize = DES_BLOCK_LEN;
  6638. + info.minkey = DES_MIN_KEY_LEN;
  6639. + info.maxkey = DES_MAX_KEY_LEN;
  6640. + break;
  6641. + case CRYPTO_3DES_CBC:
  6642. + info.blocksize = DES3_BLOCK_LEN;
  6643. + info.minkey = DES3_MIN_KEY_LEN;
  6644. + info.maxkey = DES3_MAX_KEY_LEN;
  6645. + break;
  6646. + case CRYPTO_BLF_CBC:
  6647. + info.blocksize = BLOWFISH_BLOCK_LEN;
  6648. + info.minkey = BLOWFISH_MIN_KEY_LEN;
  6649. + info.maxkey = BLOWFISH_MAX_KEY_LEN;
  6650. + break;
  6651. + case CRYPTO_CAST_CBC:
  6652. + info.blocksize = CAST128_BLOCK_LEN;
  6653. + info.minkey = CAST128_MIN_KEY_LEN;
  6654. + info.maxkey = CAST128_MAX_KEY_LEN;
  6655. + break;
  6656. + case CRYPTO_SKIPJACK_CBC:
  6657. + info.blocksize = SKIPJACK_BLOCK_LEN;
  6658. + info.minkey = SKIPJACK_MIN_KEY_LEN;
  6659. + info.maxkey = SKIPJACK_MAX_KEY_LEN;
  6660. + break;
  6661. + case CRYPTO_AES_CBC:
  6662. + info.blocksize = AES_BLOCK_LEN;
  6663. + info.minkey = AES_MIN_KEY_LEN;
  6664. + info.maxkey = AES_MAX_KEY_LEN;
  6665. + break;
  6666. + case CRYPTO_ARC4:
  6667. + info.blocksize = ARC4_BLOCK_LEN;
  6668. + info.minkey = ARC4_MIN_KEY_LEN;
  6669. + info.maxkey = ARC4_MAX_KEY_LEN;
  6670. + break;
  6671. + case CRYPTO_CAMELLIA_CBC:
  6672. + info.blocksize = CAMELLIA_BLOCK_LEN;
  6673. + info.minkey = CAMELLIA_MIN_KEY_LEN;
  6674. + info.maxkey = CAMELLIA_MAX_KEY_LEN;
  6675. + break;
  6676. + default:
  6677. + dprintk("%s(%s) - bad cipher\n", __FUNCTION__, CIOCGSESSSTR);
  6678. + error = EINVAL;
  6679. + goto bail;
  6680. + }
  6681. +
  6682. + switch (sop.mac) {
  6683. + case 0:
  6684. + dprintk("%s(%s) - no mac\n", __FUNCTION__, CIOCGSESSSTR);
  6685. + break;
  6686. + case CRYPTO_NULL_HMAC:
  6687. + info.authsize = NULL_HASH_LEN;
  6688. + break;
  6689. + case CRYPTO_MD5:
  6690. + info.authsize = MD5_HASH_LEN;
  6691. + break;
  6692. + case CRYPTO_SHA1:
  6693. + info.authsize = SHA1_HASH_LEN;
  6694. + break;
  6695. + case CRYPTO_SHA2_256:
  6696. + info.authsize = SHA2_256_HASH_LEN;
  6697. + break;
  6698. + case CRYPTO_SHA2_384:
  6699. + info.authsize = SHA2_384_HASH_LEN;
  6700. + break;
  6701. + case CRYPTO_SHA2_512:
  6702. + info.authsize = SHA2_512_HASH_LEN;
  6703. + break;
  6704. + case CRYPTO_RIPEMD160:
  6705. + info.authsize = RIPEMD160_HASH_LEN;
  6706. + break;
  6707. + case CRYPTO_MD5_HMAC:
  6708. + info.authsize = MD5_HASH_LEN;
  6709. + info.authkey = 16;
  6710. + break;
  6711. + case CRYPTO_SHA1_HMAC:
  6712. + info.authsize = SHA1_HASH_LEN;
  6713. + info.authkey = 20;
  6714. + break;
  6715. + case CRYPTO_SHA2_256_HMAC:
  6716. + info.authsize = SHA2_256_HASH_LEN;
  6717. + info.authkey = 32;
  6718. + break;
  6719. + case CRYPTO_SHA2_384_HMAC:
  6720. + info.authsize = SHA2_384_HASH_LEN;
  6721. + info.authkey = 48;
  6722. + break;
  6723. + case CRYPTO_SHA2_512_HMAC:
  6724. + info.authsize = SHA2_512_HASH_LEN;
  6725. + info.authkey = 64;
  6726. + break;
  6727. + case CRYPTO_RIPEMD160_HMAC:
  6728. + info.authsize = RIPEMD160_HASH_LEN;
  6729. + info.authkey = 20;
  6730. + break;
  6731. + default:
  6732. + dprintk("%s(%s) - bad mac\n", __FUNCTION__, CIOCGSESSSTR);
  6733. + error = EINVAL;
  6734. + goto bail;
  6735. + }
  6736. +
  6737. + if (info.blocksize) {
  6738. + crie.cri_alg = sop.cipher;
  6739. + crie.cri_klen = sop.keylen * 8;
  6740. + if ((info.maxkey && sop.keylen > info.maxkey) ||
  6741. + sop.keylen < info.minkey) {
  6742. + dprintk("%s(%s) - bad key\n", __FUNCTION__, CIOCGSESSSTR);
  6743. + error = EINVAL;
  6744. + goto bail;
  6745. + }
  6746. +
  6747. + crie.cri_key = (u_int8_t *) kmalloc(crie.cri_klen/8+1, GFP_KERNEL);
  6748. + if (copy_from_user(crie.cri_key, sop.key,
  6749. + crie.cri_klen/8)) {
  6750. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  6751. + error = EFAULT;
  6752. + goto bail;
  6753. + }
  6754. + if (info.authsize)
  6755. + crie.cri_next = &cria;
  6756. + }
  6757. +
  6758. + if (info.authsize) {
  6759. + cria.cri_alg = sop.mac;
  6760. + cria.cri_klen = sop.mackeylen * 8;
  6761. + if (info.authkey && sop.mackeylen != info.authkey) {
  6762. + dprintk("%s(%s) - mackeylen %d != %d\n", __FUNCTION__,
  6763. + CIOCGSESSSTR, sop.mackeylen, info.authkey);
  6764. + error = EINVAL;
  6765. + goto bail;
  6766. + }
  6767. +
  6768. + if (cria.cri_klen) {
  6769. + cria.cri_key = (u_int8_t *) kmalloc(cria.cri_klen/8,GFP_KERNEL);
  6770. + if (copy_from_user(cria.cri_key, sop.mackey,
  6771. + cria.cri_klen / 8)) {
  6772. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  6773. + error = EFAULT;
  6774. + goto bail;
  6775. + }
  6776. + }
  6777. + }
  6778. +
  6779. + /* NB: CIOGSESSION2 has the crid */
  6780. + if (cmd == CIOCGSESSION2) {
  6781. + crid = sop.crid;
  6782. + error = checkcrid(crid);
  6783. + if (error) {
  6784. + dprintk("%s(%s) - checkcrid %x\n", __FUNCTION__,
  6785. + CIOCGSESSSTR, error);
  6786. + goto bail;
  6787. + }
  6788. + } else {
  6789. + /* allow either HW or SW to be used */
  6790. + crid = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
  6791. + }
  6792. + error = crypto_newsession(&sid, (info.blocksize ? &crie : &cria), crid);
  6793. + if (error) {
  6794. + dprintk("%s(%s) - newsession %d\n",__FUNCTION__,CIOCGSESSSTR,error);
  6795. + goto bail;
  6796. + }
  6797. +
  6798. + cse = csecreate(fcr, sid, &crie, &cria, &info);
  6799. + if (cse == NULL) {
  6800. + crypto_freesession(sid);
  6801. + error = EINVAL;
  6802. + dprintk("%s(%s) - csecreate failed\n", __FUNCTION__, CIOCGSESSSTR);
  6803. + goto bail;
  6804. + }
  6805. + sop.ses = cse->ses;
  6806. +
  6807. + if (cmd == CIOCGSESSION2) {
  6808. + /* return hardware/driver id */
  6809. + sop.crid = CRYPTO_SESID2HID(cse->sid);
  6810. + }
  6811. +
  6812. + if (copy_to_user((void*)arg, &sop, (cmd == CIOCGSESSION) ?
  6813. + sizeof(struct session_op) : sizeof(sop))) {
  6814. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  6815. + error = EFAULT;
  6816. + }
  6817. +bail:
  6818. + if (error) {
  6819. + dprintk("%s(%s) - bail %d\n", __FUNCTION__, CIOCGSESSSTR, error);
  6820. + if (crie.cri_key)
  6821. + kfree(crie.cri_key);
  6822. + if (cria.cri_key)
  6823. + kfree(cria.cri_key);
  6824. + }
  6825. + break;
  6826. + case CIOCFSESSION:
  6827. + dprintk("%s(CIOCFSESSION)\n", __FUNCTION__);
  6828. + get_user(ses, (uint32_t*)arg);
  6829. + cse = csefind(fcr, ses);
  6830. + if (cse == NULL) {
  6831. + error = EINVAL;
  6832. + dprintk("%s(CIOCFSESSION) - Fail %d\n", __FUNCTION__, error);
  6833. + break;
  6834. + }
  6835. + csedelete(fcr, cse);
  6836. + error = csefree(cse);
  6837. + break;
  6838. + case CIOCCRYPT:
  6839. + dprintk("%s(CIOCCRYPT)\n", __FUNCTION__);
  6840. + if(copy_from_user(&cop, (void*)arg, sizeof(cop))) {
  6841. + dprintk("%s(CIOCCRYPT) - bad copy\n", __FUNCTION__);
  6842. + error = EFAULT;
  6843. + goto bail;
  6844. + }
  6845. + cse = csefind(fcr, cop.ses);
  6846. + if (cse == NULL) {
  6847. + error = EINVAL;
  6848. + dprintk("%s(CIOCCRYPT) - Fail %d\n", __FUNCTION__, error);
  6849. + break;
  6850. + }
  6851. + error = cryptodev_op(cse, &cop);
  6852. + if(copy_to_user((void*)arg, &cop, sizeof(cop))) {
  6853. + dprintk("%s(CIOCCRYPT) - bad return copy\n", __FUNCTION__);
  6854. + error = EFAULT;
  6855. + goto bail;
  6856. + }
  6857. + break;
  6858. + case CIOCKEY:
  6859. + case CIOCKEY2:
  6860. + dprintk("%s(CIOCKEY)\n", __FUNCTION__);
  6861. + if (!crypto_userasymcrypto)
  6862. + return (EPERM); /* XXX compat? */
  6863. + if(copy_from_user(&kop, (void*)arg, sizeof(kop))) {
  6864. + dprintk("%s(CIOCKEY) - bad copy\n", __FUNCTION__);
  6865. + error = EFAULT;
  6866. + goto bail;
  6867. + }
  6868. + if (cmd == CIOCKEY) {
  6869. + /* NB: crypto core enforces s/w driver use */
  6870. + kop.crk_crid =
  6871. + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
  6872. + }
  6873. + error = cryptodev_key(&kop);
  6874. + if(copy_to_user((void*)arg, &kop, sizeof(kop))) {
  6875. + dprintk("%s(CIOCGKEY) - bad return copy\n", __FUNCTION__);
  6876. + error = EFAULT;
  6877. + goto bail;
  6878. + }
  6879. + break;
  6880. + case CIOCASYMFEAT:
  6881. + dprintk("%s(CIOCASYMFEAT)\n", __FUNCTION__);
  6882. + if (!crypto_userasymcrypto) {
  6883. + /*
  6884. + * NB: if user asym crypto operations are
  6885. + * not permitted return "no algorithms"
  6886. + * so well-behaved applications will just
  6887. + * fallback to doing them in software.
  6888. + */
  6889. + feat = 0;
  6890. + } else
  6891. + error = crypto_getfeat(&feat);
  6892. + if (!error) {
  6893. + error = copy_to_user((void*)arg, &feat, sizeof(feat));
  6894. + }
  6895. + break;
  6896. + case CIOCFINDDEV:
  6897. + if (copy_from_user(&fop, (void*)arg, sizeof(fop))) {
  6898. + dprintk("%s(CIOCFINDDEV) - bad copy\n", __FUNCTION__);
  6899. + error = EFAULT;
  6900. + goto bail;
  6901. + }
  6902. + error = cryptodev_find(&fop);
  6903. + if (copy_to_user((void*)arg, &fop, sizeof(fop))) {
  6904. + dprintk("%s(CIOCFINDDEV) - bad return copy\n", __FUNCTION__);
  6905. + error = EFAULT;
  6906. + goto bail;
  6907. + }
  6908. + break;
  6909. + default:
  6910. + dprintk("%s(unknown ioctl 0x%x)\n", __FUNCTION__, cmd);
  6911. + error = EINVAL;
  6912. + break;
  6913. + }
  6914. + return(-error);
  6915. +}
  6916. +
  6917. +#ifdef HAVE_UNLOCKED_IOCTL
  6918. +static long
  6919. +cryptodev_unlocked_ioctl(
  6920. + struct file *filp,
  6921. + unsigned int cmd,
  6922. + unsigned long arg)
  6923. +{
  6924. + return cryptodev_ioctl(NULL, filp, cmd, arg);
  6925. +}
  6926. +#endif
  6927. +
  6928. +static int
  6929. +cryptodev_open(struct inode *inode, struct file *filp)
  6930. +{
  6931. + struct fcrypt *fcr;
  6932. +
  6933. + dprintk("%s()\n", __FUNCTION__);
  6934. + if (filp->private_data) {
  6935. + printk("cryptodev: Private data already exists !\n");
  6936. + return(0);
  6937. + }
  6938. +
  6939. + fcr = kmalloc(sizeof(*fcr), GFP_KERNEL);
  6940. + if (!fcr) {
  6941. + dprintk("%s() - malloc failed\n", __FUNCTION__);
  6942. + return(-ENOMEM);
  6943. + }
  6944. + memset(fcr, 0, sizeof(*fcr));
  6945. +
  6946. + INIT_LIST_HEAD(&fcr->csessions);
  6947. + filp->private_data = fcr;
  6948. + return(0);
  6949. +}
  6950. +
  6951. +static int
  6952. +cryptodev_release(struct inode *inode, struct file *filp)
  6953. +{
  6954. + struct fcrypt *fcr = filp->private_data;
  6955. + struct csession *cse, *tmp;
  6956. +
  6957. + dprintk("%s()\n", __FUNCTION__);
  6958. + if (!filp) {
  6959. + printk("cryptodev: No private data on release\n");
  6960. + return(0);
  6961. + }
  6962. +
  6963. + list_for_each_entry_safe(cse, tmp, &fcr->csessions, list) {
  6964. + list_del(&cse->list);
  6965. + (void)csefree(cse);
  6966. + }
  6967. + filp->private_data = NULL;
  6968. + kfree(fcr);
  6969. + return(0);
  6970. +}
  6971. +
  6972. +static struct file_operations cryptodev_fops = {
  6973. + .owner = THIS_MODULE,
  6974. + .open = cryptodev_open,
  6975. + .release = cryptodev_release,
  6976. +#ifdef HAVE_UNLOCKED_IOCTL
  6977. + .unlocked_ioctl = cryptodev_unlocked_ioctl,
  6978. +#endif
  6979. +};
  6980. +
  6981. +static struct miscdevice cryptodev = {
  6982. + .minor = CRYPTODEV_MINOR,
  6983. + .name = "crypto",
  6984. + .fops = &cryptodev_fops,
  6985. +};
  6986. +
  6987. +static int __init
  6988. +cryptodev_init(void)
  6989. +{
  6990. + int rc;
  6991. +
  6992. + dprintk("%s(%p)\n", __FUNCTION__, cryptodev_init);
  6993. + rc = misc_register(&cryptodev);
  6994. + if (rc) {
  6995. + printk(KERN_ERR "cryptodev: registration of /dev/crypto failed\n");
  6996. + return(rc);
  6997. + }
  6998. +
  6999. + return(0);
  7000. +}
  7001. +
  7002. +static void __exit
  7003. +cryptodev_exit(void)
  7004. +{
  7005. + dprintk("%s()\n", __FUNCTION__);
  7006. + misc_deregister(&cryptodev);
  7007. +}
  7008. +
  7009. +module_init(cryptodev_init);
  7010. +module_exit(cryptodev_exit);
  7011. +
  7012. +MODULE_LICENSE("BSD");
  7013. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  7014. +MODULE_DESCRIPTION("Cryptodev (user interface to OCF)");
  7015. diff -Nur linux-2.6.36.orig/crypto/ocf/cryptodev.h linux-2.6.36/crypto/ocf/cryptodev.h
  7016. --- linux-2.6.36.orig/crypto/ocf/cryptodev.h 1970-01-01 01:00:00.000000000 +0100
  7017. +++ linux-2.6.36/crypto/ocf/cryptodev.h 2010-11-09 20:28:04.492495480 +0100
  7018. @@ -0,0 +1,479 @@
  7019. +/* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.25 2007/05/09 19:37:02 gnn Exp $ */
  7020. +/* $OpenBSD: cryptodev.h,v 1.31 2002/06/11 11:14:29 beck Exp $ */
  7021. +
  7022. +/*-
  7023. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  7024. + * Copyright (C) 2006-2010 David McCullough
  7025. + * Copyright (C) 2004-2005 Intel Corporation.
  7026. + * The license and original author are listed below.
  7027. + *
  7028. + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
  7029. + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
  7030. + *
  7031. + * This code was written by Angelos D. Keromytis in Athens, Greece, in
  7032. + * February 2000. Network Security Technologies Inc. (NSTI) kindly
  7033. + * supported the development of this code.
  7034. + *
  7035. + * Copyright (c) 2000 Angelos D. Keromytis
  7036. + *
  7037. + * Permission to use, copy, and modify this software with or without fee
  7038. + * is hereby granted, provided that this entire notice is included in
  7039. + * all source code copies of any software which is or includes a copy or
  7040. + * modification of this software.
  7041. + *
  7042. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
  7043. + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
  7044. + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
  7045. + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
  7046. + * PURPOSE.
  7047. + *
  7048. + * Copyright (c) 2001 Theo de Raadt
  7049. + *
  7050. + * Redistribution and use in source and binary forms, with or without
  7051. + * modification, are permitted provided that the following conditions
  7052. + * are met:
  7053. + *
  7054. + * 1. Redistributions of source code must retain the above copyright
  7055. + * notice, this list of conditions and the following disclaimer.
  7056. + * 2. Redistributions in binary form must reproduce the above copyright
  7057. + * notice, this list of conditions and the following disclaimer in the
  7058. + * documentation and/or other materials provided with the distribution.
  7059. + * 3. The name of the author may not be used to endorse or promote products
  7060. + * derived from this software without specific prior written permission.
  7061. + *
  7062. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  7063. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  7064. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  7065. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  7066. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  7067. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  7068. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  7069. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  7070. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  7071. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  7072. + *
  7073. + * Effort sponsored in part by the Defense Advanced Research Projects
  7074. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  7075. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  7076. + *
  7077. + */
  7078. +
  7079. +#ifndef _CRYPTO_CRYPTO_H_
  7080. +#define _CRYPTO_CRYPTO_H_
  7081. +
  7082. +/* Some initial values */
  7083. +#define CRYPTO_DRIVERS_INITIAL 4
  7084. +#define CRYPTO_SW_SESSIONS 32
  7085. +
  7086. +/* Hash values */
  7087. +#define NULL_HASH_LEN 0
  7088. +#define MD5_HASH_LEN 16
  7089. +#define SHA1_HASH_LEN 20
  7090. +#define RIPEMD160_HASH_LEN 20
  7091. +#define SHA2_256_HASH_LEN 32
  7092. +#define SHA2_384_HASH_LEN 48
  7093. +#define SHA2_512_HASH_LEN 64
  7094. +#define MD5_KPDK_HASH_LEN 16
  7095. +#define SHA1_KPDK_HASH_LEN 20
  7096. +/* Maximum hash algorithm result length */
  7097. +#define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */
  7098. +
  7099. +/* HMAC values */
  7100. +#define NULL_HMAC_BLOCK_LEN 1
  7101. +#define MD5_HMAC_BLOCK_LEN 64
  7102. +#define SHA1_HMAC_BLOCK_LEN 64
  7103. +#define RIPEMD160_HMAC_BLOCK_LEN 64
  7104. +#define SHA2_256_HMAC_BLOCK_LEN 64
  7105. +#define SHA2_384_HMAC_BLOCK_LEN 128
  7106. +#define SHA2_512_HMAC_BLOCK_LEN 128
  7107. +/* Maximum HMAC block length */
  7108. +#define HMAC_MAX_BLOCK_LEN SHA2_512_HMAC_BLOCK_LEN /* Keep this updated */
  7109. +#define HMAC_IPAD_VAL 0x36
  7110. +#define HMAC_OPAD_VAL 0x5C
  7111. +
  7112. +/* Encryption algorithm block sizes */
  7113. +#define NULL_BLOCK_LEN 1
  7114. +#define DES_BLOCK_LEN 8
  7115. +#define DES3_BLOCK_LEN 8
  7116. +#define BLOWFISH_BLOCK_LEN 8
  7117. +#define SKIPJACK_BLOCK_LEN 8
  7118. +#define CAST128_BLOCK_LEN 8
  7119. +#define RIJNDAEL128_BLOCK_LEN 16
  7120. +#define AES_BLOCK_LEN RIJNDAEL128_BLOCK_LEN
  7121. +#define CAMELLIA_BLOCK_LEN 16
  7122. +#define ARC4_BLOCK_LEN 1
  7123. +#define EALG_MAX_BLOCK_LEN AES_BLOCK_LEN /* Keep this updated */
  7124. +
  7125. +/* Encryption algorithm min and max key sizes */
  7126. +#define NULL_MIN_KEY_LEN 0
  7127. +#define NULL_MAX_KEY_LEN 0
  7128. +#define DES_MIN_KEY_LEN 8
  7129. +#define DES_MAX_KEY_LEN 8
  7130. +#define DES3_MIN_KEY_LEN 24
  7131. +#define DES3_MAX_KEY_LEN 24
  7132. +#define BLOWFISH_MIN_KEY_LEN 4
  7133. +#define BLOWFISH_MAX_KEY_LEN 56
  7134. +#define SKIPJACK_MIN_KEY_LEN 10
  7135. +#define SKIPJACK_MAX_KEY_LEN 10
  7136. +#define CAST128_MIN_KEY_LEN 5
  7137. +#define CAST128_MAX_KEY_LEN 16
  7138. +#define RIJNDAEL128_MIN_KEY_LEN 16
  7139. +#define RIJNDAEL128_MAX_KEY_LEN 32
  7140. +#define AES_MIN_KEY_LEN RIJNDAEL128_MIN_KEY_LEN
  7141. +#define AES_MAX_KEY_LEN RIJNDAEL128_MAX_KEY_LEN
  7142. +#define CAMELLIA_MIN_KEY_LEN 16
  7143. +#define CAMELLIA_MAX_KEY_LEN 32
  7144. +#define ARC4_MIN_KEY_LEN 1
  7145. +#define ARC4_MAX_KEY_LEN 256
  7146. +
  7147. +/* Max size of data that can be processed */
  7148. +#define CRYPTO_MAX_DATA_LEN 64*1024 - 1
  7149. +
  7150. +#define CRYPTO_ALGORITHM_MIN 1
  7151. +#define CRYPTO_DES_CBC 1
  7152. +#define CRYPTO_3DES_CBC 2
  7153. +#define CRYPTO_BLF_CBC 3
  7154. +#define CRYPTO_CAST_CBC 4
  7155. +#define CRYPTO_SKIPJACK_CBC 5
  7156. +#define CRYPTO_MD5_HMAC 6
  7157. +#define CRYPTO_SHA1_HMAC 7
  7158. +#define CRYPTO_RIPEMD160_HMAC 8
  7159. +#define CRYPTO_MD5_KPDK 9
  7160. +#define CRYPTO_SHA1_KPDK 10
  7161. +#define CRYPTO_RIJNDAEL128_CBC 11 /* 128 bit blocksize */
  7162. +#define CRYPTO_AES_CBC 11 /* 128 bit blocksize -- the same as above */
  7163. +#define CRYPTO_ARC4 12
  7164. +#define CRYPTO_MD5 13
  7165. +#define CRYPTO_SHA1 14
  7166. +#define CRYPTO_NULL_HMAC 15
  7167. +#define CRYPTO_NULL_CBC 16
  7168. +#define CRYPTO_DEFLATE_COMP 17 /* Deflate compression algorithm */
  7169. +#define CRYPTO_SHA2_256_HMAC 18
  7170. +#define CRYPTO_SHA2_384_HMAC 19
  7171. +#define CRYPTO_SHA2_512_HMAC 20
  7172. +#define CRYPTO_CAMELLIA_CBC 21
  7173. +#define CRYPTO_SHA2_256 22
  7174. +#define CRYPTO_SHA2_384 23
  7175. +#define CRYPTO_SHA2_512 24
  7176. +#define CRYPTO_RIPEMD160 25
  7177. +#define CRYPTO_ALGORITHM_MAX 25 /* Keep updated - see below */
  7178. +
  7179. +/* Algorithm flags */
  7180. +#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
  7181. +#define CRYPTO_ALG_FLAG_RNG_ENABLE 0x02 /* Has HW RNG for DH/DSA */
  7182. +#define CRYPTO_ALG_FLAG_DSA_SHA 0x04 /* Can do SHA on msg */
  7183. +
  7184. +/*
  7185. + * Crypto driver/device flags. They can set in the crid
  7186. + * parameter when creating a session or submitting a key
  7187. + * op to affect the device/driver assigned. If neither
  7188. + * of these are specified then the crid is assumed to hold
  7189. + * the driver id of an existing (and suitable) device that
  7190. + * must be used to satisfy the request.
  7191. + */
  7192. +#define CRYPTO_FLAG_HARDWARE 0x01000000 /* hardware accelerated */
  7193. +#define CRYPTO_FLAG_SOFTWARE 0x02000000 /* software implementation */
  7194. +
  7195. +/* NB: deprecated */
  7196. +struct session_op {
  7197. + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
  7198. + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
  7199. +
  7200. + u_int32_t keylen; /* cipher key */
  7201. + caddr_t key;
  7202. + int mackeylen; /* mac key */
  7203. + caddr_t mackey;
  7204. +
  7205. + u_int32_t ses; /* returns: session # */
  7206. +};
  7207. +
  7208. +struct session2_op {
  7209. + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
  7210. + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
  7211. +
  7212. + u_int32_t keylen; /* cipher key */
  7213. + caddr_t key;
  7214. + int mackeylen; /* mac key */
  7215. + caddr_t mackey;
  7216. +
  7217. + u_int32_t ses; /* returns: session # */
  7218. + int crid; /* driver id + flags (rw) */
  7219. + int pad[4]; /* for future expansion */
  7220. +};
  7221. +
  7222. +struct crypt_op {
  7223. + u_int32_t ses;
  7224. + u_int16_t op; /* i.e. COP_ENCRYPT */
  7225. +#define COP_NONE 0
  7226. +#define COP_ENCRYPT 1
  7227. +#define COP_DECRYPT 2
  7228. + u_int16_t flags;
  7229. +#define COP_F_BATCH 0x0008 /* Batch op if possible */
  7230. + u_int len;
  7231. + caddr_t src, dst; /* become iov[] inside kernel */
  7232. + caddr_t mac; /* must be big enough for chosen MAC */
  7233. + caddr_t iv;
  7234. +};
  7235. +
  7236. +/*
  7237. + * Parameters for looking up a crypto driver/device by
  7238. + * device name or by id. The latter are returned for
  7239. + * created sessions (crid) and completed key operations.
  7240. + */
  7241. +struct crypt_find_op {
  7242. + int crid; /* driver id + flags */
  7243. + char name[32]; /* device/driver name */
  7244. +};
  7245. +
  7246. +/* bignum parameter, in packed bytes, ... */
  7247. +struct crparam {
  7248. + caddr_t crp_p;
  7249. + u_int crp_nbits;
  7250. +};
  7251. +
  7252. +#define CRK_MAXPARAM 8
  7253. +
  7254. +struct crypt_kop {
  7255. + u_int crk_op; /* ie. CRK_MOD_EXP or other */
  7256. + u_int crk_status; /* return status */
  7257. + u_short crk_iparams; /* # of input parameters */
  7258. + u_short crk_oparams; /* # of output parameters */
  7259. + u_int crk_crid; /* NB: only used by CIOCKEY2 (rw) */
  7260. + struct crparam crk_param[CRK_MAXPARAM];
  7261. +};
  7262. +#define CRK_ALGORITM_MIN 0
  7263. +#define CRK_MOD_EXP 0
  7264. +#define CRK_MOD_EXP_CRT 1
  7265. +#define CRK_DSA_SIGN 2
  7266. +#define CRK_DSA_VERIFY 3
  7267. +#define CRK_DH_COMPUTE_KEY 4
  7268. +#define CRK_ALGORITHM_MAX 4 /* Keep updated - see below */
  7269. +
  7270. +#define CRF_MOD_EXP (1 << CRK_MOD_EXP)
  7271. +#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT)
  7272. +#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN)
  7273. +#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY)
  7274. +#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
  7275. +
  7276. +/*
  7277. + * done against open of /dev/crypto, to get a cloned descriptor.
  7278. + * Please use F_SETFD against the cloned descriptor.
  7279. + */
  7280. +#define CRIOGET _IOWR('c', 100, u_int32_t)
  7281. +#define CRIOASYMFEAT CIOCASYMFEAT
  7282. +#define CRIOFINDDEV CIOCFINDDEV
  7283. +
  7284. +/* the following are done against the cloned descriptor */
  7285. +#define CIOCGSESSION _IOWR('c', 101, struct session_op)
  7286. +#define CIOCFSESSION _IOW('c', 102, u_int32_t)
  7287. +#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
  7288. +#define CIOCKEY _IOWR('c', 104, struct crypt_kop)
  7289. +#define CIOCASYMFEAT _IOR('c', 105, u_int32_t)
  7290. +#define CIOCGSESSION2 _IOWR('c', 106, struct session2_op)
  7291. +#define CIOCKEY2 _IOWR('c', 107, struct crypt_kop)
  7292. +#define CIOCFINDDEV _IOWR('c', 108, struct crypt_find_op)
  7293. +
  7294. +struct cryptotstat {
  7295. + struct timespec acc; /* total accumulated time */
  7296. + struct timespec min; /* min time */
  7297. + struct timespec max; /* max time */
  7298. + u_int32_t count; /* number of observations */
  7299. +};
  7300. +
  7301. +struct cryptostats {
  7302. + u_int32_t cs_ops; /* symmetric crypto ops submitted */
  7303. + u_int32_t cs_errs; /* symmetric crypto ops that failed */
  7304. + u_int32_t cs_kops; /* asymetric/key ops submitted */
  7305. + u_int32_t cs_kerrs; /* asymetric/key ops that failed */
  7306. + u_int32_t cs_intrs; /* crypto swi thread activations */
  7307. + u_int32_t cs_rets; /* crypto return thread activations */
  7308. + u_int32_t cs_blocks; /* symmetric op driver block */
  7309. + u_int32_t cs_kblocks; /* symmetric op driver block */
  7310. + /*
  7311. + * When CRYPTO_TIMING is defined at compile time and the
  7312. + * sysctl debug.crypto is set to 1, the crypto system will
  7313. + * accumulate statistics about how long it takes to process
  7314. + * crypto requests at various points during processing.
  7315. + */
  7316. + struct cryptotstat cs_invoke; /* crypto_dipsatch -> crypto_invoke */
  7317. + struct cryptotstat cs_done; /* crypto_invoke -> crypto_done */
  7318. + struct cryptotstat cs_cb; /* crypto_done -> callback */
  7319. + struct cryptotstat cs_finis; /* callback -> callback return */
  7320. +
  7321. + u_int32_t cs_drops; /* crypto ops dropped due to congestion */
  7322. +};
  7323. +
  7324. +#ifdef __KERNEL__
  7325. +
  7326. +/* Standard initialization structure beginning */
  7327. +struct cryptoini {
  7328. + int cri_alg; /* Algorithm to use */
  7329. + int cri_klen; /* Key length, in bits */
  7330. + int cri_mlen; /* Number of bytes we want from the
  7331. + entire hash. 0 means all. */
  7332. + caddr_t cri_key; /* key to use */
  7333. + u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */
  7334. + struct cryptoini *cri_next;
  7335. +};
  7336. +
  7337. +/* Describe boundaries of a single crypto operation */
  7338. +struct cryptodesc {
  7339. + int crd_skip; /* How many bytes to ignore from start */
  7340. + int crd_len; /* How many bytes to process */
  7341. + int crd_inject; /* Where to inject results, if applicable */
  7342. + int crd_flags;
  7343. +
  7344. +#define CRD_F_ENCRYPT 0x01 /* Set when doing encryption */
  7345. +#define CRD_F_IV_PRESENT 0x02 /* When encrypting, IV is already in
  7346. + place, so don't copy. */
  7347. +#define CRD_F_IV_EXPLICIT 0x04 /* IV explicitly provided */
  7348. +#define CRD_F_DSA_SHA_NEEDED 0x08 /* Compute SHA-1 of buffer for DSA */
  7349. +#define CRD_F_KEY_EXPLICIT 0x10 /* Key explicitly provided */
  7350. +#define CRD_F_COMP 0x0f /* Set when doing compression */
  7351. +
  7352. + struct cryptoini CRD_INI; /* Initialization/context data */
  7353. +#define crd_iv CRD_INI.cri_iv
  7354. +#define crd_key CRD_INI.cri_key
  7355. +#define crd_alg CRD_INI.cri_alg
  7356. +#define crd_klen CRD_INI.cri_klen
  7357. +#define crd_mlen CRD_INI.cri_mlen
  7358. +
  7359. + struct cryptodesc *crd_next;
  7360. +};
  7361. +
  7362. +/* Structure describing complete operation */
  7363. +struct cryptop {
  7364. + struct list_head crp_next;
  7365. + wait_queue_head_t crp_waitq;
  7366. +
  7367. + u_int64_t crp_sid; /* Session ID */
  7368. + int crp_ilen; /* Input data total length */
  7369. + int crp_olen; /* Result total length */
  7370. +
  7371. + int crp_etype; /*
  7372. + * Error type (zero means no error).
  7373. + * All error codes except EAGAIN
  7374. + * indicate possible data corruption (as in,
  7375. + * the data have been touched). On all
  7376. + * errors, the crp_sid may have changed
  7377. + * (reset to a new one), so the caller
  7378. + * should always check and use the new
  7379. + * value on future requests.
  7380. + */
  7381. + int crp_flags;
  7382. +
  7383. +#define CRYPTO_F_SKBUF 0x0001 /* Input/output are skbuf chains */
  7384. +#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
  7385. +#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
  7386. +#define CRYPTO_F_BATCH 0x0008 /* Batch op if possible */
  7387. +#define CRYPTO_F_CBIMM 0x0010 /* Do callback immediately */
  7388. +#define CRYPTO_F_DONE 0x0020 /* Operation completed */
  7389. +#define CRYPTO_F_CBIFSYNC 0x0040 /* Do CBIMM if op is synchronous */
  7390. +
  7391. + caddr_t crp_buf; /* Data to be processed */
  7392. + caddr_t crp_opaque; /* Opaque pointer, passed along */
  7393. + struct cryptodesc *crp_desc; /* Linked list of processing descriptors */
  7394. +
  7395. + int (*crp_callback)(struct cryptop *); /* Callback function */
  7396. +};
  7397. +
  7398. +#define CRYPTO_BUF_CONTIG 0x0
  7399. +#define CRYPTO_BUF_IOV 0x1
  7400. +#define CRYPTO_BUF_SKBUF 0x2
  7401. +
  7402. +#define CRYPTO_OP_DECRYPT 0x0
  7403. +#define CRYPTO_OP_ENCRYPT 0x1
  7404. +
  7405. +/*
  7406. + * Hints passed to process methods.
  7407. + */
  7408. +#define CRYPTO_HINT_MORE 0x1 /* more ops coming shortly */
  7409. +
  7410. +struct cryptkop {
  7411. + struct list_head krp_next;
  7412. + wait_queue_head_t krp_waitq;
  7413. +
  7414. + int krp_flags;
  7415. +#define CRYPTO_KF_DONE 0x0001 /* Operation completed */
  7416. +#define CRYPTO_KF_CBIMM 0x0002 /* Do callback immediately */
  7417. +
  7418. + u_int krp_op; /* ie. CRK_MOD_EXP or other */
  7419. + u_int krp_status; /* return status */
  7420. + u_short krp_iparams; /* # of input parameters */
  7421. + u_short krp_oparams; /* # of output parameters */
  7422. + u_int krp_crid; /* desired device, etc. */
  7423. + u_int32_t krp_hid;
  7424. + struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
  7425. + int (*krp_callback)(struct cryptkop *);
  7426. +};
  7427. +
  7428. +#include <ocf-compat.h>
  7429. +
  7430. +/*
  7431. + * Session ids are 64 bits. The lower 32 bits contain a "local id" which
  7432. + * is a driver-private session identifier. The upper 32 bits contain a
  7433. + * "hardware id" used by the core crypto code to identify the driver and
  7434. + * a copy of the driver's capabilities that can be used by client code to
  7435. + * optimize operation.
  7436. + */
  7437. +#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0x00ffffff)
  7438. +#define CRYPTO_SESID2CAPS(_sid) (((_sid) >> 32) & 0xff000000)
  7439. +#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
  7440. +
  7441. +extern int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard);
  7442. +extern int crypto_freesession(u_int64_t sid);
  7443. +#define CRYPTOCAP_F_HARDWARE CRYPTO_FLAG_HARDWARE
  7444. +#define CRYPTOCAP_F_SOFTWARE CRYPTO_FLAG_SOFTWARE
  7445. +#define CRYPTOCAP_F_SYNC 0x04000000 /* operates synchronously */
  7446. +extern int32_t crypto_get_driverid(device_t dev, int flags);
  7447. +extern int crypto_find_driver(const char *);
  7448. +extern device_t crypto_find_device_byhid(int hid);
  7449. +extern int crypto_getcaps(int hid);
  7450. +extern int crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
  7451. + u_int32_t flags);
  7452. +extern int crypto_kregister(u_int32_t, int, u_int32_t);
  7453. +extern int crypto_unregister(u_int32_t driverid, int alg);
  7454. +extern int crypto_unregister_all(u_int32_t driverid);
  7455. +extern int crypto_dispatch(struct cryptop *crp);
  7456. +extern int crypto_kdispatch(struct cryptkop *);
  7457. +#define CRYPTO_SYMQ 0x1
  7458. +#define CRYPTO_ASYMQ 0x2
  7459. +extern int crypto_unblock(u_int32_t, int);
  7460. +extern void crypto_done(struct cryptop *crp);
  7461. +extern void crypto_kdone(struct cryptkop *);
  7462. +extern int crypto_getfeat(int *);
  7463. +
  7464. +extern void crypto_freereq(struct cryptop *crp);
  7465. +extern struct cryptop *crypto_getreq(int num);
  7466. +
  7467. +extern int crypto_usercrypto; /* userland may do crypto requests */
  7468. +extern int crypto_userasymcrypto; /* userland may do asym crypto reqs */
  7469. +extern int crypto_devallowsoft; /* only use hardware crypto */
  7470. +
  7471. +/*
  7472. + * random number support, crypto_unregister_all will unregister
  7473. + */
  7474. +extern int crypto_rregister(u_int32_t driverid,
  7475. + int (*read_random)(void *arg, u_int32_t *buf, int len), void *arg);
  7476. +extern int crypto_runregister_all(u_int32_t driverid);
  7477. +
  7478. +/*
  7479. + * Crypto-related utility routines used mainly by drivers.
  7480. + *
  7481. + * XXX these don't really belong here; but for now they're
  7482. + * kept apart from the rest of the system.
  7483. + */
  7484. +struct uio;
  7485. +extern void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp);
  7486. +extern void cuio_copyback(struct uio* uio, int off, int len, caddr_t cp);
  7487. +extern struct iovec *cuio_getptr(struct uio *uio, int loc, int *off);
  7488. +
  7489. +extern void crypto_copyback(int flags, caddr_t buf, int off, int size,
  7490. + caddr_t in);
  7491. +extern void crypto_copydata(int flags, caddr_t buf, int off, int size,
  7492. + caddr_t out);
  7493. +extern int crypto_apply(int flags, caddr_t buf, int off, int len,
  7494. + int (*f)(void *, void *, u_int), void *arg);
  7495. +
  7496. +#endif /* __KERNEL__ */
  7497. +#endif /* _CRYPTO_CRYPTO_H_ */
  7498. diff -Nur linux-2.6.36.orig/crypto/ocf/cryptosoft.c linux-2.6.36/crypto/ocf/cryptosoft.c
  7499. --- linux-2.6.36.orig/crypto/ocf/cryptosoft.c 1970-01-01 01:00:00.000000000 +0100
  7500. +++ linux-2.6.36/crypto/ocf/cryptosoft.c 2010-11-09 20:28:04.532495450 +0100
  7501. @@ -0,0 +1,1210 @@
  7502. +/*
  7503. + * An OCF module that uses the linux kernel cryptoapi, based on the
  7504. + * original cryptosoft for BSD by Angelos D. Keromytis (angelos@cis.upenn.edu)
  7505. + * but is mostly unrecognisable,
  7506. + *
  7507. + * Written by David McCullough <david_mccullough@mcafee.com>
  7508. + * Copyright (C) 2004-2010 David McCullough
  7509. + * Copyright (C) 2004-2005 Intel Corporation.
  7510. + *
  7511. + * LICENSE TERMS
  7512. + *
  7513. + * The free distribution and use of this software in both source and binary
  7514. + * form is allowed (with or without changes) provided that:
  7515. + *
  7516. + * 1. distributions of this source code include the above copyright
  7517. + * notice, this list of conditions and the following disclaimer;
  7518. + *
  7519. + * 2. distributions in binary form include the above copyright
  7520. + * notice, this list of conditions and the following disclaimer
  7521. + * in the documentation and/or other associated materials;
  7522. + *
  7523. + * 3. the copyright holder's name is not used to endorse products
  7524. + * built using this software without specific written permission.
  7525. + *
  7526. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  7527. + * may be distributed under the terms of the GNU General Public License (GPL),
  7528. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  7529. + *
  7530. + * DISCLAIMER
  7531. + *
  7532. + * This software is provided 'as is' with no explicit or implied warranties
  7533. + * in respect of its properties, including, but not limited to, correctness
  7534. + * and/or fitness for purpose.
  7535. + * ---------------------------------------------------------------------------
  7536. + */
  7537. +
  7538. +#ifndef AUTOCONF_INCLUDED
  7539. +#include <linux/config.h>
  7540. +#endif
  7541. +#include <linux/module.h>
  7542. +#include <linux/init.h>
  7543. +#include <linux/list.h>
  7544. +#include <linux/slab.h>
  7545. +#include <linux/sched.h>
  7546. +#include <linux/wait.h>
  7547. +#include <linux/crypto.h>
  7548. +#include <linux/mm.h>
  7549. +#include <linux/skbuff.h>
  7550. +#include <linux/random.h>
  7551. +#include <linux/version.h>
  7552. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
  7553. +#include <linux/scatterlist.h>
  7554. +#endif
  7555. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
  7556. +#include <crypto/hash.h>
  7557. +#endif
  7558. +
  7559. +#include <cryptodev.h>
  7560. +#include <uio.h>
  7561. +
  7562. +struct {
  7563. + softc_device_decl sc_dev;
  7564. +} swcr_softc;
  7565. +
  7566. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  7567. +
  7568. +#define SW_TYPE_CIPHER 0x01
  7569. +#define SW_TYPE_HMAC 0x02
  7570. +#define SW_TYPE_HASH 0x04
  7571. +#define SW_TYPE_COMP 0x08
  7572. +#define SW_TYPE_BLKCIPHER 0x10
  7573. +#define SW_TYPE_ALG_MASK 0x1f
  7574. +
  7575. +#define SW_TYPE_ASYNC 0x8000
  7576. +
  7577. +/* We change some of the above if we have an async interface */
  7578. +
  7579. +#define SW_TYPE_ALG_AMASK (SW_TYPE_ALG_MASK | SW_TYPE_ASYNC)
  7580. +
  7581. +#define SW_TYPE_ABLKCIPHER (SW_TYPE_BLKCIPHER | SW_TYPE_ASYNC)
  7582. +#define SW_TYPE_AHASH (SW_TYPE_HASH | SW_TYPE_ASYNC)
  7583. +#define SW_TYPE_AHMAC (SW_TYPE_HMAC | SW_TYPE_ASYNC)
  7584. +
  7585. +#define SCATTERLIST_MAX 16
  7586. +
  7587. +struct swcr_data {
  7588. + int sw_type;
  7589. + int sw_alg;
  7590. + struct crypto_tfm *sw_tfm;
  7591. + union {
  7592. + struct {
  7593. + char *sw_key;
  7594. + int sw_klen;
  7595. + int sw_mlen;
  7596. + } hmac;
  7597. + void *sw_comp_buf;
  7598. + } u;
  7599. + struct swcr_data *sw_next;
  7600. +};
  7601. +
  7602. +struct swcr_req {
  7603. + struct swcr_data *sw_head;
  7604. + struct swcr_data *sw;
  7605. + struct cryptop *crp;
  7606. + struct cryptodesc *crd;
  7607. + struct scatterlist sg[SCATTERLIST_MAX];
  7608. + unsigned char iv[EALG_MAX_BLOCK_LEN];
  7609. + char result[HASH_MAX_LEN];
  7610. + void *crypto_req;
  7611. +};
  7612. +
  7613. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  7614. +static kmem_cache_t *swcr_req_cache;
  7615. +#else
  7616. +static struct kmem_cache *swcr_req_cache;
  7617. +#endif
  7618. +
  7619. +#ifndef CRYPTO_TFM_MODE_CBC
  7620. +/*
  7621. + * As of linux-2.6.21 this is no longer defined, and presumably no longer
  7622. + * needed to be passed into the crypto core code.
  7623. + */
  7624. +#define CRYPTO_TFM_MODE_CBC 0
  7625. +#define CRYPTO_TFM_MODE_ECB 0
  7626. +#endif
  7627. +
  7628. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
  7629. + /*
  7630. + * Linux 2.6.19 introduced a new Crypto API, setup macro's to convert new
  7631. + * API into old API.
  7632. + */
  7633. +
  7634. + /* Symmetric/Block Cipher */
  7635. + struct blkcipher_desc
  7636. + {
  7637. + struct crypto_tfm *tfm;
  7638. + void *info;
  7639. + };
  7640. + #define ecb(X) #X , CRYPTO_TFM_MODE_ECB
  7641. + #define cbc(X) #X , CRYPTO_TFM_MODE_CBC
  7642. + #define crypto_has_blkcipher(X, Y, Z) crypto_alg_available(X, 0)
  7643. + #define crypto_blkcipher_cast(X) X
  7644. + #define crypto_blkcipher_tfm(X) X
  7645. + #define crypto_alloc_blkcipher(X, Y, Z) crypto_alloc_tfm(X, mode)
  7646. + #define crypto_blkcipher_ivsize(X) crypto_tfm_alg_ivsize(X)
  7647. + #define crypto_blkcipher_blocksize(X) crypto_tfm_alg_blocksize(X)
  7648. + #define crypto_blkcipher_setkey(X, Y, Z) crypto_cipher_setkey(X, Y, Z)
  7649. + #define crypto_blkcipher_encrypt_iv(W, X, Y, Z) \
  7650. + crypto_cipher_encrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
  7651. + #define crypto_blkcipher_decrypt_iv(W, X, Y, Z) \
  7652. + crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
  7653. + #define crypto_blkcipher_set_flags(x, y) /* nop */
  7654. +
  7655. + /* Hash/HMAC/Digest */
  7656. + struct hash_desc
  7657. + {
  7658. + struct crypto_tfm *tfm;
  7659. + };
  7660. + #define hmac(X) #X , 0
  7661. + #define crypto_has_hash(X, Y, Z) crypto_alg_available(X, 0)
  7662. + #define crypto_hash_cast(X) X
  7663. + #define crypto_hash_tfm(X) X
  7664. + #define crypto_alloc_hash(X, Y, Z) crypto_alloc_tfm(X, mode)
  7665. + #define crypto_hash_digestsize(X) crypto_tfm_alg_digestsize(X)
  7666. + #define crypto_hash_digest(W, X, Y, Z) \
  7667. + crypto_digest_digest((W)->tfm, X, sg_num, Z)
  7668. +
  7669. + /* Asymmetric Cipher */
  7670. + #define crypto_has_cipher(X, Y, Z) crypto_alg_available(X, 0)
  7671. +
  7672. + /* Compression */
  7673. + #define crypto_has_comp(X, Y, Z) crypto_alg_available(X, 0)
  7674. + #define crypto_comp_tfm(X) X
  7675. + #define crypto_comp_cast(X) X
  7676. + #define crypto_alloc_comp(X, Y, Z) crypto_alloc_tfm(X, mode)
  7677. + #define plain(X) #X , 0
  7678. +#else
  7679. + #define ecb(X) "ecb(" #X ")" , 0
  7680. + #define cbc(X) "cbc(" #X ")" , 0
  7681. + #define hmac(X) "hmac(" #X ")" , 0
  7682. + #define plain(X) #X , 0
  7683. +#endif /* if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
  7684. +
  7685. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
  7686. +/* no ablkcipher in older kernels */
  7687. +#define crypto_alloc_ablkcipher(a,b,c) (NULL)
  7688. +#define crypto_ablkcipher_tfm(x) ((struct crypto_tfm *)(x))
  7689. +#define crypto_ablkcipher_set_flags(a, b) /* nop */
  7690. +#define crypto_ablkcipher_setkey(x, y, z) (-EINVAL)
  7691. +#define crypto_has_ablkcipher(a,b,c) (0)
  7692. +#else
  7693. +#define HAVE_ABLKCIPHER
  7694. +#endif
  7695. +
  7696. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
  7697. +/* no ahash in older kernels */
  7698. +#define crypto_ahash_tfm(x) ((struct crypto_tfm *)(x))
  7699. +#define crypto_alloc_ahash(a,b,c) (NULL)
  7700. +#define crypto_ahash_digestsize(x) 0
  7701. +#else
  7702. +#define HAVE_AHASH
  7703. +#endif
  7704. +
  7705. +struct crypto_details {
  7706. + char *alg_name;
  7707. + int mode;
  7708. + int sw_type;
  7709. +};
  7710. +
  7711. +static struct crypto_details crypto_details[] = {
  7712. + [CRYPTO_DES_CBC] = { cbc(des), SW_TYPE_BLKCIPHER, },
  7713. + [CRYPTO_3DES_CBC] = { cbc(des3_ede), SW_TYPE_BLKCIPHER, },
  7714. + [CRYPTO_BLF_CBC] = { cbc(blowfish), SW_TYPE_BLKCIPHER, },
  7715. + [CRYPTO_CAST_CBC] = { cbc(cast5), SW_TYPE_BLKCIPHER, },
  7716. + [CRYPTO_SKIPJACK_CBC] = { cbc(skipjack), SW_TYPE_BLKCIPHER, },
  7717. + [CRYPTO_MD5_HMAC] = { hmac(md5), SW_TYPE_HMAC, },
  7718. + [CRYPTO_SHA1_HMAC] = { hmac(sha1), SW_TYPE_HMAC, },
  7719. + [CRYPTO_RIPEMD160_HMAC] = { hmac(ripemd160), SW_TYPE_HMAC, },
  7720. + [CRYPTO_MD5_KPDK] = { plain(md5-kpdk), SW_TYPE_HASH, },
  7721. + [CRYPTO_SHA1_KPDK] = { plain(sha1-kpdk), SW_TYPE_HASH, },
  7722. + [CRYPTO_AES_CBC] = { cbc(aes), SW_TYPE_BLKCIPHER, },
  7723. + [CRYPTO_ARC4] = { ecb(arc4), SW_TYPE_BLKCIPHER, },
  7724. + [CRYPTO_MD5] = { plain(md5), SW_TYPE_HASH, },
  7725. + [CRYPTO_SHA1] = { plain(sha1), SW_TYPE_HASH, },
  7726. + [CRYPTO_NULL_HMAC] = { hmac(digest_null), SW_TYPE_HMAC, },
  7727. + [CRYPTO_NULL_CBC] = { cbc(cipher_null), SW_TYPE_BLKCIPHER, },
  7728. + [CRYPTO_DEFLATE_COMP] = { plain(deflate), SW_TYPE_COMP, },
  7729. + [CRYPTO_SHA2_256_HMAC] = { hmac(sha256), SW_TYPE_HMAC, },
  7730. + [CRYPTO_SHA2_384_HMAC] = { hmac(sha384), SW_TYPE_HMAC, },
  7731. + [CRYPTO_SHA2_512_HMAC] = { hmac(sha512), SW_TYPE_HMAC, },
  7732. + [CRYPTO_CAMELLIA_CBC] = { cbc(camellia), SW_TYPE_BLKCIPHER, },
  7733. + [CRYPTO_SHA2_256] = { plain(sha256), SW_TYPE_HASH, },
  7734. + [CRYPTO_SHA2_384] = { plain(sha384), SW_TYPE_HASH, },
  7735. + [CRYPTO_SHA2_512] = { plain(sha512), SW_TYPE_HASH, },
  7736. + [CRYPTO_RIPEMD160] = { plain(ripemd160), SW_TYPE_HASH, },
  7737. +};
  7738. +
  7739. +int32_t swcr_id = -1;
  7740. +module_param(swcr_id, int, 0444);
  7741. +MODULE_PARM_DESC(swcr_id, "Read-Only OCF ID for cryptosoft driver");
  7742. +
  7743. +int swcr_fail_if_compression_grows = 1;
  7744. +module_param(swcr_fail_if_compression_grows, int, 0644);
  7745. +MODULE_PARM_DESC(swcr_fail_if_compression_grows,
  7746. + "Treat compression that results in more data as a failure");
  7747. +
  7748. +int swcr_no_ahash = 0;
  7749. +module_param(swcr_no_ahash, int, 0644);
  7750. +MODULE_PARM_DESC(swcr_no_ahash,
  7751. + "Do not use async hash/hmac even if available");
  7752. +
  7753. +int swcr_no_ablk = 0;
  7754. +module_param(swcr_no_ablk, int, 0644);
  7755. +MODULE_PARM_DESC(swcr_no_ablk,
  7756. + "Do not use async blk ciphers even if available");
  7757. +
  7758. +static struct swcr_data **swcr_sessions = NULL;
  7759. +static u_int32_t swcr_sesnum = 0;
  7760. +
  7761. +static int swcr_process(device_t, struct cryptop *, int);
  7762. +static int swcr_newsession(device_t, u_int32_t *, struct cryptoini *);
  7763. +static int swcr_freesession(device_t, u_int64_t);
  7764. +
  7765. +static device_method_t swcr_methods = {
  7766. + /* crypto device methods */
  7767. + DEVMETHOD(cryptodev_newsession, swcr_newsession),
  7768. + DEVMETHOD(cryptodev_freesession,swcr_freesession),
  7769. + DEVMETHOD(cryptodev_process, swcr_process),
  7770. +};
  7771. +
  7772. +#define debug swcr_debug
  7773. +int swcr_debug = 0;
  7774. +module_param(swcr_debug, int, 0644);
  7775. +MODULE_PARM_DESC(swcr_debug, "Enable debug");
  7776. +
  7777. +static void swcr_process_req(struct swcr_req *req);
  7778. +
  7779. +/*
  7780. + * Generate a new software session.
  7781. + */
  7782. +static int
  7783. +swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  7784. +{
  7785. + struct swcr_data **swd;
  7786. + u_int32_t i;
  7787. + int error;
  7788. + char *algo;
  7789. + int mode;
  7790. +
  7791. + dprintk("%s()\n", __FUNCTION__);
  7792. + if (sid == NULL || cri == NULL) {
  7793. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  7794. + return EINVAL;
  7795. + }
  7796. +
  7797. + if (swcr_sessions) {
  7798. + for (i = 1; i < swcr_sesnum; i++)
  7799. + if (swcr_sessions[i] == NULL)
  7800. + break;
  7801. + } else
  7802. + i = 1; /* NB: to silence compiler warning */
  7803. +
  7804. + if (swcr_sessions == NULL || i == swcr_sesnum) {
  7805. + if (swcr_sessions == NULL) {
  7806. + i = 1; /* We leave swcr_sessions[0] empty */
  7807. + swcr_sesnum = CRYPTO_SW_SESSIONS;
  7808. + } else
  7809. + swcr_sesnum *= 2;
  7810. +
  7811. + swd = kmalloc(swcr_sesnum * sizeof(struct swcr_data *), SLAB_ATOMIC);
  7812. + if (swd == NULL) {
  7813. + /* Reset session number */
  7814. + if (swcr_sesnum == CRYPTO_SW_SESSIONS)
  7815. + swcr_sesnum = 0;
  7816. + else
  7817. + swcr_sesnum /= 2;
  7818. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  7819. + return ENOBUFS;
  7820. + }
  7821. + memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *));
  7822. +
  7823. + /* Copy existing sessions */
  7824. + if (swcr_sessions) {
  7825. + memcpy(swd, swcr_sessions,
  7826. + (swcr_sesnum / 2) * sizeof(struct swcr_data *));
  7827. + kfree(swcr_sessions);
  7828. + }
  7829. +
  7830. + swcr_sessions = swd;
  7831. + }
  7832. +
  7833. + swd = &swcr_sessions[i];
  7834. + *sid = i;
  7835. +
  7836. + while (cri) {
  7837. + *swd = (struct swcr_data *) kmalloc(sizeof(struct swcr_data),
  7838. + SLAB_ATOMIC);
  7839. + if (*swd == NULL) {
  7840. + swcr_freesession(NULL, i);
  7841. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  7842. + return ENOBUFS;
  7843. + }
  7844. + memset(*swd, 0, sizeof(struct swcr_data));
  7845. +
  7846. + if (cri->cri_alg < 0 ||
  7847. + cri->cri_alg>=sizeof(crypto_details)/sizeof(crypto_details[0])){
  7848. + printk("cryptosoft: Unknown algorithm 0x%x\n", cri->cri_alg);
  7849. + swcr_freesession(NULL, i);
  7850. + return EINVAL;
  7851. + }
  7852. +
  7853. + algo = crypto_details[cri->cri_alg].alg_name;
  7854. + if (!algo || !*algo) {
  7855. + printk("cryptosoft: Unsupported algorithm 0x%x\n", cri->cri_alg);
  7856. + swcr_freesession(NULL, i);
  7857. + return EINVAL;
  7858. + }
  7859. +
  7860. + mode = crypto_details[cri->cri_alg].mode;
  7861. + (*swd)->sw_type = crypto_details[cri->cri_alg].sw_type;
  7862. + (*swd)->sw_alg = cri->cri_alg;
  7863. +
  7864. + /* Algorithm specific configuration */
  7865. + switch (cri->cri_alg) {
  7866. + case CRYPTO_NULL_CBC:
  7867. + cri->cri_klen = 0; /* make it work with crypto API */
  7868. + break;
  7869. + default:
  7870. + break;
  7871. + }
  7872. +
  7873. + if ((*swd)->sw_type & SW_TYPE_BLKCIPHER) {
  7874. + dprintk("%s crypto_alloc_*blkcipher(%s, 0x%x)\n", __FUNCTION__,
  7875. + algo, mode);
  7876. +
  7877. + /* try async first */
  7878. + (*swd)->sw_tfm = swcr_no_ablk ? NULL :
  7879. + crypto_ablkcipher_tfm(crypto_alloc_ablkcipher(algo, 0, 0));
  7880. + if ((*swd)->sw_tfm) {
  7881. + dprintk("%s %s cipher is async\n", __FUNCTION__, algo);
  7882. + (*swd)->sw_type |= SW_TYPE_ASYNC;
  7883. + } else {
  7884. + dprintk("%s %s cipher is sync\n", __FUNCTION__, algo);
  7885. + (*swd)->sw_tfm = crypto_blkcipher_tfm(
  7886. + crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC));
  7887. + }
  7888. + if (!(*swd)->sw_tfm) {
  7889. + dprintk("cryptosoft: crypto_alloc_blkcipher failed(%s, 0x%x)\n",
  7890. + algo,mode);
  7891. + swcr_freesession(NULL, i);
  7892. + return EINVAL;
  7893. + }
  7894. +
  7895. + if (debug) {
  7896. + dprintk("%s key:cri->cri_klen=%d,(cri->cri_klen + 7)/8=%d",
  7897. + __FUNCTION__, cri->cri_klen, (cri->cri_klen + 7) / 8);
  7898. + for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
  7899. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  7900. + cri->cri_key[i] & 0xff);
  7901. + dprintk("\n");
  7902. + }
  7903. + if ((*swd)->sw_type & SW_TYPE_ASYNC) {
  7904. + /* OCF doesn't enforce keys */
  7905. + crypto_ablkcipher_set_flags(
  7906. + __crypto_ablkcipher_cast((*swd)->sw_tfm),
  7907. + CRYPTO_TFM_REQ_WEAK_KEY);
  7908. + error = crypto_ablkcipher_setkey(
  7909. + __crypto_ablkcipher_cast((*swd)->sw_tfm),
  7910. + cri->cri_key, (cri->cri_klen + 7) / 8);
  7911. + } else {
  7912. + /* OCF doesn't enforce keys */
  7913. + crypto_blkcipher_set_flags(
  7914. + crypto_blkcipher_cast((*swd)->sw_tfm),
  7915. + CRYPTO_TFM_REQ_WEAK_KEY);
  7916. + error = crypto_blkcipher_setkey(
  7917. + crypto_blkcipher_cast((*swd)->sw_tfm),
  7918. + cri->cri_key, (cri->cri_klen + 7) / 8);
  7919. + }
  7920. + if (error) {
  7921. + printk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n", error,
  7922. + (*swd)->sw_tfm->crt_flags);
  7923. + swcr_freesession(NULL, i);
  7924. + return error;
  7925. + }
  7926. + } else if ((*swd)->sw_type & (SW_TYPE_HMAC | SW_TYPE_HASH)) {
  7927. + dprintk("%s crypto_alloc_*hash(%s, 0x%x)\n", __FUNCTION__,
  7928. + algo, mode);
  7929. +
  7930. + /* try async first */
  7931. + (*swd)->sw_tfm = swcr_no_ahash ? NULL :
  7932. + crypto_ahash_tfm(crypto_alloc_ahash(algo, 0, 0));
  7933. + if ((*swd)->sw_tfm) {
  7934. + dprintk("%s %s hash is async\n", __FUNCTION__, algo);
  7935. + (*swd)->sw_type |= SW_TYPE_ASYNC;
  7936. + } else {
  7937. + dprintk("%s %s hash is sync\n", __FUNCTION__, algo);
  7938. + (*swd)->sw_tfm = crypto_hash_tfm(
  7939. + crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC));
  7940. + }
  7941. +
  7942. + if (!(*swd)->sw_tfm) {
  7943. + dprintk("cryptosoft: crypto_alloc_hash failed(%s,0x%x)\n",
  7944. + algo, mode);
  7945. + swcr_freesession(NULL, i);
  7946. + return EINVAL;
  7947. + }
  7948. +
  7949. + (*swd)->u.hmac.sw_klen = (cri->cri_klen + 7) / 8;
  7950. + (*swd)->u.hmac.sw_key = (char *)kmalloc((*swd)->u.hmac.sw_klen,
  7951. + SLAB_ATOMIC);
  7952. + if ((*swd)->u.hmac.sw_key == NULL) {
  7953. + swcr_freesession(NULL, i);
  7954. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  7955. + return ENOBUFS;
  7956. + }
  7957. + memcpy((*swd)->u.hmac.sw_key, cri->cri_key, (*swd)->u.hmac.sw_klen);
  7958. + if (cri->cri_mlen) {
  7959. + (*swd)->u.hmac.sw_mlen = cri->cri_mlen;
  7960. + } else if ((*swd)->sw_type & SW_TYPE_ASYNC) {
  7961. + (*swd)->u.hmac.sw_mlen = crypto_ahash_digestsize(
  7962. + __crypto_ahash_cast((*swd)->sw_tfm));
  7963. + } else {
  7964. + (*swd)->u.hmac.sw_mlen = crypto_hash_digestsize(
  7965. + crypto_hash_cast((*swd)->sw_tfm));
  7966. + }
  7967. + } else if ((*swd)->sw_type & SW_TYPE_COMP) {
  7968. + (*swd)->sw_tfm = crypto_comp_tfm(
  7969. + crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC));
  7970. + if (!(*swd)->sw_tfm) {
  7971. + dprintk("cryptosoft: crypto_alloc_comp failed(%s,0x%x)\n",
  7972. + algo, mode);
  7973. + swcr_freesession(NULL, i);
  7974. + return EINVAL;
  7975. + }
  7976. + (*swd)->u.sw_comp_buf = kmalloc(CRYPTO_MAX_DATA_LEN, SLAB_ATOMIC);
  7977. + if ((*swd)->u.sw_comp_buf == NULL) {
  7978. + swcr_freesession(NULL, i);
  7979. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  7980. + return ENOBUFS;
  7981. + }
  7982. + } else {
  7983. + printk("cryptosoft: Unhandled sw_type %d\n", (*swd)->sw_type);
  7984. + swcr_freesession(NULL, i);
  7985. + return EINVAL;
  7986. + }
  7987. +
  7988. + cri = cri->cri_next;
  7989. + swd = &((*swd)->sw_next);
  7990. + }
  7991. + return 0;
  7992. +}
  7993. +
  7994. +/*
  7995. + * Free a session.
  7996. + */
  7997. +static int
  7998. +swcr_freesession(device_t dev, u_int64_t tid)
  7999. +{
  8000. + struct swcr_data *swd;
  8001. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  8002. +
  8003. + dprintk("%s()\n", __FUNCTION__);
  8004. + if (sid > swcr_sesnum || swcr_sessions == NULL ||
  8005. + swcr_sessions[sid] == NULL) {
  8006. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8007. + return(EINVAL);
  8008. + }
  8009. +
  8010. + /* Silently accept and return */
  8011. + if (sid == 0)
  8012. + return(0);
  8013. +
  8014. + while ((swd = swcr_sessions[sid]) != NULL) {
  8015. + swcr_sessions[sid] = swd->sw_next;
  8016. + if (swd->sw_tfm) {
  8017. + switch (swd->sw_type & SW_TYPE_ALG_AMASK) {
  8018. +#ifdef HAVE_AHASH
  8019. + case SW_TYPE_AHMAC:
  8020. + case SW_TYPE_AHASH:
  8021. + crypto_free_ahash(__crypto_ahash_cast(swd->sw_tfm));
  8022. + break;
  8023. +#endif
  8024. +#ifdef HAVE_ABLKCIPHER
  8025. + case SW_TYPE_ABLKCIPHER:
  8026. + crypto_free_ablkcipher(__crypto_ablkcipher_cast(swd->sw_tfm));
  8027. + break;
  8028. +#endif
  8029. + case SW_TYPE_BLKCIPHER:
  8030. + crypto_free_blkcipher(crypto_blkcipher_cast(swd->sw_tfm));
  8031. + break;
  8032. + case SW_TYPE_HMAC:
  8033. + case SW_TYPE_HASH:
  8034. + crypto_free_hash(crypto_hash_cast(swd->sw_tfm));
  8035. + break;
  8036. + case SW_TYPE_COMP:
  8037. + crypto_free_comp(crypto_comp_cast(swd->sw_tfm));
  8038. + default:
  8039. + crypto_free_tfm(swd->sw_tfm);
  8040. + break;
  8041. + }
  8042. + swd->sw_tfm = NULL;
  8043. + }
  8044. + if (swd->sw_type & SW_TYPE_COMP) {
  8045. + if (swd->u.sw_comp_buf)
  8046. + kfree(swd->u.sw_comp_buf);
  8047. + } else {
  8048. + if (swd->u.hmac.sw_key)
  8049. + kfree(swd->u.hmac.sw_key);
  8050. + }
  8051. + kfree(swd);
  8052. + }
  8053. + return 0;
  8054. +}
  8055. +
  8056. +#if defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH)
  8057. +/* older kernels had no async interface */
  8058. +
  8059. +static void swcr_process_callback(struct crypto_async_request *creq, int err)
  8060. +{
  8061. + struct swcr_req *req = creq->data;
  8062. +
  8063. + dprintk("%s()\n", __FUNCTION__);
  8064. + if (err) {
  8065. + if (err == -EINPROGRESS)
  8066. + return;
  8067. + dprintk("%s() fail %d\n", __FUNCTION__, -err);
  8068. + req->crp->crp_etype = -err;
  8069. + goto done;
  8070. + }
  8071. +
  8072. + switch (req->sw->sw_type & SW_TYPE_ALG_AMASK) {
  8073. + case SW_TYPE_AHMAC:
  8074. + case SW_TYPE_AHASH:
  8075. + crypto_copyback(req->crp->crp_flags, req->crp->crp_buf,
  8076. + req->crd->crd_inject, req->sw->u.hmac.sw_mlen, req->result);
  8077. + ahash_request_free(req->crypto_req);
  8078. + break;
  8079. + case SW_TYPE_ABLKCIPHER:
  8080. + ablkcipher_request_free(req->crypto_req);
  8081. + break;
  8082. + default:
  8083. + req->crp->crp_etype = EINVAL;
  8084. + goto done;
  8085. + }
  8086. +
  8087. + req->crd = req->crd->crd_next;
  8088. + if (req->crd) {
  8089. + swcr_process_req(req);
  8090. + return;
  8091. + }
  8092. +
  8093. +done:
  8094. + dprintk("%s crypto_done %p\n", __FUNCTION__, req);
  8095. + crypto_done(req->crp);
  8096. + kmem_cache_free(swcr_req_cache, req);
  8097. +}
  8098. +#endif /* defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH) */
  8099. +
  8100. +
  8101. +static void swcr_process_req(struct swcr_req *req)
  8102. +{
  8103. + struct swcr_data *sw;
  8104. + struct cryptop *crp = req->crp;
  8105. + struct cryptodesc *crd = req->crd;
  8106. + struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
  8107. + struct uio *uiop = (struct uio *) crp->crp_buf;
  8108. + int sg_num, sg_len, skip;
  8109. +
  8110. + dprintk("%s()\n", __FUNCTION__);
  8111. +
  8112. + /*
  8113. + * Find the crypto context.
  8114. + *
  8115. + * XXX Note that the logic here prevents us from having
  8116. + * XXX the same algorithm multiple times in a session
  8117. + * XXX (or rather, we can but it won't give us the right
  8118. + * XXX results). To do that, we'd need some way of differentiating
  8119. + * XXX between the various instances of an algorithm (so we can
  8120. + * XXX locate the correct crypto context).
  8121. + */
  8122. + for (sw = req->sw_head; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next)
  8123. + ;
  8124. +
  8125. + /* No such context ? */
  8126. + if (sw == NULL) {
  8127. + crp->crp_etype = EINVAL;
  8128. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8129. + goto done;
  8130. + }
  8131. +
  8132. + req->sw = sw;
  8133. + skip = crd->crd_skip;
  8134. +
  8135. + /*
  8136. + * setup the SG list skip from the start of the buffer
  8137. + */
  8138. + memset(req->sg, 0, sizeof(req->sg));
  8139. + sg_init_table(req->sg, SCATTERLIST_MAX);
  8140. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  8141. + int i, len;
  8142. +
  8143. + sg_num = 0;
  8144. + sg_len = 0;
  8145. +
  8146. + if (skip < skb_headlen(skb)) {
  8147. + len = skb_headlen(skb) - skip;
  8148. + if (len + sg_len > crd->crd_len)
  8149. + len = crd->crd_len - sg_len;
  8150. + sg_set_page(&req->sg[sg_num],
  8151. + virt_to_page(skb->data + skip), len,
  8152. + offset_in_page(skb->data + skip));
  8153. + sg_len += len;
  8154. + sg_num++;
  8155. + skip = 0;
  8156. + } else
  8157. + skip -= skb_headlen(skb);
  8158. +
  8159. + for (i = 0; sg_len < crd->crd_len &&
  8160. + i < skb_shinfo(skb)->nr_frags &&
  8161. + sg_num < SCATTERLIST_MAX; i++) {
  8162. + if (skip < skb_shinfo(skb)->frags[i].size) {
  8163. + len = skb_shinfo(skb)->frags[i].size - skip;
  8164. + if (len + sg_len > crd->crd_len)
  8165. + len = crd->crd_len - sg_len;
  8166. + sg_set_page(&req->sg[sg_num],
  8167. + skb_shinfo(skb)->frags[i].page,
  8168. + len,
  8169. + skb_shinfo(skb)->frags[i].page_offset + skip);
  8170. + sg_len += len;
  8171. + sg_num++;
  8172. + skip = 0;
  8173. + } else
  8174. + skip -= skb_shinfo(skb)->frags[i].size;
  8175. + }
  8176. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  8177. + int len;
  8178. +
  8179. + sg_len = 0;
  8180. + for (sg_num = 0; sg_len < crd->crd_len &&
  8181. + sg_num < uiop->uio_iovcnt &&
  8182. + sg_num < SCATTERLIST_MAX; sg_num++) {
  8183. + if (skip <= uiop->uio_iov[sg_num].iov_len) {
  8184. + len = uiop->uio_iov[sg_num].iov_len - skip;
  8185. + if (len + sg_len > crd->crd_len)
  8186. + len = crd->crd_len - sg_len;
  8187. + sg_set_page(&req->sg[sg_num],
  8188. + virt_to_page(uiop->uio_iov[sg_num].iov_base+skip),
  8189. + len,
  8190. + offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
  8191. + sg_len += len;
  8192. + skip = 0;
  8193. + } else
  8194. + skip -= uiop->uio_iov[sg_num].iov_len;
  8195. + }
  8196. + } else {
  8197. + sg_len = (crp->crp_ilen - skip);
  8198. + if (sg_len > crd->crd_len)
  8199. + sg_len = crd->crd_len;
  8200. + sg_set_page(&req->sg[0], virt_to_page(crp->crp_buf + skip),
  8201. + sg_len, offset_in_page(crp->crp_buf + skip));
  8202. + sg_num = 1;
  8203. + }
  8204. +
  8205. + switch (sw->sw_type & SW_TYPE_ALG_AMASK) {
  8206. +
  8207. +#ifdef HAVE_AHASH
  8208. + case SW_TYPE_AHMAC:
  8209. + case SW_TYPE_AHASH:
  8210. + {
  8211. + int ret;
  8212. +
  8213. + /* check we have room for the result */
  8214. + if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
  8215. + dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
  8216. + "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
  8217. + crd->crd_inject, sw->u.hmac.sw_mlen);
  8218. + crp->crp_etype = EINVAL;
  8219. + goto done;
  8220. + }
  8221. +
  8222. + req->crypto_req =
  8223. + ahash_request_alloc(__crypto_ahash_cast(sw->sw_tfm),GFP_KERNEL);
  8224. + if (!req->crypto_req) {
  8225. + crp->crp_etype = ENOMEM;
  8226. + dprintk("%s,%d: ENOMEM ahash_request_alloc", __FILE__, __LINE__);
  8227. + goto done;
  8228. + }
  8229. +
  8230. + ahash_request_set_callback(req->crypto_req,
  8231. + CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
  8232. +
  8233. + memset(req->result, 0, sizeof(req->result));
  8234. +
  8235. + if (sw->sw_type & SW_TYPE_AHMAC)
  8236. + crypto_ahash_setkey(__crypto_ahash_cast(sw->sw_tfm),
  8237. + sw->u.hmac.sw_key, sw->u.hmac.sw_klen);
  8238. + ahash_request_set_crypt(req->crypto_req, req->sg, req->result, sg_len);
  8239. + ret = crypto_ahash_digest(req->crypto_req);
  8240. + switch (ret) {
  8241. + case -EINPROGRESS:
  8242. + case -EBUSY:
  8243. + return;
  8244. + default:
  8245. + case 0:
  8246. + dprintk("hash OP %s %d\n", ret ? "failed" : "success", ret);
  8247. + crp->crp_etype = ret;
  8248. + ahash_request_free(req->crypto_req);
  8249. + goto done;
  8250. + }
  8251. + } break;
  8252. +#endif /* HAVE_AHASH */
  8253. +
  8254. +#ifdef HAVE_ABLKCIPHER
  8255. + case SW_TYPE_ABLKCIPHER: {
  8256. + int ret;
  8257. + unsigned char *ivp = req->iv;
  8258. + int ivsize =
  8259. + crypto_ablkcipher_ivsize(__crypto_ablkcipher_cast(sw->sw_tfm));
  8260. +
  8261. + if (sg_len < crypto_ablkcipher_blocksize(
  8262. + __crypto_ablkcipher_cast(sw->sw_tfm))) {
  8263. + crp->crp_etype = EINVAL;
  8264. + dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
  8265. + sg_len, crypto_ablkcipher_blocksize(
  8266. + __crypto_ablkcipher_cast(sw->sw_tfm)));
  8267. + goto done;
  8268. + }
  8269. +
  8270. + if (ivsize > sizeof(req->iv)) {
  8271. + crp->crp_etype = EINVAL;
  8272. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8273. + goto done;
  8274. + }
  8275. +
  8276. + req->crypto_req = ablkcipher_request_alloc(
  8277. + __crypto_ablkcipher_cast(sw->sw_tfm), GFP_KERNEL);
  8278. + if (!req->crypto_req) {
  8279. + crp->crp_etype = ENOMEM;
  8280. + dprintk("%s,%d: ENOMEM ablkcipher_request_alloc",
  8281. + __FILE__, __LINE__);
  8282. + goto done;
  8283. + }
  8284. +
  8285. + ablkcipher_request_set_callback(req->crypto_req,
  8286. + CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
  8287. +
  8288. + if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
  8289. + int i, error;
  8290. +
  8291. + if (debug) {
  8292. + dprintk("%s key:", __FUNCTION__);
  8293. + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
  8294. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  8295. + crd->crd_key[i] & 0xff);
  8296. + dprintk("\n");
  8297. + }
  8298. + /* OCF doesn't enforce keys */
  8299. + crypto_ablkcipher_set_flags(__crypto_ablkcipher_cast(sw->sw_tfm),
  8300. + CRYPTO_TFM_REQ_WEAK_KEY);
  8301. + error = crypto_ablkcipher_setkey(
  8302. + __crypto_ablkcipher_cast(sw->sw_tfm), crd->crd_key,
  8303. + (crd->crd_klen + 7) / 8);
  8304. + if (error) {
  8305. + dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
  8306. + error, sw->sw_tfm->crt_flags);
  8307. + crp->crp_etype = -error;
  8308. + }
  8309. + }
  8310. +
  8311. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  8312. +
  8313. + if (crd->crd_flags & CRD_F_IV_EXPLICIT)
  8314. + ivp = crd->crd_iv;
  8315. + else
  8316. + get_random_bytes(ivp, ivsize);
  8317. + /*
  8318. + * do we have to copy the IV back to the buffer ?
  8319. + */
  8320. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  8321. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  8322. + crd->crd_inject, ivsize, (caddr_t)ivp);
  8323. + }
  8324. + ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
  8325. + sg_len, ivp);
  8326. + ret = crypto_ablkcipher_encrypt(req->crypto_req);
  8327. +
  8328. + } else { /*decrypt */
  8329. +
  8330. + if (crd->crd_flags & CRD_F_IV_EXPLICIT)
  8331. + ivp = crd->crd_iv;
  8332. + else
  8333. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  8334. + crd->crd_inject, ivsize, (caddr_t)ivp);
  8335. + ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
  8336. + sg_len, ivp);
  8337. + ret = crypto_ablkcipher_decrypt(req->crypto_req);
  8338. + }
  8339. +
  8340. + switch (ret) {
  8341. + case -EINPROGRESS:
  8342. + case -EBUSY:
  8343. + return;
  8344. + default:
  8345. + case 0:
  8346. + dprintk("crypto OP %s %d\n", ret ? "failed" : "success", ret);
  8347. + crp->crp_etype = ret;
  8348. + goto done;
  8349. + }
  8350. + } break;
  8351. +#endif /* HAVE_ABLKCIPHER */
  8352. +
  8353. + case SW_TYPE_BLKCIPHER: {
  8354. + unsigned char iv[EALG_MAX_BLOCK_LEN];
  8355. + unsigned char *ivp = iv;
  8356. + struct blkcipher_desc desc;
  8357. + int ivsize = crypto_blkcipher_ivsize(crypto_blkcipher_cast(sw->sw_tfm));
  8358. +
  8359. + if (sg_len < crypto_blkcipher_blocksize(
  8360. + crypto_blkcipher_cast(sw->sw_tfm))) {
  8361. + crp->crp_etype = EINVAL;
  8362. + dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
  8363. + sg_len, crypto_blkcipher_blocksize(
  8364. + crypto_blkcipher_cast(sw->sw_tfm)));
  8365. + goto done;
  8366. + }
  8367. +
  8368. + if (ivsize > sizeof(iv)) {
  8369. + crp->crp_etype = EINVAL;
  8370. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8371. + goto done;
  8372. + }
  8373. +
  8374. + if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
  8375. + int i, error;
  8376. +
  8377. + if (debug) {
  8378. + dprintk("%s key:", __FUNCTION__);
  8379. + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
  8380. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  8381. + crd->crd_key[i] & 0xff);
  8382. + dprintk("\n");
  8383. + }
  8384. + /* OCF doesn't enforce keys */
  8385. + crypto_blkcipher_set_flags(crypto_blkcipher_cast(sw->sw_tfm),
  8386. + CRYPTO_TFM_REQ_WEAK_KEY);
  8387. + error = crypto_blkcipher_setkey(
  8388. + crypto_blkcipher_cast(sw->sw_tfm), crd->crd_key,
  8389. + (crd->crd_klen + 7) / 8);
  8390. + if (error) {
  8391. + dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
  8392. + error, sw->sw_tfm->crt_flags);
  8393. + crp->crp_etype = -error;
  8394. + }
  8395. + }
  8396. +
  8397. + memset(&desc, 0, sizeof(desc));
  8398. + desc.tfm = crypto_blkcipher_cast(sw->sw_tfm);
  8399. +
  8400. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  8401. +
  8402. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  8403. + ivp = crd->crd_iv;
  8404. + } else {
  8405. + get_random_bytes(ivp, ivsize);
  8406. + }
  8407. + /*
  8408. + * do we have to copy the IV back to the buffer ?
  8409. + */
  8410. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  8411. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  8412. + crd->crd_inject, ivsize, (caddr_t)ivp);
  8413. + }
  8414. + desc.info = ivp;
  8415. + crypto_blkcipher_encrypt_iv(&desc, req->sg, req->sg, sg_len);
  8416. +
  8417. + } else { /*decrypt */
  8418. +
  8419. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  8420. + ivp = crd->crd_iv;
  8421. + } else {
  8422. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  8423. + crd->crd_inject, ivsize, (caddr_t)ivp);
  8424. + }
  8425. + desc.info = ivp;
  8426. + crypto_blkcipher_decrypt_iv(&desc, req->sg, req->sg, sg_len);
  8427. + }
  8428. + } break;
  8429. +
  8430. + case SW_TYPE_HMAC:
  8431. + case SW_TYPE_HASH:
  8432. + {
  8433. + char result[HASH_MAX_LEN];
  8434. + struct hash_desc desc;
  8435. +
  8436. + /* check we have room for the result */
  8437. + if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
  8438. + dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
  8439. + "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
  8440. + crd->crd_inject, sw->u.hmac.sw_mlen);
  8441. + crp->crp_etype = EINVAL;
  8442. + goto done;
  8443. + }
  8444. +
  8445. + memset(&desc, 0, sizeof(desc));
  8446. + desc.tfm = crypto_hash_cast(sw->sw_tfm);
  8447. +
  8448. + memset(result, 0, sizeof(result));
  8449. +
  8450. + if (sw->sw_type & SW_TYPE_HMAC) {
  8451. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
  8452. + crypto_hmac(sw->sw_tfm, sw->u.hmac.sw_key, &sw->u.hmac.sw_klen,
  8453. + req->sg, sg_num, result);
  8454. +#else
  8455. + crypto_hash_setkey(desc.tfm, sw->u.hmac.sw_key,
  8456. + sw->u.hmac.sw_klen);
  8457. + crypto_hash_digest(&desc, req->sg, sg_len, result);
  8458. +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
  8459. +
  8460. + } else { /* SW_TYPE_HASH */
  8461. + crypto_hash_digest(&desc, req->sg, sg_len, result);
  8462. + }
  8463. +
  8464. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  8465. + crd->crd_inject, sw->u.hmac.sw_mlen, result);
  8466. + }
  8467. + break;
  8468. +
  8469. + case SW_TYPE_COMP: {
  8470. + void *ibuf = NULL;
  8471. + void *obuf = sw->u.sw_comp_buf;
  8472. + int ilen = sg_len, olen = CRYPTO_MAX_DATA_LEN;
  8473. + int ret = 0;
  8474. +
  8475. + /*
  8476. + * we need to use an additional copy if there is more than one
  8477. + * input chunk since the kernel comp routines do not handle
  8478. + * SG yet. Otherwise we just use the input buffer as is.
  8479. + * Rather than allocate another buffer we just split the tmp
  8480. + * buffer we already have.
  8481. + * Perhaps we should just use zlib directly ?
  8482. + */
  8483. + if (sg_num > 1) {
  8484. + int blk;
  8485. +
  8486. + ibuf = obuf;
  8487. + for (blk = 0; blk < sg_num; blk++) {
  8488. + memcpy(obuf, sg_virt(&req->sg[blk]),
  8489. + req->sg[blk].length);
  8490. + obuf += req->sg[blk].length;
  8491. + }
  8492. + olen -= sg_len;
  8493. + } else
  8494. + ibuf = sg_virt(&req->sg[0]);
  8495. +
  8496. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* compress */
  8497. + ret = crypto_comp_compress(crypto_comp_cast(sw->sw_tfm),
  8498. + ibuf, ilen, obuf, &olen);
  8499. + if (!ret && olen > crd->crd_len) {
  8500. + dprintk("cryptosoft: ERANGE compress %d into %d\n",
  8501. + crd->crd_len, olen);
  8502. + if (swcr_fail_if_compression_grows)
  8503. + ret = ERANGE;
  8504. + }
  8505. + } else { /* decompress */
  8506. + ret = crypto_comp_decompress(crypto_comp_cast(sw->sw_tfm),
  8507. + ibuf, ilen, obuf, &olen);
  8508. + if (!ret && (olen + crd->crd_inject) > crp->crp_olen) {
  8509. + dprintk("cryptosoft: ETOOSMALL decompress %d into %d, "
  8510. + "space for %d,at offset %d\n",
  8511. + crd->crd_len, olen, crp->crp_olen, crd->crd_inject);
  8512. + ret = ETOOSMALL;
  8513. + }
  8514. + }
  8515. + if (ret)
  8516. + dprintk("%s,%d: ret = %d\n", __FILE__, __LINE__, ret);
  8517. +
  8518. + /*
  8519. + * on success copy result back,
  8520. + * linux crpyto API returns -errno, we need to fix that
  8521. + */
  8522. + crp->crp_etype = ret < 0 ? -ret : ret;
  8523. + if (ret == 0) {
  8524. + /* copy back the result and return it's size */
  8525. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  8526. + crd->crd_inject, olen, obuf);
  8527. + crp->crp_olen = olen;
  8528. + }
  8529. +
  8530. +
  8531. + } break;
  8532. +
  8533. + default:
  8534. + /* Unknown/unsupported algorithm */
  8535. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8536. + crp->crp_etype = EINVAL;
  8537. + goto done;
  8538. + }
  8539. +
  8540. +done:
  8541. + crypto_done(crp);
  8542. + kmem_cache_free(swcr_req_cache, req);
  8543. +}
  8544. +
  8545. +
  8546. +/*
  8547. + * Process a crypto request.
  8548. + */
  8549. +static int
  8550. +swcr_process(device_t dev, struct cryptop *crp, int hint)
  8551. +{
  8552. + struct swcr_req *req = NULL;
  8553. + u_int32_t lid;
  8554. +
  8555. + dprintk("%s()\n", __FUNCTION__);
  8556. + /* Sanity check */
  8557. + if (crp == NULL) {
  8558. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8559. + return EINVAL;
  8560. + }
  8561. +
  8562. + crp->crp_etype = 0;
  8563. +
  8564. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  8565. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8566. + crp->crp_etype = EINVAL;
  8567. + goto done;
  8568. + }
  8569. +
  8570. + lid = crp->crp_sid & 0xffffffff;
  8571. + if (lid >= swcr_sesnum || lid == 0 || swcr_sessions == NULL ||
  8572. + swcr_sessions[lid] == NULL) {
  8573. + crp->crp_etype = ENOENT;
  8574. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  8575. + goto done;
  8576. + }
  8577. +
  8578. + /*
  8579. + * do some error checking outside of the loop for SKB and IOV processing
  8580. + * this leaves us with valid skb or uiop pointers for later
  8581. + */
  8582. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  8583. + struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
  8584. + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
  8585. + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
  8586. + skb_shinfo(skb)->nr_frags);
  8587. + goto done;
  8588. + }
  8589. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  8590. + struct uio *uiop = (struct uio *) crp->crp_buf;
  8591. + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
  8592. + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
  8593. + uiop->uio_iovcnt);
  8594. + goto done;
  8595. + }
  8596. + }
  8597. +
  8598. + /*
  8599. + * setup a new request ready for queuing
  8600. + */
  8601. + req = kmem_cache_alloc(swcr_req_cache, SLAB_ATOMIC);
  8602. + if (req == NULL) {
  8603. + dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
  8604. + crp->crp_etype = ENOMEM;
  8605. + goto done;
  8606. + }
  8607. + memset(req, 0, sizeof(*req));
  8608. +
  8609. + req->sw_head = swcr_sessions[lid];
  8610. + req->crp = crp;
  8611. + req->crd = crp->crp_desc;
  8612. +
  8613. + swcr_process_req(req);
  8614. + return 0;
  8615. +
  8616. +done:
  8617. + crypto_done(crp);
  8618. + if (req)
  8619. + kmem_cache_free(swcr_req_cache, req);
  8620. + return 0;
  8621. +}
  8622. +
  8623. +
  8624. +static int
  8625. +cryptosoft_init(void)
  8626. +{
  8627. + int i, sw_type, mode;
  8628. + char *algo;
  8629. +
  8630. + dprintk("%s(%p)\n", __FUNCTION__, cryptosoft_init);
  8631. +
  8632. + swcr_req_cache = kmem_cache_create("cryptosoft_req",
  8633. + sizeof(struct swcr_req), 0, SLAB_HWCACHE_ALIGN, NULL
  8634. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  8635. + , NULL
  8636. +#endif
  8637. + );
  8638. + if (!swcr_req_cache) {
  8639. + printk("cryptosoft: failed to create request cache\n");
  8640. + return -ENOENT;
  8641. + }
  8642. +
  8643. + softc_device_init(&swcr_softc, "cryptosoft", 0, swcr_methods);
  8644. +
  8645. + swcr_id = crypto_get_driverid(softc_get_device(&swcr_softc),
  8646. + CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
  8647. + if (swcr_id < 0) {
  8648. + printk("cryptosoft: Software crypto device cannot initialize!");
  8649. + return -ENODEV;
  8650. + }
  8651. +
  8652. +#define REGISTER(alg) \
  8653. + crypto_register(swcr_id, alg, 0,0)
  8654. +
  8655. + for (i = 0; i < sizeof(crypto_details)/sizeof(crypto_details[0]); i++) {
  8656. + int found;
  8657. +
  8658. + algo = crypto_details[i].alg_name;
  8659. + if (!algo || !*algo) {
  8660. + dprintk("%s:Algorithm %d not supported\n", __FUNCTION__, i);
  8661. + continue;
  8662. + }
  8663. +
  8664. + mode = crypto_details[i].mode;
  8665. + sw_type = crypto_details[i].sw_type;
  8666. +
  8667. + found = 0;
  8668. + switch (sw_type & SW_TYPE_ALG_MASK) {
  8669. + case SW_TYPE_CIPHER:
  8670. + found = crypto_has_cipher(algo, 0, CRYPTO_ALG_ASYNC);
  8671. + break;
  8672. + case SW_TYPE_HMAC:
  8673. + found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
  8674. + break;
  8675. + case SW_TYPE_HASH:
  8676. + found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
  8677. + break;
  8678. + case SW_TYPE_COMP:
  8679. + found = crypto_has_comp(algo, 0, CRYPTO_ALG_ASYNC);
  8680. + break;
  8681. + case SW_TYPE_BLKCIPHER:
  8682. + found = crypto_has_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);
  8683. + if (!found && !swcr_no_ablk)
  8684. + found = crypto_has_ablkcipher(algo, 0, 0);
  8685. + break;
  8686. + }
  8687. + if (found) {
  8688. + REGISTER(i);
  8689. + } else {
  8690. + dprintk("%s:Algorithm Type %d not supported (algorithm %d:'%s')\n",
  8691. + __FUNCTION__, sw_type, i, algo);
  8692. + }
  8693. + }
  8694. + return 0;
  8695. +}
  8696. +
  8697. +static void
  8698. +cryptosoft_exit(void)
  8699. +{
  8700. + dprintk("%s()\n", __FUNCTION__);
  8701. + crypto_unregister_all(swcr_id);
  8702. + swcr_id = -1;
  8703. + kmem_cache_destroy(swcr_req_cache);
  8704. +}
  8705. +
  8706. +late_initcall(cryptosoft_init);
  8707. +module_exit(cryptosoft_exit);
  8708. +
  8709. +MODULE_LICENSE("Dual BSD/GPL");
  8710. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  8711. +MODULE_DESCRIPTION("Cryptosoft (OCF module for kernel crypto)");
  8712. diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/icp_asym.c linux-2.6.36/crypto/ocf/ep80579/icp_asym.c
  8713. --- linux-2.6.36.orig/crypto/ocf/ep80579/icp_asym.c 1970-01-01 01:00:00.000000000 +0100
  8714. +++ linux-2.6.36/crypto/ocf/ep80579/icp_asym.c 2010-11-09 20:28:04.572486503 +0100
  8715. @@ -0,0 +1,1334 @@
  8716. +/***************************************************************************
  8717. + *
  8718. + * This file is provided under a dual BSD/GPLv2 license. When using or
  8719. + * redistributing this file, you may do so under either license.
  8720. + *
  8721. + * GPL LICENSE SUMMARY
  8722. + *
  8723. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  8724. + *
  8725. + * This program is free software; you can redistribute it and/or modify
  8726. + * it under the terms of version 2 of the GNU General Public License as
  8727. + * published by the Free Software Foundation.
  8728. + *
  8729. + * This program is distributed in the hope that it will be useful, but
  8730. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  8731. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  8732. + * General Public License for more details.
  8733. + *
  8734. + * You should have received a copy of the GNU General Public License
  8735. + * along with this program; if not, write to the Free Software
  8736. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  8737. + * The full GNU General Public License is included in this distribution
  8738. + * in the file called LICENSE.GPL.
  8739. + *
  8740. + * Contact Information:
  8741. + * Intel Corporation
  8742. + *
  8743. + * BSD LICENSE
  8744. + *
  8745. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  8746. + * All rights reserved.
  8747. + *
  8748. + * Redistribution and use in source and binary forms, with or without
  8749. + * modification, are permitted provided that the following conditions
  8750. + * are met:
  8751. + *
  8752. + * * Redistributions of source code must retain the above copyright
  8753. + * notice, this list of conditions and the following disclaimer.
  8754. + * * Redistributions in binary form must reproduce the above copyright
  8755. + * notice, this list of conditions and the following disclaimer in
  8756. + * the documentation and/or other materials provided with the
  8757. + * distribution.
  8758. + * * Neither the name of Intel Corporation nor the names of its
  8759. + * contributors may be used to endorse or promote products derived
  8760. + * from this software without specific prior written permission.
  8761. + *
  8762. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  8763. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  8764. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8765. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  8766. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8767. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  8768. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  8769. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  8770. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  8771. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  8772. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  8773. + *
  8774. + *
  8775. + * version: Security.L.1.0.2-229
  8776. + *
  8777. + ***************************************************************************/
  8778. +
  8779. +#include "icp_ocf.h"
  8780. +
  8781. +/*The following define values (containing the word 'INDEX') are used to find
  8782. +the index of each input buffer of the crypto_kop struct (see OCF cryptodev.h).
  8783. +These values were found through analysis of the OCF OpenSSL patch. If the
  8784. +calling program uses different input buffer positions, these defines will have
  8785. +to be changed.*/
  8786. +
  8787. +/*DIFFIE HELLMAN buffer index values*/
  8788. +#define ICP_DH_KRP_PARAM_PRIME_INDEX (0)
  8789. +#define ICP_DH_KRP_PARAM_BASE_INDEX (1)
  8790. +#define ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX (2)
  8791. +#define ICP_DH_KRP_PARAM_RESULT_INDEX (3)
  8792. +
  8793. +/*MOD EXP buffer index values*/
  8794. +#define ICP_MOD_EXP_KRP_PARAM_BASE_INDEX (0)
  8795. +#define ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX (1)
  8796. +#define ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX (2)
  8797. +#define ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX (3)
  8798. +
  8799. +/*MOD EXP CRT buffer index values*/
  8800. +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX (0)
  8801. +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX (1)
  8802. +#define ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX (2)
  8803. +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX (3)
  8804. +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX (4)
  8805. +#define ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX (5)
  8806. +#define ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX (6)
  8807. +
  8808. +/*DSA sign buffer index values*/
  8809. +#define ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX (0)
  8810. +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX (1)
  8811. +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX (2)
  8812. +#define ICP_DSA_SIGN_KRP_PARAM_G_INDEX (3)
  8813. +#define ICP_DSA_SIGN_KRP_PARAM_X_INDEX (4)
  8814. +#define ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX (5)
  8815. +#define ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX (6)
  8816. +
  8817. +/*DSA verify buffer index values*/
  8818. +#define ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX (0)
  8819. +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX (1)
  8820. +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX (2)
  8821. +#define ICP_DSA_VERIFY_KRP_PARAM_G_INDEX (3)
  8822. +#define ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX (4)
  8823. +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX (5)
  8824. +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX (6)
  8825. +
  8826. +/*DSA sign prime Q vs random number K size check values*/
  8827. +#define DONT_RUN_LESS_THAN_CHECK (0)
  8828. +#define FAIL_A_IS_GREATER_THAN_B (1)
  8829. +#define FAIL_A_IS_EQUAL_TO_B (1)
  8830. +#define SUCCESS_A_IS_LESS_THAN_B (0)
  8831. +#define DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS (500)
  8832. +
  8833. +/* We need to set a cryptokp success value just in case it is set or allocated
  8834. + and not set to zero outside of this module */
  8835. +#define CRYPTO_OP_SUCCESS (0)
  8836. +
  8837. +/*Function to compute Diffie Hellman (DH) phase 1 or phase 2 key values*/
  8838. +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp);
  8839. +
  8840. +/*Function to compute a Modular Exponentiation (Mod Exp)*/
  8841. +static int icp_ocfDrvModExp(struct cryptkop *krp);
  8842. +
  8843. +/*Function to compute a Mod Exp using the Chinease Remainder Theorem*/
  8844. +static int icp_ocfDrvModExpCRT(struct cryptkop *krp);
  8845. +
  8846. +/*Helper function to compute whether the first big number argument is less than
  8847. + the second big number argument */
  8848. +static int
  8849. +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck);
  8850. +
  8851. +/*Function to sign an input with DSA R and S keys*/
  8852. +static int icp_ocfDrvDsaSign(struct cryptkop *krp);
  8853. +
  8854. +/*Function to Verify a DSA buffer signature*/
  8855. +static int icp_ocfDrvDsaVerify(struct cryptkop *krp);
  8856. +
  8857. +/*Callback function for DH operation*/
  8858. +static void
  8859. +icp_ocfDrvDhP1CallBack(void *callbackTag,
  8860. + CpaStatus status,
  8861. + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV);
  8862. +
  8863. +/*Callback function for ME operation*/
  8864. +static void
  8865. +icp_ocfDrvModExpCallBack(void *callbackTag,
  8866. + CpaStatus status,
  8867. + void *pOpData, CpaFlatBuffer * pResult);
  8868. +
  8869. +/*Callback function for ME CRT operation*/
  8870. +static void
  8871. +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
  8872. + CpaStatus status,
  8873. + void *pOpData, CpaFlatBuffer * pOutputData);
  8874. +
  8875. +/*Callback function for DSA sign operation*/
  8876. +static void
  8877. +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
  8878. + CpaStatus status,
  8879. + void *pOpData,
  8880. + CpaBoolean protocolStatus,
  8881. + CpaFlatBuffer * pR, CpaFlatBuffer * pS);
  8882. +
  8883. +/*Callback function for DSA Verify operation*/
  8884. +static void
  8885. +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
  8886. + CpaStatus status,
  8887. + void *pOpData, CpaBoolean verifyStatus);
  8888. +
  8889. +/* Name : icp_ocfDrvPkeProcess
  8890. + *
  8891. + * Description : This function will choose which PKE process to follow
  8892. + * based on the input arguments
  8893. + */
  8894. +int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint)
  8895. +{
  8896. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  8897. +
  8898. + if (NULL == krp) {
  8899. + DPRINTK("%s(): Invalid input parameters, cryptkop = %p\n",
  8900. + __FUNCTION__, krp);
  8901. + return EINVAL;
  8902. + }
  8903. +
  8904. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  8905. + krp->krp_status = ECANCELED;
  8906. + return ECANCELED;
  8907. + }
  8908. +
  8909. + switch (krp->krp_op) {
  8910. + case CRK_DH_COMPUTE_KEY:
  8911. + DPRINTK("%s() doing DH_COMPUTE_KEY\n", __FUNCTION__);
  8912. + lacStatus = icp_ocfDrvDHComputeKey(krp);
  8913. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8914. + EPRINTK("%s(): icp_ocfDrvDHComputeKey failed "
  8915. + "(%d).\n", __FUNCTION__, lacStatus);
  8916. + krp->krp_status = ECANCELED;
  8917. + return ECANCELED;
  8918. + }
  8919. +
  8920. + break;
  8921. +
  8922. + case CRK_MOD_EXP:
  8923. + DPRINTK("%s() doing MOD_EXP \n", __FUNCTION__);
  8924. + lacStatus = icp_ocfDrvModExp(krp);
  8925. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8926. + EPRINTK("%s(): icp_ocfDrvModExp failed (%d).\n",
  8927. + __FUNCTION__, lacStatus);
  8928. + krp->krp_status = ECANCELED;
  8929. + return ECANCELED;
  8930. + }
  8931. +
  8932. + break;
  8933. +
  8934. + case CRK_MOD_EXP_CRT:
  8935. + DPRINTK("%s() doing MOD_EXP_CRT \n", __FUNCTION__);
  8936. + lacStatus = icp_ocfDrvModExpCRT(krp);
  8937. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8938. + EPRINTK("%s(): icp_ocfDrvModExpCRT "
  8939. + "failed (%d).\n", __FUNCTION__, lacStatus);
  8940. + krp->krp_status = ECANCELED;
  8941. + return ECANCELED;
  8942. + }
  8943. +
  8944. + break;
  8945. +
  8946. + case CRK_DSA_SIGN:
  8947. + DPRINTK("%s() doing DSA_SIGN \n", __FUNCTION__);
  8948. + lacStatus = icp_ocfDrvDsaSign(krp);
  8949. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8950. + EPRINTK("%s(): icp_ocfDrvDsaSign "
  8951. + "failed (%d).\n", __FUNCTION__, lacStatus);
  8952. + krp->krp_status = ECANCELED;
  8953. + return ECANCELED;
  8954. + }
  8955. +
  8956. + break;
  8957. +
  8958. + case CRK_DSA_VERIFY:
  8959. + DPRINTK("%s() doing DSA_VERIFY \n", __FUNCTION__);
  8960. + lacStatus = icp_ocfDrvDsaVerify(krp);
  8961. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8962. + EPRINTK("%s(): icp_ocfDrvDsaVerify "
  8963. + "failed (%d).\n", __FUNCTION__, lacStatus);
  8964. + krp->krp_status = ECANCELED;
  8965. + return ECANCELED;
  8966. + }
  8967. +
  8968. + break;
  8969. +
  8970. + default:
  8971. + EPRINTK("%s(): Asymettric function not "
  8972. + "supported (%d).\n", __FUNCTION__, krp->krp_op);
  8973. + krp->krp_status = EOPNOTSUPP;
  8974. + return EOPNOTSUPP;
  8975. + }
  8976. +
  8977. + return ICP_OCF_DRV_STATUS_SUCCESS;
  8978. +}
  8979. +
  8980. +/* Name : icp_ocfDrvSwapBytes
  8981. + *
  8982. + * Description : This function is used to swap the byte order of a buffer.
  8983. + * It has been seen that in general we are passed little endian byte order
  8984. + * buffers, but LAC only accepts big endian byte order buffers.
  8985. + */
  8986. +static void inline icp_ocfDrvSwapBytes(u_int8_t * num, u_int32_t buff_len_bytes)
  8987. +{
  8988. +
  8989. + int i;
  8990. + u_int8_t *end_ptr;
  8991. + u_int8_t hold_val;
  8992. +
  8993. + end_ptr = num + (buff_len_bytes - 1);
  8994. + buff_len_bytes = buff_len_bytes >> 1;
  8995. + for (i = 0; i < buff_len_bytes; i++) {
  8996. + hold_val = *num;
  8997. + *num = *end_ptr;
  8998. + num++;
  8999. + *end_ptr = hold_val;
  9000. + end_ptr--;
  9001. + }
  9002. +}
  9003. +
  9004. +/* Name : icp_ocfDrvDHComputeKey
  9005. + *
  9006. + * Description : This function will map Diffie Hellman calls from OCF
  9007. + * to the LAC API. OCF uses this function for Diffie Hellman Phase1 and
  9008. + * Phase2. LAC has a separate Diffie Hellman Phase2 call, however both phases
  9009. + * break down to a modular exponentiation.
  9010. + */
  9011. +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp)
  9012. +{
  9013. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  9014. + void *callbackTag = NULL;
  9015. + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
  9016. + CpaFlatBuffer *pLocalOctetStringPV = NULL;
  9017. + uint32_t dh_prime_len_bytes = 0, dh_prime_len_bits = 0;
  9018. +
  9019. + /* Input checks - check prime is a multiple of 8 bits to allow for
  9020. + allocation later */
  9021. + dh_prime_len_bits =
  9022. + (krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_nbits);
  9023. +
  9024. + /* LAC can reject prime lengths based on prime key sizes, we just
  9025. + need to make sure we can allocate space for the base and
  9026. + exponent buffers correctly */
  9027. + if ((dh_prime_len_bits % NUM_BITS_IN_BYTE) != 0) {
  9028. + APRINTK("%s(): Warning Prime number buffer size is not a "
  9029. + "multiple of 8 bits\n", __FUNCTION__);
  9030. + }
  9031. +
  9032. + /* Result storage space should be the same size as the prime as this
  9033. + value can take up the same amount of storage space */
  9034. + if (dh_prime_len_bits !=
  9035. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits) {
  9036. + DPRINTK("%s(): Return Buffer must be the same size "
  9037. + "as the Prime buffer\n", __FUNCTION__);
  9038. + krp->krp_status = EINVAL;
  9039. + return EINVAL;
  9040. + }
  9041. + /* Switch to size in bytes */
  9042. + BITS_TO_BYTES(dh_prime_len_bytes, dh_prime_len_bits);
  9043. +
  9044. + callbackTag = krp;
  9045. +
  9046. +/*All allocations are set to ICP_M_NOWAIT due to the possibility of getting
  9047. +called in interrupt context*/
  9048. + pPhase1OpData = icp_kmem_cache_zalloc(drvDH_zone, ICP_M_NOWAIT);
  9049. + if (NULL == pPhase1OpData) {
  9050. + APRINTK("%s():Failed to get memory for key gen data\n",
  9051. + __FUNCTION__);
  9052. + krp->krp_status = ENOMEM;
  9053. + return ENOMEM;
  9054. + }
  9055. +
  9056. + pLocalOctetStringPV =
  9057. + icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  9058. + if (NULL == pLocalOctetStringPV) {
  9059. + APRINTK("%s():Failed to get memory for pLocalOctetStringPV\n",
  9060. + __FUNCTION__);
  9061. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  9062. + krp->krp_status = ENOMEM;
  9063. + return ENOMEM;
  9064. + }
  9065. +
  9066. + /* Link parameters */
  9067. + pPhase1OpData->primeP.pData =
  9068. + krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_p;
  9069. +
  9070. + pPhase1OpData->primeP.dataLenInBytes = dh_prime_len_bytes;
  9071. +
  9072. + icp_ocfDrvSwapBytes(pPhase1OpData->primeP.pData, dh_prime_len_bytes);
  9073. +
  9074. + pPhase1OpData->baseG.pData =
  9075. + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_p;
  9076. +
  9077. + BITS_TO_BYTES(pPhase1OpData->baseG.dataLenInBytes,
  9078. + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_nbits);
  9079. +
  9080. + icp_ocfDrvSwapBytes(pPhase1OpData->baseG.pData,
  9081. + pPhase1OpData->baseG.dataLenInBytes);
  9082. +
  9083. + pPhase1OpData->privateValueX.pData =
  9084. + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].crp_p;
  9085. +
  9086. + BITS_TO_BYTES(pPhase1OpData->privateValueX.dataLenInBytes,
  9087. + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].
  9088. + crp_nbits);
  9089. +
  9090. + icp_ocfDrvSwapBytes(pPhase1OpData->privateValueX.pData,
  9091. + pPhase1OpData->privateValueX.dataLenInBytes);
  9092. +
  9093. + /* Output parameters */
  9094. + pLocalOctetStringPV->pData =
  9095. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_p;
  9096. +
  9097. + BITS_TO_BYTES(pLocalOctetStringPV->dataLenInBytes,
  9098. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits);
  9099. +
  9100. + lacStatus = cpaCyDhKeyGenPhase1(CPA_INSTANCE_HANDLE_SINGLE,
  9101. + icp_ocfDrvDhP1CallBack,
  9102. + callbackTag, pPhase1OpData,
  9103. + pLocalOctetStringPV);
  9104. +
  9105. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9106. + EPRINTK("%s(): DH Phase 1 Key Gen failed (%d).\n",
  9107. + __FUNCTION__, lacStatus);
  9108. + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
  9109. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  9110. + }
  9111. +
  9112. + return lacStatus;
  9113. +}
  9114. +
  9115. +/* Name : icp_ocfDrvModExp
  9116. + *
  9117. + * Description : This function will map ordinary Modular Exponentiation calls
  9118. + * from OCF to the LAC API.
  9119. + *
  9120. + */
  9121. +static int icp_ocfDrvModExp(struct cryptkop *krp)
  9122. +{
  9123. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  9124. + void *callbackTag = NULL;
  9125. + CpaCyLnModExpOpData *pModExpOpData = NULL;
  9126. + CpaFlatBuffer *pResult = NULL;
  9127. +
  9128. + if ((krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits %
  9129. + NUM_BITS_IN_BYTE) != 0) {
  9130. + DPRINTK("%s(): Warning - modulus buffer size (%d) is not a "
  9131. + "multiple of 8 bits\n", __FUNCTION__,
  9132. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
  9133. + crp_nbits);
  9134. + }
  9135. +
  9136. + /* Result storage space should be the same size as the prime as this
  9137. + value can take up the same amount of storage space */
  9138. + if (krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits >
  9139. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_nbits) {
  9140. + APRINTK("%s(): Return Buffer size must be the same or"
  9141. + " greater than the Modulus buffer\n", __FUNCTION__);
  9142. + krp->krp_status = EINVAL;
  9143. + return EINVAL;
  9144. + }
  9145. +
  9146. + callbackTag = krp;
  9147. +
  9148. + pModExpOpData = icp_kmem_cache_zalloc(drvLnModExp_zone, ICP_M_NOWAIT);
  9149. + if (NULL == pModExpOpData) {
  9150. + APRINTK("%s():Failed to get memory for key gen data\n",
  9151. + __FUNCTION__);
  9152. + krp->krp_status = ENOMEM;
  9153. + return ENOMEM;
  9154. + }
  9155. +
  9156. + pResult = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  9157. + if (NULL == pResult) {
  9158. + APRINTK("%s():Failed to get memory for ModExp result\n",
  9159. + __FUNCTION__);
  9160. + ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);
  9161. + krp->krp_status = ENOMEM;
  9162. + return ENOMEM;
  9163. + }
  9164. +
  9165. + /* Link parameters */
  9166. + pModExpOpData->modulus.pData =
  9167. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_p;
  9168. + BITS_TO_BYTES(pModExpOpData->modulus.dataLenInBytes,
  9169. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
  9170. + crp_nbits);
  9171. +
  9172. + icp_ocfDrvSwapBytes(pModExpOpData->modulus.pData,
  9173. + pModExpOpData->modulus.dataLenInBytes);
  9174. +
  9175. + DPRINTK("%s : base (%d)\n", __FUNCTION__, krp->
  9176. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits);
  9177. + pModExpOpData->base.pData =
  9178. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_p;
  9179. + BITS_TO_BYTES(pModExpOpData->base.dataLenInBytes,
  9180. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  9181. + crp_nbits);
  9182. + icp_ocfDrvSwapBytes(pModExpOpData->base.pData,
  9183. + pModExpOpData->base.dataLenInBytes);
  9184. +
  9185. + pModExpOpData->exponent.pData =
  9186. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].crp_p;
  9187. + BITS_TO_BYTES(pModExpOpData->exponent.dataLenInBytes,
  9188. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].
  9189. + crp_nbits);
  9190. +
  9191. + icp_ocfDrvSwapBytes(pModExpOpData->exponent.pData,
  9192. + pModExpOpData->exponent.dataLenInBytes);
  9193. + /* Output parameters */
  9194. + pResult->pData =
  9195. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_p,
  9196. + BITS_TO_BYTES(pResult->dataLenInBytes,
  9197. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].
  9198. + crp_nbits);
  9199. +
  9200. + lacStatus = cpaCyLnModExp(CPA_INSTANCE_HANDLE_SINGLE,
  9201. + icp_ocfDrvModExpCallBack,
  9202. + callbackTag, pModExpOpData, pResult);
  9203. +
  9204. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9205. + EPRINTK("%s(): Mod Exp Operation failed (%d).\n",
  9206. + __FUNCTION__, lacStatus);
  9207. + krp->krp_status = ECANCELED;
  9208. + icp_ocfDrvFreeFlatBuffer(pResult);
  9209. + ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);
  9210. + }
  9211. +
  9212. + return lacStatus;
  9213. +}
  9214. +
  9215. +/* Name : icp_ocfDrvModExpCRT
  9216. + *
  9217. + * Description : This function will map ordinary Modular Exponentiation Chinese
  9218. + * Remainder Theorem implementaion calls from OCF to the LAC API.
  9219. + *
  9220. + * Note : Mod Exp CRT for this driver is accelerated through LAC RSA type 2
  9221. + * decrypt operation. Therefore P and Q input values must always be prime
  9222. + * numbers. Although basic primality checks are done in LAC, it is up to the
  9223. + * user to do any correct prime number checking before passing the inputs.
  9224. + */
  9225. +static int icp_ocfDrvModExpCRT(struct cryptkop *krp)
  9226. +{
  9227. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  9228. + CpaCyRsaDecryptOpData *rsaDecryptOpData = NULL;
  9229. + void *callbackTag = NULL;
  9230. + CpaFlatBuffer *pOutputData = NULL;
  9231. +
  9232. + /*Parameter input checks are all done by LAC, no need to repeat
  9233. + them here. */
  9234. + callbackTag = krp;
  9235. +
  9236. + rsaDecryptOpData =
  9237. + icp_kmem_cache_zalloc(drvRSADecrypt_zone, ICP_M_NOWAIT);
  9238. + if (NULL == rsaDecryptOpData) {
  9239. + APRINTK("%s():Failed to get memory"
  9240. + " for MOD EXP CRT Op data struct\n", __FUNCTION__);
  9241. + krp->krp_status = ENOMEM;
  9242. + return ENOMEM;
  9243. + }
  9244. +
  9245. + rsaDecryptOpData->pRecipientPrivateKey
  9246. + = icp_kmem_cache_zalloc(drvRSAPrivateKey_zone, ICP_M_NOWAIT);
  9247. + if (NULL == rsaDecryptOpData->pRecipientPrivateKey) {
  9248. + APRINTK("%s():Failed to get memory for MOD EXP CRT"
  9249. + " private key values struct\n", __FUNCTION__);
  9250. + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
  9251. + krp->krp_status = ENOMEM;
  9252. + return ENOMEM;
  9253. + }
  9254. +
  9255. + rsaDecryptOpData->pRecipientPrivateKey->
  9256. + version = CPA_CY_RSA_VERSION_TWO_PRIME;
  9257. + rsaDecryptOpData->pRecipientPrivateKey->
  9258. + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
  9259. +
  9260. + pOutputData = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  9261. + if (NULL == pOutputData) {
  9262. + APRINTK("%s():Failed to get memory"
  9263. + " for MOD EXP CRT output data\n", __FUNCTION__);
  9264. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  9265. + rsaDecryptOpData->pRecipientPrivateKey);
  9266. + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
  9267. + krp->krp_status = ENOMEM;
  9268. + return ENOMEM;
  9269. + }
  9270. +
  9271. + rsaDecryptOpData->pRecipientPrivateKey->
  9272. + version = CPA_CY_RSA_VERSION_TWO_PRIME;
  9273. + rsaDecryptOpData->pRecipientPrivateKey->
  9274. + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
  9275. +
  9276. + /* Link parameters */
  9277. + rsaDecryptOpData->inputData.pData =
  9278. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].crp_p;
  9279. + BITS_TO_BYTES(rsaDecryptOpData->inputData.dataLenInBytes,
  9280. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].
  9281. + crp_nbits);
  9282. +
  9283. + icp_ocfDrvSwapBytes(rsaDecryptOpData->inputData.pData,
  9284. + rsaDecryptOpData->inputData.dataLenInBytes);
  9285. +
  9286. + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime1P.pData =
  9287. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].crp_p;
  9288. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  9289. + prime1P.dataLenInBytes,
  9290. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].
  9291. + crp_nbits);
  9292. +
  9293. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  9294. + privateKeyRep2.prime1P.pData,
  9295. + rsaDecryptOpData->pRecipientPrivateKey->
  9296. + privateKeyRep2.prime1P.dataLenInBytes);
  9297. +
  9298. + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime2Q.pData =
  9299. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  9300. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  9301. + prime2Q.dataLenInBytes,
  9302. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].
  9303. + crp_nbits);
  9304. +
  9305. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  9306. + privateKeyRep2.prime2Q.pData,
  9307. + rsaDecryptOpData->pRecipientPrivateKey->
  9308. + privateKeyRep2.prime2Q.dataLenInBytes);
  9309. +
  9310. + rsaDecryptOpData->pRecipientPrivateKey->
  9311. + privateKeyRep2.exponent1Dp.pData =
  9312. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].crp_p;
  9313. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  9314. + exponent1Dp.dataLenInBytes,
  9315. + krp->
  9316. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].
  9317. + crp_nbits);
  9318. +
  9319. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  9320. + privateKeyRep2.exponent1Dp.pData,
  9321. + rsaDecryptOpData->pRecipientPrivateKey->
  9322. + privateKeyRep2.exponent1Dp.dataLenInBytes);
  9323. +
  9324. + rsaDecryptOpData->pRecipientPrivateKey->
  9325. + privateKeyRep2.exponent2Dq.pData =
  9326. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].crp_p;
  9327. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
  9328. + privateKeyRep2.exponent2Dq.dataLenInBytes,
  9329. + krp->
  9330. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].
  9331. + crp_nbits);
  9332. +
  9333. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  9334. + privateKeyRep2.exponent2Dq.pData,
  9335. + rsaDecryptOpData->pRecipientPrivateKey->
  9336. + privateKeyRep2.exponent2Dq.dataLenInBytes);
  9337. +
  9338. + rsaDecryptOpData->pRecipientPrivateKey->
  9339. + privateKeyRep2.coefficientQInv.pData =
  9340. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].crp_p;
  9341. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
  9342. + privateKeyRep2.coefficientQInv.dataLenInBytes,
  9343. + krp->
  9344. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].
  9345. + crp_nbits);
  9346. +
  9347. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  9348. + privateKeyRep2.coefficientQInv.pData,
  9349. + rsaDecryptOpData->pRecipientPrivateKey->
  9350. + privateKeyRep2.coefficientQInv.dataLenInBytes);
  9351. +
  9352. + /* Output Parameter */
  9353. + pOutputData->pData =
  9354. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].crp_p;
  9355. + BITS_TO_BYTES(pOutputData->dataLenInBytes,
  9356. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].
  9357. + crp_nbits);
  9358. +
  9359. + lacStatus = cpaCyRsaDecrypt(CPA_INSTANCE_HANDLE_SINGLE,
  9360. + icp_ocfDrvModExpCRTCallBack,
  9361. + callbackTag, rsaDecryptOpData, pOutputData);
  9362. +
  9363. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9364. + EPRINTK("%s(): Mod Exp CRT Operation failed (%d).\n",
  9365. + __FUNCTION__, lacStatus);
  9366. + krp->krp_status = ECANCELED;
  9367. + icp_ocfDrvFreeFlatBuffer(pOutputData);
  9368. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  9369. + rsaDecryptOpData->pRecipientPrivateKey);
  9370. + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
  9371. + }
  9372. +
  9373. + return lacStatus;
  9374. +}
  9375. +
  9376. +/* Name : icp_ocfDrvCheckALessThanB
  9377. + *
  9378. + * Description : This function will check whether the first argument is less
  9379. + * than the second. It is used to check whether the DSA RS sign Random K
  9380. + * value is less than the Prime Q value (as defined in the specification)
  9381. + *
  9382. + */
  9383. +static int
  9384. +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck)
  9385. +{
  9386. +
  9387. + uint8_t *MSB_K = pK->pData;
  9388. + uint8_t *MSB_Q = pQ->pData;
  9389. + uint32_t buffer_lengths_in_bytes = pQ->dataLenInBytes;
  9390. +
  9391. + if (DONT_RUN_LESS_THAN_CHECK == *doCheck) {
  9392. + return FAIL_A_IS_GREATER_THAN_B;
  9393. + }
  9394. +
  9395. +/*Check MSBs
  9396. +if A == B, check next MSB
  9397. +if A > B, return A_IS_GREATER_THAN_B
  9398. +if A < B, return A_IS_LESS_THAN_B (success)
  9399. +*/
  9400. + while (*MSB_K == *MSB_Q) {
  9401. + MSB_K++;
  9402. + MSB_Q++;
  9403. +
  9404. + buffer_lengths_in_bytes--;
  9405. + if (0 == buffer_lengths_in_bytes) {
  9406. + DPRINTK("%s() Buffers have equal value!!\n",
  9407. + __FUNCTION__);
  9408. + return FAIL_A_IS_EQUAL_TO_B;
  9409. + }
  9410. +
  9411. + }
  9412. +
  9413. + if (*MSB_K < *MSB_Q) {
  9414. + return SUCCESS_A_IS_LESS_THAN_B;
  9415. + } else {
  9416. + return FAIL_A_IS_GREATER_THAN_B;
  9417. + }
  9418. +
  9419. +}
  9420. +
  9421. +/* Name : icp_ocfDrvDsaSign
  9422. + *
  9423. + * Description : This function will map DSA RS Sign from OCF to the LAC API.
  9424. + *
  9425. + * NOTE: From looking at OCF patch to OpenSSL and even the number of input
  9426. + * parameters, OCF expects us to generate the random seed value. This value
  9427. + * is generated and passed to LAC, however the number is discared in the
  9428. + * callback and not returned to the user.
  9429. + */
  9430. +static int icp_ocfDrvDsaSign(struct cryptkop *krp)
  9431. +{
  9432. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  9433. + CpaCyDsaRSSignOpData *dsaRsSignOpData = NULL;
  9434. + void *callbackTag = NULL;
  9435. + CpaCyRandGenOpData randGenOpData;
  9436. + int primeQSizeInBytes = 0;
  9437. + int doCheck = 0;
  9438. + CpaFlatBuffer randData;
  9439. + CpaBoolean protocolStatus = CPA_FALSE;
  9440. + CpaFlatBuffer *pR = NULL;
  9441. + CpaFlatBuffer *pS = NULL;
  9442. +
  9443. + callbackTag = krp;
  9444. +
  9445. + BITS_TO_BYTES(primeQSizeInBytes,
  9446. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
  9447. + crp_nbits);
  9448. +
  9449. + if (DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES != primeQSizeInBytes) {
  9450. + APRINTK("%s(): DSA PRIME Q size not equal to the "
  9451. + "FIPS defined 20bytes, = %d\n",
  9452. + __FUNCTION__, primeQSizeInBytes);
  9453. + krp->krp_status = EDOM;
  9454. + return EDOM;
  9455. + }
  9456. +
  9457. + dsaRsSignOpData =
  9458. + icp_kmem_cache_zalloc(drvDSARSSign_zone, ICP_M_NOWAIT);
  9459. + if (NULL == dsaRsSignOpData) {
  9460. + APRINTK("%s():Failed to get memory"
  9461. + " for DSA RS Sign Op data struct\n", __FUNCTION__);
  9462. + krp->krp_status = ENOMEM;
  9463. + return ENOMEM;
  9464. + }
  9465. +
  9466. + dsaRsSignOpData->K.pData =
  9467. + icp_kmem_cache_alloc(drvDSARSSignKValue_zone, ICP_M_NOWAIT);
  9468. +
  9469. + if (NULL == dsaRsSignOpData->K.pData) {
  9470. + APRINTK("%s():Failed to get memory"
  9471. + " for DSA RS Sign Op Random value\n", __FUNCTION__);
  9472. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  9473. + krp->krp_status = ENOMEM;
  9474. + return ENOMEM;
  9475. + }
  9476. +
  9477. + pR = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  9478. + if (NULL == pR) {
  9479. + APRINTK("%s():Failed to get memory"
  9480. + " for DSA signature R\n", __FUNCTION__);
  9481. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  9482. + dsaRsSignOpData->K.pData);
  9483. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  9484. + krp->krp_status = ENOMEM;
  9485. + return ENOMEM;
  9486. + }
  9487. +
  9488. + pS = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  9489. + if (NULL == pS) {
  9490. + APRINTK("%s():Failed to get memory"
  9491. + " for DSA signature S\n", __FUNCTION__);
  9492. + icp_ocfDrvFreeFlatBuffer(pR);
  9493. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  9494. + dsaRsSignOpData->K.pData);
  9495. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  9496. + krp->krp_status = ENOMEM;
  9497. + return ENOMEM;
  9498. + }
  9499. +
  9500. + /*link prime number parameter for ease of processing */
  9501. + dsaRsSignOpData->P.pData =
  9502. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].crp_p;
  9503. + BITS_TO_BYTES(dsaRsSignOpData->P.dataLenInBytes,
  9504. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].
  9505. + crp_nbits);
  9506. +
  9507. + icp_ocfDrvSwapBytes(dsaRsSignOpData->P.pData,
  9508. + dsaRsSignOpData->P.dataLenInBytes);
  9509. +
  9510. + dsaRsSignOpData->Q.pData =
  9511. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  9512. + BITS_TO_BYTES(dsaRsSignOpData->Q.dataLenInBytes,
  9513. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
  9514. + crp_nbits);
  9515. +
  9516. + icp_ocfDrvSwapBytes(dsaRsSignOpData->Q.pData,
  9517. + dsaRsSignOpData->Q.dataLenInBytes);
  9518. +
  9519. + /*generate random number with equal buffer size to Prime value Q,
  9520. + but value less than Q */
  9521. + dsaRsSignOpData->K.dataLenInBytes = dsaRsSignOpData->Q.dataLenInBytes;
  9522. +
  9523. + randGenOpData.generateBits = CPA_TRUE;
  9524. + randGenOpData.lenInBytes = dsaRsSignOpData->K.dataLenInBytes;
  9525. +
  9526. + icp_ocfDrvPtrAndLenToFlatBuffer(dsaRsSignOpData->K.pData,
  9527. + dsaRsSignOpData->K.dataLenInBytes,
  9528. + &randData);
  9529. +
  9530. + doCheck = 0;
  9531. + while (icp_ocfDrvCheckALessThanB(&(dsaRsSignOpData->K),
  9532. + &(dsaRsSignOpData->Q), &doCheck)) {
  9533. +
  9534. + if (CPA_STATUS_SUCCESS
  9535. + != cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  9536. + NULL, NULL, &randGenOpData, &randData)) {
  9537. + APRINTK("%s(): ERROR - Failed to generate DSA RS Sign K"
  9538. + "value\n", __FUNCTION__);
  9539. + icp_ocfDrvFreeFlatBuffer(pS);
  9540. + icp_ocfDrvFreeFlatBuffer(pR);
  9541. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  9542. + dsaRsSignOpData->K.pData);
  9543. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  9544. + krp->krp_status = EAGAIN;
  9545. + return EAGAIN;
  9546. + }
  9547. +
  9548. + doCheck++;
  9549. + if (DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS == doCheck) {
  9550. + APRINTK("%s(): ERROR - Failed to find DSA RS Sign K "
  9551. + "value less than Q value\n", __FUNCTION__);
  9552. + icp_ocfDrvFreeFlatBuffer(pS);
  9553. + icp_ocfDrvFreeFlatBuffer(pR);
  9554. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  9555. + dsaRsSignOpData->K.pData);
  9556. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  9557. + krp->krp_status = EAGAIN;
  9558. + return EAGAIN;
  9559. + }
  9560. +
  9561. + }
  9562. + /*Rand Data - no need to swap bytes for pK */
  9563. +
  9564. + /* Link parameters */
  9565. + dsaRsSignOpData->G.pData =
  9566. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_p;
  9567. + BITS_TO_BYTES(dsaRsSignOpData->G.dataLenInBytes,
  9568. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_nbits);
  9569. +
  9570. + icp_ocfDrvSwapBytes(dsaRsSignOpData->G.pData,
  9571. + dsaRsSignOpData->G.dataLenInBytes);
  9572. +
  9573. + dsaRsSignOpData->X.pData =
  9574. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_p;
  9575. + BITS_TO_BYTES(dsaRsSignOpData->X.dataLenInBytes,
  9576. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_nbits);
  9577. + icp_ocfDrvSwapBytes(dsaRsSignOpData->X.pData,
  9578. + dsaRsSignOpData->X.dataLenInBytes);
  9579. +
  9580. + /*OpenSSL dgst parameter is left in big endian byte order,
  9581. + therefore no byte swap is required */
  9582. + dsaRsSignOpData->M.pData =
  9583. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].crp_p;
  9584. + BITS_TO_BYTES(dsaRsSignOpData->M.dataLenInBytes,
  9585. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].
  9586. + crp_nbits);
  9587. +
  9588. + /* Output Parameters */
  9589. + pS->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].crp_p;
  9590. + BITS_TO_BYTES(pS->dataLenInBytes,
  9591. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].
  9592. + crp_nbits);
  9593. +
  9594. + pR->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].crp_p;
  9595. + BITS_TO_BYTES(pR->dataLenInBytes,
  9596. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].
  9597. + crp_nbits);
  9598. +
  9599. + lacStatus = cpaCyDsaSignRS(CPA_INSTANCE_HANDLE_SINGLE,
  9600. + icp_ocfDrvDsaRSSignCallBack,
  9601. + callbackTag, dsaRsSignOpData,
  9602. + &protocolStatus, pR, pS);
  9603. +
  9604. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9605. + EPRINTK("%s(): DSA RS Sign Operation failed (%d).\n",
  9606. + __FUNCTION__, lacStatus);
  9607. + krp->krp_status = ECANCELED;
  9608. + icp_ocfDrvFreeFlatBuffer(pS);
  9609. + icp_ocfDrvFreeFlatBuffer(pR);
  9610. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  9611. + dsaRsSignOpData->K.pData);
  9612. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  9613. + }
  9614. +
  9615. + return lacStatus;
  9616. +}
  9617. +
  9618. +/* Name : icp_ocfDrvDsaVerify
  9619. + *
  9620. + * Description : This function will map DSA RS Verify from OCF to the LAC API.
  9621. + *
  9622. + */
  9623. +static int icp_ocfDrvDsaVerify(struct cryptkop *krp)
  9624. +{
  9625. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  9626. + CpaCyDsaVerifyOpData *dsaVerifyOpData = NULL;
  9627. + void *callbackTag = NULL;
  9628. + CpaBoolean verifyStatus = CPA_FALSE;
  9629. +
  9630. + callbackTag = krp;
  9631. +
  9632. + dsaVerifyOpData =
  9633. + icp_kmem_cache_zalloc(drvDSAVerify_zone, ICP_M_NOWAIT);
  9634. + if (NULL == dsaVerifyOpData) {
  9635. + APRINTK("%s():Failed to get memory"
  9636. + " for DSA Verify Op data struct\n", __FUNCTION__);
  9637. + krp->krp_status = ENOMEM;
  9638. + return ENOMEM;
  9639. + }
  9640. +
  9641. + /* Link parameters */
  9642. + dsaVerifyOpData->P.pData =
  9643. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].crp_p;
  9644. + BITS_TO_BYTES(dsaVerifyOpData->P.dataLenInBytes,
  9645. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].
  9646. + crp_nbits);
  9647. + icp_ocfDrvSwapBytes(dsaVerifyOpData->P.pData,
  9648. + dsaVerifyOpData->P.dataLenInBytes);
  9649. +
  9650. + dsaVerifyOpData->Q.pData =
  9651. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  9652. + BITS_TO_BYTES(dsaVerifyOpData->Q.dataLenInBytes,
  9653. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].
  9654. + crp_nbits);
  9655. + icp_ocfDrvSwapBytes(dsaVerifyOpData->Q.pData,
  9656. + dsaVerifyOpData->Q.dataLenInBytes);
  9657. +
  9658. + dsaVerifyOpData->G.pData =
  9659. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].crp_p;
  9660. + BITS_TO_BYTES(dsaVerifyOpData->G.dataLenInBytes,
  9661. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].
  9662. + crp_nbits);
  9663. + icp_ocfDrvSwapBytes(dsaVerifyOpData->G.pData,
  9664. + dsaVerifyOpData->G.dataLenInBytes);
  9665. +
  9666. + dsaVerifyOpData->Y.pData =
  9667. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].crp_p;
  9668. + BITS_TO_BYTES(dsaVerifyOpData->Y.dataLenInBytes,
  9669. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].
  9670. + crp_nbits);
  9671. + icp_ocfDrvSwapBytes(dsaVerifyOpData->Y.pData,
  9672. + dsaVerifyOpData->Y.dataLenInBytes);
  9673. +
  9674. + /*OpenSSL dgst parameter is left in big endian byte order,
  9675. + therefore no byte swap is required */
  9676. + dsaVerifyOpData->M.pData =
  9677. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].crp_p;
  9678. + BITS_TO_BYTES(dsaVerifyOpData->M.dataLenInBytes,
  9679. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].
  9680. + crp_nbits);
  9681. +
  9682. + dsaVerifyOpData->R.pData =
  9683. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].crp_p;
  9684. + BITS_TO_BYTES(dsaVerifyOpData->R.dataLenInBytes,
  9685. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].
  9686. + crp_nbits);
  9687. + icp_ocfDrvSwapBytes(dsaVerifyOpData->R.pData,
  9688. + dsaVerifyOpData->R.dataLenInBytes);
  9689. +
  9690. + dsaVerifyOpData->S.pData =
  9691. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].crp_p;
  9692. + BITS_TO_BYTES(dsaVerifyOpData->S.dataLenInBytes,
  9693. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].
  9694. + crp_nbits);
  9695. + icp_ocfDrvSwapBytes(dsaVerifyOpData->S.pData,
  9696. + dsaVerifyOpData->S.dataLenInBytes);
  9697. +
  9698. + lacStatus = cpaCyDsaVerify(CPA_INSTANCE_HANDLE_SINGLE,
  9699. + icp_ocfDrvDsaVerifyCallBack,
  9700. + callbackTag, dsaVerifyOpData, &verifyStatus);
  9701. +
  9702. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9703. + EPRINTK("%s(): DSA Verify Operation failed (%d).\n",
  9704. + __FUNCTION__, lacStatus);
  9705. + ICP_CACHE_FREE(drvDSAVerify_zone, dsaVerifyOpData);
  9706. + krp->krp_status = ECANCELED;
  9707. + }
  9708. +
  9709. + return lacStatus;
  9710. +}
  9711. +
  9712. +/* Name : icp_ocfDrvDhP1Callback
  9713. + *
  9714. + * Description : When this function returns it signifies that the LAC
  9715. + * component has completed the DH operation.
  9716. + */
  9717. +static void
  9718. +icp_ocfDrvDhP1CallBack(void *callbackTag,
  9719. + CpaStatus status,
  9720. + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV)
  9721. +{
  9722. + struct cryptkop *krp = NULL;
  9723. + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
  9724. +
  9725. + if (NULL == callbackTag) {
  9726. + DPRINTK("%s(): Invalid input parameters - "
  9727. + "callbackTag data is NULL\n", __FUNCTION__);
  9728. + return;
  9729. + }
  9730. + krp = (struct cryptkop *)callbackTag;
  9731. +
  9732. + if (NULL == pOpData) {
  9733. + DPRINTK("%s(): Invalid input parameters - "
  9734. + "Operation Data is NULL\n", __FUNCTION__);
  9735. + krp->krp_status = ECANCELED;
  9736. + crypto_kdone(krp);
  9737. + return;
  9738. + }
  9739. + pPhase1OpData = (CpaCyDhPhase1KeyGenOpData *) pOpData;
  9740. +
  9741. + if (NULL == pLocalOctetStringPV) {
  9742. + DPRINTK("%s(): Invalid input parameters - "
  9743. + "pLocalOctetStringPV Data is NULL\n", __FUNCTION__);
  9744. + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
  9745. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  9746. + krp->krp_status = ECANCELED;
  9747. + crypto_kdone(krp);
  9748. + return;
  9749. + }
  9750. +
  9751. + if (CPA_STATUS_SUCCESS == status) {
  9752. + krp->krp_status = CRYPTO_OP_SUCCESS;
  9753. + } else {
  9754. + APRINTK("%s(): Diffie Hellman Phase1 Key Gen failed - "
  9755. + "Operation Status = %d\n", __FUNCTION__, status);
  9756. + krp->krp_status = ECANCELED;
  9757. + }
  9758. +
  9759. + icp_ocfDrvSwapBytes(pLocalOctetStringPV->pData,
  9760. + pLocalOctetStringPV->dataLenInBytes);
  9761. +
  9762. + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
  9763. + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
  9764. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  9765. +
  9766. + crypto_kdone(krp);
  9767. +
  9768. + return;
  9769. +}
  9770. +
  9771. +/* Name : icp_ocfDrvModExpCallBack
  9772. + *
  9773. + * Description : When this function returns it signifies that the LAC
  9774. + * component has completed the Mod Exp operation.
  9775. + */
  9776. +static void
  9777. +icp_ocfDrvModExpCallBack(void *callbackTag,
  9778. + CpaStatus status,
  9779. + void *pOpdata, CpaFlatBuffer * pResult)
  9780. +{
  9781. + struct cryptkop *krp = NULL;
  9782. + CpaCyLnModExpOpData *pLnModExpOpData = NULL;
  9783. +
  9784. + if (NULL == callbackTag) {
  9785. + DPRINTK("%s(): Invalid input parameters - "
  9786. + "callbackTag data is NULL\n", __FUNCTION__);
  9787. + return;
  9788. + }
  9789. + krp = (struct cryptkop *)callbackTag;
  9790. +
  9791. + if (NULL == pOpdata) {
  9792. + DPRINTK("%s(): Invalid Mod Exp input parameters - "
  9793. + "Operation Data is NULL\n", __FUNCTION__);
  9794. + krp->krp_status = ECANCELED;
  9795. + crypto_kdone(krp);
  9796. + return;
  9797. + }
  9798. + pLnModExpOpData = (CpaCyLnModExpOpData *) pOpdata;
  9799. +
  9800. + if (NULL == pResult) {
  9801. + DPRINTK("%s(): Invalid input parameters - "
  9802. + "pResult data is NULL\n", __FUNCTION__);
  9803. + krp->krp_status = ECANCELED;
  9804. + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
  9805. + ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);
  9806. + crypto_kdone(krp);
  9807. + return;
  9808. + }
  9809. +
  9810. + if (CPA_STATUS_SUCCESS == status) {
  9811. + krp->krp_status = CRYPTO_OP_SUCCESS;
  9812. + } else {
  9813. + APRINTK("%s(): LAC Mod Exp Operation failed - "
  9814. + "Operation Status = %d\n", __FUNCTION__, status);
  9815. + krp->krp_status = ECANCELED;
  9816. + }
  9817. +
  9818. + icp_ocfDrvSwapBytes(pResult->pData, pResult->dataLenInBytes);
  9819. +
  9820. + /*switch base size value back to original */
  9821. + if (pLnModExpOpData->base.pData ==
  9822. + (uint8_t *) & (krp->
  9823. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  9824. + crp_nbits)) {
  9825. + *((uint32_t *) pLnModExpOpData->base.pData) =
  9826. + ntohl(*((uint32_t *) pLnModExpOpData->base.pData));
  9827. + }
  9828. + icp_ocfDrvFreeFlatBuffer(pResult);
  9829. + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
  9830. + ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);
  9831. +
  9832. + crypto_kdone(krp);
  9833. +
  9834. + return;
  9835. +
  9836. +}
  9837. +
  9838. +/* Name : icp_ocfDrvModExpCRTCallBack
  9839. + *
  9840. + * Description : When this function returns it signifies that the LAC
  9841. + * component has completed the Mod Exp CRT operation.
  9842. + */
  9843. +static void
  9844. +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
  9845. + CpaStatus status,
  9846. + void *pOpData, CpaFlatBuffer * pOutputData)
  9847. +{
  9848. + struct cryptkop *krp = NULL;
  9849. + CpaCyRsaDecryptOpData *pDecryptData = NULL;
  9850. +
  9851. + if (NULL == callbackTag) {
  9852. + DPRINTK("%s(): Invalid input parameters - "
  9853. + "callbackTag data is NULL\n", __FUNCTION__);
  9854. + return;
  9855. + }
  9856. +
  9857. + krp = (struct cryptkop *)callbackTag;
  9858. +
  9859. + if (NULL == pOpData) {
  9860. + DPRINTK("%s(): Invalid input parameters - "
  9861. + "Operation Data is NULL\n", __FUNCTION__);
  9862. + krp->krp_status = ECANCELED;
  9863. + crypto_kdone(krp);
  9864. + return;
  9865. + }
  9866. + pDecryptData = (CpaCyRsaDecryptOpData *) pOpData;
  9867. +
  9868. + if (NULL == pOutputData) {
  9869. + DPRINTK("%s(): Invalid input parameter - "
  9870. + "pOutputData is NULL\n", __FUNCTION__);
  9871. + memset(pDecryptData->pRecipientPrivateKey, 0,
  9872. + sizeof(CpaCyRsaPrivateKey));
  9873. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  9874. + pDecryptData->pRecipientPrivateKey);
  9875. + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
  9876. + ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);
  9877. + krp->krp_status = ECANCELED;
  9878. + crypto_kdone(krp);
  9879. + return;
  9880. + }
  9881. +
  9882. + if (CPA_STATUS_SUCCESS == status) {
  9883. + krp->krp_status = CRYPTO_OP_SUCCESS;
  9884. + } else {
  9885. + APRINTK("%s(): LAC Mod Exp CRT operation failed - "
  9886. + "Operation Status = %d\n", __FUNCTION__, status);
  9887. + krp->krp_status = ECANCELED;
  9888. + }
  9889. +
  9890. + icp_ocfDrvSwapBytes(pOutputData->pData, pOutputData->dataLenInBytes);
  9891. +
  9892. + icp_ocfDrvFreeFlatBuffer(pOutputData);
  9893. + memset(pDecryptData->pRecipientPrivateKey, 0,
  9894. + sizeof(CpaCyRsaPrivateKey));
  9895. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  9896. + pDecryptData->pRecipientPrivateKey);
  9897. + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
  9898. + ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);
  9899. +
  9900. + crypto_kdone(krp);
  9901. +
  9902. + return;
  9903. +}
  9904. +
  9905. +/* Name : icp_ocfDrvDsaRSSignCallBack
  9906. + *
  9907. + * Description : When this function returns it signifies that the LAC
  9908. + * component has completed the DSA RS sign operation.
  9909. + */
  9910. +static void
  9911. +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
  9912. + CpaStatus status,
  9913. + void *pOpData,
  9914. + CpaBoolean protocolStatus,
  9915. + CpaFlatBuffer * pR, CpaFlatBuffer * pS)
  9916. +{
  9917. + struct cryptkop *krp = NULL;
  9918. + CpaCyDsaRSSignOpData *pSignData = NULL;
  9919. +
  9920. + if (NULL == callbackTag) {
  9921. + DPRINTK("%s(): Invalid input parameters - "
  9922. + "callbackTag data is NULL\n", __FUNCTION__);
  9923. + return;
  9924. + }
  9925. +
  9926. + krp = (struct cryptkop *)callbackTag;
  9927. +
  9928. + if (NULL == pOpData) {
  9929. + DPRINTK("%s(): Invalid input parameters - "
  9930. + "Operation Data is NULL\n", __FUNCTION__);
  9931. + krp->krp_status = ECANCELED;
  9932. + crypto_kdone(krp);
  9933. + return;
  9934. + }
  9935. + pSignData = (CpaCyDsaRSSignOpData *) pOpData;
  9936. +
  9937. + if (NULL == pR) {
  9938. + DPRINTK("%s(): Invalid input parameter - "
  9939. + "pR sign is NULL\n", __FUNCTION__);
  9940. + icp_ocfDrvFreeFlatBuffer(pS);
  9941. + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
  9942. + krp->krp_status = ECANCELED;
  9943. + crypto_kdone(krp);
  9944. + return;
  9945. + }
  9946. +
  9947. + if (NULL == pS) {
  9948. + DPRINTK("%s(): Invalid input parameter - "
  9949. + "pS sign is NULL\n", __FUNCTION__);
  9950. + icp_ocfDrvFreeFlatBuffer(pR);
  9951. + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
  9952. + krp->krp_status = ECANCELED;
  9953. + crypto_kdone(krp);
  9954. + return;
  9955. + }
  9956. +
  9957. + if (CPA_STATUS_SUCCESS != status) {
  9958. + APRINTK("%s(): LAC DSA RS Sign operation failed - "
  9959. + "Operation Status = %d\n", __FUNCTION__, status);
  9960. + krp->krp_status = ECANCELED;
  9961. + } else {
  9962. + krp->krp_status = CRYPTO_OP_SUCCESS;
  9963. +
  9964. + if (CPA_TRUE != protocolStatus) {
  9965. + DPRINTK("%s(): LAC DSA RS Sign operation failed due "
  9966. + "to protocol error\n", __FUNCTION__);
  9967. + krp->krp_status = EIO;
  9968. + }
  9969. + }
  9970. +
  9971. + /* Swap bytes only when the callback status is successful and
  9972. + protocolStatus is set to true */
  9973. + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == protocolStatus) {
  9974. + icp_ocfDrvSwapBytes(pR->pData, pR->dataLenInBytes);
  9975. + icp_ocfDrvSwapBytes(pS->pData, pS->dataLenInBytes);
  9976. + }
  9977. +
  9978. + icp_ocfDrvFreeFlatBuffer(pR);
  9979. + icp_ocfDrvFreeFlatBuffer(pS);
  9980. + memset(pSignData->K.pData, 0, pSignData->K.dataLenInBytes);
  9981. + ICP_CACHE_FREE(drvDSARSSignKValue_zone, pSignData->K.pData);
  9982. + memset(pSignData, 0, sizeof(CpaCyDsaRSSignOpData));
  9983. + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
  9984. + crypto_kdone(krp);
  9985. +
  9986. + return;
  9987. +}
  9988. +
  9989. +/* Name : icp_ocfDrvDsaVerifyCallback
  9990. + *
  9991. + * Description : When this function returns it signifies that the LAC
  9992. + * component has completed the DSA Verify operation.
  9993. + */
  9994. +static void
  9995. +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
  9996. + CpaStatus status,
  9997. + void *pOpData, CpaBoolean verifyStatus)
  9998. +{
  9999. +
  10000. + struct cryptkop *krp = NULL;
  10001. + CpaCyDsaVerifyOpData *pVerData = NULL;
  10002. +
  10003. + if (NULL == callbackTag) {
  10004. + DPRINTK("%s(): Invalid input parameters - "
  10005. + "callbackTag data is NULL\n", __FUNCTION__);
  10006. + return;
  10007. + }
  10008. +
  10009. + krp = (struct cryptkop *)callbackTag;
  10010. +
  10011. + if (NULL == pOpData) {
  10012. + DPRINTK("%s(): Invalid input parameters - "
  10013. + "Operation Data is NULL\n", __FUNCTION__);
  10014. + krp->krp_status = ECANCELED;
  10015. + crypto_kdone(krp);
  10016. + return;
  10017. + }
  10018. + pVerData = (CpaCyDsaVerifyOpData *) pOpData;
  10019. +
  10020. + if (CPA_STATUS_SUCCESS != status) {
  10021. + APRINTK("%s(): LAC DSA Verify operation failed - "
  10022. + "Operation Status = %d\n", __FUNCTION__, status);
  10023. + krp->krp_status = ECANCELED;
  10024. + } else {
  10025. + krp->krp_status = CRYPTO_OP_SUCCESS;
  10026. +
  10027. + if (CPA_TRUE != verifyStatus) {
  10028. + DPRINTK("%s(): DSA signature invalid\n", __FUNCTION__);
  10029. + krp->krp_status = EIO;
  10030. + }
  10031. + }
  10032. +
  10033. + /* Swap bytes only when the callback status is successful and
  10034. + verifyStatus is set to true */
  10035. + /*Just swapping back the key values for now. Possibly all
  10036. + swapped buffers need to be reverted */
  10037. + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == verifyStatus) {
  10038. + icp_ocfDrvSwapBytes(pVerData->R.pData,
  10039. + pVerData->R.dataLenInBytes);
  10040. + icp_ocfDrvSwapBytes(pVerData->S.pData,
  10041. + pVerData->S.dataLenInBytes);
  10042. + }
  10043. +
  10044. + memset(pVerData, 0, sizeof(CpaCyDsaVerifyOpData));
  10045. + ICP_CACHE_FREE(drvDSAVerify_zone, pVerData);
  10046. + crypto_kdone(krp);
  10047. +
  10048. + return;
  10049. +}
  10050. diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/icp_common.c linux-2.6.36/crypto/ocf/ep80579/icp_common.c
  10051. --- linux-2.6.36.orig/crypto/ocf/ep80579/icp_common.c 1970-01-01 01:00:00.000000000 +0100
  10052. +++ linux-2.6.36/crypto/ocf/ep80579/icp_common.c 2010-11-09 20:28:04.612495446 +0100
  10053. @@ -0,0 +1,773 @@
  10054. +/*************************************************************************
  10055. + *
  10056. + * This file is provided under a dual BSD/GPLv2 license. When using or
  10057. + * redistributing this file, you may do so under either license.
  10058. + *
  10059. + * GPL LICENSE SUMMARY
  10060. + *
  10061. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  10062. + *
  10063. + * This program is free software; you can redistribute it and/or modify
  10064. + * it under the terms of version 2 of the GNU General Public License as
  10065. + * published by the Free Software Foundation.
  10066. + *
  10067. + * This program is distributed in the hope that it will be useful, but
  10068. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  10069. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10070. + * General Public License for more details.
  10071. + *
  10072. + * You should have received a copy of the GNU General Public License
  10073. + * along with this program; if not, write to the Free Software
  10074. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  10075. + * The full GNU General Public License is included in this distribution
  10076. + * in the file called LICENSE.GPL.
  10077. + *
  10078. + * Contact Information:
  10079. + * Intel Corporation
  10080. + *
  10081. + * BSD LICENSE
  10082. + *
  10083. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  10084. + * All rights reserved.
  10085. + *
  10086. + * Redistribution and use in source and binary forms, with or without
  10087. + * modification, are permitted provided that the following conditions
  10088. + * are met:
  10089. + *
  10090. + * * Redistributions of source code must retain the above copyright
  10091. + * notice, this list of conditions and the following disclaimer.
  10092. + * * Redistributions in binary form must reproduce the above copyright
  10093. + * notice, this list of conditions and the following disclaimer in
  10094. + * the documentation and/or other materials provided with the
  10095. + * distribution.
  10096. + * * Neither the name of Intel Corporation nor the names of its
  10097. + * contributors may be used to endorse or promote products derived
  10098. + * from this software without specific prior written permission.
  10099. + *
  10100. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  10101. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  10102. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  10103. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  10104. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10105. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  10106. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10107. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  10108. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  10109. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  10110. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  10111. + *
  10112. + *
  10113. + * version: Security.L.1.0.2-229
  10114. + *
  10115. + ***************************************************************************/
  10116. +
  10117. +/*
  10118. + * An OCF module that uses Intel® QuickAssist Integrated Accelerator to do the
  10119. + * crypto.
  10120. + *
  10121. + * This driver requires the ICP Access Library that is available from Intel in
  10122. + * order to operate.
  10123. + */
  10124. +
  10125. +#include "icp_ocf.h"
  10126. +
  10127. +#define ICP_OCF_COMP_NAME "ICP_OCF"
  10128. +#define ICP_OCF_VER_MAIN (2)
  10129. +#define ICP_OCF_VER_MJR (1)
  10130. +#define ICP_OCF_VER_MNR (0)
  10131. +
  10132. +#define MAX_DEREG_RETRIES (100)
  10133. +#define DEFAULT_DEREG_RETRIES (10)
  10134. +#define DEFAULT_DEREG_DELAY_IN_JIFFIES (10)
  10135. +
  10136. +/* This defines the maximum number of sessions possible between OCF
  10137. + and the OCF EP80579 Driver. If set to zero, there is no limit. */
  10138. +#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT (0)
  10139. +#define NUM_SUPPORTED_CAPABILITIES (21)
  10140. +
  10141. +/*Slab zone names*/
  10142. +#define ICP_SESSION_DATA_NAME "icp_ocf.SesDat"
  10143. +#define ICP_OP_DATA_NAME "icp_ocf.OpDat"
  10144. +#define ICP_DH_NAME "icp_ocf.DH"
  10145. +#define ICP_MODEXP_NAME "icp_ocf.ModExp"
  10146. +#define ICP_RSA_DECRYPT_NAME "icp_ocf.RSAdec"
  10147. +#define ICP_RSA_PKEY_NAME "icp_ocf.RSApk"
  10148. +#define ICP_DSA_SIGN_NAME "icp_ocf.DSAsg"
  10149. +#define ICP_DSA_VER_NAME "icp_ocf.DSAver"
  10150. +#define ICP_RAND_VAL_NAME "icp_ocf.DSArnd"
  10151. +#define ICP_FLAT_BUFF_NAME "icp_ocf.FB"
  10152. +
  10153. +/*Slabs zones*/
  10154. +icp_kmem_cache drvSessionData_zone = NULL;
  10155. +icp_kmem_cache drvOpData_zone = NULL;
  10156. +icp_kmem_cache drvDH_zone = NULL;
  10157. +icp_kmem_cache drvLnModExp_zone = NULL;
  10158. +icp_kmem_cache drvRSADecrypt_zone = NULL;
  10159. +icp_kmem_cache drvRSAPrivateKey_zone = NULL;
  10160. +icp_kmem_cache drvDSARSSign_zone = NULL;
  10161. +icp_kmem_cache drvDSARSSignKValue_zone = NULL;
  10162. +icp_kmem_cache drvDSAVerify_zone = NULL;
  10163. +
  10164. +/*Slab zones for flatbuffers and bufferlist*/
  10165. +icp_kmem_cache drvFlatBuffer_zone = NULL;
  10166. +
  10167. +static inline int icp_cache_null_check(void)
  10168. +{
  10169. + return (drvSessionData_zone && drvOpData_zone
  10170. + && drvDH_zone && drvLnModExp_zone && drvRSADecrypt_zone
  10171. + && drvRSAPrivateKey_zone && drvDSARSSign_zone
  10172. + && drvDSARSSign_zone && drvDSARSSignKValue_zone
  10173. + && drvDSAVerify_zone && drvFlatBuffer_zone);
  10174. +}
  10175. +
  10176. +/*Function to free all allocated slab caches before exiting the module*/
  10177. +static void icp_ocfDrvFreeCaches(void);
  10178. +
  10179. +int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  10180. +
  10181. +/* Module parameter - gives the number of times LAC deregistration shall be
  10182. + re-tried */
  10183. +int num_dereg_retries = DEFAULT_DEREG_RETRIES;
  10184. +
  10185. +/* Module parameter - gives the delay time in jiffies before a LAC session
  10186. + shall be attempted to be deregistered again */
  10187. +int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES;
  10188. +
  10189. +/* Module parameter - gives the maximum number of sessions possible between
  10190. + OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
  10191. +int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT;
  10192. +
  10193. +/* This is set when the module is removed from the system, no further
  10194. + processing can take place if this is set */
  10195. +icp_atomic_t icp_ocfDrvIsExiting = ICP_ATOMIC_INIT(0);
  10196. +
  10197. +/* This is used to show how many lac sessions were not deregistered*/
  10198. +icp_atomic_t lac_session_failed_dereg_count = ICP_ATOMIC_INIT(0);
  10199. +
  10200. +/* This is used to track the number of registered sessions between OCF and
  10201. + * and the OCF EP80579 driver, when max_session is set to value other than
  10202. + * zero. This ensures that the max_session set for the OCF and the driver
  10203. + * is equal to the LAC registered sessions */
  10204. +icp_atomic_t num_ocf_to_drv_registered_sessions = ICP_ATOMIC_INIT(0);
  10205. +
  10206. +/* Head of linked list used to store session data */
  10207. +icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
  10208. +icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
  10209. +
  10210. +icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
  10211. +
  10212. +/*Below pointer is only used in linux, FreeBSD uses the name to
  10213. +create its own variable name*/
  10214. +icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ = NULL;
  10215. +ICP_WORKQUEUE_DEFINE_THREAD(icp_ocfDrvFreeLacSessionWorkQ);
  10216. +
  10217. +struct icp_drvBuffListInfo defBuffListInfo;
  10218. +
  10219. +/* Name : icp_ocfDrvInit
  10220. + *
  10221. + * Description : This function will register all the symmetric and asymmetric
  10222. + * functionality that will be accelerated by the hardware. It will also
  10223. + * get a unique driver ID from the OCF and initialise all slab caches
  10224. + */
  10225. +ICP_MODULE_INIT_FUNC(icp_ocfDrvInit)
  10226. +{
  10227. + int ocfStatus = 0;
  10228. +
  10229. + IPRINTK("=== %s ver %d.%d.%d ===\n", ICP_OCF_COMP_NAME,
  10230. + ICP_OCF_VER_MAIN, ICP_OCF_VER_MJR, ICP_OCF_VER_MNR);
  10231. +
  10232. + if (MAX_DEREG_RETRIES < num_dereg_retries) {
  10233. + EPRINTK("Session deregistration retry count set to greater "
  10234. + "than %d", MAX_DEREG_RETRIES);
  10235. + icp_module_return_code(EINVAL);
  10236. + }
  10237. +
  10238. + /* Initialize and Start the Cryptographic component */
  10239. + if (CPA_STATUS_SUCCESS !=
  10240. + cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) {
  10241. + EPRINTK("Failed to initialize and start the instance "
  10242. + "of the Cryptographic component.\n");
  10243. + return icp_module_return_code(EINVAL);
  10244. + }
  10245. +
  10246. + icp_spin_lock_init(&icp_ocfDrvSymSessInfoListSpinlock);
  10247. +
  10248. + /* Set the default size of BufferList to allocate */
  10249. + memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo));
  10250. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  10251. + icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS,
  10252. + &defBuffListInfo)) {
  10253. + EPRINTK("Failed to get bufferlist memory info.\n");
  10254. + return icp_module_return_code(ENOMEM);
  10255. + }
  10256. +
  10257. + /*Register OCF EP80579 Driver with OCF */
  10258. + icp_ocfDrvDriverId = ICP_CRYPTO_GET_DRIVERID();
  10259. +
  10260. + if (icp_ocfDrvDriverId < 0) {
  10261. + EPRINTK("%s : ICP driver failed to register with OCF!\n",
  10262. + __FUNCTION__);
  10263. + return icp_module_return_code(ENODEV);
  10264. + }
  10265. +
  10266. + /*Create all the slab caches used by the OCF EP80579 Driver */
  10267. + drvSessionData_zone =
  10268. + ICP_CACHE_CREATE(ICP_SESSION_DATA_NAME, struct icp_drvSessionData);
  10269. +
  10270. + /*
  10271. + * Allocation of the OpData includes the allocation space for meta data.
  10272. + * The memory after the opData structure is reserved for this meta data.
  10273. + */
  10274. + drvOpData_zone =
  10275. + icp_kmem_cache_create(ICP_OP_DATA_NAME,
  10276. + sizeof(struct icp_drvOpData) +
  10277. + defBuffListInfo.metaSize,
  10278. + ICP_KERNEL_CACHE_ALIGN,
  10279. + ICP_KERNEL_CACHE_NOINIT);
  10280. +
  10281. + drvDH_zone = ICP_CACHE_CREATE(ICP_DH_NAME, CpaCyDhPhase1KeyGenOpData);
  10282. +
  10283. + drvLnModExp_zone =
  10284. + ICP_CACHE_CREATE(ICP_MODEXP_NAME, CpaCyLnModExpOpData);
  10285. +
  10286. + drvRSADecrypt_zone =
  10287. + ICP_CACHE_CREATE(ICP_RSA_DECRYPT_NAME, CpaCyRsaDecryptOpData);
  10288. +
  10289. + drvRSAPrivateKey_zone =
  10290. + ICP_CACHE_CREATE(ICP_RSA_PKEY_NAME, CpaCyRsaPrivateKey);
  10291. +
  10292. + drvDSARSSign_zone =
  10293. + ICP_CACHE_CREATE(ICP_DSA_SIGN_NAME, CpaCyDsaRSSignOpData);
  10294. +
  10295. + /*too awkward to use a macro here */
  10296. + drvDSARSSignKValue_zone =
  10297. + ICP_CACHE_CREATE(ICP_RAND_VAL_NAME,
  10298. + DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES);
  10299. +
  10300. + drvDSAVerify_zone =
  10301. + ICP_CACHE_CREATE(ICP_DSA_VER_NAME, CpaCyDsaVerifyOpData);
  10302. +
  10303. + drvFlatBuffer_zone =
  10304. + ICP_CACHE_CREATE(ICP_FLAT_BUFF_NAME, CpaFlatBuffer);
  10305. +
  10306. + if (0 == icp_cache_null_check()) {
  10307. + icp_ocfDrvFreeCaches();
  10308. + EPRINTK("%s() line %d: Not enough memory!\n",
  10309. + __FUNCTION__, __LINE__);
  10310. + return ENOMEM;
  10311. + }
  10312. +
  10313. + /* Register the ICP symmetric crypto support. */
  10314. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_NULL_CBC, ocfStatus);
  10315. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_DES_CBC, ocfStatus);
  10316. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_3DES_CBC, ocfStatus);
  10317. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_AES_CBC, ocfStatus);
  10318. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_ARC4, ocfStatus);
  10319. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5, ocfStatus);
  10320. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5_HMAC, ocfStatus);
  10321. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1, ocfStatus);
  10322. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1_HMAC, ocfStatus);
  10323. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256, ocfStatus);
  10324. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256_HMAC,
  10325. + ocfStatus);
  10326. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384, ocfStatus);
  10327. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384_HMAC,
  10328. + ocfStatus);
  10329. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512, ocfStatus);
  10330. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512_HMAC,
  10331. + ocfStatus);
  10332. +
  10333. + /* Register the ICP asymmetric algorithm support */
  10334. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DH_COMPUTE_KEY,
  10335. + ocfStatus);
  10336. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP, ocfStatus);
  10337. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP_CRT, ocfStatus);
  10338. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_SIGN, ocfStatus);
  10339. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_VERIFY, ocfStatus);
  10340. +
  10341. + /* Register the ICP random number generator support */
  10342. + ICP_REG_RAND_WITH_OCF(icp_ocfDrvDriverId,
  10343. + icp_ocfDrvReadRandom, NULL, ocfStatus);
  10344. +
  10345. + if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) {
  10346. + DPRINTK("%s: Failed to register any device capabilities\n",
  10347. + __FUNCTION__);
  10348. + icp_ocfDrvFreeCaches();
  10349. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  10350. + return icp_module_return_code(ECANCELED);
  10351. + }
  10352. +
  10353. + DPRINTK("%s: Registered %d of %d device capabilities\n",
  10354. + __FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES);
  10355. +
  10356. + /*Session data linked list used during module exit */
  10357. + ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);
  10358. + ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);
  10359. +
  10360. + ICP_WORKQUEUE_CREATE(icp_ocfDrvFreeLacSessionWorkQ, "icpwq");
  10361. + if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
  10362. + EPRINTK("%s: Failed to create single "
  10363. + "thread workqueue\n", __FUNCTION__);
  10364. + icp_ocfDrvFreeCaches();
  10365. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  10366. + return icp_module_return_code(ENOMEM);
  10367. + }
  10368. +
  10369. + return icp_module_return_code(0);
  10370. +}
  10371. +
  10372. +/* Name : icp_ocfDrvExit
  10373. + *
  10374. + * Description : This function will deregister all the symmetric sessions
  10375. + * registered with the LAC component. It will also deregister all symmetric
  10376. + * and asymmetric functionality that can be accelerated by the hardware via OCF
  10377. + * and random number generation if it is enabled.
  10378. + */
  10379. +ICP_MODULE_EXIT_FUNC(icp_ocfDrvExit)
  10380. +{
  10381. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  10382. + struct icp_drvSessionData *sessionData = NULL;
  10383. + struct icp_drvSessionData *tempSessionData = NULL;
  10384. + int i, remaining_delay_time_in_jiffies = 0;
  10385. +
  10386. + /* For FreeBSD the invariant macro below makes function to return */
  10387. + /* with EBUSY value in the case of any session which has been regi- */
  10388. + /* stered with LAC not being deregistered. */
  10389. + /* The Linux implementation is empty since it is purely to compensate */
  10390. + /* for a limitation of the FreeBSD 7.1 Opencrypto framework. */
  10391. +
  10392. + ICP_MODULE_EXIT_INV();
  10393. +
  10394. + /* There is a possibility of a process or new session command being */
  10395. + /* sent before this variable is incremented. The aim of this variable */
  10396. + /* is to stop a loop of calls creating a deadlock situation which */
  10397. + /* would prevent the driver from exiting. */
  10398. + icp_atomic_set(&icp_ocfDrvIsExiting, 1);
  10399. +
  10400. + /*Existing sessions will be routed to another driver after these calls */
  10401. + crypto_unregister_all(icp_ocfDrvDriverId);
  10402. + crypto_runregister_all(icp_ocfDrvDriverId);
  10403. +
  10404. + if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
  10405. + DPRINTK("%s: workqueue already "
  10406. + "destroyed, therefore module exit "
  10407. + " function already called. Exiting.\n", __FUNCTION__);
  10408. + return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
  10409. + }
  10410. + /*If any sessions are waiting to be deregistered, do that. This also
  10411. + flushes the work queue */
  10412. + ICP_WORKQUEUE_DESTROY(icp_ocfDrvFreeLacSessionWorkQ);
  10413. +
  10414. + /*ENTER CRITICAL SECTION */
  10415. + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  10416. +
  10417. + ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
  10418. + &icp_ocfDrvGlobalSymListHead, listNode) {
  10419. + for (i = 0; i < num_dereg_retries; i++) {
  10420. + /*No harm if bad input - LAC will handle error cases */
  10421. + if (ICP_SESSION_RUNNING == tempSessionData->inUse) {
  10422. + lacStatus =
  10423. + cpaCySymRemoveSession
  10424. + (CPA_INSTANCE_HANDLE_SINGLE,
  10425. + tempSessionData->sessHandle);
  10426. + if (CPA_STATUS_SUCCESS == lacStatus) {
  10427. + /* Succesfully deregistered */
  10428. + break;
  10429. + } else if (CPA_STATUS_RETRY != lacStatus) {
  10430. + icp_atomic_inc
  10431. + (&lac_session_failed_dereg_count);
  10432. + break;
  10433. + }
  10434. +
  10435. + /*schedule_timout returns the time left for completion if
  10436. + * this task is set to TASK_INTERRUPTIBLE */
  10437. + remaining_delay_time_in_jiffies =
  10438. + dereg_retry_delay_in_jiffies;
  10439. + while (0 > remaining_delay_time_in_jiffies) {
  10440. + remaining_delay_time_in_jiffies =
  10441. + icp_schedule_timeout
  10442. + (&icp_ocfDrvSymSessInfoListSpinlock,
  10443. + remaining_delay_time_in_jiffies);
  10444. + }
  10445. +
  10446. + DPRINTK
  10447. + ("%s(): Retry %d to deregistrate the session\n",
  10448. + __FUNCTION__, i);
  10449. + }
  10450. + }
  10451. +
  10452. + /*remove from current list */
  10453. + ICP_LIST_DEL(tempSessionData, listNode);
  10454. + /*add to free mem linked list */
  10455. + ICP_LIST_ADD(tempSessionData,
  10456. + &icp_ocfDrvGlobalSymListHead_FreeMemList,
  10457. + listNode);
  10458. +
  10459. + }
  10460. +
  10461. + /*EXIT CRITICAL SECTION */
  10462. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  10463. +
  10464. + /*set back to initial values */
  10465. + sessionData = NULL;
  10466. + /*still have a reference in our list! */
  10467. + tempSessionData = NULL;
  10468. + /*free memory */
  10469. +
  10470. + ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
  10471. + &icp_ocfDrvGlobalSymListHead_FreeMemList,
  10472. + listNode) {
  10473. +
  10474. + ICP_LIST_DEL(tempSessionData, listNode);
  10475. + /* Free allocated CpaCySymSessionCtx */
  10476. + if (NULL != tempSessionData->sessHandle) {
  10477. + icp_kfree(tempSessionData->sessHandle);
  10478. + }
  10479. + memset(tempSessionData, 0, sizeof(struct icp_drvSessionData));
  10480. + ICP_CACHE_FREE(drvSessionData_zone, tempSessionData);
  10481. + }
  10482. +
  10483. + if (0 != icp_atomic_read(&lac_session_failed_dereg_count)) {
  10484. + DPRINTK("%s(): %d LAC sessions were not deregistered "
  10485. + "correctly. This is not a clean exit! \n",
  10486. + __FUNCTION__,
  10487. + icp_atomic_read(&lac_session_failed_dereg_count));
  10488. + }
  10489. +
  10490. + icp_ocfDrvFreeCaches();
  10491. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  10492. +
  10493. + icp_spin_lock_destroy(&icp_ocfDrvSymSessInfoListSpinlock);
  10494. +
  10495. + /* Shutdown the Cryptographic component */
  10496. + lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE);
  10497. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10498. + DPRINTK("%s(): Failed to stop instance of the "
  10499. + "Cryptographic component.(status == %d)\n",
  10500. + __FUNCTION__, lacStatus);
  10501. + }
  10502. +
  10503. + return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
  10504. +}
  10505. +
  10506. +/* Name : icp_ocfDrvFreeCaches
  10507. + *
  10508. + * Description : This function deregisters all slab caches
  10509. + */
  10510. +static void icp_ocfDrvFreeCaches(void)
  10511. +{
  10512. + icp_atomic_set(&icp_ocfDrvIsExiting, 1);
  10513. +
  10514. + /*Sym Zones */
  10515. + ICP_CACHE_DESTROY(drvSessionData_zone);
  10516. + ICP_CACHE_DESTROY(drvOpData_zone);
  10517. +
  10518. + /*Asym zones */
  10519. + ICP_CACHE_DESTROY(drvDH_zone);
  10520. + ICP_CACHE_DESTROY(drvLnModExp_zone);
  10521. + ICP_CACHE_DESTROY(drvRSADecrypt_zone);
  10522. + ICP_CACHE_DESTROY(drvRSAPrivateKey_zone);
  10523. + ICP_CACHE_DESTROY(drvDSARSSignKValue_zone);
  10524. + ICP_CACHE_DESTROY(drvDSARSSign_zone);
  10525. + ICP_CACHE_DESTROY(drvDSAVerify_zone);
  10526. +
  10527. + /*FlatBuffer and BufferList Zones */
  10528. + ICP_CACHE_DESTROY(drvFlatBuffer_zone);
  10529. +
  10530. +}
  10531. +
  10532. +/* Name : icp_ocfDrvDeregRetry
  10533. + *
  10534. + * Description : This function will try to farm the session deregistration
  10535. + * off to a work queue. If it fails, nothing more can be done and it
  10536. + * returns an error
  10537. + */
  10538. +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
  10539. +{
  10540. + struct icp_ocfDrvFreeLacSession *workstore = NULL;
  10541. +
  10542. + DPRINTK("%s(): Retry - Deregistering session (%p)\n",
  10543. + __FUNCTION__, sessionToDeregister);
  10544. +
  10545. + /*make sure the session is not available to be allocated during this
  10546. + process */
  10547. + icp_atomic_inc(&lac_session_failed_dereg_count);
  10548. +
  10549. + /*Farm off to work queue */
  10550. + workstore =
  10551. + icp_kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), ICP_M_NOWAIT);
  10552. + if (NULL == workstore) {
  10553. + DPRINTK("%s(): unable to free session - no memory available "
  10554. + "for work queue\n", __FUNCTION__);
  10555. + return ENOMEM;
  10556. + }
  10557. +
  10558. + workstore->sessionToDeregister = sessionToDeregister;
  10559. +
  10560. + icp_init_work(&(workstore->work),
  10561. + icp_ocfDrvDeferedFreeLacSessionTaskFn, workstore);
  10562. +
  10563. + ICP_WORKQUEUE_ENQUEUE(icp_ocfDrvFreeLacSessionWorkQ,
  10564. + &(workstore->work));
  10565. +
  10566. + return ICP_OCF_DRV_STATUS_SUCCESS;
  10567. +
  10568. +}
  10569. +
  10570. +/* Name : icp_ocfDrvDeferedFreeLacSessionProcess
  10571. + *
  10572. + * Description : This function will retry (module input parameter)
  10573. + * 'num_dereg_retries' times to deregister any symmetric session that recieves a
  10574. + * CPA_STATUS_RETRY message from the LAC component. This function is run in
  10575. + * Thread context because it is called from a worker thread
  10576. + */
  10577. +void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
  10578. +{
  10579. + struct icp_ocfDrvFreeLacSession *workstore = NULL;
  10580. + CpaCySymSessionCtx sessionToDeregister = NULL;
  10581. + int i = 0;
  10582. + int remaining_delay_time_in_jiffies = 0;
  10583. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  10584. +
  10585. + workstore = (struct icp_ocfDrvFreeLacSession *)arg;
  10586. + if (NULL == workstore) {
  10587. + DPRINTK("%s() function called with null parameter \n",
  10588. + __FUNCTION__);
  10589. + return;
  10590. + }
  10591. +
  10592. + sessionToDeregister = workstore->sessionToDeregister;
  10593. + icp_kfree(workstore);
  10594. +
  10595. + /*if exiting, give deregistration one more blast only */
  10596. + if (icp_atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {
  10597. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  10598. + sessionToDeregister);
  10599. +
  10600. + if (lacStatus != CPA_STATUS_SUCCESS) {
  10601. + DPRINTK("%s() Failed to Dereg LAC session %p "
  10602. + "during module exit\n", __FUNCTION__,
  10603. + sessionToDeregister);
  10604. + return;
  10605. + }
  10606. +
  10607. + icp_atomic_dec(&lac_session_failed_dereg_count);
  10608. + return;
  10609. + }
  10610. +
  10611. + for (i = 0; i <= num_dereg_retries; i++) {
  10612. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  10613. + sessionToDeregister);
  10614. +
  10615. + if (lacStatus == CPA_STATUS_SUCCESS) {
  10616. + icp_atomic_dec(&lac_session_failed_dereg_count);
  10617. + return;
  10618. + }
  10619. + if (lacStatus != CPA_STATUS_RETRY) {
  10620. + DPRINTK("%s() Failed to deregister session - lacStatus "
  10621. + " = %d", __FUNCTION__, lacStatus);
  10622. + break;
  10623. + }
  10624. +
  10625. + /*schedule_timout returns the time left for completion if this
  10626. + task is set to TASK_INTERRUPTIBLE */
  10627. + remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies;
  10628. + while (0 < remaining_delay_time_in_jiffies) {
  10629. + remaining_delay_time_in_jiffies =
  10630. + icp_schedule_timeout(NULL,
  10631. + remaining_delay_time_in_jiffies);
  10632. + }
  10633. +
  10634. + }
  10635. +
  10636. + DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__);
  10637. + DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__,
  10638. + icp_atomic_read(&lac_session_failed_dereg_count));
  10639. +}
  10640. +
  10641. +/* Name : icp_ocfDrvPtrAndLenToFlatBuffer
  10642. + *
  10643. + * Description : This function converts a "pointer and length" buffer
  10644. + * structure to Fredericksburg Flat Buffer (CpaFlatBuffer) format.
  10645. + *
  10646. + * This function assumes that the data passed in are valid.
  10647. + */
  10648. +inline void
  10649. +icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
  10650. + CpaFlatBuffer * pFlatBuffer)
  10651. +{
  10652. + pFlatBuffer->pData = pData;
  10653. + pFlatBuffer->dataLenInBytes = len;
  10654. +}
  10655. +
  10656. +/* Name : icp_ocfDrvPtrAndLenToBufferList
  10657. + *
  10658. + * Description : This function converts a "pointer and length" buffer
  10659. + * structure to Fredericksburg Scatter/Gather Buffer (CpaBufferList) format.
  10660. + *
  10661. + * This function assumes that the data passed in are valid.
  10662. + */
  10663. +inline void
  10664. +icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
  10665. + CpaBufferList * pBufferList)
  10666. +{
  10667. + pBufferList->numBuffers = 1;
  10668. + pBufferList->pBuffers->pData = pDataIn;
  10669. + pBufferList->pBuffers->dataLenInBytes = length;
  10670. +}
  10671. +
  10672. +/* Name : icp_ocfDrvBufferListToPtrAndLen
  10673. + *
  10674. + * Description : This function converts Fredericksburg Scatter/Gather Buffer
  10675. + * (CpaBufferList) format to a "pointer and length" buffer structure.
  10676. + *
  10677. + * This function assumes that the data passed in are valid.
  10678. + */
  10679. +inline void
  10680. +icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
  10681. + void **ppDataOut, uint32_t * pLength)
  10682. +{
  10683. + *ppDataOut = pBufferList->pBuffers->pData;
  10684. + *pLength = pBufferList->pBuffers->dataLenInBytes;
  10685. +}
  10686. +
  10687. +/* Name : icp_ocfDrvBufferListMemInfo
  10688. + *
  10689. + * Description : This function will set the number of flat buffers in
  10690. + * bufferlist, the size of memory to allocate for the pPrivateMetaData
  10691. + * member of the CpaBufferList.
  10692. + */
  10693. +int
  10694. +icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
  10695. + struct icp_drvBuffListInfo *buffListInfo)
  10696. +{
  10697. + buffListInfo->numBuffers = numBuffers;
  10698. +
  10699. + if (CPA_STATUS_SUCCESS !=
  10700. + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  10701. + buffListInfo->numBuffers,
  10702. + &(buffListInfo->metaSize))) {
  10703. + EPRINTK("%s() Failed to get buffer list meta size.\n",
  10704. + __FUNCTION__);
  10705. + return ICP_OCF_DRV_STATUS_FAIL;
  10706. + }
  10707. +
  10708. + return ICP_OCF_DRV_STATUS_SUCCESS;
  10709. +}
  10710. +
  10711. +/* Name : icp_ocfDrvFreeFlatBuffer
  10712. + *
  10713. + * Description : This function will deallocate flat buffer.
  10714. + */
  10715. +inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)
  10716. +{
  10717. + if (pFlatBuffer != NULL) {
  10718. + memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer));
  10719. + ICP_CACHE_FREE(drvFlatBuffer_zone, pFlatBuffer);
  10720. + }
  10721. +}
  10722. +
  10723. +/* Name : icp_ocfDrvAllocMetaData
  10724. + *
  10725. + * Description : This function will allocate memory for the
  10726. + * pPrivateMetaData member of CpaBufferList.
  10727. + */
  10728. +inline int
  10729. +icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
  10730. + struct icp_drvOpData *pOpData)
  10731. +{
  10732. + Cpa32U metaSize = 0;
  10733. +
  10734. + if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  10735. + uint8_t *pOpDataStartAddr = (uint8_t *) pOpData;
  10736. +
  10737. + if (0 == defBuffListInfo.metaSize) {
  10738. + pBufferList->pPrivateMetaData = NULL;
  10739. + return ICP_OCF_DRV_STATUS_SUCCESS;
  10740. + }
  10741. + /*
  10742. + * The meta data allocation has been included as part of the
  10743. + * op data. It has been pre-allocated in memory just after the
  10744. + * icp_drvOpData structure.
  10745. + */
  10746. + pBufferList->pPrivateMetaData = (void *)(pOpDataStartAddr +
  10747. + sizeof(struct
  10748. + icp_drvOpData));
  10749. + } else {
  10750. + if (CPA_STATUS_SUCCESS !=
  10751. + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  10752. + pBufferList->numBuffers,
  10753. + &metaSize)) {
  10754. + EPRINTK("%s() Failed to get buffer list meta size.\n",
  10755. + __FUNCTION__);
  10756. + return ICP_OCF_DRV_STATUS_FAIL;
  10757. + }
  10758. +
  10759. + if (0 == metaSize) {
  10760. + pBufferList->pPrivateMetaData = NULL;
  10761. + return ICP_OCF_DRV_STATUS_SUCCESS;
  10762. + }
  10763. +
  10764. + pBufferList->pPrivateMetaData =
  10765. + icp_kmalloc(metaSize, ICP_M_NOWAIT);
  10766. + }
  10767. + if (NULL == pBufferList->pPrivateMetaData) {
  10768. + EPRINTK("%s() Failed to allocate pPrivateMetaData.\n",
  10769. + __FUNCTION__);
  10770. + return ICP_OCF_DRV_STATUS_FAIL;
  10771. + }
  10772. +
  10773. + return ICP_OCF_DRV_STATUS_SUCCESS;
  10774. +}
  10775. +
  10776. +/* Name : icp_ocfDrvFreeMetaData
  10777. + *
  10778. + * Description : This function will deallocate pPrivateMetaData memory.
  10779. + */
  10780. +inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList)
  10781. +{
  10782. + if (NULL == pBufferList->pPrivateMetaData) {
  10783. + return;
  10784. + }
  10785. +
  10786. + /*
  10787. + * Only free the meta data if the BufferList has more than
  10788. + * ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS number of buffers.
  10789. + * Otherwise, the meta data shall be freed when the icp_drvOpData is
  10790. + * freed.
  10791. + */
  10792. + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers) {
  10793. + icp_kfree(pBufferList->pPrivateMetaData);
  10794. + }
  10795. +}
  10796. +
  10797. +/* Module declaration, init and exit functions */
  10798. +ICP_DECLARE_MODULE(icp_ocf, icp_ocfDrvInit, icp_ocfDrvExit);
  10799. +ICP_MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");
  10800. +ICP_MODULE_VERSION(icp_ocf, ICP_OCF_VER_MJR);
  10801. +ICP_MODULE_LICENSE("Dual BSD/GPL");
  10802. +ICP_MODULE_AUTHOR("Intel");
  10803. +
  10804. +/* Module parameters */
  10805. +ICP_MODULE_PARAM_INT(icp_ocf, num_dereg_retries,
  10806. + "Number of times to retry LAC Sym Session Deregistration. "
  10807. + "Default 10, Max 100");
  10808. +ICP_MODULE_PARAM_INT(icp_ocf, dereg_retry_delay_in_jiffies, "Delay in jiffies "
  10809. + "(added to a schedule() function call) before a LAC Sym "
  10810. + "Session Dereg is retried. Default 10");
  10811. +ICP_MODULE_PARAM_INT(icp_ocf, max_sessions,
  10812. + "This sets the maximum number of sessions "
  10813. + "between OCF and this driver. If this value is set to zero,"
  10814. + "max session count checking is disabled. Default is zero(0)");
  10815. +
  10816. +/* Module dependencies */
  10817. +#define MODULE_MIN_VER 1
  10818. +#define CRYPTO_MAX_VER 3
  10819. +#define LAC_MAX_VER 2
  10820. +
  10821. +ICP_MODULE_DEPEND(icp_ocf, crypto, MODULE_MIN_VER, MODULE_MIN_VER,
  10822. + CRYPTO_MAX_VER);
  10823. +ICP_MODULE_DEPEND(icp_ocf, cryptodev, MODULE_MIN_VER, MODULE_MIN_VER,
  10824. + CRYPTO_MAX_VER);
  10825. +ICP_MODULE_DEPEND(icp_ocf, icp_crypto, MODULE_MIN_VER, MODULE_MIN_VER,
  10826. + LAC_MAX_VER);
  10827. diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/icp_ocf.h linux-2.6.36/crypto/ocf/ep80579/icp_ocf.h
  10828. --- linux-2.6.36.orig/crypto/ocf/ep80579/icp_ocf.h 1970-01-01 01:00:00.000000000 +0100
  10829. +++ linux-2.6.36/crypto/ocf/ep80579/icp_ocf.h 2010-11-09 20:28:04.662495462 +0100
  10830. @@ -0,0 +1,376 @@
  10831. +/***************************************************************************
  10832. + *
  10833. + * This file is provided under a dual BSD/GPLv2 license. When using or
  10834. + * redistributing this file, you may do so under either license.
  10835. + *
  10836. + * GPL LICENSE SUMMARY
  10837. + *
  10838. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  10839. + *
  10840. + * This program is free software; you can redistribute it and/or modify
  10841. + * it under the terms of version 2 of the GNU General Public License as
  10842. + * published by the Free Software Foundation.
  10843. + *
  10844. + * This program is distributed in the hope that it will be useful, but
  10845. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  10846. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10847. + * General Public License for more details.
  10848. + *
  10849. + * You should have received a copy of the GNU General Public License
  10850. + * along with this program; if not, write to the Free Software
  10851. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  10852. + * The full GNU General Public License is included in this distribution
  10853. + * in the file called LICENSE.GPL.
  10854. + *
  10855. + * Contact Information:
  10856. + * Intel Corporation
  10857. + *
  10858. + * BSD LICENSE
  10859. + *
  10860. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  10861. + * All rights reserved.
  10862. + *
  10863. + * Redistribution and use in source and binary forms, with or without
  10864. + * modification, are permitted provided that the following conditions
  10865. + * are met:
  10866. + *
  10867. + * * Redistributions of source code must retain the above copyright
  10868. + * notice, this list of conditions and the following disclaimer.
  10869. + * * Redistributions in binary form must reproduce the above copyright
  10870. + * notice, this list of conditions and the following disclaimer in
  10871. + * the documentation and/or other materials provided with the
  10872. + * distribution.
  10873. + * * Neither the name of Intel Corporation nor the names of its
  10874. + * contributors may be used to endorse or promote products derived
  10875. + * from this software without specific prior written permission.
  10876. + *
  10877. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  10878. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  10879. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  10880. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  10881. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10882. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  10883. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10884. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  10885. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  10886. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  10887. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  10888. + *
  10889. + *
  10890. + * version: Security.L.1.0.2-229
  10891. + *
  10892. + ***************************************************************************/
  10893. +
  10894. +/*
  10895. + * OCF driver header file for the Intel ICP processor.
  10896. + */
  10897. +
  10898. +#ifndef ICP_OCF_H_
  10899. +#define ICP_OCF_H_
  10900. +
  10901. +#include <cpa.h>
  10902. +#include <cpa_cy_im.h>
  10903. +#include <cpa_cy_sym.h>
  10904. +#include <cpa_cy_rand.h>
  10905. +#include <cpa_cy_dh.h>
  10906. +#include <cpa_cy_rsa.h>
  10907. +#include <cpa_cy_ln.h>
  10908. +#include <cpa_cy_common.h>
  10909. +#include <cpa_cy_dsa.h>
  10910. +
  10911. +#include "icp_os.h"
  10912. +
  10913. +#define NUM_BITS_IN_BYTE (8)
  10914. +#define NUM_BITS_IN_BYTE_MINUS_ONE (NUM_BITS_IN_BYTE -1)
  10915. +#define INVALID_DRIVER_ID (-1)
  10916. +#define RETURN_RAND_NUM_GEN_FAILED (-1)
  10917. +
  10918. +/*This is the max block cipher initialisation vector*/
  10919. +#define MAX_IV_LEN_IN_BYTES (20)
  10920. +/*This is used to check whether the OCF to this driver session limit has
  10921. + been disabled*/
  10922. +#define NO_OCF_TO_DRV_MAX_SESSIONS (0)
  10923. +
  10924. +/*OCF values mapped here*/
  10925. +#define ICP_SHA1_DIGEST_SIZE_IN_BYTES (SHA1_HASH_LEN)
  10926. +#define ICP_SHA256_DIGEST_SIZE_IN_BYTES (SHA2_256_HASH_LEN)
  10927. +#define ICP_SHA384_DIGEST_SIZE_IN_BYTES (SHA2_384_HASH_LEN)
  10928. +#define ICP_SHA512_DIGEST_SIZE_IN_BYTES (SHA2_512_HASH_LEN)
  10929. +#define ICP_MD5_DIGEST_SIZE_IN_BYTES (MD5_HASH_LEN)
  10930. +#define ARC4_COUNTER_LEN (ARC4_BLOCK_LEN)
  10931. +
  10932. +#define OCF_REGISTRATION_STATUS_SUCCESS (0)
  10933. +#define OCF_ZERO_FUNCTIONALITY_REGISTERED (0)
  10934. +#define ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR (0)
  10935. +#define ICP_OCF_DRV_STATUS_SUCCESS (0)
  10936. +#define ICP_OCF_DRV_STATUS_FAIL (1)
  10937. +
  10938. +/*Turn on/off debug options*/
  10939. +#define ICP_OCF_PRINT_DEBUG_MESSAGES (0)
  10940. +#define ICP_OCF_PRINT_KERN_ALERT (1)
  10941. +#define ICP_OCF_PRINT_KERN_ERRS (1)
  10942. +
  10943. +#if ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  10944. +#define DPRINTK(args...) \
  10945. +{ \
  10946. + ICP_IPRINTK(args); \
  10947. +}
  10948. +
  10949. +#else //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  10950. +
  10951. +#define DPRINTK(args...)
  10952. +
  10953. +#endif //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  10954. +
  10955. +#if ICP_OCF_PRINT_KERN_ALERT == 1
  10956. +#define APRINTK(args...) \
  10957. +{ \
  10958. + ICP_APRINTK(args); \
  10959. +}
  10960. +
  10961. +#else //ICP_OCF_PRINT_KERN_ALERT == 1
  10962. +
  10963. +#define APRINTK(args...)
  10964. +
  10965. +#endif //ICP_OCF_PRINT_KERN_ALERT == 1
  10966. +
  10967. +#if ICP_OCF_PRINT_KERN_ERRS == 1
  10968. +#define EPRINTK(args...) \
  10969. +{ \
  10970. + ICP_EPRINTK(args); \
  10971. +}
  10972. +
  10973. +#else //ICP_OCF_PRINT_KERN_ERRS == 1
  10974. +
  10975. +#define EPRINTK(args...)
  10976. +
  10977. +#endif //ICP_OCF_PRINT_KERN_ERRS == 1
  10978. +
  10979. +#define IPRINTK(args...) \
  10980. +{ \
  10981. + ICP_IPRINTK(args); \
  10982. +}
  10983. +
  10984. +/*DSA Prime Q size in bytes (as defined in the standard) */
  10985. +#define DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES (20)
  10986. +
  10987. +#define BITS_TO_BYTES(bytes, bits) \
  10988. + bytes = (bits + NUM_BITS_IN_BYTE_MINUS_ONE) / NUM_BITS_IN_BYTE
  10989. +
  10990. +typedef enum {
  10991. + ICP_OCF_DRV_ALG_CIPHER = 0,
  10992. + ICP_OCF_DRV_ALG_HASH
  10993. +} icp_ocf_drv_alg_type_t;
  10994. +
  10995. +typedef ICP_LIST_HEAD(icp_drvSessionListHead_s,
  10996. + icp_drvSessionData) icp_drvSessionListHead_t;
  10997. +
  10998. +/*Values used to derisk chances of performs being called against
  10999. +deregistered sessions (for which the slab page has been reclaimed)
  11000. +This is not a fix - since page frames are reclaimed from a slab, one cannot
  11001. +rely on that memory not being re-used by another app.*/
  11002. +typedef enum {
  11003. + ICP_SESSION_INITIALISED = 0x5C5C5C,
  11004. + ICP_SESSION_RUNNING = 0x005C00,
  11005. + ICP_SESSION_DEREGISTERED = 0xC5C5C5
  11006. +} usage_derisk;
  11007. +
  11008. +/* This struct is required for deferred session
  11009. + deregistration as a work queue function can
  11010. + only have one argument*/
  11011. +struct icp_ocfDrvFreeLacSession {
  11012. + CpaCySymSessionCtx sessionToDeregister;
  11013. + icp_workstruct work;
  11014. +};
  11015. +
  11016. +/*
  11017. +This is the OCF<->OCF_DRV session object:
  11018. +
  11019. +1.listNode
  11020. + The first member is a listNode. These session objects are added to a linked
  11021. + list in order to make it easier to remove them all at session exit time.
  11022. +
  11023. +2.inUse
  11024. + The second member is used to give the session object state and derisk the
  11025. + possibility of OCF batch calls executing against a deregistered session (as
  11026. + described above).
  11027. +
  11028. +3.sessHandle
  11029. + The third member is a LAC<->OCF_DRV session handle (initialised with the first
  11030. + perform request for that session).
  11031. +
  11032. +4.lacSessCtx
  11033. + The fourth is the LAC session context. All the parameters for this structure
  11034. + are only known when the first perform request for this session occurs. That is
  11035. + why the OCF EP80579 Driver only registers a new LAC session at perform time
  11036. +*/
  11037. +struct icp_drvSessionData {
  11038. + ICP_LIST_ENTRY(icp_drvSessionData) listNode;
  11039. + usage_derisk inUse;
  11040. + CpaCySymSessionCtx sessHandle;
  11041. + CpaCySymSessionSetupData lacSessCtx;
  11042. +};
  11043. +
  11044. +/* These are all defined in icp_common.c */
  11045. +extern icp_atomic_t lac_session_failed_dereg_count;
  11046. +extern icp_atomic_t icp_ocfDrvIsExiting;
  11047. +extern icp_atomic_t num_ocf_to_drv_registered_sessions;
  11048. +
  11049. +extern int32_t icp_ocfDrvDriverId;
  11050. +
  11051. +extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
  11052. +extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
  11053. +extern icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ;
  11054. +extern icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
  11055. +
  11056. +/*Slab zones for symettric functionality, instantiated in icp_common.c*/
  11057. +extern icp_kmem_cache drvSessionData_zone;
  11058. +extern icp_kmem_cache drvOpData_zone;
  11059. +
  11060. +/*Slabs zones for asymettric functionality, instantiated in icp_common.c*/
  11061. +extern icp_kmem_cache drvDH_zone;
  11062. +extern icp_kmem_cache drvLnModExp_zone;
  11063. +extern icp_kmem_cache drvRSADecrypt_zone;
  11064. +extern icp_kmem_cache drvRSAPrivateKey_zone;
  11065. +extern icp_kmem_cache drvDSARSSign_zone;
  11066. +extern icp_kmem_cache drvDSARSSignKValue_zone;
  11067. +extern icp_kmem_cache drvDSAVerify_zone;
  11068. +
  11069. +/* Module parameters defined in icp_cpmmon.c*/
  11070. +
  11071. +/* Module parameters - gives the number of times LAC deregistration shall be
  11072. + re-tried */
  11073. +extern int num_dereg_retries;
  11074. +
  11075. +/* Module parameter - gives the delay time in jiffies before a LAC session
  11076. + shall be attempted to be deregistered again */
  11077. +extern int dereg_retry_delay_in_jiffies;
  11078. +
  11079. +/* Module parameter - gives the maximum number of sessions possible between
  11080. + OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
  11081. +extern int max_sessions;
  11082. +
  11083. +/*Slab zones for flatbuffers and bufferlist*/
  11084. +extern icp_kmem_cache drvFlatBuffer_zone;
  11085. +
  11086. +#define ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS (16)
  11087. +
  11088. +struct icp_drvBuffListInfo {
  11089. + Cpa16U numBuffers;
  11090. + Cpa32U metaSize;
  11091. + Cpa32U metaOffset;
  11092. + Cpa32U buffListSize;
  11093. +};
  11094. +
  11095. +extern struct icp_drvBuffListInfo defBuffListInfo;
  11096. +
  11097. +/* This struct is used to keep a reference to the relevant node in the list
  11098. + of sessionData structs, to the buffer type required by OCF and to the OCF
  11099. + provided crp struct that needs to be returned. All this info is needed in
  11100. + the callback function.*/
  11101. +struct icp_drvOpData {
  11102. + CpaCySymOpData lacOpData;
  11103. + uint32_t digestSizeInBytes;
  11104. + struct cryptop *crp;
  11105. + uint8_t bufferType;
  11106. + uint8_t ivData[MAX_IV_LEN_IN_BYTES];
  11107. + uint16_t numBufferListArray;
  11108. + CpaBufferList srcBuffer;
  11109. + CpaFlatBuffer bufferListArray[ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS];
  11110. + CpaBoolean verifyResult;
  11111. +};
  11112. +
  11113. +/* Create a new session between OCF and this driver*/
  11114. +int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sild,
  11115. + struct cryptoini *cri);
  11116. +
  11117. +/* Free a session between this driver and the Quick Assist Framework*/
  11118. +int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid);
  11119. +
  11120. +/* Defer freeing a Quick Assist session*/
  11121. +void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg);
  11122. +
  11123. +/* Process OCF cryptographic request for a symmetric algorithm*/
  11124. +int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint);
  11125. +
  11126. +/* Process OCF cryptographic request for an asymmetric algorithm*/
  11127. +int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint);
  11128. +
  11129. +/* Populate a buffer with random data*/
  11130. +int icp_ocfDrvReadRandom(void *arg, uint32_t * buf, int maxwords);
  11131. +
  11132. +/* Retry Quick Assist session deregistration*/
  11133. +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister);
  11134. +
  11135. +/* Convert an OS scatter gather list to a CPA buffer list*/
  11136. +int icp_ocfDrvPacketBuffToBufferList(icp_packet_buffer_t * pPacketBuffer,
  11137. + CpaBufferList * bufferList);
  11138. +
  11139. +/* Convert a CPA buffer list to an OS scatter gather list*/
  11140. +int icp_ocfDrvBufferListToPacketBuff(CpaBufferList * bufferList,
  11141. + icp_packet_buffer_t ** pPacketBuffer);
  11142. +
  11143. +/* Get the number of buffers in an OS scatter gather list*/
  11144. +uint16_t icp_ocfDrvGetPacketBuffFrags(icp_packet_buffer_t * pPacketBuffer);
  11145. +
  11146. +/* Convert a single OS buffer to a CPA Flat Buffer*/
  11147. +void icp_ocfDrvSinglePacketBuffToFlatBuffer(icp_packet_buffer_t * pPacketBuffer,
  11148. + CpaFlatBuffer * pFlatBuffer);
  11149. +
  11150. +/* Add pointer and length to a CPA Flat Buffer structure*/
  11151. +void icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
  11152. + CpaFlatBuffer * pFlatBuffer);
  11153. +
  11154. +/* Convert pointer and length values to a CPA buffer list*/
  11155. +void icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
  11156. + CpaBufferList * pBufferList);
  11157. +
  11158. +/* Convert a CPA buffer list to pointer and length values*/
  11159. +void icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
  11160. + void **ppDataOut, uint32_t * pLength);
  11161. +
  11162. +/* Set the number of flat buffers in bufferlist and the size of memory
  11163. + to allocate for the pPrivateMetaData member of the CpaBufferList.*/
  11164. +int icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
  11165. + struct icp_drvBuffListInfo *buffListInfo);
  11166. +
  11167. +/* Find pointer position of the digest within an OS scatter gather list*/
  11168. +uint8_t *icp_ocfDrvPacketBufferDigestPointerFind(struct icp_drvOpData
  11169. + *drvOpData,
  11170. + int offsetInBytes,
  11171. + uint32_t digestSizeInBytes);
  11172. +
  11173. +/*This top level function is used to find a pointer to where a digest is
  11174. + stored/needs to be inserted. */
  11175. +uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData *drvOpData,
  11176. + struct cryptodesc *crp_desc);
  11177. +
  11178. +/* Free a CPA flat buffer*/
  11179. +void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer);
  11180. +
  11181. +/* This function will allocate memory for the pPrivateMetaData
  11182. + member of CpaBufferList. */
  11183. +int icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
  11184. + struct icp_drvOpData *pOpData);
  11185. +
  11186. +/* Free data allocated for the pPrivateMetaData
  11187. + member of CpaBufferList.*/
  11188. +void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList);
  11189. +
  11190. +#define ICP_CACHE_CREATE(cache_ID, cache_name) \
  11191. + icp_kmem_cache_create(cache_ID, sizeof(cache_name),ICP_KERNEL_CACHE_ALIGN,\
  11192. + ICP_KERNEL_CACHE_NOINIT)
  11193. +
  11194. +#define ICP_CACHE_FREE(args...) \
  11195. + icp_kmem_cache_free (args)
  11196. +
  11197. +#define ICP_CACHE_DESTROY(slab_zone)\
  11198. +{\
  11199. + if(NULL != slab_zone){\
  11200. + icp_kmem_cache_destroy(slab_zone);\
  11201. + slab_zone = NULL;\
  11202. + }\
  11203. +}
  11204. +
  11205. +#endif
  11206. +/* ICP_OCF_H_ */
  11207. diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/icp_sym.c linux-2.6.36/crypto/ocf/ep80579/icp_sym.c
  11208. --- linux-2.6.36.orig/crypto/ocf/ep80579/icp_sym.c 1970-01-01 01:00:00.000000000 +0100
  11209. +++ linux-2.6.36/crypto/ocf/ep80579/icp_sym.c 2010-11-09 20:28:04.702495471 +0100
  11210. @@ -0,0 +1,1153 @@
  11211. +/***************************************************************************
  11212. + *
  11213. + * This file is provided under a dual BSD/GPLv2 license. When using or
  11214. + * redistributing this file, you may do so under either license.
  11215. + *
  11216. + * GPL LICENSE SUMMARY
  11217. + *
  11218. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  11219. + *
  11220. + * This program is free software; you can redistribute it and/or modify
  11221. + * it under the terms of version 2 of the GNU General Public License as
  11222. + * published by the Free Software Foundation.
  11223. + *
  11224. + * This program is distributed in the hope that it will be useful, but
  11225. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  11226. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11227. + * General Public License for more details.
  11228. + *
  11229. + * You should have received a copy of the GNU General Public License
  11230. + * along with this program; if not, write to the Free Software
  11231. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  11232. + * The full GNU General Public License is included in this distribution
  11233. + * in the file called LICENSE.GPL.
  11234. + *
  11235. + * Contact Information:
  11236. + * Intel Corporation
  11237. + *
  11238. + * BSD LICENSE
  11239. + *
  11240. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  11241. + * All rights reserved.
  11242. + *
  11243. + * Redistribution and use in source and binary forms, with or without
  11244. + * modification, are permitted provided that the following conditions
  11245. + * are met:
  11246. + *
  11247. + * * Redistributions of source code must retain the above copyright
  11248. + * notice, this list of conditions and the following disclaimer.
  11249. + * * Redistributions in binary form must reproduce the above copyright
  11250. + * notice, this list of conditions and the following disclaimer in
  11251. + * the documentation and/or other materials provided with the
  11252. + * distribution.
  11253. + * * Neither the name of Intel Corporation nor the names of its
  11254. + * contributors may be used to endorse or promote products derived
  11255. + * from this software without specific prior written permission.
  11256. + *
  11257. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  11258. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  11259. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  11260. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  11261. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  11262. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11263. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  11264. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11265. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  11266. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  11267. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  11268. + *
  11269. + *
  11270. + * version: Security.L.1.0.2-229
  11271. + *
  11272. + ***************************************************************************/
  11273. +/*
  11274. + * An OCF module that uses the API for Intel® QuickAssist Technology to do the
  11275. + * cryptography.
  11276. + *
  11277. + * This driver requires the ICP Access Library that is available from Intel in
  11278. + * order to operate.
  11279. + */
  11280. +
  11281. +#include "icp_ocf.h"
  11282. +
  11283. +/*This is the call back function for all symmetric cryptographic processes.
  11284. + Its main functionality is to free driver crypto operation structure and to
  11285. + call back to OCF*/
  11286. +static void
  11287. +icp_ocfDrvSymCallBack(void *callbackTag,
  11288. + CpaStatus status,
  11289. + const CpaCySymOp operationType,
  11290. + void *pOpData,
  11291. + CpaBufferList * pDstBuffer, CpaBoolean verifyResult);
  11292. +
  11293. +/*This function is used to extract crypto processing information from the OCF
  11294. + inputs, so as that it may be passed onto LAC*/
  11295. +static int
  11296. +icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  11297. + struct cryptodesc *crp_desc);
  11298. +
  11299. +/*This function checks whether the crp_desc argument pertains to a digest or a
  11300. + cipher operation*/
  11301. +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc);
  11302. +
  11303. +/*This function copies all the passed in session context information and stores
  11304. + it in a LAC context structure*/
  11305. +static int
  11306. +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  11307. + CpaCySymSessionSetupData * lacSessCtx);
  11308. +
  11309. +/*This function is used to free an OCF->OCF_DRV session object*/
  11310. +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData);
  11311. +
  11312. +/*max IOV buffs supported in a UIO structure*/
  11313. +#define NUM_IOV_SUPPORTED (1)
  11314. +
  11315. +/* Name : icp_ocfDrvSymCallBack
  11316. + *
  11317. + * Description : When this function returns it signifies that the LAC
  11318. + * component has completed the relevant symmetric operation.
  11319. + *
  11320. + * Notes : The callbackTag is a pointer to an icp_drvOpData. This memory
  11321. + * object was passed to LAC for the cryptographic processing and contains all
  11322. + * the relevant information for cleaning up buffer handles etc. so that the
  11323. + * OCF EP80579 Driver portion of this crypto operation can be fully completed.
  11324. + */
  11325. +static void
  11326. +icp_ocfDrvSymCallBack(void *callbackTag,
  11327. + CpaStatus status,
  11328. + const CpaCySymOp operationType,
  11329. + void *pOpData,
  11330. + CpaBufferList * pDstBuffer, CpaBoolean verifyResult)
  11331. +{
  11332. + struct cryptop *crp = NULL;
  11333. + struct icp_drvOpData *temp_drvOpData =
  11334. + (struct icp_drvOpData *)callbackTag;
  11335. + uint64_t *tempBasePtr = NULL;
  11336. + uint32_t tempLen = 0;
  11337. +
  11338. + if (NULL == temp_drvOpData) {
  11339. + DPRINTK("%s(): The callback from the LAC component"
  11340. + " has failed due to Null userOpaque data"
  11341. + "(status == %d).\n", __FUNCTION__, status);
  11342. + DPRINTK("%s(): Unable to call OCF back! \n", __FUNCTION__);
  11343. + return;
  11344. + }
  11345. +
  11346. + crp = temp_drvOpData->crp;
  11347. + crp->crp_etype = ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR;
  11348. +
  11349. + if (NULL == pOpData) {
  11350. + DPRINTK("%s(): The callback from the LAC component"
  11351. + " has failed due to Null Symmetric Op data"
  11352. + "(status == %d).\n", __FUNCTION__, status);
  11353. + crp->crp_etype = ECANCELED;
  11354. + crypto_done(crp);
  11355. + return;
  11356. + }
  11357. +
  11358. + if (NULL == pDstBuffer) {
  11359. + DPRINTK("%s(): The callback from the LAC component"
  11360. + " has failed due to Null Dst Bufferlist data"
  11361. + "(status == %d).\n", __FUNCTION__, status);
  11362. + crp->crp_etype = ECANCELED;
  11363. + crypto_done(crp);
  11364. + return;
  11365. + }
  11366. +
  11367. + if (CPA_STATUS_SUCCESS == status) {
  11368. +
  11369. + if (temp_drvOpData->bufferType == ICP_CRYPTO_F_PACKET_BUF) {
  11370. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  11371. + icp_ocfDrvBufferListToPacketBuff(pDstBuffer,
  11372. + (icp_packet_buffer_t
  11373. + **)
  11374. + & (crp->crp_buf))) {
  11375. + EPRINTK("%s(): BufferList to SkBuff "
  11376. + "conversion error.\n", __FUNCTION__);
  11377. + crp->crp_etype = EPERM;
  11378. + }
  11379. + } else {
  11380. + icp_ocfDrvBufferListToPtrAndLen(pDstBuffer,
  11381. + (void **)&tempBasePtr,
  11382. + &tempLen);
  11383. + crp->crp_olen = (int)tempLen;
  11384. + }
  11385. +
  11386. + } else {
  11387. + DPRINTK("%s(): The callback from the LAC component has failed"
  11388. + "(status == %d).\n", __FUNCTION__, status);
  11389. +
  11390. + crp->crp_etype = ECANCELED;
  11391. + }
  11392. +
  11393. + if (temp_drvOpData->numBufferListArray >
  11394. + ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  11395. + icp_kfree(pDstBuffer->pBuffers);
  11396. + }
  11397. + icp_ocfDrvFreeMetaData(pDstBuffer);
  11398. + ICP_CACHE_FREE(drvOpData_zone, temp_drvOpData);
  11399. +
  11400. + /* Invoke the OCF callback function */
  11401. + crypto_done(crp);
  11402. +
  11403. + return;
  11404. +}
  11405. +
  11406. +/* Name : icp_ocfDrvNewSession
  11407. + *
  11408. + * Description : This function will create a new Driver<->OCF session
  11409. + *
  11410. + * Notes : LAC session registration happens during the first perform call.
  11411. + * That is the first time we know all information about a given session.
  11412. + */
  11413. +int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sid,
  11414. + struct cryptoini *cri)
  11415. +{
  11416. + struct icp_drvSessionData *sessionData = NULL;
  11417. + uint32_t delete_session = 0;
  11418. +
  11419. + /* The SID passed in should be our driver ID. We can return the */
  11420. + /* local ID (LID) which is a unique identifier which we can use */
  11421. + /* to differentiate between the encrypt/decrypt LAC session handles */
  11422. + if (NULL == sid) {
  11423. + EPRINTK("%s(): Invalid input parameters - NULL sid.\n",
  11424. + __FUNCTION__);
  11425. + return EINVAL;
  11426. + }
  11427. +
  11428. + if (NULL == cri) {
  11429. + EPRINTK("%s(): Invalid input parameters - NULL cryptoini.\n",
  11430. + __FUNCTION__);
  11431. + return EINVAL;
  11432. + }
  11433. +
  11434. + if (icp_ocfDrvDriverId != *sid) {
  11435. + EPRINTK("%s(): Invalid input parameters - bad driver ID\n",
  11436. + __FUNCTION__);
  11437. + EPRINTK("\t sid = 0x08%p \n \t cri = 0x08%p \n", sid, cri);
  11438. + return EINVAL;
  11439. + }
  11440. +
  11441. + sessionData = icp_kmem_cache_zalloc(drvSessionData_zone, ICP_M_NOWAIT);
  11442. + if (NULL == sessionData) {
  11443. + DPRINTK("%s():No memory for Session Data\n", __FUNCTION__);
  11444. + return ENOMEM;
  11445. + }
  11446. +
  11447. + /*ENTER CRITICAL SECTION */
  11448. + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  11449. + /*put this check in the spinlock so no new sessions can be added to the
  11450. + linked list when we are exiting */
  11451. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  11452. + delete_session++;
  11453. +
  11454. + } else if (NO_OCF_TO_DRV_MAX_SESSIONS != max_sessions) {
  11455. + if (icp_atomic_read(&num_ocf_to_drv_registered_sessions) >=
  11456. + (max_sessions -
  11457. + icp_atomic_read(&lac_session_failed_dereg_count))) {
  11458. + delete_session++;
  11459. + } else {
  11460. + icp_atomic_inc(&num_ocf_to_drv_registered_sessions);
  11461. + /* Add to session data linked list */
  11462. + ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
  11463. + listNode);
  11464. + }
  11465. +
  11466. + } else if (NO_OCF_TO_DRV_MAX_SESSIONS == max_sessions) {
  11467. + ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
  11468. + listNode);
  11469. + }
  11470. +
  11471. + sessionData->inUse = ICP_SESSION_INITIALISED;
  11472. +
  11473. + /*EXIT CRITICAL SECTION */
  11474. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  11475. +
  11476. + if (delete_session) {
  11477. + DPRINTK("%s():No Session handles available\n", __FUNCTION__);
  11478. + ICP_CACHE_FREE(drvSessionData_zone, sessionData);
  11479. + return EPERM;
  11480. + }
  11481. +
  11482. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  11483. + icp_ocfDrvAlgorithmSetup(cri, &(sessionData->lacSessCtx))) {
  11484. + DPRINTK("%s():algorithm not supported\n", __FUNCTION__);
  11485. + icp_ocfDrvFreeOCFSession(sessionData);
  11486. + return EINVAL;
  11487. + }
  11488. +
  11489. + if (cri->cri_next) {
  11490. + if (cri->cri_next->cri_next != NULL) {
  11491. + DPRINTK("%s():only two chained algorithms supported\n",
  11492. + __FUNCTION__);
  11493. + icp_ocfDrvFreeOCFSession(sessionData);
  11494. + return EPERM;
  11495. + }
  11496. +
  11497. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  11498. + icp_ocfDrvAlgorithmSetup(cri->cri_next,
  11499. + &(sessionData->lacSessCtx))) {
  11500. + DPRINTK("%s():second algorithm not supported\n",
  11501. + __FUNCTION__);
  11502. + icp_ocfDrvFreeOCFSession(sessionData);
  11503. + return EINVAL;
  11504. + }
  11505. +
  11506. + sessionData->lacSessCtx.symOperation =
  11507. + CPA_CY_SYM_OP_ALGORITHM_CHAINING;
  11508. + }
  11509. +
  11510. + *sid = (uint32_t) sessionData;
  11511. +
  11512. + return ICP_OCF_DRV_STATUS_SUCCESS;
  11513. +}
  11514. +
  11515. +/* Name : icp_ocfDrvAlgorithmSetup
  11516. + *
  11517. + * Description : This function builds the session context data from the
  11518. + * information supplied through OCF. Algorithm chain order and whether the
  11519. + * session is Encrypt/Decrypt can only be found out at perform time however, so
  11520. + * the session is registered with LAC at that time.
  11521. + */
  11522. +static int
  11523. +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  11524. + CpaCySymSessionSetupData * lacSessCtx)
  11525. +{
  11526. +
  11527. + lacSessCtx->sessionPriority = CPA_CY_PRIORITY_NORMAL;
  11528. +
  11529. + switch (cri->cri_alg) {
  11530. +
  11531. + case CRYPTO_NULL_CBC:
  11532. + DPRINTK("%s(): NULL CBC\n", __FUNCTION__);
  11533. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  11534. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  11535. + CPA_CY_SYM_CIPHER_NULL;
  11536. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  11537. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11538. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  11539. + break;
  11540. +
  11541. + case CRYPTO_DES_CBC:
  11542. + DPRINTK("%s(): DES CBC\n", __FUNCTION__);
  11543. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  11544. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  11545. + CPA_CY_SYM_CIPHER_DES_CBC;
  11546. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  11547. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11548. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  11549. + break;
  11550. +
  11551. + case CRYPTO_3DES_CBC:
  11552. + DPRINTK("%s(): 3DES CBC\n", __FUNCTION__);
  11553. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  11554. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  11555. + CPA_CY_SYM_CIPHER_3DES_CBC;
  11556. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  11557. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11558. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  11559. + break;
  11560. +
  11561. + case CRYPTO_AES_CBC:
  11562. + DPRINTK("%s(): AES CBC\n", __FUNCTION__);
  11563. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  11564. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  11565. + CPA_CY_SYM_CIPHER_AES_CBC;
  11566. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  11567. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11568. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  11569. + break;
  11570. +
  11571. + case CRYPTO_ARC4:
  11572. + DPRINTK("%s(): ARC4\n", __FUNCTION__);
  11573. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  11574. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  11575. + CPA_CY_SYM_CIPHER_ARC4;
  11576. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  11577. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11578. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  11579. + break;
  11580. +
  11581. + case CRYPTO_SHA1:
  11582. + DPRINTK("%s(): SHA1\n", __FUNCTION__);
  11583. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11584. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  11585. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  11586. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11587. + (cri->cri_mlen ?
  11588. + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  11589. +
  11590. + break;
  11591. +
  11592. + case CRYPTO_SHA1_HMAC:
  11593. + DPRINTK("%s(): SHA1_HMAC\n", __FUNCTION__);
  11594. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11595. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  11596. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  11597. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11598. + (cri->cri_mlen ?
  11599. + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  11600. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  11601. + cri->cri_key;
  11602. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  11603. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11604. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  11605. +
  11606. + break;
  11607. +
  11608. + case CRYPTO_SHA2_256:
  11609. + DPRINTK("%s(): SHA256\n", __FUNCTION__);
  11610. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11611. + lacSessCtx->hashSetupData.hashAlgorithm =
  11612. + CPA_CY_SYM_HASH_SHA256;
  11613. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  11614. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11615. + (cri->cri_mlen ?
  11616. + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  11617. +
  11618. + break;
  11619. +
  11620. + case CRYPTO_SHA2_256_HMAC:
  11621. + DPRINTK("%s(): SHA256_HMAC\n", __FUNCTION__);
  11622. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11623. + lacSessCtx->hashSetupData.hashAlgorithm =
  11624. + CPA_CY_SYM_HASH_SHA256;
  11625. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  11626. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11627. + (cri->cri_mlen ?
  11628. + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  11629. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  11630. + cri->cri_key;
  11631. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  11632. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11633. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  11634. +
  11635. + break;
  11636. +
  11637. + case CRYPTO_SHA2_384:
  11638. + DPRINTK("%s(): SHA384\n", __FUNCTION__);
  11639. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11640. + lacSessCtx->hashSetupData.hashAlgorithm =
  11641. + CPA_CY_SYM_HASH_SHA384;
  11642. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  11643. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11644. + (cri->cri_mlen ?
  11645. + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  11646. +
  11647. + break;
  11648. +
  11649. + case CRYPTO_SHA2_384_HMAC:
  11650. + DPRINTK("%s(): SHA384_HMAC\n", __FUNCTION__);
  11651. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11652. + lacSessCtx->hashSetupData.hashAlgorithm =
  11653. + CPA_CY_SYM_HASH_SHA384;
  11654. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  11655. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11656. + (cri->cri_mlen ?
  11657. + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  11658. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  11659. + cri->cri_key;
  11660. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  11661. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11662. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  11663. +
  11664. + break;
  11665. +
  11666. + case CRYPTO_SHA2_512:
  11667. + DPRINTK("%s(): SHA512\n", __FUNCTION__);
  11668. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11669. + lacSessCtx->hashSetupData.hashAlgorithm =
  11670. + CPA_CY_SYM_HASH_SHA512;
  11671. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  11672. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11673. + (cri->cri_mlen ?
  11674. + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  11675. +
  11676. + break;
  11677. +
  11678. + case CRYPTO_SHA2_512_HMAC:
  11679. + DPRINTK("%s(): SHA512_HMAC\n", __FUNCTION__);
  11680. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11681. + lacSessCtx->hashSetupData.hashAlgorithm =
  11682. + CPA_CY_SYM_HASH_SHA512;
  11683. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  11684. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11685. + (cri->cri_mlen ?
  11686. + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  11687. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  11688. + cri->cri_key;
  11689. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  11690. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11691. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  11692. +
  11693. + break;
  11694. +
  11695. + case CRYPTO_MD5:
  11696. + DPRINTK("%s(): MD5\n", __FUNCTION__);
  11697. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11698. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  11699. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  11700. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11701. + (cri->cri_mlen ?
  11702. + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  11703. +
  11704. + break;
  11705. +
  11706. + case CRYPTO_MD5_HMAC:
  11707. + DPRINTK("%s(): MD5_HMAC\n", __FUNCTION__);
  11708. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11709. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  11710. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  11711. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11712. + (cri->cri_mlen ?
  11713. + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  11714. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  11715. + cri->cri_key;
  11716. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  11717. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11718. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  11719. +
  11720. + break;
  11721. +
  11722. + default:
  11723. + DPRINTK("%s(): ALG Setup FAIL\n", __FUNCTION__);
  11724. + return ICP_OCF_DRV_STATUS_FAIL;
  11725. + }
  11726. +
  11727. + return ICP_OCF_DRV_STATUS_SUCCESS;
  11728. +}
  11729. +
  11730. +/* Name : icp_ocfDrvFreeOCFSession
  11731. + *
  11732. + * Description : This function deletes all existing Session data representing
  11733. + * the Cryptographic session established between OCF and this driver. This
  11734. + * also includes freeing the memory allocated for the session context. The
  11735. + * session object is also removed from the session linked list.
  11736. + */
  11737. +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData)
  11738. +{
  11739. +
  11740. + sessionData->inUse = ICP_SESSION_DEREGISTERED;
  11741. +
  11742. + /*ENTER CRITICAL SECTION */
  11743. + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  11744. +
  11745. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  11746. + /*If the Driver is exiting, allow that process to
  11747. + handle any deletions */
  11748. + /*EXIT CRITICAL SECTION */
  11749. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  11750. + return;
  11751. + }
  11752. +
  11753. + icp_atomic_dec(&num_ocf_to_drv_registered_sessions);
  11754. +
  11755. + ICP_LIST_DEL(sessionData, listNode);
  11756. +
  11757. + /*EXIT CRITICAL SECTION */
  11758. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  11759. +
  11760. + if (NULL != sessionData->sessHandle) {
  11761. + icp_kfree(sessionData->sessHandle);
  11762. + }
  11763. + ICP_CACHE_FREE(drvSessionData_zone, sessionData);
  11764. +}
  11765. +
  11766. +/* Name : icp_ocfDrvFreeLACSession
  11767. + *
  11768. + * Description : This attempts to deregister a LAC session. If it fails, the
  11769. + * deregistation retry function is called.
  11770. + */
  11771. +int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid)
  11772. +{
  11773. + CpaCySymSessionCtx sessionToDeregister = NULL;
  11774. + struct icp_drvSessionData *sessionData = NULL;
  11775. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  11776. + int retval = 0;
  11777. +
  11778. + sessionData = (struct icp_drvSessionData *)CRYPTO_SESID2LID(sid);
  11779. + if (NULL == sessionData) {
  11780. + EPRINTK("%s(): OCF Free session called with Null Session ID.\n",
  11781. + __FUNCTION__);
  11782. + return EINVAL;
  11783. + }
  11784. +
  11785. + sessionToDeregister = sessionData->sessHandle;
  11786. +
  11787. + if ((ICP_SESSION_INITIALISED != sessionData->inUse) &&
  11788. + (ICP_SESSION_RUNNING != sessionData->inUse) &&
  11789. + (ICP_SESSION_DEREGISTERED != sessionData->inUse)) {
  11790. + DPRINTK("%s() Session not initialised.\n", __FUNCTION__);
  11791. + return EINVAL;
  11792. + }
  11793. +
  11794. + if (ICP_SESSION_RUNNING == sessionData->inUse) {
  11795. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  11796. + sessionToDeregister);
  11797. + if (CPA_STATUS_RETRY == lacStatus) {
  11798. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  11799. + icp_ocfDrvDeregRetry(&sessionToDeregister)) {
  11800. + /* the retry function increments the
  11801. + dereg failed count */
  11802. + DPRINTK("%s(): LAC failed to deregister the "
  11803. + "session. (localSessionId= %p)\n",
  11804. + __FUNCTION__, sessionToDeregister);
  11805. + retval = EPERM;
  11806. + }
  11807. +
  11808. + } else if (CPA_STATUS_SUCCESS != lacStatus) {
  11809. + DPRINTK("%s(): LAC failed to deregister the session. "
  11810. + "localSessionId= %p, lacStatus = %d\n",
  11811. + __FUNCTION__, sessionToDeregister, lacStatus);
  11812. + icp_atomic_inc(&lac_session_failed_dereg_count);
  11813. + retval = EPERM;
  11814. + }
  11815. + } else {
  11816. + DPRINTK("%s() Session not registered with LAC.\n",
  11817. + __FUNCTION__);
  11818. + }
  11819. +
  11820. + icp_ocfDrvFreeOCFSession(sessionData);
  11821. + return retval;
  11822. +
  11823. +}
  11824. +
  11825. +/* Name : icp_ocfDrvAlgCheck
  11826. + *
  11827. + * Description : This function checks whether the cryptodesc argument pertains
  11828. + * to a sym or hash function
  11829. + */
  11830. +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc)
  11831. +{
  11832. +
  11833. + if (crp_desc->crd_alg == CRYPTO_3DES_CBC ||
  11834. + crp_desc->crd_alg == CRYPTO_AES_CBC ||
  11835. + crp_desc->crd_alg == CRYPTO_DES_CBC ||
  11836. + crp_desc->crd_alg == CRYPTO_NULL_CBC ||
  11837. + crp_desc->crd_alg == CRYPTO_ARC4) {
  11838. + return ICP_OCF_DRV_ALG_CIPHER;
  11839. + }
  11840. +
  11841. + return ICP_OCF_DRV_ALG_HASH;
  11842. +}
  11843. +
  11844. +/* Name : icp_ocfDrvSymProcess
  11845. + *
  11846. + * Description : This function will map symmetric functionality calls from OCF
  11847. + * to the LAC API. It will also allocate memory to store the session context.
  11848. + *
  11849. + * Notes: If it is the first perform call for a given session, then a LAC
  11850. + * session is registered. After the session is registered, no checks as
  11851. + * to whether session paramaters have changed (e.g. alg chain order) are
  11852. + * done.
  11853. + */
  11854. +int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint)
  11855. +{
  11856. + struct icp_drvSessionData *sessionData = NULL;
  11857. + struct icp_drvOpData *drvOpData = NULL;
  11858. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  11859. + Cpa32U sessionCtxSizeInBytes = 0;
  11860. +
  11861. + if (NULL == crp) {
  11862. + DPRINTK("%s(): Invalid input parameters, cryptop is NULL\n",
  11863. + __FUNCTION__);
  11864. + return EINVAL;
  11865. + }
  11866. +
  11867. + if (NULL == crp->crp_desc) {
  11868. + DPRINTK("%s(): Invalid input parameters, no crp_desc attached "
  11869. + "to crp\n", __FUNCTION__);
  11870. + crp->crp_etype = EINVAL;
  11871. + return EINVAL;
  11872. + }
  11873. +
  11874. + if (NULL == crp->crp_buf) {
  11875. + DPRINTK("%s(): Invalid input parameters, no buffer attached "
  11876. + "to crp\n", __FUNCTION__);
  11877. + crp->crp_etype = EINVAL;
  11878. + return EINVAL;
  11879. + }
  11880. +
  11881. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  11882. + crp->crp_etype = EFAULT;
  11883. + return EFAULT;
  11884. + }
  11885. +
  11886. + sessionData = (struct icp_drvSessionData *)
  11887. + (CRYPTO_SESID2LID(crp->crp_sid));
  11888. + if (NULL == sessionData) {
  11889. + DPRINTK("%s(): Invalid input parameters, Null Session ID \n",
  11890. + __FUNCTION__);
  11891. + crp->crp_etype = EINVAL;
  11892. + return EINVAL;
  11893. + }
  11894. +
  11895. +/*If we get a request against a deregisted session, cancel operation*/
  11896. + if (ICP_SESSION_DEREGISTERED == sessionData->inUse) {
  11897. + DPRINTK("%s(): Session ID %d was deregistered \n",
  11898. + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  11899. + crp->crp_etype = EFAULT;
  11900. + return EFAULT;
  11901. + }
  11902. +
  11903. +/*If none of the session states are set, then the session structure was either
  11904. + not initialised properly or we are reading from a freed memory area (possible
  11905. + due to OCF batch mode not removing queued requests against deregistered
  11906. + sessions*/
  11907. + if (ICP_SESSION_INITIALISED != sessionData->inUse &&
  11908. + ICP_SESSION_RUNNING != sessionData->inUse) {
  11909. + DPRINTK("%s(): Session - ID %d - not properly initialised or "
  11910. + "memory freed back to the kernel \n",
  11911. + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  11912. + crp->crp_etype = EINVAL;
  11913. + return EINVAL;
  11914. + }
  11915. +
  11916. + /*For the below checks, remember error checking is already done in LAC.
  11917. + We're not validating inputs subsequent to registration */
  11918. + if (sessionData->inUse == ICP_SESSION_INITIALISED) {
  11919. + DPRINTK("%s(): Initialising session\n", __FUNCTION__);
  11920. +
  11921. + if (NULL != crp->crp_desc->crd_next) {
  11922. + if (ICP_OCF_DRV_ALG_CIPHER ==
  11923. + icp_ocfDrvAlgCheck(crp->crp_desc)) {
  11924. +
  11925. + sessionData->lacSessCtx.algChainOrder =
  11926. + CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
  11927. +
  11928. + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  11929. + sessionData->lacSessCtx.cipherSetupData.
  11930. + cipherDirection =
  11931. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  11932. + } else {
  11933. + sessionData->lacSessCtx.cipherSetupData.
  11934. + cipherDirection =
  11935. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  11936. + }
  11937. + } else {
  11938. + sessionData->lacSessCtx.algChainOrder =
  11939. + CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
  11940. +
  11941. + if (crp->crp_desc->crd_next->crd_flags &
  11942. + CRD_F_ENCRYPT) {
  11943. + sessionData->lacSessCtx.cipherSetupData.
  11944. + cipherDirection =
  11945. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  11946. + } else {
  11947. + sessionData->lacSessCtx.cipherSetupData.
  11948. + cipherDirection =
  11949. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  11950. + }
  11951. +
  11952. + }
  11953. +
  11954. + } else if (ICP_OCF_DRV_ALG_CIPHER ==
  11955. + icp_ocfDrvAlgCheck(crp->crp_desc)) {
  11956. + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  11957. + sessionData->lacSessCtx.cipherSetupData.
  11958. + cipherDirection =
  11959. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  11960. + } else {
  11961. + sessionData->lacSessCtx.cipherSetupData.
  11962. + cipherDirection =
  11963. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  11964. + }
  11965. +
  11966. + }
  11967. +
  11968. + /*No action required for standalone Auth here */
  11969. +
  11970. + /* Allocate memory for SymSessionCtx before the Session Registration */
  11971. + lacStatus =
  11972. + cpaCySymSessionCtxGetSize(CPA_INSTANCE_HANDLE_SINGLE,
  11973. + &(sessionData->lacSessCtx),
  11974. + &sessionCtxSizeInBytes);
  11975. + if (CPA_STATUS_SUCCESS != lacStatus) {
  11976. + EPRINTK("%s(): cpaCySymSessionCtxGetSize failed - %d\n",
  11977. + __FUNCTION__, lacStatus);
  11978. + crp->crp_etype = EINVAL;
  11979. + return EINVAL;
  11980. + }
  11981. + sessionData->sessHandle =
  11982. + icp_kmalloc(sessionCtxSizeInBytes, ICP_M_NOWAIT);
  11983. + if (NULL == sessionData->sessHandle) {
  11984. + EPRINTK
  11985. + ("%s(): Failed to get memory for SymSessionCtx\n",
  11986. + __FUNCTION__);
  11987. + crp->crp_etype = ENOMEM;
  11988. + return ENOMEM;
  11989. + }
  11990. +
  11991. + lacStatus = cpaCySymInitSession(CPA_INSTANCE_HANDLE_SINGLE,
  11992. + icp_ocfDrvSymCallBack,
  11993. + &(sessionData->lacSessCtx),
  11994. + sessionData->sessHandle);
  11995. +
  11996. + if (CPA_STATUS_SUCCESS != lacStatus) {
  11997. + EPRINTK("%s(): cpaCySymInitSession failed -%d \n",
  11998. + __FUNCTION__, lacStatus);
  11999. + crp->crp_etype = EFAULT;
  12000. + return EFAULT;
  12001. + }
  12002. +
  12003. + sessionData->inUse = ICP_SESSION_RUNNING;
  12004. + }
  12005. +
  12006. + drvOpData = icp_kmem_cache_zalloc(drvOpData_zone, ICP_M_NOWAIT);
  12007. + if (NULL == drvOpData) {
  12008. + EPRINTK("%s():Failed to get memory for drvOpData\n",
  12009. + __FUNCTION__);
  12010. + crp->crp_etype = ENOMEM;
  12011. + return ENOMEM;
  12012. + }
  12013. +
  12014. + drvOpData->lacOpData.pSessionCtx = sessionData->sessHandle;
  12015. + drvOpData->digestSizeInBytes = sessionData->lacSessCtx.hashSetupData.
  12016. + digestResultLenInBytes;
  12017. + drvOpData->crp = crp;
  12018. +
  12019. + /* Set the default buffer list array memory allocation */
  12020. + drvOpData->srcBuffer.pBuffers = drvOpData->bufferListArray;
  12021. + drvOpData->numBufferListArray = ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS;
  12022. +
  12023. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  12024. + icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->crp_desc)) {
  12025. + crp->crp_etype = EINVAL;
  12026. + goto err;
  12027. + }
  12028. +
  12029. + if (drvOpData->crp->crp_desc->crd_next != NULL) {
  12030. + if (icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->
  12031. + crp_desc->crd_next)) {
  12032. + crp->crp_etype = EINVAL;
  12033. + goto err;
  12034. + }
  12035. +
  12036. + }
  12037. +
  12038. + /*
  12039. + * Allocate buffer list array memory if the data fragment is more than
  12040. + * the default number (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) and not
  12041. + * calculated already
  12042. + */
  12043. + if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  12044. + if (NULL == drvOpData->lacOpData.pDigestResult) {
  12045. + drvOpData->numBufferListArray =
  12046. + icp_ocfDrvGetPacketBuffFrags((icp_packet_buffer_t *)
  12047. + crp->crp_buf);
  12048. + }
  12049. +
  12050. + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS <
  12051. + drvOpData->numBufferListArray) {
  12052. + DPRINTK("%s() numBufferListArray more than default\n",
  12053. + __FUNCTION__);
  12054. + drvOpData->srcBuffer.pBuffers = NULL;
  12055. + drvOpData->srcBuffer.pBuffers =
  12056. + icp_kmalloc(drvOpData->numBufferListArray *
  12057. + sizeof(CpaFlatBuffer), ICP_M_NOWAIT);
  12058. + if (NULL == drvOpData->srcBuffer.pBuffers) {
  12059. + EPRINTK("%s() Failed to get memory for "
  12060. + "pBuffers\n", __FUNCTION__);
  12061. + ICP_CACHE_FREE(drvOpData_zone, drvOpData);
  12062. + crp->crp_etype = ENOMEM;
  12063. + return ENOMEM;
  12064. + }
  12065. + }
  12066. + }
  12067. +
  12068. + /*
  12069. + * Check the type of buffer structure we got and convert it into
  12070. + * CpaBufferList format.
  12071. + */
  12072. + if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  12073. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  12074. + icp_ocfDrvPacketBuffToBufferList((icp_packet_buffer_t *)
  12075. + crp->crp_buf,
  12076. + &(drvOpData->srcBuffer))) {
  12077. + EPRINTK("%s():Failed to translate from packet buffer "
  12078. + "to bufferlist\n", __FUNCTION__);
  12079. + crp->crp_etype = EINVAL;
  12080. + goto err;
  12081. + }
  12082. +
  12083. + drvOpData->bufferType = ICP_CRYPTO_F_PACKET_BUF;
  12084. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  12085. + /* OCF only supports IOV of one entry. */
  12086. + if (NUM_IOV_SUPPORTED ==
  12087. + ((struct uio *)(crp->crp_buf))->uio_iovcnt) {
  12088. +
  12089. + icp_ocfDrvPtrAndLenToBufferList(((struct uio *)(crp->
  12090. + crp_buf))->
  12091. + uio_iov[0].iov_base,
  12092. + ((struct uio *)(crp->
  12093. + crp_buf))->
  12094. + uio_iov[0].iov_len,
  12095. + &(drvOpData->
  12096. + srcBuffer));
  12097. +
  12098. + drvOpData->bufferType = CRYPTO_F_IOV;
  12099. +
  12100. + } else {
  12101. + DPRINTK("%s():Unable to handle IOVs with lengths of "
  12102. + "greater than one!\n", __FUNCTION__);
  12103. + crp->crp_etype = EINVAL;
  12104. + goto err;
  12105. + }
  12106. +
  12107. + } else {
  12108. + icp_ocfDrvPtrAndLenToBufferList(crp->crp_buf,
  12109. + crp->crp_ilen,
  12110. + &(drvOpData->srcBuffer));
  12111. +
  12112. + drvOpData->bufferType = CRYPTO_BUF_CONTIG;
  12113. + }
  12114. +
  12115. + /* Allocate srcBuffer's private meta data */
  12116. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  12117. + icp_ocfDrvAllocMetaData(&(drvOpData->srcBuffer), drvOpData)) {
  12118. + EPRINTK("%s() icp_ocfDrvAllocMetaData failed\n", __FUNCTION__);
  12119. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  12120. + crp->crp_etype = EINVAL;
  12121. + goto err;
  12122. + }
  12123. +
  12124. + /* Perform "in-place" crypto operation */
  12125. + lacStatus = cpaCySymPerformOp(CPA_INSTANCE_HANDLE_SINGLE,
  12126. + (void *)drvOpData,
  12127. + &(drvOpData->lacOpData),
  12128. + &(drvOpData->srcBuffer),
  12129. + &(drvOpData->srcBuffer),
  12130. + &(drvOpData->verifyResult));
  12131. + if (CPA_STATUS_RETRY == lacStatus) {
  12132. + DPRINTK("%s(): cpaCySymPerformOp retry, lacStatus = %d\n",
  12133. + __FUNCTION__, lacStatus);
  12134. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  12135. + crp->crp_etype = ERESTART;
  12136. + goto err;
  12137. + }
  12138. + if (CPA_STATUS_SUCCESS != lacStatus) {
  12139. + EPRINTK("%s(): cpaCySymPerformOp failed, lacStatus = %d\n",
  12140. + __FUNCTION__, lacStatus);
  12141. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  12142. + crp->crp_etype = EINVAL;
  12143. + goto err;
  12144. + }
  12145. +
  12146. + return 0; //OCF success status value
  12147. +
  12148. + err:
  12149. + if (drvOpData->numBufferListArray > ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  12150. + icp_kfree(drvOpData->srcBuffer.pBuffers);
  12151. + }
  12152. + icp_ocfDrvFreeMetaData(&(drvOpData->srcBuffer));
  12153. + ICP_CACHE_FREE(drvOpData_zone, drvOpData);
  12154. +
  12155. + return crp->crp_etype;
  12156. +}
  12157. +
  12158. +/* Name : icp_ocfDrvProcessDataSetup
  12159. + *
  12160. + * Description : This function will setup all the cryptographic operation data
  12161. + * that is required by LAC to execute the operation.
  12162. + */
  12163. +static int icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  12164. + struct cryptodesc *crp_desc)
  12165. +{
  12166. + CpaCyRandGenOpData randGenOpData;
  12167. + CpaFlatBuffer randData;
  12168. +
  12169. + drvOpData->lacOpData.packetType = CPA_CY_SYM_PACKET_TYPE_FULL;
  12170. +
  12171. + /* Convert from the cryptop to the ICP LAC crypto parameters */
  12172. + switch (crp_desc->crd_alg) {
  12173. + case CRYPTO_NULL_CBC:
  12174. + drvOpData->lacOpData.
  12175. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  12176. + drvOpData->lacOpData.
  12177. + messageLenToCipherInBytes = crp_desc->crd_len;
  12178. + drvOpData->verifyResult = CPA_FALSE;
  12179. + drvOpData->lacOpData.ivLenInBytes = NULL_BLOCK_LEN;
  12180. + break;
  12181. + case CRYPTO_DES_CBC:
  12182. + drvOpData->lacOpData.
  12183. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  12184. + drvOpData->lacOpData.
  12185. + messageLenToCipherInBytes = crp_desc->crd_len;
  12186. + drvOpData->verifyResult = CPA_FALSE;
  12187. + drvOpData->lacOpData.ivLenInBytes = DES_BLOCK_LEN;
  12188. + break;
  12189. + case CRYPTO_3DES_CBC:
  12190. + drvOpData->lacOpData.
  12191. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  12192. + drvOpData->lacOpData.
  12193. + messageLenToCipherInBytes = crp_desc->crd_len;
  12194. + drvOpData->verifyResult = CPA_FALSE;
  12195. + drvOpData->lacOpData.ivLenInBytes = DES3_BLOCK_LEN;
  12196. + break;
  12197. + case CRYPTO_ARC4:
  12198. + drvOpData->lacOpData.
  12199. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  12200. + drvOpData->lacOpData.
  12201. + messageLenToCipherInBytes = crp_desc->crd_len;
  12202. + drvOpData->verifyResult = CPA_FALSE;
  12203. + drvOpData->lacOpData.ivLenInBytes = ARC4_COUNTER_LEN;
  12204. + break;
  12205. + case CRYPTO_AES_CBC:
  12206. + drvOpData->lacOpData.
  12207. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  12208. + drvOpData->lacOpData.
  12209. + messageLenToCipherInBytes = crp_desc->crd_len;
  12210. + drvOpData->verifyResult = CPA_FALSE;
  12211. + drvOpData->lacOpData.ivLenInBytes = RIJNDAEL128_BLOCK_LEN;
  12212. + break;
  12213. + case CRYPTO_SHA1:
  12214. + case CRYPTO_SHA1_HMAC:
  12215. + case CRYPTO_SHA2_256:
  12216. + case CRYPTO_SHA2_256_HMAC:
  12217. + case CRYPTO_SHA2_384:
  12218. + case CRYPTO_SHA2_384_HMAC:
  12219. + case CRYPTO_SHA2_512:
  12220. + case CRYPTO_SHA2_512_HMAC:
  12221. + case CRYPTO_MD5:
  12222. + case CRYPTO_MD5_HMAC:
  12223. + drvOpData->lacOpData.
  12224. + hashStartSrcOffsetInBytes = crp_desc->crd_skip;
  12225. + drvOpData->lacOpData.
  12226. + messageLenToHashInBytes = crp_desc->crd_len;
  12227. + drvOpData->lacOpData.
  12228. + pDigestResult =
  12229. + icp_ocfDrvDigestPointerFind(drvOpData, crp_desc);
  12230. +
  12231. + if (NULL == drvOpData->lacOpData.pDigestResult) {
  12232. + DPRINTK("%s(): ERROR - could not calculate "
  12233. + "Digest Result memory address\n", __FUNCTION__);
  12234. + return ICP_OCF_DRV_STATUS_FAIL;
  12235. + }
  12236. +
  12237. + drvOpData->lacOpData.digestVerify = CPA_FALSE;
  12238. + break;
  12239. + default:
  12240. + DPRINTK("%s(): Crypto process error - algorithm not "
  12241. + "found \n", __FUNCTION__);
  12242. + return ICP_OCF_DRV_STATUS_FAIL;
  12243. + }
  12244. +
  12245. + /* Figure out what the IV is supposed to be */
  12246. + if ((crp_desc->crd_alg == CRYPTO_DES_CBC) ||
  12247. + (crp_desc->crd_alg == CRYPTO_3DES_CBC) ||
  12248. + (crp_desc->crd_alg == CRYPTO_AES_CBC)) {
  12249. + /*ARC4 doesn't use an IV */
  12250. + if (crp_desc->crd_flags & CRD_F_IV_EXPLICIT) {
  12251. + /* Explicit IV provided to OCF */
  12252. + drvOpData->lacOpData.pIv = crp_desc->crd_iv;
  12253. + } else {
  12254. + /* IV is not explicitly provided to OCF */
  12255. +
  12256. + /* Point the LAC OP Data IV pointer to our allocated
  12257. + storage location for this session. */
  12258. + drvOpData->lacOpData.pIv = drvOpData->ivData;
  12259. +
  12260. + if ((crp_desc->crd_flags & CRD_F_ENCRYPT) &&
  12261. + ((crp_desc->crd_flags & CRD_F_IV_PRESENT) == 0)) {
  12262. +
  12263. + /* Encrypting - need to create IV */
  12264. + randGenOpData.generateBits = CPA_TRUE;
  12265. + randGenOpData.lenInBytes = MAX_IV_LEN_IN_BYTES;
  12266. +
  12267. + icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *)
  12268. + drvOpData->
  12269. + ivData,
  12270. + MAX_IV_LEN_IN_BYTES,
  12271. + &randData);
  12272. +
  12273. + if (CPA_STATUS_SUCCESS !=
  12274. + cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  12275. + NULL, NULL,
  12276. + &randGenOpData, &randData)) {
  12277. + DPRINTK("%s(): ERROR - Failed to"
  12278. + " generate"
  12279. + " Initialisation Vector\n",
  12280. + __FUNCTION__);
  12281. + return ICP_OCF_DRV_STATUS_FAIL;
  12282. + }
  12283. +
  12284. + crypto_copyback(drvOpData->crp->
  12285. + crp_flags,
  12286. + drvOpData->crp->crp_buf,
  12287. + crp_desc->crd_inject,
  12288. + drvOpData->lacOpData.
  12289. + ivLenInBytes,
  12290. + (caddr_t) (drvOpData->lacOpData.
  12291. + pIv));
  12292. + } else {
  12293. + /* Reading IV from buffer */
  12294. + crypto_copydata(drvOpData->crp->
  12295. + crp_flags,
  12296. + drvOpData->crp->crp_buf,
  12297. + crp_desc->crd_inject,
  12298. + drvOpData->lacOpData.
  12299. + ivLenInBytes,
  12300. + (caddr_t) (drvOpData->lacOpData.
  12301. + pIv));
  12302. + }
  12303. +
  12304. + }
  12305. +
  12306. + }
  12307. +
  12308. + return ICP_OCF_DRV_STATUS_SUCCESS;
  12309. +}
  12310. +
  12311. +/* Name : icp_ocfDrvDigestPointerFind
  12312. + *
  12313. + * Description : This function is used to find the memory address of where the
  12314. + * digest information shall be stored in. Input buffer types are an skbuff, iov
  12315. + * or flat buffer. The address is found using the buffer data start address and
  12316. + * an offset.
  12317. + *
  12318. + * Note: In the case of a linux skbuff, the digest address may exist within
  12319. + * a memory space linked to from the start buffer. These linked memory spaces
  12320. + * must be traversed by the data length offset in order to find the digest start
  12321. + * address. Whether there is enough space for the digest must also be checked.
  12322. + */
  12323. +uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData * drvOpData,
  12324. + struct cryptodesc * crp_desc)
  12325. +{
  12326. +
  12327. + int offsetInBytes = crp_desc->crd_inject;
  12328. + uint32_t digestSizeInBytes = drvOpData->digestSizeInBytes;
  12329. + uint8_t *flat_buffer_base = NULL;
  12330. + int flat_buffer_length = 0;
  12331. +
  12332. + if (drvOpData->crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  12333. +
  12334. + return icp_ocfDrvPacketBufferDigestPointerFind(drvOpData,
  12335. + offsetInBytes,
  12336. + digestSizeInBytes);
  12337. +
  12338. + } else {
  12339. + /* IOV or flat buffer */
  12340. + if (drvOpData->crp->crp_flags & CRYPTO_F_IOV) {
  12341. + /*single IOV check has already been done */
  12342. + flat_buffer_base = ((struct uio *)
  12343. + (drvOpData->crp->crp_buf))->
  12344. + uio_iov[0].iov_base;
  12345. + flat_buffer_length = ((struct uio *)
  12346. + (drvOpData->crp->crp_buf))->
  12347. + uio_iov[0].iov_len;
  12348. + } else {
  12349. + flat_buffer_base = (uint8_t *) drvOpData->crp->crp_buf;
  12350. + flat_buffer_length = drvOpData->crp->crp_ilen;
  12351. + }
  12352. +
  12353. + if (flat_buffer_length < (offsetInBytes + digestSizeInBytes)) {
  12354. + DPRINTK("%s() Not enough space for Digest "
  12355. + "(IOV/Flat Buffer) \n", __FUNCTION__);
  12356. + return NULL;
  12357. + } else {
  12358. + return (uint8_t *) (flat_buffer_base + offsetInBytes);
  12359. + }
  12360. + }
  12361. + DPRINTK("%s() Should not reach this point\n", __FUNCTION__);
  12362. + return NULL;
  12363. +}
  12364. diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/Makefile linux-2.6.36/crypto/ocf/ep80579/Makefile
  12365. --- linux-2.6.36.orig/crypto/ocf/ep80579/Makefile 1970-01-01 01:00:00.000000000 +0100
  12366. +++ linux-2.6.36/crypto/ocf/ep80579/Makefile 2010-11-09 20:28:04.742495461 +0100
  12367. @@ -0,0 +1,119 @@
  12368. +#########################################################################
  12369. +#
  12370. +# Targets supported
  12371. +# all - builds everything and installs
  12372. +# install - identical to all
  12373. +# depend - build dependencies
  12374. +# clean - clears derived objects except the .depend files
  12375. +# distclean- clears all derived objects and the .depend file
  12376. +#
  12377. +# @par
  12378. +# This file is provided under a dual BSD/GPLv2 license. When using or
  12379. +# redistributing this file, you may do so under either license.
  12380. +#
  12381. +# GPL LICENSE SUMMARY
  12382. +#
  12383. +# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  12384. +#
  12385. +# This program is free software; you can redistribute it and/or modify
  12386. +# it under the terms of version 2 of the GNU General Public License as
  12387. +# published by the Free Software Foundation.
  12388. +#
  12389. +# This program is distributed in the hope that it will be useful, but
  12390. +# WITHOUT ANY WARRANTY; without even the implied warranty of
  12391. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12392. +# General Public License for more details.
  12393. +#
  12394. +# You should have received a copy of the GNU General Public License
  12395. +# along with this program; if not, write to the Free Software
  12396. +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  12397. +# The full GNU General Public License is included in this distribution
  12398. +# in the file called LICENSE.GPL.
  12399. +#
  12400. +# Contact Information:
  12401. +# Intel Corporation
  12402. +#
  12403. +# BSD LICENSE
  12404. +#
  12405. +# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  12406. +# All rights reserved.
  12407. +#
  12408. +# Redistribution and use in source and binary forms, with or without
  12409. +# modification, are permitted provided that the following conditions
  12410. +# are met:
  12411. +#
  12412. +# * Redistributions of source code must retain the above copyright
  12413. +# notice, this list of conditions and the following disclaimer.
  12414. +# * Redistributions in binary form must reproduce the above copyright
  12415. +# notice, this list of conditions and the following disclaimer in
  12416. +# the documentation and/or other materials provided with the
  12417. +# distribution.
  12418. +# * Neither the name of Intel Corporation nor the names of its
  12419. +# contributors may be used to endorse or promote products derived
  12420. +# from this software without specific prior written permission.
  12421. +#
  12422. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12423. +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12424. +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  12425. +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  12426. +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  12427. +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  12428. +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12429. +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12430. +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12431. +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  12432. +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12433. +#
  12434. +#
  12435. +# version: Security.L.1.0.2-229
  12436. +############################################################################
  12437. +
  12438. +
  12439. +####################Common variables and definitions########################
  12440. +
  12441. +ifndef ICP_ROOT
  12442. +$(warning ICP_ROOT is undefined. Please set the path to EP80579 release package directory \
  12443. + "-> setenv ICP_ROOT <path>")
  12444. +all fastdep:
  12445. + :
  12446. +else
  12447. +
  12448. +ifndef KERNEL_SOURCE_ROOT
  12449. +$(error KERNEL_SOURCE_ROOT is undefined. Please set the path to the kernel source directory \
  12450. + "-> setenv KERNEL_SOURCE_ROOT <path>")
  12451. +endif
  12452. +
  12453. +# Ensure The ENV_DIR environmental var is defined.
  12454. +ifndef ICP_ENV_DIR
  12455. +$(error ICP_ENV_DIR is undefined. Please set the path to EP80579 driver environment.mk file \
  12456. + "-> setenv ICP_ENV_DIR <path>")
  12457. +endif
  12458. +
  12459. +#Add your project environment Makefile
  12460. +include ${ICP_ENV_DIR}/environment.mk
  12461. +
  12462. +#include the makefile with all the default and common Make variable definitions
  12463. +include ${ICP_BUILDSYSTEM_PATH}/build_files/common.mk
  12464. +
  12465. +#Add the name for the executable, Library or Module output definitions
  12466. +OUTPUT_NAME= icp_ocf
  12467. +
  12468. +# List of Source Files to be compiled
  12469. +SOURCES= icp_common.c icp_sym.c icp_asym.c icp_ocf_linux.c
  12470. +
  12471. +#common includes between all supported OSes
  12472. +INCLUDES= -I ${ICP_API_DIR} -I${ICP_LAC_API} \
  12473. +-I${ICP_OCF_SRC_DIR}
  12474. +
  12475. +# The location of the os level makefile needs to be changed.
  12476. +include ${ICP_ENV_DIR}/${ICP_OS}_${ICP_OS_LEVEL}.mk
  12477. +
  12478. +# On the line directly below list the outputs you wish to build for,
  12479. +# e.g "lib_static lib_shared exe module" as shown below
  12480. +install: module
  12481. +
  12482. +###################Include rules makefiles########################
  12483. +include ${ICP_BUILDSYSTEM_PATH}/build_files/rules.mk
  12484. +###################End of Rules inclusion#########################
  12485. +
  12486. +endif
  12487. diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifn7751.c linux-2.6.36/crypto/ocf/hifn/hifn7751.c
  12488. --- linux-2.6.36.orig/crypto/ocf/hifn/hifn7751.c 1970-01-01 01:00:00.000000000 +0100
  12489. +++ linux-2.6.36/crypto/ocf/hifn/hifn7751.c 2010-11-09 20:28:04.752495537 +0100
  12490. @@ -0,0 +1,2976 @@
  12491. +/* $OpenBSD: hifn7751.c,v 1.120 2002/05/17 00:33:34 deraadt Exp $ */
  12492. +
  12493. +/*-
  12494. + * Invertex AEON / Hifn 7751 driver
  12495. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  12496. + * Copyright (c) 1999 Theo de Raadt
  12497. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  12498. + * http://www.netsec.net
  12499. + * Copyright (c) 2003 Hifn Inc.
  12500. + *
  12501. + * This driver is based on a previous driver by Invertex, for which they
  12502. + * requested: Please send any comments, feedback, bug-fixes, or feature
  12503. + * requests to software@invertex.com.
  12504. + *
  12505. + * Redistribution and use in source and binary forms, with or without
  12506. + * modification, are permitted provided that the following conditions
  12507. + * are met:
  12508. + *
  12509. + * 1. Redistributions of source code must retain the above copyright
  12510. + * notice, this list of conditions and the following disclaimer.
  12511. + * 2. Redistributions in binary form must reproduce the above copyright
  12512. + * notice, this list of conditions and the following disclaimer in the
  12513. + * documentation and/or other materials provided with the distribution.
  12514. + * 3. The name of the author may not be used to endorse or promote products
  12515. + * derived from this software without specific prior written permission.
  12516. + *
  12517. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  12518. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  12519. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  12520. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  12521. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  12522. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12523. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12524. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12525. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  12526. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12527. + *
  12528. + * Effort sponsored in part by the Defense Advanced Research Projects
  12529. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  12530. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  12531. + *
  12532. + *
  12533. +__FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam Exp $");
  12534. + */
  12535. +
  12536. +/*
  12537. + * Driver for various Hifn encryption processors.
  12538. + */
  12539. +#ifndef AUTOCONF_INCLUDED
  12540. +#include <linux/config.h>
  12541. +#endif
  12542. +#include <linux/module.h>
  12543. +#include <linux/init.h>
  12544. +#include <linux/list.h>
  12545. +#include <linux/slab.h>
  12546. +#include <linux/wait.h>
  12547. +#include <linux/sched.h>
  12548. +#include <linux/pci.h>
  12549. +#include <linux/delay.h>
  12550. +#include <linux/interrupt.h>
  12551. +#include <linux/spinlock.h>
  12552. +#include <linux/random.h>
  12553. +#include <linux/version.h>
  12554. +#include <linux/skbuff.h>
  12555. +#include <asm/io.h>
  12556. +
  12557. +#include <cryptodev.h>
  12558. +#include <uio.h>
  12559. +#include <hifn/hifn7751reg.h>
  12560. +#include <hifn/hifn7751var.h>
  12561. +
  12562. +#if 1
  12563. +#define DPRINTF(a...) if (hifn_debug) { \
  12564. + printk("%s: ", sc ? \
  12565. + device_get_nameunit(sc->sc_dev) : "hifn"); \
  12566. + printk(a); \
  12567. + } else
  12568. +#else
  12569. +#define DPRINTF(a...)
  12570. +#endif
  12571. +
  12572. +static inline int
  12573. +pci_get_revid(struct pci_dev *dev)
  12574. +{
  12575. + u8 rid = 0;
  12576. + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
  12577. + return rid;
  12578. +}
  12579. +
  12580. +static struct hifn_stats hifnstats;
  12581. +
  12582. +#define debug hifn_debug
  12583. +int hifn_debug = 0;
  12584. +module_param(hifn_debug, int, 0644);
  12585. +MODULE_PARM_DESC(hifn_debug, "Enable debug");
  12586. +
  12587. +int hifn_maxbatch = 1;
  12588. +module_param(hifn_maxbatch, int, 0644);
  12589. +MODULE_PARM_DESC(hifn_maxbatch, "max ops to batch w/o interrupt");
  12590. +
  12591. +int hifn_cache_linesize = 0x10;
  12592. +module_param(hifn_cache_linesize, int, 0444);
  12593. +MODULE_PARM_DESC(hifn_cache_linesize, "PCI config cache line size");
  12594. +
  12595. +#ifdef MODULE_PARM
  12596. +char *hifn_pllconfig = NULL;
  12597. +MODULE_PARM(hifn_pllconfig, "s");
  12598. +#else
  12599. +char hifn_pllconfig[32]; /* This setting is RO after loading */
  12600. +module_param_string(hifn_pllconfig, hifn_pllconfig, 32, 0444);
  12601. +#endif
  12602. +MODULE_PARM_DESC(hifn_pllconfig, "PLL config, ie., pci66, ext33, ...");
  12603. +
  12604. +#ifdef HIFN_VULCANDEV
  12605. +#include <sys/conf.h>
  12606. +#include <sys/uio.h>
  12607. +
  12608. +static struct cdevsw vulcanpk_cdevsw; /* forward declaration */
  12609. +#endif
  12610. +
  12611. +/*
  12612. + * Prototypes and count for the pci_device structure
  12613. + */
  12614. +static int hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent);
  12615. +static void hifn_remove(struct pci_dev *dev);
  12616. +
  12617. +static int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);
  12618. +static int hifn_freesession(device_t, u_int64_t);
  12619. +static int hifn_process(device_t, struct cryptop *, int);
  12620. +
  12621. +static device_method_t hifn_methods = {
  12622. + /* crypto device methods */
  12623. + DEVMETHOD(cryptodev_newsession, hifn_newsession),
  12624. + DEVMETHOD(cryptodev_freesession,hifn_freesession),
  12625. + DEVMETHOD(cryptodev_process, hifn_process),
  12626. +};
  12627. +
  12628. +static void hifn_reset_board(struct hifn_softc *, int);
  12629. +static void hifn_reset_puc(struct hifn_softc *);
  12630. +static void hifn_puc_wait(struct hifn_softc *);
  12631. +static int hifn_enable_crypto(struct hifn_softc *);
  12632. +static void hifn_set_retry(struct hifn_softc *sc);
  12633. +static void hifn_init_dma(struct hifn_softc *);
  12634. +static void hifn_init_pci_registers(struct hifn_softc *);
  12635. +static int hifn_sramsize(struct hifn_softc *);
  12636. +static int hifn_dramsize(struct hifn_softc *);
  12637. +static int hifn_ramtype(struct hifn_softc *);
  12638. +static void hifn_sessions(struct hifn_softc *);
  12639. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  12640. +static irqreturn_t hifn_intr(int irq, void *arg);
  12641. +#else
  12642. +static irqreturn_t hifn_intr(int irq, void *arg, struct pt_regs *regs);
  12643. +#endif
  12644. +static u_int hifn_write_command(struct hifn_command *, u_int8_t *);
  12645. +static u_int32_t hifn_next_signature(u_int32_t a, u_int cnt);
  12646. +static void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *);
  12647. +static int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int);
  12648. +static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);
  12649. +static int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *);
  12650. +static int hifn_dmamap_load_src(struct hifn_softc *, struct hifn_command *);
  12651. +static int hifn_dmamap_load_dst(struct hifn_softc *, struct hifn_command *);
  12652. +static int hifn_init_pubrng(struct hifn_softc *);
  12653. +static void hifn_tick(unsigned long arg);
  12654. +static void hifn_abort(struct hifn_softc *);
  12655. +static void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *);
  12656. +
  12657. +static void hifn_write_reg_0(struct hifn_softc *, bus_size_t, u_int32_t);
  12658. +static void hifn_write_reg_1(struct hifn_softc *, bus_size_t, u_int32_t);
  12659. +
  12660. +#ifdef CONFIG_OCF_RANDOMHARVEST
  12661. +static int hifn_read_random(void *arg, u_int32_t *buf, int len);
  12662. +#endif
  12663. +
  12664. +#define HIFN_MAX_CHIPS 8
  12665. +static struct hifn_softc *hifn_chip_idx[HIFN_MAX_CHIPS];
  12666. +
  12667. +static __inline u_int32_t
  12668. +READ_REG_0(struct hifn_softc *sc, bus_size_t reg)
  12669. +{
  12670. + u_int32_t v = readl(sc->sc_bar0 + reg);
  12671. + sc->sc_bar0_lastreg = (bus_size_t) -1;
  12672. + return (v);
  12673. +}
  12674. +#define WRITE_REG_0(sc, reg, val) hifn_write_reg_0(sc, reg, val)
  12675. +
  12676. +static __inline u_int32_t
  12677. +READ_REG_1(struct hifn_softc *sc, bus_size_t reg)
  12678. +{
  12679. + u_int32_t v = readl(sc->sc_bar1 + reg);
  12680. + sc->sc_bar1_lastreg = (bus_size_t) -1;
  12681. + return (v);
  12682. +}
  12683. +#define WRITE_REG_1(sc, reg, val) hifn_write_reg_1(sc, reg, val)
  12684. +
  12685. +/*
  12686. + * map in a given buffer (great on some arches :-)
  12687. + */
  12688. +
  12689. +static int
  12690. +pci_map_uio(struct hifn_softc *sc, struct hifn_operand *buf, struct uio *uio)
  12691. +{
  12692. + struct iovec *iov = uio->uio_iov;
  12693. +
  12694. + DPRINTF("%s()\n", __FUNCTION__);
  12695. +
  12696. + buf->mapsize = 0;
  12697. + for (buf->nsegs = 0; buf->nsegs < uio->uio_iovcnt; ) {
  12698. + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
  12699. + iov->iov_base, iov->iov_len,
  12700. + PCI_DMA_BIDIRECTIONAL);
  12701. + buf->segs[buf->nsegs].ds_len = iov->iov_len;
  12702. + buf->mapsize += iov->iov_len;
  12703. + iov++;
  12704. + buf->nsegs++;
  12705. + }
  12706. + /* identify this buffer by the first segment */
  12707. + buf->map = (void *) buf->segs[0].ds_addr;
  12708. + return(0);
  12709. +}
  12710. +
  12711. +/*
  12712. + * map in a given sk_buff
  12713. + */
  12714. +
  12715. +static int
  12716. +pci_map_skb(struct hifn_softc *sc,struct hifn_operand *buf,struct sk_buff *skb)
  12717. +{
  12718. + int i;
  12719. +
  12720. + DPRINTF("%s()\n", __FUNCTION__);
  12721. +
  12722. + buf->mapsize = 0;
  12723. +
  12724. + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
  12725. + skb->data, skb_headlen(skb), PCI_DMA_BIDIRECTIONAL);
  12726. + buf->segs[0].ds_len = skb_headlen(skb);
  12727. + buf->mapsize += buf->segs[0].ds_len;
  12728. +
  12729. + buf->nsegs = 1;
  12730. +
  12731. + for (i = 0; i < skb_shinfo(skb)->nr_frags; ) {
  12732. + buf->segs[buf->nsegs].ds_len = skb_shinfo(skb)->frags[i].size;
  12733. + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
  12734. + page_address(skb_shinfo(skb)->frags[i].page) +
  12735. + skb_shinfo(skb)->frags[i].page_offset,
  12736. + buf->segs[buf->nsegs].ds_len, PCI_DMA_BIDIRECTIONAL);
  12737. + buf->mapsize += buf->segs[buf->nsegs].ds_len;
  12738. + buf->nsegs++;
  12739. + }
  12740. +
  12741. + /* identify this buffer by the first segment */
  12742. + buf->map = (void *) buf->segs[0].ds_addr;
  12743. + return(0);
  12744. +}
  12745. +
  12746. +/*
  12747. + * map in a given contiguous buffer
  12748. + */
  12749. +
  12750. +static int
  12751. +pci_map_buf(struct hifn_softc *sc,struct hifn_operand *buf, void *b, int len)
  12752. +{
  12753. + DPRINTF("%s()\n", __FUNCTION__);
  12754. +
  12755. + buf->mapsize = 0;
  12756. + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
  12757. + b, len, PCI_DMA_BIDIRECTIONAL);
  12758. + buf->segs[0].ds_len = len;
  12759. + buf->mapsize += buf->segs[0].ds_len;
  12760. + buf->nsegs = 1;
  12761. +
  12762. + /* identify this buffer by the first segment */
  12763. + buf->map = (void *) buf->segs[0].ds_addr;
  12764. + return(0);
  12765. +}
  12766. +
  12767. +#if 0 /* not needed at this time */
  12768. +static void
  12769. +pci_sync_iov(struct hifn_softc *sc, struct hifn_operand *buf)
  12770. +{
  12771. + int i;
  12772. +
  12773. + DPRINTF("%s()\n", __FUNCTION__);
  12774. + for (i = 0; i < buf->nsegs; i++)
  12775. + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
  12776. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  12777. +}
  12778. +#endif
  12779. +
  12780. +static void
  12781. +pci_unmap_buf(struct hifn_softc *sc, struct hifn_operand *buf)
  12782. +{
  12783. + int i;
  12784. + DPRINTF("%s()\n", __FUNCTION__);
  12785. + for (i = 0; i < buf->nsegs; i++) {
  12786. + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
  12787. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  12788. + buf->segs[i].ds_addr = 0;
  12789. + buf->segs[i].ds_len = 0;
  12790. + }
  12791. + buf->nsegs = 0;
  12792. + buf->mapsize = 0;
  12793. + buf->map = 0;
  12794. +}
  12795. +
  12796. +static const char*
  12797. +hifn_partname(struct hifn_softc *sc)
  12798. +{
  12799. + /* XXX sprintf numbers when not decoded */
  12800. + switch (pci_get_vendor(sc->sc_pcidev)) {
  12801. + case PCI_VENDOR_HIFN:
  12802. + switch (pci_get_device(sc->sc_pcidev)) {
  12803. + case PCI_PRODUCT_HIFN_6500: return "Hifn 6500";
  12804. + case PCI_PRODUCT_HIFN_7751: return "Hifn 7751";
  12805. + case PCI_PRODUCT_HIFN_7811: return "Hifn 7811";
  12806. + case PCI_PRODUCT_HIFN_7951: return "Hifn 7951";
  12807. + case PCI_PRODUCT_HIFN_7955: return "Hifn 7955";
  12808. + case PCI_PRODUCT_HIFN_7956: return "Hifn 7956";
  12809. + }
  12810. + return "Hifn unknown-part";
  12811. + case PCI_VENDOR_INVERTEX:
  12812. + switch (pci_get_device(sc->sc_pcidev)) {
  12813. + case PCI_PRODUCT_INVERTEX_AEON: return "Invertex AEON";
  12814. + }
  12815. + return "Invertex unknown-part";
  12816. + case PCI_VENDOR_NETSEC:
  12817. + switch (pci_get_device(sc->sc_pcidev)) {
  12818. + case PCI_PRODUCT_NETSEC_7751: return "NetSec 7751";
  12819. + }
  12820. + return "NetSec unknown-part";
  12821. + }
  12822. + return "Unknown-vendor unknown-part";
  12823. +}
  12824. +
  12825. +static u_int
  12826. +checkmaxmin(struct pci_dev *dev, const char *what, u_int v, u_int min, u_int max)
  12827. +{
  12828. + struct hifn_softc *sc = pci_get_drvdata(dev);
  12829. + if (v > max) {
  12830. + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
  12831. + "using max %u\n", what, v, max);
  12832. + v = max;
  12833. + } else if (v < min) {
  12834. + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
  12835. + "using min %u\n", what, v, min);
  12836. + v = min;
  12837. + }
  12838. + return v;
  12839. +}
  12840. +
  12841. +/*
  12842. + * Select PLL configuration for 795x parts. This is complicated in
  12843. + * that we cannot determine the optimal parameters without user input.
  12844. + * The reference clock is derived from an external clock through a
  12845. + * multiplier. The external clock is either the host bus (i.e. PCI)
  12846. + * or an external clock generator. When using the PCI bus we assume
  12847. + * the clock is either 33 or 66 MHz; for an external source we cannot
  12848. + * tell the speed.
  12849. + *
  12850. + * PLL configuration is done with a string: "pci" for PCI bus, or "ext"
  12851. + * for an external source, followed by the frequency. We calculate
  12852. + * the appropriate multiplier and PLL register contents accordingly.
  12853. + * When no configuration is given we default to "pci66" since that
  12854. + * always will allow the card to work. If a card is using the PCI
  12855. + * bus clock and in a 33MHz slot then it will be operating at half
  12856. + * speed until the correct information is provided.
  12857. + *
  12858. + * We use a default setting of "ext66" because according to Mike Ham
  12859. + * of HiFn, almost every board in existence has an external crystal
  12860. + * populated at 66Mhz. Using PCI can be a problem on modern motherboards,
  12861. + * because PCI33 can have clocks from 0 to 33Mhz, and some have
  12862. + * non-PCI-compliant spread-spectrum clocks, which can confuse the pll.
  12863. + */
  12864. +static void
  12865. +hifn_getpllconfig(struct pci_dev *dev, u_int *pll)
  12866. +{
  12867. + const char *pllspec = hifn_pllconfig;
  12868. + u_int freq, mul, fl, fh;
  12869. + u_int32_t pllconfig;
  12870. + char *nxt;
  12871. +
  12872. + if (pllspec == NULL)
  12873. + pllspec = "ext66";
  12874. + fl = 33, fh = 66;
  12875. + pllconfig = 0;
  12876. + if (strncmp(pllspec, "ext", 3) == 0) {
  12877. + pllspec += 3;
  12878. + pllconfig |= HIFN_PLL_REF_SEL;
  12879. + switch (pci_get_device(dev)) {
  12880. + case PCI_PRODUCT_HIFN_7955:
  12881. + case PCI_PRODUCT_HIFN_7956:
  12882. + fl = 20, fh = 100;
  12883. + break;
  12884. +#ifdef notyet
  12885. + case PCI_PRODUCT_HIFN_7954:
  12886. + fl = 20, fh = 66;
  12887. + break;
  12888. +#endif
  12889. + }
  12890. + } else if (strncmp(pllspec, "pci", 3) == 0)
  12891. + pllspec += 3;
  12892. + freq = strtoul(pllspec, &nxt, 10);
  12893. + if (nxt == pllspec)
  12894. + freq = 66;
  12895. + else
  12896. + freq = checkmaxmin(dev, "frequency", freq, fl, fh);
  12897. + /*
  12898. + * Calculate multiplier. We target a Fck of 266 MHz,
  12899. + * allowing only even values, possibly rounded down.
  12900. + * Multipliers > 8 must set the charge pump current.
  12901. + */
  12902. + mul = checkmaxmin(dev, "PLL divisor", (266 / freq) &~ 1, 2, 12);
  12903. + pllconfig |= (mul / 2 - 1) << HIFN_PLL_ND_SHIFT;
  12904. + if (mul > 8)
  12905. + pllconfig |= HIFN_PLL_IS;
  12906. + *pll = pllconfig;
  12907. +}
  12908. +
  12909. +/*
  12910. + * Attach an interface that successfully probed.
  12911. + */
  12912. +static int
  12913. +hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  12914. +{
  12915. + struct hifn_softc *sc = NULL;
  12916. + char rbase;
  12917. + u_int16_t ena, rev;
  12918. + int rseg, rc;
  12919. + unsigned long mem_start, mem_len;
  12920. + static int num_chips = 0;
  12921. +
  12922. + DPRINTF("%s()\n", __FUNCTION__);
  12923. +
  12924. + if (pci_enable_device(dev) < 0)
  12925. + return(-ENODEV);
  12926. +
  12927. + if (pci_set_mwi(dev))
  12928. + return(-ENODEV);
  12929. +
  12930. + if (!dev->irq) {
  12931. + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
  12932. + pci_disable_device(dev);
  12933. + return(-ENODEV);
  12934. + }
  12935. +
  12936. + sc = (struct hifn_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  12937. + if (!sc)
  12938. + return(-ENOMEM);
  12939. + memset(sc, 0, sizeof(*sc));
  12940. +
  12941. + softc_device_init(sc, "hifn", num_chips, hifn_methods);
  12942. +
  12943. + sc->sc_pcidev = dev;
  12944. + sc->sc_irq = -1;
  12945. + sc->sc_cid = -1;
  12946. + sc->sc_num = num_chips++;
  12947. + if (sc->sc_num < HIFN_MAX_CHIPS)
  12948. + hifn_chip_idx[sc->sc_num] = sc;
  12949. +
  12950. + pci_set_drvdata(sc->sc_pcidev, sc);
  12951. +
  12952. + spin_lock_init(&sc->sc_mtx);
  12953. +
  12954. + /* XXX handle power management */
  12955. +
  12956. + /*
  12957. + * The 7951 and 795x have a random number generator and
  12958. + * public key support; note this.
  12959. + */
  12960. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  12961. + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7951 ||
  12962. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
  12963. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956))
  12964. + sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC;
  12965. + /*
  12966. + * The 7811 has a random number generator and
  12967. + * we also note it's identity 'cuz of some quirks.
  12968. + */
  12969. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  12970. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7811)
  12971. + sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG;
  12972. +
  12973. + /*
  12974. + * The 795x parts support AES.
  12975. + */
  12976. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  12977. + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
  12978. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956)) {
  12979. + sc->sc_flags |= HIFN_IS_7956 | HIFN_HAS_AES;
  12980. + /*
  12981. + * Select PLL configuration. This depends on the
  12982. + * bus and board design and must be manually configured
  12983. + * if the default setting is unacceptable.
  12984. + */
  12985. + hifn_getpllconfig(dev, &sc->sc_pllconfig);
  12986. + }
  12987. +
  12988. + /*
  12989. + * Setup PCI resources. Note that we record the bus
  12990. + * tag and handle for each register mapping, this is
  12991. + * used by the READ_REG_0, WRITE_REG_0, READ_REG_1,
  12992. + * and WRITE_REG_1 macros throughout the driver.
  12993. + */
  12994. + mem_start = pci_resource_start(sc->sc_pcidev, 0);
  12995. + mem_len = pci_resource_len(sc->sc_pcidev, 0);
  12996. + sc->sc_bar0 = (ocf_iomem_t) ioremap(mem_start, mem_len);
  12997. + if (!sc->sc_bar0) {
  12998. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 0);
  12999. + goto fail;
  13000. + }
  13001. + sc->sc_bar0_lastreg = (bus_size_t) -1;
  13002. +
  13003. + mem_start = pci_resource_start(sc->sc_pcidev, 1);
  13004. + mem_len = pci_resource_len(sc->sc_pcidev, 1);
  13005. + sc->sc_bar1 = (ocf_iomem_t) ioremap(mem_start, mem_len);
  13006. + if (!sc->sc_bar1) {
  13007. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 1);
  13008. + goto fail;
  13009. + }
  13010. + sc->sc_bar1_lastreg = (bus_size_t) -1;
  13011. +
  13012. + /* fix up the bus size */
  13013. + if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
  13014. + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
  13015. + goto fail;
  13016. + }
  13017. + if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
  13018. + device_printf(sc->sc_dev,
  13019. + "No usable consistent DMA configuration, aborting.\n");
  13020. + goto fail;
  13021. + }
  13022. +
  13023. + hifn_set_retry(sc);
  13024. +
  13025. + /*
  13026. + * Setup the area where the Hifn DMA's descriptors
  13027. + * and associated data structures.
  13028. + */
  13029. + sc->sc_dma = (struct hifn_dma *) pci_alloc_consistent(dev,
  13030. + sizeof(*sc->sc_dma),
  13031. + &sc->sc_dma_physaddr);
  13032. + if (!sc->sc_dma) {
  13033. + device_printf(sc->sc_dev, "cannot alloc sc_dma\n");
  13034. + goto fail;
  13035. + }
  13036. + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
  13037. +
  13038. + /*
  13039. + * Reset the board and do the ``secret handshake''
  13040. + * to enable the crypto support. Then complete the
  13041. + * initialization procedure by setting up the interrupt
  13042. + * and hooking in to the system crypto support so we'll
  13043. + * get used for system services like the crypto device,
  13044. + * IPsec, RNG device, etc.
  13045. + */
  13046. + hifn_reset_board(sc, 0);
  13047. +
  13048. + if (hifn_enable_crypto(sc) != 0) {
  13049. + device_printf(sc->sc_dev, "crypto enabling failed\n");
  13050. + goto fail;
  13051. + }
  13052. + hifn_reset_puc(sc);
  13053. +
  13054. + hifn_init_dma(sc);
  13055. + hifn_init_pci_registers(sc);
  13056. +
  13057. + pci_set_master(sc->sc_pcidev);
  13058. +
  13059. + /* XXX can't dynamically determine ram type for 795x; force dram */
  13060. + if (sc->sc_flags & HIFN_IS_7956)
  13061. + sc->sc_drammodel = 1;
  13062. + else if (hifn_ramtype(sc))
  13063. + goto fail;
  13064. +
  13065. + if (sc->sc_drammodel == 0)
  13066. + hifn_sramsize(sc);
  13067. + else
  13068. + hifn_dramsize(sc);
  13069. +
  13070. + /*
  13071. + * Workaround for NetSec 7751 rev A: half ram size because two
  13072. + * of the address lines were left floating
  13073. + */
  13074. + if (pci_get_vendor(dev) == PCI_VENDOR_NETSEC &&
  13075. + pci_get_device(dev) == PCI_PRODUCT_NETSEC_7751 &&
  13076. + pci_get_revid(dev) == 0x61) /*XXX???*/
  13077. + sc->sc_ramsize >>= 1;
  13078. +
  13079. + /*
  13080. + * Arrange the interrupt line.
  13081. + */
  13082. + rc = request_irq(dev->irq, hifn_intr, IRQF_SHARED, "hifn", sc);
  13083. + if (rc) {
  13084. + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
  13085. + goto fail;
  13086. + }
  13087. + sc->sc_irq = dev->irq;
  13088. +
  13089. + hifn_sessions(sc);
  13090. +
  13091. + /*
  13092. + * NB: Keep only the low 16 bits; this masks the chip id
  13093. + * from the 7951.
  13094. + */
  13095. + rev = READ_REG_1(sc, HIFN_1_REVID) & 0xffff;
  13096. +
  13097. + rseg = sc->sc_ramsize / 1024;
  13098. + rbase = 'K';
  13099. + if (sc->sc_ramsize >= (1024 * 1024)) {
  13100. + rbase = 'M';
  13101. + rseg /= 1024;
  13102. + }
  13103. + device_printf(sc->sc_dev, "%s, rev %u, %d%cB %cram",
  13104. + hifn_partname(sc), rev,
  13105. + rseg, rbase, sc->sc_drammodel ? 'd' : 's');
  13106. + if (sc->sc_flags & HIFN_IS_7956)
  13107. + printf(", pll=0x%x<%s clk, %ux mult>",
  13108. + sc->sc_pllconfig,
  13109. + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
  13110. + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
  13111. + printf("\n");
  13112. +
  13113. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  13114. + if (sc->sc_cid < 0) {
  13115. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  13116. + goto fail;
  13117. + }
  13118. +
  13119. + WRITE_REG_0(sc, HIFN_0_PUCNFG,
  13120. + READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID);
  13121. + ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  13122. +
  13123. + switch (ena) {
  13124. + case HIFN_PUSTAT_ENA_2:
  13125. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  13126. + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
  13127. + if (sc->sc_flags & HIFN_HAS_AES)
  13128. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  13129. + /*FALLTHROUGH*/
  13130. + case HIFN_PUSTAT_ENA_1:
  13131. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  13132. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  13133. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  13134. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  13135. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  13136. + break;
  13137. + }
  13138. +
  13139. + if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG))
  13140. + hifn_init_pubrng(sc);
  13141. +
  13142. + init_timer(&sc->sc_tickto);
  13143. + sc->sc_tickto.function = hifn_tick;
  13144. + sc->sc_tickto.data = (unsigned long) sc->sc_num;
  13145. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  13146. +
  13147. + return (0);
  13148. +
  13149. +fail:
  13150. + if (sc->sc_cid >= 0)
  13151. + crypto_unregister_all(sc->sc_cid);
  13152. + if (sc->sc_irq != -1)
  13153. + free_irq(sc->sc_irq, sc);
  13154. + if (sc->sc_dma) {
  13155. + /* Turn off DMA polling */
  13156. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  13157. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  13158. +
  13159. + pci_free_consistent(sc->sc_pcidev,
  13160. + sizeof(*sc->sc_dma),
  13161. + sc->sc_dma, sc->sc_dma_physaddr);
  13162. + }
  13163. + kfree(sc);
  13164. + return (-ENXIO);
  13165. +}
  13166. +
  13167. +/*
  13168. + * Detach an interface that successfully probed.
  13169. + */
  13170. +static void
  13171. +hifn_remove(struct pci_dev *dev)
  13172. +{
  13173. + struct hifn_softc *sc = pci_get_drvdata(dev);
  13174. + unsigned long l_flags;
  13175. +
  13176. + DPRINTF("%s()\n", __FUNCTION__);
  13177. +
  13178. + KASSERT(sc != NULL, ("hifn_detach: null software carrier!"));
  13179. +
  13180. + /* disable interrupts */
  13181. + HIFN_LOCK(sc);
  13182. + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
  13183. + HIFN_UNLOCK(sc);
  13184. +
  13185. + /*XXX other resources */
  13186. + del_timer_sync(&sc->sc_tickto);
  13187. +
  13188. + /* Turn off DMA polling */
  13189. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  13190. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  13191. +
  13192. + crypto_unregister_all(sc->sc_cid);
  13193. +
  13194. + free_irq(sc->sc_irq, sc);
  13195. +
  13196. + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
  13197. + sc->sc_dma, sc->sc_dma_physaddr);
  13198. +}
  13199. +
  13200. +
  13201. +static int
  13202. +hifn_init_pubrng(struct hifn_softc *sc)
  13203. +{
  13204. + int i;
  13205. +
  13206. + DPRINTF("%s()\n", __FUNCTION__);
  13207. +
  13208. + if ((sc->sc_flags & HIFN_IS_7811) == 0) {
  13209. + /* Reset 7951 public key/rng engine */
  13210. + WRITE_REG_1(sc, HIFN_1_PUB_RESET,
  13211. + READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET);
  13212. +
  13213. + for (i = 0; i < 100; i++) {
  13214. + DELAY(1000);
  13215. + if ((READ_REG_1(sc, HIFN_1_PUB_RESET) &
  13216. + HIFN_PUBRST_RESET) == 0)
  13217. + break;
  13218. + }
  13219. +
  13220. + if (i == 100) {
  13221. + device_printf(sc->sc_dev, "public key init failed\n");
  13222. + return (1);
  13223. + }
  13224. + }
  13225. +
  13226. + /* Enable the rng, if available */
  13227. +#ifdef CONFIG_OCF_RANDOMHARVEST
  13228. + if (sc->sc_flags & HIFN_HAS_RNG) {
  13229. + if (sc->sc_flags & HIFN_IS_7811) {
  13230. + u_int32_t r;
  13231. + r = READ_REG_1(sc, HIFN_1_7811_RNGENA);
  13232. + if (r & HIFN_7811_RNGENA_ENA) {
  13233. + r &= ~HIFN_7811_RNGENA_ENA;
  13234. + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
  13235. + }
  13236. + WRITE_REG_1(sc, HIFN_1_7811_RNGCFG,
  13237. + HIFN_7811_RNGCFG_DEFL);
  13238. + r |= HIFN_7811_RNGENA_ENA;
  13239. + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
  13240. + } else
  13241. + WRITE_REG_1(sc, HIFN_1_RNG_CONFIG,
  13242. + READ_REG_1(sc, HIFN_1_RNG_CONFIG) |
  13243. + HIFN_RNGCFG_ENA);
  13244. +
  13245. + sc->sc_rngfirst = 1;
  13246. + crypto_rregister(sc->sc_cid, hifn_read_random, sc);
  13247. + }
  13248. +#endif
  13249. +
  13250. + /* Enable public key engine, if available */
  13251. + if (sc->sc_flags & HIFN_HAS_PUBLIC) {
  13252. + WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE);
  13253. + sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;
  13254. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  13255. +#ifdef HIFN_VULCANDEV
  13256. + sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0,
  13257. + UID_ROOT, GID_WHEEL, 0666,
  13258. + "vulcanpk");
  13259. + sc->sc_pkdev->si_drv1 = sc;
  13260. +#endif
  13261. + }
  13262. +
  13263. + return (0);
  13264. +}
  13265. +
  13266. +#ifdef CONFIG_OCF_RANDOMHARVEST
  13267. +static int
  13268. +hifn_read_random(void *arg, u_int32_t *buf, int len)
  13269. +{
  13270. + struct hifn_softc *sc = (struct hifn_softc *) arg;
  13271. + u_int32_t sts;
  13272. + int i, rc = 0;
  13273. +
  13274. + if (len <= 0)
  13275. + return rc;
  13276. +
  13277. + if (sc->sc_flags & HIFN_IS_7811) {
  13278. + /* ONLY VALID ON 7811!!!! */
  13279. + for (i = 0; i < 5; i++) {
  13280. + sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS);
  13281. + if (sts & HIFN_7811_RNGSTS_UFL) {
  13282. + device_printf(sc->sc_dev,
  13283. + "RNG underflow: disabling\n");
  13284. + /* DAVIDM perhaps return -1 */
  13285. + break;
  13286. + }
  13287. + if ((sts & HIFN_7811_RNGSTS_RDY) == 0)
  13288. + break;
  13289. +
  13290. + /*
  13291. + * There are at least two words in the RNG FIFO
  13292. + * at this point.
  13293. + */
  13294. + if (rc < len)
  13295. + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
  13296. + if (rc < len)
  13297. + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
  13298. + }
  13299. + } else
  13300. + buf[rc++] = READ_REG_1(sc, HIFN_1_RNG_DATA);
  13301. +
  13302. + /* NB: discard first data read */
  13303. + if (sc->sc_rngfirst) {
  13304. + sc->sc_rngfirst = 0;
  13305. + rc = 0;
  13306. + }
  13307. +
  13308. + return(rc);
  13309. +}
  13310. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  13311. +
  13312. +static void
  13313. +hifn_puc_wait(struct hifn_softc *sc)
  13314. +{
  13315. + int i;
  13316. + int reg = HIFN_0_PUCTRL;
  13317. +
  13318. + if (sc->sc_flags & HIFN_IS_7956) {
  13319. + reg = HIFN_0_PUCTRL2;
  13320. + }
  13321. +
  13322. + for (i = 5000; i > 0; i--) {
  13323. + DELAY(1);
  13324. + if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET))
  13325. + break;
  13326. + }
  13327. + if (!i)
  13328. + device_printf(sc->sc_dev, "proc unit did not reset(0x%x)\n",
  13329. + READ_REG_0(sc, HIFN_0_PUCTRL));
  13330. +}
  13331. +
  13332. +/*
  13333. + * Reset the processing unit.
  13334. + */
  13335. +static void
  13336. +hifn_reset_puc(struct hifn_softc *sc)
  13337. +{
  13338. + /* Reset processing unit */
  13339. + int reg = HIFN_0_PUCTRL;
  13340. +
  13341. + if (sc->sc_flags & HIFN_IS_7956) {
  13342. + reg = HIFN_0_PUCTRL2;
  13343. + }
  13344. + WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA);
  13345. +
  13346. + hifn_puc_wait(sc);
  13347. +}
  13348. +
  13349. +/*
  13350. + * Set the Retry and TRDY registers; note that we set them to
  13351. + * zero because the 7811 locks up when forced to retry (section
  13352. + * 3.6 of "Specification Update SU-0014-04". Not clear if we
  13353. + * should do this for all Hifn parts, but it doesn't seem to hurt.
  13354. + */
  13355. +static void
  13356. +hifn_set_retry(struct hifn_softc *sc)
  13357. +{
  13358. + DPRINTF("%s()\n", __FUNCTION__);
  13359. + /* NB: RETRY only responds to 8-bit reads/writes */
  13360. + pci_write_config_byte(sc->sc_pcidev, HIFN_RETRY_TIMEOUT, 0);
  13361. + pci_write_config_dword(sc->sc_pcidev, HIFN_TRDY_TIMEOUT, 0);
  13362. + /* piggy back the cache line setting here */
  13363. + pci_write_config_byte(sc->sc_pcidev, PCI_CACHE_LINE_SIZE, hifn_cache_linesize);
  13364. +}
  13365. +
  13366. +/*
  13367. + * Resets the board. Values in the regesters are left as is
  13368. + * from the reset (i.e. initial values are assigned elsewhere).
  13369. + */
  13370. +static void
  13371. +hifn_reset_board(struct hifn_softc *sc, int full)
  13372. +{
  13373. + u_int32_t reg;
  13374. +
  13375. + DPRINTF("%s()\n", __FUNCTION__);
  13376. + /*
  13377. + * Set polling in the DMA configuration register to zero. 0x7 avoids
  13378. + * resetting the board and zeros out the other fields.
  13379. + */
  13380. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  13381. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  13382. +
  13383. + /*
  13384. + * Now that polling has been disabled, we have to wait 1 ms
  13385. + * before resetting the board.
  13386. + */
  13387. + DELAY(1000);
  13388. +
  13389. + /* Reset the DMA unit */
  13390. + if (full) {
  13391. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MODE);
  13392. + DELAY(1000);
  13393. + } else {
  13394. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG,
  13395. + HIFN_DMACNFG_MODE | HIFN_DMACNFG_MSTRESET);
  13396. + hifn_reset_puc(sc);
  13397. + }
  13398. +
  13399. + KASSERT(sc->sc_dma != NULL, ("hifn_reset_board: null DMA tag!"));
  13400. + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
  13401. +
  13402. + /* Bring dma unit out of reset */
  13403. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  13404. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  13405. +
  13406. + hifn_puc_wait(sc);
  13407. + hifn_set_retry(sc);
  13408. +
  13409. + if (sc->sc_flags & HIFN_IS_7811) {
  13410. + for (reg = 0; reg < 1000; reg++) {
  13411. + if (READ_REG_1(sc, HIFN_1_7811_MIPSRST) &
  13412. + HIFN_MIPSRST_CRAMINIT)
  13413. + break;
  13414. + DELAY(1000);
  13415. + }
  13416. + if (reg == 1000)
  13417. + device_printf(sc->sc_dev, ": cram init timeout\n");
  13418. + } else {
  13419. + /* set up DMA configuration register #2 */
  13420. + /* turn off all PK and BAR0 swaps */
  13421. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG2,
  13422. + (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)|
  13423. + (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)|
  13424. + (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)|
  13425. + (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT));
  13426. + }
  13427. +}
  13428. +
  13429. +static u_int32_t
  13430. +hifn_next_signature(u_int32_t a, u_int cnt)
  13431. +{
  13432. + int i;
  13433. + u_int32_t v;
  13434. +
  13435. + for (i = 0; i < cnt; i++) {
  13436. +
  13437. + /* get the parity */
  13438. + v = a & 0x80080125;
  13439. + v ^= v >> 16;
  13440. + v ^= v >> 8;
  13441. + v ^= v >> 4;
  13442. + v ^= v >> 2;
  13443. + v ^= v >> 1;
  13444. +
  13445. + a = (v & 1) ^ (a << 1);
  13446. + }
  13447. +
  13448. + return a;
  13449. +}
  13450. +
  13451. +
  13452. +/*
  13453. + * Checks to see if crypto is already enabled. If crypto isn't enable,
  13454. + * "hifn_enable_crypto" is called to enable it. The check is important,
  13455. + * as enabling crypto twice will lock the board.
  13456. + */
  13457. +static int
  13458. +hifn_enable_crypto(struct hifn_softc *sc)
  13459. +{
  13460. + u_int32_t dmacfg, ramcfg, encl, addr, i;
  13461. + char offtbl[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  13462. + 0x00, 0x00, 0x00, 0x00 };
  13463. +
  13464. + DPRINTF("%s()\n", __FUNCTION__);
  13465. +
  13466. + ramcfg = READ_REG_0(sc, HIFN_0_PUCNFG);
  13467. + dmacfg = READ_REG_1(sc, HIFN_1_DMA_CNFG);
  13468. +
  13469. + /*
  13470. + * The RAM config register's encrypt level bit needs to be set before
  13471. + * every read performed on the encryption level register.
  13472. + */
  13473. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
  13474. +
  13475. + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  13476. +
  13477. + /*
  13478. + * Make sure we don't re-unlock. Two unlocks kills chip until the
  13479. + * next reboot.
  13480. + */
  13481. + if (encl == HIFN_PUSTAT_ENA_1 || encl == HIFN_PUSTAT_ENA_2) {
  13482. +#ifdef HIFN_DEBUG
  13483. + if (hifn_debug)
  13484. + device_printf(sc->sc_dev,
  13485. + "Strong crypto already enabled!\n");
  13486. +#endif
  13487. + goto report;
  13488. + }
  13489. +
  13490. + if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) {
  13491. +#ifdef HIFN_DEBUG
  13492. + if (hifn_debug)
  13493. + device_printf(sc->sc_dev,
  13494. + "Unknown encryption level 0x%x\n", encl);
  13495. +#endif
  13496. + return 1;
  13497. + }
  13498. +
  13499. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_UNLOCK |
  13500. + HIFN_DMACNFG_MSTRESET | HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  13501. + DELAY(1000);
  13502. + addr = READ_REG_1(sc, HIFN_UNLOCK_SECRET1);
  13503. + DELAY(1000);
  13504. + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, 0);
  13505. + DELAY(1000);
  13506. +
  13507. + for (i = 0; i <= 12; i++) {
  13508. + addr = hifn_next_signature(addr, offtbl[i] + 0x101);
  13509. + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, addr);
  13510. +
  13511. + DELAY(1000);
  13512. + }
  13513. +
  13514. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
  13515. + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  13516. +
  13517. +#ifdef HIFN_DEBUG
  13518. + if (hifn_debug) {
  13519. + if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2)
  13520. + device_printf(sc->sc_dev, "Engine is permanently "
  13521. + "locked until next system reset!\n");
  13522. + else
  13523. + device_printf(sc->sc_dev, "Engine enabled "
  13524. + "successfully!\n");
  13525. + }
  13526. +#endif
  13527. +
  13528. +report:
  13529. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg);
  13530. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg);
  13531. +
  13532. + switch (encl) {
  13533. + case HIFN_PUSTAT_ENA_1:
  13534. + case HIFN_PUSTAT_ENA_2:
  13535. + break;
  13536. + case HIFN_PUSTAT_ENA_0:
  13537. + default:
  13538. + device_printf(sc->sc_dev, "disabled\n");
  13539. + break;
  13540. + }
  13541. +
  13542. + return 0;
  13543. +}
  13544. +
  13545. +/*
  13546. + * Give initial values to the registers listed in the "Register Space"
  13547. + * section of the HIFN Software Development reference manual.
  13548. + */
  13549. +static void
  13550. +hifn_init_pci_registers(struct hifn_softc *sc)
  13551. +{
  13552. + DPRINTF("%s()\n", __FUNCTION__);
  13553. +
  13554. + /* write fixed values needed by the Initialization registers */
  13555. + WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);
  13556. + WRITE_REG_0(sc, HIFN_0_FIFOCNFG, HIFN_FIFOCNFG_THRESHOLD);
  13557. + WRITE_REG_0(sc, HIFN_0_PUIER, HIFN_PUIER_DSTOVER);
  13558. +
  13559. + /* write all 4 ring address registers */
  13560. + WRITE_REG_1(sc, HIFN_1_DMA_CRAR, sc->sc_dma_physaddr +
  13561. + offsetof(struct hifn_dma, cmdr[0]));
  13562. + WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dma_physaddr +
  13563. + offsetof(struct hifn_dma, srcr[0]));
  13564. + WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dma_physaddr +
  13565. + offsetof(struct hifn_dma, dstr[0]));
  13566. + WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dma_physaddr +
  13567. + offsetof(struct hifn_dma, resr[0]));
  13568. +
  13569. + DELAY(2000);
  13570. +
  13571. + /* write status register */
  13572. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  13573. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS |
  13574. + HIFN_DMACSR_S_CTRL_DIS | HIFN_DMACSR_C_CTRL_DIS |
  13575. + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_D_DONE | HIFN_DMACSR_D_LAST |
  13576. + HIFN_DMACSR_D_WAIT | HIFN_DMACSR_D_OVER |
  13577. + HIFN_DMACSR_R_ABORT | HIFN_DMACSR_R_DONE | HIFN_DMACSR_R_LAST |
  13578. + HIFN_DMACSR_R_WAIT | HIFN_DMACSR_R_OVER |
  13579. + HIFN_DMACSR_S_ABORT | HIFN_DMACSR_S_DONE | HIFN_DMACSR_S_LAST |
  13580. + HIFN_DMACSR_S_WAIT |
  13581. + HIFN_DMACSR_C_ABORT | HIFN_DMACSR_C_DONE | HIFN_DMACSR_C_LAST |
  13582. + HIFN_DMACSR_C_WAIT |
  13583. + HIFN_DMACSR_ENGINE |
  13584. + ((sc->sc_flags & HIFN_HAS_PUBLIC) ?
  13585. + HIFN_DMACSR_PUBDONE : 0) |
  13586. + ((sc->sc_flags & HIFN_IS_7811) ?
  13587. + HIFN_DMACSR_ILLW | HIFN_DMACSR_ILLR : 0));
  13588. +
  13589. + sc->sc_d_busy = sc->sc_r_busy = sc->sc_s_busy = sc->sc_c_busy = 0;
  13590. + sc->sc_dmaier |= HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_ABORT |
  13591. + HIFN_DMAIER_D_OVER | HIFN_DMAIER_R_OVER |
  13592. + HIFN_DMAIER_S_ABORT | HIFN_DMAIER_D_ABORT | HIFN_DMAIER_R_ABORT |
  13593. + ((sc->sc_flags & HIFN_IS_7811) ?
  13594. + HIFN_DMAIER_ILLW | HIFN_DMAIER_ILLR : 0);
  13595. + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
  13596. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  13597. +
  13598. +
  13599. + if (sc->sc_flags & HIFN_IS_7956) {
  13600. + u_int32_t pll;
  13601. +
  13602. + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
  13603. + HIFN_PUCNFG_TCALLPHASES |
  13604. + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32);
  13605. +
  13606. + /* turn off the clocks and insure bypass is set */
  13607. + pll = READ_REG_1(sc, HIFN_1_PLL);
  13608. + pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL))
  13609. + | HIFN_PLL_BP | HIFN_PLL_MBSET;
  13610. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  13611. + DELAY(10*1000); /* 10ms */
  13612. +
  13613. + /* change configuration */
  13614. + pll = (pll &~ HIFN_PLL_CONFIG) | sc->sc_pllconfig;
  13615. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  13616. + DELAY(10*1000); /* 10ms */
  13617. +
  13618. + /* disable bypass */
  13619. + pll &= ~HIFN_PLL_BP;
  13620. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  13621. + /* enable clocks with new configuration */
  13622. + pll |= HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL;
  13623. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  13624. + } else {
  13625. + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
  13626. + HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES |
  13627. + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 |
  13628. + (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM));
  13629. + }
  13630. +
  13631. + WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER);
  13632. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  13633. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST |
  13634. + ((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) |
  13635. + ((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL));
  13636. +}
  13637. +
  13638. +/*
  13639. + * The maximum number of sessions supported by the card
  13640. + * is dependent on the amount of context ram, which
  13641. + * encryption algorithms are enabled, and how compression
  13642. + * is configured. This should be configured before this
  13643. + * routine is called.
  13644. + */
  13645. +static void
  13646. +hifn_sessions(struct hifn_softc *sc)
  13647. +{
  13648. + u_int32_t pucnfg;
  13649. + int ctxsize;
  13650. +
  13651. + DPRINTF("%s()\n", __FUNCTION__);
  13652. +
  13653. + pucnfg = READ_REG_0(sc, HIFN_0_PUCNFG);
  13654. +
  13655. + if (pucnfg & HIFN_PUCNFG_COMPSING) {
  13656. + if (pucnfg & HIFN_PUCNFG_ENCCNFG)
  13657. + ctxsize = 128;
  13658. + else
  13659. + ctxsize = 512;
  13660. + /*
  13661. + * 7955/7956 has internal context memory of 32K
  13662. + */
  13663. + if (sc->sc_flags & HIFN_IS_7956)
  13664. + sc->sc_maxses = 32768 / ctxsize;
  13665. + else
  13666. + sc->sc_maxses = 1 +
  13667. + ((sc->sc_ramsize - 32768) / ctxsize);
  13668. + } else
  13669. + sc->sc_maxses = sc->sc_ramsize / 16384;
  13670. +
  13671. + if (sc->sc_maxses > 2048)
  13672. + sc->sc_maxses = 2048;
  13673. +}
  13674. +
  13675. +/*
  13676. + * Determine ram type (sram or dram). Board should be just out of a reset
  13677. + * state when this is called.
  13678. + */
  13679. +static int
  13680. +hifn_ramtype(struct hifn_softc *sc)
  13681. +{
  13682. + u_int8_t data[8], dataexpect[8];
  13683. + int i;
  13684. +
  13685. + for (i = 0; i < sizeof(data); i++)
  13686. + data[i] = dataexpect[i] = 0x55;
  13687. + if (hifn_writeramaddr(sc, 0, data))
  13688. + return (-1);
  13689. + if (hifn_readramaddr(sc, 0, data))
  13690. + return (-1);
  13691. + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
  13692. + sc->sc_drammodel = 1;
  13693. + return (0);
  13694. + }
  13695. +
  13696. + for (i = 0; i < sizeof(data); i++)
  13697. + data[i] = dataexpect[i] = 0xaa;
  13698. + if (hifn_writeramaddr(sc, 0, data))
  13699. + return (-1);
  13700. + if (hifn_readramaddr(sc, 0, data))
  13701. + return (-1);
  13702. + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
  13703. + sc->sc_drammodel = 1;
  13704. + return (0);
  13705. + }
  13706. +
  13707. + return (0);
  13708. +}
  13709. +
  13710. +#define HIFN_SRAM_MAX (32 << 20)
  13711. +#define HIFN_SRAM_STEP_SIZE 16384
  13712. +#define HIFN_SRAM_GRANULARITY (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)
  13713. +
  13714. +static int
  13715. +hifn_sramsize(struct hifn_softc *sc)
  13716. +{
  13717. + u_int32_t a;
  13718. + u_int8_t data[8];
  13719. + u_int8_t dataexpect[sizeof(data)];
  13720. + int32_t i;
  13721. +
  13722. + for (i = 0; i < sizeof(data); i++)
  13723. + data[i] = dataexpect[i] = i ^ 0x5a;
  13724. +
  13725. + for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) {
  13726. + a = i * HIFN_SRAM_STEP_SIZE;
  13727. + bcopy(&i, data, sizeof(i));
  13728. + hifn_writeramaddr(sc, a, data);
  13729. + }
  13730. +
  13731. + for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) {
  13732. + a = i * HIFN_SRAM_STEP_SIZE;
  13733. + bcopy(&i, dataexpect, sizeof(i));
  13734. + if (hifn_readramaddr(sc, a, data) < 0)
  13735. + return (0);
  13736. + if (bcmp(data, dataexpect, sizeof(data)) != 0)
  13737. + return (0);
  13738. + sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE;
  13739. + }
  13740. +
  13741. + return (0);
  13742. +}
  13743. +
  13744. +/*
  13745. + * XXX For dram boards, one should really try all of the
  13746. + * HIFN_PUCNFG_DSZ_*'s. This just assumes that PUCNFG
  13747. + * is already set up correctly.
  13748. + */
  13749. +static int
  13750. +hifn_dramsize(struct hifn_softc *sc)
  13751. +{
  13752. + u_int32_t cnfg;
  13753. +
  13754. + if (sc->sc_flags & HIFN_IS_7956) {
  13755. + /*
  13756. + * 7955/7956 have a fixed internal ram of only 32K.
  13757. + */
  13758. + sc->sc_ramsize = 32768;
  13759. + } else {
  13760. + cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) &
  13761. + HIFN_PUCNFG_DRAMMASK;
  13762. + sc->sc_ramsize = 1 << ((cnfg >> 13) + 18);
  13763. + }
  13764. + return (0);
  13765. +}
  13766. +
  13767. +static void
  13768. +hifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, int *dstp, int *resp)
  13769. +{
  13770. + struct hifn_dma *dma = sc->sc_dma;
  13771. +
  13772. + DPRINTF("%s()\n", __FUNCTION__);
  13773. +
  13774. + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
  13775. + dma->cmdi = 0;
  13776. + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  13777. + wmb();
  13778. + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
  13779. + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
  13780. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  13781. + }
  13782. + *cmdp = dma->cmdi++;
  13783. + dma->cmdk = dma->cmdi;
  13784. +
  13785. + if (dma->srci == HIFN_D_SRC_RSIZE) {
  13786. + dma->srci = 0;
  13787. + dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  13788. + wmb();
  13789. + dma->srcr[HIFN_D_SRC_RSIZE].l |= htole32(HIFN_D_VALID);
  13790. + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
  13791. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  13792. + }
  13793. + *srcp = dma->srci++;
  13794. + dma->srck = dma->srci;
  13795. +
  13796. + if (dma->dsti == HIFN_D_DST_RSIZE) {
  13797. + dma->dsti = 0;
  13798. + dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  13799. + wmb();
  13800. + dma->dstr[HIFN_D_DST_RSIZE].l |= htole32(HIFN_D_VALID);
  13801. + HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE,
  13802. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  13803. + }
  13804. + *dstp = dma->dsti++;
  13805. + dma->dstk = dma->dsti;
  13806. +
  13807. + if (dma->resi == HIFN_D_RES_RSIZE) {
  13808. + dma->resi = 0;
  13809. + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  13810. + wmb();
  13811. + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
  13812. + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
  13813. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  13814. + }
  13815. + *resp = dma->resi++;
  13816. + dma->resk = dma->resi;
  13817. +}
  13818. +
  13819. +static int
  13820. +hifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
  13821. +{
  13822. + struct hifn_dma *dma = sc->sc_dma;
  13823. + hifn_base_command_t wc;
  13824. + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
  13825. + int r, cmdi, resi, srci, dsti;
  13826. +
  13827. + DPRINTF("%s()\n", __FUNCTION__);
  13828. +
  13829. + wc.masks = htole16(3 << 13);
  13830. + wc.session_num = htole16(addr >> 14);
  13831. + wc.total_source_count = htole16(8);
  13832. + wc.total_dest_count = htole16(addr & 0x3fff);
  13833. +
  13834. + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
  13835. +
  13836. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  13837. + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
  13838. + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
  13839. +
  13840. + /* build write command */
  13841. + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
  13842. + *(hifn_base_command_t *)dma->command_bufs[cmdi] = wc;
  13843. + bcopy(data, &dma->test_src, sizeof(dma->test_src));
  13844. +
  13845. + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr
  13846. + + offsetof(struct hifn_dma, test_src));
  13847. + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr
  13848. + + offsetof(struct hifn_dma, test_dst));
  13849. +
  13850. + dma->cmdr[cmdi].l = htole32(16 | masks);
  13851. + dma->srcr[srci].l = htole32(8 | masks);
  13852. + dma->dstr[dsti].l = htole32(4 | masks);
  13853. + dma->resr[resi].l = htole32(4 | masks);
  13854. +
  13855. + for (r = 10000; r >= 0; r--) {
  13856. + DELAY(10);
  13857. + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
  13858. + break;
  13859. + }
  13860. + if (r == 0) {
  13861. + device_printf(sc->sc_dev, "writeramaddr -- "
  13862. + "result[%d](addr %d) still valid\n", resi, addr);
  13863. + r = -1;
  13864. + return (-1);
  13865. + } else
  13866. + r = 0;
  13867. +
  13868. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  13869. + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
  13870. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
  13871. +
  13872. + return (r);
  13873. +}
  13874. +
  13875. +static int
  13876. +hifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
  13877. +{
  13878. + struct hifn_dma *dma = sc->sc_dma;
  13879. + hifn_base_command_t rc;
  13880. + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
  13881. + int r, cmdi, srci, dsti, resi;
  13882. +
  13883. + DPRINTF("%s()\n", __FUNCTION__);
  13884. +
  13885. + rc.masks = htole16(2 << 13);
  13886. + rc.session_num = htole16(addr >> 14);
  13887. + rc.total_source_count = htole16(addr & 0x3fff);
  13888. + rc.total_dest_count = htole16(8);
  13889. +
  13890. + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
  13891. +
  13892. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  13893. + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
  13894. + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
  13895. +
  13896. + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
  13897. + *(hifn_base_command_t *)dma->command_bufs[cmdi] = rc;
  13898. +
  13899. + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr +
  13900. + offsetof(struct hifn_dma, test_src));
  13901. + dma->test_src = 0;
  13902. + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr +
  13903. + offsetof(struct hifn_dma, test_dst));
  13904. + dma->test_dst = 0;
  13905. + dma->cmdr[cmdi].l = htole32(8 | masks);
  13906. + dma->srcr[srci].l = htole32(8 | masks);
  13907. + dma->dstr[dsti].l = htole32(8 | masks);
  13908. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks);
  13909. +
  13910. + for (r = 10000; r >= 0; r--) {
  13911. + DELAY(10);
  13912. + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
  13913. + break;
  13914. + }
  13915. + if (r == 0) {
  13916. + device_printf(sc->sc_dev, "readramaddr -- "
  13917. + "result[%d](addr %d) still valid\n", resi, addr);
  13918. + r = -1;
  13919. + } else {
  13920. + r = 0;
  13921. + bcopy(&dma->test_dst, data, sizeof(dma->test_dst));
  13922. + }
  13923. +
  13924. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  13925. + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
  13926. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
  13927. +
  13928. + return (r);
  13929. +}
  13930. +
  13931. +/*
  13932. + * Initialize the descriptor rings.
  13933. + */
  13934. +static void
  13935. +hifn_init_dma(struct hifn_softc *sc)
  13936. +{
  13937. + struct hifn_dma *dma = sc->sc_dma;
  13938. + int i;
  13939. +
  13940. + DPRINTF("%s()\n", __FUNCTION__);
  13941. +
  13942. + hifn_set_retry(sc);
  13943. +
  13944. + /* initialize static pointer values */
  13945. + for (i = 0; i < HIFN_D_CMD_RSIZE; i++)
  13946. + dma->cmdr[i].p = htole32(sc->sc_dma_physaddr +
  13947. + offsetof(struct hifn_dma, command_bufs[i][0]));
  13948. + for (i = 0; i < HIFN_D_RES_RSIZE; i++)
  13949. + dma->resr[i].p = htole32(sc->sc_dma_physaddr +
  13950. + offsetof(struct hifn_dma, result_bufs[i][0]));
  13951. +
  13952. + dma->cmdr[HIFN_D_CMD_RSIZE].p =
  13953. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, cmdr[0]));
  13954. + dma->srcr[HIFN_D_SRC_RSIZE].p =
  13955. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, srcr[0]));
  13956. + dma->dstr[HIFN_D_DST_RSIZE].p =
  13957. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, dstr[0]));
  13958. + dma->resr[HIFN_D_RES_RSIZE].p =
  13959. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, resr[0]));
  13960. +
  13961. + dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0;
  13962. + dma->cmdi = dma->srci = dma->dsti = dma->resi = 0;
  13963. + dma->cmdk = dma->srck = dma->dstk = dma->resk = 0;
  13964. +}
  13965. +
  13966. +/*
  13967. + * Writes out the raw command buffer space. Returns the
  13968. + * command buffer size.
  13969. + */
  13970. +static u_int
  13971. +hifn_write_command(struct hifn_command *cmd, u_int8_t *buf)
  13972. +{
  13973. + struct hifn_softc *sc = NULL;
  13974. + u_int8_t *buf_pos;
  13975. + hifn_base_command_t *base_cmd;
  13976. + hifn_mac_command_t *mac_cmd;
  13977. + hifn_crypt_command_t *cry_cmd;
  13978. + int using_mac, using_crypt, len, ivlen;
  13979. + u_int32_t dlen, slen;
  13980. +
  13981. + DPRINTF("%s()\n", __FUNCTION__);
  13982. +
  13983. + buf_pos = buf;
  13984. + using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC;
  13985. + using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT;
  13986. +
  13987. + base_cmd = (hifn_base_command_t *)buf_pos;
  13988. + base_cmd->masks = htole16(cmd->base_masks);
  13989. + slen = cmd->src_mapsize;
  13990. + if (cmd->sloplen)
  13991. + dlen = cmd->dst_mapsize - cmd->sloplen + sizeof(u_int32_t);
  13992. + else
  13993. + dlen = cmd->dst_mapsize;
  13994. + base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO);
  13995. + base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);
  13996. + dlen >>= 16;
  13997. + slen >>= 16;
  13998. + base_cmd->session_num = htole16(
  13999. + ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |
  14000. + ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));
  14001. + buf_pos += sizeof(hifn_base_command_t);
  14002. +
  14003. + if (using_mac) {
  14004. + mac_cmd = (hifn_mac_command_t *)buf_pos;
  14005. + dlen = cmd->maccrd->crd_len;
  14006. + mac_cmd->source_count = htole16(dlen & 0xffff);
  14007. + dlen >>= 16;
  14008. + mac_cmd->masks = htole16(cmd->mac_masks |
  14009. + ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M));
  14010. + mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip);
  14011. + mac_cmd->reserved = 0;
  14012. + buf_pos += sizeof(hifn_mac_command_t);
  14013. + }
  14014. +
  14015. + if (using_crypt) {
  14016. + cry_cmd = (hifn_crypt_command_t *)buf_pos;
  14017. + dlen = cmd->enccrd->crd_len;
  14018. + cry_cmd->source_count = htole16(dlen & 0xffff);
  14019. + dlen >>= 16;
  14020. + cry_cmd->masks = htole16(cmd->cry_masks |
  14021. + ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M));
  14022. + cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip);
  14023. + cry_cmd->reserved = 0;
  14024. + buf_pos += sizeof(hifn_crypt_command_t);
  14025. + }
  14026. +
  14027. + if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) {
  14028. + bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH);
  14029. + buf_pos += HIFN_MAC_KEY_LENGTH;
  14030. + }
  14031. +
  14032. + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) {
  14033. + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
  14034. + case HIFN_CRYPT_CMD_ALG_3DES:
  14035. + bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH);
  14036. + buf_pos += HIFN_3DES_KEY_LENGTH;
  14037. + break;
  14038. + case HIFN_CRYPT_CMD_ALG_DES:
  14039. + bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH);
  14040. + buf_pos += HIFN_DES_KEY_LENGTH;
  14041. + break;
  14042. + case HIFN_CRYPT_CMD_ALG_RC4:
  14043. + len = 256;
  14044. + do {
  14045. + int clen;
  14046. +
  14047. + clen = MIN(cmd->cklen, len);
  14048. + bcopy(cmd->ck, buf_pos, clen);
  14049. + len -= clen;
  14050. + buf_pos += clen;
  14051. + } while (len > 0);
  14052. + bzero(buf_pos, 4);
  14053. + buf_pos += 4;
  14054. + break;
  14055. + case HIFN_CRYPT_CMD_ALG_AES:
  14056. + /*
  14057. + * AES keys are variable 128, 192 and
  14058. + * 256 bits (16, 24 and 32 bytes).
  14059. + */
  14060. + bcopy(cmd->ck, buf_pos, cmd->cklen);
  14061. + buf_pos += cmd->cklen;
  14062. + break;
  14063. + }
  14064. + }
  14065. +
  14066. + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) {
  14067. + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
  14068. + case HIFN_CRYPT_CMD_ALG_AES:
  14069. + ivlen = HIFN_AES_IV_LENGTH;
  14070. + break;
  14071. + default:
  14072. + ivlen = HIFN_IV_LENGTH;
  14073. + break;
  14074. + }
  14075. + bcopy(cmd->iv, buf_pos, ivlen);
  14076. + buf_pos += ivlen;
  14077. + }
  14078. +
  14079. + if ((cmd->base_masks & (HIFN_BASE_CMD_MAC|HIFN_BASE_CMD_CRYPT)) == 0) {
  14080. + bzero(buf_pos, 8);
  14081. + buf_pos += 8;
  14082. + }
  14083. +
  14084. + return (buf_pos - buf);
  14085. +}
  14086. +
  14087. +static int
  14088. +hifn_dmamap_aligned(struct hifn_operand *op)
  14089. +{
  14090. + struct hifn_softc *sc = NULL;
  14091. + int i;
  14092. +
  14093. + DPRINTF("%s()\n", __FUNCTION__);
  14094. +
  14095. + for (i = 0; i < op->nsegs; i++) {
  14096. + if (op->segs[i].ds_addr & 3)
  14097. + return (0);
  14098. + if ((i != (op->nsegs - 1)) && (op->segs[i].ds_len & 3))
  14099. + return (0);
  14100. + }
  14101. + return (1);
  14102. +}
  14103. +
  14104. +static __inline int
  14105. +hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx)
  14106. +{
  14107. + struct hifn_dma *dma = sc->sc_dma;
  14108. +
  14109. + if (++idx == HIFN_D_DST_RSIZE) {
  14110. + dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
  14111. + HIFN_D_MASKDONEIRQ);
  14112. + HIFN_DSTR_SYNC(sc, idx,
  14113. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14114. + idx = 0;
  14115. + }
  14116. + return (idx);
  14117. +}
  14118. +
  14119. +static int
  14120. +hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
  14121. +{
  14122. + struct hifn_dma *dma = sc->sc_dma;
  14123. + struct hifn_operand *dst = &cmd->dst;
  14124. + u_int32_t p, l;
  14125. + int idx, used = 0, i;
  14126. +
  14127. + DPRINTF("%s()\n", __FUNCTION__);
  14128. +
  14129. + idx = dma->dsti;
  14130. + for (i = 0; i < dst->nsegs - 1; i++) {
  14131. + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
  14132. + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ | dst->segs[i].ds_len);
  14133. + wmb();
  14134. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  14135. + HIFN_DSTR_SYNC(sc, idx,
  14136. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14137. + used++;
  14138. +
  14139. + idx = hifn_dmamap_dstwrap(sc, idx);
  14140. + }
  14141. +
  14142. + if (cmd->sloplen == 0) {
  14143. + p = dst->segs[i].ds_addr;
  14144. + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
  14145. + dst->segs[i].ds_len;
  14146. + } else {
  14147. + p = sc->sc_dma_physaddr +
  14148. + offsetof(struct hifn_dma, slop[cmd->slopidx]);
  14149. + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
  14150. + sizeof(u_int32_t);
  14151. +
  14152. + if ((dst->segs[i].ds_len - cmd->sloplen) != 0) {
  14153. + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
  14154. + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ |
  14155. + (dst->segs[i].ds_len - cmd->sloplen));
  14156. + wmb();
  14157. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  14158. + HIFN_DSTR_SYNC(sc, idx,
  14159. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14160. + used++;
  14161. +
  14162. + idx = hifn_dmamap_dstwrap(sc, idx);
  14163. + }
  14164. + }
  14165. + dma->dstr[idx].p = htole32(p);
  14166. + dma->dstr[idx].l = htole32(l);
  14167. + wmb();
  14168. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  14169. + HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14170. + used++;
  14171. +
  14172. + idx = hifn_dmamap_dstwrap(sc, idx);
  14173. +
  14174. + dma->dsti = idx;
  14175. + dma->dstu += used;
  14176. + return (idx);
  14177. +}
  14178. +
  14179. +static __inline int
  14180. +hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx)
  14181. +{
  14182. + struct hifn_dma *dma = sc->sc_dma;
  14183. +
  14184. + if (++idx == HIFN_D_SRC_RSIZE) {
  14185. + dma->srcr[idx].l = htole32(HIFN_D_VALID |
  14186. + HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
  14187. + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
  14188. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  14189. + idx = 0;
  14190. + }
  14191. + return (idx);
  14192. +}
  14193. +
  14194. +static int
  14195. +hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)
  14196. +{
  14197. + struct hifn_dma *dma = sc->sc_dma;
  14198. + struct hifn_operand *src = &cmd->src;
  14199. + int idx, i;
  14200. + u_int32_t last = 0;
  14201. +
  14202. + DPRINTF("%s()\n", __FUNCTION__);
  14203. +
  14204. + idx = dma->srci;
  14205. + for (i = 0; i < src->nsegs; i++) {
  14206. + if (i == src->nsegs - 1)
  14207. + last = HIFN_D_LAST;
  14208. +
  14209. + dma->srcr[idx].p = htole32(src->segs[i].ds_addr);
  14210. + dma->srcr[idx].l = htole32(src->segs[i].ds_len |
  14211. + HIFN_D_MASKDONEIRQ | last);
  14212. + wmb();
  14213. + dma->srcr[idx].l |= htole32(HIFN_D_VALID);
  14214. + HIFN_SRCR_SYNC(sc, idx,
  14215. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  14216. +
  14217. + idx = hifn_dmamap_srcwrap(sc, idx);
  14218. + }
  14219. + dma->srci = idx;
  14220. + dma->srcu += src->nsegs;
  14221. + return (idx);
  14222. +}
  14223. +
  14224. +
  14225. +static int
  14226. +hifn_crypto(
  14227. + struct hifn_softc *sc,
  14228. + struct hifn_command *cmd,
  14229. + struct cryptop *crp,
  14230. + int hint)
  14231. +{
  14232. + struct hifn_dma *dma = sc->sc_dma;
  14233. + u_int32_t cmdlen, csr;
  14234. + int cmdi, resi, err = 0;
  14235. + unsigned long l_flags;
  14236. +
  14237. + DPRINTF("%s()\n", __FUNCTION__);
  14238. +
  14239. + /*
  14240. + * need 1 cmd, and 1 res
  14241. + *
  14242. + * NB: check this first since it's easy.
  14243. + */
  14244. + HIFN_LOCK(sc);
  14245. + if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE ||
  14246. + (dma->resu + 1) > HIFN_D_RES_RSIZE) {
  14247. +#ifdef HIFN_DEBUG
  14248. + if (hifn_debug) {
  14249. + device_printf(sc->sc_dev,
  14250. + "cmd/result exhaustion, cmdu %u resu %u\n",
  14251. + dma->cmdu, dma->resu);
  14252. + }
  14253. +#endif
  14254. + hifnstats.hst_nomem_cr++;
  14255. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  14256. + HIFN_UNLOCK(sc);
  14257. + return (ERESTART);
  14258. + }
  14259. +
  14260. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  14261. + if (pci_map_skb(sc, &cmd->src, cmd->src_skb)) {
  14262. + hifnstats.hst_nomem_load++;
  14263. + err = ENOMEM;
  14264. + goto err_srcmap1;
  14265. + }
  14266. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  14267. + if (pci_map_uio(sc, &cmd->src, cmd->src_io)) {
  14268. + hifnstats.hst_nomem_load++;
  14269. + err = ENOMEM;
  14270. + goto err_srcmap1;
  14271. + }
  14272. + } else {
  14273. + if (pci_map_buf(sc, &cmd->src, cmd->src_buf, crp->crp_ilen)) {
  14274. + hifnstats.hst_nomem_load++;
  14275. + err = ENOMEM;
  14276. + goto err_srcmap1;
  14277. + }
  14278. + }
  14279. +
  14280. + if (hifn_dmamap_aligned(&cmd->src)) {
  14281. + cmd->sloplen = cmd->src_mapsize & 3;
  14282. + cmd->dst = cmd->src;
  14283. + } else {
  14284. + if (crp->crp_flags & CRYPTO_F_IOV) {
  14285. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14286. + err = EINVAL;
  14287. + goto err_srcmap;
  14288. + } else if (crp->crp_flags & CRYPTO_F_SKBUF) {
  14289. +#ifdef NOTYET
  14290. + int totlen, len;
  14291. + struct mbuf *m, *m0, *mlast;
  14292. +
  14293. + KASSERT(cmd->dst_m == cmd->src_m,
  14294. + ("hifn_crypto: dst_m initialized improperly"));
  14295. + hifnstats.hst_unaligned++;
  14296. + /*
  14297. + * Source is not aligned on a longword boundary.
  14298. + * Copy the data to insure alignment. If we fail
  14299. + * to allocate mbufs or clusters while doing this
  14300. + * we return ERESTART so the operation is requeued
  14301. + * at the crypto later, but only if there are
  14302. + * ops already posted to the hardware; otherwise we
  14303. + * have no guarantee that we'll be re-entered.
  14304. + */
  14305. + totlen = cmd->src_mapsize;
  14306. + if (cmd->src_m->m_flags & M_PKTHDR) {
  14307. + len = MHLEN;
  14308. + MGETHDR(m0, M_DONTWAIT, MT_DATA);
  14309. + if (m0 && !m_dup_pkthdr(m0, cmd->src_m, M_DONTWAIT)) {
  14310. + m_free(m0);
  14311. + m0 = NULL;
  14312. + }
  14313. + } else {
  14314. + len = MLEN;
  14315. + MGET(m0, M_DONTWAIT, MT_DATA);
  14316. + }
  14317. + if (m0 == NULL) {
  14318. + hifnstats.hst_nomem_mbuf++;
  14319. + err = dma->cmdu ? ERESTART : ENOMEM;
  14320. + goto err_srcmap;
  14321. + }
  14322. + if (totlen >= MINCLSIZE) {
  14323. + MCLGET(m0, M_DONTWAIT);
  14324. + if ((m0->m_flags & M_EXT) == 0) {
  14325. + hifnstats.hst_nomem_mcl++;
  14326. + err = dma->cmdu ? ERESTART : ENOMEM;
  14327. + m_freem(m0);
  14328. + goto err_srcmap;
  14329. + }
  14330. + len = MCLBYTES;
  14331. + }
  14332. + totlen -= len;
  14333. + m0->m_pkthdr.len = m0->m_len = len;
  14334. + mlast = m0;
  14335. +
  14336. + while (totlen > 0) {
  14337. + MGET(m, M_DONTWAIT, MT_DATA);
  14338. + if (m == NULL) {
  14339. + hifnstats.hst_nomem_mbuf++;
  14340. + err = dma->cmdu ? ERESTART : ENOMEM;
  14341. + m_freem(m0);
  14342. + goto err_srcmap;
  14343. + }
  14344. + len = MLEN;
  14345. + if (totlen >= MINCLSIZE) {
  14346. + MCLGET(m, M_DONTWAIT);
  14347. + if ((m->m_flags & M_EXT) == 0) {
  14348. + hifnstats.hst_nomem_mcl++;
  14349. + err = dma->cmdu ? ERESTART : ENOMEM;
  14350. + mlast->m_next = m;
  14351. + m_freem(m0);
  14352. + goto err_srcmap;
  14353. + }
  14354. + len = MCLBYTES;
  14355. + }
  14356. +
  14357. + m->m_len = len;
  14358. + m0->m_pkthdr.len += len;
  14359. + totlen -= len;
  14360. +
  14361. + mlast->m_next = m;
  14362. + mlast = m;
  14363. + }
  14364. + cmd->dst_m = m0;
  14365. +#else
  14366. + device_printf(sc->sc_dev,
  14367. + "%s,%d: CRYPTO_F_SKBUF unaligned not implemented\n",
  14368. + __FILE__, __LINE__);
  14369. + err = EINVAL;
  14370. + goto err_srcmap;
  14371. +#endif
  14372. + } else {
  14373. + device_printf(sc->sc_dev,
  14374. + "%s,%d: unaligned contig buffers not implemented\n",
  14375. + __FILE__, __LINE__);
  14376. + err = EINVAL;
  14377. + goto err_srcmap;
  14378. + }
  14379. + }
  14380. +
  14381. + if (cmd->dst_map == NULL) {
  14382. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  14383. + if (pci_map_skb(sc, &cmd->dst, cmd->dst_skb)) {
  14384. + hifnstats.hst_nomem_map++;
  14385. + err = ENOMEM;
  14386. + goto err_dstmap1;
  14387. + }
  14388. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  14389. + if (pci_map_uio(sc, &cmd->dst, cmd->dst_io)) {
  14390. + hifnstats.hst_nomem_load++;
  14391. + err = ENOMEM;
  14392. + goto err_dstmap1;
  14393. + }
  14394. + } else {
  14395. + if (pci_map_buf(sc, &cmd->dst, cmd->dst_buf, crp->crp_ilen)) {
  14396. + hifnstats.hst_nomem_load++;
  14397. + err = ENOMEM;
  14398. + goto err_dstmap1;
  14399. + }
  14400. + }
  14401. + }
  14402. +
  14403. +#ifdef HIFN_DEBUG
  14404. + if (hifn_debug) {
  14405. + device_printf(sc->sc_dev,
  14406. + "Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",
  14407. + READ_REG_1(sc, HIFN_1_DMA_CSR),
  14408. + READ_REG_1(sc, HIFN_1_DMA_IER),
  14409. + dma->cmdu, dma->srcu, dma->dstu, dma->resu,
  14410. + cmd->src_nsegs, cmd->dst_nsegs);
  14411. + }
  14412. +#endif
  14413. +
  14414. +#if 0
  14415. + if (cmd->src_map == cmd->dst_map) {
  14416. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  14417. + BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
  14418. + } else {
  14419. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  14420. + BUS_DMASYNC_PREWRITE);
  14421. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  14422. + BUS_DMASYNC_PREREAD);
  14423. + }
  14424. +#endif
  14425. +
  14426. + /*
  14427. + * need N src, and N dst
  14428. + */
  14429. + if ((dma->srcu + cmd->src_nsegs) > HIFN_D_SRC_RSIZE ||
  14430. + (dma->dstu + cmd->dst_nsegs + 1) > HIFN_D_DST_RSIZE) {
  14431. +#ifdef HIFN_DEBUG
  14432. + if (hifn_debug) {
  14433. + device_printf(sc->sc_dev,
  14434. + "src/dst exhaustion, srcu %u+%u dstu %u+%u\n",
  14435. + dma->srcu, cmd->src_nsegs,
  14436. + dma->dstu, cmd->dst_nsegs);
  14437. + }
  14438. +#endif
  14439. + hifnstats.hst_nomem_sd++;
  14440. + err = ERESTART;
  14441. + goto err_dstmap;
  14442. + }
  14443. +
  14444. + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
  14445. + dma->cmdi = 0;
  14446. + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  14447. + wmb();
  14448. + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
  14449. + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
  14450. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  14451. + }
  14452. + cmdi = dma->cmdi++;
  14453. + cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]);
  14454. + HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE);
  14455. +
  14456. + /* .p for command/result already set */
  14457. + dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_LAST |
  14458. + HIFN_D_MASKDONEIRQ);
  14459. + wmb();
  14460. + dma->cmdr[cmdi].l |= htole32(HIFN_D_VALID);
  14461. + HIFN_CMDR_SYNC(sc, cmdi,
  14462. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  14463. + dma->cmdu++;
  14464. +
  14465. + /*
  14466. + * We don't worry about missing an interrupt (which a "command wait"
  14467. + * interrupt salvages us from), unless there is more than one command
  14468. + * in the queue.
  14469. + */
  14470. + if (dma->cmdu > 1) {
  14471. + sc->sc_dmaier |= HIFN_DMAIER_C_WAIT;
  14472. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  14473. + }
  14474. +
  14475. + hifnstats.hst_ipackets++;
  14476. + hifnstats.hst_ibytes += cmd->src_mapsize;
  14477. +
  14478. + hifn_dmamap_load_src(sc, cmd);
  14479. +
  14480. + /*
  14481. + * Unlike other descriptors, we don't mask done interrupt from
  14482. + * result descriptor.
  14483. + */
  14484. +#ifdef HIFN_DEBUG
  14485. + if (hifn_debug)
  14486. + device_printf(sc->sc_dev, "load res\n");
  14487. +#endif
  14488. + if (dma->resi == HIFN_D_RES_RSIZE) {
  14489. + dma->resi = 0;
  14490. + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  14491. + wmb();
  14492. + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
  14493. + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
  14494. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14495. + }
  14496. + resi = dma->resi++;
  14497. + KASSERT(dma->hifn_commands[resi] == NULL,
  14498. + ("hifn_crypto: command slot %u busy", resi));
  14499. + dma->hifn_commands[resi] = cmd;
  14500. + HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD);
  14501. + if ((hint & CRYPTO_HINT_MORE) && sc->sc_curbatch < hifn_maxbatch) {
  14502. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT |
  14503. + HIFN_D_LAST | HIFN_D_MASKDONEIRQ);
  14504. + wmb();
  14505. + dma->resr[resi].l |= htole32(HIFN_D_VALID);
  14506. + sc->sc_curbatch++;
  14507. + if (sc->sc_curbatch > hifnstats.hst_maxbatch)
  14508. + hifnstats.hst_maxbatch = sc->sc_curbatch;
  14509. + hifnstats.hst_totbatch++;
  14510. + } else {
  14511. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | HIFN_D_LAST);
  14512. + wmb();
  14513. + dma->resr[resi].l |= htole32(HIFN_D_VALID);
  14514. + sc->sc_curbatch = 0;
  14515. + }
  14516. + HIFN_RESR_SYNC(sc, resi,
  14517. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14518. + dma->resu++;
  14519. +
  14520. + if (cmd->sloplen)
  14521. + cmd->slopidx = resi;
  14522. +
  14523. + hifn_dmamap_load_dst(sc, cmd);
  14524. +
  14525. + csr = 0;
  14526. + if (sc->sc_c_busy == 0) {
  14527. + csr |= HIFN_DMACSR_C_CTRL_ENA;
  14528. + sc->sc_c_busy = 1;
  14529. + }
  14530. + if (sc->sc_s_busy == 0) {
  14531. + csr |= HIFN_DMACSR_S_CTRL_ENA;
  14532. + sc->sc_s_busy = 1;
  14533. + }
  14534. + if (sc->sc_r_busy == 0) {
  14535. + csr |= HIFN_DMACSR_R_CTRL_ENA;
  14536. + sc->sc_r_busy = 1;
  14537. + }
  14538. + if (sc->sc_d_busy == 0) {
  14539. + csr |= HIFN_DMACSR_D_CTRL_ENA;
  14540. + sc->sc_d_busy = 1;
  14541. + }
  14542. + if (csr)
  14543. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, csr);
  14544. +
  14545. +#ifdef HIFN_DEBUG
  14546. + if (hifn_debug) {
  14547. + device_printf(sc->sc_dev, "command: stat %8x ier %8x\n",
  14548. + READ_REG_1(sc, HIFN_1_DMA_CSR),
  14549. + READ_REG_1(sc, HIFN_1_DMA_IER));
  14550. + }
  14551. +#endif
  14552. +
  14553. + sc->sc_active = 5;
  14554. + HIFN_UNLOCK(sc);
  14555. + KASSERT(err == 0, ("hifn_crypto: success with error %u", err));
  14556. + return (err); /* success */
  14557. +
  14558. +err_dstmap:
  14559. + if (cmd->src_map != cmd->dst_map)
  14560. + pci_unmap_buf(sc, &cmd->dst);
  14561. +err_dstmap1:
  14562. +err_srcmap:
  14563. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  14564. + if (cmd->src_skb != cmd->dst_skb)
  14565. +#ifdef NOTYET
  14566. + m_freem(cmd->dst_m);
  14567. +#else
  14568. + device_printf(sc->sc_dev,
  14569. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  14570. + __FILE__, __LINE__);
  14571. +#endif
  14572. + }
  14573. + pci_unmap_buf(sc, &cmd->src);
  14574. +err_srcmap1:
  14575. + HIFN_UNLOCK(sc);
  14576. + return (err);
  14577. +}
  14578. +
  14579. +static void
  14580. +hifn_tick(unsigned long arg)
  14581. +{
  14582. + struct hifn_softc *sc;
  14583. + unsigned long l_flags;
  14584. +
  14585. + if (arg >= HIFN_MAX_CHIPS)
  14586. + return;
  14587. + sc = hifn_chip_idx[arg];
  14588. + if (!sc)
  14589. + return;
  14590. +
  14591. + HIFN_LOCK(sc);
  14592. + if (sc->sc_active == 0) {
  14593. + struct hifn_dma *dma = sc->sc_dma;
  14594. + u_int32_t r = 0;
  14595. +
  14596. + if (dma->cmdu == 0 && sc->sc_c_busy) {
  14597. + sc->sc_c_busy = 0;
  14598. + r |= HIFN_DMACSR_C_CTRL_DIS;
  14599. + }
  14600. + if (dma->srcu == 0 && sc->sc_s_busy) {
  14601. + sc->sc_s_busy = 0;
  14602. + r |= HIFN_DMACSR_S_CTRL_DIS;
  14603. + }
  14604. + if (dma->dstu == 0 && sc->sc_d_busy) {
  14605. + sc->sc_d_busy = 0;
  14606. + r |= HIFN_DMACSR_D_CTRL_DIS;
  14607. + }
  14608. + if (dma->resu == 0 && sc->sc_r_busy) {
  14609. + sc->sc_r_busy = 0;
  14610. + r |= HIFN_DMACSR_R_CTRL_DIS;
  14611. + }
  14612. + if (r)
  14613. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, r);
  14614. + } else
  14615. + sc->sc_active--;
  14616. + HIFN_UNLOCK(sc);
  14617. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  14618. +}
  14619. +
  14620. +static irqreturn_t
  14621. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  14622. +hifn_intr(int irq, void *arg)
  14623. +#else
  14624. +hifn_intr(int irq, void *arg, struct pt_regs *regs)
  14625. +#endif
  14626. +{
  14627. + struct hifn_softc *sc = arg;
  14628. + struct hifn_dma *dma;
  14629. + u_int32_t dmacsr, restart;
  14630. + int i, u;
  14631. + unsigned long l_flags;
  14632. +
  14633. + dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);
  14634. +
  14635. + /* Nothing in the DMA unit interrupted */
  14636. + if ((dmacsr & sc->sc_dmaier) == 0)
  14637. + return IRQ_NONE;
  14638. +
  14639. + HIFN_LOCK(sc);
  14640. +
  14641. + dma = sc->sc_dma;
  14642. +
  14643. +#ifdef HIFN_DEBUG
  14644. + if (hifn_debug) {
  14645. + device_printf(sc->sc_dev,
  14646. + "irq: stat %08x ien %08x damier %08x i %d/%d/%d/%d k %d/%d/%d/%d u %d/%d/%d/%d\n",
  14647. + dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER), sc->sc_dmaier,
  14648. + dma->cmdi, dma->srci, dma->dsti, dma->resi,
  14649. + dma->cmdk, dma->srck, dma->dstk, dma->resk,
  14650. + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
  14651. + }
  14652. +#endif
  14653. +
  14654. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier);
  14655. +
  14656. + if ((sc->sc_flags & HIFN_HAS_PUBLIC) &&
  14657. + (dmacsr & HIFN_DMACSR_PUBDONE))
  14658. + WRITE_REG_1(sc, HIFN_1_PUB_STATUS,
  14659. + READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE);
  14660. +
  14661. + restart = dmacsr & (HIFN_DMACSR_D_OVER | HIFN_DMACSR_R_OVER);
  14662. + if (restart)
  14663. + device_printf(sc->sc_dev, "overrun %x\n", dmacsr);
  14664. +
  14665. + if (sc->sc_flags & HIFN_IS_7811) {
  14666. + if (dmacsr & HIFN_DMACSR_ILLR)
  14667. + device_printf(sc->sc_dev, "illegal read\n");
  14668. + if (dmacsr & HIFN_DMACSR_ILLW)
  14669. + device_printf(sc->sc_dev, "illegal write\n");
  14670. + }
  14671. +
  14672. + restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT |
  14673. + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT);
  14674. + if (restart) {
  14675. + device_printf(sc->sc_dev, "abort, resetting.\n");
  14676. + hifnstats.hst_abort++;
  14677. + hifn_abort(sc);
  14678. + HIFN_UNLOCK(sc);
  14679. + return IRQ_HANDLED;
  14680. + }
  14681. +
  14682. + if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->cmdu == 0)) {
  14683. + /*
  14684. + * If no slots to process and we receive a "waiting on
  14685. + * command" interrupt, we disable the "waiting on command"
  14686. + * (by clearing it).
  14687. + */
  14688. + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
  14689. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  14690. + }
  14691. +
  14692. + /* clear the rings */
  14693. + i = dma->resk; u = dma->resu;
  14694. + while (u != 0) {
  14695. + HIFN_RESR_SYNC(sc, i,
  14696. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  14697. + if (dma->resr[i].l & htole32(HIFN_D_VALID)) {
  14698. + HIFN_RESR_SYNC(sc, i,
  14699. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14700. + break;
  14701. + }
  14702. +
  14703. + if (i != HIFN_D_RES_RSIZE) {
  14704. + struct hifn_command *cmd;
  14705. + u_int8_t *macbuf = NULL;
  14706. +
  14707. + HIFN_RES_SYNC(sc, i, BUS_DMASYNC_POSTREAD);
  14708. + cmd = dma->hifn_commands[i];
  14709. + KASSERT(cmd != NULL,
  14710. + ("hifn_intr: null command slot %u", i));
  14711. + dma->hifn_commands[i] = NULL;
  14712. +
  14713. + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
  14714. + macbuf = dma->result_bufs[i];
  14715. + macbuf += 12;
  14716. + }
  14717. +
  14718. + hifn_callback(sc, cmd, macbuf);
  14719. + hifnstats.hst_opackets++;
  14720. + u--;
  14721. + }
  14722. +
  14723. + if (++i == (HIFN_D_RES_RSIZE + 1))
  14724. + i = 0;
  14725. + }
  14726. + dma->resk = i; dma->resu = u;
  14727. +
  14728. + i = dma->srck; u = dma->srcu;
  14729. + while (u != 0) {
  14730. + if (i == HIFN_D_SRC_RSIZE)
  14731. + i = 0;
  14732. + HIFN_SRCR_SYNC(sc, i,
  14733. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  14734. + if (dma->srcr[i].l & htole32(HIFN_D_VALID)) {
  14735. + HIFN_SRCR_SYNC(sc, i,
  14736. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14737. + break;
  14738. + }
  14739. + i++, u--;
  14740. + }
  14741. + dma->srck = i; dma->srcu = u;
  14742. +
  14743. + i = dma->cmdk; u = dma->cmdu;
  14744. + while (u != 0) {
  14745. + HIFN_CMDR_SYNC(sc, i,
  14746. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  14747. + if (dma->cmdr[i].l & htole32(HIFN_D_VALID)) {
  14748. + HIFN_CMDR_SYNC(sc, i,
  14749. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14750. + break;
  14751. + }
  14752. + if (i != HIFN_D_CMD_RSIZE) {
  14753. + u--;
  14754. + HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE);
  14755. + }
  14756. + if (++i == (HIFN_D_CMD_RSIZE + 1))
  14757. + i = 0;
  14758. + }
  14759. + dma->cmdk = i; dma->cmdu = u;
  14760. +
  14761. + HIFN_UNLOCK(sc);
  14762. +
  14763. + if (sc->sc_needwakeup) { /* XXX check high watermark */
  14764. + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
  14765. +#ifdef HIFN_DEBUG
  14766. + if (hifn_debug)
  14767. + device_printf(sc->sc_dev,
  14768. + "wakeup crypto (%x) u %d/%d/%d/%d\n",
  14769. + sc->sc_needwakeup,
  14770. + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
  14771. +#endif
  14772. + sc->sc_needwakeup &= ~wakeup;
  14773. + crypto_unblock(sc->sc_cid, wakeup);
  14774. + }
  14775. +
  14776. + return IRQ_HANDLED;
  14777. +}
  14778. +
  14779. +/*
  14780. + * Allocate a new 'session' and return an encoded session id. 'sidp'
  14781. + * contains our registration id, and should contain an encoded session
  14782. + * id on successful allocation.
  14783. + */
  14784. +static int
  14785. +hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  14786. +{
  14787. + struct hifn_softc *sc = device_get_softc(dev);
  14788. + struct cryptoini *c;
  14789. + int mac = 0, cry = 0, sesn;
  14790. + struct hifn_session *ses = NULL;
  14791. + unsigned long l_flags;
  14792. +
  14793. + DPRINTF("%s()\n", __FUNCTION__);
  14794. +
  14795. + KASSERT(sc != NULL, ("hifn_newsession: null softc"));
  14796. + if (sidp == NULL || cri == NULL || sc == NULL) {
  14797. + DPRINTF("%s,%d: %s - EINVAL\n", __FILE__, __LINE__, __FUNCTION__);
  14798. + return (EINVAL);
  14799. + }
  14800. +
  14801. + HIFN_LOCK(sc);
  14802. + if (sc->sc_sessions == NULL) {
  14803. + ses = sc->sc_sessions = (struct hifn_session *)kmalloc(sizeof(*ses),
  14804. + SLAB_ATOMIC);
  14805. + if (ses == NULL) {
  14806. + HIFN_UNLOCK(sc);
  14807. + return (ENOMEM);
  14808. + }
  14809. + sesn = 0;
  14810. + sc->sc_nsessions = 1;
  14811. + } else {
  14812. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  14813. + if (!sc->sc_sessions[sesn].hs_used) {
  14814. + ses = &sc->sc_sessions[sesn];
  14815. + break;
  14816. + }
  14817. + }
  14818. +
  14819. + if (ses == NULL) {
  14820. + sesn = sc->sc_nsessions;
  14821. + ses = (struct hifn_session *)kmalloc((sesn + 1) * sizeof(*ses),
  14822. + SLAB_ATOMIC);
  14823. + if (ses == NULL) {
  14824. + HIFN_UNLOCK(sc);
  14825. + return (ENOMEM);
  14826. + }
  14827. + bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
  14828. + bzero(sc->sc_sessions, sesn * sizeof(*ses));
  14829. + kfree(sc->sc_sessions);
  14830. + sc->sc_sessions = ses;
  14831. + ses = &sc->sc_sessions[sesn];
  14832. + sc->sc_nsessions++;
  14833. + }
  14834. + }
  14835. + HIFN_UNLOCK(sc);
  14836. +
  14837. + bzero(ses, sizeof(*ses));
  14838. + ses->hs_used = 1;
  14839. +
  14840. + for (c = cri; c != NULL; c = c->cri_next) {
  14841. + switch (c->cri_alg) {
  14842. + case CRYPTO_MD5:
  14843. + case CRYPTO_SHA1:
  14844. + case CRYPTO_MD5_HMAC:
  14845. + case CRYPTO_SHA1_HMAC:
  14846. + if (mac) {
  14847. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14848. + return (EINVAL);
  14849. + }
  14850. + mac = 1;
  14851. + ses->hs_mlen = c->cri_mlen;
  14852. + if (ses->hs_mlen == 0) {
  14853. + switch (c->cri_alg) {
  14854. + case CRYPTO_MD5:
  14855. + case CRYPTO_MD5_HMAC:
  14856. + ses->hs_mlen = 16;
  14857. + break;
  14858. + case CRYPTO_SHA1:
  14859. + case CRYPTO_SHA1_HMAC:
  14860. + ses->hs_mlen = 20;
  14861. + break;
  14862. + }
  14863. + }
  14864. + break;
  14865. + case CRYPTO_DES_CBC:
  14866. + case CRYPTO_3DES_CBC:
  14867. + case CRYPTO_AES_CBC:
  14868. + /* XXX this may read fewer, does it matter? */
  14869. + read_random(ses->hs_iv,
  14870. + c->cri_alg == CRYPTO_AES_CBC ?
  14871. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  14872. + /*FALLTHROUGH*/
  14873. + case CRYPTO_ARC4:
  14874. + if (cry) {
  14875. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14876. + return (EINVAL);
  14877. + }
  14878. + cry = 1;
  14879. + break;
  14880. + default:
  14881. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14882. + return (EINVAL);
  14883. + }
  14884. + }
  14885. + if (mac == 0 && cry == 0) {
  14886. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14887. + return (EINVAL);
  14888. + }
  14889. +
  14890. + *sidp = HIFN_SID(device_get_unit(sc->sc_dev), sesn);
  14891. +
  14892. + return (0);
  14893. +}
  14894. +
  14895. +/*
  14896. + * Deallocate a session.
  14897. + * XXX this routine should run a zero'd mac/encrypt key into context ram.
  14898. + * XXX to blow away any keys already stored there.
  14899. + */
  14900. +static int
  14901. +hifn_freesession(device_t dev, u_int64_t tid)
  14902. +{
  14903. + struct hifn_softc *sc = device_get_softc(dev);
  14904. + int session, error;
  14905. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  14906. + unsigned long l_flags;
  14907. +
  14908. + DPRINTF("%s()\n", __FUNCTION__);
  14909. +
  14910. + KASSERT(sc != NULL, ("hifn_freesession: null softc"));
  14911. + if (sc == NULL) {
  14912. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14913. + return (EINVAL);
  14914. + }
  14915. +
  14916. + HIFN_LOCK(sc);
  14917. + session = HIFN_SESSION(sid);
  14918. + if (session < sc->sc_nsessions) {
  14919. + bzero(&sc->sc_sessions[session], sizeof(struct hifn_session));
  14920. + error = 0;
  14921. + } else {
  14922. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14923. + error = EINVAL;
  14924. + }
  14925. + HIFN_UNLOCK(sc);
  14926. +
  14927. + return (error);
  14928. +}
  14929. +
  14930. +static int
  14931. +hifn_process(device_t dev, struct cryptop *crp, int hint)
  14932. +{
  14933. + struct hifn_softc *sc = device_get_softc(dev);
  14934. + struct hifn_command *cmd = NULL;
  14935. + int session, err, ivlen;
  14936. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  14937. +
  14938. + DPRINTF("%s()\n", __FUNCTION__);
  14939. +
  14940. + if (crp == NULL || crp->crp_callback == NULL) {
  14941. + hifnstats.hst_invalid++;
  14942. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14943. + return (EINVAL);
  14944. + }
  14945. + session = HIFN_SESSION(crp->crp_sid);
  14946. +
  14947. + if (sc == NULL || session >= sc->sc_nsessions) {
  14948. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14949. + err = EINVAL;
  14950. + goto errout;
  14951. + }
  14952. +
  14953. + cmd = kmalloc(sizeof(struct hifn_command), SLAB_ATOMIC);
  14954. + if (cmd == NULL) {
  14955. + hifnstats.hst_nomem++;
  14956. + err = ENOMEM;
  14957. + goto errout;
  14958. + }
  14959. + memset(cmd, 0, sizeof(*cmd));
  14960. +
  14961. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  14962. + cmd->src_skb = (struct sk_buff *)crp->crp_buf;
  14963. + cmd->dst_skb = (struct sk_buff *)crp->crp_buf;
  14964. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  14965. + cmd->src_io = (struct uio *)crp->crp_buf;
  14966. + cmd->dst_io = (struct uio *)crp->crp_buf;
  14967. + } else {
  14968. + cmd->src_buf = crp->crp_buf;
  14969. + cmd->dst_buf = crp->crp_buf;
  14970. + }
  14971. +
  14972. + crd1 = crp->crp_desc;
  14973. + if (crd1 == NULL) {
  14974. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14975. + err = EINVAL;
  14976. + goto errout;
  14977. + }
  14978. + crd2 = crd1->crd_next;
  14979. +
  14980. + if (crd2 == NULL) {
  14981. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  14982. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  14983. + crd1->crd_alg == CRYPTO_SHA1 ||
  14984. + crd1->crd_alg == CRYPTO_MD5) {
  14985. + maccrd = crd1;
  14986. + enccrd = NULL;
  14987. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  14988. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  14989. + crd1->crd_alg == CRYPTO_AES_CBC ||
  14990. + crd1->crd_alg == CRYPTO_ARC4) {
  14991. + if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0)
  14992. + cmd->base_masks |= HIFN_BASE_CMD_DECODE;
  14993. + maccrd = NULL;
  14994. + enccrd = crd1;
  14995. + } else {
  14996. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14997. + err = EINVAL;
  14998. + goto errout;
  14999. + }
  15000. + } else {
  15001. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  15002. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  15003. + crd1->crd_alg == CRYPTO_MD5 ||
  15004. + crd1->crd_alg == CRYPTO_SHA1) &&
  15005. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  15006. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  15007. + crd2->crd_alg == CRYPTO_AES_CBC ||
  15008. + crd2->crd_alg == CRYPTO_ARC4) &&
  15009. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  15010. + cmd->base_masks = HIFN_BASE_CMD_DECODE;
  15011. + maccrd = crd1;
  15012. + enccrd = crd2;
  15013. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  15014. + crd1->crd_alg == CRYPTO_ARC4 ||
  15015. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  15016. + crd1->crd_alg == CRYPTO_AES_CBC) &&
  15017. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  15018. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  15019. + crd2->crd_alg == CRYPTO_MD5 ||
  15020. + crd2->crd_alg == CRYPTO_SHA1) &&
  15021. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  15022. + enccrd = crd1;
  15023. + maccrd = crd2;
  15024. + } else {
  15025. + /*
  15026. + * We cannot order the 7751 as requested
  15027. + */
  15028. + DPRINTF("%s,%d: %s %d,%d,%d - EINVAL\n",__FILE__,__LINE__,__FUNCTION__, crd1->crd_alg, crd2->crd_alg, crd1->crd_flags & CRD_F_ENCRYPT);
  15029. + err = EINVAL;
  15030. + goto errout;
  15031. + }
  15032. + }
  15033. +
  15034. + if (enccrd) {
  15035. + cmd->enccrd = enccrd;
  15036. + cmd->base_masks |= HIFN_BASE_CMD_CRYPT;
  15037. + switch (enccrd->crd_alg) {
  15038. + case CRYPTO_ARC4:
  15039. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4;
  15040. + break;
  15041. + case CRYPTO_DES_CBC:
  15042. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES |
  15043. + HIFN_CRYPT_CMD_MODE_CBC |
  15044. + HIFN_CRYPT_CMD_NEW_IV;
  15045. + break;
  15046. + case CRYPTO_3DES_CBC:
  15047. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES |
  15048. + HIFN_CRYPT_CMD_MODE_CBC |
  15049. + HIFN_CRYPT_CMD_NEW_IV;
  15050. + break;
  15051. + case CRYPTO_AES_CBC:
  15052. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES |
  15053. + HIFN_CRYPT_CMD_MODE_CBC |
  15054. + HIFN_CRYPT_CMD_NEW_IV;
  15055. + break;
  15056. + default:
  15057. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15058. + err = EINVAL;
  15059. + goto errout;
  15060. + }
  15061. + if (enccrd->crd_alg != CRYPTO_ARC4) {
  15062. + ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ?
  15063. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  15064. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  15065. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  15066. + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
  15067. + else
  15068. + bcopy(sc->sc_sessions[session].hs_iv,
  15069. + cmd->iv, ivlen);
  15070. +
  15071. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT)
  15072. + == 0) {
  15073. + crypto_copyback(crp->crp_flags,
  15074. + crp->crp_buf, enccrd->crd_inject,
  15075. + ivlen, cmd->iv);
  15076. + }
  15077. + } else {
  15078. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  15079. + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
  15080. + else {
  15081. + crypto_copydata(crp->crp_flags,
  15082. + crp->crp_buf, enccrd->crd_inject,
  15083. + ivlen, cmd->iv);
  15084. + }
  15085. + }
  15086. + }
  15087. +
  15088. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
  15089. + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
  15090. + cmd->ck = enccrd->crd_key;
  15091. + cmd->cklen = enccrd->crd_klen >> 3;
  15092. + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
  15093. +
  15094. + /*
  15095. + * Need to specify the size for the AES key in the masks.
  15096. + */
  15097. + if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) ==
  15098. + HIFN_CRYPT_CMD_ALG_AES) {
  15099. + switch (cmd->cklen) {
  15100. + case 16:
  15101. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128;
  15102. + break;
  15103. + case 24:
  15104. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192;
  15105. + break;
  15106. + case 32:
  15107. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256;
  15108. + break;
  15109. + default:
  15110. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15111. + err = EINVAL;
  15112. + goto errout;
  15113. + }
  15114. + }
  15115. + }
  15116. +
  15117. + if (maccrd) {
  15118. + cmd->maccrd = maccrd;
  15119. + cmd->base_masks |= HIFN_BASE_CMD_MAC;
  15120. +
  15121. + switch (maccrd->crd_alg) {
  15122. + case CRYPTO_MD5:
  15123. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
  15124. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
  15125. + HIFN_MAC_CMD_POS_IPSEC;
  15126. + break;
  15127. + case CRYPTO_MD5_HMAC:
  15128. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
  15129. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
  15130. + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
  15131. + break;
  15132. + case CRYPTO_SHA1:
  15133. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
  15134. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
  15135. + HIFN_MAC_CMD_POS_IPSEC;
  15136. + break;
  15137. + case CRYPTO_SHA1_HMAC:
  15138. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
  15139. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
  15140. + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
  15141. + break;
  15142. + }
  15143. +
  15144. + if (maccrd->crd_alg == CRYPTO_SHA1_HMAC ||
  15145. + maccrd->crd_alg == CRYPTO_MD5_HMAC) {
  15146. + cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY;
  15147. + bcopy(maccrd->crd_key, cmd->mac, maccrd->crd_klen >> 3);
  15148. + bzero(cmd->mac + (maccrd->crd_klen >> 3),
  15149. + HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3));
  15150. + }
  15151. + }
  15152. +
  15153. + cmd->crp = crp;
  15154. + cmd->session_num = session;
  15155. + cmd->softc = sc;
  15156. +
  15157. + err = hifn_crypto(sc, cmd, crp, hint);
  15158. + if (!err) {
  15159. + return 0;
  15160. + } else if (err == ERESTART) {
  15161. + /*
  15162. + * There weren't enough resources to dispatch the request
  15163. + * to the part. Notify the caller so they'll requeue this
  15164. + * request and resubmit it again soon.
  15165. + */
  15166. +#ifdef HIFN_DEBUG
  15167. + if (hifn_debug)
  15168. + device_printf(sc->sc_dev, "requeue request\n");
  15169. +#endif
  15170. + kfree(cmd);
  15171. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  15172. + return (err);
  15173. + }
  15174. +
  15175. +errout:
  15176. + if (cmd != NULL)
  15177. + kfree(cmd);
  15178. + if (err == EINVAL)
  15179. + hifnstats.hst_invalid++;
  15180. + else
  15181. + hifnstats.hst_nomem++;
  15182. + crp->crp_etype = err;
  15183. + crypto_done(crp);
  15184. + return (err);
  15185. +}
  15186. +
  15187. +static void
  15188. +hifn_abort(struct hifn_softc *sc)
  15189. +{
  15190. + struct hifn_dma *dma = sc->sc_dma;
  15191. + struct hifn_command *cmd;
  15192. + struct cryptop *crp;
  15193. + int i, u;
  15194. +
  15195. + DPRINTF("%s()\n", __FUNCTION__);
  15196. +
  15197. + i = dma->resk; u = dma->resu;
  15198. + while (u != 0) {
  15199. + cmd = dma->hifn_commands[i];
  15200. + KASSERT(cmd != NULL, ("hifn_abort: null command slot %u", i));
  15201. + dma->hifn_commands[i] = NULL;
  15202. + crp = cmd->crp;
  15203. +
  15204. + if ((dma->resr[i].l & htole32(HIFN_D_VALID)) == 0) {
  15205. + /* Salvage what we can. */
  15206. + u_int8_t *macbuf;
  15207. +
  15208. + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
  15209. + macbuf = dma->result_bufs[i];
  15210. + macbuf += 12;
  15211. + } else
  15212. + macbuf = NULL;
  15213. + hifnstats.hst_opackets++;
  15214. + hifn_callback(sc, cmd, macbuf);
  15215. + } else {
  15216. +#if 0
  15217. + if (cmd->src_map == cmd->dst_map) {
  15218. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  15219. + BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  15220. + } else {
  15221. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  15222. + BUS_DMASYNC_POSTWRITE);
  15223. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  15224. + BUS_DMASYNC_POSTREAD);
  15225. + }
  15226. +#endif
  15227. +
  15228. + if (cmd->src_skb != cmd->dst_skb) {
  15229. +#ifdef NOTYET
  15230. + m_freem(cmd->src_m);
  15231. + crp->crp_buf = (caddr_t)cmd->dst_m;
  15232. +#else
  15233. + device_printf(sc->sc_dev,
  15234. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  15235. + __FILE__, __LINE__);
  15236. +#endif
  15237. + }
  15238. +
  15239. + /* non-shared buffers cannot be restarted */
  15240. + if (cmd->src_map != cmd->dst_map) {
  15241. + /*
  15242. + * XXX should be EAGAIN, delayed until
  15243. + * after the reset.
  15244. + */
  15245. + crp->crp_etype = ENOMEM;
  15246. + pci_unmap_buf(sc, &cmd->dst);
  15247. + } else
  15248. + crp->crp_etype = ENOMEM;
  15249. +
  15250. + pci_unmap_buf(sc, &cmd->src);
  15251. +
  15252. + kfree(cmd);
  15253. + if (crp->crp_etype != EAGAIN)
  15254. + crypto_done(crp);
  15255. + }
  15256. +
  15257. + if (++i == HIFN_D_RES_RSIZE)
  15258. + i = 0;
  15259. + u--;
  15260. + }
  15261. + dma->resk = i; dma->resu = u;
  15262. +
  15263. + hifn_reset_board(sc, 1);
  15264. + hifn_init_dma(sc);
  15265. + hifn_init_pci_registers(sc);
  15266. +}
  15267. +
  15268. +static void
  15269. +hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)
  15270. +{
  15271. + struct hifn_dma *dma = sc->sc_dma;
  15272. + struct cryptop *crp = cmd->crp;
  15273. + struct cryptodesc *crd;
  15274. + int i, u, ivlen;
  15275. +
  15276. + DPRINTF("%s()\n", __FUNCTION__);
  15277. +
  15278. +#if 0
  15279. + if (cmd->src_map == cmd->dst_map) {
  15280. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  15281. + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
  15282. + } else {
  15283. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  15284. + BUS_DMASYNC_POSTWRITE);
  15285. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  15286. + BUS_DMASYNC_POSTREAD);
  15287. + }
  15288. +#endif
  15289. +
  15290. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  15291. + if (cmd->src_skb != cmd->dst_skb) {
  15292. +#ifdef NOTYET
  15293. + crp->crp_buf = (caddr_t)cmd->dst_m;
  15294. + totlen = cmd->src_mapsize;
  15295. + for (m = cmd->dst_m; m != NULL; m = m->m_next) {
  15296. + if (totlen < m->m_len) {
  15297. + m->m_len = totlen;
  15298. + totlen = 0;
  15299. + } else
  15300. + totlen -= m->m_len;
  15301. + }
  15302. + cmd->dst_m->m_pkthdr.len = cmd->src_m->m_pkthdr.len;
  15303. + m_freem(cmd->src_m);
  15304. +#else
  15305. + device_printf(sc->sc_dev,
  15306. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  15307. + __FILE__, __LINE__);
  15308. +#endif
  15309. + }
  15310. + }
  15311. +
  15312. + if (cmd->sloplen != 0) {
  15313. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  15314. + cmd->src_mapsize - cmd->sloplen, cmd->sloplen,
  15315. + (caddr_t)&dma->slop[cmd->slopidx]);
  15316. + }
  15317. +
  15318. + i = dma->dstk; u = dma->dstu;
  15319. + while (u != 0) {
  15320. + if (i == HIFN_D_DST_RSIZE)
  15321. + i = 0;
  15322. +#if 0
  15323. + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
  15324. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  15325. +#endif
  15326. + if (dma->dstr[i].l & htole32(HIFN_D_VALID)) {
  15327. +#if 0
  15328. + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
  15329. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15330. +#endif
  15331. + break;
  15332. + }
  15333. + i++, u--;
  15334. + }
  15335. + dma->dstk = i; dma->dstu = u;
  15336. +
  15337. + hifnstats.hst_obytes += cmd->dst_mapsize;
  15338. +
  15339. + if ((cmd->base_masks & (HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE)) ==
  15340. + HIFN_BASE_CMD_CRYPT) {
  15341. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  15342. + if (crd->crd_alg != CRYPTO_DES_CBC &&
  15343. + crd->crd_alg != CRYPTO_3DES_CBC &&
  15344. + crd->crd_alg != CRYPTO_AES_CBC)
  15345. + continue;
  15346. + ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?
  15347. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  15348. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  15349. + crd->crd_skip + crd->crd_len - ivlen, ivlen,
  15350. + cmd->softc->sc_sessions[cmd->session_num].hs_iv);
  15351. + break;
  15352. + }
  15353. + }
  15354. +
  15355. + if (macbuf != NULL) {
  15356. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  15357. + int len;
  15358. +
  15359. + if (crd->crd_alg != CRYPTO_MD5 &&
  15360. + crd->crd_alg != CRYPTO_SHA1 &&
  15361. + crd->crd_alg != CRYPTO_MD5_HMAC &&
  15362. + crd->crd_alg != CRYPTO_SHA1_HMAC) {
  15363. + continue;
  15364. + }
  15365. + len = cmd->softc->sc_sessions[cmd->session_num].hs_mlen;
  15366. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  15367. + crd->crd_inject, len, macbuf);
  15368. + break;
  15369. + }
  15370. + }
  15371. +
  15372. + if (cmd->src_map != cmd->dst_map)
  15373. + pci_unmap_buf(sc, &cmd->dst);
  15374. + pci_unmap_buf(sc, &cmd->src);
  15375. + kfree(cmd);
  15376. + crypto_done(crp);
  15377. +}
  15378. +
  15379. +/*
  15380. + * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0
  15381. + * and Group 1 registers; avoid conditions that could create
  15382. + * burst writes by doing a read in between the writes.
  15383. + *
  15384. + * NB: The read we interpose is always to the same register;
  15385. + * we do this because reading from an arbitrary (e.g. last)
  15386. + * register may not always work.
  15387. + */
  15388. +static void
  15389. +hifn_write_reg_0(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
  15390. +{
  15391. + if (sc->sc_flags & HIFN_IS_7811) {
  15392. + if (sc->sc_bar0_lastreg == reg - 4)
  15393. + readl(sc->sc_bar0 + HIFN_0_PUCNFG);
  15394. + sc->sc_bar0_lastreg = reg;
  15395. + }
  15396. + writel(val, sc->sc_bar0 + reg);
  15397. +}
  15398. +
  15399. +static void
  15400. +hifn_write_reg_1(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
  15401. +{
  15402. + if (sc->sc_flags & HIFN_IS_7811) {
  15403. + if (sc->sc_bar1_lastreg == reg - 4)
  15404. + readl(sc->sc_bar1 + HIFN_1_REVID);
  15405. + sc->sc_bar1_lastreg = reg;
  15406. + }
  15407. + writel(val, sc->sc_bar1 + reg);
  15408. +}
  15409. +
  15410. +
  15411. +static struct pci_device_id hifn_pci_tbl[] = {
  15412. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7951,
  15413. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15414. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955,
  15415. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15416. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956,
  15417. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15418. + { PCI_VENDOR_NETSEC, PCI_PRODUCT_NETSEC_7751,
  15419. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15420. + { PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON,
  15421. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15422. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7811,
  15423. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15424. + /*
  15425. + * Other vendors share this PCI ID as well, such as
  15426. + * http://www.powercrypt.com, and obviously they also
  15427. + * use the same key.
  15428. + */
  15429. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7751,
  15430. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15431. + { 0, 0, 0, 0, 0, 0, }
  15432. +};
  15433. +MODULE_DEVICE_TABLE(pci, hifn_pci_tbl);
  15434. +
  15435. +static struct pci_driver hifn_driver = {
  15436. + .name = "hifn",
  15437. + .id_table = hifn_pci_tbl,
  15438. + .probe = hifn_probe,
  15439. + .remove = hifn_remove,
  15440. + /* add PM stuff here one day */
  15441. +};
  15442. +
  15443. +static int __init hifn_init (void)
  15444. +{
  15445. + struct hifn_softc *sc = NULL;
  15446. + int rc;
  15447. +
  15448. + DPRINTF("%s(%p)\n", __FUNCTION__, hifn_init);
  15449. +
  15450. + rc = pci_register_driver(&hifn_driver);
  15451. + pci_register_driver_compat(&hifn_driver, rc);
  15452. +
  15453. + return rc;
  15454. +}
  15455. +
  15456. +static void __exit hifn_exit (void)
  15457. +{
  15458. + pci_unregister_driver(&hifn_driver);
  15459. +}
  15460. +
  15461. +module_init(hifn_init);
  15462. +module_exit(hifn_exit);
  15463. +
  15464. +MODULE_LICENSE("BSD");
  15465. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  15466. +MODULE_DESCRIPTION("OCF driver for hifn PCI crypto devices");
  15467. diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifn7751reg.h linux-2.6.36/crypto/ocf/hifn/hifn7751reg.h
  15468. --- linux-2.6.36.orig/crypto/ocf/hifn/hifn7751reg.h 1970-01-01 01:00:00.000000000 +0100
  15469. +++ linux-2.6.36/crypto/ocf/hifn/hifn7751reg.h 2010-11-09 20:28:04.792495416 +0100
  15470. @@ -0,0 +1,540 @@
  15471. +/* $FreeBSD: src/sys/dev/hifn/hifn7751reg.h,v 1.7 2007/03/21 03:42:49 sam Exp $ */
  15472. +/* $OpenBSD: hifn7751reg.h,v 1.35 2002/04/08 17:49:42 jason Exp $ */
  15473. +
  15474. +/*-
  15475. + * Invertex AEON / Hifn 7751 driver
  15476. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  15477. + * Copyright (c) 1999 Theo de Raadt
  15478. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  15479. + * http://www.netsec.net
  15480. + *
  15481. + * Please send any comments, feedback, bug-fixes, or feature requests to
  15482. + * software@invertex.com.
  15483. + *
  15484. + * Redistribution and use in source and binary forms, with or without
  15485. + * modification, are permitted provided that the following conditions
  15486. + * are met:
  15487. + *
  15488. + * 1. Redistributions of source code must retain the above copyright
  15489. + * notice, this list of conditions and the following disclaimer.
  15490. + * 2. Redistributions in binary form must reproduce the above copyright
  15491. + * notice, this list of conditions and the following disclaimer in the
  15492. + * documentation and/or other materials provided with the distribution.
  15493. + * 3. The name of the author may not be used to endorse or promote products
  15494. + * derived from this software without specific prior written permission.
  15495. + *
  15496. + *
  15497. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  15498. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  15499. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  15500. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  15501. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  15502. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  15503. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  15504. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  15505. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  15506. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  15507. + *
  15508. + * Effort sponsored in part by the Defense Advanced Research Projects
  15509. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  15510. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  15511. + *
  15512. + */
  15513. +#ifndef __HIFN_H__
  15514. +#define __HIFN_H__
  15515. +
  15516. +/*
  15517. + * Some PCI configuration space offset defines. The names were made
  15518. + * identical to the names used by the Linux kernel.
  15519. + */
  15520. +#define HIFN_BAR0 PCIR_BAR(0) /* PUC register map */
  15521. +#define HIFN_BAR1 PCIR_BAR(1) /* DMA register map */
  15522. +#define HIFN_TRDY_TIMEOUT 0x40
  15523. +#define HIFN_RETRY_TIMEOUT 0x41
  15524. +
  15525. +/*
  15526. + * PCI vendor and device identifiers
  15527. + * (the names are preserved from their OpenBSD source).
  15528. + */
  15529. +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
  15530. +#define PCI_PRODUCT_HIFN_7751 0x0005 /* 7751 */
  15531. +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
  15532. +#define PCI_PRODUCT_HIFN_7811 0x0007 /* 7811 */
  15533. +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
  15534. +#define PCI_PRODUCT_HIFN_7951 0x0012 /* 7951 */
  15535. +#define PCI_PRODUCT_HIFN_7955 0x0020 /* 7954/7955 */
  15536. +#define PCI_PRODUCT_HIFN_7956 0x001d /* 7956 */
  15537. +
  15538. +#define PCI_VENDOR_INVERTEX 0x14e1 /* Invertex */
  15539. +#define PCI_PRODUCT_INVERTEX_AEON 0x0005 /* AEON */
  15540. +
  15541. +#define PCI_VENDOR_NETSEC 0x1660 /* NetSec */
  15542. +#define PCI_PRODUCT_NETSEC_7751 0x7751 /* 7751 */
  15543. +
  15544. +/*
  15545. + * The values below should multiple of 4 -- and be large enough to handle
  15546. + * any command the driver implements.
  15547. + *
  15548. + * MAX_COMMAND = base command + mac command + encrypt command +
  15549. + * mac-key + rc4-key
  15550. + * MAX_RESULT = base result + mac result + mac + encrypt result
  15551. + *
  15552. + *
  15553. + */
  15554. +#define HIFN_MAX_COMMAND (8 + 8 + 8 + 64 + 260)
  15555. +#define HIFN_MAX_RESULT (8 + 4 + 20 + 4)
  15556. +
  15557. +/*
  15558. + * hifn_desc_t
  15559. + *
  15560. + * Holds an individual descriptor for any of the rings.
  15561. + */
  15562. +typedef struct hifn_desc {
  15563. + volatile u_int32_t l; /* length and status bits */
  15564. + volatile u_int32_t p;
  15565. +} hifn_desc_t;
  15566. +
  15567. +/*
  15568. + * Masks for the "length" field of struct hifn_desc.
  15569. + */
  15570. +#define HIFN_D_LENGTH 0x0000ffff /* length bit mask */
  15571. +#define HIFN_D_MASKDONEIRQ 0x02000000 /* mask the done interrupt */
  15572. +#define HIFN_D_DESTOVER 0x04000000 /* destination overflow */
  15573. +#define HIFN_D_OVER 0x08000000 /* overflow */
  15574. +#define HIFN_D_LAST 0x20000000 /* last descriptor in chain */
  15575. +#define HIFN_D_JUMP 0x40000000 /* jump descriptor */
  15576. +#define HIFN_D_VALID 0x80000000 /* valid bit */
  15577. +
  15578. +
  15579. +/*
  15580. + * Processing Unit Registers (offset from BASEREG0)
  15581. + */
  15582. +#define HIFN_0_PUDATA 0x00 /* Processing Unit Data */
  15583. +#define HIFN_0_PUCTRL 0x04 /* Processing Unit Control */
  15584. +#define HIFN_0_PUISR 0x08 /* Processing Unit Interrupt Status */
  15585. +#define HIFN_0_PUCNFG 0x0c /* Processing Unit Configuration */
  15586. +#define HIFN_0_PUIER 0x10 /* Processing Unit Interrupt Enable */
  15587. +#define HIFN_0_PUSTAT 0x14 /* Processing Unit Status/Chip ID */
  15588. +#define HIFN_0_FIFOSTAT 0x18 /* FIFO Status */
  15589. +#define HIFN_0_FIFOCNFG 0x1c /* FIFO Configuration */
  15590. +#define HIFN_0_PUCTRL2 0x28 /* Processing Unit Control (2nd map) */
  15591. +#define HIFN_0_MUTE1 0x80
  15592. +#define HIFN_0_MUTE2 0x90
  15593. +#define HIFN_0_SPACESIZE 0x100 /* Register space size */
  15594. +
  15595. +/* Processing Unit Control Register (HIFN_0_PUCTRL) */
  15596. +#define HIFN_PUCTRL_CLRSRCFIFO 0x0010 /* clear source fifo */
  15597. +#define HIFN_PUCTRL_STOP 0x0008 /* stop pu */
  15598. +#define HIFN_PUCTRL_LOCKRAM 0x0004 /* lock ram */
  15599. +#define HIFN_PUCTRL_DMAENA 0x0002 /* enable dma */
  15600. +#define HIFN_PUCTRL_RESET 0x0001 /* Reset processing unit */
  15601. +
  15602. +/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */
  15603. +#define HIFN_PUISR_CMDINVAL 0x8000 /* Invalid command interrupt */
  15604. +#define HIFN_PUISR_DATAERR 0x4000 /* Data error interrupt */
  15605. +#define HIFN_PUISR_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  15606. +#define HIFN_PUISR_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  15607. +#define HIFN_PUISR_DSTOVER 0x0200 /* Destination overrun interrupt */
  15608. +#define HIFN_PUISR_SRCCMD 0x0080 /* Source command interrupt */
  15609. +#define HIFN_PUISR_SRCCTX 0x0040 /* Source context interrupt */
  15610. +#define HIFN_PUISR_SRCDATA 0x0020 /* Source data interrupt */
  15611. +#define HIFN_PUISR_DSTDATA 0x0010 /* Destination data interrupt */
  15612. +#define HIFN_PUISR_DSTRESULT 0x0004 /* Destination result interrupt */
  15613. +
  15614. +/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */
  15615. +#define HIFN_PUCNFG_DRAMMASK 0xe000 /* DRAM size mask */
  15616. +#define HIFN_PUCNFG_DSZ_256K 0x0000 /* 256k dram */
  15617. +#define HIFN_PUCNFG_DSZ_512K 0x2000 /* 512k dram */
  15618. +#define HIFN_PUCNFG_DSZ_1M 0x4000 /* 1m dram */
  15619. +#define HIFN_PUCNFG_DSZ_2M 0x6000 /* 2m dram */
  15620. +#define HIFN_PUCNFG_DSZ_4M 0x8000 /* 4m dram */
  15621. +#define HIFN_PUCNFG_DSZ_8M 0xa000 /* 8m dram */
  15622. +#define HIFN_PUNCFG_DSZ_16M 0xc000 /* 16m dram */
  15623. +#define HIFN_PUCNFG_DSZ_32M 0xe000 /* 32m dram */
  15624. +#define HIFN_PUCNFG_DRAMREFRESH 0x1800 /* DRAM refresh rate mask */
  15625. +#define HIFN_PUCNFG_DRFR_512 0x0000 /* 512 divisor of ECLK */
  15626. +#define HIFN_PUCNFG_DRFR_256 0x0800 /* 256 divisor of ECLK */
  15627. +#define HIFN_PUCNFG_DRFR_128 0x1000 /* 128 divisor of ECLK */
  15628. +#define HIFN_PUCNFG_TCALLPHASES 0x0200 /* your guess is as good as mine... */
  15629. +#define HIFN_PUCNFG_TCDRVTOTEM 0x0100 /* your guess is as good as mine... */
  15630. +#define HIFN_PUCNFG_BIGENDIAN 0x0080 /* DMA big endian mode */
  15631. +#define HIFN_PUCNFG_BUS32 0x0040 /* Bus width 32bits */
  15632. +#define HIFN_PUCNFG_BUS16 0x0000 /* Bus width 16 bits */
  15633. +#define HIFN_PUCNFG_CHIPID 0x0020 /* Allow chipid from PUSTAT */
  15634. +#define HIFN_PUCNFG_DRAM 0x0010 /* Context RAM is DRAM */
  15635. +#define HIFN_PUCNFG_SRAM 0x0000 /* Context RAM is SRAM */
  15636. +#define HIFN_PUCNFG_COMPSING 0x0004 /* Enable single compression context */
  15637. +#define HIFN_PUCNFG_ENCCNFG 0x0002 /* Encryption configuration */
  15638. +
  15639. +/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */
  15640. +#define HIFN_PUIER_CMDINVAL 0x8000 /* Invalid command interrupt */
  15641. +#define HIFN_PUIER_DATAERR 0x4000 /* Data error interrupt */
  15642. +#define HIFN_PUIER_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  15643. +#define HIFN_PUIER_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  15644. +#define HIFN_PUIER_DSTOVER 0x0200 /* Destination overrun interrupt */
  15645. +#define HIFN_PUIER_SRCCMD 0x0080 /* Source command interrupt */
  15646. +#define HIFN_PUIER_SRCCTX 0x0040 /* Source context interrupt */
  15647. +#define HIFN_PUIER_SRCDATA 0x0020 /* Source data interrupt */
  15648. +#define HIFN_PUIER_DSTDATA 0x0010 /* Destination data interrupt */
  15649. +#define HIFN_PUIER_DSTRESULT 0x0004 /* Destination result interrupt */
  15650. +
  15651. +/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */
  15652. +#define HIFN_PUSTAT_CMDINVAL 0x8000 /* Invalid command interrupt */
  15653. +#define HIFN_PUSTAT_DATAERR 0x4000 /* Data error interrupt */
  15654. +#define HIFN_PUSTAT_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  15655. +#define HIFN_PUSTAT_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  15656. +#define HIFN_PUSTAT_DSTOVER 0x0200 /* Destination overrun interrupt */
  15657. +#define HIFN_PUSTAT_SRCCMD 0x0080 /* Source command interrupt */
  15658. +#define HIFN_PUSTAT_SRCCTX 0x0040 /* Source context interrupt */
  15659. +#define HIFN_PUSTAT_SRCDATA 0x0020 /* Source data interrupt */
  15660. +#define HIFN_PUSTAT_DSTDATA 0x0010 /* Destination data interrupt */
  15661. +#define HIFN_PUSTAT_DSTRESULT 0x0004 /* Destination result interrupt */
  15662. +#define HIFN_PUSTAT_CHIPREV 0x00ff /* Chip revision mask */
  15663. +#define HIFN_PUSTAT_CHIPENA 0xff00 /* Chip enabled mask */
  15664. +#define HIFN_PUSTAT_ENA_2 0x1100 /* Level 2 enabled */
  15665. +#define HIFN_PUSTAT_ENA_1 0x1000 /* Level 1 enabled */
  15666. +#define HIFN_PUSTAT_ENA_0 0x3000 /* Level 0 enabled */
  15667. +#define HIFN_PUSTAT_REV_2 0x0020 /* 7751 PT6/2 */
  15668. +#define HIFN_PUSTAT_REV_3 0x0030 /* 7751 PT6/3 */
  15669. +
  15670. +/* FIFO Status Register (HIFN_0_FIFOSTAT) */
  15671. +#define HIFN_FIFOSTAT_SRC 0x7f00 /* Source FIFO available */
  15672. +#define HIFN_FIFOSTAT_DST 0x007f /* Destination FIFO available */
  15673. +
  15674. +/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */
  15675. +#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as this value */
  15676. +
  15677. +/*
  15678. + * DMA Interface Registers (offset from BASEREG1)
  15679. + */
  15680. +#define HIFN_1_DMA_CRAR 0x0c /* DMA Command Ring Address */
  15681. +#define HIFN_1_DMA_SRAR 0x1c /* DMA Source Ring Address */
  15682. +#define HIFN_1_DMA_RRAR 0x2c /* DMA Result Ring Address */
  15683. +#define HIFN_1_DMA_DRAR 0x3c /* DMA Destination Ring Address */
  15684. +#define HIFN_1_DMA_CSR 0x40 /* DMA Status and Control */
  15685. +#define HIFN_1_DMA_IER 0x44 /* DMA Interrupt Enable */
  15686. +#define HIFN_1_DMA_CNFG 0x48 /* DMA Configuration */
  15687. +#define HIFN_1_PLL 0x4c /* 7955/7956: PLL config */
  15688. +#define HIFN_1_7811_RNGENA 0x60 /* 7811: rng enable */
  15689. +#define HIFN_1_7811_RNGCFG 0x64 /* 7811: rng config */
  15690. +#define HIFN_1_7811_RNGDAT 0x68 /* 7811: rng data */
  15691. +#define HIFN_1_7811_RNGSTS 0x6c /* 7811: rng status */
  15692. +#define HIFN_1_DMA_CNFG2 0x6c /* 7955/7956: dma config #2 */
  15693. +#define HIFN_1_7811_MIPSRST 0x94 /* 7811: MIPS reset */
  15694. +#define HIFN_1_REVID 0x98 /* Revision ID */
  15695. +
  15696. +#define HIFN_1_PUB_RESET 0x204 /* Public/RNG Reset */
  15697. +#define HIFN_1_PUB_BASE 0x300 /* Public Base Address */
  15698. +#define HIFN_1_PUB_OPLEN 0x304 /* 7951-compat Public Operand Length */
  15699. +#define HIFN_1_PUB_OP 0x308 /* 7951-compat Public Operand */
  15700. +#define HIFN_1_PUB_STATUS 0x30c /* 7951-compat Public Status */
  15701. +#define HIFN_1_PUB_IEN 0x310 /* Public Interrupt enable */
  15702. +#define HIFN_1_RNG_CONFIG 0x314 /* RNG config */
  15703. +#define HIFN_1_RNG_DATA 0x318 /* RNG data */
  15704. +#define HIFN_1_PUB_MODE 0x320 /* PK mode */
  15705. +#define HIFN_1_PUB_FIFO_OPLEN 0x380 /* first element of oplen fifo */
  15706. +#define HIFN_1_PUB_FIFO_OP 0x384 /* first element of op fifo */
  15707. +#define HIFN_1_PUB_MEM 0x400 /* start of Public key memory */
  15708. +#define HIFN_1_PUB_MEMEND 0xbff /* end of Public key memory */
  15709. +
  15710. +/* DMA Status and Control Register (HIFN_1_DMA_CSR) */
  15711. +#define HIFN_DMACSR_D_CTRLMASK 0xc0000000 /* Destinition Ring Control */
  15712. +#define HIFN_DMACSR_D_CTRL_NOP 0x00000000 /* Dest. Control: no-op */
  15713. +#define HIFN_DMACSR_D_CTRL_DIS 0x40000000 /* Dest. Control: disable */
  15714. +#define HIFN_DMACSR_D_CTRL_ENA 0x80000000 /* Dest. Control: enable */
  15715. +#define HIFN_DMACSR_D_ABORT 0x20000000 /* Destinition Ring PCIAbort */
  15716. +#define HIFN_DMACSR_D_DONE 0x10000000 /* Destinition Ring Done */
  15717. +#define HIFN_DMACSR_D_LAST 0x08000000 /* Destinition Ring Last */
  15718. +#define HIFN_DMACSR_D_WAIT 0x04000000 /* Destinition Ring Waiting */
  15719. +#define HIFN_DMACSR_D_OVER 0x02000000 /* Destinition Ring Overflow */
  15720. +#define HIFN_DMACSR_R_CTRL 0x00c00000 /* Result Ring Control */
  15721. +#define HIFN_DMACSR_R_CTRL_NOP 0x00000000 /* Result Control: no-op */
  15722. +#define HIFN_DMACSR_R_CTRL_DIS 0x00400000 /* Result Control: disable */
  15723. +#define HIFN_DMACSR_R_CTRL_ENA 0x00800000 /* Result Control: enable */
  15724. +#define HIFN_DMACSR_R_ABORT 0x00200000 /* Result Ring PCI Abort */
  15725. +#define HIFN_DMACSR_R_DONE 0x00100000 /* Result Ring Done */
  15726. +#define HIFN_DMACSR_R_LAST 0x00080000 /* Result Ring Last */
  15727. +#define HIFN_DMACSR_R_WAIT 0x00040000 /* Result Ring Waiting */
  15728. +#define HIFN_DMACSR_R_OVER 0x00020000 /* Result Ring Overflow */
  15729. +#define HIFN_DMACSR_S_CTRL 0x0000c000 /* Source Ring Control */
  15730. +#define HIFN_DMACSR_S_CTRL_NOP 0x00000000 /* Source Control: no-op */
  15731. +#define HIFN_DMACSR_S_CTRL_DIS 0x00004000 /* Source Control: disable */
  15732. +#define HIFN_DMACSR_S_CTRL_ENA 0x00008000 /* Source Control: enable */
  15733. +#define HIFN_DMACSR_S_ABORT 0x00002000 /* Source Ring PCI Abort */
  15734. +#define HIFN_DMACSR_S_DONE 0x00001000 /* Source Ring Done */
  15735. +#define HIFN_DMACSR_S_LAST 0x00000800 /* Source Ring Last */
  15736. +#define HIFN_DMACSR_S_WAIT 0x00000400 /* Source Ring Waiting */
  15737. +#define HIFN_DMACSR_ILLW 0x00000200 /* Illegal write (7811 only) */
  15738. +#define HIFN_DMACSR_ILLR 0x00000100 /* Illegal read (7811 only) */
  15739. +#define HIFN_DMACSR_C_CTRL 0x000000c0 /* Command Ring Control */
  15740. +#define HIFN_DMACSR_C_CTRL_NOP 0x00000000 /* Command Control: no-op */
  15741. +#define HIFN_DMACSR_C_CTRL_DIS 0x00000040 /* Command Control: disable */
  15742. +#define HIFN_DMACSR_C_CTRL_ENA 0x00000080 /* Command Control: enable */
  15743. +#define HIFN_DMACSR_C_ABORT 0x00000020 /* Command Ring PCI Abort */
  15744. +#define HIFN_DMACSR_C_DONE 0x00000010 /* Command Ring Done */
  15745. +#define HIFN_DMACSR_C_LAST 0x00000008 /* Command Ring Last */
  15746. +#define HIFN_DMACSR_C_WAIT 0x00000004 /* Command Ring Waiting */
  15747. +#define HIFN_DMACSR_PUBDONE 0x00000002 /* Public op done (7951 only) */
  15748. +#define HIFN_DMACSR_ENGINE 0x00000001 /* Command Ring Engine IRQ */
  15749. +
  15750. +/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */
  15751. +#define HIFN_DMAIER_D_ABORT 0x20000000 /* Destination Ring PCIAbort */
  15752. +#define HIFN_DMAIER_D_DONE 0x10000000 /* Destination Ring Done */
  15753. +#define HIFN_DMAIER_D_LAST 0x08000000 /* Destination Ring Last */
  15754. +#define HIFN_DMAIER_D_WAIT 0x04000000 /* Destination Ring Waiting */
  15755. +#define HIFN_DMAIER_D_OVER 0x02000000 /* Destination Ring Overflow */
  15756. +#define HIFN_DMAIER_R_ABORT 0x00200000 /* Result Ring PCI Abort */
  15757. +#define HIFN_DMAIER_R_DONE 0x00100000 /* Result Ring Done */
  15758. +#define HIFN_DMAIER_R_LAST 0x00080000 /* Result Ring Last */
  15759. +#define HIFN_DMAIER_R_WAIT 0x00040000 /* Result Ring Waiting */
  15760. +#define HIFN_DMAIER_R_OVER 0x00020000 /* Result Ring Overflow */
  15761. +#define HIFN_DMAIER_S_ABORT 0x00002000 /* Source Ring PCI Abort */
  15762. +#define HIFN_DMAIER_S_DONE 0x00001000 /* Source Ring Done */
  15763. +#define HIFN_DMAIER_S_LAST 0x00000800 /* Source Ring Last */
  15764. +#define HIFN_DMAIER_S_WAIT 0x00000400 /* Source Ring Waiting */
  15765. +#define HIFN_DMAIER_ILLW 0x00000200 /* Illegal write (7811 only) */
  15766. +#define HIFN_DMAIER_ILLR 0x00000100 /* Illegal read (7811 only) */
  15767. +#define HIFN_DMAIER_C_ABORT 0x00000020 /* Command Ring PCI Abort */
  15768. +#define HIFN_DMAIER_C_DONE 0x00000010 /* Command Ring Done */
  15769. +#define HIFN_DMAIER_C_LAST 0x00000008 /* Command Ring Last */
  15770. +#define HIFN_DMAIER_C_WAIT 0x00000004 /* Command Ring Waiting */
  15771. +#define HIFN_DMAIER_PUBDONE 0x00000002 /* public op done (7951 only) */
  15772. +#define HIFN_DMAIER_ENGINE 0x00000001 /* Engine IRQ */
  15773. +
  15774. +/* DMA Configuration Register (HIFN_1_DMA_CNFG) */
  15775. +#define HIFN_DMACNFG_BIGENDIAN 0x10000000 /* big endian mode */
  15776. +#define HIFN_DMACNFG_POLLFREQ 0x00ff0000 /* Poll frequency mask */
  15777. +#define HIFN_DMACNFG_UNLOCK 0x00000800
  15778. +#define HIFN_DMACNFG_POLLINVAL 0x00000700 /* Invalid Poll Scalar */
  15779. +#define HIFN_DMACNFG_LAST 0x00000010 /* Host control LAST bit */
  15780. +#define HIFN_DMACNFG_MODE 0x00000004 /* DMA mode */
  15781. +#define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */
  15782. +#define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */
  15783. +
  15784. +/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */
  15785. +#define HIFN_DMACNFG2_PKSWAP32 (1 << 19) /* swap the OPLEN/OP reg */
  15786. +#define HIFN_DMACNFG2_PKSWAP8 (1 << 18) /* swap the bits of OPLEN/OP */
  15787. +#define HIFN_DMACNFG2_BAR0_SWAP32 (1<<17) /* swap the bytes of BAR0 */
  15788. +#define HIFN_DMACNFG2_BAR1_SWAP8 (1<<16) /* swap the bits of BAR0 */
  15789. +#define HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12
  15790. +#define HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8
  15791. +#define HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4
  15792. +#define HIFN_DMACNFG2_TGT_READ_BURST_SHIFT 0
  15793. +
  15794. +/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */
  15795. +#define HIFN_7811_RNGENA_ENA 0x00000001 /* enable RNG */
  15796. +
  15797. +/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */
  15798. +#define HIFN_7811_RNGCFG_PRE1 0x00000f00 /* first prescalar */
  15799. +#define HIFN_7811_RNGCFG_OPRE 0x00000080 /* output prescalar */
  15800. +#define HIFN_7811_RNGCFG_DEFL 0x00000f80 /* 2 words/ 1/100 sec */
  15801. +
  15802. +/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */
  15803. +#define HIFN_7811_RNGSTS_RDY 0x00004000 /* two numbers in FIFO */
  15804. +#define HIFN_7811_RNGSTS_UFL 0x00001000 /* rng underflow */
  15805. +
  15806. +/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */
  15807. +#define HIFN_MIPSRST_BAR2SIZE 0xffff0000 /* sdram size */
  15808. +#define HIFN_MIPSRST_GPRAMINIT 0x00008000 /* gpram can be accessed */
  15809. +#define HIFN_MIPSRST_CRAMINIT 0x00004000 /* ctxram can be accessed */
  15810. +#define HIFN_MIPSRST_LED2 0x00000400 /* external LED2 */
  15811. +#define HIFN_MIPSRST_LED1 0x00000200 /* external LED1 */
  15812. +#define HIFN_MIPSRST_LED0 0x00000100 /* external LED0 */
  15813. +#define HIFN_MIPSRST_MIPSDIS 0x00000004 /* disable MIPS */
  15814. +#define HIFN_MIPSRST_MIPSRST 0x00000002 /* warm reset MIPS */
  15815. +#define HIFN_MIPSRST_MIPSCOLD 0x00000001 /* cold reset MIPS */
  15816. +
  15817. +/* Public key reset register (HIFN_1_PUB_RESET) */
  15818. +#define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */
  15819. +
  15820. +/* Public operation register (HIFN_1_PUB_OP) */
  15821. +#define HIFN_PUBOP_AOFFSET 0x0000003e /* A offset */
  15822. +#define HIFN_PUBOP_BOFFSET 0x00000fc0 /* B offset */
  15823. +#define HIFN_PUBOP_MOFFSET 0x0003f000 /* M offset */
  15824. +#define HIFN_PUBOP_OP_MASK 0x003c0000 /* Opcode: */
  15825. +#define HIFN_PUBOP_OP_NOP 0x00000000 /* NOP */
  15826. +#define HIFN_PUBOP_OP_ADD 0x00040000 /* ADD */
  15827. +#define HIFN_PUBOP_OP_ADDC 0x00080000 /* ADD w/carry */
  15828. +#define HIFN_PUBOP_OP_SUB 0x000c0000 /* SUB */
  15829. +#define HIFN_PUBOP_OP_SUBC 0x00100000 /* SUB w/carry */
  15830. +#define HIFN_PUBOP_OP_MODADD 0x00140000 /* Modular ADD */
  15831. +#define HIFN_PUBOP_OP_MODSUB 0x00180000 /* Modular SUB */
  15832. +#define HIFN_PUBOP_OP_INCA 0x001c0000 /* INC A */
  15833. +#define HIFN_PUBOP_OP_DECA 0x00200000 /* DEC A */
  15834. +#define HIFN_PUBOP_OP_MULT 0x00240000 /* MULT */
  15835. +#define HIFN_PUBOP_OP_MODMULT 0x00280000 /* Modular MULT */
  15836. +#define HIFN_PUBOP_OP_MODRED 0x002c0000 /* Modular Red */
  15837. +#define HIFN_PUBOP_OP_MODEXP 0x00300000 /* Modular Exp */
  15838. +
  15839. +/* Public operand length register (HIFN_1_PUB_OPLEN) */
  15840. +#define HIFN_PUBOPLEN_MODLEN 0x0000007f
  15841. +#define HIFN_PUBOPLEN_EXPLEN 0x0003ff80
  15842. +#define HIFN_PUBOPLEN_REDLEN 0x003c0000
  15843. +
  15844. +/* Public status register (HIFN_1_PUB_STATUS) */
  15845. +#define HIFN_PUBSTS_DONE 0x00000001 /* operation done */
  15846. +#define HIFN_PUBSTS_CARRY 0x00000002 /* carry */
  15847. +#define HIFN_PUBSTS_FIFO_EMPTY 0x00000100 /* fifo empty */
  15848. +#define HIFN_PUBSTS_FIFO_FULL 0x00000200 /* fifo full */
  15849. +#define HIFN_PUBSTS_FIFO_OVFL 0x00000400 /* fifo overflow */
  15850. +#define HIFN_PUBSTS_FIFO_WRITE 0x000f0000 /* fifo write */
  15851. +#define HIFN_PUBSTS_FIFO_READ 0x0f000000 /* fifo read */
  15852. +
  15853. +/* Public interrupt enable register (HIFN_1_PUB_IEN) */
  15854. +#define HIFN_PUBIEN_DONE 0x00000001 /* operation done interrupt */
  15855. +
  15856. +/* Random number generator config register (HIFN_1_RNG_CONFIG) */
  15857. +#define HIFN_RNGCFG_ENA 0x00000001 /* enable rng */
  15858. +
  15859. +/*
  15860. + * Register offsets in register set 1
  15861. + */
  15862. +
  15863. +#define HIFN_UNLOCK_SECRET1 0xf4
  15864. +#define HIFN_UNLOCK_SECRET2 0xfc
  15865. +
  15866. +/*
  15867. + * PLL config register
  15868. + *
  15869. + * This register is present only on 7954/7955/7956 parts. It must be
  15870. + * programmed according to the bus interface method used by the h/w.
  15871. + * Note that the parts require a stable clock. Since the PCI clock
  15872. + * may vary the reference clock must usually be used. To avoid
  15873. + * overclocking the core logic, setup must be done carefully, refer
  15874. + * to the driver for details. The exact multiplier required varies
  15875. + * by part and system configuration; refer to the Hifn documentation.
  15876. + */
  15877. +#define HIFN_PLL_REF_SEL 0x00000001 /* REF/HBI clk selection */
  15878. +#define HIFN_PLL_BP 0x00000002 /* bypass (used during setup) */
  15879. +/* bit 2 reserved */
  15880. +#define HIFN_PLL_PK_CLK_SEL 0x00000008 /* public key clk select */
  15881. +#define HIFN_PLL_PE_CLK_SEL 0x00000010 /* packet engine clk select */
  15882. +/* bits 5-9 reserved */
  15883. +#define HIFN_PLL_MBSET 0x00000400 /* must be set to 1 */
  15884. +#define HIFN_PLL_ND 0x00003800 /* Fpll_ref multiplier select */
  15885. +#define HIFN_PLL_ND_SHIFT 11
  15886. +#define HIFN_PLL_ND_2 0x00000000 /* 2x */
  15887. +#define HIFN_PLL_ND_4 0x00000800 /* 4x */
  15888. +#define HIFN_PLL_ND_6 0x00001000 /* 6x */
  15889. +#define HIFN_PLL_ND_8 0x00001800 /* 8x */
  15890. +#define HIFN_PLL_ND_10 0x00002000 /* 10x */
  15891. +#define HIFN_PLL_ND_12 0x00002800 /* 12x */
  15892. +/* bits 14-15 reserved */
  15893. +#define HIFN_PLL_IS 0x00010000 /* charge pump current select */
  15894. +/* bits 17-31 reserved */
  15895. +
  15896. +/*
  15897. + * Board configuration specifies only these bits.
  15898. + */
  15899. +#define HIFN_PLL_CONFIG (HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL)
  15900. +
  15901. +/*
  15902. + * Public Key Engine Mode Register
  15903. + */
  15904. +#define HIFN_PKMODE_HOSTINVERT (1 << 0) /* HOST INVERT */
  15905. +#define HIFN_PKMODE_ENHANCED (1 << 1) /* Enable enhanced mode */
  15906. +
  15907. +
  15908. +/*********************************************************************
  15909. + * Structs for board commands
  15910. + *
  15911. + *********************************************************************/
  15912. +
  15913. +/*
  15914. + * Structure to help build up the command data structure.
  15915. + */
  15916. +typedef struct hifn_base_command {
  15917. + volatile u_int16_t masks;
  15918. + volatile u_int16_t session_num;
  15919. + volatile u_int16_t total_source_count;
  15920. + volatile u_int16_t total_dest_count;
  15921. +} hifn_base_command_t;
  15922. +
  15923. +#define HIFN_BASE_CMD_MAC 0x0400
  15924. +#define HIFN_BASE_CMD_CRYPT 0x0800
  15925. +#define HIFN_BASE_CMD_DECODE 0x2000
  15926. +#define HIFN_BASE_CMD_SRCLEN_M 0xc000
  15927. +#define HIFN_BASE_CMD_SRCLEN_S 14
  15928. +#define HIFN_BASE_CMD_DSTLEN_M 0x3000
  15929. +#define HIFN_BASE_CMD_DSTLEN_S 12
  15930. +#define HIFN_BASE_CMD_LENMASK_HI 0x30000
  15931. +#define HIFN_BASE_CMD_LENMASK_LO 0x0ffff
  15932. +
  15933. +/*
  15934. + * Structure to help build up the command data structure.
  15935. + */
  15936. +typedef struct hifn_crypt_command {
  15937. + volatile u_int16_t masks;
  15938. + volatile u_int16_t header_skip;
  15939. + volatile u_int16_t source_count;
  15940. + volatile u_int16_t reserved;
  15941. +} hifn_crypt_command_t;
  15942. +
  15943. +#define HIFN_CRYPT_CMD_ALG_MASK 0x0003 /* algorithm: */
  15944. +#define HIFN_CRYPT_CMD_ALG_DES 0x0000 /* DES */
  15945. +#define HIFN_CRYPT_CMD_ALG_3DES 0x0001 /* 3DES */
  15946. +#define HIFN_CRYPT_CMD_ALG_RC4 0x0002 /* RC4 */
  15947. +#define HIFN_CRYPT_CMD_ALG_AES 0x0003 /* AES */
  15948. +#define HIFN_CRYPT_CMD_MODE_MASK 0x0018 /* Encrypt mode: */
  15949. +#define HIFN_CRYPT_CMD_MODE_ECB 0x0000 /* ECB */
  15950. +#define HIFN_CRYPT_CMD_MODE_CBC 0x0008 /* CBC */
  15951. +#define HIFN_CRYPT_CMD_MODE_CFB 0x0010 /* CFB */
  15952. +#define HIFN_CRYPT_CMD_MODE_OFB 0x0018 /* OFB */
  15953. +#define HIFN_CRYPT_CMD_CLR_CTX 0x0040 /* clear context */
  15954. +#define HIFN_CRYPT_CMD_NEW_KEY 0x0800 /* expect new key */
  15955. +#define HIFN_CRYPT_CMD_NEW_IV 0x1000 /* expect new iv */
  15956. +
  15957. +#define HIFN_CRYPT_CMD_SRCLEN_M 0xc000
  15958. +#define HIFN_CRYPT_CMD_SRCLEN_S 14
  15959. +
  15960. +#define HIFN_CRYPT_CMD_KSZ_MASK 0x0600 /* AES key size: */
  15961. +#define HIFN_CRYPT_CMD_KSZ_128 0x0000 /* 128 bit */
  15962. +#define HIFN_CRYPT_CMD_KSZ_192 0x0200 /* 192 bit */
  15963. +#define HIFN_CRYPT_CMD_KSZ_256 0x0400 /* 256 bit */
  15964. +
  15965. +/*
  15966. + * Structure to help build up the command data structure.
  15967. + */
  15968. +typedef struct hifn_mac_command {
  15969. + volatile u_int16_t masks;
  15970. + volatile u_int16_t header_skip;
  15971. + volatile u_int16_t source_count;
  15972. + volatile u_int16_t reserved;
  15973. +} hifn_mac_command_t;
  15974. +
  15975. +#define HIFN_MAC_CMD_ALG_MASK 0x0001
  15976. +#define HIFN_MAC_CMD_ALG_SHA1 0x0000
  15977. +#define HIFN_MAC_CMD_ALG_MD5 0x0001
  15978. +#define HIFN_MAC_CMD_MODE_MASK 0x000c
  15979. +#define HIFN_MAC_CMD_MODE_HMAC 0x0000
  15980. +#define HIFN_MAC_CMD_MODE_SSL_MAC 0x0004
  15981. +#define HIFN_MAC_CMD_MODE_HASH 0x0008
  15982. +#define HIFN_MAC_CMD_MODE_FULL 0x0004
  15983. +#define HIFN_MAC_CMD_TRUNC 0x0010
  15984. +#define HIFN_MAC_CMD_RESULT 0x0020
  15985. +#define HIFN_MAC_CMD_APPEND 0x0040
  15986. +#define HIFN_MAC_CMD_SRCLEN_M 0xc000
  15987. +#define HIFN_MAC_CMD_SRCLEN_S 14
  15988. +
  15989. +/*
  15990. + * MAC POS IPsec initiates authentication after encryption on encodes
  15991. + * and before decryption on decodes.
  15992. + */
  15993. +#define HIFN_MAC_CMD_POS_IPSEC 0x0200
  15994. +#define HIFN_MAC_CMD_NEW_KEY 0x0800
  15995. +
  15996. +/*
  15997. + * The poll frequency and poll scalar defines are unshifted values used
  15998. + * to set fields in the DMA Configuration Register.
  15999. + */
  16000. +#ifndef HIFN_POLL_FREQUENCY
  16001. +#define HIFN_POLL_FREQUENCY 0x1
  16002. +#endif
  16003. +
  16004. +#ifndef HIFN_POLL_SCALAR
  16005. +#define HIFN_POLL_SCALAR 0x0
  16006. +#endif
  16007. +
  16008. +#define HIFN_MAX_SEGLEN 0xffff /* maximum dma segment len */
  16009. +#define HIFN_MAX_DMALEN 0x3ffff /* maximum dma length */
  16010. +#endif /* __HIFN_H__ */
  16011. diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifn7751var.h linux-2.6.36/crypto/ocf/hifn/hifn7751var.h
  16012. --- linux-2.6.36.orig/crypto/ocf/hifn/hifn7751var.h 1970-01-01 01:00:00.000000000 +0100
  16013. +++ linux-2.6.36/crypto/ocf/hifn/hifn7751var.h 2010-11-09 20:28:04.832495385 +0100
  16014. @@ -0,0 +1,369 @@
  16015. +/* $FreeBSD: src/sys/dev/hifn/hifn7751var.h,v 1.9 2007/03/21 03:42:49 sam Exp $ */
  16016. +/* $OpenBSD: hifn7751var.h,v 1.42 2002/04/08 17:49:42 jason Exp $ */
  16017. +
  16018. +/*-
  16019. + * Invertex AEON / Hifn 7751 driver
  16020. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  16021. + * Copyright (c) 1999 Theo de Raadt
  16022. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  16023. + * http://www.netsec.net
  16024. + *
  16025. + * Please send any comments, feedback, bug-fixes, or feature requests to
  16026. + * software@invertex.com.
  16027. + *
  16028. + * Redistribution and use in source and binary forms, with or without
  16029. + * modification, are permitted provided that the following conditions
  16030. + * are met:
  16031. + *
  16032. + * 1. Redistributions of source code must retain the above copyright
  16033. + * notice, this list of conditions and the following disclaimer.
  16034. + * 2. Redistributions in binary form must reproduce the above copyright
  16035. + * notice, this list of conditions and the following disclaimer in the
  16036. + * documentation and/or other materials provided with the distribution.
  16037. + * 3. The name of the author may not be used to endorse or promote products
  16038. + * derived from this software without specific prior written permission.
  16039. + *
  16040. + *
  16041. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16042. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16043. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16044. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  16045. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  16046. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  16047. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  16048. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  16049. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  16050. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16051. + *
  16052. + * Effort sponsored in part by the Defense Advanced Research Projects
  16053. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  16054. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  16055. + *
  16056. + */
  16057. +
  16058. +#ifndef __HIFN7751VAR_H__
  16059. +#define __HIFN7751VAR_H__
  16060. +
  16061. +#ifdef __KERNEL__
  16062. +
  16063. +/*
  16064. + * Some configurable values for the driver. By default command+result
  16065. + * descriptor rings are the same size. The src+dst descriptor rings
  16066. + * are sized at 3.5x the number of potential commands. Slower parts
  16067. + * (e.g. 7951) tend to run out of src descriptors; faster parts (7811)
  16068. + * src+cmd/result descriptors. It's not clear that increasing the size
  16069. + * of the descriptor rings helps performance significantly as other
  16070. + * factors tend to come into play (e.g. copying misaligned packets).
  16071. + */
  16072. +#define HIFN_D_CMD_RSIZE 24 /* command descriptors */
  16073. +#define HIFN_D_SRC_RSIZE ((HIFN_D_CMD_RSIZE * 7) / 2) /* source descriptors */
  16074. +#define HIFN_D_RES_RSIZE HIFN_D_CMD_RSIZE /* result descriptors */
  16075. +#define HIFN_D_DST_RSIZE HIFN_D_SRC_RSIZE /* destination descriptors */
  16076. +
  16077. +/*
  16078. + * Length values for cryptography
  16079. + */
  16080. +#define HIFN_DES_KEY_LENGTH 8
  16081. +#define HIFN_3DES_KEY_LENGTH 24
  16082. +#define HIFN_MAX_CRYPT_KEY_LENGTH HIFN_3DES_KEY_LENGTH
  16083. +#define HIFN_IV_LENGTH 8
  16084. +#define HIFN_AES_IV_LENGTH 16
  16085. +#define HIFN_MAX_IV_LENGTH HIFN_AES_IV_LENGTH
  16086. +
  16087. +/*
  16088. + * Length values for authentication
  16089. + */
  16090. +#define HIFN_MAC_KEY_LENGTH 64
  16091. +#define HIFN_MD5_LENGTH 16
  16092. +#define HIFN_SHA1_LENGTH 20
  16093. +#define HIFN_MAC_TRUNC_LENGTH 12
  16094. +
  16095. +#define MAX_SCATTER 64
  16096. +
  16097. +/*
  16098. + * Data structure to hold all 4 rings and any other ring related data.
  16099. + */
  16100. +struct hifn_dma {
  16101. + /*
  16102. + * Descriptor rings. We add +1 to the size to accomidate the
  16103. + * jump descriptor.
  16104. + */
  16105. + struct hifn_desc cmdr[HIFN_D_CMD_RSIZE+1];
  16106. + struct hifn_desc srcr[HIFN_D_SRC_RSIZE+1];
  16107. + struct hifn_desc dstr[HIFN_D_DST_RSIZE+1];
  16108. + struct hifn_desc resr[HIFN_D_RES_RSIZE+1];
  16109. +
  16110. + struct hifn_command *hifn_commands[HIFN_D_RES_RSIZE];
  16111. +
  16112. + u_char command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];
  16113. + u_char result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];
  16114. + u_int32_t slop[HIFN_D_CMD_RSIZE];
  16115. +
  16116. + u_int64_t test_src, test_dst;
  16117. +
  16118. + /*
  16119. + * Our current positions for insertion and removal from the desriptor
  16120. + * rings.
  16121. + */
  16122. + int cmdi, srci, dsti, resi;
  16123. + volatile int cmdu, srcu, dstu, resu;
  16124. + int cmdk, srck, dstk, resk;
  16125. +};
  16126. +
  16127. +struct hifn_session {
  16128. + int hs_used;
  16129. + int hs_mlen;
  16130. + u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
  16131. +};
  16132. +
  16133. +#define HIFN_RING_SYNC(sc, r, i, f) \
  16134. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  16135. +
  16136. +#define HIFN_CMDR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), cmdr, (i), (f))
  16137. +#define HIFN_RESR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), resr, (i), (f))
  16138. +#define HIFN_SRCR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), srcr, (i), (f))
  16139. +#define HIFN_DSTR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), dstr, (i), (f))
  16140. +
  16141. +#define HIFN_CMD_SYNC(sc, i, f) \
  16142. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  16143. +
  16144. +#define HIFN_RES_SYNC(sc, i, f) \
  16145. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  16146. +
  16147. +typedef int bus_size_t;
  16148. +
  16149. +/*
  16150. + * Holds data specific to a single HIFN board.
  16151. + */
  16152. +struct hifn_softc {
  16153. + softc_device_decl sc_dev;
  16154. +
  16155. + struct pci_dev *sc_pcidev; /* PCI device pointer */
  16156. + spinlock_t sc_mtx; /* per-instance lock */
  16157. +
  16158. + int sc_num; /* for multiple devs */
  16159. +
  16160. + ocf_iomem_t sc_bar0;
  16161. + bus_size_t sc_bar0_lastreg;/* bar0 last reg written */
  16162. + ocf_iomem_t sc_bar1;
  16163. + bus_size_t sc_bar1_lastreg;/* bar1 last reg written */
  16164. +
  16165. + int sc_irq;
  16166. +
  16167. + u_int32_t sc_dmaier;
  16168. + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
  16169. + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
  16170. +
  16171. + struct hifn_dma *sc_dma;
  16172. + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
  16173. +
  16174. + int sc_dmansegs;
  16175. + int32_t sc_cid;
  16176. + int sc_maxses;
  16177. + int sc_nsessions;
  16178. + struct hifn_session *sc_sessions;
  16179. + int sc_ramsize;
  16180. + int sc_flags;
  16181. +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
  16182. +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
  16183. +#define HIFN_HAS_AES 0x4 /* includes AES support */
  16184. +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
  16185. +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
  16186. +
  16187. + struct timer_list sc_tickto; /* for managing DMA */
  16188. +
  16189. + int sc_rngfirst;
  16190. + int sc_rnghz; /* RNG polling frequency */
  16191. +
  16192. + int sc_c_busy; /* command ring busy */
  16193. + int sc_s_busy; /* source data ring busy */
  16194. + int sc_d_busy; /* destination data ring busy */
  16195. + int sc_r_busy; /* result ring busy */
  16196. + int sc_active; /* for initial countdown */
  16197. + int sc_needwakeup; /* ops q'd wating on resources */
  16198. + int sc_curbatch; /* # ops submitted w/o int */
  16199. + int sc_suspended;
  16200. +#ifdef HIFN_VULCANDEV
  16201. + struct cdev *sc_pkdev;
  16202. +#endif
  16203. +};
  16204. +
  16205. +#define HIFN_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
  16206. +#define HIFN_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
  16207. +
  16208. +/*
  16209. + * hifn_command_t
  16210. + *
  16211. + * This is the control structure used to pass commands to hifn_encrypt().
  16212. + *
  16213. + * flags
  16214. + * -----
  16215. + * Flags is the bitwise "or" values for command configuration. A single
  16216. + * encrypt direction needs to be set:
  16217. + *
  16218. + * HIFN_ENCODE or HIFN_DECODE
  16219. + *
  16220. + * To use cryptography, a single crypto algorithm must be included:
  16221. + *
  16222. + * HIFN_CRYPT_3DES or HIFN_CRYPT_DES
  16223. + *
  16224. + * To use authentication is used, a single MAC algorithm must be included:
  16225. + *
  16226. + * HIFN_MAC_MD5 or HIFN_MAC_SHA1
  16227. + *
  16228. + * By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash.
  16229. + * If the value below is set, hash values are truncated or assumed
  16230. + * truncated to 12 bytes:
  16231. + *
  16232. + * HIFN_MAC_TRUNC
  16233. + *
  16234. + * Keys for encryption and authentication can be sent as part of a command,
  16235. + * or the last key value used with a particular session can be retrieved
  16236. + * and used again if either of these flags are not specified.
  16237. + *
  16238. + * HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY
  16239. + *
  16240. + * session_num
  16241. + * -----------
  16242. + * A number between 0 and 2048 (for DRAM models) or a number between
  16243. + * 0 and 768 (for SRAM models). Those who don't want to use session
  16244. + * numbers should leave value at zero and send a new crypt key and/or
  16245. + * new MAC key on every command. If you use session numbers and
  16246. + * don't send a key with a command, the last key sent for that same
  16247. + * session number will be used.
  16248. + *
  16249. + * Warning: Using session numbers and multiboard at the same time
  16250. + * is currently broken.
  16251. + *
  16252. + * mbuf
  16253. + * ----
  16254. + * Either fill in the mbuf pointer and npa=0 or
  16255. + * fill packp[] and packl[] and set npa to > 0
  16256. + *
  16257. + * mac_header_skip
  16258. + * ---------------
  16259. + * The number of bytes of the source_buf that are skipped over before
  16260. + * authentication begins. This must be a number between 0 and 2^16-1
  16261. + * and can be used by IPsec implementers to skip over IP headers.
  16262. + * *** Value ignored if authentication not used ***
  16263. + *
  16264. + * crypt_header_skip
  16265. + * -----------------
  16266. + * The number of bytes of the source_buf that are skipped over before
  16267. + * the cryptographic operation begins. This must be a number between 0
  16268. + * and 2^16-1. For IPsec, this number will always be 8 bytes larger
  16269. + * than the auth_header_skip (to skip over the ESP header).
  16270. + * *** Value ignored if cryptography not used ***
  16271. + *
  16272. + */
  16273. +struct hifn_operand {
  16274. + union {
  16275. + struct sk_buff *skb;
  16276. + struct uio *io;
  16277. + unsigned char *buf;
  16278. + } u;
  16279. + void *map;
  16280. + bus_size_t mapsize;
  16281. + int nsegs;
  16282. + struct {
  16283. + dma_addr_t ds_addr;
  16284. + int ds_len;
  16285. + } segs[MAX_SCATTER];
  16286. +};
  16287. +
  16288. +struct hifn_command {
  16289. + u_int16_t session_num;
  16290. + u_int16_t base_masks, cry_masks, mac_masks;
  16291. + u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];
  16292. + int cklen;
  16293. + int sloplen, slopidx;
  16294. +
  16295. + struct hifn_operand src;
  16296. + struct hifn_operand dst;
  16297. +
  16298. + struct hifn_softc *softc;
  16299. + struct cryptop *crp;
  16300. + struct cryptodesc *enccrd, *maccrd;
  16301. +};
  16302. +
  16303. +#define src_skb src.u.skb
  16304. +#define src_io src.u.io
  16305. +#define src_map src.map
  16306. +#define src_mapsize src.mapsize
  16307. +#define src_segs src.segs
  16308. +#define src_nsegs src.nsegs
  16309. +#define src_buf src.u.buf
  16310. +
  16311. +#define dst_skb dst.u.skb
  16312. +#define dst_io dst.u.io
  16313. +#define dst_map dst.map
  16314. +#define dst_mapsize dst.mapsize
  16315. +#define dst_segs dst.segs
  16316. +#define dst_nsegs dst.nsegs
  16317. +#define dst_buf dst.u.buf
  16318. +
  16319. +/*
  16320. + * Return values for hifn_crypto()
  16321. + */
  16322. +#define HIFN_CRYPTO_SUCCESS 0
  16323. +#define HIFN_CRYPTO_BAD_INPUT (-1)
  16324. +#define HIFN_CRYPTO_RINGS_FULL (-2)
  16325. +
  16326. +/**************************************************************************
  16327. + *
  16328. + * Function: hifn_crypto
  16329. + *
  16330. + * Purpose: Called by external drivers to begin an encryption on the
  16331. + * HIFN board.
  16332. + *
  16333. + * Blocking/Non-blocking Issues
  16334. + * ============================
  16335. + * The driver cannot block in hifn_crypto (no calls to tsleep) currently.
  16336. + * hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough
  16337. + * room in any of the rings for the request to proceed.
  16338. + *
  16339. + * Return Values
  16340. + * =============
  16341. + * 0 for success, negative values on error
  16342. + *
  16343. + * Defines for negative error codes are:
  16344. + *
  16345. + * HIFN_CRYPTO_BAD_INPUT : The passed in command had invalid settings.
  16346. + * HIFN_CRYPTO_RINGS_FULL : All DMA rings were full and non-blocking
  16347. + * behaviour was requested.
  16348. + *
  16349. + *************************************************************************/
  16350. +
  16351. +/*
  16352. + * Convert back and forth from 'sid' to 'card' and 'session'
  16353. + */
  16354. +#define HIFN_CARD(sid) (((sid) & 0xf0000000) >> 28)
  16355. +#define HIFN_SESSION(sid) ((sid) & 0x000007ff)
  16356. +#define HIFN_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
  16357. +
  16358. +#endif /* _KERNEL */
  16359. +
  16360. +struct hifn_stats {
  16361. + u_int64_t hst_ibytes;
  16362. + u_int64_t hst_obytes;
  16363. + u_int32_t hst_ipackets;
  16364. + u_int32_t hst_opackets;
  16365. + u_int32_t hst_invalid;
  16366. + u_int32_t hst_nomem; /* malloc or one of hst_nomem_* */
  16367. + u_int32_t hst_abort;
  16368. + u_int32_t hst_noirq; /* IRQ for no reason */
  16369. + u_int32_t hst_totbatch; /* ops submitted w/o interrupt */
  16370. + u_int32_t hst_maxbatch; /* max ops submitted together */
  16371. + u_int32_t hst_unaligned; /* unaligned src caused copy */
  16372. + /*
  16373. + * The following divides hst_nomem into more specific buckets.
  16374. + */
  16375. + u_int32_t hst_nomem_map; /* bus_dmamap_create failed */
  16376. + u_int32_t hst_nomem_load; /* bus_dmamap_load_* failed */
  16377. + u_int32_t hst_nomem_mbuf; /* MGET* failed */
  16378. + u_int32_t hst_nomem_mcl; /* MCLGET* failed */
  16379. + u_int32_t hst_nomem_cr; /* out of command/result descriptor */
  16380. + u_int32_t hst_nomem_sd; /* out of src/dst descriptors */
  16381. +};
  16382. +
  16383. +#endif /* __HIFN7751VAR_H__ */
  16384. diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPP.c linux-2.6.36/crypto/ocf/hifn/hifnHIPP.c
  16385. --- linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPP.c 1970-01-01 01:00:00.000000000 +0100
  16386. +++ linux-2.6.36/crypto/ocf/hifn/hifnHIPP.c 2010-11-09 20:28:04.881244876 +0100
  16387. @@ -0,0 +1,420 @@
  16388. +/*-
  16389. + * Driver for Hifn HIPP-I/II chipset
  16390. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
  16391. + *
  16392. + * Redistribution and use in source and binary forms, with or without
  16393. + * modification, are permitted provided that the following conditions
  16394. + * are met:
  16395. + *
  16396. + * 1. Redistributions of source code must retain the above copyright
  16397. + * notice, this list of conditions and the following disclaimer.
  16398. + * 2. Redistributions in binary form must reproduce the above copyright
  16399. + * notice, this list of conditions and the following disclaimer in the
  16400. + * documentation and/or other materials provided with the distribution.
  16401. + * 3. The name of the author may not be used to endorse or promote products
  16402. + * derived from this software without specific prior written permission.
  16403. + *
  16404. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16405. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16406. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16407. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  16408. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  16409. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  16410. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  16411. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  16412. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  16413. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16414. + *
  16415. + * Effort sponsored by Hifn Inc.
  16416. + *
  16417. + */
  16418. +
  16419. +/*
  16420. + * Driver for various Hifn encryption processors.
  16421. + */
  16422. +#ifndef AUTOCONF_INCLUDED
  16423. +#include <linux/config.h>
  16424. +#endif
  16425. +#include <linux/module.h>
  16426. +#include <linux/init.h>
  16427. +#include <linux/list.h>
  16428. +#include <linux/slab.h>
  16429. +#include <linux/wait.h>
  16430. +#include <linux/sched.h>
  16431. +#include <linux/pci.h>
  16432. +#include <linux/delay.h>
  16433. +#include <linux/interrupt.h>
  16434. +#include <linux/spinlock.h>
  16435. +#include <linux/random.h>
  16436. +#include <linux/version.h>
  16437. +#include <linux/skbuff.h>
  16438. +#include <linux/uio.h>
  16439. +#include <linux/sysfs.h>
  16440. +#include <linux/miscdevice.h>
  16441. +#include <asm/io.h>
  16442. +
  16443. +#include <cryptodev.h>
  16444. +
  16445. +#include "hifnHIPPreg.h"
  16446. +#include "hifnHIPPvar.h"
  16447. +
  16448. +#if 1
  16449. +#define DPRINTF(a...) if (hipp_debug) { \
  16450. + printk("%s: ", sc ? \
  16451. + device_get_nameunit(sc->sc_dev) : "hifn"); \
  16452. + printk(a); \
  16453. + } else
  16454. +#else
  16455. +#define DPRINTF(a...)
  16456. +#endif
  16457. +
  16458. +typedef int bus_size_t;
  16459. +
  16460. +static inline int
  16461. +pci_get_revid(struct pci_dev *dev)
  16462. +{
  16463. + u8 rid = 0;
  16464. + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
  16465. + return rid;
  16466. +}
  16467. +
  16468. +#define debug hipp_debug
  16469. +int hipp_debug = 0;
  16470. +module_param(hipp_debug, int, 0644);
  16471. +MODULE_PARM_DESC(hipp_debug, "Enable debug");
  16472. +
  16473. +int hipp_maxbatch = 1;
  16474. +module_param(hipp_maxbatch, int, 0644);
  16475. +MODULE_PARM_DESC(hipp_maxbatch, "max ops to batch w/o interrupt");
  16476. +
  16477. +static int hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent);
  16478. +static void hipp_remove(struct pci_dev *dev);
  16479. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  16480. +static irqreturn_t hipp_intr(int irq, void *arg);
  16481. +#else
  16482. +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs);
  16483. +#endif
  16484. +
  16485. +static int hipp_num_chips = 0;
  16486. +static struct hipp_softc *hipp_chip_idx[HIPP_MAX_CHIPS];
  16487. +
  16488. +static int hipp_newsession(device_t, u_int32_t *, struct cryptoini *);
  16489. +static int hipp_freesession(device_t, u_int64_t);
  16490. +static int hipp_process(device_t, struct cryptop *, int);
  16491. +
  16492. +static device_method_t hipp_methods = {
  16493. + /* crypto device methods */
  16494. + DEVMETHOD(cryptodev_newsession, hipp_newsession),
  16495. + DEVMETHOD(cryptodev_freesession,hipp_freesession),
  16496. + DEVMETHOD(cryptodev_process, hipp_process),
  16497. +};
  16498. +
  16499. +static __inline u_int32_t
  16500. +READ_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg)
  16501. +{
  16502. + u_int32_t v = readl(sc->sc_bar[barno] + reg);
  16503. + //sc->sc_bar0_lastreg = (bus_size_t) -1;
  16504. + return (v);
  16505. +}
  16506. +static __inline void
  16507. +WRITE_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg, u_int32_t val)
  16508. +{
  16509. + writel(val, sc->sc_bar[barno] + reg);
  16510. +}
  16511. +
  16512. +#define READ_REG_0(sc, reg) READ_REG(sc, 0, reg)
  16513. +#define WRITE_REG_0(sc, reg, val) WRITE_REG(sc,0, reg, val)
  16514. +#define READ_REG_1(sc, reg) READ_REG(sc, 1, reg)
  16515. +#define WRITE_REG_1(sc, reg, val) WRITE_REG(sc,1, reg, val)
  16516. +
  16517. +static int
  16518. +hipp_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  16519. +{
  16520. + return EINVAL;
  16521. +}
  16522. +
  16523. +static int
  16524. +hipp_freesession(device_t dev, u_int64_t tid)
  16525. +{
  16526. + return EINVAL;
  16527. +}
  16528. +
  16529. +static int
  16530. +hipp_process(device_t dev, struct cryptop *crp, int hint)
  16531. +{
  16532. + return EINVAL;
  16533. +}
  16534. +
  16535. +static const char*
  16536. +hipp_partname(struct hipp_softc *sc, char buf[128], size_t blen)
  16537. +{
  16538. + char *n = NULL;
  16539. +
  16540. + switch (pci_get_vendor(sc->sc_pcidev)) {
  16541. + case PCI_VENDOR_HIFN:
  16542. + switch (pci_get_device(sc->sc_pcidev)) {
  16543. + case PCI_PRODUCT_HIFN_7855: n = "Hifn 7855";
  16544. + case PCI_PRODUCT_HIFN_8155: n = "Hifn 8155";
  16545. + case PCI_PRODUCT_HIFN_6500: n = "Hifn 6500";
  16546. + }
  16547. + }
  16548. +
  16549. + if(n==NULL) {
  16550. + snprintf(buf, blen, "VID=%02x,PID=%02x",
  16551. + pci_get_vendor(sc->sc_pcidev),
  16552. + pci_get_device(sc->sc_pcidev));
  16553. + } else {
  16554. + buf[0]='\0';
  16555. + strncat(buf, n, blen);
  16556. + }
  16557. + return buf;
  16558. +}
  16559. +
  16560. +struct hipp_fs_entry {
  16561. + struct attribute attr;
  16562. + /* other stuff */
  16563. +};
  16564. +
  16565. +
  16566. +static ssize_t
  16567. +cryptoid_show(struct device *dev,
  16568. + struct device_attribute *attr,
  16569. + char *buf)
  16570. +{
  16571. + struct hipp_softc *sc;
  16572. +
  16573. + sc = pci_get_drvdata(to_pci_dev (dev));
  16574. + return sprintf (buf, "%d\n", sc->sc_cid);
  16575. +}
  16576. +
  16577. +struct device_attribute hipp_dev_cryptoid = __ATTR_RO(cryptoid);
  16578. +
  16579. +/*
  16580. + * Attach an interface that successfully probed.
  16581. + */
  16582. +static int
  16583. +hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  16584. +{
  16585. + struct hipp_softc *sc = NULL;
  16586. + int i;
  16587. + //char rbase;
  16588. + //u_int16_t ena;
  16589. + int rev;
  16590. + //int rseg;
  16591. + int rc;
  16592. +
  16593. + DPRINTF("%s()\n", __FUNCTION__);
  16594. +
  16595. + if (pci_enable_device(dev) < 0)
  16596. + return(-ENODEV);
  16597. +
  16598. + if (pci_set_mwi(dev))
  16599. + return(-ENODEV);
  16600. +
  16601. + if (!dev->irq) {
  16602. + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
  16603. + pci_disable_device(dev);
  16604. + return(-ENODEV);
  16605. + }
  16606. +
  16607. + sc = (struct hipp_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  16608. + if (!sc)
  16609. + return(-ENOMEM);
  16610. + memset(sc, 0, sizeof(*sc));
  16611. +
  16612. + softc_device_init(sc, "hifn-hipp", hipp_num_chips, hipp_methods);
  16613. +
  16614. + sc->sc_pcidev = dev;
  16615. + sc->sc_irq = -1;
  16616. + sc->sc_cid = -1;
  16617. + sc->sc_num = hipp_num_chips++;
  16618. +
  16619. + if (sc->sc_num < HIPP_MAX_CHIPS)
  16620. + hipp_chip_idx[sc->sc_num] = sc;
  16621. +
  16622. + pci_set_drvdata(sc->sc_pcidev, sc);
  16623. +
  16624. + spin_lock_init(&sc->sc_mtx);
  16625. +
  16626. + /*
  16627. + * Setup PCI resources.
  16628. + * The READ_REG_0, WRITE_REG_0, READ_REG_1,
  16629. + * and WRITE_REG_1 macros throughout the driver are used
  16630. + * to permit better debugging.
  16631. + */
  16632. + for(i=0; i<4; i++) {
  16633. + unsigned long mem_start, mem_len;
  16634. + mem_start = pci_resource_start(sc->sc_pcidev, i);
  16635. + mem_len = pci_resource_len(sc->sc_pcidev, i);
  16636. + sc->sc_barphy[i] = (caddr_t)mem_start;
  16637. + sc->sc_bar[i] = (ocf_iomem_t) ioremap(mem_start, mem_len);
  16638. + if (!sc->sc_bar[i]) {
  16639. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", i);
  16640. + goto fail;
  16641. + }
  16642. + }
  16643. +
  16644. + //hipp_reset_board(sc, 0);
  16645. + pci_set_master(sc->sc_pcidev);
  16646. +
  16647. + /*
  16648. + * Arrange the interrupt line.
  16649. + */
  16650. + rc = request_irq(dev->irq, hipp_intr, IRQF_SHARED, "hifn", sc);
  16651. + if (rc) {
  16652. + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
  16653. + goto fail;
  16654. + }
  16655. + sc->sc_irq = dev->irq;
  16656. +
  16657. + rev = READ_REG_1(sc, HIPP_1_REVID) & 0xffff;
  16658. +
  16659. + {
  16660. + char b[32];
  16661. + device_printf(sc->sc_dev, "%s, rev %u",
  16662. + hipp_partname(sc, b, sizeof(b)), rev);
  16663. + }
  16664. +
  16665. +#if 0
  16666. + if (sc->sc_flags & HIFN_IS_7956)
  16667. + printf(", pll=0x%x<%s clk, %ux mult>",
  16668. + sc->sc_pllconfig,
  16669. + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
  16670. + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
  16671. +#endif
  16672. + printf("\n");
  16673. +
  16674. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  16675. + if (sc->sc_cid < 0) {
  16676. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  16677. + goto fail;
  16678. + }
  16679. +
  16680. +#if 0 /* cannot work with a non-GPL module */
  16681. + /* make a sysfs entry to let the world know what entry we got */
  16682. + sysfs_create_file(&sc->sc_pcidev->dev.kobj, &hipp_dev_cryptoid.attr);
  16683. +#endif
  16684. +
  16685. +#if 0
  16686. + init_timer(&sc->sc_tickto);
  16687. + sc->sc_tickto.function = hifn_tick;
  16688. + sc->sc_tickto.data = (unsigned long) sc->sc_num;
  16689. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  16690. +#endif
  16691. +
  16692. +#if 0 /* no code here yet ?? */
  16693. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  16694. +#endif
  16695. +
  16696. + return (0);
  16697. +
  16698. +fail:
  16699. + if (sc->sc_cid >= 0)
  16700. + crypto_unregister_all(sc->sc_cid);
  16701. + if (sc->sc_irq != -1)
  16702. + free_irq(sc->sc_irq, sc);
  16703. +
  16704. +#if 0
  16705. + if (sc->sc_dma) {
  16706. + /* Turn off DMA polling */
  16707. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  16708. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  16709. +
  16710. + pci_free_consistent(sc->sc_pcidev,
  16711. + sizeof(*sc->sc_dma),
  16712. + sc->sc_dma, sc->sc_dma_physaddr);
  16713. + }
  16714. +#endif
  16715. + kfree(sc);
  16716. + return (-ENXIO);
  16717. +}
  16718. +
  16719. +/*
  16720. + * Detach an interface that successfully probed.
  16721. + */
  16722. +static void
  16723. +hipp_remove(struct pci_dev *dev)
  16724. +{
  16725. + struct hipp_softc *sc = pci_get_drvdata(dev);
  16726. + unsigned long l_flags;
  16727. +
  16728. + DPRINTF("%s()\n", __FUNCTION__);
  16729. +
  16730. + /* disable interrupts */
  16731. + HIPP_LOCK(sc);
  16732. +
  16733. +#if 0
  16734. + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
  16735. + HIFN_UNLOCK(sc);
  16736. +
  16737. + /*XXX other resources */
  16738. + del_timer_sync(&sc->sc_tickto);
  16739. +
  16740. + /* Turn off DMA polling */
  16741. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  16742. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  16743. +#endif
  16744. +
  16745. + crypto_unregister_all(sc->sc_cid);
  16746. +
  16747. + free_irq(sc->sc_irq, sc);
  16748. +
  16749. +#if 0
  16750. + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
  16751. + sc->sc_dma, sc->sc_dma_physaddr);
  16752. +#endif
  16753. +}
  16754. +
  16755. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  16756. +static irqreturn_t hipp_intr(int irq, void *arg)
  16757. +#else
  16758. +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs)
  16759. +#endif
  16760. +{
  16761. + struct hipp_softc *sc = arg;
  16762. +
  16763. + sc = sc; /* shut up compiler */
  16764. +
  16765. + return IRQ_HANDLED;
  16766. +}
  16767. +
  16768. +static struct pci_device_id hipp_pci_tbl[] = {
  16769. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7855,
  16770. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16771. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_8155,
  16772. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16773. +};
  16774. +MODULE_DEVICE_TABLE(pci, hipp_pci_tbl);
  16775. +
  16776. +static struct pci_driver hipp_driver = {
  16777. + .name = "hipp",
  16778. + .id_table = hipp_pci_tbl,
  16779. + .probe = hipp_probe,
  16780. + .remove = hipp_remove,
  16781. + /* add PM stuff here one day */
  16782. +};
  16783. +
  16784. +static int __init hipp_init (void)
  16785. +{
  16786. + struct hipp_softc *sc = NULL;
  16787. + int rc;
  16788. +
  16789. + DPRINTF("%s(%p)\n", __FUNCTION__, hipp_init);
  16790. +
  16791. + rc = pci_register_driver(&hipp_driver);
  16792. + pci_register_driver_compat(&hipp_driver, rc);
  16793. +
  16794. + return rc;
  16795. +}
  16796. +
  16797. +static void __exit hipp_exit (void)
  16798. +{
  16799. + pci_unregister_driver(&hipp_driver);
  16800. +}
  16801. +
  16802. +module_init(hipp_init);
  16803. +module_exit(hipp_exit);
  16804. +
  16805. +MODULE_LICENSE("BSD");
  16806. +MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
  16807. +MODULE_DESCRIPTION("OCF driver for hifn HIPP-I/II PCI crypto devices");
  16808. diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPPreg.h linux-2.6.36/crypto/ocf/hifn/hifnHIPPreg.h
  16809. --- linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPPreg.h 1970-01-01 01:00:00.000000000 +0100
  16810. +++ linux-2.6.36/crypto/ocf/hifn/hifnHIPPreg.h 2010-11-09 20:28:04.922495399 +0100
  16811. @@ -0,0 +1,46 @@
  16812. +/*-
  16813. + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
  16814. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
  16815. + *
  16816. + * Redistribution and use in source and binary forms, with or without
  16817. + * modification, are permitted provided that the following conditions
  16818. + * are met:
  16819. + *
  16820. + * 1. Redistributions of source code must retain the above copyright
  16821. + * notice, this list of conditions and the following disclaimer.
  16822. + * 2. Redistributions in binary form must reproduce the above copyright
  16823. + * notice, this list of conditions and the following disclaimer in the
  16824. + * documentation and/or other materials provided with the distribution.
  16825. + * 3. The name of the author may not be used to endorse or promote products
  16826. + * derived from this software without specific prior written permission.
  16827. + *
  16828. + *
  16829. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16830. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16831. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16832. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  16833. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  16834. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  16835. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  16836. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  16837. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  16838. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16839. + *
  16840. + * Effort sponsored by Hifn inc.
  16841. + *
  16842. + */
  16843. +
  16844. +#ifndef __HIFNHIPP_H__
  16845. +#define __HIFNHIPP_H__
  16846. +
  16847. +/*
  16848. + * PCI vendor and device identifiers
  16849. + */
  16850. +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
  16851. +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
  16852. +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
  16853. +#define PCI_PRODUCT_HIFN_8155 0x999 /* XXX 8155 */
  16854. +
  16855. +#define HIPP_1_REVID 0x01 /* BOGUS */
  16856. +
  16857. +#endif /* __HIPP_H__ */
  16858. diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPPvar.h linux-2.6.36/crypto/ocf/hifn/hifnHIPPvar.h
  16859. --- linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPPvar.h 1970-01-01 01:00:00.000000000 +0100
  16860. +++ linux-2.6.36/crypto/ocf/hifn/hifnHIPPvar.h 2010-11-09 20:28:04.964807923 +0100
  16861. @@ -0,0 +1,93 @@
  16862. +/*
  16863. + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
  16864. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com> *
  16865. + *
  16866. + * Redistribution and use in source and binary forms, with or without
  16867. + * modification, are permitted provided that the following conditions
  16868. + * are met:
  16869. + *
  16870. + * 1. Redistributions of source code must retain the above copyright
  16871. + * notice, this list of conditions and the following disclaimer.
  16872. + * 2. Redistributions in binary form must reproduce the above copyright
  16873. + * notice, this list of conditions and the following disclaimer in the
  16874. + * documentation and/or other materials provided with the distribution.
  16875. + * 3. The name of the author may not be used to endorse or promote products
  16876. + * derived from this software without specific prior written permission.
  16877. + *
  16878. + *
  16879. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16880. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16881. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16882. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  16883. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  16884. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  16885. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  16886. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  16887. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  16888. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16889. + *
  16890. + * Effort sponsored by Hifn inc.
  16891. + *
  16892. + */
  16893. +
  16894. +#ifndef __HIFNHIPPVAR_H__
  16895. +#define __HIFNHIPPVAR_H__
  16896. +
  16897. +#define HIPP_MAX_CHIPS 8
  16898. +
  16899. +/*
  16900. + * Holds data specific to a single Hifn HIPP-I board.
  16901. + */
  16902. +struct hipp_softc {
  16903. + softc_device_decl sc_dev;
  16904. +
  16905. + struct pci_dev *sc_pcidev; /* device backpointer */
  16906. + ocf_iomem_t sc_bar[5];
  16907. + caddr_t sc_barphy[5]; /* physical address */
  16908. + int sc_num; /* for multiple devs */
  16909. + spinlock_t sc_mtx; /* per-instance lock */
  16910. + int32_t sc_cid;
  16911. + int sc_irq;
  16912. +
  16913. +#if 0
  16914. +
  16915. + u_int32_t sc_dmaier;
  16916. + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
  16917. + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
  16918. +
  16919. + struct hifn_dma *sc_dma;
  16920. + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
  16921. +
  16922. + int sc_dmansegs;
  16923. + int sc_maxses;
  16924. + int sc_nsessions;
  16925. + struct hifn_session *sc_sessions;
  16926. + int sc_ramsize;
  16927. + int sc_flags;
  16928. +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
  16929. +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
  16930. +#define HIFN_HAS_AES 0x4 /* includes AES support */
  16931. +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
  16932. +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
  16933. +
  16934. + struct timer_list sc_tickto; /* for managing DMA */
  16935. +
  16936. + int sc_rngfirst;
  16937. + int sc_rnghz; /* RNG polling frequency */
  16938. +
  16939. + int sc_c_busy; /* command ring busy */
  16940. + int sc_s_busy; /* source data ring busy */
  16941. + int sc_d_busy; /* destination data ring busy */
  16942. + int sc_r_busy; /* result ring busy */
  16943. + int sc_active; /* for initial countdown */
  16944. + int sc_needwakeup; /* ops q'd wating on resources */
  16945. + int sc_curbatch; /* # ops submitted w/o int */
  16946. + int sc_suspended;
  16947. + struct miscdevice sc_miscdev;
  16948. +#endif
  16949. +};
  16950. +
  16951. +#define HIPP_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
  16952. +#define HIPP_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
  16953. +
  16954. +#endif /* __HIFNHIPPVAR_H__ */
  16955. diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/Makefile linux-2.6.36/crypto/ocf/hifn/Makefile
  16956. --- linux-2.6.36.orig/crypto/ocf/hifn/Makefile 1970-01-01 01:00:00.000000000 +0100
  16957. +++ linux-2.6.36/crypto/ocf/hifn/Makefile 2010-11-09 20:28:05.002825564 +0100
  16958. @@ -0,0 +1,13 @@
  16959. +# for SGlinux builds
  16960. +-include $(ROOTDIR)/modules/.config
  16961. +
  16962. +obj-$(CONFIG_OCF_HIFN) += hifn7751.o
  16963. +obj-$(CONFIG_OCF_HIFNHIPP) += hifnHIPP.o
  16964. +
  16965. +obj ?= .
  16966. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  16967. +
  16968. +ifdef TOPDIR
  16969. +-include $(TOPDIR)/Rules.make
  16970. +endif
  16971. +
  16972. diff -Nur linux-2.6.36.orig/crypto/ocf/ixp4xx/ixp4xx.c linux-2.6.36/crypto/ocf/ixp4xx/ixp4xx.c
  16973. --- linux-2.6.36.orig/crypto/ocf/ixp4xx/ixp4xx.c 1970-01-01 01:00:00.000000000 +0100
  16974. +++ linux-2.6.36/crypto/ocf/ixp4xx/ixp4xx.c 2010-11-09 20:28:05.051258556 +0100
  16975. @@ -0,0 +1,1324 @@
  16976. +/*
  16977. + * An OCF module that uses Intels IXP CryptACC API to do the crypto.
  16978. + * This driver requires the IXP400 Access Library that is available
  16979. + * from Intel in order to operate (or compile).
  16980. + *
  16981. + * Written by David McCullough <david_mccullough@mcafee.com>
  16982. + * Copyright (C) 2006-2010 David McCullough
  16983. + * Copyright (C) 2004-2005 Intel Corporation.
  16984. + *
  16985. + * LICENSE TERMS
  16986. + *
  16987. + * The free distribution and use of this software in both source and binary
  16988. + * form is allowed (with or without changes) provided that:
  16989. + *
  16990. + * 1. distributions of this source code include the above copyright
  16991. + * notice, this list of conditions and the following disclaimer;
  16992. + *
  16993. + * 2. distributions in binary form include the above copyright
  16994. + * notice, this list of conditions and the following disclaimer
  16995. + * in the documentation and/or other associated materials;
  16996. + *
  16997. + * 3. the copyright holder's name is not used to endorse products
  16998. + * built using this software without specific written permission.
  16999. + *
  17000. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  17001. + * may be distributed under the terms of the GNU General Public License (GPL),
  17002. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  17003. + *
  17004. + * DISCLAIMER
  17005. + *
  17006. + * This software is provided 'as is' with no explicit or implied warranties
  17007. + * in respect of its properties, including, but not limited to, correctness
  17008. + * and/or fitness for purpose.
  17009. + */
  17010. +
  17011. +#ifndef AUTOCONF_INCLUDED
  17012. +#include <linux/config.h>
  17013. +#endif
  17014. +#include <linux/module.h>
  17015. +#include <linux/init.h>
  17016. +#include <linux/list.h>
  17017. +#include <linux/slab.h>
  17018. +#include <linux/sched.h>
  17019. +#include <linux/wait.h>
  17020. +#include <linux/crypto.h>
  17021. +#include <linux/interrupt.h>
  17022. +#include <asm/scatterlist.h>
  17023. +
  17024. +#include <IxTypes.h>
  17025. +#include <IxOsBuffMgt.h>
  17026. +#include <IxNpeDl.h>
  17027. +#include <IxCryptoAcc.h>
  17028. +#include <IxQMgr.h>
  17029. +#include <IxOsServices.h>
  17030. +#include <IxOsCacheMMU.h>
  17031. +
  17032. +#include <cryptodev.h>
  17033. +#include <uio.h>
  17034. +
  17035. +#ifndef IX_MBUF_PRIV
  17036. +#define IX_MBUF_PRIV(x) ((x)->priv)
  17037. +#endif
  17038. +
  17039. +struct ixp_data;
  17040. +
  17041. +struct ixp_q {
  17042. + struct list_head ixp_q_list;
  17043. + struct ixp_data *ixp_q_data;
  17044. + struct cryptop *ixp_q_crp;
  17045. + struct cryptodesc *ixp_q_ccrd;
  17046. + struct cryptodesc *ixp_q_acrd;
  17047. + IX_MBUF ixp_q_mbuf;
  17048. + UINT8 *ixp_hash_dest; /* Location for hash in client buffer */
  17049. + UINT8 *ixp_hash_src; /* Location of hash in internal buffer */
  17050. + unsigned char ixp_q_iv_data[IX_CRYPTO_ACC_MAX_CIPHER_IV_LENGTH];
  17051. + unsigned char *ixp_q_iv;
  17052. +};
  17053. +
  17054. +struct ixp_data {
  17055. + int ixp_registered; /* is the context registered */
  17056. + int ixp_crd_flags; /* detect direction changes */
  17057. +
  17058. + int ixp_cipher_alg;
  17059. + int ixp_auth_alg;
  17060. +
  17061. + UINT32 ixp_ctx_id;
  17062. + UINT32 ixp_hash_key_id; /* used when hashing */
  17063. + IxCryptoAccCtx ixp_ctx;
  17064. + IX_MBUF ixp_pri_mbuf;
  17065. + IX_MBUF ixp_sec_mbuf;
  17066. +
  17067. + struct work_struct ixp_pending_work;
  17068. + struct work_struct ixp_registration_work;
  17069. + struct list_head ixp_q; /* unprocessed requests */
  17070. +};
  17071. +
  17072. +#ifdef __ixp46X
  17073. +
  17074. +#define MAX_IOP_SIZE 64 /* words */
  17075. +#define MAX_OOP_SIZE 128
  17076. +
  17077. +#define MAX_PARAMS 3
  17078. +
  17079. +struct ixp_pkq {
  17080. + struct list_head pkq_list;
  17081. + struct cryptkop *pkq_krp;
  17082. +
  17083. + IxCryptoAccPkeEauInOperands pkq_op;
  17084. + IxCryptoAccPkeEauOpResult pkq_result;
  17085. +
  17086. + UINT32 pkq_ibuf0[MAX_IOP_SIZE];
  17087. + UINT32 pkq_ibuf1[MAX_IOP_SIZE];
  17088. + UINT32 pkq_ibuf2[MAX_IOP_SIZE];
  17089. + UINT32 pkq_obuf[MAX_OOP_SIZE];
  17090. +};
  17091. +
  17092. +static LIST_HEAD(ixp_pkq); /* current PK wait list */
  17093. +static struct ixp_pkq *ixp_pk_cur;
  17094. +static spinlock_t ixp_pkq_lock;
  17095. +
  17096. +#endif /* __ixp46X */
  17097. +
  17098. +static int ixp_blocked = 0;
  17099. +
  17100. +static int32_t ixp_id = -1;
  17101. +static struct ixp_data **ixp_sessions = NULL;
  17102. +static u_int32_t ixp_sesnum = 0;
  17103. +
  17104. +static int ixp_process(device_t, struct cryptop *, int);
  17105. +static int ixp_newsession(device_t, u_int32_t *, struct cryptoini *);
  17106. +static int ixp_freesession(device_t, u_int64_t);
  17107. +#ifdef __ixp46X
  17108. +static int ixp_kprocess(device_t, struct cryptkop *krp, int hint);
  17109. +#endif
  17110. +
  17111. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  17112. +static kmem_cache_t *qcache;
  17113. +#else
  17114. +static struct kmem_cache *qcache;
  17115. +#endif
  17116. +
  17117. +#define debug ixp_debug
  17118. +static int ixp_debug = 0;
  17119. +module_param(ixp_debug, int, 0644);
  17120. +MODULE_PARM_DESC(ixp_debug, "Enable debug");
  17121. +
  17122. +static int ixp_init_crypto = 1;
  17123. +module_param(ixp_init_crypto, int, 0444); /* RO after load/boot */
  17124. +MODULE_PARM_DESC(ixp_init_crypto, "Call ixCryptoAccInit (default is 1)");
  17125. +
  17126. +static void ixp_process_pending(void *arg);
  17127. +static void ixp_registration(void *arg);
  17128. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  17129. +static void ixp_process_pending_wq(struct work_struct *work);
  17130. +static void ixp_registration_wq(struct work_struct *work);
  17131. +#endif
  17132. +
  17133. +/*
  17134. + * dummy device structure
  17135. + */
  17136. +
  17137. +static struct {
  17138. + softc_device_decl sc_dev;
  17139. +} ixpdev;
  17140. +
  17141. +static device_method_t ixp_methods = {
  17142. + /* crypto device methods */
  17143. + DEVMETHOD(cryptodev_newsession, ixp_newsession),
  17144. + DEVMETHOD(cryptodev_freesession,ixp_freesession),
  17145. + DEVMETHOD(cryptodev_process, ixp_process),
  17146. +#ifdef __ixp46X
  17147. + DEVMETHOD(cryptodev_kprocess, ixp_kprocess),
  17148. +#endif
  17149. +};
  17150. +
  17151. +/*
  17152. + * Generate a new software session.
  17153. + */
  17154. +static int
  17155. +ixp_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  17156. +{
  17157. + struct ixp_data *ixp;
  17158. + u_int32_t i;
  17159. +#define AUTH_LEN(cri, def) \
  17160. + (cri->cri_mlen ? cri->cri_mlen : (def))
  17161. +
  17162. + dprintk("%s():alg %d\n", __FUNCTION__,cri->cri_alg);
  17163. + if (sid == NULL || cri == NULL) {
  17164. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  17165. + return EINVAL;
  17166. + }
  17167. +
  17168. + if (ixp_sessions) {
  17169. + for (i = 1; i < ixp_sesnum; i++)
  17170. + if (ixp_sessions[i] == NULL)
  17171. + break;
  17172. + } else
  17173. + i = 1; /* NB: to silence compiler warning */
  17174. +
  17175. + if (ixp_sessions == NULL || i == ixp_sesnum) {
  17176. + struct ixp_data **ixpd;
  17177. +
  17178. + if (ixp_sessions == NULL) {
  17179. + i = 1; /* We leave ixp_sessions[0] empty */
  17180. + ixp_sesnum = CRYPTO_SW_SESSIONS;
  17181. + } else
  17182. + ixp_sesnum *= 2;
  17183. +
  17184. + ixpd = kmalloc(ixp_sesnum * sizeof(struct ixp_data *), SLAB_ATOMIC);
  17185. + if (ixpd == NULL) {
  17186. + /* Reset session number */
  17187. + if (ixp_sesnum == CRYPTO_SW_SESSIONS)
  17188. + ixp_sesnum = 0;
  17189. + else
  17190. + ixp_sesnum /= 2;
  17191. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  17192. + return ENOBUFS;
  17193. + }
  17194. + memset(ixpd, 0, ixp_sesnum * sizeof(struct ixp_data *));
  17195. +
  17196. + /* Copy existing sessions */
  17197. + if (ixp_sessions) {
  17198. + memcpy(ixpd, ixp_sessions,
  17199. + (ixp_sesnum / 2) * sizeof(struct ixp_data *));
  17200. + kfree(ixp_sessions);
  17201. + }
  17202. +
  17203. + ixp_sessions = ixpd;
  17204. + }
  17205. +
  17206. + ixp_sessions[i] = (struct ixp_data *) kmalloc(sizeof(struct ixp_data),
  17207. + SLAB_ATOMIC);
  17208. + if (ixp_sessions[i] == NULL) {
  17209. + ixp_freesession(NULL, i);
  17210. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  17211. + return ENOBUFS;
  17212. + }
  17213. +
  17214. + *sid = i;
  17215. +
  17216. + ixp = ixp_sessions[i];
  17217. + memset(ixp, 0, sizeof(*ixp));
  17218. +
  17219. + ixp->ixp_cipher_alg = -1;
  17220. + ixp->ixp_auth_alg = -1;
  17221. + ixp->ixp_ctx_id = -1;
  17222. + INIT_LIST_HEAD(&ixp->ixp_q);
  17223. +
  17224. + ixp->ixp_ctx.useDifferentSrcAndDestMbufs = 0;
  17225. +
  17226. + while (cri) {
  17227. + switch (cri->cri_alg) {
  17228. + case CRYPTO_DES_CBC:
  17229. + ixp->ixp_cipher_alg = cri->cri_alg;
  17230. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_DES;
  17231. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  17232. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  17233. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  17234. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
  17235. + IX_CRYPTO_ACC_DES_IV_64;
  17236. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  17237. + cri->cri_key, (cri->cri_klen + 7) / 8);
  17238. + break;
  17239. +
  17240. + case CRYPTO_3DES_CBC:
  17241. + ixp->ixp_cipher_alg = cri->cri_alg;
  17242. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
  17243. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  17244. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  17245. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  17246. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
  17247. + IX_CRYPTO_ACC_DES_IV_64;
  17248. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  17249. + cri->cri_key, (cri->cri_klen + 7) / 8);
  17250. + break;
  17251. +
  17252. + case CRYPTO_RIJNDAEL128_CBC:
  17253. + ixp->ixp_cipher_alg = cri->cri_alg;
  17254. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_AES;
  17255. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  17256. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  17257. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = 16;
  17258. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen = 16;
  17259. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  17260. + cri->cri_key, (cri->cri_klen + 7) / 8);
  17261. + break;
  17262. +
  17263. + case CRYPTO_MD5:
  17264. + case CRYPTO_MD5_HMAC:
  17265. + ixp->ixp_auth_alg = cri->cri_alg;
  17266. + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_MD5;
  17267. + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, MD5_HASH_LEN);
  17268. + ixp->ixp_ctx.authCtx.aadLen = 0;
  17269. + /* Only MD5_HMAC needs a key */
  17270. + if (cri->cri_alg == CRYPTO_MD5_HMAC) {
  17271. + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
  17272. + if (ixp->ixp_ctx.authCtx.authKeyLen >
  17273. + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
  17274. + printk(
  17275. + "ixp4xx: Invalid key length for MD5_HMAC - %d bits\n",
  17276. + cri->cri_klen);
  17277. + ixp_freesession(NULL, i);
  17278. + return EINVAL;
  17279. + }
  17280. + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
  17281. + cri->cri_key, (cri->cri_klen + 7) / 8);
  17282. + }
  17283. + break;
  17284. +
  17285. + case CRYPTO_SHA1:
  17286. + case CRYPTO_SHA1_HMAC:
  17287. + ixp->ixp_auth_alg = cri->cri_alg;
  17288. + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
  17289. + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, SHA1_HASH_LEN);
  17290. + ixp->ixp_ctx.authCtx.aadLen = 0;
  17291. + /* Only SHA1_HMAC needs a key */
  17292. + if (cri->cri_alg == CRYPTO_SHA1_HMAC) {
  17293. + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
  17294. + if (ixp->ixp_ctx.authCtx.authKeyLen >
  17295. + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
  17296. + printk(
  17297. + "ixp4xx: Invalid key length for SHA1_HMAC - %d bits\n",
  17298. + cri->cri_klen);
  17299. + ixp_freesession(NULL, i);
  17300. + return EINVAL;
  17301. + }
  17302. + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
  17303. + cri->cri_key, (cri->cri_klen + 7) / 8);
  17304. + }
  17305. + break;
  17306. +
  17307. + default:
  17308. + printk("ixp: unknown algo 0x%x\n", cri->cri_alg);
  17309. + ixp_freesession(NULL, i);
  17310. + return EINVAL;
  17311. + }
  17312. + cri = cri->cri_next;
  17313. + }
  17314. +
  17315. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  17316. + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending_wq);
  17317. + INIT_WORK(&ixp->ixp_registration_work, ixp_registration_wq);
  17318. +#else
  17319. + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending, ixp);
  17320. + INIT_WORK(&ixp->ixp_registration_work, ixp_registration, ixp);
  17321. +#endif
  17322. +
  17323. + return 0;
  17324. +}
  17325. +
  17326. +
  17327. +/*
  17328. + * Free a session.
  17329. + */
  17330. +static int
  17331. +ixp_freesession(device_t dev, u_int64_t tid)
  17332. +{
  17333. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  17334. +
  17335. + dprintk("%s()\n", __FUNCTION__);
  17336. + if (sid > ixp_sesnum || ixp_sessions == NULL ||
  17337. + ixp_sessions[sid] == NULL) {
  17338. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  17339. + return EINVAL;
  17340. + }
  17341. +
  17342. + /* Silently accept and return */
  17343. + if (sid == 0)
  17344. + return 0;
  17345. +
  17346. + if (ixp_sessions[sid]) {
  17347. + if (ixp_sessions[sid]->ixp_ctx_id != -1) {
  17348. + ixCryptoAccCtxUnregister(ixp_sessions[sid]->ixp_ctx_id);
  17349. + ixp_sessions[sid]->ixp_ctx_id = -1;
  17350. + }
  17351. + kfree(ixp_sessions[sid]);
  17352. + }
  17353. + ixp_sessions[sid] = NULL;
  17354. + if (ixp_blocked) {
  17355. + ixp_blocked = 0;
  17356. + crypto_unblock(ixp_id, CRYPTO_SYMQ);
  17357. + }
  17358. + return 0;
  17359. +}
  17360. +
  17361. +
  17362. +/*
  17363. + * callback for when hash processing is complete
  17364. + */
  17365. +
  17366. +static void
  17367. +ixp_hash_perform_cb(
  17368. + UINT32 hash_key_id,
  17369. + IX_MBUF *bufp,
  17370. + IxCryptoAccStatus status)
  17371. +{
  17372. + struct ixp_q *q;
  17373. +
  17374. + dprintk("%s(%u, %p, 0x%x)\n", __FUNCTION__, hash_key_id, bufp, status);
  17375. +
  17376. + if (bufp == NULL) {
  17377. + printk("ixp: NULL buf in %s\n", __FUNCTION__);
  17378. + return;
  17379. + }
  17380. +
  17381. + q = IX_MBUF_PRIV(bufp);
  17382. + if (q == NULL) {
  17383. + printk("ixp: NULL priv in %s\n", __FUNCTION__);
  17384. + return;
  17385. + }
  17386. +
  17387. + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
  17388. + /* On success, need to copy hash back into original client buffer */
  17389. + memcpy(q->ixp_hash_dest, q->ixp_hash_src,
  17390. + (q->ixp_q_data->ixp_auth_alg == CRYPTO_SHA1) ?
  17391. + SHA1_HASH_LEN : MD5_HASH_LEN);
  17392. + }
  17393. + else {
  17394. + printk("ixp: hash perform failed status=%d\n", status);
  17395. + q->ixp_q_crp->crp_etype = EINVAL;
  17396. + }
  17397. +
  17398. + /* Free internal buffer used for hashing */
  17399. + kfree(IX_MBUF_MDATA(&q->ixp_q_mbuf));
  17400. +
  17401. + crypto_done(q->ixp_q_crp);
  17402. + kmem_cache_free(qcache, q);
  17403. +}
  17404. +
  17405. +/*
  17406. + * setup a request and perform it
  17407. + */
  17408. +static void
  17409. +ixp_q_process(struct ixp_q *q)
  17410. +{
  17411. + IxCryptoAccStatus status;
  17412. + struct ixp_data *ixp = q->ixp_q_data;
  17413. + int auth_off = 0;
  17414. + int auth_len = 0;
  17415. + int crypt_off = 0;
  17416. + int crypt_len = 0;
  17417. + int icv_off = 0;
  17418. + char *crypt_func;
  17419. +
  17420. + dprintk("%s(%p)\n", __FUNCTION__, q);
  17421. +
  17422. + if (q->ixp_q_ccrd) {
  17423. + if (q->ixp_q_ccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  17424. + q->ixp_q_iv = q->ixp_q_ccrd->crd_iv;
  17425. + } else {
  17426. + q->ixp_q_iv = q->ixp_q_iv_data;
  17427. + crypto_copydata(q->ixp_q_crp->crp_flags, q->ixp_q_crp->crp_buf,
  17428. + q->ixp_q_ccrd->crd_inject,
  17429. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen,
  17430. + (caddr_t) q->ixp_q_iv);
  17431. + }
  17432. +
  17433. + if (q->ixp_q_acrd) {
  17434. + auth_off = q->ixp_q_acrd->crd_skip;
  17435. + auth_len = q->ixp_q_acrd->crd_len;
  17436. + icv_off = q->ixp_q_acrd->crd_inject;
  17437. + }
  17438. +
  17439. + crypt_off = q->ixp_q_ccrd->crd_skip;
  17440. + crypt_len = q->ixp_q_ccrd->crd_len;
  17441. + } else { /* if (q->ixp_q_acrd) */
  17442. + auth_off = q->ixp_q_acrd->crd_skip;
  17443. + auth_len = q->ixp_q_acrd->crd_len;
  17444. + icv_off = q->ixp_q_acrd->crd_inject;
  17445. + }
  17446. +
  17447. + if (q->ixp_q_crp->crp_flags & CRYPTO_F_SKBUF) {
  17448. + struct sk_buff *skb = (struct sk_buff *) q->ixp_q_crp->crp_buf;
  17449. + if (skb_shinfo(skb)->nr_frags) {
  17450. + /*
  17451. + * DAVIDM fix this limitation one day by using
  17452. + * a buffer pool and chaining, it is not currently
  17453. + * needed for current user/kernel space acceleration
  17454. + */
  17455. + printk("ixp: Cannot handle fragmented skb's yet !\n");
  17456. + q->ixp_q_crp->crp_etype = ENOENT;
  17457. + goto done;
  17458. + }
  17459. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  17460. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = skb->len;
  17461. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = skb->data;
  17462. + } else if (q->ixp_q_crp->crp_flags & CRYPTO_F_IOV) {
  17463. + struct uio *uiop = (struct uio *) q->ixp_q_crp->crp_buf;
  17464. + if (uiop->uio_iovcnt != 1) {
  17465. + /*
  17466. + * DAVIDM fix this limitation one day by using
  17467. + * a buffer pool and chaining, it is not currently
  17468. + * needed for current user/kernel space acceleration
  17469. + */
  17470. + printk("ixp: Cannot handle more than 1 iovec yet !\n");
  17471. + q->ixp_q_crp->crp_etype = ENOENT;
  17472. + goto done;
  17473. + }
  17474. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  17475. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_len;
  17476. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_base;
  17477. + } else /* contig buffer */ {
  17478. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  17479. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_ilen;
  17480. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_buf;
  17481. + }
  17482. +
  17483. + IX_MBUF_PRIV(&q->ixp_q_mbuf) = q;
  17484. +
  17485. + if (ixp->ixp_auth_alg == CRYPTO_SHA1 || ixp->ixp_auth_alg == CRYPTO_MD5) {
  17486. + /*
  17487. + * For SHA1 and MD5 hash, need to create an internal buffer that is big
  17488. + * enough to hold the original data + the appropriate padding for the
  17489. + * hash algorithm.
  17490. + */
  17491. + UINT8 *tbuf = NULL;
  17492. +
  17493. + IX_MBUF_MLEN(&q->ixp_q_mbuf) = IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) =
  17494. + ((IX_MBUF_MLEN(&q->ixp_q_mbuf) * 8) + 72 + 511) / 8;
  17495. + tbuf = kmalloc(IX_MBUF_MLEN(&q->ixp_q_mbuf), SLAB_ATOMIC);
  17496. +
  17497. + if (IX_MBUF_MDATA(&q->ixp_q_mbuf) == NULL) {
  17498. + printk("ixp: kmalloc(%u, SLAB_ATOMIC) failed\n",
  17499. + IX_MBUF_MLEN(&q->ixp_q_mbuf));
  17500. + q->ixp_q_crp->crp_etype = ENOMEM;
  17501. + goto done;
  17502. + }
  17503. + memcpy(tbuf, &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off], auth_len);
  17504. +
  17505. + /* Set location in client buffer to copy hash into */
  17506. + q->ixp_hash_dest =
  17507. + &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off + auth_len];
  17508. +
  17509. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = tbuf;
  17510. +
  17511. + /* Set location in internal buffer for where hash starts */
  17512. + q->ixp_hash_src = &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_len];
  17513. +
  17514. + crypt_func = "ixCryptoAccHashPerform";
  17515. + status = ixCryptoAccHashPerform(ixp->ixp_ctx.authCtx.authAlgo,
  17516. + &q->ixp_q_mbuf, ixp_hash_perform_cb, 0, auth_len, auth_len,
  17517. + &ixp->ixp_hash_key_id);
  17518. + }
  17519. + else {
  17520. + crypt_func = "ixCryptoAccAuthCryptPerform";
  17521. + status = ixCryptoAccAuthCryptPerform(ixp->ixp_ctx_id, &q->ixp_q_mbuf,
  17522. + NULL, auth_off, auth_len, crypt_off, crypt_len, icv_off,
  17523. + q->ixp_q_iv);
  17524. + }
  17525. +
  17526. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  17527. + return;
  17528. +
  17529. + if (IX_CRYPTO_ACC_STATUS_QUEUE_FULL == status) {
  17530. + q->ixp_q_crp->crp_etype = ENOMEM;
  17531. + goto done;
  17532. + }
  17533. +
  17534. + printk("ixp: %s failed %u\n", crypt_func, status);
  17535. + q->ixp_q_crp->crp_etype = EINVAL;
  17536. +
  17537. +done:
  17538. + crypto_done(q->ixp_q_crp);
  17539. + kmem_cache_free(qcache, q);
  17540. +}
  17541. +
  17542. +
  17543. +/*
  17544. + * because we cannot process the Q from the Register callback
  17545. + * we do it here on a task Q.
  17546. + */
  17547. +
  17548. +static void
  17549. +ixp_process_pending(void *arg)
  17550. +{
  17551. + struct ixp_data *ixp = arg;
  17552. + struct ixp_q *q = NULL;
  17553. +
  17554. + dprintk("%s(%p)\n", __FUNCTION__, arg);
  17555. +
  17556. + if (!ixp)
  17557. + return;
  17558. +
  17559. + while (!list_empty(&ixp->ixp_q)) {
  17560. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  17561. + list_del(&q->ixp_q_list);
  17562. + ixp_q_process(q);
  17563. + }
  17564. +}
  17565. +
  17566. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  17567. +static void
  17568. +ixp_process_pending_wq(struct work_struct *work)
  17569. +{
  17570. + struct ixp_data *ixp = container_of(work, struct ixp_data, ixp_pending_work);
  17571. + ixp_process_pending(ixp);
  17572. +}
  17573. +#endif
  17574. +
  17575. +/*
  17576. + * callback for when context registration is complete
  17577. + */
  17578. +
  17579. +static void
  17580. +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
  17581. +{
  17582. + int i;
  17583. + struct ixp_data *ixp;
  17584. + struct ixp_q *q;
  17585. +
  17586. + dprintk("%s(%d, %p, %d)\n", __FUNCTION__, ctx_id, bufp, status);
  17587. +
  17588. + /*
  17589. + * free any buffer passed in to this routine
  17590. + */
  17591. + if (bufp) {
  17592. + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
  17593. + kfree(IX_MBUF_MDATA(bufp));
  17594. + IX_MBUF_MDATA(bufp) = NULL;
  17595. + }
  17596. +
  17597. + for (i = 0; i < ixp_sesnum; i++) {
  17598. + ixp = ixp_sessions[i];
  17599. + if (ixp && ixp->ixp_ctx_id == ctx_id)
  17600. + break;
  17601. + }
  17602. + if (i >= ixp_sesnum) {
  17603. + printk("ixp: invalid context id %d\n", ctx_id);
  17604. + return;
  17605. + }
  17606. +
  17607. + if (IX_CRYPTO_ACC_STATUS_WAIT == status) {
  17608. + /* this is normal to free the first of two buffers */
  17609. + dprintk("ixp: register not finished yet.\n");
  17610. + return;
  17611. + }
  17612. +
  17613. + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
  17614. + printk("ixp: register failed 0x%x\n", status);
  17615. + while (!list_empty(&ixp->ixp_q)) {
  17616. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  17617. + list_del(&q->ixp_q_list);
  17618. + q->ixp_q_crp->crp_etype = EINVAL;
  17619. + crypto_done(q->ixp_q_crp);
  17620. + kmem_cache_free(qcache, q);
  17621. + }
  17622. + return;
  17623. + }
  17624. +
  17625. + /*
  17626. + * we are now registered, we cannot start processing the Q here
  17627. + * or we get strange errors with AES (DES/3DES seem to be ok).
  17628. + */
  17629. + ixp->ixp_registered = 1;
  17630. + schedule_work(&ixp->ixp_pending_work);
  17631. +}
  17632. +
  17633. +
  17634. +/*
  17635. + * callback for when data processing is complete
  17636. + */
  17637. +
  17638. +static void
  17639. +ixp_perform_cb(
  17640. + UINT32 ctx_id,
  17641. + IX_MBUF *sbufp,
  17642. + IX_MBUF *dbufp,
  17643. + IxCryptoAccStatus status)
  17644. +{
  17645. + struct ixp_q *q;
  17646. +
  17647. + dprintk("%s(%d, %p, %p, 0x%x)\n", __FUNCTION__, ctx_id, sbufp,
  17648. + dbufp, status);
  17649. +
  17650. + if (sbufp == NULL) {
  17651. + printk("ixp: NULL sbuf in ixp_perform_cb\n");
  17652. + return;
  17653. + }
  17654. +
  17655. + q = IX_MBUF_PRIV(sbufp);
  17656. + if (q == NULL) {
  17657. + printk("ixp: NULL priv in ixp_perform_cb\n");
  17658. + return;
  17659. + }
  17660. +
  17661. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  17662. + printk("ixp: perform failed status=%d\n", status);
  17663. + q->ixp_q_crp->crp_etype = EINVAL;
  17664. + }
  17665. +
  17666. + crypto_done(q->ixp_q_crp);
  17667. + kmem_cache_free(qcache, q);
  17668. +}
  17669. +
  17670. +
  17671. +/*
  17672. + * registration is not callable at IRQ time, so we defer
  17673. + * to a task queue, this routines completes the registration for us
  17674. + * when the task queue runs
  17675. + *
  17676. + * Unfortunately this means we cannot tell OCF that the driver is blocked,
  17677. + * we do that on the next request.
  17678. + */
  17679. +
  17680. +static void
  17681. +ixp_registration(void *arg)
  17682. +{
  17683. + struct ixp_data *ixp = arg;
  17684. + struct ixp_q *q = NULL;
  17685. + IX_MBUF *pri = NULL, *sec = NULL;
  17686. + int status = IX_CRYPTO_ACC_STATUS_SUCCESS;
  17687. +
  17688. + if (!ixp) {
  17689. + printk("ixp: ixp_registration with no arg\n");
  17690. + return;
  17691. + }
  17692. +
  17693. + if (ixp->ixp_ctx_id != -1) {
  17694. + ixCryptoAccCtxUnregister(ixp->ixp_ctx_id);
  17695. + ixp->ixp_ctx_id = -1;
  17696. + }
  17697. +
  17698. + if (list_empty(&ixp->ixp_q)) {
  17699. + printk("ixp: ixp_registration with no Q\n");
  17700. + return;
  17701. + }
  17702. +
  17703. + /*
  17704. + * setup the primary and secondary buffers
  17705. + */
  17706. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  17707. + if (q->ixp_q_acrd) {
  17708. + pri = &ixp->ixp_pri_mbuf;
  17709. + sec = &ixp->ixp_sec_mbuf;
  17710. + IX_MBUF_MLEN(pri) = IX_MBUF_PKT_LEN(pri) = 128;
  17711. + IX_MBUF_MDATA(pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  17712. + IX_MBUF_MLEN(sec) = IX_MBUF_PKT_LEN(sec) = 128;
  17713. + IX_MBUF_MDATA(sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  17714. + }
  17715. +
  17716. + /* Only need to register if a crypt op or HMAC op */
  17717. + if (!(ixp->ixp_auth_alg == CRYPTO_SHA1 ||
  17718. + ixp->ixp_auth_alg == CRYPTO_MD5)) {
  17719. + status = ixCryptoAccCtxRegister(
  17720. + &ixp->ixp_ctx,
  17721. + pri, sec,
  17722. + ixp_register_cb,
  17723. + ixp_perform_cb,
  17724. + &ixp->ixp_ctx_id);
  17725. + }
  17726. + else {
  17727. + /* Otherwise we start processing pending q */
  17728. + schedule_work(&ixp->ixp_pending_work);
  17729. + }
  17730. +
  17731. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  17732. + return;
  17733. +
  17734. + if (IX_CRYPTO_ACC_STATUS_EXCEED_MAX_TUNNELS == status) {
  17735. + printk("ixp: ixCryptoAccCtxRegister failed (out of tunnels)\n");
  17736. + ixp_blocked = 1;
  17737. + /* perhaps we should return EGAIN on queued ops ? */
  17738. + return;
  17739. + }
  17740. +
  17741. + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
  17742. + ixp->ixp_ctx_id = -1;
  17743. +
  17744. + /*
  17745. + * everything waiting is toasted
  17746. + */
  17747. + while (!list_empty(&ixp->ixp_q)) {
  17748. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  17749. + list_del(&q->ixp_q_list);
  17750. + q->ixp_q_crp->crp_etype = ENOENT;
  17751. + crypto_done(q->ixp_q_crp);
  17752. + kmem_cache_free(qcache, q);
  17753. + }
  17754. +}
  17755. +
  17756. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  17757. +static void
  17758. +ixp_registration_wq(struct work_struct *work)
  17759. +{
  17760. + struct ixp_data *ixp = container_of(work, struct ixp_data,
  17761. + ixp_registration_work);
  17762. + ixp_registration(ixp);
  17763. +}
  17764. +#endif
  17765. +
  17766. +/*
  17767. + * Process a request.
  17768. + */
  17769. +static int
  17770. +ixp_process(device_t dev, struct cryptop *crp, int hint)
  17771. +{
  17772. + struct ixp_data *ixp;
  17773. + unsigned int lid;
  17774. + struct ixp_q *q = NULL;
  17775. + int status;
  17776. +
  17777. + dprintk("%s()\n", __FUNCTION__);
  17778. +
  17779. + /* Sanity check */
  17780. + if (crp == NULL) {
  17781. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  17782. + return EINVAL;
  17783. + }
  17784. +
  17785. + crp->crp_etype = 0;
  17786. +
  17787. + if (ixp_blocked)
  17788. + return ERESTART;
  17789. +
  17790. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  17791. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  17792. + crp->crp_etype = EINVAL;
  17793. + goto done;
  17794. + }
  17795. +
  17796. + /*
  17797. + * find the session we are using
  17798. + */
  17799. +
  17800. + lid = crp->crp_sid & 0xffffffff;
  17801. + if (lid >= ixp_sesnum || lid == 0 || ixp_sessions == NULL ||
  17802. + ixp_sessions[lid] == NULL) {
  17803. + crp->crp_etype = ENOENT;
  17804. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  17805. + goto done;
  17806. + }
  17807. + ixp = ixp_sessions[lid];
  17808. +
  17809. + /*
  17810. + * setup a new request ready for queuing
  17811. + */
  17812. + q = kmem_cache_alloc(qcache, SLAB_ATOMIC);
  17813. + if (q == NULL) {
  17814. + dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
  17815. + crp->crp_etype = ENOMEM;
  17816. + goto done;
  17817. + }
  17818. + /*
  17819. + * save some cycles by only zeroing the important bits
  17820. + */
  17821. + memset(&q->ixp_q_mbuf, 0, sizeof(q->ixp_q_mbuf));
  17822. + q->ixp_q_ccrd = NULL;
  17823. + q->ixp_q_acrd = NULL;
  17824. + q->ixp_q_crp = crp;
  17825. + q->ixp_q_data = ixp;
  17826. +
  17827. + /*
  17828. + * point the cipher and auth descriptors appropriately
  17829. + * check that we have something to do
  17830. + */
  17831. + if (crp->crp_desc->crd_alg == ixp->ixp_cipher_alg)
  17832. + q->ixp_q_ccrd = crp->crp_desc;
  17833. + else if (crp->crp_desc->crd_alg == ixp->ixp_auth_alg)
  17834. + q->ixp_q_acrd = crp->crp_desc;
  17835. + else {
  17836. + crp->crp_etype = ENOENT;
  17837. + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
  17838. + goto done;
  17839. + }
  17840. + if (crp->crp_desc->crd_next) {
  17841. + if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_cipher_alg)
  17842. + q->ixp_q_ccrd = crp->crp_desc->crd_next;
  17843. + else if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_auth_alg)
  17844. + q->ixp_q_acrd = crp->crp_desc->crd_next;
  17845. + else {
  17846. + crp->crp_etype = ENOENT;
  17847. + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
  17848. + goto done;
  17849. + }
  17850. + }
  17851. +
  17852. + /*
  17853. + * If there is a direction change for this context then we mark it as
  17854. + * unregistered and re-register is for the new direction. This is not
  17855. + * a very expensive operation and currently only tends to happen when
  17856. + * user-space application are doing benchmarks
  17857. + *
  17858. + * DM - we should be checking for pending requests before unregistering.
  17859. + */
  17860. + if (q->ixp_q_ccrd && ixp->ixp_registered &&
  17861. + ixp->ixp_crd_flags != (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT)) {
  17862. + dprintk("%s - detected direction change on session\n", __FUNCTION__);
  17863. + ixp->ixp_registered = 0;
  17864. + }
  17865. +
  17866. + /*
  17867. + * if we are registered, call straight into the perform code
  17868. + */
  17869. + if (ixp->ixp_registered) {
  17870. + ixp_q_process(q);
  17871. + return 0;
  17872. + }
  17873. +
  17874. + /*
  17875. + * the only part of the context not set in newsession is the direction
  17876. + * dependent parts
  17877. + */
  17878. + if (q->ixp_q_ccrd) {
  17879. + ixp->ixp_crd_flags = (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT);
  17880. + if (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT) {
  17881. + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
  17882. + IX_CRYPTO_ACC_OP_ENCRYPT_AUTH : IX_CRYPTO_ACC_OP_ENCRYPT;
  17883. + } else {
  17884. + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
  17885. + IX_CRYPTO_ACC_OP_AUTH_DECRYPT : IX_CRYPTO_ACC_OP_DECRYPT;
  17886. + }
  17887. + } else {
  17888. + /* q->ixp_q_acrd must be set if we are here */
  17889. + ixp->ixp_ctx.operation = IX_CRYPTO_ACC_OP_AUTH_CALC;
  17890. + }
  17891. +
  17892. + status = list_empty(&ixp->ixp_q);
  17893. + list_add_tail(&q->ixp_q_list, &ixp->ixp_q);
  17894. + if (status)
  17895. + schedule_work(&ixp->ixp_registration_work);
  17896. + return 0;
  17897. +
  17898. +done:
  17899. + if (q)
  17900. + kmem_cache_free(qcache, q);
  17901. + crypto_done(crp);
  17902. + return 0;
  17903. +}
  17904. +
  17905. +
  17906. +#ifdef __ixp46X
  17907. +/*
  17908. + * key processing support for the ixp465
  17909. + */
  17910. +
  17911. +
  17912. +/*
  17913. + * copy a BN (LE) into a buffer (BE) an fill out the op appropriately
  17914. + * assume zeroed and only copy bits that are significant
  17915. + */
  17916. +
  17917. +static int
  17918. +ixp_copy_ibuf(struct crparam *p, IxCryptoAccPkeEauOperand *op, UINT32 *buf)
  17919. +{
  17920. + unsigned char *src = (unsigned char *) p->crp_p;
  17921. + unsigned char *dst;
  17922. + int len, bits = p->crp_nbits;
  17923. +
  17924. + dprintk("%s()\n", __FUNCTION__);
  17925. +
  17926. + if (bits > MAX_IOP_SIZE * sizeof(UINT32) * 8) {
  17927. + dprintk("%s - ibuf too big (%d > %d)\n", __FUNCTION__,
  17928. + bits, MAX_IOP_SIZE * sizeof(UINT32) * 8);
  17929. + return -1;
  17930. + }
  17931. +
  17932. + len = (bits + 31) / 32; /* the number UINT32's needed */
  17933. +
  17934. + dst = (unsigned char *) &buf[len];
  17935. + dst--;
  17936. +
  17937. + while (bits > 0) {
  17938. + *dst-- = *src++;
  17939. + bits -= 8;
  17940. + }
  17941. +
  17942. +#if 0 /* no need to zero remaining bits as it is done during request alloc */
  17943. + while (dst > (unsigned char *) buf)
  17944. + *dst-- = '\0';
  17945. +#endif
  17946. +
  17947. + op->pData = buf;
  17948. + op->dataLen = len;
  17949. + return 0;
  17950. +}
  17951. +
  17952. +/*
  17953. + * copy out the result, be as forgiving as we can about small output buffers
  17954. + */
  17955. +
  17956. +static int
  17957. +ixp_copy_obuf(struct crparam *p, IxCryptoAccPkeEauOpResult *op, UINT32 *buf)
  17958. +{
  17959. + unsigned char *dst = (unsigned char *) p->crp_p;
  17960. + unsigned char *src = (unsigned char *) buf;
  17961. + int len, z, bits = p->crp_nbits;
  17962. +
  17963. + dprintk("%s()\n", __FUNCTION__);
  17964. +
  17965. + len = op->dataLen * sizeof(UINT32);
  17966. +
  17967. + /* skip leading zeroes to be small buffer friendly */
  17968. + z = 0;
  17969. + while (z < len && src[z] == '\0')
  17970. + z++;
  17971. +
  17972. + src += len;
  17973. + src--;
  17974. + len -= z;
  17975. +
  17976. + while (len > 0 && bits > 0) {
  17977. + *dst++ = *src--;
  17978. + len--;
  17979. + bits -= 8;
  17980. + }
  17981. +
  17982. + while (bits > 0) {
  17983. + *dst++ = '\0';
  17984. + bits -= 8;
  17985. + }
  17986. +
  17987. + if (len > 0) {
  17988. + dprintk("%s - obuf is %d (z=%d, ob=%d) bytes too small\n",
  17989. + __FUNCTION__, len, z, p->crp_nbits / 8);
  17990. + return -1;
  17991. + }
  17992. +
  17993. + return 0;
  17994. +}
  17995. +
  17996. +
  17997. +/*
  17998. + * the parameter offsets for exp_mod
  17999. + */
  18000. +
  18001. +#define IXP_PARAM_BASE 0
  18002. +#define IXP_PARAM_EXP 1
  18003. +#define IXP_PARAM_MOD 2
  18004. +#define IXP_PARAM_RES 3
  18005. +
  18006. +/*
  18007. + * key processing complete callback, is also used to start processing
  18008. + * by passing a NULL for pResult
  18009. + */
  18010. +
  18011. +static void
  18012. +ixp_kperform_cb(
  18013. + IxCryptoAccPkeEauOperation operation,
  18014. + IxCryptoAccPkeEauOpResult *pResult,
  18015. + BOOL carryOrBorrow,
  18016. + IxCryptoAccStatus status)
  18017. +{
  18018. + struct ixp_pkq *q, *tmp;
  18019. + unsigned long flags;
  18020. +
  18021. + dprintk("%s(0x%x, %p, %d, 0x%x)\n", __FUNCTION__, operation, pResult,
  18022. + carryOrBorrow, status);
  18023. +
  18024. + /* handle a completed request */
  18025. + if (pResult) {
  18026. + if (ixp_pk_cur && &ixp_pk_cur->pkq_result == pResult) {
  18027. + q = ixp_pk_cur;
  18028. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  18029. + dprintk("%s() - op failed 0x%x\n", __FUNCTION__, status);
  18030. + q->pkq_krp->krp_status = ERANGE; /* could do better */
  18031. + } else {
  18032. + /* copy out the result */
  18033. + if (ixp_copy_obuf(&q->pkq_krp->krp_param[IXP_PARAM_RES],
  18034. + &q->pkq_result, q->pkq_obuf))
  18035. + q->pkq_krp->krp_status = ERANGE;
  18036. + }
  18037. + crypto_kdone(q->pkq_krp);
  18038. + kfree(q);
  18039. + ixp_pk_cur = NULL;
  18040. + } else
  18041. + printk("%s - callback with invalid result pointer\n", __FUNCTION__);
  18042. + }
  18043. +
  18044. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  18045. + if (ixp_pk_cur || list_empty(&ixp_pkq)) {
  18046. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  18047. + return;
  18048. + }
  18049. +
  18050. + list_for_each_entry_safe(q, tmp, &ixp_pkq, pkq_list) {
  18051. +
  18052. + list_del(&q->pkq_list);
  18053. + ixp_pk_cur = q;
  18054. +
  18055. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  18056. +
  18057. + status = ixCryptoAccPkeEauPerform(
  18058. + IX_CRYPTO_ACC_OP_EAU_MOD_EXP,
  18059. + &q->pkq_op,
  18060. + ixp_kperform_cb,
  18061. + &q->pkq_result);
  18062. +
  18063. + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
  18064. + dprintk("%s() - ixCryptoAccPkeEauPerform SUCCESS\n", __FUNCTION__);
  18065. + return; /* callback will return here for callback */
  18066. + } else if (status == IX_CRYPTO_ACC_STATUS_RETRY) {
  18067. + printk("%s() - ixCryptoAccPkeEauPerform RETRY\n", __FUNCTION__);
  18068. + } else {
  18069. + printk("%s() - ixCryptoAccPkeEauPerform failed %d\n",
  18070. + __FUNCTION__, status);
  18071. + }
  18072. + q->pkq_krp->krp_status = ERANGE; /* could do better */
  18073. + crypto_kdone(q->pkq_krp);
  18074. + kfree(q);
  18075. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  18076. + }
  18077. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  18078. +}
  18079. +
  18080. +
  18081. +static int
  18082. +ixp_kprocess(device_t dev, struct cryptkop *krp, int hint)
  18083. +{
  18084. + struct ixp_pkq *q;
  18085. + int rc = 0;
  18086. + unsigned long flags;
  18087. +
  18088. + dprintk("%s l1=%d l2=%d l3=%d l4=%d\n", __FUNCTION__,
  18089. + krp->krp_param[IXP_PARAM_BASE].crp_nbits,
  18090. + krp->krp_param[IXP_PARAM_EXP].crp_nbits,
  18091. + krp->krp_param[IXP_PARAM_MOD].crp_nbits,
  18092. + krp->krp_param[IXP_PARAM_RES].crp_nbits);
  18093. +
  18094. +
  18095. + if (krp->krp_op != CRK_MOD_EXP) {
  18096. + krp->krp_status = EOPNOTSUPP;
  18097. + goto err;
  18098. + }
  18099. +
  18100. + q = (struct ixp_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
  18101. + if (q == NULL) {
  18102. + krp->krp_status = ENOMEM;
  18103. + goto err;
  18104. + }
  18105. +
  18106. + /*
  18107. + * The PKE engine does not appear to zero the output buffer
  18108. + * appropriately, so we need to do it all here.
  18109. + */
  18110. + memset(q, 0, sizeof(*q));
  18111. +
  18112. + q->pkq_krp = krp;
  18113. + INIT_LIST_HEAD(&q->pkq_list);
  18114. +
  18115. + if (ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_BASE], &q->pkq_op.modExpOpr.M,
  18116. + q->pkq_ibuf0))
  18117. + rc = 1;
  18118. + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_EXP],
  18119. + &q->pkq_op.modExpOpr.e, q->pkq_ibuf1))
  18120. + rc = 2;
  18121. + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_MOD],
  18122. + &q->pkq_op.modExpOpr.N, q->pkq_ibuf2))
  18123. + rc = 3;
  18124. +
  18125. + if (rc) {
  18126. + kfree(q);
  18127. + krp->krp_status = ERANGE;
  18128. + goto err;
  18129. + }
  18130. +
  18131. + q->pkq_result.pData = q->pkq_obuf;
  18132. + q->pkq_result.dataLen =
  18133. + (krp->krp_param[IXP_PARAM_RES].crp_nbits + 31) / 32;
  18134. +
  18135. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  18136. + list_add_tail(&q->pkq_list, &ixp_pkq);
  18137. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  18138. +
  18139. + if (!ixp_pk_cur)
  18140. + ixp_kperform_cb(0, NULL, 0, 0);
  18141. + return (0);
  18142. +
  18143. +err:
  18144. + crypto_kdone(krp);
  18145. + return (0);
  18146. +}
  18147. +
  18148. +
  18149. +
  18150. +#ifdef CONFIG_OCF_RANDOMHARVEST
  18151. +/*
  18152. + * We run the random number generator output through SHA so that it
  18153. + * is FIPS compliant.
  18154. + */
  18155. +
  18156. +static volatile int sha_done = 0;
  18157. +static unsigned char sha_digest[20];
  18158. +
  18159. +static void
  18160. +ixp_hash_cb(UINT8 *digest, IxCryptoAccStatus status)
  18161. +{
  18162. + dprintk("%s(%p, %d)\n", __FUNCTION__, digest, status);
  18163. + if (sha_digest != digest)
  18164. + printk("digest error\n");
  18165. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  18166. + sha_done = 1;
  18167. + else
  18168. + sha_done = -status;
  18169. +}
  18170. +
  18171. +static int
  18172. +ixp_read_random(void *arg, u_int32_t *buf, int maxwords)
  18173. +{
  18174. + IxCryptoAccStatus status;
  18175. + int i, n, rc;
  18176. +
  18177. + dprintk("%s(%p, %d)\n", __FUNCTION__, buf, maxwords);
  18178. + memset(buf, 0, maxwords * sizeof(*buf));
  18179. + status = ixCryptoAccPkePseudoRandomNumberGet(maxwords, buf);
  18180. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  18181. + dprintk("%s: ixCryptoAccPkePseudoRandomNumberGet failed %d\n",
  18182. + __FUNCTION__, status);
  18183. + return 0;
  18184. + }
  18185. +
  18186. + /*
  18187. + * run the random data through SHA to make it look more random
  18188. + */
  18189. +
  18190. + n = sizeof(sha_digest); /* process digest bytes at a time */
  18191. +
  18192. + rc = 0;
  18193. + for (i = 0; i < maxwords; i += n / sizeof(*buf)) {
  18194. + if ((maxwords - i) * sizeof(*buf) < n)
  18195. + n = (maxwords - i) * sizeof(*buf);
  18196. + sha_done = 0;
  18197. + status = ixCryptoAccPkeHashPerform(IX_CRYPTO_ACC_AUTH_SHA1,
  18198. + (UINT8 *) &buf[i], n, ixp_hash_cb, sha_digest);
  18199. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  18200. + dprintk("ixCryptoAccPkeHashPerform failed %d\n", status);
  18201. + return -EIO;
  18202. + }
  18203. + while (!sha_done)
  18204. + schedule();
  18205. + if (sha_done < 0) {
  18206. + dprintk("ixCryptoAccPkeHashPerform failed CB %d\n", -sha_done);
  18207. + return 0;
  18208. + }
  18209. + memcpy(&buf[i], sha_digest, n);
  18210. + rc += n / sizeof(*buf);;
  18211. + }
  18212. +
  18213. + return rc;
  18214. +}
  18215. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  18216. +
  18217. +#endif /* __ixp46X */
  18218. +
  18219. +
  18220. +
  18221. +/*
  18222. + * our driver startup and shutdown routines
  18223. + */
  18224. +
  18225. +static int
  18226. +ixp_init(void)
  18227. +{
  18228. + dprintk("%s(%p)\n", __FUNCTION__, ixp_init);
  18229. +
  18230. + if (ixp_init_crypto && ixCryptoAccInit() != IX_CRYPTO_ACC_STATUS_SUCCESS)
  18231. + printk("ixCryptoAccInit failed, assuming already initialised!\n");
  18232. +
  18233. + qcache = kmem_cache_create("ixp4xx_q", sizeof(struct ixp_q), 0,
  18234. + SLAB_HWCACHE_ALIGN, NULL
  18235. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  18236. + , NULL
  18237. +#endif
  18238. + );
  18239. + if (!qcache) {
  18240. + printk("failed to create Qcache\n");
  18241. + return -ENOENT;
  18242. + }
  18243. +
  18244. + memset(&ixpdev, 0, sizeof(ixpdev));
  18245. + softc_device_init(&ixpdev, "ixp4xx", 0, ixp_methods);
  18246. +
  18247. + ixp_id = crypto_get_driverid(softc_get_device(&ixpdev),
  18248. + CRYPTOCAP_F_HARDWARE);
  18249. + if (ixp_id < 0)
  18250. + panic("IXP/OCF crypto device cannot initialize!");
  18251. +
  18252. +#define REGISTER(alg) \
  18253. + crypto_register(ixp_id,alg,0,0)
  18254. +
  18255. + REGISTER(CRYPTO_DES_CBC);
  18256. + REGISTER(CRYPTO_3DES_CBC);
  18257. + REGISTER(CRYPTO_RIJNDAEL128_CBC);
  18258. +#ifdef CONFIG_OCF_IXP4XX_SHA1_MD5
  18259. + REGISTER(CRYPTO_MD5);
  18260. + REGISTER(CRYPTO_SHA1);
  18261. +#endif
  18262. + REGISTER(CRYPTO_MD5_HMAC);
  18263. + REGISTER(CRYPTO_SHA1_HMAC);
  18264. +#undef REGISTER
  18265. +
  18266. +#ifdef __ixp46X
  18267. + spin_lock_init(&ixp_pkq_lock);
  18268. + /*
  18269. + * we do not enable the go fast options here as they can potentially
  18270. + * allow timing based attacks
  18271. + *
  18272. + * http://www.openssl.org/news/secadv_20030219.txt
  18273. + */
  18274. + ixCryptoAccPkeEauExpConfig(0, 0);
  18275. + crypto_kregister(ixp_id, CRK_MOD_EXP, 0);
  18276. +#ifdef CONFIG_OCF_RANDOMHARVEST
  18277. + crypto_rregister(ixp_id, ixp_read_random, NULL);
  18278. +#endif
  18279. +#endif
  18280. +
  18281. + return 0;
  18282. +}
  18283. +
  18284. +static void
  18285. +ixp_exit(void)
  18286. +{
  18287. + dprintk("%s()\n", __FUNCTION__);
  18288. + crypto_unregister_all(ixp_id);
  18289. + ixp_id = -1;
  18290. + kmem_cache_destroy(qcache);
  18291. + qcache = NULL;
  18292. +}
  18293. +
  18294. +module_init(ixp_init);
  18295. +module_exit(ixp_exit);
  18296. +
  18297. +MODULE_LICENSE("Dual BSD/GPL");
  18298. +MODULE_AUTHOR("David McCullough <dmccullough@cyberguard.com>");
  18299. +MODULE_DESCRIPTION("ixp (OCF module for IXP4xx crypto)");
  18300. diff -Nur linux-2.6.36.orig/crypto/ocf/ixp4xx/Makefile linux-2.6.36/crypto/ocf/ixp4xx/Makefile
  18301. --- linux-2.6.36.orig/crypto/ocf/ixp4xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  18302. +++ linux-2.6.36/crypto/ocf/ixp4xx/Makefile 2010-11-09 20:28:05.113478850 +0100
  18303. @@ -0,0 +1,104 @@
  18304. +# for SGlinux builds
  18305. +-include $(ROOTDIR)/modules/.config
  18306. +
  18307. +#
  18308. +# You will need to point this at your Intel ixp425 includes, this portion
  18309. +# of the Makefile only really works under SGLinux with the appropriate libs
  18310. +# installed. They can be downloaded from http://www.snapgear.org/
  18311. +#
  18312. +ifeq ($(CONFIG_CPU_IXP46X),y)
  18313. +IXPLATFORM = ixp46X
  18314. +else
  18315. +ifeq ($(CONFIG_CPU_IXP43X),y)
  18316. +IXPLATFORM = ixp43X
  18317. +else
  18318. +IXPLATFORM = ixp42X
  18319. +endif
  18320. +endif
  18321. +
  18322. +ifdef CONFIG_IXP400_LIB_2_4
  18323. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp400_xscale_sw
  18324. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp_osal
  18325. +endif
  18326. +ifdef CONFIG_IXP400_LIB_2_1
  18327. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp400_xscale_sw
  18328. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp_osal
  18329. +endif
  18330. +ifdef CONFIG_IXP400_LIB_2_0
  18331. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp400_xscale_sw
  18332. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp_osal
  18333. +endif
  18334. +ifdef IX_XSCALE_SW
  18335. +ifdef CONFIG_IXP400_LIB_2_4
  18336. +IXP_CFLAGS = \
  18337. + -I$(ROOTDIR)/. \
  18338. + -I$(IX_XSCALE_SW)/src/include \
  18339. + -I$(OSAL_DIR)/common/include/ \
  18340. + -I$(OSAL_DIR)/common/include/modules/ \
  18341. + -I$(OSAL_DIR)/common/include/modules/ddk/ \
  18342. + -I$(OSAL_DIR)/common/include/modules/bufferMgt/ \
  18343. + -I$(OSAL_DIR)/common/include/modules/ioMem/ \
  18344. + -I$(OSAL_DIR)/common/os/linux/include/ \
  18345. + -I$(OSAL_DIR)/common/os/linux/include/core/ \
  18346. + -I$(OSAL_DIR)/common/os/linux/include/modules/ \
  18347. + -I$(OSAL_DIR)/common/os/linux/include/modules/ddk/ \
  18348. + -I$(OSAL_DIR)/common/os/linux/include/modules/bufferMgt/ \
  18349. + -I$(OSAL_DIR)/common/os/linux/include/modules/ioMem/ \
  18350. + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/include/ \
  18351. + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/os/linux/include/ \
  18352. + -DENABLE_IOMEM -DENABLE_BUFFERMGT -DENABLE_DDK \
  18353. + -DUSE_IXP4XX_CRYPTO
  18354. +else
  18355. +IXP_CFLAGS = \
  18356. + -I$(ROOTDIR)/. \
  18357. + -I$(IX_XSCALE_SW)/src/include \
  18358. + -I$(OSAL_DIR)/ \
  18359. + -I$(OSAL_DIR)/os/linux/include/ \
  18360. + -I$(OSAL_DIR)/os/linux/include/modules/ \
  18361. + -I$(OSAL_DIR)/os/linux/include/modules/ioMem/ \
  18362. + -I$(OSAL_DIR)/os/linux/include/modules/bufferMgt/ \
  18363. + -I$(OSAL_DIR)/os/linux/include/core/ \
  18364. + -I$(OSAL_DIR)/os/linux/include/platforms/ \
  18365. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ \
  18366. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp425 \
  18367. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp465 \
  18368. + -I$(OSAL_DIR)/os/linux/include/core/ \
  18369. + -I$(OSAL_DIR)/include/ \
  18370. + -I$(OSAL_DIR)/include/modules/ \
  18371. + -I$(OSAL_DIR)/include/modules/bufferMgt/ \
  18372. + -I$(OSAL_DIR)/include/modules/ioMem/ \
  18373. + -I$(OSAL_DIR)/include/platforms/ \
  18374. + -I$(OSAL_DIR)/include/platforms/ixp400/ \
  18375. + -DUSE_IXP4XX_CRYPTO
  18376. +endif
  18377. +endif
  18378. +ifdef CONFIG_IXP400_LIB_1_4
  18379. +IXP_CFLAGS = \
  18380. + -I$(ROOTDIR)/. \
  18381. + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/include \
  18382. + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/linux \
  18383. + -DUSE_IXP4XX_CRYPTO
  18384. +endif
  18385. +ifndef IXPDIR
  18386. +IXPDIR = ixp-version-is-not-supported
  18387. +endif
  18388. +
  18389. +ifeq ($(CONFIG_CPU_IXP46X),y)
  18390. +IXP_CFLAGS += -D__ixp46X
  18391. +else
  18392. +ifeq ($(CONFIG_CPU_IXP43X),y)
  18393. +IXP_CFLAGS += -D__ixp43X
  18394. +else
  18395. +IXP_CFLAGS += -D__ixp42X
  18396. +endif
  18397. +endif
  18398. +
  18399. +obj-$(CONFIG_OCF_IXP4XX) += ixp4xx.o
  18400. +
  18401. +obj ?= .
  18402. +EXTRA_CFLAGS += $(IXP_CFLAGS) -I$(obj)/.. -I$(obj)/.
  18403. +
  18404. +ifdef TOPDIR
  18405. +-include $(TOPDIR)/Rules.make
  18406. +endif
  18407. +
  18408. diff -Nur linux-2.6.36.orig/crypto/ocf/Kconfig linux-2.6.36/crypto/ocf/Kconfig
  18409. --- linux-2.6.36.orig/crypto/ocf/Kconfig 1970-01-01 01:00:00.000000000 +0100
  18410. +++ linux-2.6.36/crypto/ocf/Kconfig 2010-11-09 20:28:05.141255099 +0100
  18411. @@ -0,0 +1,119 @@
  18412. +menu "OCF Configuration"
  18413. +
  18414. +config OCF_OCF
  18415. + tristate "OCF (Open Cryptograhic Framework)"
  18416. + help
  18417. + A linux port of the OpenBSD/FreeBSD crypto framework.
  18418. +
  18419. +config OCF_RANDOMHARVEST
  18420. + bool "crypto random --- harvest entropy for /dev/random"
  18421. + depends on OCF_OCF
  18422. + help
  18423. + Includes code to harvest random numbers from devices that support it.
  18424. +
  18425. +config OCF_FIPS
  18426. + bool "enable fips RNG checks"
  18427. + depends on OCF_OCF && OCF_RANDOMHARVEST
  18428. + help
  18429. + Run all RNG provided data through a fips check before
  18430. + adding it /dev/random's entropy pool.
  18431. +
  18432. +config OCF_CRYPTODEV
  18433. + tristate "cryptodev (user space support)"
  18434. + depends on OCF_OCF
  18435. + help
  18436. + The user space API to access crypto hardware.
  18437. +
  18438. +config OCF_CRYPTOSOFT
  18439. + tristate "cryptosoft (software crypto engine)"
  18440. + depends on OCF_OCF
  18441. + help
  18442. + A software driver for the OCF framework that uses
  18443. + the kernel CryptoAPI.
  18444. +
  18445. +config OCF_SAFE
  18446. + tristate "safenet (HW crypto engine)"
  18447. + depends on OCF_OCF
  18448. + help
  18449. + A driver for a number of the safenet Excel crypto accelerators.
  18450. + Currently tested and working on the 1141 and 1741.
  18451. +
  18452. +config OCF_IXP4XX
  18453. + tristate "IXP4xx (HW crypto engine)"
  18454. + depends on OCF_OCF
  18455. + help
  18456. + XScale IXP4xx crypto accelerator driver. Requires the
  18457. + Intel Access library.
  18458. +
  18459. +config OCF_IXP4XX_SHA1_MD5
  18460. + bool "IXP4xx SHA1 and MD5 Hashing"
  18461. + depends on OCF_IXP4XX
  18462. + help
  18463. + Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.
  18464. + Note: this is MUCH slower than using cryptosoft (software crypto engine).
  18465. +
  18466. +config OCF_HIFN
  18467. + tristate "hifn (HW crypto engine)"
  18468. + depends on OCF_OCF
  18469. + help
  18470. + OCF driver for various HIFN based crypto accelerators.
  18471. + (7951, 7955, 7956, 7751, 7811)
  18472. +
  18473. +config OCF_HIFNHIPP
  18474. + tristate "Hifn HIPP (HW packet crypto engine)"
  18475. + depends on OCF_OCF
  18476. + help
  18477. + OCF driver for various HIFN (HIPP) based crypto accelerators
  18478. + (7855)
  18479. +
  18480. +config OCF_TALITOS
  18481. + tristate "talitos (HW crypto engine)"
  18482. + depends on OCF_OCF
  18483. + help
  18484. + OCF driver for Freescale's security engine (SEC/talitos).
  18485. +
  18486. +config OCF_PASEMI
  18487. + tristate "pasemi (HW crypto engine)"
  18488. + depends on OCF_OCF && PPC_PASEMI
  18489. + help
  18490. + OCF driver for the PA Semi PWRficient DMA Engine
  18491. +
  18492. +config OCF_EP80579
  18493. + tristate "ep80579 (HW crypto engine)"
  18494. + depends on OCF_OCF
  18495. + help
  18496. + OCF driver for the Intel EP80579 Integrated Processor Product Line.
  18497. +
  18498. +config OCF_CRYPTOCTEON
  18499. + tristate "cryptocteon (HW crypto engine)"
  18500. + depends on OCF_OCF
  18501. + help
  18502. + OCF driver for the Cavium OCTEON Processors.
  18503. +
  18504. +config OCF_KIRKWOOD
  18505. + tristate "kirkwood (HW crypto engine)"
  18506. + depends on OCF_OCF
  18507. + help
  18508. + OCF driver for the Marvell Kirkwood (88F6xxx) Processors.
  18509. +
  18510. +config OCF_C7108
  18511. + tristate "Micronas 7108 (HW crypto engine)"
  18512. + depends on OCF_OCF
  18513. + help
  18514. + OCF driver for the Microna 7108 Cipher processors.
  18515. +
  18516. +config OCF_OCFNULL
  18517. + tristate "ocfnull (fake crypto engine)"
  18518. + depends on OCF_OCF
  18519. + help
  18520. + OCF driver for measuring ipsec overheads (does no crypto)
  18521. +
  18522. +config OCF_BENCH
  18523. + tristate "ocf-bench (HW crypto in-kernel benchmark)"
  18524. + depends on OCF_OCF
  18525. + help
  18526. + A very simple encryption test for the in-kernel interface
  18527. + of OCF. Also includes code to benchmark the IXP Access library
  18528. + for comparison.
  18529. +
  18530. +endmenu
  18531. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c
  18532. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c 1970-01-01 01:00:00.000000000 +0100
  18533. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c 2010-11-09 20:28:05.189557501 +0100
  18534. @@ -0,0 +1,317 @@
  18535. +/* rijndael-alg-ref.c v2.0 August '99
  18536. + * Reference ANSI C code
  18537. + * authors: Paulo Barreto
  18538. + * Vincent Rijmen, K.U.Leuven
  18539. + *
  18540. + * This code is placed in the public domain.
  18541. + */
  18542. +
  18543. +#include "mvOs.h"
  18544. +
  18545. +#include "mvAesAlg.h"
  18546. +
  18547. +#include "mvAesBoxes.dat"
  18548. +
  18549. +
  18550. +MV_U8 mul1(MV_U8 aa, MV_U8 bb);
  18551. +void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC);
  18552. +void ShiftRow128Enc(MV_U8 a[4][MAXBC]);
  18553. +void ShiftRow128Dec(MV_U8 a[4][MAXBC]);
  18554. +void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]);
  18555. +void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]);
  18556. +void InvMixColumn(MV_U8 a[4][MAXBC]);
  18557. +
  18558. +
  18559. +#define mul(aa, bb) (mask[bb] & Alogtable[aa + Logtable[bb]])
  18560. +
  18561. +MV_U8 mul1(MV_U8 aa, MV_U8 bb)
  18562. +{
  18563. + return mask[bb] & Alogtable[aa + Logtable[bb]];
  18564. +}
  18565. +
  18566. +
  18567. +void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC)
  18568. +{
  18569. + /* Exor corresponding text input and round key input bytes
  18570. + */
  18571. + ((MV_U32*)(&(a[0][0])))[0] ^= ((MV_U32*)(&(rk[0][0])))[0];
  18572. + ((MV_U32*)(&(a[1][0])))[0] ^= ((MV_U32*)(&(rk[1][0])))[0];
  18573. + ((MV_U32*)(&(a[2][0])))[0] ^= ((MV_U32*)(&(rk[2][0])))[0];
  18574. + ((MV_U32*)(&(a[3][0])))[0] ^= ((MV_U32*)(&(rk[3][0])))[0];
  18575. +
  18576. +}
  18577. +
  18578. +void ShiftRow128Enc(MV_U8 a[4][MAXBC]) {
  18579. + /* Row 0 remains unchanged
  18580. + * The other three rows are shifted a variable amount
  18581. + */
  18582. + MV_U8 tmp[MAXBC];
  18583. +
  18584. + tmp[0] = a[1][1];
  18585. + tmp[1] = a[1][2];
  18586. + tmp[2] = a[1][3];
  18587. + tmp[3] = a[1][0];
  18588. +
  18589. + ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  18590. + /*
  18591. + a[1][0] = tmp[0];
  18592. + a[1][1] = tmp[1];
  18593. + a[1][2] = tmp[2];
  18594. + a[1][3] = tmp[3];
  18595. + */
  18596. + tmp[0] = a[2][2];
  18597. + tmp[1] = a[2][3];
  18598. + tmp[2] = a[2][0];
  18599. + tmp[3] = a[2][1];
  18600. +
  18601. + ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  18602. + /*
  18603. + a[2][0] = tmp[0];
  18604. + a[2][1] = tmp[1];
  18605. + a[2][2] = tmp[2];
  18606. + a[2][3] = tmp[3];
  18607. + */
  18608. + tmp[0] = a[3][3];
  18609. + tmp[1] = a[3][0];
  18610. + tmp[2] = a[3][1];
  18611. + tmp[3] = a[3][2];
  18612. +
  18613. + ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  18614. + /*
  18615. + a[3][0] = tmp[0];
  18616. + a[3][1] = tmp[1];
  18617. + a[3][2] = tmp[2];
  18618. + a[3][3] = tmp[3];
  18619. + */
  18620. +}
  18621. +
  18622. +void ShiftRow128Dec(MV_U8 a[4][MAXBC]) {
  18623. + /* Row 0 remains unchanged
  18624. + * The other three rows are shifted a variable amount
  18625. + */
  18626. + MV_U8 tmp[MAXBC];
  18627. +
  18628. + tmp[0] = a[1][3];
  18629. + tmp[1] = a[1][0];
  18630. + tmp[2] = a[1][1];
  18631. + tmp[3] = a[1][2];
  18632. +
  18633. + ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  18634. + /*
  18635. + a[1][0] = tmp[0];
  18636. + a[1][1] = tmp[1];
  18637. + a[1][2] = tmp[2];
  18638. + a[1][3] = tmp[3];
  18639. + */
  18640. +
  18641. + tmp[0] = a[2][2];
  18642. + tmp[1] = a[2][3];
  18643. + tmp[2] = a[2][0];
  18644. + tmp[3] = a[2][1];
  18645. +
  18646. + ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  18647. + /*
  18648. + a[2][0] = tmp[0];
  18649. + a[2][1] = tmp[1];
  18650. + a[2][2] = tmp[2];
  18651. + a[2][3] = tmp[3];
  18652. + */
  18653. +
  18654. + tmp[0] = a[3][1];
  18655. + tmp[1] = a[3][2];
  18656. + tmp[2] = a[3][3];
  18657. + tmp[3] = a[3][0];
  18658. +
  18659. + ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  18660. + /*
  18661. + a[3][0] = tmp[0];
  18662. + a[3][1] = tmp[1];
  18663. + a[3][2] = tmp[2];
  18664. + a[3][3] = tmp[3];
  18665. + */
  18666. +}
  18667. +
  18668. +void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]) {
  18669. + /* Replace every byte of the input by the byte at that place
  18670. + * in the nonlinear S-box
  18671. + */
  18672. + int i, j;
  18673. +
  18674. + for(i = 0; i < 4; i++)
  18675. + for(j = 0; j < 4; j++) a[i][j] = box[a[i][j]] ;
  18676. +}
  18677. +
  18678. +void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]) {
  18679. + /* Mix the four bytes of every column in a linear way
  18680. + */
  18681. + MV_U8 b[4][MAXBC];
  18682. + int i, j;
  18683. +
  18684. + for(j = 0; j < 4; j++){
  18685. + b[0][j] = mul(25,a[0][j]) ^ mul(1,a[1][j]) ^ a[2][j] ^ a[3][j];
  18686. + b[1][j] = mul(25,a[1][j]) ^ mul(1,a[2][j]) ^ a[3][j] ^ a[0][j];
  18687. + b[2][j] = mul(25,a[2][j]) ^ mul(1,a[3][j]) ^ a[0][j] ^ a[1][j];
  18688. + b[3][j] = mul(25,a[3][j]) ^ mul(1,a[0][j]) ^ a[1][j] ^ a[2][j];
  18689. + }
  18690. + for(i = 0; i < 4; i++)
  18691. + /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
  18692. + ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0] ^ ((MV_U32*)(&(rk[i][0])))[0];;
  18693. +}
  18694. +
  18695. +void InvMixColumn(MV_U8 a[4][MAXBC]) {
  18696. + /* Mix the four bytes of every column in a linear way
  18697. + * This is the opposite operation of Mixcolumn
  18698. + */
  18699. + MV_U8 b[4][MAXBC];
  18700. + int i, j;
  18701. +
  18702. + for(j = 0; j < 4; j++){
  18703. + b[0][j] = mul(223,a[0][j]) ^ mul(104,a[1][j]) ^ mul(238,a[2][j]) ^ mul(199,a[3][j]);
  18704. + b[1][j] = mul(223,a[1][j]) ^ mul(104,a[2][j]) ^ mul(238,a[3][j]) ^ mul(199,a[0][j]);
  18705. + b[2][j] = mul(223,a[2][j]) ^ mul(104,a[3][j]) ^ mul(238,a[0][j]) ^ mul(199,a[1][j]);
  18706. + b[3][j] = mul(223,a[3][j]) ^ mul(104,a[0][j]) ^ mul(238,a[1][j]) ^ mul(199,a[2][j]);
  18707. + }
  18708. + for(i = 0; i < 4; i++)
  18709. + /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
  18710. + ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0];
  18711. +}
  18712. +
  18713. +int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 W[MAXROUNDS+1][4][MAXBC])
  18714. +{
  18715. + /* Calculate the necessary round keys
  18716. + * The number of calculations depends on keyBits and blockBits
  18717. + */
  18718. + int KC, BC, ROUNDS;
  18719. + int i, j, t, rconpointer = 0;
  18720. + MV_U8 tk[4][MAXKC];
  18721. +
  18722. + switch (keyBits) {
  18723. + case 128: KC = 4; break;
  18724. + case 192: KC = 6; break;
  18725. + case 256: KC = 8; break;
  18726. + default : return (-1);
  18727. + }
  18728. +
  18729. + switch (blockBits) {
  18730. + case 128: BC = 4; break;
  18731. + case 192: BC = 6; break;
  18732. + case 256: BC = 8; break;
  18733. + default : return (-2);
  18734. + }
  18735. +
  18736. + switch (keyBits >= blockBits ? keyBits : blockBits) {
  18737. + case 128: ROUNDS = 10; break;
  18738. + case 192: ROUNDS = 12; break;
  18739. + case 256: ROUNDS = 14; break;
  18740. + default : return (-3); /* this cannot happen */
  18741. + }
  18742. +
  18743. +
  18744. + for(j = 0; j < KC; j++)
  18745. + for(i = 0; i < 4; i++)
  18746. + tk[i][j] = k[i][j];
  18747. + t = 0;
  18748. + /* copy values into round key array */
  18749. + for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
  18750. + for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
  18751. +
  18752. + while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
  18753. + /* calculate new values */
  18754. + for(i = 0; i < 4; i++)
  18755. + tk[i][0] ^= S[tk[(i+1)%4][KC-1]];
  18756. + tk[0][0] ^= rcon[rconpointer++];
  18757. +
  18758. + if (KC != 8)
  18759. + for(j = 1; j < KC; j++)
  18760. + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  18761. + else {
  18762. + for(j = 1; j < KC/2; j++)
  18763. + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  18764. + for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]];
  18765. + for(j = KC/2 + 1; j < KC; j++)
  18766. + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  18767. + }
  18768. + /* copy values into round key array */
  18769. + for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
  18770. + for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
  18771. + }
  18772. +
  18773. + return 0;
  18774. +}
  18775. +
  18776. +
  18777. +
  18778. +int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
  18779. +{
  18780. + /* Encryption of one block.
  18781. + */
  18782. + int r, BC, ROUNDS;
  18783. +
  18784. + BC = 4;
  18785. + ROUNDS = rounds;
  18786. +
  18787. + /* begin with a key addition
  18788. + */
  18789. +
  18790. + KeyAddition(a,rk[0],BC);
  18791. +
  18792. + /* ROUNDS-1 ordinary rounds
  18793. + */
  18794. + for(r = 1; r < ROUNDS; r++) {
  18795. + Substitution(a,S);
  18796. + ShiftRow128Enc(a);
  18797. + MixColumn(a, rk[r]);
  18798. + /*KeyAddition(a,rk[r],BC);*/
  18799. + }
  18800. +
  18801. + /* Last round is special: there is no MixColumn
  18802. + */
  18803. + Substitution(a,S);
  18804. + ShiftRow128Enc(a);
  18805. + KeyAddition(a,rk[ROUNDS],BC);
  18806. +
  18807. + return 0;
  18808. +}
  18809. +
  18810. +
  18811. +int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
  18812. +{
  18813. + int r, BC, ROUNDS;
  18814. +
  18815. + BC = 4;
  18816. + ROUNDS = rounds;
  18817. +
  18818. + /* To decrypt: apply the inverse operations of the encrypt routine,
  18819. + * in opposite order
  18820. + *
  18821. + * (KeyAddition is an involution: it 's equal to its inverse)
  18822. + * (the inverse of Substitution with table S is Substitution with the inverse table of S)
  18823. + * (the inverse of Shiftrow is Shiftrow over a suitable distance)
  18824. + */
  18825. +
  18826. + /* First the special round:
  18827. + * without InvMixColumn
  18828. + * with extra KeyAddition
  18829. + */
  18830. + KeyAddition(a,rk[ROUNDS],BC);
  18831. + ShiftRow128Dec(a);
  18832. + Substitution(a,Si);
  18833. +
  18834. + /* ROUNDS-1 ordinary rounds
  18835. + */
  18836. + for(r = ROUNDS-1; r > 0; r--) {
  18837. + KeyAddition(a,rk[r],BC);
  18838. + InvMixColumn(a);
  18839. + ShiftRow128Dec(a);
  18840. + Substitution(a,Si);
  18841. +
  18842. + }
  18843. +
  18844. + /* End with the extra key addition
  18845. + */
  18846. +
  18847. + KeyAddition(a,rk[0],BC);
  18848. +
  18849. + return 0;
  18850. +}
  18851. +
  18852. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h
  18853. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h 1970-01-01 01:00:00.000000000 +0100
  18854. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h 2010-11-09 20:28:05.222495460 +0100
  18855. @@ -0,0 +1,19 @@
  18856. +/* rijndael-alg-ref.h v2.0 August '99
  18857. + * Reference ANSI C code
  18858. + * authors: Paulo Barreto
  18859. + * Vincent Rijmen, K.U.Leuven
  18860. + */
  18861. +#ifndef __RIJNDAEL_ALG_H
  18862. +#define __RIJNDAEL_ALG_H
  18863. +
  18864. +#define MAXBC (128/32)
  18865. +#define MAXKC (256/32)
  18866. +#define MAXROUNDS 14
  18867. +
  18868. +
  18869. +int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 rk[MAXROUNDS+1][4][MAXBC]);
  18870. +
  18871. +int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
  18872. +int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
  18873. +
  18874. +#endif /* __RIJNDAEL_ALG_H */
  18875. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c
  18876. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c 1970-01-01 01:00:00.000000000 +0100
  18877. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c 2010-11-09 20:28:05.264499847 +0100
  18878. @@ -0,0 +1,312 @@
  18879. +/* rijndael-api-ref.c v2.1 April 2000
  18880. + * Reference ANSI C code
  18881. + * authors: v2.0 Paulo Barreto
  18882. + * Vincent Rijmen, K.U.Leuven
  18883. + * v2.1 Vincent Rijmen, K.U.Leuven
  18884. + *
  18885. + * This code is placed in the public domain.
  18886. + */
  18887. +#include "mvOs.h"
  18888. +
  18889. +#include "mvAes.h"
  18890. +#include "mvAesAlg.h"
  18891. +
  18892. +
  18893. +/* Defines:
  18894. + Add any additional defines you need
  18895. +*/
  18896. +
  18897. +#define MODE_ECB 1 /* Are we ciphering in ECB mode? */
  18898. +#define MODE_CBC 2 /* Are we ciphering in CBC mode? */
  18899. +#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
  18900. +
  18901. +
  18902. +int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen)
  18903. +{
  18904. + MV_U8 W[MAXROUNDS+1][4][MAXBC];
  18905. + MV_U8 k[4][MAXKC];
  18906. + MV_U8 j;
  18907. + int i, rounds, KC;
  18908. +
  18909. + if (expandedKey == NULL)
  18910. + {
  18911. + return AES_BAD_KEY_INSTANCE;
  18912. + }
  18913. +
  18914. + if (!((keyLen == 128) || (keyLen == 192) || (keyLen == 256)))
  18915. + {
  18916. + return AES_BAD_KEY_MAT;
  18917. + }
  18918. +
  18919. + if (keyMaterial == NULL)
  18920. + {
  18921. + return AES_BAD_KEY_MAT;
  18922. + }
  18923. +
  18924. + /* initialize key schedule: */
  18925. + for(i=0; i<keyLen/8; i++)
  18926. + {
  18927. + j = keyMaterial[i];
  18928. + k[i % 4][i / 4] = j;
  18929. + }
  18930. +
  18931. + rijndaelKeySched (k, keyLen, blockLen, W);
  18932. +#ifdef MV_AES_DEBUG
  18933. + {
  18934. + MV_U8* pW = &W[0][0][0];
  18935. + int x;
  18936. +
  18937. + mvOsPrintf("Expended Key: size = %d\n", sizeof(W));
  18938. + for(i=0; i<sizeof(W); i++)
  18939. + {
  18940. + mvOsPrintf("%02x ", pW[i]);
  18941. + }
  18942. + for(i=0; i<MAXROUNDS+1; i++)
  18943. + {
  18944. + mvOsPrintf("\n Round #%02d: ", i);
  18945. + for(x=0; x<MAXBC; x++)
  18946. + {
  18947. + mvOsPrintf("%02x%02x%02x%02x ",
  18948. + W[i][0][x], W[i][1][x], W[i][2][x], W[i][3][x]);
  18949. + }
  18950. + mvOsPrintf("\n");
  18951. + }
  18952. + }
  18953. +#endif /* MV_AES_DEBUG */
  18954. + switch (keyLen)
  18955. + {
  18956. + case 128:
  18957. + rounds = 10;
  18958. + KC = 4;
  18959. + break;
  18960. + case 192:
  18961. + rounds = 12;
  18962. + KC = 6;
  18963. + break;
  18964. + case 256:
  18965. + rounds = 14;
  18966. + KC = 8;
  18967. + break;
  18968. + default :
  18969. + return (-1);
  18970. + }
  18971. +
  18972. + for(i=0; i<MAXBC; i++)
  18973. + {
  18974. + for(j=0; j<4; j++)
  18975. + {
  18976. + expandedKey[i*4+j] = W[rounds][j][i];
  18977. + }
  18978. + }
  18979. + for(; i<KC; i++)
  18980. + {
  18981. + for(j=0; j<4; j++)
  18982. + {
  18983. + expandedKey[i*4+j] = W[rounds-1][j][i+MAXBC-KC];
  18984. + }
  18985. + }
  18986. +
  18987. +
  18988. + return 0;
  18989. +}
  18990. +
  18991. +int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  18992. + MV_U32 *plain, int numBlocks, MV_U32 *cipher)
  18993. +{
  18994. + int i, j, t;
  18995. + MV_U8 block[4][MAXBC];
  18996. + int rounds;
  18997. + char *input, *outBuffer;
  18998. +
  18999. + input = (char*)plain;
  19000. + outBuffer = (char*)cipher;
  19001. +
  19002. + /* check parameter consistency: */
  19003. + if( (expandedKey == NULL) || ((keyLen != 128) && (keyLen != 192) && (keyLen != 256)))
  19004. + {
  19005. + return AES_BAD_KEY_MAT;
  19006. + }
  19007. + if ((mode != MODE_ECB && mode != MODE_CBC))
  19008. + {
  19009. + return AES_BAD_CIPHER_STATE;
  19010. + }
  19011. +
  19012. + switch (keyLen)
  19013. + {
  19014. + case 128: rounds = 10; break;
  19015. + case 192: rounds = 12; break;
  19016. + case 256: rounds = 14; break;
  19017. + default : return (-3); /* this cannot happen */
  19018. + }
  19019. +
  19020. +
  19021. + switch (mode)
  19022. + {
  19023. + case MODE_ECB:
  19024. + for (i = 0; i < numBlocks; i++)
  19025. + {
  19026. + for (j = 0; j < 4; j++)
  19027. + {
  19028. + for(t = 0; t < 4; t++)
  19029. + /* parse input stream into rectangular array */
  19030. + block[t][j] = input[16*i+4*j+t] & 0xFF;
  19031. + }
  19032. + rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  19033. + for (j = 0; j < 4; j++)
  19034. + {
  19035. + /* parse rectangular array into output ciphertext bytes */
  19036. + for(t = 0; t < 4; t++)
  19037. + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
  19038. +
  19039. + }
  19040. + }
  19041. + break;
  19042. +
  19043. + case MODE_CBC:
  19044. + for (j = 0; j < 4; j++)
  19045. + {
  19046. + for(t = 0; t < 4; t++)
  19047. + /* parse initial value into rectangular array */
  19048. + block[t][j] = IV[t+4*j] & 0xFF;
  19049. + }
  19050. + for (i = 0; i < numBlocks; i++)
  19051. + {
  19052. + for (j = 0; j < 4; j++)
  19053. + {
  19054. + for(t = 0; t < 4; t++)
  19055. + /* parse input stream into rectangular array and exor with
  19056. + IV or the previous ciphertext */
  19057. + block[t][j] ^= input[16*i+4*j+t] & 0xFF;
  19058. + }
  19059. + rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  19060. + for (j = 0; j < 4; j++)
  19061. + {
  19062. + /* parse rectangular array into output ciphertext bytes */
  19063. + for(t = 0; t < 4; t++)
  19064. + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
  19065. + }
  19066. + }
  19067. + break;
  19068. +
  19069. + default: return AES_BAD_CIPHER_STATE;
  19070. + }
  19071. +
  19072. + return 0;
  19073. +}
  19074. +
  19075. +int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  19076. + MV_U32 *srcData, int numBlocks, MV_U32 *dstData)
  19077. +{
  19078. + int i, j, t;
  19079. + MV_U8 block[4][MAXBC];
  19080. + MV_U8 iv[4][MAXBC];
  19081. + int rounds;
  19082. + char *input, *outBuffer;
  19083. +
  19084. + input = (char*)srcData;
  19085. + outBuffer = (char*)dstData;
  19086. +
  19087. + if (expandedKey == NULL)
  19088. + {
  19089. + return AES_BAD_KEY_MAT;
  19090. + }
  19091. +
  19092. + /* check parameter consistency: */
  19093. + if (keyLen != 128 && keyLen != 192 && keyLen != 256)
  19094. + {
  19095. + return AES_BAD_KEY_MAT;
  19096. + }
  19097. + if ((mode != MODE_ECB && mode != MODE_CBC))
  19098. + {
  19099. + return AES_BAD_CIPHER_STATE;
  19100. + }
  19101. +
  19102. + switch (keyLen)
  19103. + {
  19104. + case 128: rounds = 10; break;
  19105. + case 192: rounds = 12; break;
  19106. + case 256: rounds = 14; break;
  19107. + default : return (-3); /* this cannot happen */
  19108. + }
  19109. +
  19110. +
  19111. + switch (mode)
  19112. + {
  19113. + case MODE_ECB:
  19114. + for (i = 0; i < numBlocks; i++)
  19115. + {
  19116. + for (j = 0; j < 4; j++)
  19117. + {
  19118. + for(t = 0; t < 4; t++)
  19119. + {
  19120. + /* parse input stream into rectangular array */
  19121. + block[t][j] = input[16*i+4*j+t] & 0xFF;
  19122. + }
  19123. + }
  19124. + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  19125. + for (j = 0; j < 4; j++)
  19126. + {
  19127. + /* parse rectangular array into output ciphertext bytes */
  19128. + for(t = 0; t < 4; t++)
  19129. + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
  19130. + }
  19131. + }
  19132. + break;
  19133. +
  19134. + case MODE_CBC:
  19135. + /* first block */
  19136. + for (j = 0; j < 4; j++)
  19137. + {
  19138. + for(t = 0; t < 4; t++)
  19139. + {
  19140. + /* parse input stream into rectangular array */
  19141. + block[t][j] = input[4*j+t] & 0xFF;
  19142. + iv[t][j] = block[t][j];
  19143. + }
  19144. + }
  19145. + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  19146. +
  19147. + for (j = 0; j < 4; j++)
  19148. + {
  19149. + /* exor the IV and parse rectangular array into output ciphertext bytes */
  19150. + for(t = 0; t < 4; t++)
  19151. + {
  19152. + outBuffer[4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);
  19153. + IV[t+4*j] = iv[t][j];
  19154. + }
  19155. + }
  19156. +
  19157. + /* next blocks */
  19158. + for (i = 1; i < numBlocks; i++)
  19159. + {
  19160. + for (j = 0; j < 4; j++)
  19161. + {
  19162. + for(t = 0; t < 4; t++)
  19163. + {
  19164. + /* parse input stream into rectangular array */
  19165. + iv[t][j] = input[16*i+4*j+t] & 0xFF;
  19166. + block[t][j] = iv[t][j];
  19167. + }
  19168. + }
  19169. + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  19170. +
  19171. + for (j = 0; j < 4; j++)
  19172. + {
  19173. + /* exor previous ciphertext block and parse rectangular array
  19174. + into output ciphertext bytes */
  19175. + for(t = 0; t < 4; t++)
  19176. + {
  19177. + outBuffer[16*i+4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);
  19178. + IV[t+4*j] = iv[t][j];
  19179. + }
  19180. + }
  19181. + }
  19182. + break;
  19183. +
  19184. + default: return AES_BAD_CIPHER_STATE;
  19185. + }
  19186. +
  19187. + return 0;
  19188. +}
  19189. +
  19190. +
  19191. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAes.h linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAes.h
  19192. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAes.h 1970-01-01 01:00:00.000000000 +0100
  19193. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAes.h 2010-11-09 20:28:05.292495461 +0100
  19194. @@ -0,0 +1,62 @@
  19195. +/* mvAes.h v2.0 August '99
  19196. + * Reference ANSI C code
  19197. + */
  19198. +
  19199. +/* AES Cipher header file for ANSI C Submissions
  19200. + Lawrence E. Bassham III
  19201. + Computer Security Division
  19202. + National Institute of Standards and Technology
  19203. +
  19204. + April 15, 1998
  19205. +
  19206. + This sample is to assist implementers developing to the Cryptographic
  19207. +API Profile for AES Candidate Algorithm Submissions. Please consult this
  19208. +document as a cross-reference.
  19209. +
  19210. + ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE
  19211. +MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH
  19212. +THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS CANNOT
  19213. +BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO INCLUDE
  19214. +IMPLEMENTATION SPECIFIC INFORMATION.
  19215. +*/
  19216. +
  19217. +/* Includes:
  19218. + Standard include files
  19219. +*/
  19220. +
  19221. +#include "mvOs.h"
  19222. +
  19223. +
  19224. +/* Error Codes - CHANGE POSSIBLE: inclusion of additional error codes */
  19225. +
  19226. +/* Key direction is invalid, e.g., unknown value */
  19227. +#define AES_BAD_KEY_DIR -1
  19228. +
  19229. +/* Key material not of correct length */
  19230. +#define AES_BAD_KEY_MAT -2
  19231. +
  19232. +/* Key passed is not valid */
  19233. +#define AES_BAD_KEY_INSTANCE -3
  19234. +
  19235. +/* Params struct passed to cipherInit invalid */
  19236. +#define AES_BAD_CIPHER_MODE -4
  19237. +
  19238. +/* Cipher in wrong state (e.g., not initialized) */
  19239. +#define AES_BAD_CIPHER_STATE -5
  19240. +
  19241. +#define AES_BAD_CIPHER_INSTANCE -7
  19242. +
  19243. +
  19244. +/* Function protoypes */
  19245. +/* CHANGED: makeKey(): parameter blockLen added
  19246. + this parameter is absolutely necessary if you want to
  19247. + setup the round keys in a variable block length setting
  19248. + cipherInit(): parameter blockLen added (for obvious reasons)
  19249. + */
  19250. +int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen);
  19251. +int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  19252. + MV_U32 *plain, int numBlocks, MV_U32 *cipher);
  19253. +int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  19254. + MV_U32 *plain, int numBlocks, MV_U32 *cipher);
  19255. +
  19256. +
  19257. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesa.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesa.c
  19258. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesa.c 1970-01-01 01:00:00.000000000 +0100
  19259. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesa.c 2010-11-09 20:28:05.302495516 +0100
  19260. @@ -0,0 +1,3126 @@
  19261. +/*******************************************************************************
  19262. +Copyright (C) Marvell International Ltd. and its affiliates
  19263. +
  19264. +This software file (the "File") is owned and distributed by Marvell
  19265. +International Ltd. and/or its affiliates ("Marvell") under the following
  19266. +alternative licensing terms. Once you have made an election to distribute the
  19267. +File under one of the following license alternatives, please (i) delete this
  19268. +introductory statement regarding license alternatives, (ii) delete the two
  19269. +license alternatives that you have not elected to use and (iii) preserve the
  19270. +Marvell copyright notice above.
  19271. +
  19272. +********************************************************************************
  19273. +Marvell Commercial License Option
  19274. +
  19275. +If you received this File from Marvell and you have entered into a commercial
  19276. +license agreement (a "Commercial License") with Marvell, the File is licensed
  19277. +to you under the terms of the applicable Commercial License.
  19278. +
  19279. +********************************************************************************
  19280. +Marvell GPL License Option
  19281. +
  19282. +If you received this File from Marvell, you may opt to use, redistribute and/or
  19283. +modify this File in accordance with the terms and conditions of the General
  19284. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  19285. +available along with the File in the license.txt file or by writing to the Free
  19286. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  19287. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  19288. +
  19289. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  19290. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  19291. +DISCLAIMED. The GPL License provides additional details about this warranty
  19292. +disclaimer.
  19293. +********************************************************************************
  19294. +Marvell BSD License Option
  19295. +
  19296. +If you received this File from Marvell, you may opt to use, redistribute and/or
  19297. +modify this File under the following licensing terms.
  19298. +Redistribution and use in source and binary forms, with or without modification,
  19299. +are permitted provided that the following conditions are met:
  19300. +
  19301. + * Redistributions of source code must retain the above copyright notice,
  19302. + this list of conditions and the following disclaimer.
  19303. +
  19304. + * Redistributions in binary form must reproduce the above copyright
  19305. + notice, this list of conditions and the following disclaimer in the
  19306. + documentation and/or other materials provided with the distribution.
  19307. +
  19308. + * Neither the name of Marvell nor the names of its contributors may be
  19309. + used to endorse or promote products derived from this software without
  19310. + specific prior written permission.
  19311. +
  19312. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  19313. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19314. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19315. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  19316. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19317. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  19318. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  19319. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  19320. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  19321. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  19322. +
  19323. +*******************************************************************************/
  19324. +
  19325. +#include "cesa/mvCesa.h"
  19326. +
  19327. +#include "ctrlEnv/mvCtrlEnvLib.h"
  19328. +#undef CESA_DEBUG
  19329. +
  19330. +
  19331. +/********** Global variables **********/
  19332. +
  19333. +/* If request size is more than MV_CESA_MAX_BUF_SIZE the
  19334. + * request is processed as fragmented request.
  19335. + */
  19336. +
  19337. +MV_CESA_STATS cesaStats;
  19338. +
  19339. +MV_BUF_INFO cesaSramSaBuf;
  19340. +short cesaLastSid = -1;
  19341. +MV_CESA_SA* pCesaSAD = NULL;
  19342. +MV_U16 cesaMaxSA = 0;
  19343. +
  19344. +MV_CESA_REQ* pCesaReqFirst = NULL;
  19345. +MV_CESA_REQ* pCesaReqLast = NULL;
  19346. +MV_CESA_REQ* pCesaReqEmpty = NULL;
  19347. +MV_CESA_REQ* pCesaReqProcess = NULL;
  19348. +int cesaQueueDepth = 0;
  19349. +int cesaReqResources = 0;
  19350. +
  19351. +MV_CESA_SRAM_MAP* cesaSramVirtPtr = NULL;
  19352. +MV_U32 cesaCryptEngBase = 0;
  19353. +void *cesaOsHandle = NULL;
  19354. +#if (MV_CESA_VERSION >= 3)
  19355. +MV_U32 cesaChainLength = 0;
  19356. +int chainReqNum = 0;
  19357. +MV_U32 chainIndex = 0;
  19358. +MV_CESA_REQ* pNextActiveChain = 0;
  19359. +MV_CESA_REQ* pEndCurrChain = 0;
  19360. +MV_BOOL isFirstReq = MV_TRUE;
  19361. +#endif
  19362. +
  19363. +static INLINE MV_U8* mvCesaSramAddrGet(void)
  19364. +{
  19365. +#ifdef MV_CESA_NO_SRAM
  19366. + return (MV_U8*)cesaSramVirtPtr;
  19367. +#else
  19368. + return (MV_U8*)cesaCryptEngBase;
  19369. +#endif /* MV_CESA_NO_SRAM */
  19370. +}
  19371. +
  19372. +static INLINE MV_ULONG mvCesaSramVirtToPhys(void* pDev, MV_U8* pSramVirt)
  19373. +{
  19374. +#ifdef MV_CESA_NO_SRAM
  19375. + return (MV_ULONG)mvOsIoVirtToPhy(NULL, pSramVirt);
  19376. +#else
  19377. + return (MV_ULONG)pSramVirt;
  19378. +#endif /* MV_CESA_NO_SRAM */
  19379. +}
  19380. +
  19381. +/* Internal Function prototypes */
  19382. +
  19383. +static INLINE void mvCesaSramDescrBuild(MV_U32 config, int frag,
  19384. + int cryptoOffset, int ivOffset, int cryptoLength,
  19385. + int macOffset, int digestOffset, int macLength, int macTotalLen,
  19386. + MV_CESA_REQ *pCesaReq, MV_DMA_DESC* pDmaDesc);
  19387. +
  19388. +static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc);
  19389. +
  19390. +static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
  19391. + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
  19392. + int offset, int copySize, MV_BOOL skipFlush);
  19393. +
  19394. +static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,
  19395. + unsigned char innerIV[], unsigned char outerIV[]);
  19396. +
  19397. +static MV_STATUS mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,
  19398. + int macDataSize);
  19399. +
  19400. +static MV_CESA_COMMAND* mvCesaCtrModeInit(void);
  19401. +
  19402. +static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd);
  19403. +static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd);
  19404. +static void mvCesaCtrModeFinish(MV_CESA_COMMAND *pCmd);
  19405. +
  19406. +static INLINE MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq);
  19407. +static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag);
  19408. +
  19409. +static INLINE MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset);
  19410. +static INLINE MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd);
  19411. +
  19412. +static INLINE void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq,
  19413. + int cryptoOffset, int macOffset,
  19414. + int* pCopySize, int* pCryptoDataSize, int* pMacDataSize);
  19415. +static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size);
  19416. +
  19417. +
  19418. +/* Go to the next request in the request queue */
  19419. +static INLINE MV_CESA_REQ* MV_CESA_REQ_NEXT_PTR(MV_CESA_REQ* pReq)
  19420. +{
  19421. + if(pReq == pCesaReqLast)
  19422. + return pCesaReqFirst;
  19423. +
  19424. + return pReq+1;
  19425. +}
  19426. +
  19427. +#if (MV_CESA_VERSION >= 3)
  19428. +/* Go to the previous request in the request queue */
  19429. +static INLINE MV_CESA_REQ* MV_CESA_REQ_PREV_PTR(MV_CESA_REQ* pReq)
  19430. +{
  19431. + if(pReq == pCesaReqFirst)
  19432. + return pCesaReqLast;
  19433. +
  19434. + return pReq-1;
  19435. +}
  19436. +
  19437. +#endif
  19438. +
  19439. +
  19440. +static INLINE void mvCesaReqProcessStart(MV_CESA_REQ* pReq)
  19441. +{
  19442. + int frag;
  19443. +
  19444. +#if (MV_CESA_VERSION >= 3)
  19445. + pReq->state = MV_CESA_CHAIN;
  19446. +#else
  19447. + pReq->state = MV_CESA_PROCESS;
  19448. +#endif
  19449. + cesaStats.startCount++;
  19450. +
  19451. + if(pReq->fragMode == MV_CESA_FRAG_NONE)
  19452. + {
  19453. + frag = 0;
  19454. + }
  19455. + else
  19456. + {
  19457. + frag = pReq->frags.nextFrag;
  19458. + pReq->frags.nextFrag++;
  19459. + }
  19460. +#if (MV_CESA_VERSION >= 2)
  19461. + /* Enable TDMA engine */
  19462. + MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);
  19463. + MV_REG_WRITE(MV_CESA_TDMA_NEXT_DESC_PTR_REG,
  19464. + (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
  19465. +#else
  19466. + /* Enable IDMA engine */
  19467. + MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
  19468. + MV_REG_WRITE(IDMA_NEXT_DESC_PTR_REG(0),
  19469. + (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
  19470. +#endif /* MV_CESA_VERSION >= 2 */
  19471. +
  19472. +#if defined(MV_BRIDGE_SYNC_REORDER)
  19473. + mvOsBridgeReorderWA();
  19474. +#endif
  19475. +
  19476. + /* Start Accelerator */
  19477. + MV_REG_WRITE(MV_CESA_CMD_REG, MV_CESA_CMD_CHAN_ENABLE_MASK);
  19478. +}
  19479. +
  19480. +
  19481. +/*******************************************************************************
  19482. +* mvCesaHalInit - Initialize the CESA driver
  19483. +*
  19484. +* DESCRIPTION:
  19485. +* This function initialize the CESA driver.
  19486. +* 1) Session database
  19487. +* 2) Request queue
  19488. +* 4) DMA descriptor lists - one list per request. Each list
  19489. +* has MV_CESA_MAX_DMA_DESC descriptors.
  19490. +*
  19491. +* INPUT:
  19492. +* numOfSession - maximum number of supported sessions
  19493. +* queueDepth - number of elements in the request queue.
  19494. +* pSramBase - virtual address of Sram
  19495. +* osHandle - A handle used by the OS to allocate memory for the
  19496. +* module (Passed to the OS Services layer)
  19497. +*
  19498. +* RETURN:
  19499. +* MV_OK - Success
  19500. +* MV_NO_RESOURCE - Fail, can't allocate resources:
  19501. +* Session database, request queue,
  19502. +* DMA descriptors list, LRU cache database.
  19503. +* MV_NOT_ALIGNED - Sram base address is not 8 byte aligned.
  19504. +*
  19505. +*******************************************************************************/
  19506. +MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase,
  19507. + void *osHandle)
  19508. +{
  19509. + int i, req;
  19510. + MV_U32 descOffsetReg, configReg;
  19511. + MV_CESA_SRAM_SA *pSramSA;
  19512. +
  19513. +
  19514. + mvOsPrintf("mvCesaInit: sessions=%d, queue=%d, pSram=%p\n",
  19515. + numOfSession, queueDepth, pSramBase);
  19516. +
  19517. + cesaOsHandle = osHandle;
  19518. + /* Create Session database */
  19519. + pCesaSAD = mvOsMalloc(sizeof(MV_CESA_SA)*numOfSession);
  19520. + if(pCesaSAD == NULL)
  19521. + {
  19522. + mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d SAs\n",
  19523. + sizeof(MV_CESA_SA)*numOfSession, numOfSession);
  19524. + mvCesaFinish();
  19525. + return MV_NO_RESOURCE;
  19526. + }
  19527. + memset(pCesaSAD, 0, sizeof(MV_CESA_SA)*numOfSession);
  19528. + cesaMaxSA = numOfSession;
  19529. +
  19530. + /* Allocate imag of sramSA in the DRAM */
  19531. + cesaSramSaBuf.bufSize = sizeof(MV_CESA_SRAM_SA)*numOfSession +
  19532. + CPU_D_CACHE_LINE_SIZE;
  19533. +
  19534. + cesaSramSaBuf.bufVirtPtr = mvOsIoCachedMalloc(osHandle,cesaSramSaBuf.bufSize,
  19535. + &cesaSramSaBuf.bufPhysAddr,
  19536. + &cesaSramSaBuf.memHandle);
  19537. +
  19538. + if(cesaSramSaBuf.bufVirtPtr == NULL)
  19539. + {
  19540. + mvOsPrintf("mvCesaInit: Can't allocate %d bytes for sramSA structures\n",
  19541. + cesaSramSaBuf.bufSize);
  19542. + mvCesaFinish();
  19543. + return MV_NO_RESOURCE;
  19544. + }
  19545. + memset(cesaSramSaBuf.bufVirtPtr, 0, cesaSramSaBuf.bufSize);
  19546. + pSramSA = (MV_CESA_SRAM_SA*)MV_ALIGN_UP((MV_ULONG)cesaSramSaBuf.bufVirtPtr,
  19547. + CPU_D_CACHE_LINE_SIZE);
  19548. + for(i=0; i<numOfSession; i++)
  19549. + {
  19550. + pCesaSAD[i].pSramSA = &pSramSA[i];
  19551. + }
  19552. +
  19553. + /* Create request queue */
  19554. + pCesaReqFirst = mvOsMalloc(sizeof(MV_CESA_REQ)*queueDepth);
  19555. + if(pCesaReqFirst == NULL)
  19556. + {
  19557. + mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d requests\n",
  19558. + sizeof(MV_CESA_REQ)*queueDepth, queueDepth);
  19559. + mvCesaFinish();
  19560. + return MV_NO_RESOURCE;
  19561. + }
  19562. + memset(pCesaReqFirst, 0, sizeof(MV_CESA_REQ)*queueDepth);
  19563. + pCesaReqEmpty = pCesaReqFirst;
  19564. + pCesaReqLast = pCesaReqFirst + (queueDepth-1);
  19565. + pCesaReqProcess = pCesaReqEmpty;
  19566. + cesaQueueDepth = queueDepth;
  19567. + cesaReqResources = queueDepth;
  19568. +#if (MV_CESA_VERSION >= 3)
  19569. + cesaChainLength = MAX_CESA_CHAIN_LENGTH;
  19570. +#endif
  19571. + /* pSramBase must be 8 byte aligned */
  19572. + if( MV_IS_NOT_ALIGN((MV_ULONG)pSramBase, 8) )
  19573. + {
  19574. + mvOsPrintf("mvCesaInit: pSramBase (%p) must be 8 byte aligned\n",
  19575. + pSramBase);
  19576. + mvCesaFinish();
  19577. + return MV_NOT_ALIGNED;
  19578. + }
  19579. + cesaSramVirtPtr = (MV_CESA_SRAM_MAP*)pSramBase;
  19580. +
  19581. + cesaCryptEngBase = cryptEngBase;
  19582. +
  19583. + /*memset(cesaSramVirtPtr, 0, sizeof(MV_CESA_SRAM_MAP));*/
  19584. +
  19585. + /* Clear registers */
  19586. + MV_REG_WRITE( MV_CESA_CFG_REG, 0);
  19587. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  19588. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
  19589. +
  19590. + /* Initialize DMA descriptor lists for all requests in Request queue */
  19591. + descOffsetReg = configReg = 0;
  19592. + for(req=0; req<queueDepth; req++)
  19593. + {
  19594. + int frag;
  19595. + MV_CESA_REQ* pReq;
  19596. + MV_DMA_DESC* pDmaDesc;
  19597. +
  19598. + pReq = &pCesaReqFirst[req];
  19599. +
  19600. + pReq->cesaDescBuf.bufSize = sizeof(MV_CESA_DESC)*MV_CESA_MAX_REQ_FRAGS +
  19601. + CPU_D_CACHE_LINE_SIZE;
  19602. +
  19603. + pReq->cesaDescBuf.bufVirtPtr =
  19604. + mvOsIoCachedMalloc(osHandle,pReq->cesaDescBuf.bufSize,
  19605. + &pReq->cesaDescBuf.bufPhysAddr,
  19606. + &pReq->cesaDescBuf.memHandle);
  19607. +
  19608. + if(pReq->cesaDescBuf.bufVirtPtr == NULL)
  19609. + {
  19610. + mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for CESA descriptors\n",
  19611. + req, pReq->cesaDescBuf.bufSize);
  19612. + mvCesaFinish();
  19613. + return MV_NO_RESOURCE;
  19614. + }
  19615. + memset(pReq->cesaDescBuf.bufVirtPtr, 0, pReq->cesaDescBuf.bufSize);
  19616. + pReq->pCesaDesc = (MV_CESA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->cesaDescBuf.bufVirtPtr,
  19617. + CPU_D_CACHE_LINE_SIZE);
  19618. +
  19619. + pReq->dmaDescBuf.bufSize = sizeof(MV_DMA_DESC)*MV_CESA_MAX_DMA_DESC*MV_CESA_MAX_REQ_FRAGS +
  19620. + CPU_D_CACHE_LINE_SIZE;
  19621. +
  19622. + pReq->dmaDescBuf.bufVirtPtr =
  19623. + mvOsIoCachedMalloc(osHandle,pReq->dmaDescBuf.bufSize,
  19624. + &pReq->dmaDescBuf.bufPhysAddr,
  19625. + &pReq->dmaDescBuf.memHandle);
  19626. +
  19627. + if(pReq->dmaDescBuf.bufVirtPtr == NULL)
  19628. + {
  19629. + mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for DMA descriptor list\n",
  19630. + req, pReq->dmaDescBuf.bufSize);
  19631. + mvCesaFinish();
  19632. + return MV_NO_RESOURCE;
  19633. + }
  19634. + memset(pReq->dmaDescBuf.bufVirtPtr, 0, pReq->dmaDescBuf.bufSize);
  19635. + pDmaDesc = (MV_DMA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->dmaDescBuf.bufVirtPtr,
  19636. + CPU_D_CACHE_LINE_SIZE);
  19637. +
  19638. + for(frag=0; frag<MV_CESA_MAX_REQ_FRAGS; frag++)
  19639. + {
  19640. + MV_CESA_DMA* pDma = &pReq->dma[frag];
  19641. +
  19642. + pDma->pDmaFirst = pDmaDesc;
  19643. + pDma->pDmaLast = NULL;
  19644. +
  19645. + for(i=0; i<MV_CESA_MAX_DMA_DESC-1; i++)
  19646. + {
  19647. + /* link all DMA descriptors together */
  19648. + pDma->pDmaFirst[i].phyNextDescPtr =
  19649. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pDmaDesc[i+1]));
  19650. + }
  19651. + pDma->pDmaFirst[i].phyNextDescPtr = 0;
  19652. + mvOsCacheFlush(NULL, &pDma->pDmaFirst[0], MV_CESA_MAX_DMA_DESC*sizeof(MV_DMA_DESC));
  19653. +
  19654. + pDmaDesc += MV_CESA_MAX_DMA_DESC;
  19655. + }
  19656. + }
  19657. + /*mvCesaCryptoIvSet(NULL, MV_CESA_MAX_IV_LENGTH);*/
  19658. + descOffsetReg = (MV_U16)((MV_U8*)&cesaSramVirtPtr->desc - mvCesaSramAddrGet());
  19659. + MV_REG_WRITE(MV_CESA_CHAN_DESC_OFFSET_REG, descOffsetReg);
  19660. +
  19661. + configReg |= (MV_CESA_CFG_WAIT_DMA_MASK | MV_CESA_CFG_ACT_DMA_MASK);
  19662. +#if (MV_CESA_VERSION >= 3)
  19663. + configReg |= MV_CESA_CFG_CHAIN_MODE_MASK;
  19664. +#endif
  19665. +
  19666. +#if (MV_CESA_VERSION >= 2)
  19667. + /* Initialize TDMA engine */
  19668. + MV_REG_WRITE(MV_CESA_TDMA_CTRL_REG, MV_CESA_TDMA_CTRL_VALUE);
  19669. + MV_REG_WRITE(MV_CESA_TDMA_BYTE_COUNT_REG, 0);
  19670. + MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);
  19671. +#else
  19672. + /* Initialize IDMA #0 engine */
  19673. + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
  19674. + MV_REG_WRITE(IDMA_BYTE_COUNT_REG(0), 0);
  19675. + MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
  19676. + MV_REG_WRITE(IDMA_CTRL_HIGH_REG(0), ICCHR_ENDIAN_LITTLE
  19677. +#ifdef MV_CPU_LE
  19678. + | ICCHR_DESC_BYTE_SWAP_EN
  19679. +#endif
  19680. + );
  19681. + /* Clear Cause Byte of IDMA channel to be used */
  19682. + MV_REG_WRITE( IDMA_CAUSE_REG, ~ICICR_CAUSE_MASK_ALL(0));
  19683. + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), MV_CESA_IDMA_CTRL_LOW_VALUE);
  19684. +#endif /* (MV_CESA_VERSION >= 2) */
  19685. +
  19686. + /* Set CESA configuration registers */
  19687. + MV_REG_WRITE( MV_CESA_CFG_REG, configReg);
  19688. + mvCesaDebugStatsClear();
  19689. +
  19690. + return MV_OK;
  19691. +}
  19692. +
  19693. +/*******************************************************************************
  19694. +* mvCesaFinish - Shutdown the CESA driver
  19695. +*
  19696. +* DESCRIPTION:
  19697. +* This function shutdown the CESA driver and free all allocted resources.
  19698. +*
  19699. +* INPUT: None
  19700. +*
  19701. +* RETURN:
  19702. +* MV_OK - Success
  19703. +* Other - Fail
  19704. +*
  19705. +*******************************************************************************/
  19706. +MV_STATUS mvCesaFinish (void)
  19707. +{
  19708. + int req;
  19709. + MV_CESA_REQ* pReq;
  19710. +
  19711. + mvOsPrintf("mvCesaFinish: \n");
  19712. +
  19713. + cesaSramVirtPtr = NULL;
  19714. +
  19715. + /* Free all resources: DMA list, etc. */
  19716. + for(req=0; req<cesaQueueDepth; req++)
  19717. + {
  19718. + pReq = &pCesaReqFirst[req];
  19719. + if(pReq->dmaDescBuf.bufVirtPtr != NULL)
  19720. + {
  19721. + mvOsIoCachedFree(cesaOsHandle,pReq->dmaDescBuf.bufSize,
  19722. + pReq->dmaDescBuf.bufPhysAddr,
  19723. + pReq->dmaDescBuf.bufVirtPtr,
  19724. + pReq->dmaDescBuf.memHandle);
  19725. + }
  19726. + if(pReq->cesaDescBuf.bufVirtPtr != NULL)
  19727. + {
  19728. + mvOsIoCachedFree(cesaOsHandle,pReq->cesaDescBuf.bufSize,
  19729. + pReq->cesaDescBuf.bufPhysAddr,
  19730. + pReq->cesaDescBuf.bufVirtPtr,
  19731. + pReq->cesaDescBuf.memHandle);
  19732. + }
  19733. + }
  19734. +#if (MV_CESA_VERSION < 2)
  19735. + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
  19736. +#endif /* (MV_CESA_VERSION < 2) */
  19737. +
  19738. + /* Free request queue */
  19739. + if(pCesaReqFirst != NULL)
  19740. + {
  19741. + mvOsFree(pCesaReqFirst);
  19742. + pCesaReqFirst = pCesaReqLast = NULL;
  19743. + pCesaReqEmpty = pCesaReqProcess = NULL;
  19744. + cesaQueueDepth = cesaReqResources = 0;
  19745. + }
  19746. + /* Free SA database */
  19747. + if(pCesaSAD != NULL)
  19748. + {
  19749. + mvOsFree(pCesaSAD);
  19750. + pCesaSAD = NULL;
  19751. + cesaMaxSA = 0;
  19752. + }
  19753. + MV_REG_WRITE( MV_CESA_CFG_REG, 0);
  19754. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  19755. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
  19756. +
  19757. + return MV_OK;
  19758. +}
  19759. +
  19760. +/*******************************************************************************
  19761. +* mvCesaCryptoIvSet - Set IV value for Crypto algorithm working in CBC mode
  19762. +*
  19763. +* DESCRIPTION:
  19764. +* This function set IV value using by Crypto algorithms in CBC mode.
  19765. +* Each channel has its own IV value.
  19766. +* This function gets IV value from the caller. If no IV value passed from
  19767. +* the caller or only part of IV passed, the function will init the rest part
  19768. +* of IV value (or the whole IV) by random value.
  19769. +*
  19770. +* INPUT:
  19771. +* MV_U8* pIV - Pointer to IV value supplied by user. If pIV==NULL
  19772. +* the function will generate random IV value.
  19773. +* int ivSize - size (in bytes) of IV provided by user. If ivSize is
  19774. +* smaller than maximum IV size, the function will complete
  19775. +* IV by random value.
  19776. +*
  19777. +* RETURN:
  19778. +* MV_OK - Success
  19779. +* Other - Fail
  19780. +*
  19781. +*******************************************************************************/
  19782. +MV_STATUS mvCesaCryptoIvSet(MV_U8* pIV, int ivSize)
  19783. +{
  19784. + MV_U8* pSramIV;
  19785. +#if defined(MV646xx)
  19786. + mvOsPrintf("mvCesaCryptoIvSet: ERR. shouldn't use this call on MV64660\n");
  19787. +#endif
  19788. + pSramIV = cesaSramVirtPtr->cryptoIV;
  19789. + if(ivSize > MV_CESA_MAX_IV_LENGTH)
  19790. + {
  19791. + mvOsPrintf("mvCesaCryptoIvSet: ivSize (%d) is too large\n", ivSize);
  19792. + ivSize = MV_CESA_MAX_IV_LENGTH;
  19793. + }
  19794. + if(pIV != NULL)
  19795. + {
  19796. + memcpy(pSramIV, pIV, ivSize);
  19797. + ivSize = MV_CESA_MAX_IV_LENGTH - ivSize;
  19798. + pSramIV += ivSize;
  19799. + }
  19800. +
  19801. + while(ivSize > 0)
  19802. + {
  19803. + int size, mv_random = mvOsRand();
  19804. +
  19805. + size = MV_MIN(ivSize, sizeof(mv_random));
  19806. + memcpy(pSramIV, (void*)&mv_random, size);
  19807. +
  19808. + pSramIV += size;
  19809. + ivSize -= size;
  19810. + }
  19811. +/*
  19812. + mvOsCacheFlush(NULL, cesaSramVirtPtr->cryptoIV,
  19813. + MV_CESA_MAX_IV_LENGTH);
  19814. + mvOsCacheInvalidate(NULL, cesaSramVirtPtr->cryptoIV,
  19815. + MV_CESA_MAX_IV_LENGTH);
  19816. +*/
  19817. + return MV_OK;
  19818. +}
  19819. +
  19820. +/*******************************************************************************
  19821. +* mvCesaSessionOpen - Open new uni-directional crypto session
  19822. +*
  19823. +* DESCRIPTION:
  19824. +* This function open new session.
  19825. +*
  19826. +* INPUT:
  19827. +* MV_CESA_OPEN_SESSION *pSession - pointer to new session input parameters
  19828. +*
  19829. +* OUTPUT:
  19830. +* short *pSid - session ID, should be used for all future
  19831. +* requests over this session.
  19832. +*
  19833. +* RETURN:
  19834. +* MV_OK - Session opend successfully.
  19835. +* MV_FULL - All sessions are in use, no free place in
  19836. +* SA database.
  19837. +* MV_BAD_PARAM - One of session input parameters is invalid.
  19838. +*
  19839. +*******************************************************************************/
  19840. +MV_STATUS mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid)
  19841. +{
  19842. + short sid;
  19843. + MV_U32 config = 0;
  19844. + int digestSize;
  19845. +
  19846. + cesaStats.openedCount++;
  19847. +
  19848. + /* Find free entry in SAD */
  19849. + for(sid=0; sid<cesaMaxSA; sid++)
  19850. + {
  19851. + if(pCesaSAD[sid].valid == 0)
  19852. + {
  19853. + break;
  19854. + }
  19855. + }
  19856. + if(sid == cesaMaxSA)
  19857. + {
  19858. + mvOsPrintf("mvCesaSessionOpen: SA Database is FULL\n");
  19859. + return MV_FULL;
  19860. + }
  19861. +
  19862. + /* Check Input parameters for Open session */
  19863. + if (pSession->operation >= MV_CESA_MAX_OPERATION)
  19864. + {
  19865. + mvOsPrintf("mvCesaSessionOpen: Unexpected operation %d\n",
  19866. + pSession->operation);
  19867. + return MV_BAD_PARAM;
  19868. + }
  19869. + config |= (pSession->operation << MV_CESA_OPERATION_OFFSET);
  19870. +
  19871. + if( (pSession->direction != MV_CESA_DIR_ENCODE) &&
  19872. + (pSession->direction != MV_CESA_DIR_DECODE) )
  19873. + {
  19874. + mvOsPrintf("mvCesaSessionOpen: Unexpected direction %d\n",
  19875. + pSession->direction);
  19876. + return MV_BAD_PARAM;
  19877. + }
  19878. + config |= (pSession->direction << MV_CESA_DIRECTION_BIT);
  19879. + /* Clear SA entry */
  19880. + /* memset(&pCesaSAD[sid], 0, sizeof(pCesaSAD[sid])); */
  19881. +
  19882. + /* Check AUTH parameters and update SA entry */
  19883. + if(pSession->operation != MV_CESA_CRYPTO_ONLY)
  19884. + {
  19885. + /* For HMAC (MD5 and SHA1) - Maximum Key size is 64 bytes */
  19886. + if( (pSession->macMode == MV_CESA_MAC_HMAC_MD5) ||
  19887. + (pSession->macMode == MV_CESA_MAC_HMAC_SHA1) )
  19888. + {
  19889. + if(pSession->macKeyLength > MV_CESA_MAX_MAC_KEY_LENGTH)
  19890. + {
  19891. + mvOsPrintf("mvCesaSessionOpen: macKeyLength %d is too large\n",
  19892. + pSession->macKeyLength);
  19893. + return MV_BAD_PARAM;
  19894. + }
  19895. + mvCesaHmacIvGet(pSession->macMode, pSession->macKey, pSession->macKeyLength,
  19896. + pCesaSAD[sid].pSramSA->macInnerIV,
  19897. + pCesaSAD[sid].pSramSA->macOuterIV);
  19898. + pCesaSAD[sid].macKeyLength = pSession->macKeyLength;
  19899. + }
  19900. + switch(pSession->macMode)
  19901. + {
  19902. + case MV_CESA_MAC_MD5:
  19903. + case MV_CESA_MAC_HMAC_MD5:
  19904. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  19905. + break;
  19906. +
  19907. + case MV_CESA_MAC_SHA1:
  19908. + case MV_CESA_MAC_HMAC_SHA1:
  19909. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  19910. + break;
  19911. +
  19912. + default:
  19913. + mvOsPrintf("mvCesaSessionOpen: Unexpected macMode %d\n",
  19914. + pSession->macMode);
  19915. + return MV_BAD_PARAM;
  19916. + }
  19917. + config |= (pSession->macMode << MV_CESA_MAC_MODE_OFFSET);
  19918. +
  19919. + /* Supported digest sizes: MD5 - 16 bytes (128 bits), */
  19920. + /* SHA1 - 20 bytes (160 bits) or 12 bytes (96 bits) for both */
  19921. + if( (pSession->digestSize != digestSize) && (pSession->digestSize != 12))
  19922. + {
  19923. + mvOsPrintf("mvCesaSessionOpen: Unexpected digest size %d\n",
  19924. + pSession->digestSize);
  19925. + mvOsPrintf("\t Valid values [bytes]: MD5-16, SHA1-20, Both-12\n");
  19926. + return MV_BAD_PARAM;
  19927. + }
  19928. + pCesaSAD[sid].digestSize = pSession->digestSize;
  19929. +
  19930. + if(pCesaSAD[sid].digestSize == 12)
  19931. + {
  19932. + /* Set MV_CESA_MAC_DIGEST_SIZE_BIT if digest size is 96 bits */
  19933. + config |= (MV_CESA_MAC_DIGEST_96B << MV_CESA_MAC_DIGEST_SIZE_BIT);
  19934. + }
  19935. + }
  19936. +
  19937. + /* Check CRYPTO parameters and update SA entry */
  19938. + if(pSession->operation != MV_CESA_MAC_ONLY)
  19939. + {
  19940. + switch(pSession->cryptoAlgorithm)
  19941. + {
  19942. + case MV_CESA_CRYPTO_DES:
  19943. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_DES_KEY_LENGTH;
  19944. + pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;
  19945. + break;
  19946. +
  19947. + case MV_CESA_CRYPTO_3DES:
  19948. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_3DES_KEY_LENGTH;
  19949. + pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;
  19950. + /* Only EDE mode is supported */
  19951. + config |= (MV_CESA_CRYPTO_3DES_EDE <<
  19952. + MV_CESA_CRYPTO_3DES_MODE_BIT);
  19953. + break;
  19954. +
  19955. + case MV_CESA_CRYPTO_AES:
  19956. + switch(pSession->cryptoKeyLength)
  19957. + {
  19958. + case 16:
  19959. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_128_KEY_LENGTH;
  19960. + config |= (MV_CESA_CRYPTO_AES_KEY_128 <<
  19961. + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
  19962. + break;
  19963. +
  19964. + case 24:
  19965. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_192_KEY_LENGTH;
  19966. + config |= (MV_CESA_CRYPTO_AES_KEY_192 <<
  19967. + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
  19968. + break;
  19969. +
  19970. + case 32:
  19971. + default:
  19972. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_256_KEY_LENGTH;
  19973. + config |= (MV_CESA_CRYPTO_AES_KEY_256 <<
  19974. + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
  19975. + break;
  19976. + }
  19977. + pCesaSAD[sid].cryptoBlockSize = MV_CESA_AES_BLOCK_SIZE;
  19978. + break;
  19979. +
  19980. + default:
  19981. + mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoAlgorithm %d\n",
  19982. + pSession->cryptoAlgorithm);
  19983. + return MV_BAD_PARAM;
  19984. + }
  19985. + config |= (pSession->cryptoAlgorithm << MV_CESA_CRYPTO_ALG_OFFSET);
  19986. +
  19987. + if(pSession->cryptoKeyLength != pCesaSAD[sid].cryptoKeyLength)
  19988. + {
  19989. + mvOsPrintf("cesaSessionOpen: Wrong CryptoKeySize %d != %d\n",
  19990. + pSession->cryptoKeyLength, pCesaSAD[sid].cryptoKeyLength);
  19991. + return MV_BAD_PARAM;
  19992. + }
  19993. +
  19994. + /* Copy Crypto key */
  19995. + if( (pSession->cryptoAlgorithm == MV_CESA_CRYPTO_AES) &&
  19996. + (pSession->direction == MV_CESA_DIR_DECODE))
  19997. + {
  19998. + /* Crypto Key for AES decode is computed from original key material */
  19999. + /* and depend on cryptoKeyLength (128/192/256 bits) */
  20000. + aesMakeKey(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey,
  20001. + pSession->cryptoKeyLength*8, MV_CESA_AES_BLOCK_SIZE*8);
  20002. + }
  20003. + else
  20004. + {
  20005. + /*panic("mvCesaSessionOpen2");*/
  20006. + memcpy(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey,
  20007. + pCesaSAD[sid].cryptoKeyLength);
  20008. +
  20009. + }
  20010. +
  20011. + switch(pSession->cryptoMode)
  20012. + {
  20013. + case MV_CESA_CRYPTO_ECB:
  20014. + pCesaSAD[sid].cryptoIvSize = 0;
  20015. + break;
  20016. +
  20017. + case MV_CESA_CRYPTO_CBC:
  20018. + pCesaSAD[sid].cryptoIvSize = pCesaSAD[sid].cryptoBlockSize;
  20019. + break;
  20020. +
  20021. + case MV_CESA_CRYPTO_CTR:
  20022. + /* Supported only for AES algorithm */
  20023. + if(pSession->cryptoAlgorithm != MV_CESA_CRYPTO_AES)
  20024. + {
  20025. + mvOsPrintf("mvCesaSessionOpen: CRYPTO CTR mode supported for AES only\n");
  20026. + return MV_BAD_PARAM;
  20027. + }
  20028. + pCesaSAD[sid].cryptoIvSize = 0;
  20029. + pCesaSAD[sid].ctrMode = 1;
  20030. + /* Replace to ECB mode for HW */
  20031. + pSession->cryptoMode = MV_CESA_CRYPTO_ECB;
  20032. + break;
  20033. +
  20034. + default:
  20035. + mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoMode %d\n",
  20036. + pSession->cryptoMode);
  20037. + return MV_BAD_PARAM;
  20038. + }
  20039. +
  20040. + config |= (pSession->cryptoMode << MV_CESA_CRYPTO_MODE_BIT);
  20041. + }
  20042. + pCesaSAD[sid].config = config;
  20043. +
  20044. + mvOsCacheFlush(NULL, pCesaSAD[sid].pSramSA, sizeof(MV_CESA_SRAM_SA));
  20045. + if(pSid != NULL)
  20046. + *pSid = sid;
  20047. +
  20048. + pCesaSAD[sid].valid = 1;
  20049. + return MV_OK;
  20050. +}
  20051. +
  20052. +/*******************************************************************************
  20053. +* mvCesaSessionClose - Close active crypto session
  20054. +*
  20055. +* DESCRIPTION:
  20056. +* This function closes existing session
  20057. +*
  20058. +* INPUT:
  20059. +* short sid - Unique identifier of the session to be closed
  20060. +*
  20061. +* RETURN:
  20062. +* MV_OK - Session closed successfully.
  20063. +* MV_BAD_PARAM - Session identifier is out of valid range.
  20064. +* MV_NOT_FOUND - There is no active session with such ID.
  20065. +*
  20066. +*******************************************************************************/
  20067. +MV_STATUS mvCesaSessionClose(short sid)
  20068. +{
  20069. + cesaStats.closedCount++;
  20070. +
  20071. + if(sid >= cesaMaxSA)
  20072. + {
  20073. + mvOsPrintf("CESA Error: sid (%d) is too big\n", sid);
  20074. + return MV_BAD_PARAM;
  20075. + }
  20076. + if(pCesaSAD[sid].valid == 0)
  20077. + {
  20078. + mvOsPrintf("CESA Warning: Session (sid=%d) is invalid\n", sid);
  20079. + return MV_NOT_FOUND;
  20080. + }
  20081. + if(cesaLastSid == sid)
  20082. + cesaLastSid = -1;
  20083. +
  20084. + pCesaSAD[sid].valid = 0;
  20085. + return MV_OK;
  20086. +}
  20087. +
  20088. +/*******************************************************************************
  20089. +* mvCesaAction - Perform crypto operation
  20090. +*
  20091. +* DESCRIPTION:
  20092. +* This function set new CESA request FIFO queue for further HW processing.
  20093. +* The function checks request parameters before set new request to the queue.
  20094. +* If one of the CESA channels is ready for processing the request will be
  20095. +* passed to HW. When request processing is finished the CESA interrupt will
  20096. +* be generated by HW. The caller should call mvCesaReadyGet() function to
  20097. +* complete request processing and get result.
  20098. +*
  20099. +* INPUT:
  20100. +* MV_CESA_COMMAND *pCmd - pointer to new CESA request.
  20101. +* It includes pointers to Source and Destination
  20102. +* buffers, session identifier get from
  20103. +* mvCesaSessionOpen() function, pointer to caller
  20104. +* private data and all needed crypto parameters.
  20105. +*
  20106. +* RETURN:
  20107. +* MV_OK - request successfully added to request queue
  20108. +* and will be processed.
  20109. +* MV_NO_MORE - request successfully added to request queue and will
  20110. +* be processed, but request queue became Full and next
  20111. +* request will not be accepted.
  20112. +* MV_NO_RESOURCE - request queue is FULL and the request can not
  20113. +* be processed.
  20114. +* MV_OUT_OF_CPU_MEM - memory allocation needed for request processing is
  20115. +* failed. Request can not be processed.
  20116. +* MV_NOT_ALLOWED - This mixed request (CRYPTO+MAC) can not be processed
  20117. +* as one request and should be splitted for two requests:
  20118. +* CRYPTO_ONLY and MAC_ONLY.
  20119. +* MV_BAD_PARAM - One of the request parameters is out of valid range.
  20120. +* The request can not be processed.
  20121. +*
  20122. +*******************************************************************************/
  20123. +MV_STATUS mvCesaAction (MV_CESA_COMMAND *pCmd)
  20124. +{
  20125. + MV_STATUS status;
  20126. + MV_CESA_REQ* pReq = pCesaReqEmpty;
  20127. + int sid = pCmd->sessionId;
  20128. + MV_CESA_SA* pSA = &pCesaSAD[sid];
  20129. +#if (MV_CESA_VERSION >= 3)
  20130. + MV_CESA_REQ* pFromReq;
  20131. + MV_CESA_REQ* pToReq;
  20132. +#endif
  20133. + cesaStats.reqCount++;
  20134. +
  20135. + /* Check that the request queue is not FULL */
  20136. + if(cesaReqResources == 0)
  20137. + return MV_NO_RESOURCE;
  20138. +
  20139. + if( (sid >= cesaMaxSA) || (!pSA->valid) )
  20140. + {
  20141. + mvOsPrintf("CESA Action Error: Session sid=%d is INVALID\n", sid);
  20142. + return MV_BAD_PARAM;
  20143. + }
  20144. + pSA->count++;
  20145. +
  20146. + if(pSA->ctrMode)
  20147. + {
  20148. + /* AES in CTR mode can't be mixed with Authentication */
  20149. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  20150. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  20151. + {
  20152. + mvOsPrintf("mvCesaAction : CRYPTO CTR mode can't be mixed with AUTH\n");
  20153. + return MV_NOT_ALLOWED;
  20154. + }
  20155. + /* All other request parameters should not be checked because key stream */
  20156. + /* (not user data) processed by AES HW engine */
  20157. + pReq->pOrgCmd = pCmd;
  20158. + /* Allocate temporary pCmd structure for Key stream */
  20159. + pCmd = mvCesaCtrModeInit();
  20160. + if(pCmd == NULL)
  20161. + return MV_OUT_OF_CPU_MEM;
  20162. +
  20163. + /* Prepare Key stream */
  20164. + mvCesaCtrModePrepare(pCmd, pReq->pOrgCmd);
  20165. + pReq->fixOffset = 0;
  20166. + }
  20167. + else
  20168. + {
  20169. + /* Check request parameters and calculae fixOffset */
  20170. + status = mvCesaParamCheck(pSA, pCmd, &pReq->fixOffset);
  20171. + if(status != MV_OK)
  20172. + {
  20173. + return status;
  20174. + }
  20175. + }
  20176. + pReq->pCmd = pCmd;
  20177. +
  20178. + /* Check if the packet need fragmentation */
  20179. + if(pCmd->pSrc->mbufSize <= sizeof(cesaSramVirtPtr->buf) )
  20180. + {
  20181. + /* request size is smaller than single buffer size */
  20182. + pReq->fragMode = MV_CESA_FRAG_NONE;
  20183. +
  20184. + /* Prepare NOT fragmented packets */
  20185. + status = mvCesaReqProcess(pReq);
  20186. + if(status != MV_OK)
  20187. + {
  20188. + mvOsPrintf("CesaReady: ReqProcess error: pReq=%p, status=0x%x\n",
  20189. + pReq, status);
  20190. + }
  20191. +#if (MV_CESA_VERSION >= 3)
  20192. + pReq->frags.numFrag = 1;
  20193. +#endif
  20194. + }
  20195. + else
  20196. + {
  20197. + MV_U8 frag = 0;
  20198. +
  20199. + /* request size is larger than buffer size - needs fragmentation */
  20200. +
  20201. + /* Check restrictions for processing fragmented packets */
  20202. + status = mvCesaFragParamCheck(pSA, pCmd);
  20203. + if(status != MV_OK)
  20204. + return status;
  20205. +
  20206. + pReq->fragMode = MV_CESA_FRAG_FIRST;
  20207. + pReq->frags.nextFrag = 0;
  20208. +
  20209. + /* Prepare Process Fragmented packets */
  20210. + while(pReq->fragMode != MV_CESA_FRAG_LAST)
  20211. + {
  20212. + if(frag >= MV_CESA_MAX_REQ_FRAGS)
  20213. + {
  20214. + mvOsPrintf("mvCesaAction Error: Too large request frag=%d\n", frag);
  20215. + return MV_OUT_OF_CPU_MEM;
  20216. + }
  20217. + status = mvCesaFragReqProcess(pReq, frag);
  20218. + if(status == MV_OK) {
  20219. +#if (MV_CESA_VERSION >= 3)
  20220. + if(frag) {
  20221. + pReq->dma[frag-1].pDmaLast->phyNextDescPtr =
  20222. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
  20223. + mvOsCacheFlush(NULL, pReq->dma[frag-1].pDmaLast, sizeof(MV_DMA_DESC));
  20224. + }
  20225. +#endif
  20226. + frag++;
  20227. + }
  20228. + }
  20229. + pReq->frags.numFrag = frag;
  20230. +#if (MV_CESA_VERSION >= 3)
  20231. + if(chainReqNum) {
  20232. + chainReqNum += pReq->frags.numFrag;
  20233. + if(chainReqNum >= MAX_CESA_CHAIN_LENGTH)
  20234. + chainReqNum = MAX_CESA_CHAIN_LENGTH;
  20235. + }
  20236. +#endif
  20237. + }
  20238. +
  20239. + pReq->state = MV_CESA_PENDING;
  20240. +
  20241. + pCesaReqEmpty = MV_CESA_REQ_NEXT_PTR(pReq);
  20242. + cesaReqResources -= 1;
  20243. +
  20244. +/* #ifdef CESA_DEBUG */
  20245. + if( (cesaQueueDepth - cesaReqResources) > cesaStats.maxReqCount)
  20246. + cesaStats.maxReqCount = (cesaQueueDepth - cesaReqResources);
  20247. +/* #endif CESA_DEBUG */
  20248. +
  20249. + cesaLastSid = sid;
  20250. +
  20251. +#if (MV_CESA_VERSION >= 3)
  20252. + /* Are we within chain bounderies and follows the first request ? */
  20253. + if((chainReqNum > 0) && (chainReqNum < MAX_CESA_CHAIN_LENGTH)) {
  20254. + if(chainIndex) {
  20255. + pFromReq = MV_CESA_REQ_PREV_PTR(pReq);
  20256. + pToReq = pReq;
  20257. + pReq->state = MV_CESA_CHAIN;
  20258. + /* assume concatenating is possible */
  20259. + pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast->phyNextDescPtr =
  20260. + MV_32BIT_LE(mvCesaVirtToPhys(&pToReq->dmaDescBuf, pToReq->dma[0].pDmaFirst));
  20261. + mvOsCacheFlush(NULL, pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast, sizeof(MV_DMA_DESC));
  20262. +
  20263. + /* align active & next pointers */
  20264. + if(pNextActiveChain->state != MV_CESA_PENDING)
  20265. + pEndCurrChain = pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pReq);
  20266. + }
  20267. + else { /* we have only one chain, start new one */
  20268. + chainReqNum = 0;
  20269. + chainIndex++;
  20270. + /* align active & next pointers */
  20271. + if(pNextActiveChain->state != MV_CESA_PENDING)
  20272. + pEndCurrChain = pNextActiveChain = pReq;
  20273. + }
  20274. + }
  20275. + else {
  20276. + /* In case we concatenate full chain */
  20277. + if(chainReqNum == MAX_CESA_CHAIN_LENGTH) {
  20278. + chainIndex++;
  20279. + if(pNextActiveChain->state != MV_CESA_PENDING)
  20280. + pEndCurrChain = pNextActiveChain = pReq;
  20281. + chainReqNum = 0;
  20282. + }
  20283. +
  20284. + pReq = pCesaReqProcess;
  20285. + if(pReq->state == MV_CESA_PENDING) {
  20286. + pNextActiveChain = pReq;
  20287. + pEndCurrChain = MV_CESA_REQ_NEXT_PTR(pReq);
  20288. + /* Start Process new request */
  20289. + mvCesaReqProcessStart(pReq);
  20290. + }
  20291. + }
  20292. +
  20293. + chainReqNum++;
  20294. +
  20295. + if((chainIndex < MAX_CESA_CHAIN_LENGTH) && (chainReqNum > cesaStats.maxChainUsage))
  20296. + cesaStats.maxChainUsage = chainReqNum;
  20297. +
  20298. +#else
  20299. +
  20300. + /* Check status of CESA channels and process requests if possible */
  20301. + pReq = pCesaReqProcess;
  20302. + if(pReq->state == MV_CESA_PENDING)
  20303. + {
  20304. + /* Start Process new request */
  20305. + mvCesaReqProcessStart(pReq);
  20306. + }
  20307. +#endif
  20308. + /* If request queue became FULL - return MV_NO_MORE */
  20309. + if(cesaReqResources == 0)
  20310. + return MV_NO_MORE;
  20311. +
  20312. + return MV_OK;
  20313. +
  20314. +}
  20315. +
  20316. +/*******************************************************************************
  20317. +* mvCesaReadyGet - Get crypto request that processing is finished
  20318. +*
  20319. +* DESCRIPTION:
  20320. +* This function complete request processing and return ready request to
  20321. +* caller. To don't miss interrupts the caller must call this function
  20322. +* while MV_OK or MV_TERMINATE values returned.
  20323. +*
  20324. +* INPUT:
  20325. +* MV_U32 chanMap - map of CESA channels finished thier job
  20326. +* accordingly with CESA Cause register.
  20327. +* MV_CESA_RESULT* pResult - pointer to structure contains information
  20328. +* about ready request. It includes pointer to
  20329. +* user private structure "pReqPrv", session identifier
  20330. +* for this request "sessionId" and return code.
  20331. +* Return code set to MV_FAIL if calculated digest value
  20332. +* on decode direction is different than digest value
  20333. +* in the packet.
  20334. +*
  20335. +* RETURN:
  20336. +* MV_OK - Success, ready request is returned.
  20337. +* MV_NOT_READY - Next request is not ready yet. New interrupt will
  20338. +* be generated for futher request processing.
  20339. +* MV_EMPTY - There is no more request for processing.
  20340. +* MV_BUSY - Fragmented request is not ready yet.
  20341. +* MV_TERMINATE - Call this function once more to complete processing
  20342. +* of fragmented request.
  20343. +*
  20344. +*******************************************************************************/
  20345. +MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult)
  20346. +{
  20347. + MV_STATUS status, readyStatus = MV_NOT_READY;
  20348. + MV_U32 statusReg;
  20349. + MV_CESA_REQ* pReq;
  20350. + MV_CESA_SA* pSA;
  20351. +
  20352. +#if (MV_CESA_VERSION >= 3)
  20353. + if(isFirstReq == MV_TRUE) {
  20354. + if(chainIndex == 0)
  20355. + chainReqNum = 0;
  20356. +
  20357. + isFirstReq = MV_FALSE;
  20358. +
  20359. + if(pNextActiveChain->state == MV_CESA_PENDING) {
  20360. + /* Start request Process */
  20361. + mvCesaReqProcessStart(pNextActiveChain);
  20362. + pEndCurrChain = pNextActiveChain;
  20363. + if(chainIndex > 0)
  20364. + chainIndex--;
  20365. + /* Update pNextActiveChain to next chain head */
  20366. + while(pNextActiveChain->state == MV_CESA_CHAIN)
  20367. + pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pNextActiveChain);
  20368. + }
  20369. + }
  20370. +
  20371. + /* Check if there are more processed requests - can we remove pEndCurrChain ??? */
  20372. + if(pCesaReqProcess == pEndCurrChain) {
  20373. + isFirstReq = MV_TRUE;
  20374. + pEndCurrChain = pNextActiveChain;
  20375. +#else
  20376. + if(pCesaReqProcess->state != MV_CESA_PROCESS) {
  20377. +#endif
  20378. + return MV_EMPTY;
  20379. + }
  20380. +
  20381. +#ifdef CESA_DEBUG
  20382. + statusReg = MV_REG_READ(MV_CESA_STATUS_REG);
  20383. + if( statusReg & MV_CESA_STATUS_ACTIVE_MASK )
  20384. + {
  20385. + mvOsPrintf("mvCesaReadyGet: Not Ready, Status = 0x%x\n", statusReg);
  20386. + cesaStats.notReadyCount++;
  20387. + return MV_NOT_READY;
  20388. + }
  20389. +#endif /* CESA_DEBUG */
  20390. +
  20391. + cesaStats.readyCount++;
  20392. +
  20393. + pReq = pCesaReqProcess;
  20394. + pSA = &pCesaSAD[pReq->pCmd->sessionId];
  20395. +
  20396. + pResult->retCode = MV_OK;
  20397. + if(pReq->fragMode != MV_CESA_FRAG_NONE)
  20398. + {
  20399. + MV_U8* pNewDigest;
  20400. + int frag;
  20401. +#if (MV_CESA_VERSION >= 3)
  20402. + pReq->frags.nextFrag = 1;
  20403. + while(pReq->frags.nextFrag <= pReq->frags.numFrag) {
  20404. +#endif
  20405. + frag = (pReq->frags.nextFrag - 1);
  20406. +
  20407. + /* Restore DMA descriptor list */
  20408. + pReq->dma[frag].pDmaLast->phyNextDescPtr =
  20409. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[frag].pDmaLast[1]));
  20410. + pReq->dma[frag].pDmaLast = NULL;
  20411. +
  20412. + /* Special processing for finished fragmented request */
  20413. + if(pReq->frags.nextFrag >= pReq->frags.numFrag)
  20414. + {
  20415. + mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);
  20416. +
  20417. + /* Fragmented packet is ready */
  20418. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  20419. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  20420. + {
  20421. + int macDataSize = pReq->pCmd->macLength - pReq->frags.macSize;
  20422. +
  20423. + if(macDataSize != 0)
  20424. + {
  20425. + /* Calculate all other blocks by SW */
  20426. + mvCesaFragAuthComplete(pReq, pSA, macDataSize);
  20427. + }
  20428. +
  20429. + /* Copy new digest from SRAM to the Destination buffer */
  20430. + pNewDigest = cesaSramVirtPtr->buf + pReq->frags.newDigestOffset;
  20431. + status = mvCesaCopyToMbuf(pNewDigest, pReq->pCmd->pDst,
  20432. + pReq->pCmd->digestOffset, pSA->digestSize);
  20433. +
  20434. + /* For decryption: Compare new digest value with original one */
  20435. + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
  20436. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
  20437. + {
  20438. + if( memcmp(pNewDigest, pReq->frags.orgDigest, pSA->digestSize) != 0)
  20439. + {
  20440. +/*
  20441. + mvOsPrintf("Digest error: chan=%d, newDigest=%p, orgDigest=%p, status = 0x%x\n",
  20442. + chan, pNewDigest, pReq->frags.orgDigest, MV_REG_READ(MV_CESA_STATUS_REG));
  20443. +*/
  20444. + /* Signiture verification is failed */
  20445. + pResult->retCode = MV_FAIL;
  20446. + }
  20447. + }
  20448. + }
  20449. + readyStatus = MV_OK;
  20450. + }
  20451. +#if (MV_CESA_VERSION >= 3)
  20452. + pReq->frags.nextFrag++;
  20453. + }
  20454. +#endif
  20455. + }
  20456. + else
  20457. + {
  20458. + mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);
  20459. +
  20460. + /* Restore DMA descriptor list */
  20461. + pReq->dma[0].pDmaLast->phyNextDescPtr =
  20462. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[0].pDmaLast[1]));
  20463. + pReq->dma[0].pDmaLast = NULL;
  20464. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  20465. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) &&
  20466. + ((pSA->config & MV_CESA_DIRECTION_MASK) ==
  20467. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT)) )
  20468. + {
  20469. + /* For AUTH on decode : Check Digest result in Status register */
  20470. + statusReg = MV_REG_READ(MV_CESA_STATUS_REG);
  20471. + if(statusReg & MV_CESA_STATUS_DIGEST_ERR_MASK)
  20472. + {
  20473. +/*
  20474. + mvOsPrintf("Digest error: chan=%d, status = 0x%x\n",
  20475. + chan, statusReg);
  20476. +*/
  20477. + /* Signiture verification is failed */
  20478. + pResult->retCode = MV_FAIL;
  20479. + }
  20480. + }
  20481. + readyStatus = MV_OK;
  20482. + }
  20483. +
  20484. + if(readyStatus == MV_OK)
  20485. + {
  20486. + /* If Request is ready - Prepare pResult structure */
  20487. + pResult->pReqPrv = pReq->pCmd->pReqPrv;
  20488. + pResult->sessionId = pReq->pCmd->sessionId;
  20489. +
  20490. + pReq->state = MV_CESA_IDLE;
  20491. + pCesaReqProcess = MV_CESA_REQ_NEXT_PTR(pReq);
  20492. + cesaReqResources++;
  20493. +
  20494. + if(pSA->ctrMode)
  20495. + {
  20496. + /* For AES CTR mode - complete processing and free allocated resources */
  20497. + mvCesaCtrModeComplete(pReq->pOrgCmd, pReq->pCmd);
  20498. + mvCesaCtrModeFinish(pReq->pCmd);
  20499. + pReq->pOrgCmd = NULL;
  20500. + }
  20501. + }
  20502. +
  20503. +#if (MV_CESA_VERSION < 3)
  20504. + if(pCesaReqProcess->state == MV_CESA_PROCESS)
  20505. + {
  20506. + /* Start request Process */
  20507. + mvCesaReqProcessStart(pCesaReqProcess);
  20508. + if(readyStatus == MV_NOT_READY)
  20509. + readyStatus = MV_BUSY;
  20510. + }
  20511. + else if(pCesaReqProcess != pCesaReqEmpty)
  20512. + {
  20513. + /* Start process new request from the queue */
  20514. + mvCesaReqProcessStart(pCesaReqProcess);
  20515. + }
  20516. +#endif
  20517. + return readyStatus;
  20518. +}
  20519. +
  20520. +/***************** Functions to work with CESA_MBUF structure ******************/
  20521. +
  20522. +/*******************************************************************************
  20523. +* mvCesaMbufOffset - Locate offset in the Mbuf structure
  20524. +*
  20525. +* DESCRIPTION:
  20526. +* This function locates offset inside Multi-Bufeer structure.
  20527. +* It get fragment number and place in the fragment where the offset
  20528. +* is located.
  20529. +*
  20530. +*
  20531. +* INPUT:
  20532. +* MV_CESA_MBUF* pMbuf - Pointer to multi-buffer structure
  20533. +* int offset - Offset from the beginning of the data presented by
  20534. +* the Mbuf structure.
  20535. +*
  20536. +* OUTPUT:
  20537. +* int* pBufOffset - Offset from the beginning of the fragment where
  20538. +* the offset is located.
  20539. +*
  20540. +* RETURN:
  20541. +* int - Number of fragment, where the offset is located\
  20542. +*
  20543. +*******************************************************************************/
  20544. +int mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset)
  20545. +{
  20546. + int frag = 0;
  20547. +
  20548. + while(offset > 0)
  20549. + {
  20550. + if(frag >= pMbuf->numFrags)
  20551. + {
  20552. + mvOsPrintf("mvCesaMbufOffset: Error: frag (%d) > numFrags (%d)\n",
  20553. + frag, pMbuf->numFrags);
  20554. + return MV_INVALID;
  20555. + }
  20556. + if(offset < pMbuf->pFrags[frag].bufSize)
  20557. + {
  20558. + break;
  20559. + }
  20560. + offset -= pMbuf->pFrags[frag].bufSize;
  20561. + frag++;
  20562. + }
  20563. + if(pBufOffset != NULL)
  20564. + *pBufOffset = offset;
  20565. +
  20566. + return frag;
  20567. +}
  20568. +
  20569. +/*******************************************************************************
  20570. +* mvCesaCopyFromMbuf - Copy data from the Mbuf structure to continuous buffer
  20571. +*
  20572. +* DESCRIPTION:
  20573. +*
  20574. +*
  20575. +* INPUT:
  20576. +* MV_U8* pDstBuf - Pointer to continuous buffer, where data is
  20577. +* copied to.
  20578. +* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
  20579. +* copied from.
  20580. +* int offset - Offset in the Mbuf structure where located first
  20581. +* byte of data should be copied.
  20582. +* int size - Size of data should be copied
  20583. +*
  20584. +* RETURN:
  20585. +* MV_OK - Success, all data is copied successfully.
  20586. +* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
  20587. +* No data is copied.
  20588. +* MV_EMPTY - Multi-buffer structure has not enough data to copy
  20589. +* Data from the offset to end of Mbuf data is copied.
  20590. +*
  20591. +*******************************************************************************/
  20592. +MV_STATUS mvCesaCopyFromMbuf(MV_U8* pDstBuf, MV_CESA_MBUF* pSrcMbuf,
  20593. + int offset, int size)
  20594. +{
  20595. + int frag, fragOffset, bufSize;
  20596. + MV_U8* pBuf;
  20597. +
  20598. + if(size == 0)
  20599. + return MV_OK;
  20600. +
  20601. + frag = mvCesaMbufOffset(pSrcMbuf, offset, &fragOffset);
  20602. + if(frag == MV_INVALID)
  20603. + {
  20604. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  20605. + return MV_OUT_OF_RANGE;
  20606. + }
  20607. +
  20608. + bufSize = pSrcMbuf->pFrags[frag].bufSize - fragOffset;
  20609. + pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  20610. + while(MV_TRUE)
  20611. + {
  20612. + if(size <= bufSize)
  20613. + {
  20614. + memcpy(pDstBuf, pBuf, size);
  20615. + return MV_OK;
  20616. + }
  20617. + memcpy(pDstBuf, pBuf, bufSize);
  20618. + size -= bufSize;
  20619. + frag++;
  20620. + pDstBuf += bufSize;
  20621. + if(frag >= pSrcMbuf->numFrags)
  20622. + break;
  20623. +
  20624. + bufSize = pSrcMbuf->pFrags[frag].bufSize;
  20625. + pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr;
  20626. + }
  20627. + mvOsPrintf("mvCesaCopyFromMbuf: Mbuf is EMPTY - %d bytes isn't copied\n",
  20628. + size);
  20629. + return MV_EMPTY;
  20630. +}
  20631. +
  20632. +/*******************************************************************************
  20633. +* mvCesaCopyToMbuf - Copy data from continuous buffer to the Mbuf structure
  20634. +*
  20635. +* DESCRIPTION:
  20636. +*
  20637. +*
  20638. +* INPUT:
  20639. +* MV_U8* pSrcBuf - Pointer to continuous buffer, where data is
  20640. +* copied from.
  20641. +* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
  20642. +* copied to.
  20643. +* int offset - Offset in the Mbuf structure where located first
  20644. +* byte of data should be copied.
  20645. +* int size - Size of data should be copied
  20646. +*
  20647. +* RETURN:
  20648. +* MV_OK - Success, all data is copied successfully.
  20649. +* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
  20650. +* No data is copied.
  20651. +* MV_FULL - Multi-buffer structure has not enough place to copy
  20652. +* all data. Data from the offset to end of Mbuf data
  20653. +* is copied.
  20654. +*
  20655. +*******************************************************************************/
  20656. +MV_STATUS mvCesaCopyToMbuf(MV_U8* pSrcBuf, MV_CESA_MBUF* pDstMbuf,
  20657. + int offset, int size)
  20658. +{
  20659. + int frag, fragOffset, bufSize;
  20660. + MV_U8* pBuf;
  20661. +
  20662. + if(size == 0)
  20663. + return MV_OK;
  20664. +
  20665. + frag = mvCesaMbufOffset(pDstMbuf, offset, &fragOffset);
  20666. + if(frag == MV_INVALID)
  20667. + {
  20668. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  20669. + return MV_OUT_OF_RANGE;
  20670. + }
  20671. +
  20672. + bufSize = pDstMbuf->pFrags[frag].bufSize - fragOffset;
  20673. + pBuf = pDstMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  20674. + while(MV_TRUE)
  20675. + {
  20676. + if(size <= bufSize)
  20677. + {
  20678. + memcpy(pBuf, pSrcBuf, size);
  20679. + return MV_OK;
  20680. + }
  20681. + memcpy(pBuf, pSrcBuf, bufSize);
  20682. + size -= bufSize;
  20683. + frag++;
  20684. + pSrcBuf += bufSize;
  20685. + if(frag >= pDstMbuf->numFrags)
  20686. + break;
  20687. +
  20688. + bufSize = pDstMbuf->pFrags[frag].bufSize;
  20689. + pBuf = pDstMbuf->pFrags[frag].bufVirtPtr;
  20690. + }
  20691. + mvOsPrintf("mvCesaCopyToMbuf: Mbuf is FULL - %d bytes isn't copied\n",
  20692. + size);
  20693. + return MV_FULL;
  20694. +}
  20695. +
  20696. +/*******************************************************************************
  20697. +* mvCesaMbufCopy - Copy data from one Mbuf structure to the other Mbuf structure
  20698. +*
  20699. +* DESCRIPTION:
  20700. +*
  20701. +*
  20702. +* INPUT:
  20703. +*
  20704. +* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
  20705. +* copied to.
  20706. +* int dstMbufOffset - Offset in the dstMbuf structure where first byte
  20707. +* of data should be copied to.
  20708. +* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
  20709. +* copied from.
  20710. +* int srcMbufOffset - Offset in the srcMbuf structure where first byte
  20711. +* of data should be copied from.
  20712. +* int size - Size of data should be copied
  20713. +*
  20714. +* RETURN:
  20715. +* MV_OK - Success, all data is copied successfully.
  20716. +* MV_OUT_OF_RANGE - Failed, srcMbufOffset or dstMbufOffset is out of
  20717. +* srcMbuf or dstMbuf structure correspondently.
  20718. +* No data is copied.
  20719. +* MV_BAD_SIZE - srcMbuf or dstMbuf structure is too small to copy
  20720. +* all data. Partial data is copied
  20721. +*
  20722. +*******************************************************************************/
  20723. +MV_STATUS mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,
  20724. + MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size)
  20725. +{
  20726. + int srcFrag, dstFrag, srcSize, dstSize, srcOffset, dstOffset;
  20727. + int copySize;
  20728. + MV_U8 *pSrc, *pDst;
  20729. +
  20730. + if(size == 0)
  20731. + return MV_OK;
  20732. +
  20733. + srcFrag = mvCesaMbufOffset(pMbufSrc, srcMbufOffset, &srcOffset);
  20734. + if(srcFrag == MV_INVALID)
  20735. + {
  20736. + mvOsPrintf("CESA srcMbuf Error: offset (%d) out of range\n", srcMbufOffset);
  20737. + return MV_OUT_OF_RANGE;
  20738. + }
  20739. + pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr + srcOffset;
  20740. + srcSize = pMbufSrc->pFrags[srcFrag].bufSize - srcOffset;
  20741. +
  20742. + dstFrag = mvCesaMbufOffset(pMbufDst, dstMbufOffset, &dstOffset);
  20743. + if(dstFrag == MV_INVALID)
  20744. + {
  20745. + mvOsPrintf("CESA dstMbuf Error: offset (%d) out of range\n", dstMbufOffset);
  20746. + return MV_OUT_OF_RANGE;
  20747. + }
  20748. + pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr + dstOffset;
  20749. + dstSize = pMbufDst->pFrags[dstFrag].bufSize - dstOffset;
  20750. +
  20751. + while(size > 0)
  20752. + {
  20753. + copySize = MV_MIN(srcSize, dstSize);
  20754. + if(size <= copySize)
  20755. + {
  20756. + memcpy(pDst, pSrc, size);
  20757. + return MV_OK;
  20758. + }
  20759. + memcpy(pDst, pSrc, copySize);
  20760. + size -= copySize;
  20761. + srcSize -= copySize;
  20762. + dstSize -= copySize;
  20763. +
  20764. + if(srcSize == 0)
  20765. + {
  20766. + srcFrag++;
  20767. + if(srcFrag >= pMbufSrc->numFrags)
  20768. + break;
  20769. +
  20770. + pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr;
  20771. + srcSize = pMbufSrc->pFrags[srcFrag].bufSize;
  20772. + }
  20773. +
  20774. + if(dstSize == 0)
  20775. + {
  20776. + dstFrag++;
  20777. + if(dstFrag >= pMbufDst->numFrags)
  20778. + break;
  20779. +
  20780. + pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr;
  20781. + dstSize = pMbufDst->pFrags[dstFrag].bufSize;
  20782. + }
  20783. + }
  20784. + mvOsPrintf("mvCesaMbufCopy: BAD size - %d bytes isn't copied\n",
  20785. + size);
  20786. +
  20787. + return MV_BAD_SIZE;
  20788. +}
  20789. +
  20790. +static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size)
  20791. +{
  20792. + int frag, fragOffset, bufSize;
  20793. + MV_U8* pBuf;
  20794. +
  20795. + if(size == 0)
  20796. + return MV_OK;
  20797. +
  20798. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  20799. + if(frag == MV_INVALID)
  20800. + {
  20801. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  20802. + return MV_OUT_OF_RANGE;
  20803. + }
  20804. +
  20805. + bufSize = pMbuf->pFrags[frag].bufSize - fragOffset;
  20806. + pBuf = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  20807. + while(MV_TRUE)
  20808. + {
  20809. + if(size <= bufSize)
  20810. + {
  20811. + mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), size);
  20812. + return MV_OK;
  20813. + }
  20814. +
  20815. + mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), bufSize);
  20816. + size -= bufSize;
  20817. + frag++;
  20818. + if(frag >= pMbuf->numFrags)
  20819. + break;
  20820. +
  20821. + bufSize = pMbuf->pFrags[frag].bufSize;
  20822. + pBuf = pMbuf->pFrags[frag].bufVirtPtr;
  20823. + }
  20824. + mvOsPrintf("%s: Mbuf is FULL - %d bytes isn't Unmapped\n",
  20825. + __FUNCTION__, size);
  20826. + return MV_FULL;
  20827. +}
  20828. +
  20829. +
  20830. +/*************************************** Local Functions ******************************/
  20831. +
  20832. +/*******************************************************************************
  20833. +* mvCesaFragReqProcess - Process fragmented request
  20834. +*
  20835. +* DESCRIPTION:
  20836. +* This function processes a fragment of fragmented request (First, Middle or Last)
  20837. +*
  20838. +*
  20839. +* INPUT:
  20840. +* MV_CESA_REQ* pReq - Pointer to the request in the request queue.
  20841. +*
  20842. +* RETURN:
  20843. +* MV_OK - The fragment is successfully passed to HW for processing.
  20844. +* MV_TERMINATE - Means, that HW finished its work on this packet and no more
  20845. +* interrupts will be generated for this request.
  20846. +* Function mvCesaReadyGet() must be called to complete request
  20847. +* processing and get request result.
  20848. +*
  20849. +*******************************************************************************/
  20850. +static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag)
  20851. +{
  20852. + int i, copySize, cryptoDataSize, macDataSize, sid;
  20853. + int cryptoIvOffset, digestOffset;
  20854. + MV_U32 config;
  20855. + MV_CESA_COMMAND* pCmd = pReq->pCmd;
  20856. + MV_CESA_SA* pSA;
  20857. + MV_CESA_MBUF* pMbuf;
  20858. + MV_DMA_DESC* pDmaDesc = pReq->dma[frag].pDmaFirst;
  20859. + MV_U8* pSramBuf = cesaSramVirtPtr->buf;
  20860. + int macTotalLen = 0;
  20861. + int fixOffset, cryptoOffset, macOffset;
  20862. +
  20863. + cesaStats.fragCount++;
  20864. +
  20865. + sid = pReq->pCmd->sessionId;
  20866. +
  20867. + pSA = &pCesaSAD[sid];
  20868. +
  20869. + cryptoIvOffset = digestOffset = 0;
  20870. + i = macDataSize = 0;
  20871. + cryptoDataSize = 0;
  20872. +
  20873. + /* First fragment processing */
  20874. + if(pReq->fragMode == MV_CESA_FRAG_FIRST)
  20875. + {
  20876. + /* pReq->frags monitors processing of fragmented request between fragments */
  20877. + pReq->frags.bufOffset = 0;
  20878. + pReq->frags.cryptoSize = 0;
  20879. + pReq->frags.macSize = 0;
  20880. +
  20881. + config = pSA->config | (MV_CESA_FRAG_FIRST << MV_CESA_FRAG_MODE_OFFSET);
  20882. +
  20883. + /* fixOffset can be not equal to zero only for FIRST fragment */
  20884. + fixOffset = pReq->fixOffset;
  20885. + /* For FIRST fragment crypto and mac offsets are taken from pCmd */
  20886. + cryptoOffset = pCmd->cryptoOffset;
  20887. + macOffset = pCmd->macOffset;
  20888. +
  20889. + copySize = sizeof(cesaSramVirtPtr->buf) - pReq->fixOffset;
  20890. +
  20891. + /* Find fragment size: Must meet all requirements for CRYPTO and MAC
  20892. + * cryptoDataSize - size of data will be encrypted/decrypted in this fragment
  20893. + * macDataSize - size of data will be signed/verified in this fragment
  20894. + * copySize - size of data will be copied from srcMbuf to SRAM and
  20895. + * back to dstMbuf for this fragment
  20896. + */
  20897. + mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,
  20898. + &copySize, &cryptoDataSize, &macDataSize);
  20899. +
  20900. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  20901. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET))
  20902. + {
  20903. + /* CryptoIV special processing */
  20904. + if( (pSA->config & MV_CESA_CRYPTO_MODE_MASK) ==
  20905. + (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT) )
  20906. + {
  20907. + /* In CBC mode for encode direction when IV from user */
  20908. + if( (pCmd->ivFromUser) &&
  20909. + ((pSA->config & MV_CESA_DIRECTION_MASK) ==
  20910. + (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) )
  20911. + {
  20912. +
  20913. + /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
  20914. + * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
  20915. + * in the buffer to SRAM IVPointer
  20916. + */
  20917. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
  20918. + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  20919. + }
  20920. +
  20921. + /* Special processing when IV is not located in the first fragment */
  20922. + if(pCmd->ivOffset > (copySize - pSA->cryptoIvSize))
  20923. + {
  20924. + /* Prepare dummy place for cryptoIV in SRAM */
  20925. + cryptoIvOffset = cesaSramVirtPtr->tempCryptoIV - mvCesaSramAddrGet();
  20926. +
  20927. + /* For Decryption: Copy IV value from pCmd->ivOffset to Special SRAM place */
  20928. + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
  20929. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
  20930. + {
  20931. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->tempCryptoIV, &pDmaDesc[i],
  20932. + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  20933. + }
  20934. + else
  20935. + {
  20936. + /* For Encryption when IV is NOT from User: */
  20937. + /* Copy IV from SRAM to buffer (pCmd->ivOffset) */
  20938. + if(pCmd->ivFromUser == 0)
  20939. + {
  20940. + /* copy IV value from cryptoIV to Buffer (pCmd->ivOffset) */
  20941. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
  20942. + MV_TRUE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  20943. + }
  20944. + }
  20945. + }
  20946. + else
  20947. + {
  20948. + cryptoIvOffset = pCmd->ivOffset;
  20949. + }
  20950. + }
  20951. + }
  20952. +
  20953. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  20954. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  20955. + {
  20956. + /* MAC digest special processing on Decode direction */
  20957. + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
  20958. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
  20959. + {
  20960. + /* Save digest from pCmd->digestOffset */
  20961. + mvCesaCopyFromMbuf(pReq->frags.orgDigest,
  20962. + pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);
  20963. +
  20964. + /* If pCmd->digestOffset is not located on the first */
  20965. + if(pCmd->digestOffset > (copySize - pSA->digestSize))
  20966. + {
  20967. + MV_U8 digestZero[MV_CESA_MAX_DIGEST_SIZE];
  20968. +
  20969. + /* Set zeros to pCmd->digestOffset (DRAM) */
  20970. + memset(digestZero, 0, MV_CESA_MAX_DIGEST_SIZE);
  20971. + mvCesaCopyToMbuf(digestZero, pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);
  20972. +
  20973. + /* Prepare dummy place for digest in SRAM */
  20974. + digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
  20975. + }
  20976. + else
  20977. + {
  20978. + digestOffset = pCmd->digestOffset;
  20979. + }
  20980. + }
  20981. + }
  20982. + /* Update SA in SRAM */
  20983. + if(cesaLastSid != sid)
  20984. + {
  20985. + mvCesaSramSaUpdate(sid, &pDmaDesc[i]);
  20986. + i++;
  20987. + }
  20988. +
  20989. + pReq->fragMode = MV_CESA_FRAG_MIDDLE;
  20990. + }
  20991. + else
  20992. + {
  20993. + /* Continue fragment */
  20994. + fixOffset = 0;
  20995. + cryptoOffset = 0;
  20996. + macOffset = 0;
  20997. + if( (pCmd->pSrc->mbufSize - pReq->frags.bufOffset) <= sizeof(cesaSramVirtPtr->buf))
  20998. + {
  20999. + /* Last fragment */
  21000. + config = pSA->config | (MV_CESA_FRAG_LAST << MV_CESA_FRAG_MODE_OFFSET);
  21001. + pReq->fragMode = MV_CESA_FRAG_LAST;
  21002. + copySize = pCmd->pSrc->mbufSize - pReq->frags.bufOffset;
  21003. +
  21004. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  21005. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  21006. + {
  21007. + macDataSize = pCmd->macLength - pReq->frags.macSize;
  21008. +
  21009. + /* If pCmd->digestOffset is not located on last fragment */
  21010. + if(pCmd->digestOffset < pReq->frags.bufOffset)
  21011. + {
  21012. + /* Prepare dummy place for digest in SRAM */
  21013. + digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
  21014. + }
  21015. + else
  21016. + {
  21017. + digestOffset = pCmd->digestOffset - pReq->frags.bufOffset;
  21018. + }
  21019. + pReq->frags.newDigestOffset = digestOffset;
  21020. + macTotalLen = pCmd->macLength;
  21021. +
  21022. + /* HW can't calculate the Digest correctly for fragmented packets
  21023. + * in the following cases:
  21024. + * - MV88F5182 ||
  21025. + * - MV88F5181L when total macLength more that 16 Kbytes ||
  21026. + * - total macLength more that 64 Kbytes
  21027. + */
  21028. + if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||
  21029. + ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&
  21030. + (mvCtrlRevGet() >= MV_5181L_A0_REV) &&
  21031. + (pCmd->macLength >= (1 << 14)) ) )
  21032. + {
  21033. + return MV_TERMINATE;
  21034. + }
  21035. + }
  21036. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  21037. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
  21038. + {
  21039. + cryptoDataSize = pCmd->cryptoLength - pReq->frags.cryptoSize;
  21040. + }
  21041. +
  21042. + /* cryptoIvOffset - don't care */
  21043. + }
  21044. + else
  21045. + {
  21046. + /* WA for MV88F5182 SHA1 and MD5 fragmentation mode */
  21047. + if( (mvCtrlModelGet() == MV_5182_DEV_ID) &&
  21048. + (((pSA->config & MV_CESA_MAC_MODE_MASK) ==
  21049. + (MV_CESA_MAC_MD5 << MV_CESA_MAC_MODE_OFFSET)) ||
  21050. + ((pSA->config & MV_CESA_MAC_MODE_MASK) ==
  21051. + (MV_CESA_MAC_SHA1 << MV_CESA_MAC_MODE_OFFSET))) )
  21052. + {
  21053. + pReq->frags.newDigestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
  21054. + pReq->fragMode = MV_CESA_FRAG_LAST;
  21055. +
  21056. + return MV_TERMINATE;
  21057. + }
  21058. + /* Middle fragment */
  21059. + config = pSA->config | (MV_CESA_FRAG_MIDDLE << MV_CESA_FRAG_MODE_OFFSET);
  21060. + copySize = sizeof(cesaSramVirtPtr->buf);
  21061. + /* digestOffset and cryptoIvOffset - don't care */
  21062. +
  21063. + /* Find fragment size */
  21064. + mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,
  21065. + &copySize, &cryptoDataSize, &macDataSize);
  21066. + }
  21067. + }
  21068. + /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
  21069. + pMbuf = pCmd->pSrc;
  21070. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  21071. + MV_FALSE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);
  21072. +
  21073. + /* Prepare CESA descriptor to copy from DRAM to SRAM by DMA */
  21074. + mvCesaSramDescrBuild(config, frag,
  21075. + cryptoOffset + fixOffset, cryptoIvOffset + fixOffset,
  21076. + cryptoDataSize, macOffset + fixOffset,
  21077. + digestOffset + fixOffset, macDataSize, macTotalLen,
  21078. + pReq, &pDmaDesc[i]);
  21079. + i++;
  21080. +
  21081. + /* Add special descriptor Ownership for CPU */
  21082. + pDmaDesc[i].byteCnt = 0;
  21083. + pDmaDesc[i].phySrcAdd = 0;
  21084. + pDmaDesc[i].phyDestAdd = 0;
  21085. + i++;
  21086. +
  21087. + /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
  21088. + pMbuf = pCmd->pDst;
  21089. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  21090. + MV_TRUE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);
  21091. +
  21092. + /* Next field of Last DMA descriptor must be NULL */
  21093. + pDmaDesc[i-1].phyNextDescPtr = 0;
  21094. + pReq->dma[frag].pDmaLast = &pDmaDesc[i-1];
  21095. + mvOsCacheFlush(NULL, pReq->dma[frag].pDmaFirst,
  21096. + i*sizeof(MV_DMA_DESC));
  21097. +
  21098. + /*mvCesaDebugDescriptor(&cesaSramVirtPtr->desc[frag]);*/
  21099. +
  21100. + pReq->frags.bufOffset += copySize;
  21101. + pReq->frags.cryptoSize += cryptoDataSize;
  21102. + pReq->frags.macSize += macDataSize;
  21103. +
  21104. + return MV_OK;
  21105. +}
  21106. +
  21107. +
  21108. +/*******************************************************************************
  21109. +* mvCesaReqProcess - Process regular (Non-fragmented) request
  21110. +*
  21111. +* DESCRIPTION:
  21112. +* This function processes the whole (not fragmented) request
  21113. +*
  21114. +* INPUT:
  21115. +* MV_CESA_REQ* pReq - Pointer to the request in the request queue.
  21116. +*
  21117. +* RETURN:
  21118. +* MV_OK - The request is successfully passed to HW for processing.
  21119. +* Other - Failure. The request will not be processed
  21120. +*
  21121. +*******************************************************************************/
  21122. +static MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq)
  21123. +{
  21124. + MV_CESA_MBUF *pMbuf;
  21125. + MV_DMA_DESC *pDmaDesc;
  21126. + MV_U8 *pSramBuf;
  21127. + int sid, i, fixOffset;
  21128. + MV_CESA_SA *pSA;
  21129. + MV_CESA_COMMAND *pCmd = pReq->pCmd;
  21130. +
  21131. + cesaStats.procCount++;
  21132. +
  21133. + sid = pCmd->sessionId;
  21134. + pSA = &pCesaSAD[sid];
  21135. + pDmaDesc = pReq->dma[0].pDmaFirst;
  21136. + pSramBuf = cesaSramVirtPtr->buf;
  21137. + fixOffset = pReq->fixOffset;
  21138. +
  21139. +/*
  21140. + mvOsPrintf("mvCesaReqProcess: sid=%d, pSA=%p, pDmaDesc=%p, pSramBuf=%p\n",
  21141. + sid, pSA, pDmaDesc, pSramBuf);
  21142. +*/
  21143. + i = 0;
  21144. +
  21145. + /* Crypto IV Special processing in CBC mode for Encryption direction */
  21146. + if( ((pSA->config & MV_CESA_OPERATION_MASK) != (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) &&
  21147. + ((pSA->config & MV_CESA_CRYPTO_MODE_MASK) == (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT)) &&
  21148. + ((pSA->config & MV_CESA_DIRECTION_MASK) == (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) &&
  21149. + (pCmd->ivFromUser) )
  21150. + {
  21151. + /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
  21152. + * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
  21153. + * in the buffer to SRAM IVPointer
  21154. + */
  21155. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
  21156. + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  21157. + }
  21158. +
  21159. + /* Update SA in SRAM */
  21160. + if(cesaLastSid != sid)
  21161. + {
  21162. + mvCesaSramSaUpdate(sid, &pDmaDesc[i]);
  21163. + i++;
  21164. + }
  21165. +
  21166. + /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
  21167. + pMbuf = pCmd->pSrc;
  21168. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  21169. + MV_FALSE, 0, pMbuf->mbufSize, pCmd->skipFlush);
  21170. +
  21171. + /* Prepare Security Accelerator descriptor to SRAM words 0 - 7 */
  21172. + mvCesaSramDescrBuild(pSA->config, 0, pCmd->cryptoOffset + fixOffset,
  21173. + pCmd->ivOffset + fixOffset, pCmd->cryptoLength,
  21174. + pCmd->macOffset + fixOffset, pCmd->digestOffset + fixOffset,
  21175. + pCmd->macLength, pCmd->macLength, pReq, &pDmaDesc[i]);
  21176. + i++;
  21177. +
  21178. + /* Add special descriptor Ownership for CPU */
  21179. + pDmaDesc[i].byteCnt = 0;
  21180. + pDmaDesc[i].phySrcAdd = 0;
  21181. + pDmaDesc[i].phyDestAdd = 0;
  21182. + i++;
  21183. +
  21184. + /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
  21185. + pMbuf = pCmd->pDst;
  21186. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  21187. + MV_TRUE, 0, pMbuf->mbufSize, pCmd->skipFlush);
  21188. +
  21189. + /* Next field of Last DMA descriptor must be NULL */
  21190. + pDmaDesc[i-1].phyNextDescPtr = 0;
  21191. + pReq->dma[0].pDmaLast = &pDmaDesc[i-1];
  21192. + mvOsCacheFlush(NULL, pReq->dma[0].pDmaFirst, i*sizeof(MV_DMA_DESC));
  21193. +
  21194. + return MV_OK;
  21195. +}
  21196. +
  21197. +
  21198. +/*******************************************************************************
  21199. +* mvCesaSramDescrBuild - Set CESA descriptor in SRAM
  21200. +*
  21201. +* DESCRIPTION:
  21202. +* This function builds CESA descriptor in SRAM from all Command parameters
  21203. +*
  21204. +*
  21205. +* INPUT:
  21206. +* int chan - CESA channel uses the descriptor
  21207. +* MV_U32 config - 32 bits of WORD_0 in CESA descriptor structure
  21208. +* int cryptoOffset - Offset from the beginning of SRAM buffer where
  21209. +* data for encryption/decription is started.
  21210. +* int ivOffset - Offset of crypto IV from the SRAM base. Valid only
  21211. +* for first fragment.
  21212. +* int cryptoLength - Size (in bytes) of data for encryption/descryption
  21213. +* operation on this fragment.
  21214. +* int macOffset - Offset from the beginning of SRAM buffer where
  21215. +* data for Authentication is started
  21216. +* int digestOffset - Offset from the beginning of SRAM buffer where
  21217. +* digest is located. Valid for first and last fragments.
  21218. +* int macLength - Size (in bytes) of data for Authentication
  21219. +* operation on this fragment.
  21220. +* int macTotalLen - Toatl size (in bytes) of data for Authentication
  21221. +* operation on the whole request (packet). Valid for
  21222. +* last fragment only.
  21223. +*
  21224. +* RETURN: None
  21225. +*
  21226. +*******************************************************************************/
  21227. +static void mvCesaSramDescrBuild(MV_U32 config, int frag,
  21228. + int cryptoOffset, int ivOffset, int cryptoLength,
  21229. + int macOffset, int digestOffset, int macLength,
  21230. + int macTotalLen, MV_CESA_REQ* pReq, MV_DMA_DESC* pDmaDesc)
  21231. +{
  21232. + MV_CESA_DESC* pCesaDesc = &pReq->pCesaDesc[frag];
  21233. + MV_CESA_DESC* pSramDesc = pSramDesc = &cesaSramVirtPtr->desc;
  21234. + MV_U16 sramBufOffset = (MV_U16)((MV_U8*)cesaSramVirtPtr->buf - mvCesaSramAddrGet());
  21235. +
  21236. + pCesaDesc->config = MV_32BIT_LE(config);
  21237. +
  21238. + if( (config & MV_CESA_OPERATION_MASK) !=
  21239. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
  21240. + {
  21241. + /* word 1 */
  21242. + pCesaDesc->cryptoSrcOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);
  21243. + pCesaDesc->cryptoDstOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);
  21244. + /* word 2 */
  21245. + pCesaDesc->cryptoDataLen = MV_16BIT_LE(cryptoLength);
  21246. + /* word 3 */
  21247. + pCesaDesc->cryptoKeyOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.cryptoKey -
  21248. + mvCesaSramAddrGet()));
  21249. + /* word 4 */
  21250. + pCesaDesc->cryptoIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->cryptoIV -
  21251. + mvCesaSramAddrGet()));
  21252. + pCesaDesc->cryptoIvBufOffset = MV_16BIT_LE(sramBufOffset + ivOffset);
  21253. + }
  21254. +
  21255. + if( (config & MV_CESA_OPERATION_MASK) !=
  21256. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  21257. + {
  21258. + /* word 5 */
  21259. + pCesaDesc->macSrcOffset = MV_16BIT_LE(sramBufOffset + macOffset);
  21260. + pCesaDesc->macTotalLen = MV_16BIT_LE(macTotalLen);
  21261. +
  21262. + /* word 6 */
  21263. + pCesaDesc->macDigestOffset = MV_16BIT_LE(sramBufOffset + digestOffset);
  21264. + pCesaDesc->macDataLen = MV_16BIT_LE(macLength);
  21265. +
  21266. + /* word 7 */
  21267. + pCesaDesc->macInnerIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macInnerIV -
  21268. + mvCesaSramAddrGet()));
  21269. + pCesaDesc->macOuterIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macOuterIV -
  21270. + mvCesaSramAddrGet()));
  21271. + }
  21272. + /* Prepare DMA descriptor to CESA descriptor from DRAM to SRAM */
  21273. + pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&pReq->cesaDescBuf, pCesaDesc));
  21274. + pDmaDesc->phyDestAdd = MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)pSramDesc));
  21275. + pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_DESC) | BIT31);
  21276. +
  21277. + /* flush Source buffer */
  21278. + mvOsCacheFlush(NULL, pCesaDesc, sizeof(MV_CESA_DESC));
  21279. +}
  21280. +
  21281. +/*******************************************************************************
  21282. +* mvCesaSramSaUpdate - Move required SA information to SRAM if needed.
  21283. +*
  21284. +* DESCRIPTION:
  21285. +* Copy to SRAM values of the required SA.
  21286. +*
  21287. +*
  21288. +* INPUT:
  21289. +* short sid - Session ID needs SRAM Cache update
  21290. +* MV_DMA_DESC *pDmaDesc - Pointer to DMA descriptor used to
  21291. +* copy SA values from DRAM to SRAM.
  21292. +*
  21293. +* RETURN:
  21294. +* MV_OK - Cache entry for this SA copied to SRAM.
  21295. +* MV_NO_CHANGE - Cache entry for this SA already exist in SRAM
  21296. +*
  21297. +*******************************************************************************/
  21298. +static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc)
  21299. +{
  21300. + MV_CESA_SA *pSA = &pCesaSAD[sid];
  21301. +
  21302. + /* Prepare DMA descriptor to Copy CACHE_SA from SA database in DRAM to SRAM */
  21303. + pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_SRAM_SA) | BIT31);
  21304. + pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&cesaSramSaBuf, pSA->pSramSA));
  21305. + pDmaDesc->phyDestAdd =
  21306. + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)&cesaSramVirtPtr->sramSA));
  21307. +
  21308. + /* Source buffer is already flushed during OpenSession*/
  21309. + /*mvOsCacheFlush(NULL, &pSA->sramSA, sizeof(MV_CESA_SRAM_SA));*/
  21310. +}
  21311. +
  21312. +/*******************************************************************************
  21313. +* mvCesaDmaCopyPrepare - prepare DMA descriptor list to copy data presented by
  21314. +* Mbuf structure from DRAM to SRAM
  21315. +*
  21316. +* DESCRIPTION:
  21317. +*
  21318. +*
  21319. +* INPUT:
  21320. +* MV_CESA_MBUF* pMbuf - pointer to Mbuf structure contains request
  21321. +* data in DRAM
  21322. +* MV_U8* pSramBuf - pointer to buffer in SRAM where data should
  21323. +* be copied to.
  21324. +* MV_DMA_DESC* pDmaDesc - pointer to first DMA descriptor for this copy.
  21325. +* The function set number of DMA descriptors needed
  21326. +* to copy the copySize bytes from Mbuf.
  21327. +* MV_BOOL isToMbuf - Copy direction.
  21328. +* MV_TRUE means copy from SRAM buffer to Mbuf in DRAM.
  21329. +* MV_FALSE means copy from Mbuf in DRAM to SRAM buffer.
  21330. +* int offset - Offset in the Mbuf structure that copy should be
  21331. +* started from.
  21332. +* int copySize - Size of data should be copied.
  21333. +*
  21334. +* RETURN:
  21335. +* int - number of DMA descriptors used for the copy.
  21336. +*
  21337. +*******************************************************************************/
  21338. +#ifndef MV_NETBSD
  21339. +static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
  21340. + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
  21341. + int offset, int copySize, MV_BOOL skipFlush)
  21342. +{
  21343. + int bufOffset, bufSize, size, frag, i;
  21344. + MV_U8* pBuf;
  21345. +
  21346. + i = 0;
  21347. +
  21348. + /* Calculate start place for copy: fragment number and offset in the fragment */
  21349. + frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);
  21350. + bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;
  21351. + pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;
  21352. +
  21353. + /* Size accumulate total copy size */
  21354. + size = 0;
  21355. +
  21356. + /* Create DMA lists to copy mBuf from pSrc to SRAM */
  21357. + while(size < copySize)
  21358. + {
  21359. + /* Find copy size for each DMA descriptor */
  21360. + bufSize = MV_MIN(bufSize, (copySize - size));
  21361. + pDmaDesc[i].byteCnt = MV_32BIT_LE(bufSize | BIT31);
  21362. + if(isToMbuf)
  21363. + {
  21364. + pDmaDesc[i].phyDestAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
  21365. + pDmaDesc[i].phySrcAdd =
  21366. + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));
  21367. + /* invalidate the buffer */
  21368. + if(skipFlush == MV_FALSE)
  21369. + mvOsCacheInvalidate(NULL, pBuf, bufSize);
  21370. + }
  21371. + else
  21372. + {
  21373. + pDmaDesc[i].phySrcAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
  21374. + pDmaDesc[i].phyDestAdd =
  21375. + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));
  21376. + /* flush the buffer */
  21377. + if(skipFlush == MV_FALSE)
  21378. + mvOsCacheFlush(NULL, pBuf, bufSize);
  21379. + }
  21380. +
  21381. + /* Count number of used DMA descriptors */
  21382. + i++;
  21383. + size += bufSize;
  21384. +
  21385. + /* go to next fragment in the Mbuf */
  21386. + frag++;
  21387. + pBuf = pMbuf->pFrags[frag].bufVirtPtr;
  21388. + bufSize = pMbuf->pFrags[frag].bufSize;
  21389. + }
  21390. + return i;
  21391. +}
  21392. +#else /* MV_NETBSD */
  21393. +static int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
  21394. + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
  21395. + int offset, int copySize, MV_BOOL skipFlush)
  21396. +{
  21397. + int bufOffset, bufSize, thisSize, size, frag, i;
  21398. + MV_ULONG bufPhys, sramPhys;
  21399. + MV_U8* pBuf;
  21400. +
  21401. + /*
  21402. + * Calculate start place for copy: fragment number and offset in
  21403. + * the fragment
  21404. + */
  21405. + frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);
  21406. +
  21407. + /*
  21408. + * Get SRAM physical address only once. We can update it in-place
  21409. + * as we build the descriptor chain.
  21410. + */
  21411. + sramPhys = mvCesaSramVirtToPhys(NULL, pSramBuf);
  21412. +
  21413. + /*
  21414. + * 'size' accumulates total copy size, 'i' counts desccriptors.
  21415. + */
  21416. + size = i = 0;
  21417. +
  21418. + /* Create DMA lists to copy mBuf from pSrc to SRAM */
  21419. + while (size < copySize) {
  21420. + /*
  21421. + * Calculate # of bytes to copy from the current fragment,
  21422. + * and the pointer to the start of data
  21423. + */
  21424. + bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;
  21425. + pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;
  21426. + bufOffset = 0; /* First frag may be non-zero */
  21427. + frag++;
  21428. +
  21429. + /*
  21430. + * As long as there is data in the current fragment...
  21431. + */
  21432. + while (bufSize > 0) {
  21433. + /*
  21434. + * Ensure we don't cross an MMU page boundary.
  21435. + * XXX: This is NetBSD-specific, but it is a
  21436. + * quick and dirty way to fix the problem.
  21437. + * A true HAL would rely on the OS-specific
  21438. + * driver to do this...
  21439. + */
  21440. + thisSize = PAGE_SIZE -
  21441. + (((MV_ULONG)pBuf) & (PAGE_SIZE - 1));
  21442. + thisSize = MV_MIN(bufSize, thisSize);
  21443. + /*
  21444. + * Make sure we don't copy more than requested
  21445. + */
  21446. + if (thisSize > (copySize - size)) {
  21447. + thisSize = copySize - size;
  21448. + bufSize = 0;
  21449. + }
  21450. +
  21451. + /*
  21452. + * Physicall address of this fragment
  21453. + */
  21454. + bufPhys = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
  21455. +
  21456. + /*
  21457. + * Set up the descriptor
  21458. + */
  21459. + pDmaDesc[i].byteCnt = MV_32BIT_LE(thisSize | BIT31);
  21460. + if(isToMbuf) {
  21461. + pDmaDesc[i].phyDestAdd = bufPhys;
  21462. + pDmaDesc[i].phySrcAdd = MV_32BIT_LE(sramPhys);
  21463. + /* invalidate the buffer */
  21464. + if(skipFlush == MV_FALSE)
  21465. + mvOsCacheInvalidate(NULL, pBuf, thisSize);
  21466. + } else {
  21467. + pDmaDesc[i].phySrcAdd = bufPhys;
  21468. + pDmaDesc[i].phyDestAdd = MV_32BIT_LE(sramPhys);
  21469. + /* flush the buffer */
  21470. + if(skipFlush == MV_FALSE)
  21471. + mvOsCacheFlush(NULL, pBuf, thisSize);
  21472. + }
  21473. +
  21474. + pDmaDesc[i].phyNextDescPtr =
  21475. + MV_32BIT_LE(mvOsIoVirtToPhy(NULL,(&pDmaDesc[i+1])));
  21476. +
  21477. + /* flush the DMA desc */
  21478. + mvOsCacheFlush(NULL, &pDmaDesc[i], sizeof(MV_DMA_DESC));
  21479. +
  21480. + /* Update state */
  21481. + bufSize -= thisSize;
  21482. + sramPhys += thisSize;
  21483. + pBuf += thisSize;
  21484. + size += thisSize;
  21485. + i++;
  21486. + }
  21487. + }
  21488. +
  21489. + return i;
  21490. +}
  21491. +#endif /* MV_NETBSD */
  21492. +/*******************************************************************************
  21493. +* mvCesaHmacIvGet - Calculate Inner and Outter values from HMAC key
  21494. +*
  21495. +* DESCRIPTION:
  21496. +* This function calculate Inner and Outer values used for HMAC algorithm.
  21497. +* This operation allows improve performance fro the whole HMAC processing.
  21498. +*
  21499. +* INPUT:
  21500. +* MV_CESA_MAC_MODE macMode - Authentication mode: HMAC_MD5 or HMAC_SHA1.
  21501. +* unsigned char key[] - Pointer to HMAC key.
  21502. +* int keyLength - Size of HMAC key (maximum 64 bytes)
  21503. +*
  21504. +* OUTPUT:
  21505. +* unsigned char innerIV[] - HASH(key^inner)
  21506. +* unsigned char outerIV[] - HASH(key^outter)
  21507. +*
  21508. +* RETURN: None
  21509. +*
  21510. +*******************************************************************************/
  21511. +static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,
  21512. + unsigned char innerIV[], unsigned char outerIV[])
  21513. +{
  21514. + unsigned char inner[MV_CESA_MAX_MAC_KEY_LENGTH];
  21515. + unsigned char outer[MV_CESA_MAX_MAC_KEY_LENGTH];
  21516. + int i, digestSize = 0;
  21517. +#if defined(MV_CPU_LE) || defined(MV_PPC)
  21518. + MV_U32 swapped32, val32, *pVal32;
  21519. +#endif
  21520. + for(i=0; i<keyLength; i++)
  21521. + {
  21522. + inner[i] = 0x36 ^ key[i];
  21523. + outer[i] = 0x5c ^ key[i];
  21524. + }
  21525. +
  21526. + for(i=keyLength; i<MV_CESA_MAX_MAC_KEY_LENGTH; i++)
  21527. + {
  21528. + inner[i] = 0x36;
  21529. + outer[i] = 0x5c;
  21530. + }
  21531. + if(macMode == MV_CESA_MAC_HMAC_MD5)
  21532. + {
  21533. + MV_MD5_CONTEXT ctx;
  21534. +
  21535. + mvMD5Init(&ctx);
  21536. + mvMD5Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);
  21537. +
  21538. + memcpy(innerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);
  21539. + memset(&ctx, 0, sizeof(ctx));
  21540. +
  21541. + mvMD5Init(&ctx);
  21542. + mvMD5Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);
  21543. + memcpy(outerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);
  21544. + memset(&ctx, 0, sizeof(ctx));
  21545. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  21546. + }
  21547. + else if(macMode == MV_CESA_MAC_HMAC_SHA1)
  21548. + {
  21549. + MV_SHA1_CTX ctx;
  21550. +
  21551. + mvSHA1Init(&ctx);
  21552. + mvSHA1Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);
  21553. + memcpy(innerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);
  21554. + memset(&ctx, 0, sizeof(ctx));
  21555. +
  21556. + mvSHA1Init(&ctx);
  21557. + mvSHA1Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);
  21558. + memcpy(outerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);
  21559. + memset(&ctx, 0, sizeof(ctx));
  21560. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  21561. + }
  21562. + else
  21563. + {
  21564. + mvOsPrintf("hmacGetIV: Unexpected macMode %d\n", macMode);
  21565. + }
  21566. +#if defined(MV_CPU_LE) || defined(MV_PPC)
  21567. + /* 32 bits Swap of Inner and Outer values */
  21568. + pVal32 = (MV_U32*)innerIV;
  21569. + for(i=0; i<digestSize/4; i++)
  21570. + {
  21571. + val32 = *pVal32;
  21572. + swapped32 = MV_BYTE_SWAP_32BIT(val32);
  21573. + *pVal32 = swapped32;
  21574. + pVal32++;
  21575. + }
  21576. + pVal32 = (MV_U32*)outerIV;
  21577. + for(i=0; i<digestSize/4; i++)
  21578. + {
  21579. + val32 = *pVal32;
  21580. + swapped32 = MV_BYTE_SWAP_32BIT(val32);
  21581. + *pVal32 = swapped32;
  21582. + pVal32++;
  21583. + }
  21584. +#endif /* defined(MV_CPU_LE) || defined(MV_PPC) */
  21585. +}
  21586. +
  21587. +
  21588. +/*******************************************************************************
  21589. +* mvCesaFragSha1Complete - Complete SHA1 authentication started by HW using SW
  21590. +*
  21591. +* DESCRIPTION:
  21592. +*
  21593. +*
  21594. +* INPUT:
  21595. +* MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
  21596. +* for SHA1 is placed.
  21597. +* int offset - Offset in the Mbuf structure where
  21598. +* unprocessed data for SHA1 is started.
  21599. +* MV_U8* pOuterIV - Pointer to OUTER for this session.
  21600. +* If pOuterIV==NULL - MAC mode is HASH_SHA1
  21601. +* If pOuterIV!=NULL - MAC mode is HMAC_SHA1
  21602. +* int macLeftSize - Size of unprocessed data for SHA1.
  21603. +* int macTotalSize - Total size of data for SHA1 in the
  21604. +* request (processed + unprocessed)
  21605. +*
  21606. +* OUTPUT:
  21607. +* MV_U8* pDigest - Pointer to place where calculated Digest will
  21608. +* be stored.
  21609. +*
  21610. +* RETURN: None
  21611. +*
  21612. +*******************************************************************************/
  21613. +static void mvCesaFragSha1Complete(MV_CESA_MBUF* pMbuf, int offset,
  21614. + MV_U8* pOuterIV, int macLeftSize,
  21615. + int macTotalSize, MV_U8* pDigest)
  21616. +{
  21617. + MV_SHA1_CTX ctx;
  21618. + MV_U8 *pData;
  21619. + int i, frag, fragOffset, size;
  21620. +
  21621. + /* Read temporary Digest from HW */
  21622. + for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)
  21623. + {
  21624. + ctx.state[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));
  21625. + }
  21626. + /* Initialize MV_SHA1_CTX structure */
  21627. + memset(ctx.buffer, 0, 64);
  21628. + /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
  21629. + /* so count[1] is always 0 */
  21630. + ctx.count[0] = ((macTotalSize - macLeftSize) * 8);
  21631. + ctx.count[1] = 0;
  21632. +
  21633. + /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
  21634. + if(pOuterIV != NULL)
  21635. + ctx.count[0] += (64 * 8);
  21636. +
  21637. + /* Get place of unprocessed data in the Mbuf structure */
  21638. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  21639. + if(frag == MV_INVALID)
  21640. + {
  21641. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  21642. + return;
  21643. + }
  21644. +
  21645. + pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  21646. + size = pMbuf->pFrags[frag].bufSize - fragOffset;
  21647. +
  21648. + /* Complete Inner part */
  21649. + while(macLeftSize > 0)
  21650. + {
  21651. + if(macLeftSize <= size)
  21652. + {
  21653. + mvSHA1Update(&ctx, pData, macLeftSize);
  21654. + break;
  21655. + }
  21656. + mvSHA1Update(&ctx, pData, size);
  21657. + macLeftSize -= size;
  21658. + frag++;
  21659. + pData = pMbuf->pFrags[frag].bufVirtPtr;
  21660. + size = pMbuf->pFrags[frag].bufSize;
  21661. + }
  21662. + mvSHA1Final(pDigest, &ctx);
  21663. +/*
  21664. + mvOsPrintf("mvCesaFragSha1Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
  21665. + pOuterIV, macLeftSize, macTotalSize);
  21666. + mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);
  21667. +*/
  21668. +
  21669. + if(pOuterIV != NULL)
  21670. + {
  21671. + /* If HMAC - Complete Outer part */
  21672. + for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)
  21673. + {
  21674. +#if defined(MV_CPU_LE) || defined(MV_ARM)
  21675. + ctx.state[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);
  21676. +#else
  21677. + ctx.state[i] = ((MV_U32*)pOuterIV)[i];
  21678. +#endif
  21679. + }
  21680. + memset(ctx.buffer, 0, 64);
  21681. +
  21682. + ctx.count[0] = 64*8;
  21683. + ctx.count[1] = 0;
  21684. + mvSHA1Update(&ctx, pDigest, MV_CESA_SHA1_DIGEST_SIZE);
  21685. + mvSHA1Final(pDigest, &ctx);
  21686. + }
  21687. +}
  21688. +
  21689. +/*******************************************************************************
  21690. +* mvCesaFragMd5Complete - Complete MD5 authentication started by HW using SW
  21691. +*
  21692. +* DESCRIPTION:
  21693. +*
  21694. +*
  21695. +* INPUT:
  21696. +* MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
  21697. +* for SHA1 is placed.
  21698. +* int offset - Offset in the Mbuf structure where
  21699. +* unprocessed data for MD5 is started.
  21700. +* MV_U8* pOuterIV - Pointer to OUTER for this session.
  21701. +* If pOuterIV==NULL - MAC mode is HASH_MD5
  21702. +* If pOuterIV!=NULL - MAC mode is HMAC_MD5
  21703. +* int macLeftSize - Size of unprocessed data for MD5.
  21704. +* int macTotalSize - Total size of data for MD5 in the
  21705. +* request (processed + unprocessed)
  21706. +*
  21707. +* OUTPUT:
  21708. +* MV_U8* pDigest - Pointer to place where calculated Digest will
  21709. +* be stored.
  21710. +*
  21711. +* RETURN: None
  21712. +*
  21713. +*******************************************************************************/
  21714. +static void mvCesaFragMd5Complete(MV_CESA_MBUF* pMbuf, int offset,
  21715. + MV_U8* pOuterIV, int macLeftSize,
  21716. + int macTotalSize, MV_U8* pDigest)
  21717. +{
  21718. + MV_MD5_CONTEXT ctx;
  21719. + MV_U8 *pData;
  21720. + int i, frag, fragOffset, size;
  21721. +
  21722. + /* Read temporary Digest from HW */
  21723. + for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)
  21724. + {
  21725. + ctx.buf[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));
  21726. + }
  21727. + memset(ctx.in, 0, 64);
  21728. +
  21729. + /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
  21730. + /* so count[1] is always 0 */
  21731. + ctx.bits[0] = ((macTotalSize - macLeftSize) * 8);
  21732. + ctx.bits[1] = 0;
  21733. +
  21734. + /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
  21735. + if(pOuterIV != NULL)
  21736. + ctx.bits[0] += (64 * 8);
  21737. +
  21738. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  21739. + if(frag == MV_INVALID)
  21740. + {
  21741. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  21742. + return;
  21743. + }
  21744. +
  21745. + pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  21746. + size = pMbuf->pFrags[frag].bufSize - fragOffset;
  21747. +
  21748. + /* Complete Inner part */
  21749. + while(macLeftSize > 0)
  21750. + {
  21751. + if(macLeftSize <= size)
  21752. + {
  21753. + mvMD5Update(&ctx, pData, macLeftSize);
  21754. + break;
  21755. + }
  21756. + mvMD5Update(&ctx, pData, size);
  21757. + macLeftSize -= size;
  21758. + frag++;
  21759. + pData = pMbuf->pFrags[frag].bufVirtPtr;
  21760. + size = pMbuf->pFrags[frag].bufSize;
  21761. + }
  21762. + mvMD5Final(pDigest, &ctx);
  21763. +
  21764. +/*
  21765. + mvOsPrintf("mvCesaFragMd5Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
  21766. + pOuterIV, macLeftSize, macTotalSize);
  21767. + mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);
  21768. +*/
  21769. + if(pOuterIV != NULL)
  21770. + {
  21771. + /* Complete Outer part */
  21772. + for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)
  21773. + {
  21774. +#if defined(MV_CPU_LE) || defined(MV_ARM)
  21775. + ctx.buf[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);
  21776. +#else
  21777. + ctx.buf[i] = ((MV_U32*)pOuterIV)[i];
  21778. +#endif
  21779. + }
  21780. + memset(ctx.in, 0, 64);
  21781. +
  21782. + ctx.bits[0] = 64*8;
  21783. + ctx.bits[1] = 0;
  21784. + mvMD5Update(&ctx, pDigest, MV_CESA_MD5_DIGEST_SIZE);
  21785. + mvMD5Final(pDigest, &ctx);
  21786. + }
  21787. +}
  21788. +
  21789. +/*******************************************************************************
  21790. +* mvCesaFragAuthComplete -
  21791. +*
  21792. +* DESCRIPTION:
  21793. +*
  21794. +*
  21795. +* INPUT:
  21796. +* MV_CESA_REQ* pReq,
  21797. +* MV_CESA_SA* pSA,
  21798. +* int macDataSize
  21799. +*
  21800. +* RETURN:
  21801. +* MV_STATUS
  21802. +*
  21803. +*******************************************************************************/
  21804. +static MV_STATUS mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,
  21805. + int macDataSize)
  21806. +{
  21807. + MV_CESA_COMMAND* pCmd = pReq->pCmd;
  21808. + MV_U8* pDigest;
  21809. + MV_CESA_MAC_MODE macMode;
  21810. + MV_U8* pOuterIV = NULL;
  21811. +
  21812. + /* Copy data from Source fragment to Destination */
  21813. + if(pCmd->pSrc != pCmd->pDst)
  21814. + {
  21815. + mvCesaMbufCopy(pCmd->pDst, pReq->frags.bufOffset,
  21816. + pCmd->pSrc, pReq->frags.bufOffset, macDataSize);
  21817. + }
  21818. +
  21819. +/*
  21820. + mvCesaCopyFromMbuf(cesaSramVirtPtr->buf[0], pCmd->pSrc, pReq->frags.bufOffset, macDataSize);
  21821. + mvCesaCopyToMbuf(cesaSramVirtPtr->buf[0], pCmd->pDst, pReq->frags.bufOffset, macDataSize);
  21822. +*/
  21823. + pDigest = (mvCesaSramAddrGet() + pReq->frags.newDigestOffset);
  21824. +
  21825. + macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;
  21826. +/*
  21827. + mvOsPrintf("macDataSize=%d, macLength=%d, digestOffset=%d, macMode=%d\n",
  21828. + macDataSize, pCmd->macLength, pCmd->digestOffset, macMode);
  21829. +*/
  21830. + switch(macMode)
  21831. + {
  21832. + case MV_CESA_MAC_HMAC_MD5:
  21833. + pOuterIV = pSA->pSramSA->macOuterIV;
  21834. +
  21835. + case MV_CESA_MAC_MD5:
  21836. + mvCesaFragMd5Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,
  21837. + macDataSize, pCmd->macLength, pDigest);
  21838. + break;
  21839. +
  21840. + case MV_CESA_MAC_HMAC_SHA1:
  21841. + pOuterIV = pSA->pSramSA->macOuterIV;
  21842. +
  21843. + case MV_CESA_MAC_SHA1:
  21844. + mvCesaFragSha1Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,
  21845. + macDataSize, pCmd->macLength, pDigest);
  21846. + break;
  21847. +
  21848. + default:
  21849. + mvOsPrintf("mvCesaFragAuthComplete: Unexpected macMode %d\n", macMode);
  21850. + return MV_BAD_PARAM;
  21851. + }
  21852. + return MV_OK;
  21853. +}
  21854. +
  21855. +/*******************************************************************************
  21856. +* mvCesaCtrModeInit -
  21857. +*
  21858. +* DESCRIPTION:
  21859. +*
  21860. +*
  21861. +* INPUT: NONE
  21862. +*
  21863. +*
  21864. +* RETURN:
  21865. +* MV_CESA_COMMAND*
  21866. +*
  21867. +*******************************************************************************/
  21868. +static MV_CESA_COMMAND* mvCesaCtrModeInit(void)
  21869. +{
  21870. + MV_CESA_MBUF *pMbuf;
  21871. + MV_U8 *pBuf;
  21872. + MV_CESA_COMMAND *pCmd;
  21873. +
  21874. + pBuf = mvOsMalloc(sizeof(MV_CESA_COMMAND) +
  21875. + sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) + 100);
  21876. + if(pBuf == NULL)
  21877. + {
  21878. + mvOsPrintf("mvCesaSessionOpen: Can't allocate %u bytes for CTR Mode\n",
  21879. + sizeof(MV_CESA_COMMAND) + sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) );
  21880. + return NULL;
  21881. + }
  21882. + pCmd = (MV_CESA_COMMAND*)pBuf;
  21883. + pBuf += sizeof(MV_CESA_COMMAND);
  21884. +
  21885. + pMbuf = (MV_CESA_MBUF*)pBuf;
  21886. + pBuf += sizeof(MV_CESA_MBUF);
  21887. +
  21888. + pMbuf->pFrags = (MV_BUF_INFO*)pBuf;
  21889. +
  21890. + pMbuf->numFrags = 1;
  21891. + pCmd->pSrc = pMbuf;
  21892. + pCmd->pDst = pMbuf;
  21893. +/*
  21894. + mvOsPrintf("CtrModeInit: pCmd=%p, pSrc=%p, pDst=%p, pFrags=%p\n",
  21895. + pCmd, pCmd->pSrc, pCmd->pDst,
  21896. + pMbuf->pFrags);
  21897. +*/
  21898. + return pCmd;
  21899. +}
  21900. +
  21901. +/*******************************************************************************
  21902. +* mvCesaCtrModePrepare -
  21903. +*
  21904. +* DESCRIPTION:
  21905. +*
  21906. +*
  21907. +* INPUT:
  21908. +* MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd
  21909. +*
  21910. +* RETURN:
  21911. +* MV_STATUS
  21912. +*
  21913. +*******************************************************************************/
  21914. +static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd)
  21915. +{
  21916. + MV_CESA_MBUF *pMbuf;
  21917. + MV_U8 *pBuf, *pIV;
  21918. + MV_U32 counter, *pCounter;
  21919. + int cryptoSize = MV_ALIGN_UP(pCmd->cryptoLength, MV_CESA_AES_BLOCK_SIZE);
  21920. +/*
  21921. + mvOsPrintf("CtrModePrepare: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
  21922. + pCmd, pCmd->pSrc, pCmd->pDst,
  21923. + pCtrModeCmd, pCtrModeCmd->pSrc, pCtrModeCmd->pDst);
  21924. +*/
  21925. + pMbuf = pCtrModeCmd->pSrc;
  21926. +
  21927. + /* Allocate buffer for Key stream */
  21928. + pBuf = mvOsIoCachedMalloc(cesaOsHandle,cryptoSize,
  21929. + &pMbuf->pFrags[0].bufPhysAddr,
  21930. + &pMbuf->pFrags[0].memHandle);
  21931. + if(pBuf == NULL)
  21932. + {
  21933. + mvOsPrintf("mvCesaCtrModePrepare: Can't allocate %d bytes\n", cryptoSize);
  21934. + return MV_OUT_OF_CPU_MEM;
  21935. + }
  21936. + memset(pBuf, 0, cryptoSize);
  21937. + mvOsCacheFlush(NULL, pBuf, cryptoSize);
  21938. +
  21939. + pMbuf->pFrags[0].bufVirtPtr = pBuf;
  21940. + pMbuf->mbufSize = cryptoSize;
  21941. + pMbuf->pFrags[0].bufSize = cryptoSize;
  21942. +
  21943. + pCtrModeCmd->pReqPrv = pCmd->pReqPrv;
  21944. + pCtrModeCmd->sessionId = pCmd->sessionId;
  21945. +
  21946. + /* ivFromUser and ivOffset are don't care */
  21947. + pCtrModeCmd->cryptoOffset = 0;
  21948. + pCtrModeCmd->cryptoLength = cryptoSize;
  21949. +
  21950. + /* digestOffset, macOffset and macLength are don't care */
  21951. +
  21952. + mvCesaCopyFromMbuf(pBuf, pCmd->pSrc, pCmd->ivOffset, MV_CESA_AES_BLOCK_SIZE);
  21953. + pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));
  21954. + counter = *pCounter;
  21955. + counter = MV_32BIT_BE(counter);
  21956. + pIV = pBuf;
  21957. + cryptoSize -= MV_CESA_AES_BLOCK_SIZE;
  21958. +
  21959. + /* fill key stream */
  21960. + while(cryptoSize > 0)
  21961. + {
  21962. + pBuf += MV_CESA_AES_BLOCK_SIZE;
  21963. + memcpy(pBuf, pIV, MV_CESA_AES_BLOCK_SIZE - sizeof(counter));
  21964. + pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));
  21965. + counter++;
  21966. + *pCounter = MV_32BIT_BE(counter);
  21967. + cryptoSize -= MV_CESA_AES_BLOCK_SIZE;
  21968. + }
  21969. +
  21970. + return MV_OK;
  21971. +}
  21972. +
  21973. +/*******************************************************************************
  21974. +* mvCesaCtrModeComplete -
  21975. +*
  21976. +* DESCRIPTION:
  21977. +*
  21978. +*
  21979. +* INPUT:
  21980. +* MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd
  21981. +*
  21982. +* RETURN:
  21983. +* MV_STATUS
  21984. +*
  21985. +*******************************************************************************/
  21986. +static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd)
  21987. +{
  21988. + int srcFrag, dstFrag, srcOffset, dstOffset, keyOffset, srcSize, dstSize;
  21989. + int cryptoSize = pCmd->cryptoLength;
  21990. + MV_U8 *pSrc, *pDst, *pKey;
  21991. + MV_STATUS status = MV_OK;
  21992. +/*
  21993. + mvOsPrintf("CtrModeComplete: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
  21994. + pCmd, pCmd->pSrc, pCmd->pDst,
  21995. + pOrgCmd, pOrgCmd->pSrc, pOrgCmd->pDst);
  21996. +*/
  21997. + /* XOR source data with key stream to destination data */
  21998. + pKey = pCmd->pDst->pFrags[0].bufVirtPtr;
  21999. + keyOffset = 0;
  22000. +
  22001. + if( (pOrgCmd->pSrc != pOrgCmd->pDst) &&
  22002. + (pOrgCmd->cryptoOffset > 0) )
  22003. + {
  22004. + /* Copy Prefix from source buffer to destination buffer */
  22005. +
  22006. + status = mvCesaMbufCopy(pOrgCmd->pDst, 0,
  22007. + pOrgCmd->pSrc, 0, pOrgCmd->cryptoOffset);
  22008. +/*
  22009. + status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
  22010. + 0, pOrgCmd->cryptoOffset);
  22011. + status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
  22012. + 0, pOrgCmd->cryptoOffset);
  22013. +*/
  22014. + }
  22015. +
  22016. + srcFrag = mvCesaMbufOffset(pOrgCmd->pSrc, pOrgCmd->cryptoOffset, &srcOffset);
  22017. + pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;
  22018. + srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;
  22019. +
  22020. + dstFrag = mvCesaMbufOffset(pOrgCmd->pDst, pOrgCmd->cryptoOffset, &dstOffset);
  22021. + pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;
  22022. + dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;
  22023. +
  22024. + while(cryptoSize > 0)
  22025. + {
  22026. + pDst[dstOffset] = (pSrc[srcOffset] ^ pKey[keyOffset]);
  22027. +
  22028. + cryptoSize--;
  22029. + dstOffset++;
  22030. + srcOffset++;
  22031. + keyOffset++;
  22032. +
  22033. + if(srcOffset >= srcSize)
  22034. + {
  22035. + srcFrag++;
  22036. + srcOffset = 0;
  22037. + pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;
  22038. + srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;
  22039. + }
  22040. +
  22041. + if(dstOffset >= dstSize)
  22042. + {
  22043. + dstFrag++;
  22044. + dstOffset = 0;
  22045. + pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;
  22046. + dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;
  22047. + }
  22048. + }
  22049. +
  22050. + if(pOrgCmd->pSrc != pOrgCmd->pDst)
  22051. + {
  22052. + /* Copy Suffix from source buffer to destination buffer */
  22053. + srcOffset = pOrgCmd->cryptoOffset + pOrgCmd->cryptoLength;
  22054. +
  22055. + if( (pOrgCmd->pDst->mbufSize - srcOffset) > 0)
  22056. + {
  22057. + status = mvCesaMbufCopy(pOrgCmd->pDst, srcOffset,
  22058. + pOrgCmd->pSrc, srcOffset,
  22059. + pOrgCmd->pDst->mbufSize - srcOffset);
  22060. + }
  22061. +
  22062. +/*
  22063. + status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
  22064. + srcOffset, pOrgCmd->pSrc->mbufSize - srcOffset);
  22065. + status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
  22066. + srcOffset, pOrgCmd->pDst->mbufSize - srcOffset);
  22067. +*/
  22068. + }
  22069. +
  22070. + /* Free buffer used for Key stream */
  22071. + mvOsIoCachedFree(cesaOsHandle,pCmd->pDst->pFrags[0].bufSize,
  22072. + pCmd->pDst->pFrags[0].bufPhysAddr,
  22073. + pCmd->pDst->pFrags[0].bufVirtPtr,
  22074. + pCmd->pDst->pFrags[0].memHandle);
  22075. +
  22076. + return MV_OK;
  22077. +}
  22078. +
  22079. +/*******************************************************************************
  22080. +* mvCesaCtrModeFinish -
  22081. +*
  22082. +* DESCRIPTION:
  22083. +*
  22084. +*
  22085. +* INPUT:
  22086. +* MV_CESA_COMMAND* pCmd
  22087. +*
  22088. +* RETURN:
  22089. +* MV_STATUS
  22090. +*
  22091. +*******************************************************************************/
  22092. +static void mvCesaCtrModeFinish(MV_CESA_COMMAND* pCmd)
  22093. +{
  22094. + mvOsFree(pCmd);
  22095. +}
  22096. +
  22097. +/*******************************************************************************
  22098. +* mvCesaParamCheck -
  22099. +*
  22100. +* DESCRIPTION:
  22101. +*
  22102. +*
  22103. +* INPUT:
  22104. +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset
  22105. +*
  22106. +* RETURN:
  22107. +* MV_STATUS
  22108. +*
  22109. +*******************************************************************************/
  22110. +static MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,
  22111. + MV_U8* pFixOffset)
  22112. +{
  22113. + MV_U8 fixOffset = 0xFF;
  22114. +
  22115. + /* Check AUTH operation parameters */
  22116. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  22117. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )
  22118. + {
  22119. + /* MAC offset should be at least 4 byte aligned */
  22120. + if( MV_IS_NOT_ALIGN(pCmd->macOffset, 4) )
  22121. + {
  22122. + mvOsPrintf("mvCesaAction: macOffset %d must be 4 byte aligned\n",
  22123. + pCmd->macOffset);
  22124. + return MV_BAD_PARAM;
  22125. + }
  22126. + /* Digest offset must be 4 byte aligned */
  22127. + if( MV_IS_NOT_ALIGN(pCmd->digestOffset, 4) )
  22128. + {
  22129. + mvOsPrintf("mvCesaAction: digestOffset %d must be 4 byte aligned\n",
  22130. + pCmd->digestOffset);
  22131. + return MV_BAD_PARAM;
  22132. + }
  22133. + /* In addition all offsets should be the same alignment: 8 or 4 */
  22134. + if(fixOffset == 0xFF)
  22135. + {
  22136. + fixOffset = (pCmd->macOffset % 8);
  22137. + }
  22138. + else
  22139. + {
  22140. + if( (pCmd->macOffset % 8) != fixOffset)
  22141. + {
  22142. + mvOsPrintf("mvCesaAction: macOffset %d mod 8 must be equal %d\n",
  22143. + pCmd->macOffset, fixOffset);
  22144. + return MV_BAD_PARAM;
  22145. + }
  22146. + }
  22147. + if( (pCmd->digestOffset % 8) != fixOffset)
  22148. + {
  22149. + mvOsPrintf("mvCesaAction: digestOffset %d mod 8 must be equal %d\n",
  22150. + pCmd->digestOffset, fixOffset);
  22151. + return MV_BAD_PARAM;
  22152. + }
  22153. + }
  22154. + /* Check CRYPTO operation parameters */
  22155. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  22156. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )
  22157. + {
  22158. + /* CryptoOffset should be at least 4 byte aligned */
  22159. + if( MV_IS_NOT_ALIGN(pCmd->cryptoOffset, 4) )
  22160. + {
  22161. + mvOsPrintf("CesaAction: cryptoOffset=%d must be 4 byte aligned\n",
  22162. + pCmd->cryptoOffset);
  22163. + return MV_BAD_PARAM;
  22164. + }
  22165. + /* cryptoLength should be the whole number of blocks */
  22166. + if( MV_IS_NOT_ALIGN(pCmd->cryptoLength, pSA->cryptoBlockSize) )
  22167. + {
  22168. + mvOsPrintf("mvCesaAction: cryptoLength=%d must be %d byte aligned\n",
  22169. + pCmd->cryptoLength, pSA->cryptoBlockSize);
  22170. + return MV_BAD_PARAM;
  22171. + }
  22172. + if(fixOffset == 0xFF)
  22173. + {
  22174. + fixOffset = (pCmd->cryptoOffset % 8);
  22175. + }
  22176. + else
  22177. + {
  22178. + /* In addition all offsets should be the same alignment: 8 or 4 */
  22179. + if( (pCmd->cryptoOffset % 8) != fixOffset)
  22180. + {
  22181. + mvOsPrintf("mvCesaAction: cryptoOffset %d mod 8 must be equal %d \n",
  22182. + pCmd->cryptoOffset, fixOffset);
  22183. + return MV_BAD_PARAM;
  22184. + }
  22185. + }
  22186. +
  22187. + /* check for CBC mode */
  22188. + if(pSA->cryptoIvSize > 0)
  22189. + {
  22190. + /* cryptoIV must not be part of CryptoLength */
  22191. + if( ((pCmd->ivOffset + pSA->cryptoIvSize) > pCmd->cryptoOffset) &&
  22192. + (pCmd->ivOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )
  22193. + {
  22194. + mvOsPrintf("mvCesaFragParamCheck: cryptoIvOffset (%d) is part of cryptoLength (%d+%d)\n",
  22195. + pCmd->ivOffset, pCmd->macOffset, pCmd->macLength);
  22196. + return MV_BAD_PARAM;
  22197. + }
  22198. +
  22199. + /* ivOffset must be 4 byte aligned */
  22200. + if( MV_IS_NOT_ALIGN(pCmd->ivOffset, 4) )
  22201. + {
  22202. + mvOsPrintf("CesaAction: ivOffset=%d must be 4 byte aligned\n",
  22203. + pCmd->ivOffset);
  22204. + return MV_BAD_PARAM;
  22205. + }
  22206. + /* In addition all offsets should be the same alignment: 8 or 4 */
  22207. + if( (pCmd->ivOffset % 8) != fixOffset)
  22208. + {
  22209. + mvOsPrintf("mvCesaAction: ivOffset %d mod 8 must be %d\n",
  22210. + pCmd->ivOffset, fixOffset);
  22211. + return MV_BAD_PARAM;
  22212. + }
  22213. + }
  22214. + }
  22215. + return MV_OK;
  22216. +}
  22217. +
  22218. +/*******************************************************************************
  22219. +* mvCesaFragParamCheck -
  22220. +*
  22221. +* DESCRIPTION:
  22222. +*
  22223. +*
  22224. +* INPUT:
  22225. +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd
  22226. +*
  22227. +* RETURN:
  22228. +* MV_STATUS
  22229. +*
  22230. +*******************************************************************************/
  22231. +static MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd)
  22232. +{
  22233. + int offset;
  22234. +
  22235. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  22236. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )
  22237. + {
  22238. + /* macOffset must be less that SRAM buffer size */
  22239. + if(pCmd->macOffset > (sizeof(cesaSramVirtPtr->buf) - MV_CESA_AUTH_BLOCK_SIZE))
  22240. + {
  22241. + mvOsPrintf("mvCesaFragParamCheck: macOffset is too large (%d)\n",
  22242. + pCmd->macOffset);
  22243. + return MV_BAD_PARAM;
  22244. + }
  22245. + /* macOffset+macSize must be more than mbufSize - SRAM buffer size */
  22246. + if( ((pCmd->macOffset + pCmd->macLength) > pCmd->pSrc->mbufSize) ||
  22247. + ((pCmd->pSrc->mbufSize - (pCmd->macOffset + pCmd->macLength)) >=
  22248. + sizeof(cesaSramVirtPtr->buf)) )
  22249. + {
  22250. + mvOsPrintf("mvCesaFragParamCheck: macLength is too large (%d), mbufSize=%d\n",
  22251. + pCmd->macLength, pCmd->pSrc->mbufSize);
  22252. + return MV_BAD_PARAM;
  22253. + }
  22254. + }
  22255. +
  22256. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  22257. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )
  22258. + {
  22259. + /* cryptoOffset must be less that SRAM buffer size */
  22260. + /* 4 for possible fixOffset */
  22261. + if( (pCmd->cryptoOffset + 4) > (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize))
  22262. + {
  22263. + mvOsPrintf("mvCesaFragParamCheck: cryptoOffset is too large (%d)\n",
  22264. + pCmd->cryptoOffset);
  22265. + return MV_BAD_PARAM;
  22266. + }
  22267. +
  22268. + /* cryptoOffset+cryptoSize must be more than mbufSize - SRAM buffer size */
  22269. + if( ((pCmd->cryptoOffset + pCmd->cryptoLength) > pCmd->pSrc->mbufSize) ||
  22270. + ((pCmd->pSrc->mbufSize - (pCmd->cryptoOffset + pCmd->cryptoLength)) >=
  22271. + (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize)) )
  22272. + {
  22273. + mvOsPrintf("mvCesaFragParamCheck: cryptoLength is too large (%d), mbufSize=%d\n",
  22274. + pCmd->cryptoLength, pCmd->pSrc->mbufSize);
  22275. + return MV_BAD_PARAM;
  22276. + }
  22277. + }
  22278. +
  22279. + /* When MAC_THEN_CRYPTO or CRYPTO_THEN_MAC */
  22280. + if( ((pSA->config & MV_CESA_OPERATION_MASK) ==
  22281. + (MV_CESA_MAC_THEN_CRYPTO << MV_CESA_OPERATION_OFFSET)) ||
  22282. + ((pSA->config & MV_CESA_OPERATION_MASK) ==
  22283. + (MV_CESA_CRYPTO_THEN_MAC << MV_CESA_OPERATION_OFFSET)) )
  22284. + {
  22285. + if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||
  22286. + ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&
  22287. + (mvCtrlRevGet() >= MV_5181L_A0_REV) &&
  22288. + (pCmd->macLength >= (1 << 14)) ) )
  22289. + {
  22290. + return MV_NOT_ALLOWED;
  22291. + }
  22292. +
  22293. + /* abs(cryptoOffset-macOffset) must be aligned cryptoBlockSize */
  22294. + if(pCmd->cryptoOffset > pCmd->macOffset)
  22295. + {
  22296. + offset = pCmd->cryptoOffset - pCmd->macOffset;
  22297. + }
  22298. + else
  22299. + {
  22300. + offset = pCmd->macOffset - pCmd->cryptoOffset;
  22301. + }
  22302. +
  22303. + if( MV_IS_NOT_ALIGN(offset, pSA->cryptoBlockSize) )
  22304. + {
  22305. +/*
  22306. + mvOsPrintf("mvCesaFragParamCheck: (cryptoOffset - macOffset) must be %d byte aligned\n",
  22307. + pSA->cryptoBlockSize);
  22308. +*/
  22309. + return MV_NOT_ALLOWED;
  22310. + }
  22311. + /* Digest must not be part of CryptoLength */
  22312. + if( ((pCmd->digestOffset + pSA->digestSize) > pCmd->cryptoOffset) &&
  22313. + (pCmd->digestOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )
  22314. + {
  22315. +/*
  22316. + mvOsPrintf("mvCesaFragParamCheck: digestOffset (%d) is part of cryptoLength (%d+%d)\n",
  22317. + pCmd->digestOffset, pCmd->cryptoOffset, pCmd->cryptoLength);
  22318. +*/
  22319. + return MV_NOT_ALLOWED;
  22320. + }
  22321. + }
  22322. + return MV_OK;
  22323. +}
  22324. +
  22325. +/*******************************************************************************
  22326. +* mvCesaFragSizeFind -
  22327. +*
  22328. +* DESCRIPTION:
  22329. +*
  22330. +*
  22331. +* INPUT:
  22332. +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,
  22333. +* int cryptoOffset, int macOffset,
  22334. +*
  22335. +* OUTPUT:
  22336. +* int* pCopySize, int* pCryptoDataSize, int* pMacDataSize
  22337. +*
  22338. +* RETURN:
  22339. +* MV_STATUS
  22340. +*
  22341. +*******************************************************************************/
  22342. +static void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq,
  22343. + int cryptoOffset, int macOffset,
  22344. + int* pCopySize, int* pCryptoDataSize, int* pMacDataSize)
  22345. +{
  22346. + MV_CESA_COMMAND *pCmd = pReq->pCmd;
  22347. + int cryptoDataSize, macDataSize, copySize;
  22348. +
  22349. + cryptoDataSize = macDataSize = 0;
  22350. + copySize = *pCopySize;
  22351. +
  22352. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  22353. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
  22354. + {
  22355. + cryptoDataSize = MV_MIN( (copySize - cryptoOffset),
  22356. + (pCmd->cryptoLength - (pReq->frags.cryptoSize + 1)) );
  22357. +
  22358. + /* cryptoSize for each fragment must be the whole number of blocksSize */
  22359. + if( MV_IS_NOT_ALIGN(cryptoDataSize, pSA->cryptoBlockSize) )
  22360. + {
  22361. + cryptoDataSize = MV_ALIGN_DOWN(cryptoDataSize, pSA->cryptoBlockSize);
  22362. + copySize = cryptoOffset + cryptoDataSize;
  22363. + }
  22364. + }
  22365. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  22366. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  22367. + {
  22368. + macDataSize = MV_MIN( (copySize - macOffset),
  22369. + (pCmd->macLength - (pReq->frags.macSize + 1)));
  22370. +
  22371. + /* macSize for each fragment (except last) must be the whole number of blocksSize */
  22372. + if( MV_IS_NOT_ALIGN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE) )
  22373. + {
  22374. + macDataSize = MV_ALIGN_DOWN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE);
  22375. + copySize = macOffset + macDataSize;
  22376. + }
  22377. + cryptoDataSize = copySize - cryptoOffset;
  22378. + }
  22379. + *pCopySize = copySize;
  22380. +
  22381. + if(pCryptoDataSize != NULL)
  22382. + *pCryptoDataSize = cryptoDataSize;
  22383. +
  22384. + if(pMacDataSize != NULL)
  22385. + *pMacDataSize = macDataSize;
  22386. +}
  22387. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaDebug.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaDebug.c
  22388. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaDebug.c 1970-01-01 01:00:00.000000000 +0100
  22389. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaDebug.c 2010-11-09 20:28:05.342495385 +0100
  22390. @@ -0,0 +1,484 @@
  22391. +/*******************************************************************************
  22392. +Copyright (C) Marvell International Ltd. and its affiliates
  22393. +
  22394. +This software file (the "File") is owned and distributed by Marvell
  22395. +International Ltd. and/or its affiliates ("Marvell") under the following
  22396. +alternative licensing terms. Once you have made an election to distribute the
  22397. +File under one of the following license alternatives, please (i) delete this
  22398. +introductory statement regarding license alternatives, (ii) delete the two
  22399. +license alternatives that you have not elected to use and (iii) preserve the
  22400. +Marvell copyright notice above.
  22401. +
  22402. +********************************************************************************
  22403. +Marvell Commercial License Option
  22404. +
  22405. +If you received this File from Marvell and you have entered into a commercial
  22406. +license agreement (a "Commercial License") with Marvell, the File is licensed
  22407. +to you under the terms of the applicable Commercial License.
  22408. +
  22409. +********************************************************************************
  22410. +Marvell GPL License Option
  22411. +
  22412. +If you received this File from Marvell, you may opt to use, redistribute and/or
  22413. +modify this File in accordance with the terms and conditions of the General
  22414. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  22415. +available along with the File in the license.txt file or by writing to the Free
  22416. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  22417. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  22418. +
  22419. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  22420. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  22421. +DISCLAIMED. The GPL License provides additional details about this warranty
  22422. +disclaimer.
  22423. +********************************************************************************
  22424. +Marvell BSD License Option
  22425. +
  22426. +If you received this File from Marvell, you may opt to use, redistribute and/or
  22427. +modify this File under the following licensing terms.
  22428. +Redistribution and use in source and binary forms, with or without modification,
  22429. +are permitted provided that the following conditions are met:
  22430. +
  22431. + * Redistributions of source code must retain the above copyright notice,
  22432. + this list of conditions and the following disclaimer.
  22433. +
  22434. + * Redistributions in binary form must reproduce the above copyright
  22435. + notice, this list of conditions and the following disclaimer in the
  22436. + documentation and/or other materials provided with the distribution.
  22437. +
  22438. + * Neither the name of Marvell nor the names of its contributors may be
  22439. + used to endorse or promote products derived from this software without
  22440. + specific prior written permission.
  22441. +
  22442. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  22443. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  22444. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22445. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  22446. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22447. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22448. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  22449. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22450. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  22451. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22452. +
  22453. +*******************************************************************************/
  22454. +
  22455. +#include "mvOs.h"
  22456. +#include "mvDebug.h"
  22457. +
  22458. +#include "cesa/mvMD5.h"
  22459. +#include "cesa/mvSHA1.h"
  22460. +
  22461. +#include "cesa/mvCesa.h"
  22462. +#include "cesa/mvCesaRegs.h"
  22463. +#include "cesa/AES/mvAes.h"
  22464. +
  22465. +static const char* mvCesaDebugStateStr(MV_CESA_STATE state)
  22466. +{
  22467. + switch(state)
  22468. + {
  22469. + case MV_CESA_IDLE:
  22470. + return "Idle";
  22471. +
  22472. + case MV_CESA_PENDING:
  22473. + return "Pend";
  22474. +
  22475. + case MV_CESA_PROCESS:
  22476. + return "Proc";
  22477. +
  22478. + case MV_CESA_READY:
  22479. + return "Ready";
  22480. +
  22481. + default:
  22482. + break;
  22483. + }
  22484. + return "Unknown";
  22485. +}
  22486. +
  22487. +static const char* mvCesaDebugOperStr(MV_CESA_OPERATION oper)
  22488. +{
  22489. + switch(oper)
  22490. + {
  22491. + case MV_CESA_MAC_ONLY:
  22492. + return "MacOnly";
  22493. +
  22494. + case MV_CESA_CRYPTO_ONLY:
  22495. + return "CryptoOnly";
  22496. +
  22497. + case MV_CESA_MAC_THEN_CRYPTO:
  22498. + return "MacCrypto";
  22499. +
  22500. + case MV_CESA_CRYPTO_THEN_MAC:
  22501. + return "CryptoMac";
  22502. +
  22503. + default:
  22504. + break;
  22505. + }
  22506. + return "Null";
  22507. +}
  22508. +
  22509. +static const char* mvCesaDebugCryptoAlgStr(MV_CESA_CRYPTO_ALG cryptoAlg)
  22510. +{
  22511. + switch(cryptoAlg)
  22512. + {
  22513. + case MV_CESA_CRYPTO_DES:
  22514. + return "DES";
  22515. +
  22516. + case MV_CESA_CRYPTO_3DES:
  22517. + return "3DES";
  22518. +
  22519. + case MV_CESA_CRYPTO_AES:
  22520. + return "AES";
  22521. +
  22522. + default:
  22523. + break;
  22524. + }
  22525. + return "Null";
  22526. +}
  22527. +
  22528. +static const char* mvCesaDebugMacModeStr(MV_CESA_MAC_MODE macMode)
  22529. +{
  22530. + switch(macMode)
  22531. + {
  22532. + case MV_CESA_MAC_MD5:
  22533. + return "MD5";
  22534. +
  22535. + case MV_CESA_MAC_SHA1:
  22536. + return "SHA1";
  22537. +
  22538. + case MV_CESA_MAC_HMAC_MD5:
  22539. + return "HMAC-MD5";
  22540. +
  22541. + case MV_CESA_MAC_HMAC_SHA1:
  22542. + return "HMAC_SHA1";
  22543. +
  22544. + default:
  22545. + break;
  22546. + }
  22547. + return "Null";
  22548. +}
  22549. +
  22550. +void mvCesaDebugCmd(MV_CESA_COMMAND* pCmd, int mode)
  22551. +{
  22552. + mvOsPrintf("pCmd=%p, pReqPrv=%p, pSrc=%p, pDst=%p, pCB=%p, sid=%d\n",
  22553. + pCmd, pCmd->pReqPrv, pCmd->pSrc, pCmd->pDst,
  22554. + pCmd->pFuncCB, pCmd->sessionId);
  22555. + mvOsPrintf("isUser=%d, ivOffs=%d, crOffs=%d, crLen=%d, digest=%d, macOffs=%d, macLen=%d\n",
  22556. + pCmd->ivFromUser, pCmd->ivOffset, pCmd->cryptoOffset, pCmd->cryptoLength,
  22557. + pCmd->digestOffset, pCmd->macOffset, pCmd->macLength);
  22558. +}
  22559. +
  22560. +/* no need to use in tool */
  22561. +void mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size)
  22562. +{
  22563. + int frag, len, fragOffset;
  22564. +
  22565. + if(str != NULL)
  22566. + mvOsPrintf("%s: pMbuf=%p, numFrags=%d, mbufSize=%d\n",
  22567. + str, pMbuf, pMbuf->numFrags, pMbuf->mbufSize);
  22568. +
  22569. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  22570. + if(frag == MV_INVALID)
  22571. + {
  22572. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  22573. + return;
  22574. + }
  22575. +
  22576. + for(; frag<pMbuf->numFrags; frag++)
  22577. + {
  22578. + mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n",
  22579. + frag, pMbuf->pFrags[frag].bufVirtPtr,
  22580. + pMbuf->pFrags[frag].bufSize);
  22581. + if(size > 0)
  22582. + {
  22583. + len = MV_MIN(pMbuf->pFrags[frag].bufSize, size);
  22584. + mvDebugMemDump(pMbuf->pFrags[frag].bufVirtPtr+fragOffset, len, 1);
  22585. + size -= len;
  22586. + fragOffset = 0;
  22587. + }
  22588. + }
  22589. +}
  22590. +
  22591. +void mvCesaDebugRegs(void)
  22592. +{
  22593. + mvOsPrintf("\t CESA Registers:\n");
  22594. +
  22595. + mvOsPrintf("MV_CESA_CMD_REG : 0x%X = 0x%08x\n",
  22596. + MV_CESA_CMD_REG,
  22597. + MV_REG_READ( MV_CESA_CMD_REG ) );
  22598. +
  22599. + mvOsPrintf("MV_CESA_CHAN_DESC_OFFSET_REG : 0x%X = 0x%08x\n",
  22600. + MV_CESA_CHAN_DESC_OFFSET_REG,
  22601. + MV_REG_READ(MV_CESA_CHAN_DESC_OFFSET_REG) );
  22602. +
  22603. + mvOsPrintf("MV_CESA_CFG_REG : 0x%X = 0x%08x\n",
  22604. + MV_CESA_CFG_REG,
  22605. + MV_REG_READ( MV_CESA_CFG_REG ) );
  22606. +
  22607. + mvOsPrintf("MV_CESA_STATUS_REG : 0x%X = 0x%08x\n",
  22608. + MV_CESA_STATUS_REG,
  22609. + MV_REG_READ( MV_CESA_STATUS_REG ) );
  22610. +
  22611. + mvOsPrintf("MV_CESA_ISR_CAUSE_REG : 0x%X = 0x%08x\n",
  22612. + MV_CESA_ISR_CAUSE_REG,
  22613. + MV_REG_READ( MV_CESA_ISR_CAUSE_REG ) );
  22614. +
  22615. + mvOsPrintf("MV_CESA_ISR_MASK_REG : 0x%X = 0x%08x\n",
  22616. + MV_CESA_ISR_MASK_REG,
  22617. + MV_REG_READ( MV_CESA_ISR_MASK_REG ) );
  22618. +#if (MV_CESA_VERSION >= 2)
  22619. + mvOsPrintf("MV_CESA_TDMA_CTRL_REG : 0x%X = 0x%08x\n",
  22620. + MV_CESA_TDMA_CTRL_REG,
  22621. + MV_REG_READ( MV_CESA_TDMA_CTRL_REG ) );
  22622. +
  22623. + mvOsPrintf("MV_CESA_TDMA_BYTE_COUNT_REG : 0x%X = 0x%08x\n",
  22624. + MV_CESA_TDMA_BYTE_COUNT_REG,
  22625. + MV_REG_READ( MV_CESA_TDMA_BYTE_COUNT_REG ) );
  22626. +
  22627. + mvOsPrintf("MV_CESA_TDMA_SRC_ADDR_REG : 0x%X = 0x%08x\n",
  22628. + MV_CESA_TDMA_SRC_ADDR_REG,
  22629. + MV_REG_READ( MV_CESA_TDMA_SRC_ADDR_REG ) );
  22630. +
  22631. + mvOsPrintf("MV_CESA_TDMA_DST_ADDR_REG : 0x%X = 0x%08x\n",
  22632. + MV_CESA_TDMA_DST_ADDR_REG,
  22633. + MV_REG_READ( MV_CESA_TDMA_DST_ADDR_REG ) );
  22634. +
  22635. + mvOsPrintf("MV_CESA_TDMA_NEXT_DESC_PTR_REG : 0x%X = 0x%08x\n",
  22636. + MV_CESA_TDMA_NEXT_DESC_PTR_REG,
  22637. + MV_REG_READ( MV_CESA_TDMA_NEXT_DESC_PTR_REG ) );
  22638. +
  22639. + mvOsPrintf("MV_CESA_TDMA_CURR_DESC_PTR_REG : 0x%X = 0x%08x\n",
  22640. + MV_CESA_TDMA_CURR_DESC_PTR_REG,
  22641. + MV_REG_READ( MV_CESA_TDMA_CURR_DESC_PTR_REG ) );
  22642. +
  22643. + mvOsPrintf("MV_CESA_TDMA_ERROR_CAUSE_REG : 0x%X = 0x%08x\n",
  22644. + MV_CESA_TDMA_ERROR_CAUSE_REG,
  22645. + MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );
  22646. +
  22647. + mvOsPrintf("MV_CESA_TDMA_ERROR_MASK_REG : 0x%X = 0x%08x\n",
  22648. + MV_CESA_TDMA_ERROR_MASK_REG,
  22649. + MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );
  22650. +
  22651. +#endif
  22652. +}
  22653. +
  22654. +void mvCesaDebugStatus(void)
  22655. +{
  22656. + mvOsPrintf("\n\t CESA Status\n\n");
  22657. +
  22658. + mvOsPrintf("pReqQ=%p, qDepth=%d, reqSize=%ld bytes, qRes=%d, ",
  22659. + pCesaReqFirst, cesaQueueDepth, sizeof(MV_CESA_REQ),
  22660. + cesaReqResources);
  22661. +#if (MV_CESA_VERSION >= 3)
  22662. + mvOsPrintf("chainLength=%u\n",cesaChainLength);
  22663. +#else
  22664. + mvOsPrintf("\n");
  22665. +#endif
  22666. +
  22667. + mvOsPrintf("pSAD=%p, maxSA=%d, sizeSA=%ld bytes\n",
  22668. + pCesaSAD, cesaMaxSA, sizeof(MV_CESA_SA));
  22669. +
  22670. + mvOsPrintf("\n");
  22671. +
  22672. + mvCesaDebugRegs();
  22673. + mvCesaDebugStats();
  22674. + mvCesaDebugStatsClear();
  22675. +}
  22676. +
  22677. +void mvCesaDebugDescriptor(MV_CESA_DESC* pDesc)
  22678. +{
  22679. + mvOsPrintf("config=0x%08x, crSrcOffs=0x%04x, crDstOffs=0x%04x\n",
  22680. + pDesc->config, pDesc->cryptoSrcOffset, pDesc->cryptoDstOffset);
  22681. +
  22682. + mvOsPrintf("crLen=0x%04x, crKeyOffs=0x%04x, ivOffs=0x%04x, ivBufOffs=0x%04x\n",
  22683. + pDesc->cryptoDataLen, pDesc->cryptoKeyOffset,
  22684. + pDesc->cryptoIvOffset, pDesc->cryptoIvBufOffset);
  22685. +
  22686. + mvOsPrintf("macSrc=0x%04x, digest=0x%04x, macLen=0x%04x, inIv=0x%04x, outIv=0x%04x\n",
  22687. + pDesc->macSrcOffset, pDesc->macDigestOffset, pDesc->macDataLen,
  22688. + pDesc->macInnerIvOffset, pDesc->macOuterIvOffset);
  22689. +}
  22690. +
  22691. +void mvCesaDebugQueue(int mode)
  22692. +{
  22693. + mvOsPrintf("\n\t CESA Request Queue:\n\n");
  22694. +
  22695. + mvOsPrintf("pFirstReq=%p, pLastReq=%p, qDepth=%d, reqSize=%ld bytes\n",
  22696. + pCesaReqFirst, pCesaReqLast, cesaQueueDepth, sizeof(MV_CESA_REQ));
  22697. +
  22698. + mvOsPrintf("pEmpty=%p, pProcess=%p, qResources=%d\n",
  22699. + pCesaReqEmpty, pCesaReqProcess,
  22700. + cesaReqResources);
  22701. +
  22702. + if(mode != 0)
  22703. + {
  22704. + int count = 0;
  22705. + MV_CESA_REQ* pReq = pCesaReqFirst;
  22706. +
  22707. + for(count=0; count<cesaQueueDepth; count++)
  22708. + {
  22709. + /* Print out requsts */
  22710. + mvOsPrintf("%02d. pReq=%p, state=%s, frag=0x%x, pCmd=%p, pDma=%p, pDesc=%p\n",
  22711. + count, pReq, mvCesaDebugStateStr(pReq->state),
  22712. + pReq->fragMode, pReq->pCmd, pReq->dma[0].pDmaFirst, &pReq->pCesaDesc[0]);
  22713. + if(pReq->fragMode != MV_CESA_FRAG_NONE)
  22714. + {
  22715. + int frag;
  22716. +
  22717. + mvOsPrintf("pFrags=%p, num=%d, next=%d, bufOffset=%d, cryptoSize=%d, macSize=%d\n",
  22718. + &pReq->frags, pReq->frags.numFrag, pReq->frags.nextFrag,
  22719. + pReq->frags.bufOffset, pReq->frags.cryptoSize, pReq->frags.macSize);
  22720. + for(frag=0; frag<pReq->frags.numFrag; frag++)
  22721. + {
  22722. + mvOsPrintf("#%d: pDmaFirst=%p, pDesc=%p\n", frag,
  22723. + pReq->dma[frag].pDmaFirst, &pReq->pCesaDesc[frag]);
  22724. + }
  22725. + }
  22726. + if(mode > 1)
  22727. + {
  22728. + /* Print out Command */
  22729. + mvCesaDebugCmd(pReq->pCmd, mode);
  22730. +
  22731. + /* Print out Descriptor */
  22732. + mvCesaDebugDescriptor(&pReq->pCesaDesc[0]);
  22733. + }
  22734. + pReq++;
  22735. + }
  22736. + }
  22737. +}
  22738. +
  22739. +
  22740. +void mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode)
  22741. +{
  22742. + if(pSramSA == NULL)
  22743. + {
  22744. + mvOsPrintf("cesaSramSA: Unexpected pSramSA=%p\n", pSramSA);
  22745. + return;
  22746. + }
  22747. + mvOsPrintf("pSramSA=%p, sizeSramSA=%ld bytes\n",
  22748. + pSramSA, sizeof(MV_CESA_SRAM_SA));
  22749. +
  22750. + if(mode != 0)
  22751. + {
  22752. + mvOsPrintf("cryptoKey=%p, maxCryptoKey=%d bytes\n",
  22753. + pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH);
  22754. + mvDebugMemDump(pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH, 1);
  22755. +
  22756. + mvOsPrintf("macInnerIV=%p, maxInnerIV=%d bytes\n",
  22757. + pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE);
  22758. + mvDebugMemDump(pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE, 1);
  22759. +
  22760. + mvOsPrintf("macOuterIV=%p, maxOuterIV=%d bytes\n",
  22761. + pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE);
  22762. + mvDebugMemDump(pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE, 1);
  22763. + }
  22764. +}
  22765. +
  22766. +void mvCesaDebugSA(short sid, int mode)
  22767. +{
  22768. + MV_CESA_OPERATION oper;
  22769. + MV_CESA_DIRECTION dir;
  22770. + MV_CESA_CRYPTO_ALG cryptoAlg;
  22771. + MV_CESA_CRYPTO_MODE cryptoMode;
  22772. + MV_CESA_MAC_MODE macMode;
  22773. + MV_CESA_SA* pSA = &pCesaSAD[sid];
  22774. +
  22775. + if( (pSA->valid) || ((pSA->count != 0) && (mode > 0)) || (mode >= 2) )
  22776. + {
  22777. + mvOsPrintf("\n\nCESA SA Entry #%d (%p) - %s (count=%d)\n",
  22778. + sid, pSA,
  22779. + pSA->valid ? "Valid" : "Invalid", pSA->count);
  22780. +
  22781. + oper = (pSA->config & MV_CESA_OPERATION_MASK) >> MV_CESA_OPERATION_OFFSET;
  22782. + dir = (pSA->config & MV_CESA_DIRECTION_MASK) >> MV_CESA_DIRECTION_BIT;
  22783. + mvOsPrintf("%s - %s ", mvCesaDebugOperStr(oper),
  22784. + (dir == MV_CESA_DIR_ENCODE) ? "Encode" : "Decode");
  22785. + if(oper != MV_CESA_MAC_ONLY)
  22786. + {
  22787. + cryptoAlg = (pSA->config & MV_CESA_CRYPTO_ALG_MASK) >> MV_CESA_CRYPTO_ALG_OFFSET;
  22788. + cryptoMode = (pSA->config & MV_CESA_CRYPTO_MODE_MASK) >> MV_CESA_CRYPTO_MODE_BIT;
  22789. + mvOsPrintf("- %s - %s ", mvCesaDebugCryptoAlgStr(cryptoAlg),
  22790. + (cryptoMode == MV_CESA_CRYPTO_ECB) ? "ECB" : "CBC");
  22791. + }
  22792. + if(oper != MV_CESA_CRYPTO_ONLY)
  22793. + {
  22794. + macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;
  22795. + mvOsPrintf("- %s ", mvCesaDebugMacModeStr(macMode));
  22796. + }
  22797. + mvOsPrintf("\n");
  22798. +
  22799. + if(mode > 0)
  22800. + {
  22801. + mvOsPrintf("config=0x%08x, cryptoKeySize=%d, digestSize=%d\n",
  22802. + pCesaSAD[sid].config, pCesaSAD[sid].cryptoKeyLength,
  22803. + pCesaSAD[sid].digestSize);
  22804. +
  22805. + mvCesaDebugSramSA(pCesaSAD[sid].pSramSA, mode);
  22806. + }
  22807. + }
  22808. +}
  22809. +
  22810. +
  22811. +/**/
  22812. +void mvCesaDebugSram(int mode)
  22813. +{
  22814. + mvOsPrintf("\n\t SRAM contents: size=%ld, pVirt=%p\n\n",
  22815. + sizeof(MV_CESA_SRAM_MAP), cesaSramVirtPtr);
  22816. +
  22817. + mvOsPrintf("\n\t Sram buffer: size=%d, pVirt=%p\n",
  22818. + MV_CESA_MAX_BUF_SIZE, cesaSramVirtPtr->buf);
  22819. + if(mode != 0)
  22820. + mvDebugMemDump(cesaSramVirtPtr->buf, 64, 1);
  22821. +
  22822. + mvOsPrintf("\n");
  22823. + mvOsPrintf("\n\t Sram descriptor: size=%ld, pVirt=%p\n",
  22824. + sizeof(MV_CESA_DESC), &cesaSramVirtPtr->desc);
  22825. + if(mode != 0)
  22826. + {
  22827. + mvOsPrintf("\n");
  22828. + mvCesaDebugDescriptor(&cesaSramVirtPtr->desc);
  22829. + }
  22830. + mvOsPrintf("\n\t Sram IV: size=%d, pVirt=%p\n",
  22831. + MV_CESA_MAX_IV_LENGTH, &cesaSramVirtPtr->cryptoIV);
  22832. + if(mode != 0)
  22833. + {
  22834. + mvOsPrintf("\n");
  22835. + mvDebugMemDump(cesaSramVirtPtr->cryptoIV, MV_CESA_MAX_IV_LENGTH, 1);
  22836. + }
  22837. + mvOsPrintf("\n");
  22838. + mvCesaDebugSramSA(&cesaSramVirtPtr->sramSA, 0);
  22839. +}
  22840. +
  22841. +void mvCesaDebugSAD(int mode)
  22842. +{
  22843. + int sid;
  22844. +
  22845. + mvOsPrintf("\n\t Cesa SAD status: pSAD=%p, maxSA=%d\n",
  22846. + pCesaSAD, cesaMaxSA);
  22847. +
  22848. + for(sid=0; sid<cesaMaxSA; sid++)
  22849. + {
  22850. + mvCesaDebugSA(sid, mode);
  22851. + }
  22852. +}
  22853. +
  22854. +void mvCesaDebugStats(void)
  22855. +{
  22856. + mvOsPrintf("\n\t Cesa Statistics\n");
  22857. +
  22858. + mvOsPrintf("Opened=%u, Closed=%u\n",
  22859. + cesaStats.openedCount, cesaStats.closedCount);
  22860. + mvOsPrintf("Req=%u, maxReq=%u, frags=%u, start=%u\n",
  22861. + cesaStats.reqCount, cesaStats.maxReqCount,
  22862. + cesaStats.fragCount, cesaStats.startCount);
  22863. +#if (MV_CESA_VERSION >= 3)
  22864. + mvOsPrintf("maxChainUsage=%u\n",cesaStats.maxChainUsage);
  22865. +#endif
  22866. + mvOsPrintf("\n");
  22867. + mvOsPrintf("proc=%u, ready=%u, notReady=%u\n",
  22868. + cesaStats.procCount, cesaStats.readyCount, cesaStats.notReadyCount);
  22869. +}
  22870. +
  22871. +void mvCesaDebugStatsClear(void)
  22872. +{
  22873. + memset(&cesaStats, 0, sizeof(cesaStats));
  22874. +}
  22875. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesa.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesa.h
  22876. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesa.h 1970-01-01 01:00:00.000000000 +0100
  22877. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesa.h 2010-11-09 20:28:05.737859537 +0100
  22878. @@ -0,0 +1,412 @@
  22879. +/*******************************************************************************
  22880. +Copyright (C) Marvell International Ltd. and its affiliates
  22881. +
  22882. +This software file (the "File") is owned and distributed by Marvell
  22883. +International Ltd. and/or its affiliates ("Marvell") under the following
  22884. +alternative licensing terms. Once you have made an election to distribute the
  22885. +File under one of the following license alternatives, please (i) delete this
  22886. +introductory statement regarding license alternatives, (ii) delete the two
  22887. +license alternatives that you have not elected to use and (iii) preserve the
  22888. +Marvell copyright notice above.
  22889. +
  22890. +********************************************************************************
  22891. +Marvell Commercial License Option
  22892. +
  22893. +If you received this File from Marvell and you have entered into a commercial
  22894. +license agreement (a "Commercial License") with Marvell, the File is licensed
  22895. +to you under the terms of the applicable Commercial License.
  22896. +
  22897. +********************************************************************************
  22898. +Marvell GPL License Option
  22899. +
  22900. +If you received this File from Marvell, you may opt to use, redistribute and/or
  22901. +modify this File in accordance with the terms and conditions of the General
  22902. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  22903. +available along with the File in the license.txt file or by writing to the Free
  22904. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  22905. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  22906. +
  22907. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  22908. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  22909. +DISCLAIMED. The GPL License provides additional details about this warranty
  22910. +disclaimer.
  22911. +********************************************************************************
  22912. +Marvell BSD License Option
  22913. +
  22914. +If you received this File from Marvell, you may opt to use, redistribute and/or
  22915. +modify this File under the following licensing terms.
  22916. +Redistribution and use in source and binary forms, with or without modification,
  22917. +are permitted provided that the following conditions are met:
  22918. +
  22919. + * Redistributions of source code must retain the above copyright notice,
  22920. + this list of conditions and the following disclaimer.
  22921. +
  22922. + * Redistributions in binary form must reproduce the above copyright
  22923. + notice, this list of conditions and the following disclaimer in the
  22924. + documentation and/or other materials provided with the distribution.
  22925. +
  22926. + * Neither the name of Marvell nor the names of its contributors may be
  22927. + used to endorse or promote products derived from this software without
  22928. + specific prior written permission.
  22929. +
  22930. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  22931. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  22932. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22933. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  22934. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22935. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22936. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  22937. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22938. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  22939. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22940. +
  22941. +*******************************************************************************/
  22942. +
  22943. +/*******************************************************************************
  22944. +* mvCesa.h - Header File for Cryptographic Engines and Security Accelerator
  22945. +*
  22946. +* DESCRIPTION:
  22947. +* This header file contains macros typedefs and function declaration for
  22948. +* the Marvell Cryptographic Engines and Security Accelerator.
  22949. +*
  22950. +*******************************************************************************/
  22951. +
  22952. +#ifndef __mvCesa_h__
  22953. +#define __mvCesa_h__
  22954. +
  22955. +#include "mvOs.h"
  22956. +#include "mvCommon.h"
  22957. +#include "mvDebug.h"
  22958. +
  22959. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  22960. +
  22961. +#include "cesa/mvMD5.h"
  22962. +#include "cesa/mvSHA1.h"
  22963. +
  22964. +#include "cesa/mvCesa.h"
  22965. +#include "cesa/AES/mvAes.h"
  22966. +#include "mvSysHwConfig.h"
  22967. +
  22968. +#ifdef MV_INCLUDE_IDMA
  22969. +#include "idma/mvIdma.h"
  22970. +#include "idma/mvIdmaRegs.h"
  22971. +#else
  22972. +/* Redefine MV_DMA_DESC structure */
  22973. +typedef struct _mvDmaDesc
  22974. +{
  22975. + MV_U32 byteCnt; /* The total number of bytes to transfer */
  22976. + MV_U32 phySrcAdd; /* The physical source address */
  22977. + MV_U32 phyDestAdd; /* The physical destination address */
  22978. + MV_U32 phyNextDescPtr; /* If we are using chain mode DMA transfer, */
  22979. + /* then this pointer should point to the */
  22980. + /* physical address of the next descriptor, */
  22981. + /* otherwise it should be NULL. */
  22982. +}MV_DMA_DESC;
  22983. +#endif /* MV_INCLUDE_IDMA */
  22984. +
  22985. +#include "cesa/mvCesaRegs.h"
  22986. +
  22987. +#define MV_CESA_AUTH_BLOCK_SIZE 64 /* bytes */
  22988. +
  22989. +#define MV_CESA_MD5_DIGEST_SIZE 16 /* bytes */
  22990. +#define MV_CESA_SHA1_DIGEST_SIZE 20 /* bytes */
  22991. +
  22992. +#define MV_CESA_MAX_DIGEST_SIZE MV_CESA_SHA1_DIGEST_SIZE
  22993. +
  22994. +#define MV_CESA_DES_KEY_LENGTH 8 /* bytes = 64 bits */
  22995. +#define MV_CESA_3DES_KEY_LENGTH 24 /* bytes = 192 bits */
  22996. +#define MV_CESA_AES_128_KEY_LENGTH 16 /* bytes = 128 bits */
  22997. +#define MV_CESA_AES_192_KEY_LENGTH 24 /* bytes = 192 bits */
  22998. +#define MV_CESA_AES_256_KEY_LENGTH 32 /* bytes = 256 bits */
  22999. +
  23000. +#define MV_CESA_MAX_CRYPTO_KEY_LENGTH MV_CESA_AES_256_KEY_LENGTH
  23001. +
  23002. +#define MV_CESA_DES_BLOCK_SIZE 8 /* bytes = 64 bits */
  23003. +#define MV_CESA_3DES_BLOCK_SIZE 8 /* bytes = 64 bits */
  23004. +
  23005. +#define MV_CESA_AES_BLOCK_SIZE 16 /* bytes = 128 bits */
  23006. +
  23007. +#define MV_CESA_MAX_IV_LENGTH MV_CESA_AES_BLOCK_SIZE
  23008. +
  23009. +#define MV_CESA_MAX_MAC_KEY_LENGTH 64 /* bytes */
  23010. +
  23011. +typedef struct
  23012. +{
  23013. + MV_U8 cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];
  23014. + MV_U8 macKey[MV_CESA_MAX_MAC_KEY_LENGTH];
  23015. + MV_CESA_OPERATION operation;
  23016. + MV_CESA_DIRECTION direction;
  23017. + MV_CESA_CRYPTO_ALG cryptoAlgorithm;
  23018. + MV_CESA_CRYPTO_MODE cryptoMode;
  23019. + MV_U8 cryptoKeyLength;
  23020. + MV_CESA_MAC_MODE macMode;
  23021. + MV_U8 macKeyLength;
  23022. + MV_U8 digestSize;
  23023. +
  23024. +} MV_CESA_OPEN_SESSION;
  23025. +
  23026. +typedef struct
  23027. +{
  23028. + MV_BUF_INFO *pFrags;
  23029. + MV_U16 numFrags;
  23030. + MV_U16 mbufSize;
  23031. +
  23032. +} MV_CESA_MBUF;
  23033. +
  23034. +typedef struct
  23035. +{
  23036. + void* pReqPrv; /* instead of reqId */
  23037. + MV_U32 retCode;
  23038. + MV_16 sessionId;
  23039. +
  23040. +} MV_CESA_RESULT;
  23041. +
  23042. +typedef void (*MV_CESA_CALLBACK) (MV_CESA_RESULT* pResult);
  23043. +
  23044. +
  23045. +typedef struct
  23046. +{
  23047. + void* pReqPrv; /* instead of reqId */
  23048. + MV_CESA_MBUF* pSrc;
  23049. + MV_CESA_MBUF* pDst;
  23050. + MV_CESA_CALLBACK* pFuncCB;
  23051. + MV_16 sessionId;
  23052. + MV_U16 ivFromUser;
  23053. + MV_U16 ivOffset;
  23054. + MV_U16 cryptoOffset;
  23055. + MV_U16 cryptoLength;
  23056. + MV_U16 digestOffset;
  23057. + MV_U16 macOffset;
  23058. + MV_U16 macLength;
  23059. + MV_BOOL skipFlush;
  23060. +} MV_CESA_COMMAND;
  23061. +
  23062. +
  23063. +
  23064. +MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase, void *osHandle);
  23065. +MV_STATUS mvCesaFinish (void);
  23066. +MV_STATUS mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid);
  23067. +MV_STATUS mvCesaSessionClose(short sid);
  23068. +MV_STATUS mvCesaCryptoIvSet(MV_U8* pIV, int ivSize);
  23069. +
  23070. +MV_STATUS mvCesaAction (MV_CESA_COMMAND* pCmd);
  23071. +
  23072. +MV_U32 mvCesaInProcessGet(void);
  23073. +MV_STATUS mvCesaReadyDispatch(void);
  23074. +MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult);
  23075. +MV_BOOL mvCesaIsReady(void);
  23076. +
  23077. +int mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset);
  23078. +MV_STATUS mvCesaCopyFromMbuf(MV_U8* pDst, MV_CESA_MBUF* pSrcMbuf,
  23079. + int offset, int size);
  23080. +MV_STATUS mvCesaCopyToMbuf(MV_U8* pSrc, MV_CESA_MBUF* pDstMbuf,
  23081. + int offset, int size);
  23082. +MV_STATUS mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,
  23083. + MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size);
  23084. +
  23085. +/********** Debug functions ********/
  23086. +
  23087. +void mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size);
  23088. +void mvCesaDebugSA(short sid, int mode);
  23089. +void mvCesaDebugStats(void);
  23090. +void mvCesaDebugStatsClear(void);
  23091. +void mvCesaDebugRegs(void);
  23092. +void mvCesaDebugStatus(void);
  23093. +void mvCesaDebugQueue(int mode);
  23094. +void mvCesaDebugSram(int mode);
  23095. +void mvCesaDebugSAD(int mode);
  23096. +
  23097. +
  23098. +/******** CESA Private definitions ********/
  23099. +#if (MV_CESA_VERSION >= 2)
  23100. +#if (MV_CACHE_COHERENCY == MV_CACHE_COHER_SW)
  23101. +#define MV_CESA_TDMA_CTRL_VALUE MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
  23102. + | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
  23103. + | MV_CESA_TDMA_OUTSTAND_READ_EN_MASK \
  23104. + | MV_CESA_TDMA_NO_BYTE_SWAP_MASK \
  23105. + | MV_CESA_TDMA_ENABLE_MASK
  23106. +#else
  23107. +#define MV_CESA_TDMA_CTRL_VALUE MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_32B) \
  23108. + | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
  23109. + /*| MV_CESA_TDMA_OUTSTAND_READ_EN_MASK */\
  23110. + | MV_CESA_TDMA_ENABLE_MASK
  23111. +
  23112. +#endif
  23113. +#else
  23114. +#define MV_CESA_IDMA_CTRL_LOW_VALUE ICCLR_DST_BURST_LIM_128BYTE \
  23115. + | ICCLR_SRC_BURST_LIM_128BYTE \
  23116. + | ICCLR_INT_MODE_MASK \
  23117. + | ICCLR_BLOCK_MODE \
  23118. + | ICCLR_CHAN_ENABLE \
  23119. + | ICCLR_DESC_MODE_16M
  23120. +#endif /* MV_CESA_VERSION >= 2 */
  23121. +
  23122. +#define MV_CESA_MAX_PKT_SIZE (64 * 1024)
  23123. +#define MV_CESA_MAX_MBUF_FRAGS 20
  23124. +
  23125. +#define MV_CESA_MAX_REQ_FRAGS ( (MV_CESA_MAX_PKT_SIZE / MV_CESA_MAX_BUF_SIZE) + 1)
  23126. +
  23127. +#define MV_CESA_MAX_DMA_DESC (MV_CESA_MAX_MBUF_FRAGS*2 + 5)
  23128. +
  23129. +#define MAX_CESA_CHAIN_LENGTH 20
  23130. +
  23131. +typedef enum
  23132. +{
  23133. + MV_CESA_IDLE = 0,
  23134. + MV_CESA_PENDING,
  23135. + MV_CESA_PROCESS,
  23136. + MV_CESA_READY,
  23137. +#if (MV_CESA_VERSION >= 3)
  23138. + MV_CESA_CHAIN,
  23139. +#endif
  23140. +} MV_CESA_STATE;
  23141. +
  23142. +
  23143. +/* Session database */
  23144. +
  23145. +/* Map of Key materials of the session in SRAM.
  23146. + * Each field must be 8 byte aligned
  23147. + * Total size: 32 + 24 + 24 = 80 bytes
  23148. + */
  23149. +typedef struct
  23150. +{
  23151. + MV_U8 cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];
  23152. + MV_U8 macInnerIV[MV_CESA_MAX_DIGEST_SIZE];
  23153. + MV_U8 reservedInner[4];
  23154. + MV_U8 macOuterIV[MV_CESA_MAX_DIGEST_SIZE];
  23155. + MV_U8 reservedOuter[4];
  23156. +
  23157. +} MV_CESA_SRAM_SA;
  23158. +
  23159. +typedef struct
  23160. +{
  23161. + MV_CESA_SRAM_SA* pSramSA;
  23162. + MV_U32 config;
  23163. + MV_U8 cryptoKeyLength;
  23164. + MV_U8 cryptoIvSize;
  23165. + MV_U8 cryptoBlockSize;
  23166. + MV_U8 digestSize;
  23167. + MV_U8 macKeyLength;
  23168. + MV_U8 valid;
  23169. + MV_U8 ctrMode;
  23170. + MV_U32 count;
  23171. +
  23172. +} MV_CESA_SA;
  23173. +
  23174. +/* DMA list management */
  23175. +typedef struct
  23176. +{
  23177. + MV_DMA_DESC* pDmaFirst;
  23178. + MV_DMA_DESC* pDmaLast;
  23179. +
  23180. +} MV_CESA_DMA;
  23181. +
  23182. +
  23183. +typedef struct
  23184. +{
  23185. + MV_U8 numFrag;
  23186. + MV_U8 nextFrag;
  23187. + int bufOffset;
  23188. + int cryptoSize;
  23189. + int macSize;
  23190. + int newDigestOffset;
  23191. + MV_U8 orgDigest[MV_CESA_MAX_DIGEST_SIZE];
  23192. +
  23193. +} MV_CESA_FRAGS;
  23194. +
  23195. +/* Request queue */
  23196. +typedef struct
  23197. +{
  23198. + MV_U8 state;
  23199. + MV_U8 fragMode;
  23200. + MV_U8 fixOffset;
  23201. + MV_CESA_COMMAND* pCmd;
  23202. + MV_CESA_COMMAND* pOrgCmd;
  23203. + MV_BUF_INFO dmaDescBuf;
  23204. + MV_CESA_DMA dma[MV_CESA_MAX_REQ_FRAGS];
  23205. + MV_BUF_INFO cesaDescBuf;
  23206. + MV_CESA_DESC* pCesaDesc;
  23207. + MV_CESA_FRAGS frags;
  23208. +
  23209. +
  23210. +} MV_CESA_REQ;
  23211. +
  23212. +
  23213. +/* SRAM map */
  23214. +/* Total SRAM size calculation */
  23215. +/* SRAM size =
  23216. + * MV_CESA_MAX_BUF_SIZE +
  23217. + * sizeof(MV_CESA_DESC) +
  23218. + * MV_CESA_MAX_IV_LENGTH +
  23219. + * MV_CESA_MAX_IV_LENGTH +
  23220. + * MV_CESA_MAX_DIGEST_SIZE +
  23221. + * sizeof(MV_CESA_SRAM_SA)
  23222. + * = 1600 + 32 + 16 + 16 + 24 + 80 + 280 (reserved) = 2048 bytes
  23223. + * = 3200 + 32 + 16 + 16 + 24 + 80 + 728 (reserved) = 4096 bytes
  23224. + */
  23225. +typedef struct
  23226. +{
  23227. + MV_U8 buf[MV_CESA_MAX_BUF_SIZE];
  23228. + MV_CESA_DESC desc;
  23229. + MV_U8 cryptoIV[MV_CESA_MAX_IV_LENGTH];
  23230. + MV_U8 tempCryptoIV[MV_CESA_MAX_IV_LENGTH];
  23231. + MV_U8 tempDigest[MV_CESA_MAX_DIGEST_SIZE+4];
  23232. + MV_CESA_SRAM_SA sramSA;
  23233. +
  23234. +} MV_CESA_SRAM_MAP;
  23235. +
  23236. +
  23237. +typedef struct
  23238. +{
  23239. + MV_U32 openedCount;
  23240. + MV_U32 closedCount;
  23241. + MV_U32 fragCount;
  23242. + MV_U32 reqCount;
  23243. + MV_U32 maxReqCount;
  23244. + MV_U32 procCount;
  23245. + MV_U32 readyCount;
  23246. + MV_U32 notReadyCount;
  23247. + MV_U32 startCount;
  23248. +#if (MV_CESA_VERSION >= 3)
  23249. + MV_U32 maxChainUsage;
  23250. +#endif
  23251. +
  23252. +} MV_CESA_STATS;
  23253. +
  23254. +
  23255. +/* External variables */
  23256. +
  23257. +extern MV_CESA_STATS cesaStats;
  23258. +extern MV_CESA_FRAGS cesaFrags;
  23259. +
  23260. +extern MV_BUF_INFO cesaSramSaBuf;
  23261. +
  23262. +extern MV_CESA_SA* pCesaSAD;
  23263. +extern MV_U16 cesaMaxSA;
  23264. +
  23265. +extern MV_CESA_REQ* pCesaReqFirst;
  23266. +extern MV_CESA_REQ* pCesaReqLast;
  23267. +extern MV_CESA_REQ* pCesaReqEmpty;
  23268. +extern MV_CESA_REQ* pCesaReqProcess;
  23269. +extern int cesaQueueDepth;
  23270. +extern int cesaReqResources;
  23271. +#if (MV_CESA_VERSION>= 3)
  23272. +extern MV_U32 cesaChainLength;
  23273. +#endif
  23274. +
  23275. +extern MV_CESA_SRAM_MAP* cesaSramVirtPtr;
  23276. +extern MV_U32 cesaSramPhysAddr;
  23277. +
  23278. +static INLINE MV_ULONG mvCesaVirtToPhys(MV_BUF_INFO* pBufInfo, void* pVirt)
  23279. +{
  23280. + return (pBufInfo->bufPhysAddr + ((MV_U8*)pVirt - pBufInfo->bufVirtPtr));
  23281. +}
  23282. +
  23283. +/* Additional DEBUG functions */
  23284. +void mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode);
  23285. +void mvCesaDebugCmd(MV_CESA_COMMAND* pCmd, int mode);
  23286. +void mvCesaDebugDescriptor(MV_CESA_DESC* pDesc);
  23287. +
  23288. +
  23289. +
  23290. +#endif /* __mvCesa_h__ */
  23291. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaRegs.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaRegs.h
  23292. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaRegs.h 1970-01-01 01:00:00.000000000 +0100
  23293. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaRegs.h 2010-11-09 20:28:05.772495441 +0100
  23294. @@ -0,0 +1,357 @@
  23295. +/*******************************************************************************
  23296. +Copyright (C) Marvell International Ltd. and its affiliates
  23297. +
  23298. +This software file (the "File") is owned and distributed by Marvell
  23299. +International Ltd. and/or its affiliates ("Marvell") under the following
  23300. +alternative licensing terms. Once you have made an election to distribute the
  23301. +File under one of the following license alternatives, please (i) delete this
  23302. +introductory statement regarding license alternatives, (ii) delete the two
  23303. +license alternatives that you have not elected to use and (iii) preserve the
  23304. +Marvell copyright notice above.
  23305. +
  23306. +********************************************************************************
  23307. +Marvell Commercial License Option
  23308. +
  23309. +If you received this File from Marvell and you have entered into a commercial
  23310. +license agreement (a "Commercial License") with Marvell, the File is licensed
  23311. +to you under the terms of the applicable Commercial License.
  23312. +
  23313. +********************************************************************************
  23314. +Marvell GPL License Option
  23315. +
  23316. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23317. +modify this File in accordance with the terms and conditions of the General
  23318. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  23319. +available along with the File in the license.txt file or by writing to the Free
  23320. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  23321. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  23322. +
  23323. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  23324. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  23325. +DISCLAIMED. The GPL License provides additional details about this warranty
  23326. +disclaimer.
  23327. +********************************************************************************
  23328. +Marvell BSD License Option
  23329. +
  23330. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23331. +modify this File under the following licensing terms.
  23332. +Redistribution and use in source and binary forms, with or without modification,
  23333. +are permitted provided that the following conditions are met:
  23334. +
  23335. + * Redistributions of source code must retain the above copyright notice,
  23336. + this list of conditions and the following disclaimer.
  23337. +
  23338. + * Redistributions in binary form must reproduce the above copyright
  23339. + notice, this list of conditions and the following disclaimer in the
  23340. + documentation and/or other materials provided with the distribution.
  23341. +
  23342. + * Neither the name of Marvell nor the names of its contributors may be
  23343. + used to endorse or promote products derived from this software without
  23344. + specific prior written permission.
  23345. +
  23346. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  23347. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23348. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23349. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  23350. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23351. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23352. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  23353. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23354. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23355. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23356. +
  23357. +*******************************************************************************/
  23358. +
  23359. +#ifndef __mvCesaRegs_h__
  23360. +#define __mvCesaRegs_h__
  23361. +
  23362. +#include "mvTypes.h"
  23363. +
  23364. +typedef struct
  23365. +{
  23366. + /* word 0 */
  23367. + MV_U32 config;
  23368. + /* word 1 */
  23369. + MV_U16 cryptoSrcOffset;
  23370. + MV_U16 cryptoDstOffset;
  23371. + /* word 2 */
  23372. + MV_U16 cryptoDataLen;
  23373. + MV_U16 reserved1;
  23374. + /* word 3 */
  23375. + MV_U16 cryptoKeyOffset;
  23376. + MV_U16 reserved2;
  23377. + /* word 4 */
  23378. + MV_U16 cryptoIvOffset;
  23379. + MV_U16 cryptoIvBufOffset;
  23380. + /* word 5 */
  23381. + MV_U16 macSrcOffset;
  23382. + MV_U16 macTotalLen;
  23383. + /* word 6 */
  23384. + MV_U16 macDigestOffset;
  23385. + MV_U16 macDataLen;
  23386. + /* word 7 */
  23387. + MV_U16 macInnerIvOffset;
  23388. + MV_U16 macOuterIvOffset;
  23389. +
  23390. +} MV_CESA_DESC;
  23391. +
  23392. +/* operation */
  23393. +typedef enum
  23394. +{
  23395. + MV_CESA_MAC_ONLY = 0,
  23396. + MV_CESA_CRYPTO_ONLY = 1,
  23397. + MV_CESA_MAC_THEN_CRYPTO = 2,
  23398. + MV_CESA_CRYPTO_THEN_MAC = 3,
  23399. +
  23400. + MV_CESA_MAX_OPERATION
  23401. +
  23402. +} MV_CESA_OPERATION;
  23403. +
  23404. +#define MV_CESA_OPERATION_OFFSET 0
  23405. +#define MV_CESA_OPERATION_MASK (0x3 << MV_CESA_OPERATION_OFFSET)
  23406. +
  23407. +/* mac algorithm */
  23408. +typedef enum
  23409. +{
  23410. + MV_CESA_MAC_NULL = 0,
  23411. + MV_CESA_MAC_MD5 = 4,
  23412. + MV_CESA_MAC_SHA1 = 5,
  23413. + MV_CESA_MAC_HMAC_MD5 = 6,
  23414. + MV_CESA_MAC_HMAC_SHA1 = 7,
  23415. +
  23416. +} MV_CESA_MAC_MODE;
  23417. +
  23418. +#define MV_CESA_MAC_MODE_OFFSET 4
  23419. +#define MV_CESA_MAC_MODE_MASK (0x7 << MV_CESA_MAC_MODE_OFFSET)
  23420. +
  23421. +typedef enum
  23422. +{
  23423. + MV_CESA_MAC_DIGEST_FULL = 0,
  23424. + MV_CESA_MAC_DIGEST_96B = 1,
  23425. +
  23426. +} MV_CESA_MAC_DIGEST_SIZE;
  23427. +
  23428. +#define MV_CESA_MAC_DIGEST_SIZE_BIT 7
  23429. +#define MV_CESA_MAC_DIGEST_SIZE_MASK (1 << MV_CESA_MAC_DIGEST_SIZE_BIT)
  23430. +
  23431. +
  23432. +typedef enum
  23433. +{
  23434. + MV_CESA_CRYPTO_NULL = 0,
  23435. + MV_CESA_CRYPTO_DES = 1,
  23436. + MV_CESA_CRYPTO_3DES = 2,
  23437. + MV_CESA_CRYPTO_AES = 3,
  23438. +
  23439. +} MV_CESA_CRYPTO_ALG;
  23440. +
  23441. +#define MV_CESA_CRYPTO_ALG_OFFSET 8
  23442. +#define MV_CESA_CRYPTO_ALG_MASK (0x3 << MV_CESA_CRYPTO_ALG_OFFSET)
  23443. +
  23444. +
  23445. +/* direction */
  23446. +typedef enum
  23447. +{
  23448. + MV_CESA_DIR_ENCODE = 0,
  23449. + MV_CESA_DIR_DECODE = 1,
  23450. +
  23451. +} MV_CESA_DIRECTION;
  23452. +
  23453. +#define MV_CESA_DIRECTION_BIT 12
  23454. +#define MV_CESA_DIRECTION_MASK (1 << MV_CESA_DIRECTION_BIT)
  23455. +
  23456. +/* crypto IV mode */
  23457. +typedef enum
  23458. +{
  23459. + MV_CESA_CRYPTO_ECB = 0,
  23460. + MV_CESA_CRYPTO_CBC = 1,
  23461. +
  23462. + /* NO HW Support */
  23463. + MV_CESA_CRYPTO_CTR = 10,
  23464. +
  23465. +} MV_CESA_CRYPTO_MODE;
  23466. +
  23467. +#define MV_CESA_CRYPTO_MODE_BIT 16
  23468. +#define MV_CESA_CRYPTO_MODE_MASK (1 << MV_CESA_CRYPTO_MODE_BIT)
  23469. +
  23470. +/* 3DES mode */
  23471. +typedef enum
  23472. +{
  23473. + MV_CESA_CRYPTO_3DES_EEE = 0,
  23474. + MV_CESA_CRYPTO_3DES_EDE = 1,
  23475. +
  23476. +} MV_CESA_CRYPTO_3DES_MODE;
  23477. +
  23478. +#define MV_CESA_CRYPTO_3DES_MODE_BIT 20
  23479. +#define MV_CESA_CRYPTO_3DES_MODE_MASK (1 << MV_CESA_CRYPTO_3DES_MODE_BIT)
  23480. +
  23481. +
  23482. +/* AES Key Length */
  23483. +typedef enum
  23484. +{
  23485. + MV_CESA_CRYPTO_AES_KEY_128 = 0,
  23486. + MV_CESA_CRYPTO_AES_KEY_192 = 1,
  23487. + MV_CESA_CRYPTO_AES_KEY_256 = 2,
  23488. +
  23489. +} MV_CESA_CRYPTO_AES_KEY_LEN;
  23490. +
  23491. +#define MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET 24
  23492. +#define MV_CESA_CRYPTO_AES_KEY_LEN_MASK (0x3 << MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET)
  23493. +
  23494. +/* Fragmentation mode */
  23495. +typedef enum
  23496. +{
  23497. + MV_CESA_FRAG_NONE = 0,
  23498. + MV_CESA_FRAG_FIRST = 1,
  23499. + MV_CESA_FRAG_LAST = 2,
  23500. + MV_CESA_FRAG_MIDDLE = 3,
  23501. +
  23502. +} MV_CESA_FRAG_MODE;
  23503. +
  23504. +#define MV_CESA_FRAG_MODE_OFFSET 30
  23505. +#define MV_CESA_FRAG_MODE_MASK (0x3 << MV_CESA_FRAG_MODE_OFFSET)
  23506. +/*---------------------------------------------------------------------------*/
  23507. +
  23508. +/********** Security Accelerator Command Register **************/
  23509. +#define MV_CESA_CMD_REG (MV_CESA_REG_BASE + 0xE00)
  23510. +
  23511. +#define MV_CESA_CMD_CHAN_ENABLE_BIT 0
  23512. +#define MV_CESA_CMD_CHAN_ENABLE_MASK (1 << MV_CESA_CMD_CHAN_ENABLE_BIT)
  23513. +
  23514. +#define MV_CESA_CMD_CHAN_DISABLE_BIT 2
  23515. +#define MV_CESA_CMD_CHAN_DISABLE_MASK (1 << MV_CESA_CMD_CHAN_DISABLE_BIT)
  23516. +
  23517. +/********** Security Accelerator Descriptor Pointers Register **********/
  23518. +#define MV_CESA_CHAN_DESC_OFFSET_REG (MV_CESA_REG_BASE + 0xE04)
  23519. +
  23520. +/********** Security Accelerator Configuration Register **********/
  23521. +#define MV_CESA_CFG_REG (MV_CESA_REG_BASE + 0xE08)
  23522. +
  23523. +#define MV_CESA_CFG_STOP_DIGEST_ERR_BIT 0
  23524. +#define MV_CESA_CFG_STOP_DIGEST_ERR_MASK (1 << MV_CESA_CFG_STOP_DIGEST_ERR_BIT)
  23525. +
  23526. +#define MV_CESA_CFG_WAIT_DMA_BIT 7
  23527. +#define MV_CESA_CFG_WAIT_DMA_MASK (1 << MV_CESA_CFG_WAIT_DMA_BIT)
  23528. +
  23529. +#define MV_CESA_CFG_ACT_DMA_BIT 9
  23530. +#define MV_CESA_CFG_ACT_DMA_MASK (1 << MV_CESA_CFG_ACT_DMA_BIT)
  23531. +
  23532. +#define MV_CESA_CFG_CHAIN_MODE_BIT 11
  23533. +#define MV_CESA_CFG_CHAIN_MODE_MASK (1 << MV_CESA_CFG_CHAIN_MODE_BIT)
  23534. +
  23535. +/********** Security Accelerator Status Register ***********/
  23536. +#define MV_CESA_STATUS_REG (MV_CESA_REG_BASE + 0xE0C)
  23537. +
  23538. +#define MV_CESA_STATUS_ACTIVE_BIT 0
  23539. +#define MV_CESA_STATUS_ACTIVE_MASK (1 << MV_CESA_STATUS_ACTIVE_BIT)
  23540. +
  23541. +#define MV_CESA_STATUS_DIGEST_ERR_BIT 8
  23542. +#define MV_CESA_STATUS_DIGEST_ERR_MASK (1 << MV_CESA_STATUS_DIGEST_ERR_BIT)
  23543. +
  23544. +
  23545. +/* Cryptographic Engines and Security Accelerator Interrupt Cause Register */
  23546. +#define MV_CESA_ISR_CAUSE_REG (MV_CESA_REG_BASE + 0xE20)
  23547. +
  23548. +/* Cryptographic Engines and Security Accelerator Interrupt Mask Register */
  23549. +#define MV_CESA_ISR_MASK_REG (MV_CESA_REG_BASE + 0xE24)
  23550. +
  23551. +#define MV_CESA_CAUSE_AUTH_MASK (1 << 0)
  23552. +#define MV_CESA_CAUSE_DES_MASK (1 << 1)
  23553. +#define MV_CESA_CAUSE_AES_ENCR_MASK (1 << 2)
  23554. +#define MV_CESA_CAUSE_AES_DECR_MASK (1 << 3)
  23555. +#define MV_CESA_CAUSE_DES_ALL_MASK (1 << 4)
  23556. +
  23557. +#define MV_CESA_CAUSE_ACC_BIT 5
  23558. +#define MV_CESA_CAUSE_ACC_MASK (1 << MV_CESA_CAUSE_ACC_BIT)
  23559. +
  23560. +#define MV_CESA_CAUSE_ACC_DMA_BIT 7
  23561. +#define MV_CESA_CAUSE_ACC_DMA_MASK (1 << MV_CESA_CAUSE_ACC_DMA_BIT)
  23562. +#define MV_CESA_CAUSE_ACC_DMA_ALL_MASK (3 << MV_CESA_CAUSE_ACC_DMA_BIT)
  23563. +
  23564. +#define MV_CESA_CAUSE_DMA_COMPL_BIT 9
  23565. +#define MV_CESA_CAUSE_DMA_COMPL_MASK (1 << MV_CESA_CAUSE_DMA_COMPL_BIT)
  23566. +
  23567. +#define MV_CESA_CAUSE_DMA_OWN_ERR_BIT 10
  23568. +#define MV_CESA_CAUSE_DMA_OWN_ERR_MASK (1 < MV_CESA_CAUSE_DMA_OWN_ERR_BIT)
  23569. +
  23570. +#define MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT 11
  23571. +#define MV_CESA_CAUSE_DMA_CHAIN_PKT_MASK (1 < MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT)
  23572. +
  23573. +
  23574. +#define MV_CESA_AUTH_DATA_IN_REG (MV_CESA_REG_BASE + 0xd38)
  23575. +#define MV_CESA_AUTH_BIT_COUNT_LOW_REG (MV_CESA_REG_BASE + 0xd20)
  23576. +#define MV_CESA_AUTH_BIT_COUNT_HIGH_REG (MV_CESA_REG_BASE + 0xd24)
  23577. +
  23578. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i) (MV_CESA_REG_BASE + 0xd00 + (i<<2))
  23579. +
  23580. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_A_REG (MV_CESA_REG_BASE + 0xd00)
  23581. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_B_REG (MV_CESA_REG_BASE + 0xd04)
  23582. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_C_REG (MV_CESA_REG_BASE + 0xd08)
  23583. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_D_REG (MV_CESA_REG_BASE + 0xd0c)
  23584. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_E_REG (MV_CESA_REG_BASE + 0xd10)
  23585. +#define MV_CESA_AUTH_COMMAND_REG (MV_CESA_REG_BASE + 0xd18)
  23586. +
  23587. +#define MV_CESA_AUTH_ALGORITHM_BIT 0
  23588. +#define MV_CESA_AUTH_ALGORITHM_MD5 (0<<AUTH_ALGORITHM_BIT)
  23589. +#define MV_CESA_AUTH_ALGORITHM_SHA1 (1<<AUTH_ALGORITHM_BIT)
  23590. +
  23591. +#define MV_CESA_AUTH_IV_MODE_BIT 1
  23592. +#define MV_CESA_AUTH_IV_MODE_INIT (0<<AUTH_IV_MODE_BIT)
  23593. +#define MV_CESA_AUTH_IV_MODE_CONTINUE (1<<AUTH_IV_MODE_BIT)
  23594. +
  23595. +#define MV_CESA_AUTH_DATA_BYTE_SWAP_BIT 2
  23596. +#define MV_CESA_AUTH_DATA_BYTE_SWAP_MASK (1<<AUTH_DATA_BYTE_SWAP_BIT)
  23597. +
  23598. +
  23599. +#define MV_CESA_AUTH_IV_BYTE_SWAP_BIT 4
  23600. +#define MV_CESA_AUTH_IV_BYTE_SWAP_MASK (1<<AUTH_IV_BYTE_SWAP_BIT)
  23601. +
  23602. +#define MV_CESA_AUTH_TERMINATION_BIT 31
  23603. +#define MV_CESA_AUTH_TERMINATION_MASK (1<<AUTH_TERMINATION_BIT)
  23604. +
  23605. +
  23606. +/*************** TDMA Control Register ************************************************/
  23607. +#define MV_CESA_TDMA_CTRL_REG (MV_CESA_TDMA_REG_BASE + 0x840)
  23608. +
  23609. +#define MV_CESA_TDMA_BURST_32B 3
  23610. +#define MV_CESA_TDMA_BURST_128B 4
  23611. +
  23612. +#define MV_CESA_TDMA_DST_BURST_OFFSET 0
  23613. +#define MV_CESA_TDMA_DST_BURST_ALL_MASK (0x7<<MV_CESA_TDMA_DST_BURST_OFFSET)
  23614. +#define MV_CESA_TDMA_DST_BURST_MASK(burst) ((burst)<<MV_CESA_TDMA_DST_BURST_OFFSET)
  23615. +
  23616. +#define MV_CESA_TDMA_OUTSTAND_READ_EN_BIT 4
  23617. +#define MV_CESA_TDMA_OUTSTAND_READ_EN_MASK (1<<MV_CESA_TDMA_OUTSTAND_READ_EN_BIT)
  23618. +
  23619. +#define MV_CESA_TDMA_SRC_BURST_OFFSET 6
  23620. +#define MV_CESA_TDMA_SRC_BURST_ALL_MASK (0x7<<MV_CESA_TDMA_SRC_BURST_OFFSET)
  23621. +#define MV_CESA_TDMA_SRC_BURST_MASK(burst) ((burst)<<MV_CESA_TDMA_SRC_BURST_OFFSET)
  23622. +
  23623. +#define MV_CESA_TDMA_CHAIN_MODE_BIT 9
  23624. +#define MV_CESA_TDMA_NON_CHAIN_MODE_MASK (1<<MV_CESA_TDMA_CHAIN_MODE_BIT)
  23625. +
  23626. +#define MV_CESA_TDMA_BYTE_SWAP_BIT 11
  23627. +#define MV_CESA_TDMA_BYTE_SWAP_MASK (0 << MV_CESA_TDMA_BYTE_SWAP_BIT)
  23628. +#define MV_CESA_TDMA_NO_BYTE_SWAP_MASK (1 << MV_CESA_TDMA_BYTE_SWAP_BIT)
  23629. +
  23630. +#define MV_CESA_TDMA_ENABLE_BIT 12
  23631. +#define MV_CESA_TDMA_ENABLE_MASK (1<<MV_CESA_TDMA_ENABLE_BIT)
  23632. +
  23633. +#define MV_CESA_TDMA_FETCH_NEXT_DESC_BIT 13
  23634. +#define MV_CESA_TDMA_FETCH_NEXT_DESC_MASK (1<<MV_CESA_TDMA_FETCH_NEXT_DESC_BIT)
  23635. +
  23636. +#define MV_CESA_TDMA_CHAN_ACTIVE_BIT 14
  23637. +#define MV_CESA_TDMA_CHAN_ACTIVE_MASK (1<<MV_CESA_TDMA_CHAN_ACTIVE_BIT)
  23638. +/*------------------------------------------------------------------------------------*/
  23639. +
  23640. +#define MV_CESA_TDMA_BYTE_COUNT_REG (MV_CESA_TDMA_REG_BASE + 0x800)
  23641. +#define MV_CESA_TDMA_SRC_ADDR_REG (MV_CESA_TDMA_REG_BASE + 0x810)
  23642. +#define MV_CESA_TDMA_DST_ADDR_REG (MV_CESA_TDMA_REG_BASE + 0x820)
  23643. +#define MV_CESA_TDMA_NEXT_DESC_PTR_REG (MV_CESA_TDMA_REG_BASE + 0x830)
  23644. +#define MV_CESA_TDMA_CURR_DESC_PTR_REG (MV_CESA_TDMA_REG_BASE + 0x870)
  23645. +
  23646. +#define MV_CESA_TDMA_ERROR_CAUSE_REG (MV_CESA_TDMA_REG_BASE + 0x8C0)
  23647. +#define MV_CESA_TDMA_ERROR_MASK_REG (MV_CESA_TDMA_REG_BASE + 0x8C4)
  23648. +
  23649. +
  23650. +#endif /* __mvCesaRegs_h__ */
  23651. +
  23652. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaTest.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaTest.c
  23653. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaTest.c 1970-01-01 01:00:00.000000000 +0100
  23654. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaTest.c 2010-11-09 20:28:05.782495527 +0100
  23655. @@ -0,0 +1,3096 @@
  23656. +/*******************************************************************************
  23657. +Copyright (C) Marvell International Ltd. and its affiliates
  23658. +
  23659. +This software file (the "File") is owned and distributed by Marvell
  23660. +International Ltd. and/or its affiliates ("Marvell") under the following
  23661. +alternative licensing terms. Once you have made an election to distribute the
  23662. +File under one of the following license alternatives, please (i) delete this
  23663. +introductory statement regarding license alternatives, (ii) delete the two
  23664. +license alternatives that you have not elected to use and (iii) preserve the
  23665. +Marvell copyright notice above.
  23666. +
  23667. +********************************************************************************
  23668. +Marvell Commercial License Option
  23669. +
  23670. +If you received this File from Marvell and you have entered into a commercial
  23671. +license agreement (a "Commercial License") with Marvell, the File is licensed
  23672. +to you under the terms of the applicable Commercial License.
  23673. +
  23674. +********************************************************************************
  23675. +Marvell GPL License Option
  23676. +
  23677. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23678. +modify this File in accordance with the terms and conditions of the General
  23679. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  23680. +available along with the File in the license.txt file or by writing to the Free
  23681. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  23682. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  23683. +
  23684. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  23685. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  23686. +DISCLAIMED. The GPL License provides additional details about this warranty
  23687. +disclaimer.
  23688. +********************************************************************************
  23689. +Marvell BSD License Option
  23690. +
  23691. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23692. +modify this File under the following licensing terms.
  23693. +Redistribution and use in source and binary forms, with or without modification,
  23694. +are permitted provided that the following conditions are met:
  23695. +
  23696. + * Redistributions of source code must retain the above copyright notice,
  23697. + this list of conditions and the following disclaimer.
  23698. +
  23699. + * Redistributions in binary form must reproduce the above copyright
  23700. + notice, this list of conditions and the following disclaimer in the
  23701. + documentation and/or other materials provided with the distribution.
  23702. +
  23703. + * Neither the name of Marvell nor the names of its contributors may be
  23704. + used to endorse or promote products derived from this software without
  23705. + specific prior written permission.
  23706. +
  23707. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  23708. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23709. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23710. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  23711. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23712. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23713. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  23714. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23715. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23716. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23717. +
  23718. +*******************************************************************************/
  23719. +
  23720. +#include "mvOs.h"
  23721. +
  23722. +#if defined(MV_VXWORKS)
  23723. +
  23724. +#include "sysLib.h"
  23725. +#include "logLib.h"
  23726. +#include "tickLib.h"
  23727. +#include "intLib.h"
  23728. +#include "config.h"
  23729. +
  23730. +
  23731. +SEM_ID cesaSemId = NULL;
  23732. +SEM_ID cesaWaitSemId = NULL;
  23733. +
  23734. +#define CESA_TEST_LOCK(flags) flags = intLock()
  23735. +#define CESA_TEST_UNLOCK(flags) intUnlock(flags)
  23736. +
  23737. +#define CESA_TEST_WAIT_INIT() cesaWaitSemId = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)
  23738. +#define CESA_TEST_WAKE_UP() semGive(cesaWaitSemId)
  23739. +#define CESA_TEST_WAIT(cond, ms) semTake(cesaWaitSemId, (sysClkRateGet()*ms)/1000)
  23740. +
  23741. +#define CESA_TEST_TICK_GET() tickGet()
  23742. +#define CESA_TEST_TICK_TO_MS(tick) (((tick)*1000)/sysClkRateGet())
  23743. +
  23744. +#elif defined(MV_LINUX)
  23745. +
  23746. +#include <linux/wait.h>
  23747. +wait_queue_head_t cesaTest_waitq;
  23748. +spinlock_t cesaLock;
  23749. +
  23750. +#define CESA_TEST_LOCK(flags) spin_lock_irqsave( &cesaLock, flags)
  23751. +#define CESA_TEST_UNLOCK(flags) spin_unlock_irqrestore( &cesaLock, flags);
  23752. +
  23753. +#define CESA_TEST_WAIT_INIT() init_waitqueue_head(&cesaTest_waitq)
  23754. +#define CESA_TEST_WAKE_UP() wake_up(&cesaTest_waitq)
  23755. +#define CESA_TEST_WAIT(cond, ms) wait_event_timeout(cesaTest_waitq, (cond), msecs_to_jiffies(ms))
  23756. +
  23757. +#define CESA_TEST_TICK_GET() jiffies
  23758. +#define CESA_TEST_TICK_TO_MS(tick) jiffies_to_msecs(tick)
  23759. +
  23760. +#elif defined(MV_NETBSD)
  23761. +
  23762. +#include <sys/param.h>
  23763. +#include <sys/kernel.h>
  23764. +static int cesaLock;
  23765. +
  23766. +#define CESA_TEST_LOCK(flags) flags = splnet()
  23767. +#define CESA_TEST_UNLOCK(flags) splx(flags)
  23768. +
  23769. +#define CESA_TEST_WAIT_INIT() /* nothing */
  23770. +#define CESA_TEST_WAKE_UP() wakeup(&cesaLock)
  23771. +#define CESA_TEST_WAIT(cond, ms) \
  23772. +do { \
  23773. + while (!(cond)) \
  23774. + tsleep(&cesaLock, PWAIT, "cesatest",mstohz(ms)); \
  23775. +} while (/*CONSTCOND*/0)
  23776. +
  23777. +#define CESA_TEST_TICK_GET() hardclock_ticks
  23778. +#define CESA_TEST_TICK_TO_MS(tick) ((1000/hz)*(tick))
  23779. +
  23780. +#define request_irq(i,h,t,n,a) \
  23781. + !mv_intr_establish((i),IPL_NET,(int(*)(void *))(h),(a))
  23782. +
  23783. +#else
  23784. +#error "Only Linux, VxWorks, or NetBSD OS are supported"
  23785. +#endif
  23786. +
  23787. +#include "mvDebug.h"
  23788. +
  23789. +#include "mvSysHwConfig.h"
  23790. +#include "boardEnv/mvBoardEnvLib.h"
  23791. +#include "ctrlEnv/sys/mvCpuIf.h"
  23792. +#include "cntmr/mvCntmr.h"
  23793. +#include "cesa/mvCesa.h"
  23794. +#include "cesa/mvCesaRegs.h"
  23795. +#include "cesa/mvMD5.h"
  23796. +#include "cesa/mvSHA1.h"
  23797. +
  23798. +#if defined(CONFIG_MV646xx)
  23799. +#include "marvell_pic.h"
  23800. +#endif
  23801. +
  23802. +#define MV_CESA_USE_TIMER_ID 0
  23803. +#define CESA_DEF_BUF_SIZE 1500
  23804. +#define CESA_DEF_BUF_NUM 1
  23805. +#define CESA_DEF_SESSION_NUM 32
  23806. +
  23807. +#define CESA_DEF_ITER_NUM 100
  23808. +
  23809. +#define CESA_DEF_REQ_SIZE 256
  23810. +
  23811. +
  23812. +/* CESA Tests Debug */
  23813. +#undef CESA_TEST_DEBUG
  23814. +
  23815. +#ifdef CESA_TEST_DEBUG
  23816. +
  23817. +# define CESA_TEST_DEBUG_PRINT(msg) mvOsPrintf msg
  23818. +# define CESA_TEST_DEBUG_CODE(code) code
  23819. +
  23820. +typedef struct
  23821. +{
  23822. + int type; /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */
  23823. + MV_U32 timeStamp;
  23824. + MV_U32 cause;
  23825. + MV_U32 realCause;
  23826. + MV_U32 dmaCause;
  23827. + int resources;
  23828. + MV_CESA_REQ* pReqReady;
  23829. + MV_CESA_REQ* pReqEmpty;
  23830. + MV_CESA_REQ* pReqProcess;
  23831. +} MV_CESA_TEST_TRACE;
  23832. +
  23833. +#define MV_CESA_TEST_TRACE_SIZE 25
  23834. +
  23835. +static int cesaTestTraceIdx = 0;
  23836. +static MV_CESA_TEST_TRACE cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];
  23837. +
  23838. +static void cesaTestTraceAdd(int type, MV_U32 cause)
  23839. +{
  23840. + cesaTestTrace[cesaTestTraceIdx].type = type;
  23841. + cesaTestTrace[cesaTestTraceIdx].cause = cause;
  23842. + cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  23843. + cesaTestTrace[cesaTestTraceIdx].dmaCause = MV_REG_READ(IDMA_CAUSE_REG);
  23844. + cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;
  23845. + cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;
  23846. + cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;
  23847. + cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;
  23848. + cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);
  23849. + cesaTestTraceIdx++;
  23850. + if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)
  23851. + cesaTestTraceIdx = 0;
  23852. +}
  23853. +
  23854. +#else
  23855. +
  23856. +# define CESA_TEST_DEBUG_PRINT(msg)
  23857. +# define CESA_TEST_DEBUG_CODE(code)
  23858. +
  23859. +#endif /* CESA_TEST_DEBUG */
  23860. +
  23861. +int cesaExpReqId=0;
  23862. +int cesaCbIter=0;
  23863. +
  23864. +int cesaIdx;
  23865. +int cesaIteration;
  23866. +int cesaRateSize;
  23867. +int cesaReqSize;
  23868. +unsigned long cesaTaskId;
  23869. +int cesaBufNum;
  23870. +int cesaBufSize;
  23871. +int cesaCheckOffset;
  23872. +int cesaCheckSize;
  23873. +int cesaCheckMode;
  23874. +int cesaTestIdx;
  23875. +int cesaCaseIdx;
  23876. +
  23877. +
  23878. +MV_U32 cesaTestIsrCount = 0;
  23879. +MV_U32 cesaTestIsrMissCount = 0;
  23880. +
  23881. +MV_U32 cesaCryptoError = 0;
  23882. +MV_U32 cesaReqIdError = 0;
  23883. +MV_U32 cesaError = 0;
  23884. +
  23885. +char* cesaHexBuffer = NULL;
  23886. +
  23887. +char* cesaBinBuffer = NULL;
  23888. +char* cesaExpBinBuffer = NULL;
  23889. +
  23890. +char* cesaInputHexStr = NULL;
  23891. +char* cesaOutputHexStr = NULL;
  23892. +
  23893. +MV_BUF_INFO cesaReqBufs[CESA_DEF_REQ_SIZE];
  23894. +
  23895. +MV_CESA_COMMAND* cesaCmdRing;
  23896. +MV_CESA_RESULT cesaResult;
  23897. +
  23898. +int cesaTestFull = 0;
  23899. +
  23900. +MV_BOOL cesaIsReady = MV_FALSE;
  23901. +MV_U32 cesaCycles = 0;
  23902. +MV_U32 cesaBeginTicks = 0;
  23903. +MV_U32 cesaEndTicks = 0;
  23904. +MV_U32 cesaRate = 0;
  23905. +MV_U32 cesaRateAfterDot = 0;
  23906. +
  23907. +void *cesaTestOSHandle = NULL;
  23908. +
  23909. +enum
  23910. +{
  23911. + CESA_FAST_CHECK_MODE = 0,
  23912. + CESA_FULL_CHECK_MODE,
  23913. + CESA_NULL_CHECK_MODE,
  23914. + CESA_SHOW_CHECK_MODE,
  23915. + CESA_SW_SHOW_CHECK_MODE,
  23916. + CESA_SW_NULL_CHECK_MODE,
  23917. +
  23918. + CESA_MAX_CHECK_MODE
  23919. +};
  23920. +
  23921. +enum
  23922. +{
  23923. + DES_TEST_TYPE = 0,
  23924. + TRIPLE_DES_TEST_TYPE = 1,
  23925. + AES_TEST_TYPE = 2,
  23926. + MD5_TEST_TYPE = 3,
  23927. + SHA_TEST_TYPE = 4,
  23928. + COMBINED_TEST_TYPE = 5,
  23929. +
  23930. + MAX_TEST_TYPE
  23931. +};
  23932. +
  23933. +/* Tests data base */
  23934. +typedef struct
  23935. +{
  23936. + short sid;
  23937. + char cryptoAlgorithm; /* DES/3DES/AES */
  23938. + char cryptoMode; /* ECB or CBC */
  23939. + char macAlgorithm; /* MD5 / SHA1 */
  23940. + char operation; /* CRYPTO/HMAC/CRYPTO+HMAC/HMAC+CRYPTO */
  23941. + char direction; /* ENCODE(SIGN)/DECODE(VERIFY) */
  23942. + unsigned char* pCryptoKey;
  23943. + int cryptoKeySize;
  23944. + unsigned char* pMacKey;
  23945. + int macKeySize;
  23946. + const char* name;
  23947. +
  23948. +} MV_CESA_TEST_SESSION;
  23949. +
  23950. +typedef struct
  23951. +{
  23952. + MV_CESA_TEST_SESSION* pSessions;
  23953. + int numSessions;
  23954. +
  23955. +} MV_CESA_TEST_DB_ENTRY;
  23956. +
  23957. +typedef struct
  23958. +{
  23959. + char* plainHexStr;
  23960. + char* cipherHexStr;
  23961. + unsigned char* pCryptoIV;
  23962. + int cryptoLength;
  23963. + int macLength;
  23964. + int digestOffset;
  23965. +
  23966. +} MV_CESA_TEST_CASE;
  23967. +
  23968. +typedef struct
  23969. +{
  23970. + int size;
  23971. + const char* outputHexStr;
  23972. +
  23973. +} MV_CESA_SIZE_TEST;
  23974. +
  23975. +static unsigned char cryptoKey1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
  23976. + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
  23977. + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  23978. +
  23979. +static unsigned char cryptoKey7[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  23980. +static unsigned char iv1[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef};
  23981. +
  23982. +
  23983. +static unsigned char cryptoKey2[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  23984. + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
  23985. +
  23986. +static unsigned char cryptoKey3[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  23987. + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  23988. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
  23989. +
  23990. +static unsigned char cryptoKey4[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  23991. + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  23992. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  23993. + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
  23994. +
  23995. +static unsigned char cryptoKey5[] = {0x56, 0xe4, 0x7a, 0x38, 0xc5, 0x59, 0x89, 0x74,
  23996. + 0xbc, 0x46, 0x90, 0x3d, 0xba, 0x29, 0x03, 0x49};
  23997. +
  23998. +
  23999. +static unsigned char key3des1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
  24000. + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
  24001. + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23};
  24002. +
  24003. +/* Input ASCII string: The quick brown fox jump */
  24004. +static char plain3des1[] = "54686520717566636B2062726F776E20666F78206A756D70";
  24005. +static char cipher3des1[] = "A826FD8CE53B855FCCE21C8112256FE668D5C05DD9B6B900";
  24006. +
  24007. +static unsigned char key3des2[] = {0x62, 0x7f, 0x46, 0x0e, 0x08, 0x10, 0x4a, 0x10,
  24008. + 0x43, 0xcd, 0x26, 0x5d, 0x58, 0x40, 0xea, 0xf1,
  24009. + 0x31, 0x3e, 0xdf, 0x97, 0xdf, 0x2a, 0x8a, 0x8c};
  24010. +
  24011. +static unsigned char iv3des2[] = {0x8e, 0x29, 0xf7, 0x5e, 0xa7, 0x7e, 0x54, 0x75};
  24012. +
  24013. +static char plain3des2[] = "326a494cd33fe756";
  24014. +
  24015. +static char cipher3desCbc2[] = "8e29f75ea77e5475"
  24016. + "b22b8d66de970692";
  24017. +
  24018. +static unsigned char key3des3[] = {0x37, 0xae, 0x5e, 0xbf, 0x46, 0xdf, 0xf2, 0xdc,
  24019. + 0x07, 0x54, 0xb9, 0x4f, 0x31, 0xcb, 0xb3, 0x85,
  24020. + 0x5e, 0x7f, 0xd3, 0x6d, 0xc8, 0x70, 0xbf, 0xae};
  24021. +
  24022. +static unsigned char iv3des3[] = {0x3d, 0x1d, 0xe3, 0xcc, 0x13, 0x2e, 0x3b, 0x65};
  24023. +
  24024. +static char plain3des3[] = "84401f78fe6c10876d8ea23094ea5309";
  24025. +
  24026. +static char cipher3desCbc3[] = "3d1de3cc132e3b65"
  24027. + "7b1f7c7e3b1c948ebd04a75ffba7d2f5";
  24028. +
  24029. +static unsigned char iv5[] = {0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c,
  24030. + 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9};
  24031. +
  24032. +static unsigned char aesCtrKey[] = {0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
  24033. + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC};
  24034. +
  24035. +static unsigned char mdKey1[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  24036. + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
  24037. +
  24038. +static unsigned char mdKey2[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  24039. + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
  24040. +
  24041. +static unsigned char shaKey1[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  24042. + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  24043. + 0x0b, 0x0b, 0x0b, 0x0b};
  24044. +
  24045. +static unsigned char shaKey2[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  24046. + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  24047. + 0xaa, 0xaa, 0xaa, 0xaa};
  24048. +
  24049. +static unsigned char mdKey4[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24050. + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
  24051. +
  24052. +static unsigned char shaKey4[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24053. + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
  24054. + 0x11, 0x12, 0x13, 0x14};
  24055. +
  24056. +
  24057. +static MV_CESA_TEST_SESSION desTestSessions[] =
  24058. +{
  24059. +/*000*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  24060. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24061. + MV_CESA_DIR_ENCODE,
  24062. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  24063. + NULL, 0,
  24064. + "DES ECB encode",
  24065. + },
  24066. +/*001*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  24067. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24068. + MV_CESA_DIR_DECODE,
  24069. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  24070. + NULL, 0,
  24071. + "DES ECB decode",
  24072. + },
  24073. +/*002*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,
  24074. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24075. + MV_CESA_DIR_ENCODE,
  24076. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  24077. + NULL, 0,
  24078. + "DES CBC encode"
  24079. + },
  24080. +/*003*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,
  24081. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24082. + MV_CESA_DIR_DECODE,
  24083. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  24084. + NULL, 0,
  24085. + "DES CBC decode"
  24086. + },
  24087. +/*004*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24088. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24089. + MV_CESA_DIR_ENCODE,
  24090. + NULL, 0, NULL, 0,
  24091. + "NULL Crypto Algorithm encode"
  24092. + },
  24093. +};
  24094. +
  24095. +
  24096. +static MV_CESA_TEST_SESSION tripleDesTestSessions[] =
  24097. +{
  24098. +/*100*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  24099. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24100. + MV_CESA_DIR_ENCODE,
  24101. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24102. + NULL, 0,
  24103. + "3DES ECB encode",
  24104. + },
  24105. +/*101*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  24106. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24107. + MV_CESA_DIR_DECODE,
  24108. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24109. + NULL, 0,
  24110. + "3DES ECB decode",
  24111. + },
  24112. +/*102*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  24113. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24114. + MV_CESA_DIR_ENCODE,
  24115. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24116. + NULL, 0,
  24117. + "3DES CBC encode"
  24118. + },
  24119. +/*103*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  24120. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24121. + MV_CESA_DIR_DECODE,
  24122. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24123. + NULL, 0,
  24124. + "3DES CBC decode"
  24125. + },
  24126. +/*104*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  24127. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24128. + MV_CESA_DIR_ENCODE,
  24129. + key3des1, sizeof(key3des1),
  24130. + NULL, 0,
  24131. + "3DES ECB encode"
  24132. + },
  24133. +/*105*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  24134. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24135. + MV_CESA_DIR_ENCODE,
  24136. + key3des2, sizeof(key3des2),
  24137. + NULL, 0,
  24138. + "3DES ECB encode"
  24139. + },
  24140. +/*106*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  24141. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24142. + MV_CESA_DIR_ENCODE,
  24143. + key3des3, sizeof(key3des3),
  24144. + NULL, 0,
  24145. + "3DES ECB encode"
  24146. + },
  24147. +};
  24148. +
  24149. +
  24150. +static MV_CESA_TEST_SESSION aesTestSessions[] =
  24151. +{
  24152. +/*200*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  24153. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24154. + MV_CESA_DIR_ENCODE,
  24155. + cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),
  24156. + NULL, 0,
  24157. + "AES-128 ECB encode"
  24158. + },
  24159. +/*201*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  24160. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24161. + MV_CESA_DIR_DECODE,
  24162. + cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),
  24163. + NULL, 0,
  24164. + "AES-128 ECB decode"
  24165. + },
  24166. +/*202*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  24167. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24168. + MV_CESA_DIR_ENCODE,
  24169. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  24170. + NULL, 0,
  24171. + "AES-128 CBC encode"
  24172. + },
  24173. +/*203*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  24174. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24175. + MV_CESA_DIR_DECODE,
  24176. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  24177. + NULL, 0,
  24178. + "AES-128 CBC decode"
  24179. + },
  24180. +/*204*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  24181. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24182. + MV_CESA_DIR_ENCODE,
  24183. + cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),
  24184. + NULL, 0,
  24185. + "AES-192 ECB encode"
  24186. + },
  24187. +/*205*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  24188. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24189. + MV_CESA_DIR_DECODE,
  24190. + cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),
  24191. + NULL, 0,
  24192. + "AES-192 ECB decode"
  24193. + },
  24194. +/*206*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  24195. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24196. + MV_CESA_DIR_ENCODE,
  24197. + cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),
  24198. + NULL, 0,
  24199. + "AES-256 ECB encode"
  24200. + },
  24201. +/*207*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  24202. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24203. + MV_CESA_DIR_DECODE,
  24204. + cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),
  24205. + NULL, 0,
  24206. + "AES-256 ECB decode"
  24207. + },
  24208. +/*208*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CTR,
  24209. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24210. + MV_CESA_DIR_ENCODE,
  24211. + aesCtrKey, sizeof(aesCtrKey)/sizeof(aesCtrKey[0]),
  24212. + NULL, 0,
  24213. + "AES-128 CTR encode"
  24214. + },
  24215. +};
  24216. +
  24217. +
  24218. +static MV_CESA_TEST_SESSION md5TestSessions[] =
  24219. +{
  24220. +/*300*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24221. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  24222. + MV_CESA_DIR_ENCODE,
  24223. + NULL, 0,
  24224. + mdKey1, sizeof(mdKey1),
  24225. + "HMAC-MD5 Generate Signature"
  24226. + },
  24227. +/*301*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24228. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  24229. + MV_CESA_DIR_DECODE,
  24230. + NULL, 0,
  24231. + mdKey1, sizeof(mdKey1),
  24232. + "HMAC-MD5 Verify Signature"
  24233. + },
  24234. +/*302*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24235. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  24236. + MV_CESA_DIR_ENCODE,
  24237. + NULL, 0,
  24238. + mdKey2, sizeof(mdKey2),
  24239. + "HMAC-MD5 Generate Signature"
  24240. + },
  24241. +/*303*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24242. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  24243. + MV_CESA_DIR_DECODE,
  24244. + NULL, 0,
  24245. + mdKey2, sizeof(mdKey2),
  24246. + "HMAC-MD5 Verify Signature"
  24247. + },
  24248. +/*304*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24249. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  24250. + MV_CESA_DIR_ENCODE,
  24251. + NULL, 0,
  24252. + mdKey4, sizeof(mdKey4),
  24253. + "HMAC-MD5 Generate Signature"
  24254. + },
  24255. +/*305*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24256. + MV_CESA_MAC_MD5, MV_CESA_MAC_ONLY,
  24257. + MV_CESA_DIR_ENCODE,
  24258. + NULL, 0,
  24259. + NULL, 0,
  24260. + "HASH-MD5 Generate Signature"
  24261. + },
  24262. +};
  24263. +
  24264. +
  24265. +static MV_CESA_TEST_SESSION shaTestSessions[] =
  24266. +{
  24267. +/*400*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24268. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  24269. + MV_CESA_DIR_ENCODE,
  24270. + NULL, 0,
  24271. + shaKey1, sizeof(shaKey1),
  24272. + "HMAC-SHA1 Generate Signature"
  24273. + },
  24274. +/*401*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24275. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  24276. + MV_CESA_DIR_DECODE,
  24277. + NULL, 0,
  24278. + shaKey1, sizeof(shaKey1),
  24279. + "HMAC-SHA1 Verify Signature"
  24280. + },
  24281. +/*402*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24282. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  24283. + MV_CESA_DIR_ENCODE,
  24284. + NULL, 0,
  24285. + shaKey2, sizeof(shaKey2),
  24286. + "HMAC-SHA1 Generate Signature"
  24287. + },
  24288. +/*403*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24289. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  24290. + MV_CESA_DIR_DECODE,
  24291. + NULL, 0,
  24292. + shaKey2, sizeof(shaKey2),
  24293. + "HMAC-SHA1 Verify Signature"
  24294. + },
  24295. +/*404*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24296. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  24297. + MV_CESA_DIR_ENCODE,
  24298. + NULL, 0,
  24299. + shaKey4, sizeof(shaKey4),
  24300. + "HMAC-SHA1 Generate Signature"
  24301. + },
  24302. +/*405*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24303. + MV_CESA_MAC_SHA1, MV_CESA_MAC_ONLY,
  24304. + MV_CESA_DIR_ENCODE,
  24305. + NULL, 0,
  24306. + NULL, 0,
  24307. + "HASH-SHA1 Generate Signature"
  24308. + },
  24309. +};
  24310. +
  24311. +static MV_CESA_TEST_SESSION combinedTestSessions[] =
  24312. +{
  24313. +/*500*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  24314. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  24315. + MV_CESA_DIR_ENCODE,
  24316. + cryptoKey1, MV_CESA_DES_KEY_LENGTH,
  24317. + mdKey4, sizeof(mdKey4),
  24318. + "DES + MD5 encode"
  24319. + },
  24320. +/*501*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  24321. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  24322. + MV_CESA_DIR_ENCODE,
  24323. + cryptoKey1, MV_CESA_DES_KEY_LENGTH,
  24324. + shaKey4, sizeof(shaKey4),
  24325. + "DES + SHA1 encode"
  24326. + },
  24327. +/*502*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  24328. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  24329. + MV_CESA_DIR_ENCODE,
  24330. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24331. + mdKey4, sizeof(mdKey4),
  24332. + "3DES + MD5 encode"
  24333. + },
  24334. +/*503*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  24335. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  24336. + MV_CESA_DIR_ENCODE,
  24337. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24338. + shaKey4, sizeof(shaKey4),
  24339. + "3DES + SHA1 encode"
  24340. + },
  24341. +/*504*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  24342. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  24343. + MV_CESA_DIR_ENCODE,
  24344. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24345. + mdKey4, sizeof(mdKey4),
  24346. + "3DES CBC + MD5 encode"
  24347. + },
  24348. +/*505*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  24349. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  24350. + MV_CESA_DIR_ENCODE,
  24351. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24352. + shaKey4, sizeof(shaKey4),
  24353. + "3DES CBC + SHA1 encode"
  24354. + },
  24355. +/*506*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  24356. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  24357. + MV_CESA_DIR_ENCODE,
  24358. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  24359. + mdKey4, sizeof(mdKey4),
  24360. + "AES-128 CBC + MD5 encode"
  24361. + },
  24362. +/*507*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  24363. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  24364. + MV_CESA_DIR_ENCODE,
  24365. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  24366. + shaKey4, sizeof(shaKey4),
  24367. + "AES-128 CBC + SHA1 encode"
  24368. + },
  24369. +/*508*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  24370. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_THEN_CRYPTO,
  24371. + MV_CESA_DIR_DECODE,
  24372. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24373. + mdKey4, sizeof(mdKey4),
  24374. + "HMAC-MD5 + 3DES decode"
  24375. + },
  24376. +};
  24377. +
  24378. +
  24379. +static MV_CESA_TEST_DB_ENTRY cesaTestsDB[MAX_TEST_TYPE+1] =
  24380. +{
  24381. + { desTestSessions, sizeof(desTestSessions)/sizeof(desTestSessions[0]) },
  24382. + { tripleDesTestSessions, sizeof(tripleDesTestSessions)/sizeof(tripleDesTestSessions[0]) },
  24383. + { aesTestSessions, sizeof(aesTestSessions)/sizeof(aesTestSessions[0]) },
  24384. + { md5TestSessions, sizeof(md5TestSessions)/sizeof(md5TestSessions[0]) },
  24385. + { shaTestSessions, sizeof(shaTestSessions)/sizeof(shaTestSessions[0]) },
  24386. + { combinedTestSessions, sizeof(combinedTestSessions)/sizeof(combinedTestSessions[0]) },
  24387. + { NULL, 0 }
  24388. +};
  24389. +
  24390. +
  24391. +char cesaNullPlainHexText[] = "000000000000000000000000000000000000000000000000";
  24392. +
  24393. +char cesaPlainAsciiText[] = "Now is the time for all ";
  24394. +char cesaPlainHexEbc[] = "4e6f77206973207468652074696d6520666f7220616c6c20";
  24395. +char cesaCipherHexEcb[] = "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53";
  24396. +char cesaPlainHexCbc[] = "1234567890abcdef4e6f77206973207468652074696d6520666f7220616c6c20";
  24397. +char cesaCipherHexCbc[] = "1234567890abcdefe5c7cdde872bf27c43e934008c389c0f683788499a7c05f6";
  24398. +
  24399. +char cesaAesPlainHexEcb[] = "000102030405060708090a0b0c0d0e0f";
  24400. +char cesaAes128cipherHexEcb[] = "0a940bb5416ef045f1c39458c653ea5a";
  24401. +char cesaAes192cipherHexEcb[] = "0060bffe46834bb8da5cf9a61ff220ae";
  24402. +char cesaAes256cipherHexEcb[] = "5a6e045708fb7196f02e553d02c3a692";
  24403. +
  24404. +char cesaAsciiStr1[] = "Hi There";
  24405. +char cesaDataHexStr1[] = "4869205468657265";
  24406. +char cesaHmacMd5digestHex1[] = "9294727a3638bb1c13f48ef8158bfc9d";
  24407. +char cesaHmacSha1digestHex1[] = "b617318655057264e28bc0b6fb378c8ef146be00";
  24408. +char cesaDataAndMd5digest1[] = "48692054686572659294727a3638bb1c13f48ef8158bfc9d";
  24409. +char cesaDataAndSha1digest1[] = "4869205468657265b617318655057264e28bc0b6fb378c8ef146be00";
  24410. +
  24411. +char cesaAesPlainText[] = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
  24412. + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
  24413. + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
  24414. + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
  24415. +
  24416. +char cesaAes128CipherCbc[] = "c30e32ffedc0774e6aff6af0869f71aa"
  24417. + "0f3af07a9a31a9c684db207eb0ef8e4e"
  24418. + "35907aa632c3ffdf868bb7b29d3d46ad"
  24419. + "83ce9f9a102ee99d49a53e87f4c3da55";
  24420. +
  24421. +char cesaAesIvPlainText[] = "8ce82eefbea0da3c44699ed7db51b7d9"
  24422. + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
  24423. + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
  24424. + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
  24425. + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
  24426. +
  24427. +char cesaAes128IvCipherCbc[] = "8ce82eefbea0da3c44699ed7db51b7d9"
  24428. + "c30e32ffedc0774e6aff6af0869f71aa"
  24429. + "0f3af07a9a31a9c684db207eb0ef8e4e"
  24430. + "35907aa632c3ffdf868bb7b29d3d46ad"
  24431. + "83ce9f9a102ee99d49a53e87f4c3da55";
  24432. +
  24433. +char cesaAesCtrPlain[] = "00E0017B27777F3F4A1786F000000001"
  24434. + "000102030405060708090A0B0C0D0E0F"
  24435. + "101112131415161718191A1B1C1D1E1F"
  24436. + "20212223";
  24437. +
  24438. +char cesaAesCtrCipher[] = "00E0017B27777F3F4A1786F000000001"
  24439. + "C1CF48A89F2FFDD9CF4652E9EFDB72D7"
  24440. + "4540A42BDE6D7836D59A5CEAAEF31053"
  24441. + "25B2072F";
  24442. +
  24443. +
  24444. +
  24445. +/* Input cesaHmacHex3 is '0xdd' repeated 50 times */
  24446. +char cesaHmacMd5digestHex3[] = "56be34521d144c88dbb8c733f0e8b3f6";
  24447. +char cesaHmacSha1digestHex3[] = "125d7342b9ac11cd91a39af48aa17b4f63f175d3";
  24448. +char cesaDataHexStr3[50*2+1] = "";
  24449. +char cesaDataAndMd5digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacMd5digestHex3)+8*2+1] = "";
  24450. +char cesaDataAndSha1digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacSha1digestHex3)+8*2+1] = "";
  24451. +
  24452. +/* Ascii string is "abc" */
  24453. +char hashHexStr3[] = "616263";
  24454. +char hashMd5digest3[] = "900150983cd24fb0d6963f7d28e17f72";
  24455. +char hashSha1digest3[] = "a9993e364706816aba3e25717850c26c9cd0d89d";
  24456. +
  24457. +char hashHexStr80[] = "31323334353637383930"
  24458. + "31323334353637383930"
  24459. + "31323334353637383930"
  24460. + "31323334353637383930"
  24461. + "31323334353637383930"
  24462. + "31323334353637383930"
  24463. + "31323334353637383930"
  24464. + "31323334353637383930";
  24465. +
  24466. +char hashMd5digest80[] = "57edf4a22be3c955ac49da2e2107b67a";
  24467. +
  24468. +char tripleDesThenMd5digest80[] = "b7726a03aad490bd6c5a452a89a1b271";
  24469. +char tripleDesThenSha1digest80[] = "b2ddeaca91030eab5b95a234ef2c0f6e738ff883";
  24470. +
  24471. +char cbc3desThenMd5digest80[] = "6f463057e1a90e0e91ae505b527bcec0";
  24472. +char cbc3desThenSha1digest80[] = "1b002ed050be743aa98860cf35659646bb8efcc0";
  24473. +
  24474. +char cbcAes128ThenMd5digest80[] = "6b6e863ac5a71d15e3e9b1c86c9ba05f";
  24475. +char cbcAes128ThenSha1digest80[] = "13558472d1fc1c90dffec6e5136c7203452d509b";
  24476. +
  24477. +
  24478. +static MV_CESA_TEST_CASE cesaTestCases[] =
  24479. +{
  24480. + /* plainHexStr cipherHexStr IV crypto mac digest */
  24481. + /* Length Length Offset */
  24482. + /*0*/ { NULL, NULL, NULL, 0, 0, -1 },
  24483. + /*1*/ { cesaPlainHexEbc, cesaCipherHexEcb, NULL, 24, 0, -1 },
  24484. + /*2*/ { cesaPlainHexCbc, cesaCipherHexCbc, NULL, 24, 0, -1 },
  24485. + /*3*/ { cesaAesPlainHexEcb, cesaAes128cipherHexEcb, NULL, 16, 0, -1 },
  24486. + /*4*/ { cesaAesPlainHexEcb, cesaAes192cipherHexEcb, NULL, 16, 0, -1 },
  24487. + /*5*/ { cesaAesPlainHexEcb, cesaAes256cipherHexEcb, NULL, 16, 0, -1 },
  24488. + /*6*/ { cesaDataHexStr1, cesaHmacMd5digestHex1, NULL, 0, 8, -1 },
  24489. + /*7*/ { NULL, cesaDataAndMd5digest1, NULL, 0, 8, -1 },
  24490. + /*8*/ { cesaDataHexStr3, cesaHmacMd5digestHex3, NULL, 0, 50, -1 },
  24491. + /*9*/ { NULL, cesaDataAndMd5digest3, NULL, 0, 50, -1 },
  24492. +/*10*/ { cesaAesPlainText, cesaAes128IvCipherCbc, iv5, 64, 0, -1 },
  24493. +/*11*/ { cesaDataHexStr1, cesaHmacSha1digestHex1, NULL, 0, 8, -1 },
  24494. +/*12*/ { NULL, cesaDataAndSha1digest1, NULL, 0, 8, -1 },
  24495. +/*13*/ { cesaDataHexStr3, cesaHmacSha1digestHex3, NULL, 0, 50, -1 },
  24496. +/*14*/ { NULL, cesaDataAndSha1digest3, NULL, 0, 50, -1 },
  24497. +/*15*/ { hashHexStr3, hashMd5digest3, NULL, 0, 3, -1 },
  24498. +/*16*/ { hashHexStr3, hashSha1digest3, NULL, 0, 3, -1 },
  24499. +/*17*/ { hashHexStr80, tripleDesThenMd5digest80, NULL, 80, 80, -1 },
  24500. +/*18*/ { hashHexStr80, tripleDesThenSha1digest80, NULL, 80, 80, -1 },
  24501. +/*19*/ { hashHexStr80, cbc3desThenMd5digest80, iv1, 80, 80, -1 },
  24502. +/*20*/ { hashHexStr80, cbc3desThenSha1digest80, iv1, 80, 80, -1 },
  24503. +/*21*/ { hashHexStr80, cbcAes128ThenMd5digest80, iv5, 80, 80, -1 },
  24504. +/*22*/ { hashHexStr80, cbcAes128ThenSha1digest80, iv5, 80, 80, -1 },
  24505. +/*23*/ { cesaAesCtrPlain, cesaAesCtrCipher, NULL, 36, 0, -1 },
  24506. +/*24*/ { cesaAesIvPlainText, cesaAes128IvCipherCbc, NULL, 64, 0, -1 },
  24507. +/*25*/ { plain3des1, cipher3des1, NULL, 0, 0, -1 },
  24508. +/*26*/ { plain3des2, cipher3desCbc2, iv3des2,0, 0, -1 },
  24509. +/*27*/ { plain3des3, cipher3desCbc3, iv3des3,0, 0, -1 },
  24510. +};
  24511. +
  24512. +
  24513. +/* Key = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  24514. + * 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
  24515. + * Input 0xdd repeated "size" times
  24516. + */
  24517. +static MV_CESA_SIZE_TEST mdMultiSizeTest302[] =
  24518. +{
  24519. + { 80, "7a031a640c14a4872814930b1ef3a5b2" },
  24520. + { 512, "5488e6c5a14dc72a79f28312ca5b939b" },
  24521. + { 1000, "d00814f586a8b78a05724239d2531821" },
  24522. + { 1001, "bf07df7b7f49d3f5b5ecacd4e9e63281" },
  24523. + { 1002, "1ed4a1a802e87817a819d4e37bb4d0f7" },
  24524. + { 1003, "5972ab64a4f265ee371dac2f2f137f90" },
  24525. + { 1004, "71f95e7ec3aa7df2548e90898abdb28e" },
  24526. + { 1005, "e082790b4857fcfc266e92e59e608814" },
  24527. + { 1006, "9500f02fd8ac7fde8b10e4fece9a920d" },
  24528. + { 1336, "e42edcce57d0b75b01aa09d71427948b" },
  24529. + { 1344, "bb5454ada0deb49ba0a97ffd60f57071" },
  24530. + { 1399, "0f44d793e744b24d53f44f295082ee8c" },
  24531. + { 1400, "359de8a03a9b707928c6c60e0e8d79f1" },
  24532. + { 1401, "e913858b484cbe2b384099ea88d8855b" },
  24533. + { 1402, "d9848a164af53620e0540c1d7d87629e" },
  24534. + { 1403, "0c9ee1c2c9ef45e9b625c26cbaf3e822" },
  24535. + { 1404, "12edd4f609416e3c936170360561b064" },
  24536. + { 1405, "7fc912718a05446395345009132bf562" },
  24537. + { 1406, "882f17425e579ff0d85a91a59f308aa0" },
  24538. + { 1407, "005cae408630a2fb5db82ad9db7e59da" },
  24539. + { 1408, "64655f8b404b3fea7a3e3e609bc5088f" },
  24540. + { 1409, "4a145284a7f74e01b6bb1a0ec6a0dd80" },
  24541. + { 2048, "67caf64475650732def374ebb8bde3fd" },
  24542. + { 2049, "6c84f11f472825f7e6cd125c2981884b" },
  24543. + { 2050, "8999586754a73a99efbe4dbad2816d41" },
  24544. + { 2051, "ba6946b610e098d286bc81091659dfff" },
  24545. + { 2052, "d0afa01c92d4d13def2b024f36faed83" },
  24546. + { 3072, "61d8beac61806afa2585d74a9a0e6974" },
  24547. + { 3074, "f6501a28dcc24d1e4770505c51a87ed3" },
  24548. + { 3075, "ea4a6929be67e33e61ff475369248b73" },
  24549. + { 4048, "aa8c4d68f282a07e7385acdfa69f4bed" },
  24550. + { 4052, "afb5ed2c0e1d430ea59e59ed5ed6b18a" },
  24551. + { 4058, "9e8553f9bdd43aebe0bd729f0e600c99" },
  24552. + { 6144, "f628f3e5d183fe5cdd3a5abee39cf872" },
  24553. + { 6150, "89a3efcea9a2f25f919168ad4a1fd292" },
  24554. + { 6400, "cdd176b7fb747873efa4da5e32bdf88f" },
  24555. + { 6528, "b1d707b027354aca152c45ee559ccd3f" },
  24556. + { 8192, "c600ea4429ac47f9941f09182166e51a" },
  24557. + {16384, "16e8754bfbeb4c649218422792267a37" },
  24558. + {18432, "0fd0607521b0aa8b52219cfbe215f63e" },
  24559. + { 0, NULL },
  24560. +};
  24561. +
  24562. +/* Key = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24563. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24564. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24565. + */
  24566. +static MV_CESA_SIZE_TEST mdMultiSizeTest304[] =
  24567. +{
  24568. + { 80, "a456c4723fee6068530af5a2afa71627" },
  24569. + { 512, "f85c2a2344f5de68b432208ad13e5794" },
  24570. + { 1000, "35464d6821fd4a293a41eb84e274c8c5" },
  24571. + { 1001, "c08eedbdce60cceb54bc2d732bb32c8b" },
  24572. + { 1002, "5664f71800c011cc311cb6943339c1b8" },
  24573. + { 1003, "779c723b044c585dc7802b13e8501bdc" },
  24574. + { 1004, "55e500766a2c307bc5c5fdd15e4cacd4" },
  24575. + { 1005, "d5f978954f5c38529d1679d2b714f068" },
  24576. + { 1006, "cd3efc827ce628b7281b72172693abf9" },
  24577. + { 1336, "6f04479910785878ae6335b8d1e87edf" },
  24578. + { 1344, "b6d27b50c2bce1ba2a8e1b5cc4324368" },
  24579. + { 1399, "65f70a1d4c86e5eaeb0704c8a7816795" },
  24580. + { 1400, "3394b5adc4cb3ff98843ca260a44a88a" },
  24581. + { 1401, "3a06f3582033a66a4e57e0603ce94e74" },
  24582. + { 1402, "e4d97f5ed51edc48abfa46eeb5c31752" },
  24583. + { 1403, "3d05e40b080ee3bedf293cb87b7140e7" },
  24584. + { 1404, "8cf294fc3cd153ab18dccb2a52cbf244" },
  24585. + { 1405, "d1487bd42f6edd9b4dab316631159221" },
  24586. + { 1406, "0527123b6bf6936cf5d369dc18c6c70f" },
  24587. + { 1407, "3224a06639db70212a0cd1ae1fcc570a" },
  24588. + { 1408, "a9e13335612c0356f5e2c27086e86c43" },
  24589. + { 1409, "a86d1f37d1ed8a3552e9a4f04dceea98" },
  24590. + { 2048, "396905c9b961cd0f6152abfb69c4449c" },
  24591. + { 2049, "49f39bff85d9dcf059fadb89efc4a70f" },
  24592. + { 2050, "3a2b4823bc4d0415656550226a63e34a" },
  24593. + { 2051, "dec60580d406c782540f398ad0bcc7e0" },
  24594. + { 2052, "32f76610a14310309eb748fe025081bf" },
  24595. + { 3072, "45edc1a42bf9d708a621076b63b774da" },
  24596. + { 3074, "9be1b333fe7c0c9f835fb369dc45f778" },
  24597. + { 3075, "8c06fcac7bd0e7b7a17fd6508c09a549" },
  24598. + { 4048, "0ddaef848184bf0ad98507a10f1e90e4" },
  24599. + { 4052, "81976bcaeb274223983996c137875cb8" },
  24600. + { 4058, "0b0a7a1c82bc7cbc64d8b7cd2dc2bb22" },
  24601. + { 6144, "1c24056f52725ede2dff0d7f9fc9855f" },
  24602. + { 6150, "b7f4b65681c4e43ee68ca466ca9ca4ec" },
  24603. + { 6400, "443bbaab9f7331ddd4bf11b659cd43c8" },
  24604. + { 6528, "216f44f23047cfee03a7a64f88f9a995" },
  24605. + { 8192, "ac7a993b2cad54879dba1bde63e39097" },
  24606. + { 8320, "55ed7be9682d6c0025b3221a62088d08" },
  24607. + {16384, "c6c722087653b62007aea668277175e5" },
  24608. + {18432, "f1faca8e907872c809e14ffbd85792d6" },
  24609. + { 0, NULL },
  24610. +};
  24611. +
  24612. +/* HASH-MD5
  24613. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24614. + * repeated "size" times
  24615. + */
  24616. +static MV_CESA_SIZE_TEST mdMultiSizeTest305[] =
  24617. +{
  24618. + { 80, "57edf4a22be3c955ac49da2e2107b67a" },
  24619. + { 512, "c729ae8f0736cc377a9767a660eaa04e" },
  24620. + { 1000, "f1257a8659eb92d36fe14c6bf3852a6a" },
  24621. + { 1001, "f8a46fe8ea04fdc8c7de0e84042d3878" },
  24622. + { 1002, "da188dd67bff87d58aa3c02af2d0cc0f" },
  24623. + { 1003, "961753017feee04c9b93a8e51658a829" },
  24624. + { 1004, "dd68c4338608dcc87807a711636bf2af" },
  24625. + { 1005, "e338d567d3ce66bf69ada29658a8759b" },
  24626. + { 1006, "443c9811e8b92599b0b149e8d7ec700a" },
  24627. + { 1336, "89a98511706008ba4cbd0b4a24fa5646" },
  24628. + { 1344, "335a919805f370b9e402a62c6fe01739" },
  24629. + { 1399, "5d18d0eddcd84212fe28d812b5e80e3b" },
  24630. + { 1400, "6b695c240d2dffd0dffc99459ca76db6" },
  24631. + { 1401, "49590f61298a76719bc93a57a30136f5" },
  24632. + { 1402, "94c2999fa3ef1910a683d69b2b8476f2" },
  24633. + { 1403, "37073a02ab00ecba2645c57c228860db" },
  24634. + { 1404, "1bcd06994fce28b624f0c5fdc2dcdd2b" },
  24635. + { 1405, "11b93671a64c95079e8cf9e7cddc8b3d" },
  24636. + { 1406, "4b6695772a4c66313fa4871017d05f36" },
  24637. + { 1407, "d1539b97fbfda1c075624e958de19c5b" },
  24638. + { 1408, "b801b9b69920907cd018e8063092ede9" },
  24639. + { 1409, "b765f1406cfe78e238273ed01bbcaf7e" },
  24640. + { 2048, "1d7e2c64ac29e2b3fb4c272844ed31f5" },
  24641. + { 2049, "71d38fac49c6b1f4478d8d88447bcdd0" },
  24642. + { 2050, "141c34a5592b1bebfa731e0b23d0cdba" },
  24643. + { 2051, "c5e1853f21c59f5d6039bd13d4b380d8" },
  24644. + { 2052, "dd44a0d128b63d4b5cccd967906472d7" },
  24645. + { 3072, "37d158e33b21390822739d13db7b87fe" },
  24646. + { 3074, "aef3b209d01d39d0597fe03634bbf441" },
  24647. + { 3075, "335ffb428eabf210bada96d74d5a4012" },
  24648. + { 4048, "2434c2b43d798d2819487a886261fc64" },
  24649. + { 4052, "ac2fa84a8a33065b2e92e36432e861f8" },
  24650. + { 4058, "856781f85616c341c3533d090c1e1e84" },
  24651. + { 6144, "e5d134c652c18bf19833e115f7a82e9b" },
  24652. + { 6150, "a09a353be7795fac2401dac5601872e6" },
  24653. + { 6400, "08b9033ac6a1821398f50af75a2dbc83" },
  24654. + { 6528, "3d47aa193a8540c091e7e02f779e6751" },
  24655. + { 8192, "d3164e710c0626f6f395b38f20141cb7" },
  24656. + { 8320, "b727589d9183ff4e8491dd24466974a3" },
  24657. + {16384, "3f54d970793d2274d5b20d10a69938ac" },
  24658. + {18432, "f558511dcf81985b7a1bb57fad970531" },
  24659. + { 0, NULL },
  24660. +};
  24661. +
  24662. +
  24663. +/* Key = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  24664. + * 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
  24665. + * 0xaa, 0xaa, 0xaa, 0xaa
  24666. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24667. + */
  24668. +static MV_CESA_SIZE_TEST shaMultiSizeTest402[] =
  24669. +{
  24670. + { 80, "e812f370e659705a1649940d1f78cd7af18affd3" },
  24671. + { 512, "e547f886b2c15d995ed76a8a924cb408c8080f66" },
  24672. + { 1000, "239443194409f1a5342ecde1a092c8f3a3ed790a" },
  24673. + { 1001, "f278ab9a102850a9f48dc4e9e6822afe2d0c52b5" },
  24674. + { 1002, "8bcc667df5ab6ece988b3af361d09747c77f4e72" },
  24675. + { 1003, "0fae6046c7dc1d3e356b25af836f6077a363f338" },
  24676. + { 1004, "0ea48401cc92ae6bc92ae76685269cb0167fbe1a" },
  24677. + { 1005, "ecbcd7c879b295bafcd8766cbeac58cc371e31d1" },
  24678. + { 1006, "eb4a4a3d07d1e9a15e6f1ab8a9c47f243e27324c" },
  24679. + { 1336, "f5950ee1d77c10e9011d2149699c9366fe52529c" },
  24680. + { 1344, "b04263604a63c351b0b3b9cf1785b4bdba6c8838" },
  24681. + { 1399, "8cb1cff61d5b784045974a2fc69386e3b8d24218" },
  24682. + { 1400, "9bb2f3fcbeddb2b90f0be797cd647334a2816d51" },
  24683. + { 1401, "23ae462a7a0cb440f7445791079a5d75a535dd33" },
  24684. + { 1402, "832974b524a4d3f9cc2f45a3cabf5ccef65cd2aa" },
  24685. + { 1403, "d1c683742fe404c3c20d5704a5430e7832a7ec95" },
  24686. + { 1404, "867c79042e64f310628e219d8b85594cd0c7adc3" },
  24687. + { 1405, "c9d81d49d13d94358f56ccfd61af02b36c69f7c3" },
  24688. + { 1406, "0df43daab2786172f9b8d07d61f14a070cf1287a" },
  24689. + { 1407, "0fd8f3ad7f169534b274d4c66bbddd89f759e391" },
  24690. + { 1408, "3987511182b18473a564436003139b808fa46343" },
  24691. + { 1409, "ef667e063c9e9f539a8987a8d0bd3066ee85d901" },
  24692. + { 2048, "921109c99f3fedaca21727156d5f2b4460175327" },
  24693. + { 2049, "47188600dd165eb45f27c27196d3c46f4f042c1b" },
  24694. + { 2050, "8831939904009338de10e7fa670847041387807d" },
  24695. + { 2051, "2f8ebb5db2997d614e767be1050366f3641e7520" },
  24696. + { 2052, "669e51cd730dae158d3bef8adba075bd95a0d011" },
  24697. + { 3072, "cfee66cfd83abc8451af3c96c6b35a41cc6c55f5" },
  24698. + { 3074, "216ea26f02976a261b7d21a4dd3085157bedfabd" },
  24699. + { 3075, "bd612ebba021fd8e012b14c3bd60c8c5161fabc0" },
  24700. + { 4048, "c2564c1fdf2d5e9d7dde7aace2643428e90662e8" },
  24701. + { 4052, "91ce61fe924b445dfe7b5a1dcd10a27caec16df6" },
  24702. + { 4058, "db2a9be5ee8124f091c7ebd699266c5de223c164" },
  24703. + { 6144, "855109903feae2ba3a7a05a326b8a171116eb368" },
  24704. + { 6150, "37520bb3a668294d9c7b073e7e3daf8fee248a78" },
  24705. + { 6400, "60a353c841b6d2b1a05890349dad2fa33c7536b7" },
  24706. + { 6528, "9e53a43a69bb42d7c8522ca8bd632e421d5edb36" },
  24707. + { 8192, "a918cb0da862eaea0a33ee0efea50243e6b4927c" },
  24708. + { 8320, "29a5dcf55d1db29cd113fcf0572ae414f1c71329" },
  24709. + {16384, "6fb27966138e0c8d5a0d65ace817ebd53633cee1" },
  24710. + {18432, "ca09900d891c7c9ae2a559b10f63a217003341c1" },
  24711. + { 0, NULL },
  24712. +};
  24713. +
  24714. +/* Key = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24715. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24716. + * 0x11, 0x12, 0x13, 0x14
  24717. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24718. + */
  24719. +static MV_CESA_SIZE_TEST shaMultiSizeTest404[] =
  24720. +{
  24721. + { 80, "beaf20a34b06a87558d156c0949bc3957d40222e" },
  24722. + { 512, "3353955358d886bc2940a3c7f337ff7dafb59c7b" },
  24723. + { 1000, "8737a542c5e9b2b6244b757ebb69d5bd602a829f" },
  24724. + { 1001, "fd9e7582d8a5d3c9fe3b923e4e6a41b07a1eb4d4" },
  24725. + { 1002, "a146d14a6fc3c274ff600568f4d75b977989e00d" },
  24726. + { 1003, "be22601bbc027ddef2dec97d30b3dc424fd803c5" },
  24727. + { 1004, "3e71fe99b2fe2b7bfdf4dbf0c7f3da25d7ea35e7" },
  24728. + { 1005, "2c422735d7295408fddd76f5e8a83a2a8da13df3" },
  24729. + { 1006, "6d875319049314b61855101a647b9ba3313428e6" },
  24730. + { 1336, "c1631ea80bad9dc43a180712461b65a0598c711c" },
  24731. + { 1344, "816069bf91d34581005746e2e0283d0f9c7b7605" },
  24732. + { 1399, "4e139866dc61cfcb8b67ca2ebd637b3a538593af" },
  24733. + { 1400, "ff2a0f8dd2b02c5417910f6f55d33a78e081a723" },
  24734. + { 1401, "ab00c12be62336964cbce31ae97fe2a0002984d5" },
  24735. + { 1402, "61349e7f999f3a1acc56c3e9a5060a9c4a7b05b6" },
  24736. + { 1403, "3edbc0f61e435bc1317fa27d840076093fb79353" },
  24737. + { 1404, "d052c6dfdbe63d45dab23ef9893e2aa4636aca1e" },
  24738. + { 1405, "0cc16b7388d67bf0add15a31e6e6c753cfae4987" },
  24739. + { 1406, "c96ba7eaad74253c38c22101b558d2850b1d1b90" },
  24740. + { 1407, "3445428a40d2c6556e7c55797ad8d323b61a48d9" },
  24741. + { 1408, "8d6444f937a09317c89834187b8ea9b8d3a8c56b" },
  24742. + { 1409, "c700acd3ecd19014ea2bdb4d42510c467e088475" },
  24743. + { 2048, "ee27d2a0cb77470c2f496212dfd68b5bb7b04e4b" },
  24744. + { 2049, "683762d7a02983b26a6d046e6451d9cd82c25932" },
  24745. + { 2050, "0fd20f1d55a9ee18363c2a6fd54aa13aee69992f" },
  24746. + { 2051, "86c267d8cc4bc8d59090e4f8b303da960fd228b7" },
  24747. + { 2052, "452395ae05b3ec503eea34f86fc0832485ad97c1" },
  24748. + { 3072, "75198e3cfd0b9bcff2dabdf8e38e6fdaa33ca49a" },
  24749. + { 3074, "4e24785ef080141ce4aab4675986d9acea624d7c" },
  24750. + { 3075, "3a20c5978dd637ec0e809bf84f0d9ccf30bc65bf" },
  24751. + { 4048, "3c32da256be7a7554922bf5fed51b0d2d09e59ad" },
  24752. + { 4052, "fff898426ea16e54325ae391a32c6c9bce4c23c0" },
  24753. + { 4058, "c800b9e562e1c91e1310116341a3c91d37f848ec" },
  24754. + { 6144, "d91d509d0cc4376c2d05bf9a5097717a373530e6" },
  24755. + { 6150, "d957030e0f13c5df07d9eec298542d8f94a07f12" },
  24756. + { 6400, "bb745313c3d7dc17b3f955e5534ad500a1082613" },
  24757. + { 6528, "77905f80d9ca82080bbb3e5654896dabfcfd1bdb" },
  24758. + { 8192, "5237fd9a81830c974396f99f32047586612ff3c0" },
  24759. + { 8320, "57668e28d5f2dba0839518a11db0f6af3d7e08bf" },
  24760. + {16384, "62e093fde467f0748087beea32e9af97d5c61241" },
  24761. + {18432, "845fb33130c7d6ea554fd5aacb9c50cf7ccb5929" },
  24762. + { 0, NULL },
  24763. +};
  24764. +
  24765. +/* HASH-SHA1
  24766. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24767. + * repeated "size" times
  24768. + */
  24769. +static MV_CESA_SIZE_TEST shaMultiSizeTest405[] =
  24770. +{
  24771. + { 80, "50abf5706a150990a08b2c5ea40fa0e585554732" },
  24772. + { 512, "f14516a08948fa27917a974d219741a697ba0087" },
  24773. + { 1000, "0bd18c378d5788817eb4f1e5dc07d867efa5cbf4" },
  24774. + { 1001, "ca29b85c35db1b8aef83c977893a11159d1b7aa2" },
  24775. + { 1002, "d83bc973eaaedb8a31437994dabbb3304b0be086" },
  24776. + { 1003, "2cf7bbef0acd6c00536b5c58ca470df9a3a90b6c" },
  24777. + { 1004, "e4375d09b1223385a8a393066f8209acfd936a80" },
  24778. + { 1005, "1029b38043e027745d019ce1d2d68e3d8b9d8f99" },
  24779. + { 1006, "deea16dcebbd8ac137e2b984deb639b9fb5e9680" },
  24780. + { 1336, "ea031b065fff63dcfb6a41956e4777520cdbc55d" },
  24781. + { 1344, "b52096c6445e6c0a8355995c70dc36ae186c863c" },
  24782. + { 1399, "cde2f6f8379870db4b32cf17471dc828a8dbff2b" },
  24783. + { 1400, "e53ff664064bc09fe5054c650806bd42d8179518" },
  24784. + { 1401, "d1156db5ddafcace64cdb510ff0d4af9b9a8ad64" },
  24785. + { 1402, "34ede0e9a909dd84a2ae291539105c0507b958e1" },
  24786. + { 1403, "a772ca3536da77e6ad3251e4f9e1234a4d7b87c0" },
  24787. + { 1404, "29740fd2b04e7a8bfd32242db6233156ad699948" },
  24788. + { 1405, "65b17397495b70ce4865dad93bf991b74c97cce1" },
  24789. + { 1406, "a7ee89cd0754061fdb91af7ea6abad2c69d542e3" },
  24790. + { 1407, "3eebf82f7420188e23d328b7ce93580b279a5715" },
  24791. + { 1408, "e08d3363a8b9a490dfb3a4c453452b8f114deeec" },
  24792. + { 1409, "95d74df739181a4ff30b8c39e28793a36598e924" },
  24793. + { 2048, "aa40262509c2abf84aab0197f83187fc90056d91" },
  24794. + { 2049, "7dec28ef105bc313bade8d9a7cdeac58b99de5ea" },
  24795. + { 2050, "d2e30f77ec81197de20f56588a156094ecb88450" },
  24796. + { 2051, "6b22ccc874833e96551a39da0c0edcaa0d969d92" },
  24797. + { 2052, "f843141e57875cd669af58744bc60aa9ea59549c" },
  24798. + { 3072, "09c5fedeaa62c132e673cc3c608a00142273d086" },
  24799. + { 3074, "b09e95eea9c7b1b007a58accec488301901a7f3d" },
  24800. + { 3075, "e6226b77b4ada287a8c9bbcf4ed71eec5ce632dc" },
  24801. + { 4048, "e99394894f855821951ddddf5bfc628547435f5c" },
  24802. + { 4052, "32d2f1af38be9cfba6cd03d55a254d0b3e1eb382" },
  24803. + { 4058, "d906552a4f2aca3a22e1fecccbcd183d7289d0ef" },
  24804. + { 6144, "2e7f62d35a860988e1224dc0543204af19316041" },
  24805. + { 6150, "d6b89698ee133df46fec9d552fadc328aa5a1b51" },
  24806. + { 6400, "dff50e90c46853988fa3a4b4ce5dda6945aae976" },
  24807. + { 6528, "9e63ec0430b96db02d38bc78357a2f63de2ab7f8" },
  24808. + { 8192, "971eb71ed60394d5ab5abb12e88420bdd41b5992" },
  24809. + { 8320, "91606a31b46afeaac965cecf87297e791b211013" },
  24810. + {16384, "547f830a5ec1f5f170ce818f156b1002cabc7569" },
  24811. + {18432, "f16f272787f3b8d539652e4dc315af6ab4fda0ef" },
  24812. + { 0, NULL },
  24813. +};
  24814. +
  24815. +/* CryptoKey = 0x01234567, 0x89abcdef,
  24816. + * 0x01234567, 0x89abcdef,
  24817. + * 0x01234567, 0x89abcdef;
  24818. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24819. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24820. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24821. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  24822. + */
  24823. +static MV_CESA_SIZE_TEST tripleDesMdMultiSizeTest502[] =
  24824. +{
  24825. + { 64, "9586962a2aaaef28803dec2e17807a7f" },
  24826. + { 80, "b7726a03aad490bd6c5a452a89a1b271" },
  24827. + { 352, "f1ed9563aecc3c0d2766eb2bed3b4e4c" },
  24828. + { 512, "0f9decb11ab40fe86f4d4d9397bc020e" },
  24829. + { 1000, "3ba69deac12cab8ff9dff7dbd9669927" },
  24830. + { 1336, "6cf47bf1e80e03e2c1d0945bc50d37d2" },
  24831. + { 1344, "4be388dab21ceb3fa1b8d302e9b821f7" },
  24832. + { 1400, "a58b79fb21dd9bfc6ec93e3b99fb0ef1" },
  24833. + { 1408, "8bc97379fc2ac3237effcdd4f7a86528" },
  24834. + { 2048, "1339f03ab3076f25a20bc4cba16eb5bf" },
  24835. + { 3072, "731204d2d90c4b36ae41f5e1fb874288" },
  24836. + { 4048, "c028d998cfda5642547b7e1ed5ea16e4" },
  24837. + { 6144, "b1b19cd910cc51bd22992f1e59f1e068" },
  24838. + { 6400, "44e4613496ba622deb0e7cb768135a2f" },
  24839. + { 6528, "3b06b0a86f8db9cd67f9448dfcf10549" },
  24840. + { 8192, "d581780b7163138a0f412be681457d82" },
  24841. + {16384, "03b8ac05527faaf1bed03df149c65ccf" },
  24842. + {18432, "677c8a86a41dab6c5d81b85b8fb10ff6" },
  24843. + { 0, NULL },
  24844. +};
  24845. +
  24846. +
  24847. +/* CryptoKey = 0x01234567, 0x89abcdef,
  24848. + * 0x01234567, 0x89abcdef,
  24849. + * 0x01234567, 0x89abcdef;
  24850. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24851. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24852. + * 0x11, 0x12, 0x13, 0x14
  24853. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24854. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  24855. + */
  24856. +static MV_CESA_SIZE_TEST tripleDesShaMultiSizeTest503[] =
  24857. +{
  24858. + { 64, "44a1e9bcbfc1429630d9ea68b7a48b0427a684f2" },
  24859. + { 80, "b2ddeaca91030eab5b95a234ef2c0f6e738ff883" },
  24860. + { 352, "4b91864c7ff629bdff75d9726421f76705452aaf" },
  24861. + { 512, "6dd37faceeb2aa98ba74f4242ed6734a4d546af5" },
  24862. + { 1000, "463661c30300be512a9df40904f0757cde5f1141" },
  24863. + { 1336, "b931f831d9034fe59c65176400b039fe9c1f44a5" },
  24864. + { 1344, "af8866b1cd4a4887d6185bfe72470ffdfb3648e1" },
  24865. + { 1400, "49c6caf07296d5e31d2504d088bc5b20c3ee7cdb" },
  24866. + { 1408, "fcae8deedbc6ebf0763575dc7e9de075b448a0f4" },
  24867. + { 2048, "edece5012146c1faa0dd10f50b183ba5d2af58ac" },
  24868. + { 3072, "5b83625adb43a488b8d64fecf39bb766818547b7" },
  24869. + { 4048, "d2c533678d26c970293af60f14c8279dc708bfc9" },
  24870. + { 6144, "b8f67af4f991b08b725f969b049ebf813bfacc5c" },
  24871. + { 6400, "d9a6c7f746ac7a60ef2edbed2841cf851c25cfb0" },
  24872. + { 6528, "376792b8c8d18161d15579fb7829e6e3a27e9946" },
  24873. + { 8192, "d890eabdca195b34ef8724b28360cffa92ae5655" },
  24874. + {16384, "a167ee52639ec7bf19aee9c6e8f76667c14134b9" },
  24875. + {18432, "e4396ab56f67296b220985a12078f4a0e365d2cc" },
  24876. + { 0, NULL },
  24877. +};
  24878. +
  24879. +/* CryptoKey = 0x01234567, 0x89abcdef,
  24880. + * 0x01234567, 0x89abcdef,
  24881. + * 0x01234567, 0x89abcdef
  24882. + * IV = 0x12345678, 0x90abcdef
  24883. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24884. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24885. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24886. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  24887. + */
  24888. +static MV_CESA_SIZE_TEST cbc3desMdMultiSizeTest504[] =
  24889. +{
  24890. + { 64, "8d10e00802460ede0058c139ba48bd2d" },
  24891. + { 80, "6f463057e1a90e0e91ae505b527bcec0" },
  24892. + { 352, "4938d48bdf86aece2c6851e7c6079788" },
  24893. + { 512, "516705d59f3cf810ebf2a13a23a7d42e" },
  24894. + { 1000, "a5a000ee5c830e67ddc6a2d2e5644b31" },
  24895. + { 1336, "44af60087b74ed07950088efbe3b126a" },
  24896. + { 1344, "1f5b39e0577920af731dabbfcf6dfc2a" },
  24897. + { 1400, "6804ea640e29b9cd39e08bc37dbce734" },
  24898. + { 1408, "4fb436624b02516fc9d1535466574bf9" },
  24899. + { 2048, "c909b0985c423d8d86719f701e9e83db" },
  24900. + { 3072, "cfe0bc34ef97213ee3d3f8b10122db21" },
  24901. + { 4048, "03ea10b5ae4ddeb20aed6af373082ed1" },
  24902. + { 6144, "b9a0ff4f87fc14b3c2dc6f0ed0998fdf" },
  24903. + { 6400, "6995f85d9d4985dd99e974ec7dda9dd6" },
  24904. + { 6528, "bbbb548ce2fa3d58467f6a6a5168a0e6" },
  24905. + { 8192, "afe101fbe745bb449ae4f50d10801456" },
  24906. + {16384, "9741706d0b1c923340c4660ff97cacdf" },
  24907. + {18432, "b0217becb73cb8f61fd79c7ce9d023fb" },
  24908. + { 0, NULL },
  24909. +};
  24910. +
  24911. +
  24912. +/* CryptoKey = 0x01234567, 0x89abcdef,
  24913. + * 0x01234567, 0x89abcdef,
  24914. + * 0x01234567, 0x89abcdef;
  24915. + * IV = 0x12345678, 0x90abcdef
  24916. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24917. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24918. + * 0x11, 0x12, 0x13, 0x14
  24919. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24920. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  24921. + */
  24922. +static MV_CESA_SIZE_TEST cbc3desShaMultiSizeTest505[] =
  24923. +{
  24924. + { 64, "409187e5bdb0be4a7754ca3747f7433dc4f01b98" },
  24925. + { 80, "1b002ed050be743aa98860cf35659646bb8efcc0" },
  24926. + { 352, "6cbf7ebe50fa4fa6eecc19eca23f9eae553ccfff" },
  24927. + { 512, "cfb5253fb4bf72b743320c30c7e48c54965853b0" },
  24928. + { 1000, "95e04e1ca2937e7c5a9aba9e42d2bcdb8a7af21f" },
  24929. + { 1336, "3b5c1f5eee5837ebf67b83ae01405542d77a6627" },
  24930. + { 1344, "2b3d42ab25615437f98a1ee310b81d07a02badc2" },
  24931. + { 1400, "7f8687df7c1af44e4baf3c934b6cca5ab6bc993e" },
  24932. + { 1408, "473a581c5f04f7527d50793c845471ac87e86430" },
  24933. + { 2048, "e41d20cae7ebe34e6e828ed62b1e5734019037bb" },
  24934. + { 3072, "275664afd7a561d804e6b0d204e53939cde653ae" },
  24935. + { 4048, "0d220cc5b34aeeb46bbbd637dde6290b5a8285a3" },
  24936. + { 6144, "cb393ddcc8b1c206060625b7d822ef9839e67bc5" },
  24937. + { 6400, "dd3317e2a627fc04800f74a4b05bfda00fab0347" },
  24938. + { 6528, "8a74c3b2441ab3f5a7e08895cc432566219a7c41" },
  24939. + { 8192, "b8e6ef3a549ed0e005bd5b8b1a5fe6689e9711a7" },
  24940. + {16384, "55f59404008276cdac0e2ba0d193af2d40eac5ce" },
  24941. + {18432, "86ae6c4fc72369a54cce39938e2d0296cd9c6ec5" },
  24942. + { 0, NULL },
  24943. +};
  24944. +
  24945. +
  24946. +/* CryptoKey = 0x01234567, 0x89abcdef,
  24947. + * 0x01234567, 0x89abcdef,
  24948. + * 0x01234567, 0x89abcdef
  24949. + * IV = 0x12345678, 0x90abcdef
  24950. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24951. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24952. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24953. + * Note: only sizes aligned to AES block size (16 bytes) allowed
  24954. + */
  24955. +static MV_CESA_SIZE_TEST cbcAes128md5multiSizeTest506[] =
  24956. +{
  24957. + { 16, "7ca4c2ba866751598720c5c4aa0d6786" },
  24958. + { 64, "7dba7fb988e80da609b1fea7254bced8" },
  24959. + { 80, "6b6e863ac5a71d15e3e9b1c86c9ba05f" },
  24960. + { 352, "a1ceb9c2e3021002400d525187a9f38c" },
  24961. + { 512, "596c055c1c55db748379223164075641" },
  24962. + { 1008, "f920989c02f3b3603f53c99d89492377" },
  24963. + { 1344, "2e496b73759d77ed32ea222dbd2e7b41" },
  24964. + { 1408, "7178c046b3a8d772efdb6a71c4991ea4" },
  24965. + { 2048, "a917f0099c69eb94079a8421714b6aad" },
  24966. + { 3072, "693cd5033d7f5391d3c958519fa9e934" },
  24967. + { 4048, "139dca91bcff65b3c40771749052906b" },
  24968. + { 6144, "428d9cef6df4fb70a6e9b6bbe4819e55" },
  24969. + { 6400, "9c0b909e76daa811e12b1fc17000a0c4" },
  24970. + { 6528, "ad876f6297186a7be1f1b907ed860eda" },
  24971. + { 8192, "479cbbaca37dd3191ea1f3e8134a0ef4" },
  24972. + {16384, "60fda559c74f91df538100c9842f2f15" },
  24973. + {18432, "4a3eb1cba1fa45f3981270953f720c42" },
  24974. + { 0, NULL },
  24975. +};
  24976. +
  24977. +
  24978. +/* CryptoKey = 0x01234567, 0x89abcdef,
  24979. + * 0x01234567, 0x89abcdef,
  24980. + * 0x01234567, 0x89abcdef;
  24981. + * IV = 0x12345678, 0x90abcdef
  24982. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24983. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24984. + * 0x11, 0x12, 0x13, 0x14
  24985. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24986. + * Note: only sizes aligned to AES block size (16 bytes) allowed
  24987. + */
  24988. +static MV_CESA_SIZE_TEST cbcAes128sha1multiSizeTest507[] =
  24989. +{
  24990. + { 16, "9aa8dc1c45f0946daf78057fa978759c625c1fee" },
  24991. + { 64, "9f588fc1ede851e5f8b20256abc9979465ae2189" },
  24992. + { 80, "13558472d1fc1c90dffec6e5136c7203452d509b" },
  24993. + { 352, "6b93518e006cfaa1f7adb24615e7291fb0a27e06" },
  24994. + { 512, "096874951a77fbbf333e49d80c096ee2016e09bd" },
  24995. + { 1008, "696fc203c2e4b5ae0ec5d1db3f623c490bc6dbac" },
  24996. + { 1344, "79bf77509935ccd3528caaac6a5eb6481f74029b" },
  24997. + { 1408, "627f9462b95fc188e8cfa7eec15119bdc5d4fcf1" },
  24998. + { 2048, "3d50d0c005feba92fe41502d609fced9c882b4d1" },
  24999. + { 3072, "758807e5b983e3a91c06fb218fe0f73f77111e94" },
  25000. + { 4048, "ca90e85242e33f005da3504416a52098d0d31fb2" },
  25001. + { 6144, "8044c1d4fd06642dfc46990b4f18b61ef1e972cf" },
  25002. + { 6400, "166f1f4ea57409f04feba9fb1e39af0e00bd6f43" },
  25003. + { 6528, "0389016a39485d6e330f8b4215ddf718b404f7e9" },
  25004. + { 8192, "6df7ee2a8b61d6f7f860ce8dbf778f0c2a5b508b" },
  25005. + {16384, "a70a6d8dfa1f91ded621c3dbaed34162bc48783f" },
  25006. + {18432, "8dfad627922ce15df1eed10bdbed49244efa57db" },
  25007. + { 0, NULL },
  25008. +};
  25009. +
  25010. +
  25011. +void cesaTestPrintStatus(void);
  25012. +
  25013. +
  25014. +/*------------------------- LOCAL FUNCTIONs ---------------------------------*/
  25015. +MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,
  25016. + MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize);
  25017. +MV_STATUS testClose(int idx);
  25018. +MV_STATUS testOpen(int idx);
  25019. +void close_session(int sid);
  25020. +void cesaTestCheckReady(const MV_CESA_RESULT *r);
  25021. +void cesaCheckReady(MV_CESA_RESULT* r);
  25022. +void printTestResults(int idx, MV_STATUS status, int checkMode);
  25023. +void cesaLastResult(void);
  25024. +void cesaTestPrintReq(int req, int offset, int size);
  25025. +
  25026. +void cesaTestPrintStatus(void);
  25027. +void cesaTestPrintSession(int idx);
  25028. +void sizeTest(int testIdx, int iter, int checkMode);
  25029. +void multiTest(int iter, int reqSize, int checkMode);
  25030. +void oneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);
  25031. +void multiSizeTest(int idx, int iter, int checkMode, char* inputData);
  25032. +void cesaTest(int iter, int reqSize, int checkMode);
  25033. +void cesaOneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);
  25034. +void combiTest(int iter, int reqSize, int checkMode);
  25035. +void shaTest(int iter, int reqSize, int checkMode);
  25036. +void mdTest(int iter, int reqSize, int checkMode);
  25037. +void aesTest(int iter, int reqSize, int checkMode);
  25038. +void tripleDesTest(int iter, int reqSize, int checkMode);
  25039. +void desTest(int iter, int reqSize, int checkMode);
  25040. +void cesaTestStop(void);
  25041. +MV_STATUS testRun(int idx, int caseIdx, int iter,int reqSize, int checkMode);
  25042. +void cesaTestStart(int bufNum, int bufSize);
  25043. +
  25044. +
  25045. +static MV_U32 getRate(MV_U32* remainder)
  25046. +{
  25047. + MV_U32 kBits, milliSec, rate;
  25048. +
  25049. + milliSec = 0;
  25050. + if( (cesaEndTicks - cesaBeginTicks) > 0)
  25051. + {
  25052. + milliSec = CESA_TEST_TICK_TO_MS(cesaEndTicks - cesaBeginTicks);
  25053. + }
  25054. + if(milliSec == 0)
  25055. + {
  25056. + if(remainder != NULL)
  25057. + *remainder = 0;
  25058. + return 0;
  25059. + }
  25060. +
  25061. + kBits = (cesaIteration*cesaRateSize*8)/1000;
  25062. + rate = kBits/milliSec;
  25063. + if(remainder != NULL)
  25064. + *remainder = ((kBits % milliSec)*10)/milliSec;
  25065. +
  25066. + return rate;
  25067. +}
  25068. +
  25069. +static char* extractMbuf(MV_CESA_MBUF *pMbuf,
  25070. + int offset, int size, char* hexStr)
  25071. +{
  25072. + mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, size);
  25073. + mvBinToHex((const MV_U8*)cesaBinBuffer, hexStr, size);
  25074. +
  25075. + return hexStr;
  25076. +}
  25077. +
  25078. +static MV_BOOL cesaCheckMbuf(MV_CESA_MBUF *pMbuf,
  25079. + const char* hexString, int offset,
  25080. + int checkSize)
  25081. +{
  25082. + MV_BOOL isFailed = MV_FALSE;
  25083. + MV_STATUS status;
  25084. + int size = strlen(hexString)/2;
  25085. + int checkedSize = 0;
  25086. +/*
  25087. + mvOsPrintf("cesaCheckMbuf: pMbuf=%p, offset=%d, checkSize=%d, mBufSize=%d\n",
  25088. + pMbuf, offset, checkSize, pMbuf->mbufSize);
  25089. +*/
  25090. + if(pMbuf->mbufSize < (checkSize + offset))
  25091. + {
  25092. + mvOsPrintf("checkSize (%d) is too large: offset=%d, mbufSize=%d\n",
  25093. + checkSize, offset, pMbuf->mbufSize);
  25094. + return MV_TRUE;
  25095. + }
  25096. + status = mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, checkSize);
  25097. + if(status != MV_OK)
  25098. + {
  25099. + mvOsPrintf("CesaTest: Can't copy %d bytes from Mbuf=%p to checkBuf=%p\n",
  25100. + checkSize, pMbuf, cesaBinBuffer);
  25101. + return MV_TRUE;
  25102. + }
  25103. +/*
  25104. + mvDebugMemDump(cesaBinBuffer, size, 1);
  25105. +*/
  25106. + mvHexToBin(hexString, (MV_U8*)cesaExpBinBuffer, size);
  25107. +
  25108. + /* Compare buffers */
  25109. + while(checkSize > checkedSize)
  25110. + {
  25111. + size = MV_MIN(size, (checkSize - checkedSize));
  25112. + if(memcmp(cesaExpBinBuffer, &cesaBinBuffer[checkedSize], size) != 0)
  25113. + {
  25114. + mvOsPrintf("CheckMbuf failed: checkSize=%d, size=%d, checkedSize=%d\n",
  25115. + checkSize, size, checkedSize);
  25116. + mvDebugMemDump(&cesaBinBuffer[checkedSize], size, 1);
  25117. + mvDebugMemDump(cesaExpBinBuffer, size, 1);
  25118. +
  25119. + isFailed = MV_TRUE;
  25120. + break;
  25121. + }
  25122. + checkedSize += size;
  25123. + }
  25124. +
  25125. + return isFailed;
  25126. +}
  25127. +
  25128. +static MV_STATUS cesaSetMbuf(MV_CESA_MBUF *pMbuf,
  25129. + const char* hexString,
  25130. + int offset, int reqSize)
  25131. +{
  25132. + MV_STATUS status = MV_OK;
  25133. + int copySize, size = strlen(hexString)/2;
  25134. +
  25135. + mvHexToBin(hexString, (MV_U8*)cesaBinBuffer, size);
  25136. +
  25137. + copySize = 0;
  25138. + while(reqSize > copySize)
  25139. + {
  25140. + size = MV_MIN(size, (reqSize - copySize));
  25141. +
  25142. + status = mvCesaCopyToMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset+copySize, size);
  25143. + if(status != MV_OK)
  25144. + {
  25145. + mvOsPrintf("cesaSetMbuf Error: Copy %d of %d bytes to MBuf\n",
  25146. + copySize, reqSize);
  25147. + break;
  25148. + }
  25149. + copySize += size;
  25150. + }
  25151. + pMbuf->mbufSize = offset+copySize;
  25152. + return status;
  25153. +}
  25154. +
  25155. +static MV_CESA_TEST_SESSION* getTestSessionDb(int idx, int* pTestIdx)
  25156. +{
  25157. + int testIdx, dbIdx = idx/100;
  25158. +
  25159. + if(dbIdx > MAX_TEST_TYPE)
  25160. + {
  25161. + mvOsPrintf("Wrong index %d - No such test type\n", idx);
  25162. + return NULL;
  25163. + }
  25164. + testIdx = idx % 100;
  25165. +
  25166. + if(testIdx >= cesaTestsDB[dbIdx].numSessions)
  25167. + {
  25168. + mvOsPrintf("Wrong index %d - No such test\n", idx);
  25169. + return NULL;
  25170. + }
  25171. + if(pTestIdx != NULL)
  25172. + *pTestIdx = testIdx;
  25173. +
  25174. + return cesaTestsDB[dbIdx].pSessions;
  25175. +}
  25176. +
  25177. +/* Debug */
  25178. +void cesaTestPrintReq(int req, int offset, int size)
  25179. +{
  25180. + MV_CESA_MBUF* pMbuf;
  25181. +
  25182. + mvOsPrintf("cesaTestPrintReq: req=%d, offset=%d, size=%d\n",
  25183. + req, offset, size);
  25184. + mvDebugMemDump(cesaCmdRing, 128, 4);
  25185. +
  25186. + pMbuf = cesaCmdRing[req].pSrc;
  25187. + mvCesaDebugMbuf("src", pMbuf, offset,size);
  25188. + pMbuf = cesaCmdRing[req].pDst;
  25189. + mvCesaDebugMbuf("dst", pMbuf, offset, size);
  25190. +
  25191. + cesaTestPrintStatus();
  25192. +}
  25193. +
  25194. +void cesaLastResult(void)
  25195. +{
  25196. + mvOsPrintf("Last Result: ReqId = %d, SessionId = %d, rc = (%d)\n",
  25197. + (MV_U32)cesaResult.pReqPrv, cesaResult.sessionId,
  25198. + cesaResult.retCode);
  25199. +}
  25200. +
  25201. +void printTestResults(int idx, MV_STATUS status, int checkMode)
  25202. +{
  25203. + int testIdx;
  25204. + MV_CESA_TEST_SESSION* pTestSessions = getTestSessionDb(idx, &testIdx);
  25205. +
  25206. + if(pTestSessions == NULL)
  25207. + return;
  25208. +
  25209. + mvOsPrintf("%-35s %4dx%-4d : ", pTestSessions[testIdx].name,
  25210. + cesaIteration, cesaReqSize);
  25211. + if( (status == MV_OK) &&
  25212. + (cesaCryptoError == 0) &&
  25213. + (cesaError == 0) &&
  25214. + (cesaReqIdError == 0) )
  25215. + {
  25216. + mvOsPrintf("Passed, Rate=%3u.%u Mbps (%5u cpp)\n",
  25217. + cesaRate, cesaRateAfterDot, cesaEndTicks - cesaBeginTicks);
  25218. + }
  25219. + else
  25220. + {
  25221. + mvOsPrintf("Failed, Status = 0x%x\n", status);
  25222. + if(cesaCryptoError > 0)
  25223. + mvOsPrintf("cryptoError : %d\n", cesaCryptoError);
  25224. + if(cesaReqIdError > 0)
  25225. + mvOsPrintf("reqIdError : %d\n", cesaReqIdError);
  25226. + if(cesaError > 0)
  25227. + mvOsPrintf("cesaError : %d\n", cesaError);
  25228. + }
  25229. + if(cesaTestIsrMissCount > 0)
  25230. + mvOsPrintf("cesaIsrMissed : %d\n", cesaTestIsrMissCount);
  25231. +}
  25232. +
  25233. +void cesaCheckReady(MV_CESA_RESULT* r)
  25234. +{
  25235. + int reqId;
  25236. + MV_CESA_MBUF *pMbuf;
  25237. + MV_BOOL isFailed;
  25238. +
  25239. + cesaResult = *r;
  25240. + reqId = (int)cesaResult.pReqPrv;
  25241. + pMbuf = cesaCmdRing[reqId].pDst;
  25242. +
  25243. +/*
  25244. + mvOsPrintf("cesaCheckReady: reqId=%d, checkOffset=%d, checkSize=%d\n",
  25245. + reqId, cesaCheckOffset, cesaCheckSize);
  25246. +*/
  25247. + /* Check expected reqId */
  25248. + if(reqId != cesaExpReqId)
  25249. + {
  25250. + cesaReqIdError++;
  25251. +/*
  25252. + mvOsPrintf("CESA reqId Error: cbIter=%d (%d), reqId=%d, expReqId=%d\n",
  25253. + cesaCbIter, cesaIteration, reqId, cesaExpReqId);
  25254. +*/
  25255. + }
  25256. + else
  25257. + {
  25258. + if( (cesaCheckMode == CESA_FULL_CHECK_MODE) ||
  25259. + (cesaCheckMode == CESA_FAST_CHECK_MODE) )
  25260. + {
  25261. + if(cesaResult.retCode != MV_OK)
  25262. + {
  25263. + cesaError++;
  25264. +
  25265. + mvOsPrintf("CESA Error: cbIter=%d (%d), reqId=%d, rc=%d\n",
  25266. + cesaCbIter, cesaIteration, reqId, cesaResult.retCode);
  25267. + }
  25268. + else
  25269. + {
  25270. + if( (cesaCheckSize > 0) && (cesaOutputHexStr != NULL) )
  25271. + {
  25272. + /* Check expected output */
  25273. +
  25274. + isFailed = cesaCheckMbuf(pMbuf, cesaOutputHexStr, cesaCheckOffset, cesaCheckSize);
  25275. + if(isFailed)
  25276. + {
  25277. + mvOsPrintf("CESA Crypto Error: cbIter=%d (%d), reqId=%d\n",
  25278. + cesaCbIter, cesaIteration, reqId);
  25279. +
  25280. + CESA_TEST_DEBUG_PRINT(("Error: reqId=%d, reqSize=%d, checkOffset=%d, checkSize=%d\n",
  25281. + reqId, cesaReqSize, cesaCheckOffset, cesaCheckSize));
  25282. +
  25283. + CESA_TEST_DEBUG_PRINT(("Output str: %s\n", cesaOutputHexStr));
  25284. +
  25285. + CESA_TEST_DEBUG_CODE( mvCesaDebugMbuf("error", pMbuf, 0, cesaCheckOffset+cesaCheckSize) );
  25286. +
  25287. + cesaCryptoError++;
  25288. + }
  25289. + }
  25290. + }
  25291. + }
  25292. + }
  25293. + if(cesaCheckMode == CESA_SHOW_CHECK_MODE)
  25294. + {
  25295. + extractMbuf(pMbuf, cesaCheckOffset, cesaCheckSize, cesaHexBuffer);
  25296. + mvOsPrintf("%4d, %s\n", cesaCheckOffset, cesaHexBuffer);
  25297. + }
  25298. +
  25299. + cesaCbIter++;
  25300. + if(cesaCbIter >= cesaIteration)
  25301. + {
  25302. + cesaCbIter = 0;
  25303. + cesaExpReqId = 0;
  25304. + cesaIsReady = MV_TRUE;
  25305. +
  25306. + cesaEndTicks = CESA_TEST_TICK_GET();
  25307. + cesaRate = getRate(&cesaRateAfterDot);
  25308. + }
  25309. + else
  25310. + {
  25311. + cesaExpReqId = reqId + 1;
  25312. + if(cesaExpReqId == CESA_DEF_REQ_SIZE)
  25313. + cesaExpReqId = 0;
  25314. + }
  25315. +}
  25316. +
  25317. +
  25318. +#ifdef MV_NETBSD
  25319. +static int cesaTestReadyIsr(void *arg)
  25320. +#else
  25321. +#ifdef __KERNEL__
  25322. +static irqreturn_t cesaTestReadyIsr( int irq , void *dev_id)
  25323. +#endif
  25324. +#ifdef MV_VXWORKS
  25325. +void cesaTestReadyIsr(void)
  25326. +#endif
  25327. +#endif
  25328. +{
  25329. + MV_U32 cause;
  25330. + MV_STATUS status;
  25331. + MV_CESA_RESULT result;
  25332. +
  25333. + cesaTestIsrCount++;
  25334. + /* Clear cause register */
  25335. + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  25336. + if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)
  25337. + {
  25338. + mvOsPrintf("cesaTestReadyIsr: cause=0x%x\n", cause);
  25339. +#ifdef MV_NETBSD
  25340. + return 0;
  25341. +#else
  25342. +#ifdef __KERNEL__
  25343. + return 1;
  25344. +#else
  25345. + return;
  25346. +#endif
  25347. +#endif
  25348. + }
  25349. +
  25350. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  25351. +
  25352. + while(MV_TRUE)
  25353. + {
  25354. + /* Get Ready requests */
  25355. + status = mvCesaReadyGet(&result);
  25356. + if(status == MV_OK)
  25357. + cesaCheckReady(&result);
  25358. +
  25359. + break;
  25360. + }
  25361. + if( (cesaTestFull == 1) && (status != MV_BUSY) )
  25362. + {
  25363. + cesaTestFull = 0;
  25364. + CESA_TEST_WAKE_UP();
  25365. + }
  25366. +
  25367. +#ifdef __KERNEL__
  25368. + return 1;
  25369. +#endif
  25370. +}
  25371. +
  25372. +void
  25373. +cesaTestCheckReady(const MV_CESA_RESULT *r)
  25374. +{
  25375. + MV_CESA_RESULT result = *r;
  25376. +
  25377. + cesaCheckReady(&result);
  25378. +
  25379. + if (cesaTestFull == 1) {
  25380. + cesaTestFull = 0;
  25381. + CESA_TEST_WAKE_UP();
  25382. + }
  25383. +}
  25384. +
  25385. +static INLINE int open_session(MV_CESA_OPEN_SESSION* pOs)
  25386. +{
  25387. + MV_U16 sid;
  25388. + MV_STATUS status;
  25389. +
  25390. + status = mvCesaSessionOpen(pOs, (short*)&sid);
  25391. + if(status != MV_OK)
  25392. + {
  25393. + mvOsPrintf("CesaTest: Can't open new session - status = 0x%x\n",
  25394. + status);
  25395. + return -1;
  25396. + }
  25397. +
  25398. + return (int)sid;
  25399. +}
  25400. +
  25401. +void close_session(int sid)
  25402. +{
  25403. + MV_STATUS status;
  25404. +
  25405. + status = mvCesaSessionClose(sid);
  25406. + if(status != MV_OK)
  25407. + {
  25408. + mvOsPrintf("CesaTest: Can't close session %d - status = 0x%x\n",
  25409. + sid, status);
  25410. + }
  25411. +}
  25412. +
  25413. +MV_STATUS testOpen(int idx)
  25414. +{
  25415. + MV_CESA_OPEN_SESSION os;
  25416. + int sid, i, testIdx;
  25417. + MV_CESA_TEST_SESSION* pTestSession;
  25418. + MV_U16 digestSize = 0;
  25419. +
  25420. + pTestSession = getTestSessionDb(idx, &testIdx);
  25421. + if(pTestSession == NULL)
  25422. + {
  25423. + mvOsPrintf("Test %d is not exist\n", idx);
  25424. + return MV_BAD_PARAM;
  25425. + }
  25426. + pTestSession = &pTestSession[testIdx];
  25427. +
  25428. + if(pTestSession->sid != -1)
  25429. + {
  25430. + mvOsPrintf("Session for test %d already created: sid=%d\n",
  25431. + idx, pTestSession->sid);
  25432. + return MV_OK;
  25433. + }
  25434. +
  25435. + os.cryptoAlgorithm = pTestSession->cryptoAlgorithm;
  25436. + os.macMode = pTestSession->macAlgorithm;
  25437. + switch(os.macMode)
  25438. + {
  25439. + case MV_CESA_MAC_MD5:
  25440. + case MV_CESA_MAC_HMAC_MD5:
  25441. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  25442. + break;
  25443. +
  25444. + case MV_CESA_MAC_SHA1:
  25445. + case MV_CESA_MAC_HMAC_SHA1:
  25446. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  25447. + break;
  25448. +
  25449. + case MV_CESA_MAC_NULL:
  25450. + digestSize = 0;
  25451. + }
  25452. + os.cryptoMode = pTestSession->cryptoMode;
  25453. + os.direction = pTestSession->direction;
  25454. + os.operation = pTestSession->operation;
  25455. +
  25456. + for(i=0; i<pTestSession->cryptoKeySize; i++)
  25457. + os.cryptoKey[i] = pTestSession->pCryptoKey[i];
  25458. +
  25459. + os.cryptoKeyLength = pTestSession->cryptoKeySize;
  25460. +
  25461. + for(i=0; i<pTestSession->macKeySize; i++)
  25462. + os.macKey[i] = pTestSession->pMacKey[i];
  25463. +
  25464. + os.macKeyLength = pTestSession->macKeySize;
  25465. + os.digestSize = digestSize;
  25466. +
  25467. + sid = open_session(&os);
  25468. + if(sid == -1)
  25469. + {
  25470. + mvOsPrintf("Can't open session for test %d: rc=0x%x\n",
  25471. + idx, cesaResult.retCode);
  25472. + return cesaResult.retCode;
  25473. + }
  25474. + CESA_TEST_DEBUG_PRINT(("Opened session: sid = %d\n", sid));
  25475. + pTestSession->sid = sid;
  25476. + return MV_OK;
  25477. +}
  25478. +
  25479. +MV_STATUS testClose(int idx)
  25480. +{
  25481. + int testIdx;
  25482. + MV_CESA_TEST_SESSION* pTestSession;
  25483. +
  25484. + pTestSession = getTestSessionDb(idx, &testIdx);
  25485. + if(pTestSession == NULL)
  25486. + {
  25487. + mvOsPrintf("Test %d is not exist\n", idx);
  25488. + return MV_BAD_PARAM;
  25489. + }
  25490. + pTestSession = &pTestSession[testIdx];
  25491. +
  25492. + if(pTestSession->sid == -1)
  25493. + {
  25494. + mvOsPrintf("Test session %d is not opened\n", idx);
  25495. + return MV_NO_SUCH;
  25496. + }
  25497. +
  25498. + close_session(pTestSession->sid);
  25499. + pTestSession->sid = -1;
  25500. +
  25501. + return MV_OK;
  25502. +}
  25503. +
  25504. +MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,
  25505. + MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize)
  25506. +{
  25507. + int cmdReqId = 0;
  25508. + int i;
  25509. + MV_STATUS rc = MV_OK;
  25510. + char ivZeroHex[] = "0000";
  25511. +
  25512. + if(iter == 0)
  25513. + iter = CESA_DEF_ITER_NUM;
  25514. +
  25515. + if(pCmd == NULL)
  25516. + {
  25517. + mvOsPrintf("testCmd failed: pCmd=NULL\n");
  25518. + return MV_BAD_PARAM;
  25519. + }
  25520. + pCmd->sessionId = sid;
  25521. +
  25522. + cesaCryptoError = 0;
  25523. + cesaReqIdError = 0;
  25524. + cesaError = 0;
  25525. + cesaTestIsrMissCount = 0;
  25526. + cesaIsReady = MV_FALSE;
  25527. + cesaIteration = iter;
  25528. +
  25529. + if(cesaInputHexStr == NULL)
  25530. + cesaInputHexStr = cesaPlainHexEbc;
  25531. +
  25532. + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
  25533. + {
  25534. + pCmd->pSrc = (MV_CESA_MBUF*)(cesaCmdRing[i].pSrc);
  25535. + if(pIV != NULL)
  25536. + {
  25537. + /* If IV from SA - set IV in Source buffer to zeros */
  25538. + cesaSetMbuf(pCmd->pSrc, ivZeroHex, 0, pCmd->cryptoOffset);
  25539. + cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, pCmd->cryptoOffset,
  25540. + (cesaReqSize - pCmd->cryptoOffset));
  25541. + }
  25542. + else
  25543. + {
  25544. + cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, 0, cesaReqSize);
  25545. + }
  25546. + pCmd->pDst = (MV_CESA_MBUF*)(cesaCmdRing[i].pDst);
  25547. + cesaSetMbuf(pCmd->pDst, cesaNullPlainHexText, 0, cesaReqSize);
  25548. +
  25549. + memcpy(&cesaCmdRing[i], pCmd, sizeof(*pCmd));
  25550. + }
  25551. +
  25552. + if(cesaCheckMode == CESA_SW_SHOW_CHECK_MODE)
  25553. + {
  25554. + MV_U8 pDigest[MV_CESA_MAX_DIGEST_SIZE];
  25555. +
  25556. + if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)
  25557. + {
  25558. + mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);
  25559. + mvOsPrintf("SW HASH_MD5: reqSize=%d, macLength=%d\n",
  25560. + cesaReqSize, pCmd->macLength);
  25561. + mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);
  25562. + return MV_OK;
  25563. + }
  25564. + if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)
  25565. + {
  25566. + mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);
  25567. + mvOsPrintf("SW HASH_SHA1: reqSize=%d, macLength=%d\n",
  25568. + cesaReqSize, pCmd->macLength);
  25569. + mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);
  25570. + return MV_OK;
  25571. + }
  25572. + }
  25573. +
  25574. + cesaBeginTicks = CESA_TEST_TICK_GET();
  25575. + CESA_TEST_DEBUG_CODE( memset(cesaTestTrace, 0, sizeof(cesaTestTrace));
  25576. + cesaTestTraceIdx = 0;
  25577. + );
  25578. +
  25579. + if(cesaCheckMode == CESA_SW_NULL_CHECK_MODE)
  25580. + {
  25581. + volatile MV_U8 pDigest[MV_CESA_MAX_DIGEST_SIZE];
  25582. +
  25583. + for(i=0; i<iter; i++)
  25584. + {
  25585. + if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)
  25586. + {
  25587. + mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (unsigned char*)pDigest);
  25588. + }
  25589. + if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)
  25590. + {
  25591. + mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (MV_U8 *)pDigest);
  25592. + }
  25593. + }
  25594. + cesaEndTicks = CESA_TEST_TICK_GET();
  25595. + cesaRate = getRate(&cesaRateAfterDot);
  25596. + cesaIsReady = MV_TRUE;
  25597. +
  25598. + return MV_OK;
  25599. + }
  25600. +
  25601. + /*cesaTestIsrCount = 0;*/
  25602. + /*mvCesaDebugStatsClear();*/
  25603. +
  25604. +#ifndef MV_NETBSD
  25605. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  25606. +#endif
  25607. +
  25608. + for(i=0; i<iter; i++)
  25609. + {
  25610. + unsigned long flags;
  25611. +
  25612. + pCmd = &cesaCmdRing[cmdReqId];
  25613. + pCmd->pReqPrv = (void*)cmdReqId;
  25614. +
  25615. + CESA_TEST_LOCK(flags);
  25616. +
  25617. + rc = mvCesaAction(pCmd);
  25618. + if(rc == MV_NO_RESOURCE)
  25619. + cesaTestFull = 1;
  25620. +
  25621. + CESA_TEST_UNLOCK(flags);
  25622. +
  25623. + if(rc == MV_NO_RESOURCE)
  25624. + {
  25625. + CESA_TEST_LOCK(flags);
  25626. + CESA_TEST_WAIT( (cesaTestFull == 0), 100);
  25627. + CESA_TEST_UNLOCK(flags);
  25628. + if(cesaTestFull == 1)
  25629. + {
  25630. + mvOsPrintf("CESA Test timeout: i=%d, iter=%d, cesaTestFull=%d\n",
  25631. + i, iter, cesaTestFull);
  25632. + cesaTestFull = 0;
  25633. + return MV_TIMEOUT;
  25634. + }
  25635. +
  25636. + CESA_TEST_LOCK(flags);
  25637. +
  25638. + rc = mvCesaAction(pCmd);
  25639. +
  25640. + CESA_TEST_UNLOCK(flags);
  25641. + }
  25642. + if( (rc != MV_OK) && (rc != MV_NO_MORE) )
  25643. + {
  25644. + mvOsPrintf("mvCesaAction failed: rc=%d\n", rc);
  25645. + return rc;
  25646. + }
  25647. +
  25648. + cmdReqId++;
  25649. + if(cmdReqId >= CESA_DEF_REQ_SIZE)
  25650. + cmdReqId = 0;
  25651. +
  25652. +#ifdef MV_LINUX
  25653. + /* Reschedule each 16 requests */
  25654. + if( (i & 0xF) == 0)
  25655. + schedule();
  25656. +#endif
  25657. + }
  25658. + return MV_OK;
  25659. +}
  25660. +
  25661. +void cesaTestStart(int bufNum, int bufSize)
  25662. +{
  25663. + int i, j, idx;
  25664. + MV_CESA_MBUF *pMbufSrc, *pMbufDst;
  25665. + MV_BUF_INFO *pFragsSrc, *pFragsDst;
  25666. + char *pBuf;
  25667. +#ifndef MV_NETBSD
  25668. + int numOfSessions, queueDepth;
  25669. + char *pSram;
  25670. + MV_STATUS status;
  25671. + MV_CPU_DEC_WIN addrDecWin;
  25672. +#endif
  25673. +
  25674. + cesaCmdRing = mvOsMalloc(sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
  25675. + if(cesaCmdRing == NULL)
  25676. + {
  25677. + mvOsPrintf("testStart: Can't allocate %ld bytes of memory\n",
  25678. + sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
  25679. + return;
  25680. + }
  25681. + memset(cesaCmdRing, 0, sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
  25682. +
  25683. + if(bufNum == 0)
  25684. + bufNum = CESA_DEF_BUF_NUM;
  25685. +
  25686. + if(bufSize == 0)
  25687. + bufSize = CESA_DEF_BUF_SIZE;
  25688. +
  25689. + cesaBufNum = bufNum;
  25690. + cesaBufSize = bufSize;
  25691. + mvOsPrintf("CESA test started: bufNum = %d, bufSize = %d\n",
  25692. + bufNum, bufSize);
  25693. +
  25694. + cesaHexBuffer = mvOsMalloc(2*bufNum*bufSize);
  25695. + if(cesaHexBuffer == NULL)
  25696. + {
  25697. + mvOsPrintf("testStart: Can't malloc %d bytes for cesaHexBuffer.\n",
  25698. + 2*bufNum*bufSize);
  25699. + return;
  25700. + }
  25701. + memset(cesaHexBuffer, 0, (2*bufNum*bufSize));
  25702. +
  25703. + cesaBinBuffer = mvOsMalloc(bufNum*bufSize);
  25704. + if(cesaBinBuffer == NULL)
  25705. + {
  25706. + mvOsPrintf("testStart: Can't malloc %d bytes for cesaBinBuffer\n",
  25707. + bufNum*bufSize);
  25708. + return;
  25709. + }
  25710. + memset(cesaBinBuffer, 0, (bufNum*bufSize));
  25711. +
  25712. + cesaExpBinBuffer = mvOsMalloc(bufNum*bufSize);
  25713. + if(cesaExpBinBuffer == NULL)
  25714. + {
  25715. + mvOsPrintf("testStart: Can't malloc %d bytes for cesaExpBinBuffer\n",
  25716. + bufNum*bufSize);
  25717. + return;
  25718. + }
  25719. + memset(cesaExpBinBuffer, 0, (bufNum*bufSize));
  25720. +
  25721. + CESA_TEST_WAIT_INIT();
  25722. +
  25723. + pMbufSrc = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  25724. + pFragsSrc = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  25725. +
  25726. + pMbufDst = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  25727. + pFragsDst = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  25728. +
  25729. + if( (pMbufSrc == NULL) || (pFragsSrc == NULL) ||
  25730. + (pMbufDst == NULL) || (pFragsDst == NULL) )
  25731. + {
  25732. + mvOsPrintf("testStart: Can't malloc Src and Dst pMbuf and pFrags structures.\n");
  25733. + /* !!!! Dima cesaTestCleanup();*/
  25734. + return;
  25735. + }
  25736. +
  25737. + memset(pMbufSrc, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  25738. + memset(pFragsSrc, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  25739. +
  25740. + memset(pMbufDst, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  25741. + memset(pFragsDst, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  25742. +
  25743. + mvOsPrintf("Cesa Test Start: pMbufSrc=%p, pFragsSrc=%p, pMbufDst=%p, pFragsDst=%p\n",
  25744. + pMbufSrc, pFragsSrc, pMbufDst, pFragsDst);
  25745. +
  25746. + idx = 0;
  25747. + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
  25748. + {
  25749. + pBuf = mvOsIoCachedMalloc(cesaTestOSHandle,bufSize * bufNum * 2,
  25750. + &cesaReqBufs[i].bufPhysAddr,
  25751. + &cesaReqBufs[i].memHandle);
  25752. + if(pBuf == NULL)
  25753. + {
  25754. + mvOsPrintf("testStart: Can't malloc %d bytes for pBuf\n",
  25755. + bufSize * bufNum * 2);
  25756. + return;
  25757. + }
  25758. +
  25759. + memset(pBuf, 0, bufSize * bufNum * 2);
  25760. + mvOsCacheFlush(cesaTestOSHandle,pBuf, bufSize * bufNum * 2);
  25761. + if(pBuf == NULL)
  25762. + {
  25763. + mvOsPrintf("cesaTestStart: Can't allocate %d bytes for req_%d buffers\n",
  25764. + bufSize * bufNum * 2, i);
  25765. + return;
  25766. + }
  25767. +
  25768. + cesaReqBufs[i].bufVirtPtr = (MV_U8*)pBuf;
  25769. + cesaReqBufs[i].bufSize = bufSize * bufNum * 2;
  25770. +
  25771. + cesaCmdRing[i].pSrc = &pMbufSrc[i];
  25772. + cesaCmdRing[i].pSrc->pFrags = &pFragsSrc[idx];
  25773. + cesaCmdRing[i].pSrc->numFrags = bufNum;
  25774. + cesaCmdRing[i].pSrc->mbufSize = 0;
  25775. +
  25776. + cesaCmdRing[i].pDst = &pMbufDst[i];
  25777. + cesaCmdRing[i].pDst->pFrags = &pFragsDst[idx];
  25778. + cesaCmdRing[i].pDst->numFrags = bufNum;
  25779. + cesaCmdRing[i].pDst->mbufSize = 0;
  25780. +
  25781. + for(j=0; j<bufNum; j++)
  25782. + {
  25783. + cesaCmdRing[i].pSrc->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;
  25784. + cesaCmdRing[i].pSrc->pFrags[j].bufSize = bufSize;
  25785. + pBuf += bufSize;
  25786. + cesaCmdRing[i].pDst->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;
  25787. + cesaCmdRing[i].pDst->pFrags[j].bufSize = bufSize;
  25788. + pBuf += bufSize;
  25789. + }
  25790. + idx += bufNum;
  25791. + }
  25792. +
  25793. +#ifndef MV_NETBSD
  25794. + if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)
  25795. + pSram = (char*)addrDecWin.addrWin.baseLow;
  25796. + else
  25797. + {
  25798. + mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");
  25799. + return;
  25800. + }
  25801. +
  25802. +#ifdef MV_CESA_NO_SRAM
  25803. + pSram = mvOsMalloc(4*1024+8);
  25804. + if(pSram == NULL)
  25805. + {
  25806. + mvOsPrintf("CesaTest: can't allocate %d bytes for SRAM simulation\n",
  25807. + 4*1024+8);
  25808. + /* !!!! Dima cesaTestCleanup();*/
  25809. + return;
  25810. + }
  25811. + pSram = (MV_U8*)MV_ALIGN_UP((MV_U32)pSram, 8);
  25812. +#endif /* MV_CESA_NO_SRAM */
  25813. +
  25814. + numOfSessions = CESA_DEF_SESSION_NUM;
  25815. + queueDepth = CESA_DEF_REQ_SIZE - MV_CESA_MAX_CHAN;
  25816. +
  25817. + status = mvCesaInit(numOfSessions, queueDepth, pSram, NULL);
  25818. + if(status != MV_OK)
  25819. + {
  25820. + mvOsPrintf("mvCesaInit is Failed: status = 0x%x\n", status);
  25821. + /* !!!! Dima cesaTestCleanup();*/
  25822. + return;
  25823. + }
  25824. +#endif /* !MV_NETBSD */
  25825. +
  25826. + /* Prepare data for tests */
  25827. + for(i=0; i<50; i++)
  25828. + strcat((char*)cesaDataHexStr3, "dd");
  25829. +
  25830. + strcpy((char*)cesaDataAndMd5digest3, cesaDataHexStr3);
  25831. + strcpy((char*)cesaDataAndSha1digest3, cesaDataHexStr3);
  25832. +
  25833. + /* Digest must be 8 byte aligned */
  25834. + for(; i<56; i++)
  25835. + {
  25836. + strcat((char*)cesaDataAndMd5digest3, "00");
  25837. + strcat((char*)cesaDataAndSha1digest3, "00");
  25838. + }
  25839. + strcat((char*)cesaDataAndMd5digest3, cesaHmacMd5digestHex3);
  25840. + strcat((char*)cesaDataAndSha1digest3, cesaHmacSha1digestHex3);
  25841. +
  25842. +#ifndef MV_NETBSD
  25843. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  25844. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);
  25845. +#endif
  25846. +
  25847. +#ifdef MV_VXWORKS
  25848. + {
  25849. + MV_STATUS status;
  25850. +
  25851. + status = intConnect((VOIDFUNCPTR *)INT_LVL_CESA, cesaTestReadyIsr, (int)NULL);
  25852. + if (status != OK)
  25853. + {
  25854. + mvOsPrintf("CESA: Can't connect CESA (%d) interrupt, status=0x%x \n",
  25855. + INT_LVL_CESA, status);
  25856. + /* !!!! Dima cesaTestCleanup();*/
  25857. + return;
  25858. + }
  25859. + cesaSemId = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
  25860. + if(cesaSemId == NULL)
  25861. + {
  25862. + mvOsPrintf("cesaTestStart: Can't create semaphore\n");
  25863. + return;
  25864. + }
  25865. + intEnable(INT_LVL_CESA);
  25866. + }
  25867. +#endif /* MV_VXWORKS */
  25868. +
  25869. +#if !defined(MV_NETBSD) && defined(__KERNEL__)
  25870. + if( request_irq(CESA_IRQ, cesaTestReadyIsr, (SA_INTERRUPT) , "cesa_test", NULL ) )
  25871. + {
  25872. + mvOsPrintf( "cannot assign irq\n" );
  25873. + /* !!!! Dima cesaTestCleanup();*/
  25874. + return;
  25875. + }
  25876. + spin_lock_init( &cesaLock );
  25877. +#endif
  25878. +}
  25879. +
  25880. +MV_STATUS testRun(int idx, int caseIdx, int iter,
  25881. + int reqSize, int checkMode)
  25882. +{
  25883. + int testIdx, count, sid, digestSize;
  25884. + int blockSize;
  25885. + MV_CESA_TEST_SESSION* pTestSession;
  25886. + MV_CESA_COMMAND cmd;
  25887. + MV_STATUS status;
  25888. +
  25889. + memset(&cmd, 0, sizeof(cmd));
  25890. +
  25891. + pTestSession = getTestSessionDb(idx, &testIdx);
  25892. + if(pTestSession == NULL)
  25893. + {
  25894. + mvOsPrintf("Test %d is not exist\n", idx);
  25895. + return MV_BAD_PARAM;
  25896. + }
  25897. + pTestSession = &pTestSession[testIdx];
  25898. +
  25899. + sid = pTestSession->sid;
  25900. + if(sid == -1)
  25901. + {
  25902. + mvOsPrintf("Test %d is not opened\n", idx);
  25903. + return MV_BAD_STATE;
  25904. + }
  25905. + switch(pTestSession->cryptoAlgorithm)
  25906. + {
  25907. + case MV_CESA_CRYPTO_DES:
  25908. + case MV_CESA_CRYPTO_3DES:
  25909. + blockSize = MV_CESA_DES_BLOCK_SIZE;
  25910. + break;
  25911. +
  25912. + case MV_CESA_CRYPTO_AES:
  25913. + blockSize = MV_CESA_AES_BLOCK_SIZE;
  25914. + break;
  25915. +
  25916. + case MV_CESA_CRYPTO_NULL:
  25917. + blockSize = 0;
  25918. + break;
  25919. +
  25920. + default:
  25921. + mvOsPrintf("cesaTestRun: Bad CryptoAlgorithm=%d\n",
  25922. + pTestSession->cryptoAlgorithm);
  25923. + return MV_BAD_PARAM;
  25924. + }
  25925. + switch(pTestSession->macAlgorithm)
  25926. + {
  25927. + case MV_CESA_MAC_MD5:
  25928. + case MV_CESA_MAC_HMAC_MD5:
  25929. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  25930. + break;
  25931. +
  25932. + case MV_CESA_MAC_SHA1:
  25933. + case MV_CESA_MAC_HMAC_SHA1:
  25934. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  25935. + break;
  25936. + default:
  25937. + digestSize = 0;
  25938. + }
  25939. +
  25940. + if(iter == 0)
  25941. + iter = CESA_DEF_ITER_NUM;
  25942. +
  25943. + if(pTestSession->direction == MV_CESA_DIR_ENCODE)
  25944. + {
  25945. + cesaOutputHexStr = cesaTestCases[caseIdx].cipherHexStr;
  25946. + cesaInputHexStr = cesaTestCases[caseIdx].plainHexStr;
  25947. + }
  25948. + else
  25949. + {
  25950. + cesaOutputHexStr = cesaTestCases[caseIdx].plainHexStr;
  25951. + cesaInputHexStr = cesaTestCases[caseIdx].cipherHexStr;
  25952. + }
  25953. +
  25954. + cmd.sessionId = sid;
  25955. + if(checkMode == CESA_FAST_CHECK_MODE)
  25956. + {
  25957. + cmd.cryptoLength = cesaTestCases[caseIdx].cryptoLength;
  25958. + cmd.macLength = cesaTestCases[caseIdx].macLength;
  25959. + }
  25960. + else
  25961. + {
  25962. + cmd.cryptoLength = reqSize;
  25963. + cmd.macLength = reqSize;
  25964. + }
  25965. + cesaRateSize = cmd.cryptoLength;
  25966. + cesaReqSize = cmd.cryptoLength;
  25967. + cmd.cryptoOffset = 0;
  25968. + if(pTestSession->operation != MV_CESA_MAC_ONLY)
  25969. + {
  25970. + if( (pTestSession->cryptoMode == MV_CESA_CRYPTO_CBC) ||
  25971. + (pTestSession->cryptoMode == MV_CESA_CRYPTO_CTR) )
  25972. + {
  25973. + cmd.ivOffset = 0;
  25974. + cmd.cryptoOffset = blockSize;
  25975. + if(cesaTestCases[caseIdx].pCryptoIV == NULL)
  25976. + {
  25977. + cmd.ivFromUser = 1;
  25978. + }
  25979. + else
  25980. + {
  25981. + cmd.ivFromUser = 0;
  25982. + mvCesaCryptoIvSet(cesaTestCases[caseIdx].pCryptoIV, blockSize);
  25983. + }
  25984. + cesaReqSize = cmd.cryptoOffset + cmd.cryptoLength;
  25985. + }
  25986. + }
  25987. +
  25988. +/*
  25989. + mvOsPrintf("ivFromUser=%d, cryptoLength=%d, cesaReqSize=%d, cryptoOffset=%d\n",
  25990. + cmd.ivFromUser, cmd.cryptoLength, cesaReqSize, cmd.cryptoOffset);
  25991. +*/
  25992. + if(pTestSession->operation != MV_CESA_CRYPTO_ONLY)
  25993. + {
  25994. + cmd.macOffset = cmd.cryptoOffset;
  25995. +
  25996. + if(cesaTestCases[caseIdx].digestOffset == -1)
  25997. + {
  25998. + cmd.digestOffset = cmd.macOffset + cmd.macLength;
  25999. + cmd.digestOffset = MV_ALIGN_UP(cmd.digestOffset, 8);
  26000. + }
  26001. + else
  26002. + {
  26003. + cmd.digestOffset = cesaTestCases[caseIdx].digestOffset;
  26004. + }
  26005. + if( (cmd.digestOffset + digestSize) > cesaReqSize)
  26006. + cesaReqSize = cmd.digestOffset + digestSize;
  26007. + }
  26008. +
  26009. + cesaCheckMode = checkMode;
  26010. +
  26011. + if(checkMode == CESA_NULL_CHECK_MODE)
  26012. + {
  26013. + cesaCheckSize = 0;
  26014. + cesaCheckOffset = 0;
  26015. + }
  26016. + else
  26017. + {
  26018. + if(pTestSession->operation == MV_CESA_CRYPTO_ONLY)
  26019. + {
  26020. + cesaCheckOffset = 0;
  26021. + cesaCheckSize = cmd.cryptoLength;
  26022. + }
  26023. + else
  26024. + {
  26025. + cesaCheckSize = digestSize;
  26026. + cesaCheckOffset = cmd.digestOffset;
  26027. + }
  26028. + }
  26029. +/*
  26030. + mvOsPrintf("reqSize=%d, checkSize=%d, checkOffset=%d, checkMode=%d\n",
  26031. + cesaReqSize, cesaCheckSize, cesaCheckOffset, cesaCheckMode);
  26032. +
  26033. + mvOsPrintf("blockSize=%d, ivOffset=%d, ivFromUser=%d, crOffset=%d, crLength=%d\n",
  26034. + blockSize, cmd.ivOffset, cmd.ivFromUser,
  26035. + cmd.cryptoOffset, cmd.cryptoLength);
  26036. +
  26037. + mvOsPrintf("macOffset=%d, digestOffset=%d, macLength=%d\n",
  26038. + cmd.macOffset, cmd.digestOffset, cmd.macLength);
  26039. +*/
  26040. + status = testCmd(sid, iter, &cmd, pTestSession,
  26041. + cesaTestCases[caseIdx].pCryptoIV, blockSize);
  26042. +
  26043. + if(status != MV_OK)
  26044. + return status;
  26045. +
  26046. + /* Wait when all callbacks is received */
  26047. + count = 0;
  26048. + while(cesaIsReady == MV_FALSE)
  26049. + {
  26050. + mvOsSleep(10);
  26051. + count++;
  26052. + if(count > 100)
  26053. + {
  26054. + mvOsPrintf("testRun: Timeout occured\n");
  26055. + return MV_TIMEOUT;
  26056. + }
  26057. + }
  26058. +
  26059. + return MV_OK;
  26060. +}
  26061. +
  26062. +
  26063. +void cesaTestStop(void)
  26064. +{
  26065. + MV_CESA_MBUF *pMbufSrc, *pMbufDst;
  26066. + MV_BUF_INFO *pFragsSrc, *pFragsDst;
  26067. + int i;
  26068. +
  26069. + /* Release all allocated memories */
  26070. + pMbufSrc = (MV_CESA_MBUF*)(cesaCmdRing[0].pSrc);
  26071. + pFragsSrc = cesaCmdRing[0].pSrc->pFrags;
  26072. +
  26073. + pMbufDst = (MV_CESA_MBUF*)(cesaCmdRing[0].pDst);
  26074. + pFragsDst = cesaCmdRing[0].pDst->pFrags;
  26075. +
  26076. + mvOsFree(pMbufSrc);
  26077. + mvOsFree(pMbufDst);
  26078. + mvOsFree(pFragsSrc);
  26079. + mvOsFree(pFragsDst);
  26080. +
  26081. + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
  26082. + {
  26083. + mvOsIoCachedFree(cesaTestOSHandle,cesaReqBufs[i].bufSize,
  26084. + cesaReqBufs[i].bufPhysAddr,cesaReqBufs[i].bufVirtPtr,
  26085. + cesaReqBufs[i].memHandle);
  26086. + }
  26087. + cesaDataHexStr3[0] = '\0';
  26088. +}
  26089. +
  26090. +void desTest(int iter, int reqSize, int checkMode)
  26091. +{
  26092. + int mode, i;
  26093. + MV_STATUS status;
  26094. +
  26095. + mode = checkMode;
  26096. + if(checkMode == CESA_FULL_CHECK_MODE)
  26097. + mode = CESA_FAST_CHECK_MODE;
  26098. + i = iter;
  26099. + if(mode != CESA_NULL_CHECK_MODE)
  26100. + i = 1;
  26101. +
  26102. + testOpen(0);
  26103. + testOpen(1);
  26104. + testOpen(2);
  26105. + testOpen(3);
  26106. +
  26107. +/* DES / ECB mode / Encrypt only */
  26108. + status = testRun(0, 1, iter, reqSize, checkMode);
  26109. + printTestResults(0, status, checkMode);
  26110. +
  26111. +/* DES / ECB mode / Decrypt only */
  26112. + status = testRun(1, 1, iter, reqSize, checkMode);
  26113. + printTestResults(1, status, checkMode);
  26114. +
  26115. +/* DES / CBC mode / Encrypt only */
  26116. + status = testRun(2, 2, i, reqSize, mode);
  26117. + printTestResults(2, status, mode);
  26118. +
  26119. +/* DES / CBC mode / Decrypt only */
  26120. + status = testRun(3, 2, iter, reqSize, mode);
  26121. + printTestResults(3, status, mode);
  26122. +
  26123. + testClose(0);
  26124. + testClose(1);
  26125. + testClose(2);
  26126. + testClose(3);
  26127. +}
  26128. +
  26129. +void tripleDesTest(int iter, int reqSize, int checkMode)
  26130. +{
  26131. + int mode, i;
  26132. + MV_STATUS status;
  26133. +
  26134. + mode = checkMode;
  26135. + if(checkMode == CESA_FULL_CHECK_MODE)
  26136. + mode = CESA_FAST_CHECK_MODE;
  26137. + i = iter;
  26138. + if(mode != CESA_NULL_CHECK_MODE)
  26139. + i = 1;
  26140. +
  26141. + testOpen(100);
  26142. + testOpen(101);
  26143. + testOpen(102);
  26144. + testOpen(103);
  26145. +
  26146. +/* 3DES / ECB mode / Encrypt only */
  26147. + status = testRun(100, 1, iter, reqSize, checkMode);
  26148. + printTestResults(100, status, checkMode);
  26149. +
  26150. +/* 3DES / ECB mode / Decrypt only */
  26151. + status = testRun(101, 1, iter, reqSize, checkMode);
  26152. + printTestResults(101, status, checkMode);
  26153. +
  26154. +/* 3DES / CBC mode / Encrypt only */
  26155. + status = testRun(102, 2, i, reqSize, mode);
  26156. + printTestResults(102, status, mode);
  26157. +
  26158. +/* 3DES / CBC mode / Decrypt only */
  26159. + status = testRun(103, 2, iter, reqSize, mode);
  26160. + printTestResults(103, status, mode);
  26161. +
  26162. + testClose(100);
  26163. + testClose(101);
  26164. + testClose(102);
  26165. + testClose(103);
  26166. +}
  26167. +
  26168. +void aesTest(int iter, int reqSize, int checkMode)
  26169. +{
  26170. + MV_STATUS status;
  26171. + int mode, i;
  26172. +
  26173. + mode = checkMode;
  26174. + if(checkMode == CESA_FULL_CHECK_MODE)
  26175. + mode = CESA_FAST_CHECK_MODE;
  26176. +
  26177. + i = iter;
  26178. + if(mode != CESA_NULL_CHECK_MODE)
  26179. + i = 1;
  26180. +
  26181. + testOpen(200);
  26182. + testOpen(201);
  26183. + testOpen(202);
  26184. + testOpen(203);
  26185. + testOpen(204);
  26186. + testOpen(205);
  26187. + testOpen(206);
  26188. + testOpen(207);
  26189. + testOpen(208);
  26190. +
  26191. +/* AES-128 Encode ECB mode */
  26192. + status = testRun(200, 3, iter, reqSize, checkMode);
  26193. + printTestResults(200, status, checkMode);
  26194. +
  26195. +/* AES-128 Decode ECB mode */
  26196. + status = testRun(201, 3, iter, reqSize, checkMode);
  26197. + printTestResults(201, status, checkMode);
  26198. +
  26199. +/* AES-128 Encode CBC mode (IV from SA) */
  26200. + status = testRun(202, 10, i, reqSize, mode);
  26201. + printTestResults(202, status, mode);
  26202. +
  26203. +/* AES-128 Encode CBC mode (IV from User) */
  26204. + status = testRun(202, 24, i, reqSize, mode);
  26205. + printTestResults(202, status, mode);
  26206. +
  26207. +/* AES-128 Decode CBC mode */
  26208. + status = testRun(203, 24, iter, reqSize, mode);
  26209. + printTestResults(203, status, checkMode);
  26210. +
  26211. +/* AES-192 Encode ECB mode */
  26212. + status = testRun(204, 4, iter, reqSize, checkMode);
  26213. + printTestResults(204, status, checkMode);
  26214. +
  26215. +/* AES-192 Decode ECB mode */
  26216. + status = testRun(205, 4, iter, reqSize, checkMode);
  26217. + printTestResults(205, status, checkMode);
  26218. +
  26219. +/* AES-256 Encode ECB mode */
  26220. + status = testRun(206, 5, iter, reqSize, checkMode);
  26221. + printTestResults(206, status, checkMode);
  26222. +
  26223. +/* AES-256 Decode ECB mode */
  26224. + status = testRun(207, 5, iter, reqSize, checkMode);
  26225. + printTestResults(207, status, checkMode);
  26226. +
  26227. +#if defined(MV_LINUX)
  26228. +/* AES-128 Encode CTR mode */
  26229. + status = testRun(208, 23, iter, reqSize, mode);
  26230. + printTestResults(208, status, checkMode);
  26231. +#endif
  26232. + testClose(200);
  26233. + testClose(201);
  26234. + testClose(202);
  26235. + testClose(203);
  26236. + testClose(204);
  26237. + testClose(205);
  26238. + testClose(206);
  26239. + testClose(207);
  26240. + testClose(208);
  26241. +}
  26242. +
  26243. +
  26244. +void mdTest(int iter, int reqSize, int checkMode)
  26245. +{
  26246. + int mode;
  26247. + MV_STATUS status;
  26248. +
  26249. + if(iter == 0)
  26250. + iter = CESA_DEF_ITER_NUM;
  26251. +
  26252. + mode = checkMode;
  26253. + if(checkMode == CESA_FULL_CHECK_MODE)
  26254. + mode = CESA_FAST_CHECK_MODE;
  26255. +
  26256. + testOpen(300);
  26257. + testOpen(301);
  26258. + testOpen(302);
  26259. + testOpen(303);
  26260. + testOpen(305);
  26261. +
  26262. +/* HMAC-MD5 Generate signature test */
  26263. + status = testRun(300, 6, iter, reqSize, mode);
  26264. + printTestResults(300, status, checkMode);
  26265. +
  26266. +/* HMAC-MD5 Verify Signature test */
  26267. + status = testRun(301, 7, iter, reqSize, mode);
  26268. + printTestResults(301, status, checkMode);
  26269. +
  26270. +/* HMAC-MD5 Generate signature test */
  26271. + status = testRun(302, 8, iter, reqSize, mode);
  26272. + printTestResults(302, status, checkMode);
  26273. +
  26274. +/* HMAC-MD5 Verify Signature test */
  26275. + status = testRun(303, 9, iter, reqSize, mode);
  26276. + printTestResults(303, status, checkMode);
  26277. +
  26278. +/* HASH-MD5 Generate signature test */
  26279. + status = testRun(305, 15, iter, reqSize, mode);
  26280. + printTestResults(305, status, checkMode);
  26281. +
  26282. + testClose(300);
  26283. + testClose(301);
  26284. + testClose(302);
  26285. + testClose(303);
  26286. + testClose(305);
  26287. +}
  26288. +
  26289. +void shaTest(int iter, int reqSize, int checkMode)
  26290. +{
  26291. + int mode;
  26292. + MV_STATUS status;
  26293. +
  26294. + if(iter == 0)
  26295. + iter = CESA_DEF_ITER_NUM;
  26296. +
  26297. + mode = checkMode;
  26298. + if(checkMode == CESA_FULL_CHECK_MODE)
  26299. + mode = CESA_FAST_CHECK_MODE;
  26300. +
  26301. + testOpen(400);
  26302. + testOpen(401);
  26303. + testOpen(402);
  26304. + testOpen(403);
  26305. + testOpen(405);
  26306. +
  26307. +/* HMAC-SHA1 Generate signature test */
  26308. + status = testRun(400, 11, iter, reqSize, mode);
  26309. + printTestResults(400, status, checkMode);
  26310. +
  26311. +/* HMAC-SHA1 Verify Signature test */
  26312. + status = testRun(401, 12, iter, reqSize, mode);
  26313. + printTestResults(401, status, checkMode);
  26314. +
  26315. +/* HMAC-SHA1 Generate signature test */
  26316. + status = testRun(402, 13, iter, reqSize, mode);
  26317. + printTestResults(402, status, checkMode);
  26318. +
  26319. +/* HMAC-SHA1 Verify Signature test */
  26320. + status = testRun(403, 14, iter, reqSize, mode);
  26321. + printTestResults(403, status, checkMode);
  26322. +
  26323. +/* HMAC-SHA1 Generate signature test */
  26324. + status = testRun(405, 16, iter, reqSize, mode);
  26325. + printTestResults(405, status, checkMode);
  26326. +
  26327. + testClose(400);
  26328. + testClose(401);
  26329. + testClose(402);
  26330. + testClose(403);
  26331. + testClose(405);
  26332. +}
  26333. +
  26334. +void combiTest(int iter, int reqSize, int checkMode)
  26335. +{
  26336. + MV_STATUS status;
  26337. + int mode, i;
  26338. +
  26339. + mode = checkMode;
  26340. + if(checkMode == CESA_FULL_CHECK_MODE)
  26341. + mode = CESA_FAST_CHECK_MODE;
  26342. +
  26343. + if(iter == 0)
  26344. + iter = CESA_DEF_ITER_NUM;
  26345. +
  26346. + i = iter;
  26347. + if(mode != CESA_NULL_CHECK_MODE)
  26348. + i = 1;
  26349. +
  26350. + testOpen(500);
  26351. + testOpen(501);
  26352. + testOpen(502);
  26353. + testOpen(503);
  26354. + testOpen(504);
  26355. + testOpen(505);
  26356. + testOpen(506);
  26357. + testOpen(507);
  26358. +
  26359. +/* DES ECB + MD5 encode test */
  26360. + status = testRun(500, 17, iter, reqSize, mode);
  26361. + printTestResults(500, status, mode);
  26362. +
  26363. +/* DES ECB + SHA1 encode test */
  26364. + status = testRun(501, 18, iter, reqSize, mode);
  26365. + printTestResults(501, status, mode);
  26366. +
  26367. +/* 3DES ECB + MD5 encode test */
  26368. + status = testRun(502, 17, iter, reqSize, mode);
  26369. + printTestResults(502, status, mode);
  26370. +
  26371. +/* 3DES ECB + SHA1 encode test */
  26372. + status = testRun(503, 18, iter, reqSize, mode);
  26373. + printTestResults(503, status, mode);
  26374. +
  26375. +/* 3DES CBC + MD5 encode test */
  26376. + status = testRun(504, 19, i, reqSize, mode);
  26377. + printTestResults(504, status, mode);
  26378. +
  26379. +/* 3DES CBC + SHA1 encode test */
  26380. + status = testRun(505, 20, i, reqSize, mode);
  26381. + printTestResults(505, status, mode);
  26382. +
  26383. +/* AES-128 CBC + MD5 encode test */
  26384. + status = testRun(506, 21, i, reqSize, mode);
  26385. + printTestResults(506, status, mode);
  26386. +
  26387. +/* AES-128 CBC + SHA1 encode test */
  26388. + status = testRun(507, 22, i, reqSize, mode);
  26389. + printTestResults(507, status, mode);
  26390. +
  26391. + testClose(500);
  26392. + testClose(501);
  26393. + testClose(502);
  26394. + testClose(503);
  26395. + testClose(504);
  26396. + testClose(505);
  26397. + testClose(506);
  26398. + testClose(507);
  26399. +}
  26400. +
  26401. +void cesaOneTest(int testIdx, int caseIdx,
  26402. + int iter, int reqSize, int checkMode)
  26403. +{
  26404. + MV_STATUS status;
  26405. +
  26406. + if(iter == 0)
  26407. + iter = CESA_DEF_ITER_NUM;
  26408. +
  26409. + mvOsPrintf("test=%d, case=%d, size=%d, iter=%d\n",
  26410. + testIdx, caseIdx, reqSize, iter);
  26411. +
  26412. + status = testOpen(testIdx);
  26413. +
  26414. + status = testRun(testIdx, caseIdx, iter, reqSize, checkMode);
  26415. + printTestResults(testIdx, status, checkMode);
  26416. + status = testClose(testIdx);
  26417. +
  26418. +}
  26419. +
  26420. +void cesaTest(int iter, int reqSize, int checkMode)
  26421. +{
  26422. + if(iter == 0)
  26423. + iter = CESA_DEF_ITER_NUM;
  26424. +
  26425. + mvOsPrintf("%d iteration\n", iter);
  26426. + mvOsPrintf("%d size\n\n", reqSize);
  26427. +
  26428. +/* DES tests */
  26429. + desTest(iter, reqSize, checkMode);
  26430. +
  26431. +/* 3DES tests */
  26432. + tripleDesTest(iter, reqSize, checkMode);
  26433. +
  26434. +/* AES tests */
  26435. + aesTest(iter, reqSize, checkMode);
  26436. +
  26437. +/* MD5 tests */
  26438. + mdTest(iter, reqSize, checkMode);
  26439. +
  26440. +/* SHA-1 tests */
  26441. + shaTest(iter, reqSize, checkMode);
  26442. +}
  26443. +
  26444. +void multiSizeTest(int idx, int iter, int checkMode, char* inputData)
  26445. +{
  26446. + MV_STATUS status;
  26447. + int i;
  26448. + MV_CESA_SIZE_TEST* pMultiTest;
  26449. +
  26450. + if( testOpen(idx) != MV_OK)
  26451. + return;
  26452. +
  26453. + if(iter == 0)
  26454. + iter = CESA_DEF_ITER_NUM;
  26455. +
  26456. + if(checkMode == CESA_SHOW_CHECK_MODE)
  26457. + {
  26458. + iter = 1;
  26459. + }
  26460. + else
  26461. + checkMode = CESA_FULL_CHECK_MODE;
  26462. +
  26463. + cesaTestCases[0].plainHexStr = inputData;
  26464. + cesaTestCases[0].pCryptoIV = NULL;
  26465. +
  26466. + switch(idx)
  26467. + {
  26468. + case 302:
  26469. + pMultiTest = mdMultiSizeTest302;
  26470. + if(inputData == NULL)
  26471. + cesaTestCases[0].plainHexStr = cesaDataHexStr3;
  26472. + break;
  26473. +
  26474. + case 304:
  26475. + pMultiTest = mdMultiSizeTest304;
  26476. + if(inputData == NULL)
  26477. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26478. + break;
  26479. +
  26480. + case 305:
  26481. + pMultiTest = mdMultiSizeTest305;
  26482. + if(inputData == NULL)
  26483. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26484. + break;
  26485. +
  26486. + case 402:
  26487. + pMultiTest = shaMultiSizeTest402;
  26488. + if(inputData == NULL)
  26489. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26490. + break;
  26491. +
  26492. + case 404:
  26493. + pMultiTest = shaMultiSizeTest404;
  26494. + if(inputData == NULL)
  26495. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26496. + break;
  26497. +
  26498. + case 405:
  26499. + pMultiTest = shaMultiSizeTest405;
  26500. + if(inputData == NULL)
  26501. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26502. + break;
  26503. +
  26504. + case 502:
  26505. + pMultiTest = tripleDesMdMultiSizeTest502;
  26506. + if(inputData == NULL)
  26507. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26508. + break;
  26509. +
  26510. + case 503:
  26511. + pMultiTest = tripleDesShaMultiSizeTest503;
  26512. + if(inputData == NULL)
  26513. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26514. + break;
  26515. +
  26516. + case 504:
  26517. + iter = 1;
  26518. + pMultiTest = cbc3desMdMultiSizeTest504;
  26519. + cesaTestCases[0].pCryptoIV = iv1;
  26520. + if(inputData == NULL)
  26521. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26522. + break;
  26523. +
  26524. + case 505:
  26525. + iter = 1;
  26526. + pMultiTest = cbc3desShaMultiSizeTest505;
  26527. + cesaTestCases[0].pCryptoIV = iv1;
  26528. + if(inputData == NULL)
  26529. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26530. + break;
  26531. +
  26532. + case 506:
  26533. + iter = 1;
  26534. + pMultiTest = cbcAes128md5multiSizeTest506;
  26535. + cesaTestCases[0].pCryptoIV = iv5;
  26536. + if(inputData == NULL)
  26537. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26538. + break;
  26539. +
  26540. + case 507:
  26541. + iter = 1;
  26542. + pMultiTest = cbcAes128sha1multiSizeTest507;
  26543. + cesaTestCases[0].pCryptoIV = iv5;
  26544. + if(inputData == NULL)
  26545. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26546. + break;
  26547. +
  26548. + default:
  26549. + iter = 1;
  26550. + checkMode = CESA_SHOW_CHECK_MODE;
  26551. + pMultiTest = mdMultiSizeTest302;
  26552. + if(inputData == NULL)
  26553. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26554. + }
  26555. + i = 0;
  26556. + while(pMultiTest[i].outputHexStr != NULL)
  26557. + {
  26558. + cesaTestCases[0].cipherHexStr = (char *)pMultiTest[i].outputHexStr;
  26559. + status = testRun(idx, 0, iter, pMultiTest[i].size,
  26560. + checkMode);
  26561. + if(checkMode != CESA_SHOW_CHECK_MODE)
  26562. + {
  26563. + cesaReqSize = pMultiTest[i].size;
  26564. + printTestResults(idx, status, checkMode);
  26565. + }
  26566. + if(status != MV_OK)
  26567. + break;
  26568. + i++;
  26569. + }
  26570. + testClose(idx);
  26571. +/*
  26572. + mvCesaDebugStatus();
  26573. + cesaTestPrintStatus();
  26574. +*/
  26575. +}
  26576. +
  26577. +void open_session_test(int idx, int caseIdx, int iter)
  26578. +{
  26579. + int reqIdError, cryptoError, openErrors, i;
  26580. + int openErrDisp[100];
  26581. + MV_STATUS status;
  26582. +
  26583. + memset(openErrDisp, 0, sizeof(openErrDisp));
  26584. + openErrors = 0;
  26585. + reqIdError = 0;
  26586. + cryptoError = 0;
  26587. + for(i=0; i<iter; i++)
  26588. + {
  26589. + status = testOpen(idx);
  26590. + if(status != MV_OK)
  26591. + {
  26592. + openErrors++;
  26593. + openErrDisp[status]++;
  26594. + }
  26595. + else
  26596. + {
  26597. + testRun(idx, caseIdx, 1, 0, CESA_FAST_CHECK_MODE);
  26598. + if(cesaCryptoError > 0)
  26599. + cryptoError++;
  26600. + if(cesaReqIdError > 0)
  26601. + reqIdError++;
  26602. +
  26603. + testClose(idx);
  26604. + }
  26605. + }
  26606. + if(cryptoError > 0)
  26607. + mvOsPrintf("cryptoError : %d\n", cryptoError);
  26608. + if(reqIdError > 0)
  26609. + mvOsPrintf("reqIdError : %d\n", reqIdError);
  26610. +
  26611. + if(openErrors > 0)
  26612. + {
  26613. + mvOsPrintf("Open Errors = %d\n", openErrors);
  26614. + for(i=0; i<100; i++)
  26615. + {
  26616. + if(openErrDisp[i] != 0)
  26617. + mvOsPrintf("Error %d - occurs %d times\n", i, openErrDisp[i]);
  26618. + }
  26619. + }
  26620. +}
  26621. +
  26622. +
  26623. +void loopback_test(int idx, int iter, int size, char* pPlainData)
  26624. +{
  26625. +}
  26626. +
  26627. +
  26628. +#if defined(MV_VXWORKS)
  26629. +int testMode = 0;
  26630. +unsigned __TASKCONV cesaTask(void* args)
  26631. +{
  26632. + int reqSize = cesaReqSize;
  26633. +
  26634. + if(testMode == 0)
  26635. + {
  26636. + cesaOneTest(cesaTestIdx, cesaCaseIdx, cesaIteration,
  26637. + reqSize, cesaCheckMode);
  26638. + }
  26639. + else
  26640. + {
  26641. + if(testMode == 1)
  26642. + {
  26643. + cesaTest(cesaIteration, reqSize, cesaCheckMode);
  26644. + combiTest(cesaIteration, reqSize, cesaCheckMode);
  26645. + }
  26646. + else
  26647. + {
  26648. + multiSizeTest(cesaIdx, cesaIteration, cesaCheckMode, NULL);
  26649. + }
  26650. + }
  26651. + return 0;
  26652. +}
  26653. +
  26654. +void oneTest(int testIdx, int caseIdx,
  26655. + int iter, int reqSize, int checkMode)
  26656. +{
  26657. + long rc;
  26658. +
  26659. + cesaIteration = iter;
  26660. + cesaReqSize = cesaRateSize = reqSize;
  26661. + cesaCheckMode = checkMode;
  26662. + testMode = 0;
  26663. + cesaTestIdx = testIdx;
  26664. + cesaCaseIdx = caseIdx;
  26665. + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
  26666. + if (rc != MV_OK)
  26667. + {
  26668. + mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);
  26669. + }
  26670. +}
  26671. +
  26672. +void multiTest(int iter, int reqSize, int checkMode)
  26673. +{
  26674. + long rc;
  26675. +
  26676. + cesaIteration = iter;
  26677. + cesaCheckMode = checkMode;
  26678. + cesaReqSize = reqSize;
  26679. + testMode = 1;
  26680. + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
  26681. + if (rc != MV_OK)
  26682. + {
  26683. + mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);
  26684. + }
  26685. +}
  26686. +
  26687. +void sizeTest(int testIdx, int iter, int checkMode)
  26688. +{
  26689. + long rc;
  26690. +
  26691. + cesaIteration = iter;
  26692. + cesaCheckMode = checkMode;
  26693. + testMode = 2;
  26694. + cesaIdx = testIdx;
  26695. + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
  26696. + if (rc != MV_OK)
  26697. + {
  26698. + mvOsPrintf("hMW: Can't create CESA test task, rc = %ld\n", rc);
  26699. + }
  26700. +}
  26701. +
  26702. +#endif /* MV_VXWORKS */
  26703. +
  26704. +extern void mvCesaDebugSA(short sid, int mode);
  26705. +void cesaTestPrintSession(int idx)
  26706. +{
  26707. + int testIdx;
  26708. + MV_CESA_TEST_SESSION* pTestSession;
  26709. +
  26710. + pTestSession = getTestSessionDb(idx, &testIdx);
  26711. + if(pTestSession == NULL)
  26712. + {
  26713. + mvOsPrintf("Test %d is not exist\n", idx);
  26714. + return;
  26715. + }
  26716. + pTestSession = &pTestSession[testIdx];
  26717. +
  26718. + if(pTestSession->sid == -1)
  26719. + {
  26720. + mvOsPrintf("Test session %d is not opened\n", idx);
  26721. + return;
  26722. + }
  26723. +
  26724. + mvCesaDebugSA(pTestSession->sid, 1);
  26725. +}
  26726. +
  26727. +void cesaTestPrintStatus(void)
  26728. +{
  26729. + mvOsPrintf("\n\t Cesa Test Status\n\n");
  26730. +
  26731. + mvOsPrintf("isrCount=%d\n",
  26732. + cesaTestIsrCount);
  26733. +
  26734. +#ifdef CESA_TEST_DEBUG
  26735. + {
  26736. + int i, j;
  26737. + j = cesaTestTraceIdx;
  26738. + mvOsPrintf("No Type Cause rCause iCause Res Time pReady pProc pEmpty\n");
  26739. + for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)
  26740. + {
  26741. + mvOsPrintf("%02d. %d 0x%04x 0x%04x 0x%04x 0x%02x 0x%02x %02d 0x%06x %p %p %p\n",
  26742. + j, cesaTestTrace[j].type, cesaTestTrace[j].cause, cesaTestTrace[j].realCause,
  26743. + cesaTestTrace[j].dmaCause, cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,
  26744. + cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);
  26745. + j++;
  26746. + if(j == MV_CESA_TEST_TRACE_SIZE)
  26747. + j = 0;
  26748. + }
  26749. + }
  26750. +#endif /* CESA_TEST_DEBUG */
  26751. +}
  26752. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvLru.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvLru.c
  26753. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvLru.c 1970-01-01 01:00:00.000000000 +0100
  26754. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvLru.c 2010-11-09 20:28:05.822495424 +0100
  26755. @@ -0,0 +1,158 @@
  26756. +/*******************************************************************************
  26757. +Copyright (C) Marvell International Ltd. and its affiliates
  26758. +
  26759. +This software file (the "File") is owned and distributed by Marvell
  26760. +International Ltd. and/or its affiliates ("Marvell") under the following
  26761. +alternative licensing terms. Once you have made an election to distribute the
  26762. +File under one of the following license alternatives, please (i) delete this
  26763. +introductory statement regarding license alternatives, (ii) delete the two
  26764. +license alternatives that you have not elected to use and (iii) preserve the
  26765. +Marvell copyright notice above.
  26766. +
  26767. +********************************************************************************
  26768. +Marvell Commercial License Option
  26769. +
  26770. +If you received this File from Marvell and you have entered into a commercial
  26771. +license agreement (a "Commercial License") with Marvell, the File is licensed
  26772. +to you under the terms of the applicable Commercial License.
  26773. +
  26774. +********************************************************************************
  26775. +Marvell GPL License Option
  26776. +
  26777. +If you received this File from Marvell, you may opt to use, redistribute and/or
  26778. +modify this File in accordance with the terms and conditions of the General
  26779. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  26780. +available along with the File in the license.txt file or by writing to the Free
  26781. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  26782. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  26783. +
  26784. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  26785. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  26786. +DISCLAIMED. The GPL License provides additional details about this warranty
  26787. +disclaimer.
  26788. +********************************************************************************
  26789. +Marvell BSD License Option
  26790. +
  26791. +If you received this File from Marvell, you may opt to use, redistribute and/or
  26792. +modify this File under the following licensing terms.
  26793. +Redistribution and use in source and binary forms, with or without modification,
  26794. +are permitted provided that the following conditions are met:
  26795. +
  26796. + * Redistributions of source code must retain the above copyright notice,
  26797. + this list of conditions and the following disclaimer.
  26798. +
  26799. + * Redistributions in binary form must reproduce the above copyright
  26800. + notice, this list of conditions and the following disclaimer in the
  26801. + documentation and/or other materials provided with the distribution.
  26802. +
  26803. + * Neither the name of Marvell nor the names of its contributors may be
  26804. + used to endorse or promote products derived from this software without
  26805. + specific prior written permission.
  26806. +
  26807. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  26808. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  26809. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26810. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  26811. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26812. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26813. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26814. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26815. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26816. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26817. +
  26818. +*******************************************************************************/
  26819. +
  26820. +#include "mvOs.h"
  26821. +#include "mvLru.h"
  26822. +/* LRU Cache support */
  26823. +
  26824. +
  26825. +/* Init LRU cache database */
  26826. +MV_LRU_CACHE* mvLruCacheInit(int numOfEntries)
  26827. +{
  26828. + int i;
  26829. + MV_LRU_CACHE* pLruCache;
  26830. +
  26831. + pLruCache = mvOsMalloc(sizeof(MV_LRU_CACHE));
  26832. + if(pLruCache == NULL)
  26833. + {
  26834. + return NULL;
  26835. + }
  26836. + memset(pLruCache, 0, sizeof(MV_LRU_CACHE));
  26837. +
  26838. + pLruCache->table = mvOsMalloc(numOfEntries*sizeof(MV_LRU_ENTRY));
  26839. + if(pLruCache->table == NULL)
  26840. + {
  26841. + mvOsFree(pLruCache);
  26842. + return NULL;
  26843. + }
  26844. + memset(pLruCache->table, 0, numOfEntries*sizeof(MV_LRU_ENTRY));
  26845. + pLruCache->tableSize = numOfEntries;
  26846. +
  26847. + for(i=0; i<numOfEntries; i++)
  26848. + {
  26849. + pLruCache->table[i].next = i+1;
  26850. + pLruCache->table[i].prev = i-1;
  26851. + }
  26852. + pLruCache->least = 0;
  26853. + pLruCache->most = numOfEntries-1;
  26854. +
  26855. + return pLruCache;
  26856. +}
  26857. +
  26858. +void mvLruCacheFinish(MV_LRU_CACHE* pLruCache)
  26859. +{
  26860. + mvOsFree(pLruCache->table);
  26861. + mvOsFree(pLruCache);
  26862. +}
  26863. +
  26864. +/* Update LRU cache database after using cache Index */
  26865. +void mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx)
  26866. +{
  26867. + int prev, next;
  26868. +
  26869. + if(cacheIdx == pLruHndl->most)
  26870. + return;
  26871. +
  26872. + next = pLruHndl->table[cacheIdx].next;
  26873. + if(cacheIdx == pLruHndl->least)
  26874. + {
  26875. + pLruHndl->least = next;
  26876. + }
  26877. + else
  26878. + {
  26879. + prev = pLruHndl->table[cacheIdx].prev;
  26880. +
  26881. + pLruHndl->table[next].prev = prev;
  26882. + pLruHndl->table[prev].next = next;
  26883. + }
  26884. +
  26885. + pLruHndl->table[pLruHndl->most].next = cacheIdx;
  26886. + pLruHndl->table[cacheIdx].prev = pLruHndl->most;
  26887. + pLruHndl->most = cacheIdx;
  26888. +}
  26889. +
  26890. +/* Delete LRU cache entry */
  26891. +void mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx)
  26892. +{
  26893. + int prev, next;
  26894. +
  26895. + if(cacheIdx == pLruHndl->least)
  26896. + return;
  26897. +
  26898. + prev = pLruHndl->table[cacheIdx].prev;
  26899. + if(cacheIdx == pLruHndl->most)
  26900. + {
  26901. + pLruHndl->most = prev;
  26902. + }
  26903. + else
  26904. + {
  26905. + next = pLruHndl->table[cacheIdx].next;
  26906. +
  26907. + pLruHndl->table[next].prev = prev;
  26908. + pLruHndl->table[prev].next = next;
  26909. + }
  26910. + pLruHndl->table[pLruHndl->least].prev = cacheIdx;
  26911. + pLruHndl->table[cacheIdx].next = pLruHndl->least;
  26912. + pLruHndl->least = cacheIdx;
  26913. +}
  26914. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvLru.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvLru.h
  26915. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvLru.h 1970-01-01 01:00:00.000000000 +0100
  26916. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvLru.h 2010-11-09 20:28:05.861235773 +0100
  26917. @@ -0,0 +1,112 @@
  26918. +/*******************************************************************************
  26919. +Copyright (C) Marvell International Ltd. and its affiliates
  26920. +
  26921. +This software file (the "File") is owned and distributed by Marvell
  26922. +International Ltd. and/or its affiliates ("Marvell") under the following
  26923. +alternative licensing terms. Once you have made an election to distribute the
  26924. +File under one of the following license alternatives, please (i) delete this
  26925. +introductory statement regarding license alternatives, (ii) delete the two
  26926. +license alternatives that you have not elected to use and (iii) preserve the
  26927. +Marvell copyright notice above.
  26928. +
  26929. +********************************************************************************
  26930. +Marvell Commercial License Option
  26931. +
  26932. +If you received this File from Marvell and you have entered into a commercial
  26933. +license agreement (a "Commercial License") with Marvell, the File is licensed
  26934. +to you under the terms of the applicable Commercial License.
  26935. +
  26936. +********************************************************************************
  26937. +Marvell GPL License Option
  26938. +
  26939. +If you received this File from Marvell, you may opt to use, redistribute and/or
  26940. +modify this File in accordance with the terms and conditions of the General
  26941. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  26942. +available along with the File in the license.txt file or by writing to the Free
  26943. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  26944. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  26945. +
  26946. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  26947. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  26948. +DISCLAIMED. The GPL License provides additional details about this warranty
  26949. +disclaimer.
  26950. +********************************************************************************
  26951. +Marvell BSD License Option
  26952. +
  26953. +If you received this File from Marvell, you may opt to use, redistribute and/or
  26954. +modify this File under the following licensing terms.
  26955. +Redistribution and use in source and binary forms, with or without modification,
  26956. +are permitted provided that the following conditions are met:
  26957. +
  26958. + * Redistributions of source code must retain the above copyright notice,
  26959. + this list of conditions and the following disclaimer.
  26960. +
  26961. + * Redistributions in binary form must reproduce the above copyright
  26962. + notice, this list of conditions and the following disclaimer in the
  26963. + documentation and/or other materials provided with the distribution.
  26964. +
  26965. + * Neither the name of Marvell nor the names of its contributors may be
  26966. + used to endorse or promote products derived from this software without
  26967. + specific prior written permission.
  26968. +
  26969. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  26970. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  26971. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26972. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  26973. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26974. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26975. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26976. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26977. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26978. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26979. +
  26980. +*******************************************************************************/
  26981. +/*******************************************************************************
  26982. +* mvLru.h - Header File for Least Recently Used Cache algorithm
  26983. +*
  26984. +* DESCRIPTION:
  26985. +* This header file contains macros typedefs and function declaration for
  26986. +* the Least Recently Used Cache algorithm.
  26987. +*
  26988. +*******************************************************************************/
  26989. +
  26990. +#ifndef __mvLru_h__
  26991. +#define __mvLru_h__
  26992. +
  26993. +
  26994. +typedef struct
  26995. +{
  26996. + int next;
  26997. + int prev;
  26998. +} MV_LRU_ENTRY;
  26999. +
  27000. +typedef struct
  27001. +{
  27002. + int least;
  27003. + int most;
  27004. + MV_LRU_ENTRY* table;
  27005. + int tableSize;
  27006. +
  27007. +}MV_LRU_CACHE;
  27008. +
  27009. +
  27010. +/* Find Cache index for replacement LRU */
  27011. +static INLINE int mvLruCacheIdxFind(MV_LRU_CACHE* pLruHndl)
  27012. +{
  27013. + return pLruHndl->least;
  27014. +}
  27015. +
  27016. +/* Init LRU cache module */
  27017. +MV_LRU_CACHE* mvLruCacheInit(int numOfEntries);
  27018. +
  27019. +/* Finish LRU cache module */
  27020. +void mvLruCacheFinish(MV_LRU_CACHE* pLruHndl);
  27021. +
  27022. +/* Update LRU cache database after using cache Index */
  27023. +void mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx);
  27024. +
  27025. +/* Delete LRU cache entry */
  27026. +void mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx);
  27027. +
  27028. +
  27029. +#endif /* __mvLru_h__ */
  27030. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvMD5.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvMD5.c
  27031. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvMD5.c 1970-01-01 01:00:00.000000000 +0100
  27032. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvMD5.c 2010-11-09 20:28:05.902495799 +0100
  27033. @@ -0,0 +1,349 @@
  27034. +/*******************************************************************************
  27035. +Copyright (C) Marvell International Ltd. and its affiliates
  27036. +
  27037. +This software file (the "File") is owned and distributed by Marvell
  27038. +International Ltd. and/or its affiliates ("Marvell") under the following
  27039. +alternative licensing terms. Once you have made an election to distribute the
  27040. +File under one of the following license alternatives, please (i) delete this
  27041. +introductory statement regarding license alternatives, (ii) delete the two
  27042. +license alternatives that you have not elected to use and (iii) preserve the
  27043. +Marvell copyright notice above.
  27044. +
  27045. +********************************************************************************
  27046. +Marvell Commercial License Option
  27047. +
  27048. +If you received this File from Marvell and you have entered into a commercial
  27049. +license agreement (a "Commercial License") with Marvell, the File is licensed
  27050. +to you under the terms of the applicable Commercial License.
  27051. +
  27052. +********************************************************************************
  27053. +Marvell GPL License Option
  27054. +
  27055. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27056. +modify this File in accordance with the terms and conditions of the General
  27057. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  27058. +available along with the File in the license.txt file or by writing to the Free
  27059. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  27060. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  27061. +
  27062. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  27063. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  27064. +DISCLAIMED. The GPL License provides additional details about this warranty
  27065. +disclaimer.
  27066. +********************************************************************************
  27067. +Marvell BSD License Option
  27068. +
  27069. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27070. +modify this File under the following licensing terms.
  27071. +Redistribution and use in source and binary forms, with or without modification,
  27072. +are permitted provided that the following conditions are met:
  27073. +
  27074. + * Redistributions of source code must retain the above copyright notice,
  27075. + this list of conditions and the following disclaimer.
  27076. +
  27077. + * Redistributions in binary form must reproduce the above copyright
  27078. + notice, this list of conditions and the following disclaimer in the
  27079. + documentation and/or other materials provided with the distribution.
  27080. +
  27081. + * Neither the name of Marvell nor the names of its contributors may be
  27082. + used to endorse or promote products derived from this software without
  27083. + specific prior written permission.
  27084. +
  27085. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  27086. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  27087. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27088. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  27089. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27090. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27091. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  27092. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27093. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27094. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27095. +
  27096. +*******************************************************************************/
  27097. +
  27098. +#include "mvOs.h"
  27099. +#include "mvMD5.h"
  27100. +
  27101. +static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN]);
  27102. +
  27103. +#ifdef MV_CPU_LE
  27104. +#define mvByteReverse(buf, len) /* Nothing */
  27105. +#else
  27106. +static void mvByteReverse(unsigned char *buf, unsigned longs);
  27107. +
  27108. +/*
  27109. + * Note: this code is harmless on little-endian machines.
  27110. + */
  27111. +static void mvByteReverse(unsigned char *buf, unsigned longs)
  27112. +{
  27113. + MV_U32 t;
  27114. +
  27115. + do
  27116. + {
  27117. + t = (MV_U32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
  27118. + ((unsigned) buf[1] << 8 | buf[0]);
  27119. + *(MV_U32 *) buf = t;
  27120. + buf += 4;
  27121. + } while (--longs);
  27122. +}
  27123. +#endif
  27124. +
  27125. +/*
  27126. + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
  27127. + * initialization constants.
  27128. + */
  27129. +void mvMD5Init(MV_MD5_CONTEXT *ctx)
  27130. +{
  27131. + ctx->buf[0] = 0x67452301;
  27132. + ctx->buf[1] = 0xefcdab89;
  27133. + ctx->buf[2] = 0x98badcfe;
  27134. + ctx->buf[3] = 0x10325476;
  27135. +
  27136. + ctx->bits[0] = 0;
  27137. + ctx->bits[1] = 0;
  27138. +}
  27139. +
  27140. +/*
  27141. + * Update context to reflect the concatenation of another buffer full
  27142. + * of bytes.
  27143. + */
  27144. +void mvMD5Update(MV_MD5_CONTEXT *ctx, unsigned char const *buf, unsigned len)
  27145. +{
  27146. + MV_U32 t;
  27147. +
  27148. + /* Update bitcount */
  27149. +
  27150. + t = ctx->bits[0];
  27151. + if ((ctx->bits[0] = t + ((MV_U32) len << 3)) < t)
  27152. + ctx->bits[1]++; /* Carry from low to high */
  27153. + ctx->bits[1] += len >> 29;
  27154. +
  27155. + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
  27156. +
  27157. + /* Handle any leading odd-sized chunks */
  27158. +
  27159. + if (t)
  27160. + {
  27161. + unsigned char *p = (unsigned char *) ctx->in + t;
  27162. +
  27163. + t = 64 - t;
  27164. + if (len < t)
  27165. + {
  27166. + memcpy(p, buf, len);
  27167. + return;
  27168. + }
  27169. + memcpy(p, buf, t);
  27170. + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
  27171. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  27172. + buf += t;
  27173. + len -= t;
  27174. + }
  27175. + /* Process data in 64-byte chunks */
  27176. +
  27177. + while (len >= 64)
  27178. + {
  27179. + memcpy(ctx->in, buf, 64);
  27180. + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
  27181. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  27182. + buf += 64;
  27183. + len -= 64;
  27184. + }
  27185. +
  27186. + /* Handle any remaining bytes of data. */
  27187. +
  27188. + memcpy(ctx->in, buf, len);
  27189. +}
  27190. +
  27191. +/*
  27192. + * Final wrapup - pad to 64-byte boundary with the bit pattern
  27193. + * 1 0* (64-bit count of bits processed, MSB-first)
  27194. + */
  27195. +void mvMD5Final(unsigned char digest[MV_MD5_MAC_LEN], MV_MD5_CONTEXT *ctx)
  27196. +{
  27197. + unsigned count;
  27198. + unsigned char *p;
  27199. +
  27200. + /* Compute number of bytes mod 64 */
  27201. + count = (ctx->bits[0] >> 3) & 0x3F;
  27202. +
  27203. + /* Set the first char of padding to 0x80. This is safe since there is
  27204. + always at least one byte free */
  27205. + p = ctx->in + count;
  27206. + *p++ = 0x80;
  27207. +
  27208. + /* Bytes of padding needed to make 64 bytes */
  27209. + count = 64 - 1 - count;
  27210. +
  27211. + /* Pad out to 56 mod 64 */
  27212. + if (count < 8)
  27213. + {
  27214. + /* Two lots of padding: Pad the first block to 64 bytes */
  27215. + memset(p, 0, count);
  27216. + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
  27217. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  27218. +
  27219. + /* Now fill the next block with 56 bytes */
  27220. + memset(ctx->in, 0, 56);
  27221. + }
  27222. + else
  27223. + {
  27224. + /* Pad block to 56 bytes */
  27225. + memset(p, 0, count - 8);
  27226. + }
  27227. + mvByteReverse(ctx->in, 14);
  27228. +
  27229. + /* Append length in bits and transform */
  27230. + ((MV_U32 *) ctx->in)[14] = ctx->bits[0];
  27231. + ((MV_U32 *) ctx->in)[15] = ctx->bits[1];
  27232. +
  27233. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  27234. + mvByteReverse((unsigned char *) ctx->buf, 4);
  27235. + memcpy(digest, ctx->buf, MV_MD5_MAC_LEN);
  27236. + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
  27237. +}
  27238. +
  27239. +/* The four core functions - F1 is optimized somewhat */
  27240. +
  27241. +/* #define F1(x, y, z) (x & y | ~x & z) */
  27242. +#define F1(x, y, z) (z ^ (x & (y ^ z)))
  27243. +#define F2(x, y, z) F1(z, x, y)
  27244. +#define F3(x, y, z) (x ^ y ^ z)
  27245. +#define F4(x, y, z) (y ^ (x | ~z))
  27246. +
  27247. +/* This is the central step in the MD5 algorithm. */
  27248. +#define MD5STEP(f, w, x, y, z, data, s) \
  27249. + ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
  27250. +
  27251. +/*
  27252. + * The core of the MD5 algorithm, this alters an existing MD5 hash to
  27253. + * reflect the addition of 16 longwords of new data. MD5Update blocks
  27254. + * the data and converts bytes into longwords for this routine.
  27255. + */
  27256. +static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN])
  27257. +{
  27258. + register MV_U32 a, b, c, d;
  27259. +
  27260. + a = buf[0];
  27261. + b = buf[1];
  27262. + c = buf[2];
  27263. + d = buf[3];
  27264. +
  27265. + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
  27266. + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
  27267. + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
  27268. + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
  27269. + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
  27270. + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
  27271. + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
  27272. + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
  27273. + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
  27274. + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
  27275. + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
  27276. + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
  27277. + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
  27278. + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
  27279. + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
  27280. + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
  27281. +
  27282. + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
  27283. + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
  27284. + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
  27285. + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
  27286. + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
  27287. + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
  27288. + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
  27289. + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
  27290. + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
  27291. + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
  27292. + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
  27293. + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
  27294. + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
  27295. + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
  27296. + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
  27297. + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
  27298. +
  27299. + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
  27300. + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
  27301. + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
  27302. + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
  27303. + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
  27304. + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
  27305. + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
  27306. + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
  27307. + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
  27308. + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
  27309. + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
  27310. + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
  27311. + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
  27312. + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
  27313. + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
  27314. + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
  27315. +
  27316. + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
  27317. + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
  27318. + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
  27319. + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
  27320. + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
  27321. + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
  27322. + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
  27323. + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
  27324. + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
  27325. + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
  27326. + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
  27327. + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
  27328. + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
  27329. + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
  27330. + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
  27331. + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
  27332. +
  27333. + buf[0] += a;
  27334. + buf[1] += b;
  27335. + buf[2] += c;
  27336. + buf[3] += d;
  27337. +}
  27338. +
  27339. +void mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest)
  27340. +{
  27341. + MV_MD5_CONTEXT ctx;
  27342. +
  27343. + mvMD5Init(&ctx);
  27344. + mvMD5Update(&ctx, buf, len);
  27345. + mvMD5Final(digest, &ctx);
  27346. +}
  27347. +
  27348. +
  27349. +void mvHmacMd5(unsigned char const* text, int text_len,
  27350. + unsigned char const* key, int key_len,
  27351. + unsigned char* digest)
  27352. +{
  27353. + int i;
  27354. + MV_MD5_CONTEXT ctx;
  27355. + unsigned char k_ipad[64+1]; /* inner padding - key XORd with ipad */
  27356. + unsigned char k_opad[64+1]; /* outer padding - key XORd with opad */
  27357. +
  27358. + /* start out by storing key in pads */
  27359. + memset(k_ipad, 0, 64);
  27360. + memcpy(k_ipad, key, key_len);
  27361. + memset(k_opad, 0, 64);
  27362. + memcpy(k_opad, key, key_len);
  27363. +
  27364. + /* XOR key with ipad and opad values */
  27365. + for (i=0; i<64; i++)
  27366. + {
  27367. + k_ipad[i] ^= 0x36;
  27368. + k_opad[i] ^= 0x5c;
  27369. + }
  27370. +
  27371. + /* perform inner MD5 */
  27372. + mvMD5Init(&ctx); /* init ctx for 1st pass */
  27373. + mvMD5Update(&ctx, k_ipad, 64); /* start with inner pad */
  27374. + mvMD5Update(&ctx, text, text_len); /* then text of datagram */
  27375. + mvMD5Final(digest, &ctx); /* finish up 1st pass */
  27376. +
  27377. + /* perform outer MD5 */
  27378. + mvMD5Init(&ctx); /* init ctx for 2nd pass */
  27379. + mvMD5Update(&ctx, k_opad, 64); /* start with outer pad */
  27380. + mvMD5Update(&ctx, digest, 16); /* then results of 1st hash */
  27381. + mvMD5Final(digest, &ctx); /* finish up 2nd pass */
  27382. +}
  27383. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvMD5.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvMD5.h
  27384. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvMD5.h 1970-01-01 01:00:00.000000000 +0100
  27385. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvMD5.h 2010-11-09 20:28:05.942495390 +0100
  27386. @@ -0,0 +1,93 @@
  27387. +/*******************************************************************************
  27388. +Copyright (C) Marvell International Ltd. and its affiliates
  27389. +
  27390. +This software file (the "File") is owned and distributed by Marvell
  27391. +International Ltd. and/or its affiliates ("Marvell") under the following
  27392. +alternative licensing terms. Once you have made an election to distribute the
  27393. +File under one of the following license alternatives, please (i) delete this
  27394. +introductory statement regarding license alternatives, (ii) delete the two
  27395. +license alternatives that you have not elected to use and (iii) preserve the
  27396. +Marvell copyright notice above.
  27397. +
  27398. +********************************************************************************
  27399. +Marvell Commercial License Option
  27400. +
  27401. +If you received this File from Marvell and you have entered into a commercial
  27402. +license agreement (a "Commercial License") with Marvell, the File is licensed
  27403. +to you under the terms of the applicable Commercial License.
  27404. +
  27405. +********************************************************************************
  27406. +Marvell GPL License Option
  27407. +
  27408. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27409. +modify this File in accordance with the terms and conditions of the General
  27410. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  27411. +available along with the File in the license.txt file or by writing to the Free
  27412. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  27413. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  27414. +
  27415. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  27416. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  27417. +DISCLAIMED. The GPL License provides additional details about this warranty
  27418. +disclaimer.
  27419. +********************************************************************************
  27420. +Marvell BSD License Option
  27421. +
  27422. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27423. +modify this File under the following licensing terms.
  27424. +Redistribution and use in source and binary forms, with or without modification,
  27425. +are permitted provided that the following conditions are met:
  27426. +
  27427. + * Redistributions of source code must retain the above copyright notice,
  27428. + this list of conditions and the following disclaimer.
  27429. +
  27430. + * Redistributions in binary form must reproduce the above copyright
  27431. + notice, this list of conditions and the following disclaimer in the
  27432. + documentation and/or other materials provided with the distribution.
  27433. +
  27434. + * Neither the name of Marvell nor the names of its contributors may be
  27435. + used to endorse or promote products derived from this software without
  27436. + specific prior written permission.
  27437. +
  27438. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  27439. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  27440. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27441. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  27442. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27443. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27444. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  27445. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27446. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27447. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27448. +
  27449. +*******************************************************************************/
  27450. +
  27451. +#ifndef __mvMD5_h__
  27452. +#define __mvMD5_h__
  27453. +
  27454. +#include "mvMD5.h"
  27455. +
  27456. +#define MV_MD5_MAC_LEN 16
  27457. +
  27458. +
  27459. +typedef struct
  27460. +{
  27461. + MV_U32 buf[4];
  27462. + MV_U32 bits[2];
  27463. + MV_U8 in[64];
  27464. +
  27465. +} MV_MD5_CONTEXT;
  27466. +
  27467. +void mvMD5Init(MV_MD5_CONTEXT *context);
  27468. +void mvMD5Update(MV_MD5_CONTEXT *context, unsigned char const *buf,
  27469. + unsigned len);
  27470. +void mvMD5Final(unsigned char digest[16], MV_MD5_CONTEXT *context);
  27471. +
  27472. +void mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest);
  27473. +
  27474. +void mvHmacMd5(unsigned char const* text, int text_len,
  27475. + unsigned char const* key, int key_len,
  27476. + unsigned char* digest);
  27477. +
  27478. +
  27479. +#endif /* __mvMD5_h__ */
  27480. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvSHA1.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvSHA1.c
  27481. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvSHA1.c 1970-01-01 01:00:00.000000000 +0100
  27482. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvSHA1.c 2010-11-09 20:28:05.972495400 +0100
  27483. @@ -0,0 +1,239 @@
  27484. +/*******************************************************************************
  27485. +Copyright (C) Marvell International Ltd. and its affiliates
  27486. +
  27487. +This software file (the "File") is owned and distributed by Marvell
  27488. +International Ltd. and/or its affiliates ("Marvell") under the following
  27489. +alternative licensing terms. Once you have made an election to distribute the
  27490. +File under one of the following license alternatives, please (i) delete this
  27491. +introductory statement regarding license alternatives, (ii) delete the two
  27492. +license alternatives that you have not elected to use and (iii) preserve the
  27493. +Marvell copyright notice above.
  27494. +
  27495. +********************************************************************************
  27496. +Marvell Commercial License Option
  27497. +
  27498. +If you received this File from Marvell and you have entered into a commercial
  27499. +license agreement (a "Commercial License") with Marvell, the File is licensed
  27500. +to you under the terms of the applicable Commercial License.
  27501. +
  27502. +********************************************************************************
  27503. +Marvell GPL License Option
  27504. +
  27505. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27506. +modify this File in accordance with the terms and conditions of the General
  27507. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  27508. +available along with the File in the license.txt file or by writing to the Free
  27509. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  27510. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  27511. +
  27512. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  27513. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  27514. +DISCLAIMED. The GPL License provides additional details about this warranty
  27515. +disclaimer.
  27516. +********************************************************************************
  27517. +Marvell BSD License Option
  27518. +
  27519. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27520. +modify this File under the following licensing terms.
  27521. +Redistribution and use in source and binary forms, with or without modification,
  27522. +are permitted provided that the following conditions are met:
  27523. +
  27524. + * Redistributions of source code must retain the above copyright notice,
  27525. + this list of conditions and the following disclaimer.
  27526. +
  27527. + * Redistributions in binary form must reproduce the above copyright
  27528. + notice, this list of conditions and the following disclaimer in the
  27529. + documentation and/or other materials provided with the distribution.
  27530. +
  27531. + * Neither the name of Marvell nor the names of its contributors may be
  27532. + used to endorse or promote products derived from this software without
  27533. + specific prior written permission.
  27534. +
  27535. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  27536. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  27537. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27538. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  27539. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27540. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27541. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  27542. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27543. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27544. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27545. +
  27546. +*******************************************************************************/
  27547. +
  27548. +#include "mvOs.h"
  27549. +#include "mvSHA1.h"
  27550. +
  27551. +#define SHA1HANDSOFF
  27552. +
  27553. +typedef union
  27554. +{
  27555. + MV_U8 c[64];
  27556. + MV_U32 l[16];
  27557. +
  27558. +} CHAR64LONG16;
  27559. +
  27560. +static void mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer);
  27561. +
  27562. +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
  27563. +
  27564. +
  27565. +#ifdef MV_CPU_LE
  27566. +#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
  27567. + (rol(block->l[i], 8) & 0x00FF00FF))
  27568. +#else
  27569. +#define blk0(i) block->l[i]
  27570. +#endif
  27571. +#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
  27572. + block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
  27573. +
  27574. +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
  27575. +#define R0(v,w,x,y,z,i) \
  27576. + z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
  27577. + w = rol(w, 30);
  27578. +#define R1(v,w,x,y,z,i) \
  27579. + z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
  27580. + w = rol(w, 30);
  27581. +#define R2(v,w,x,y,z,i) \
  27582. + z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
  27583. +#define R3(v,w,x,y,z,i) \
  27584. + z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
  27585. + w = rol(w, 30);
  27586. +#define R4(v,w,x,y,z,i) \
  27587. + z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
  27588. + w=rol(w, 30);
  27589. +
  27590. +/* Hash a single 512-bit block. This is the core of the algorithm. */
  27591. +static void mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer)
  27592. +{
  27593. + MV_U32 a, b, c, d, e;
  27594. + CHAR64LONG16* block;
  27595. +
  27596. +#ifdef SHA1HANDSOFF
  27597. + static MV_U32 workspace[16];
  27598. +
  27599. + block = (CHAR64LONG16 *) workspace;
  27600. + memcpy(block, buffer, 64);
  27601. +#else
  27602. + block = (CHAR64LONG16 *) buffer;
  27603. +#endif
  27604. + /* Copy context->state[] to working vars */
  27605. + a = state[0];
  27606. + b = state[1];
  27607. + c = state[2];
  27608. + d = state[3];
  27609. + e = state[4];
  27610. + /* 4 rounds of 20 operations each. Loop unrolled. */
  27611. + 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);
  27612. + 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);
  27613. + 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);
  27614. + 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);
  27615. + 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);
  27616. + 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);
  27617. + 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);
  27618. + 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);
  27619. + 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);
  27620. + 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);
  27621. + 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);
  27622. + 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);
  27623. + 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);
  27624. + 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);
  27625. + 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);
  27626. + 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);
  27627. + 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);
  27628. + 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);
  27629. + 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);
  27630. + 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);
  27631. + /* Add the working vars back into context.state[] */
  27632. + state[0] += a;
  27633. + state[1] += b;
  27634. + state[2] += c;
  27635. + state[3] += d;
  27636. + state[4] += e;
  27637. + /* Wipe variables */
  27638. + a = b = c = d = e = 0;
  27639. +}
  27640. +
  27641. +void mvSHA1Init(MV_SHA1_CTX* context)
  27642. +{
  27643. + /* SHA1 initialization constants */
  27644. + context->state[0] = 0x67452301;
  27645. + context->state[1] = 0xEFCDAB89;
  27646. + context->state[2] = 0x98BADCFE;
  27647. + context->state[3] = 0x10325476;
  27648. + context->state[4] = 0xC3D2E1F0;
  27649. + context->count[0] = context->count[1] = 0;
  27650. +}
  27651. +
  27652. +
  27653. +/* Run your data through this. */
  27654. +void mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *data,
  27655. + unsigned int len)
  27656. +{
  27657. + MV_U32 i, j;
  27658. +
  27659. + j = (context->count[0] >> 3) & 63;
  27660. + if ((context->count[0] += len << 3) < (len << 3))
  27661. + context->count[1]++;
  27662. + context->count[1] += (len >> 29);
  27663. + if ((j + len) > 63)
  27664. + {
  27665. + memcpy(&context->buffer[j], data, (i = 64-j));
  27666. + mvSHA1Transform(context->state, context->buffer);
  27667. + for ( ; i + 63 < len; i += 64)
  27668. + {
  27669. + mvSHA1Transform(context->state, &data[i]);
  27670. + }
  27671. + j = 0;
  27672. + }
  27673. + else
  27674. + {
  27675. + i = 0;
  27676. + }
  27677. + memcpy(&context->buffer[j], &data[i], len - i);
  27678. +}
  27679. +
  27680. +void mvSHA1Final(MV_U8* digest, MV_SHA1_CTX* context)
  27681. +{
  27682. + MV_U32 i;
  27683. + MV_U8 finalcount[8];
  27684. +
  27685. + for (i = 0; i < 8; i++)
  27686. + {
  27687. + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >>
  27688. + ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
  27689. + }
  27690. + mvSHA1Update(context, (const unsigned char *) "\200", 1);
  27691. + while ((context->count[0] & 504) != 448)
  27692. + {
  27693. + mvSHA1Update(context, (const unsigned char *) "\0", 1);
  27694. + }
  27695. + mvSHA1Update(context, finalcount, 8); /* Should cause a mvSHA1Transform()
  27696. + */
  27697. + for (i = 0; i < 20; i++)
  27698. + {
  27699. + digest[i] = (unsigned char)
  27700. + ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
  27701. + }
  27702. + /* Wipe variables */
  27703. + i = 0;
  27704. + memset(context->buffer, 0, 64);
  27705. + memset(context->state, 0, 20);
  27706. + memset(context->count, 0, 8);
  27707. + memset(finalcount, 0, 8);
  27708. +
  27709. +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
  27710. + mvSHA1Transform(context->state, context->buffer);
  27711. +#endif
  27712. +}
  27713. +
  27714. +
  27715. +void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest)
  27716. +{
  27717. + MV_SHA1_CTX ctx;
  27718. +
  27719. + mvSHA1Init(&ctx);
  27720. + mvSHA1Update(&ctx, buf, len);
  27721. + mvSHA1Final(digest, &ctx);
  27722. +}
  27723. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvSHA1.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvSHA1.h
  27724. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvSHA1.h 1970-01-01 01:00:00.000000000 +0100
  27725. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvSHA1.h 2010-11-09 20:28:06.012495345 +0100
  27726. @@ -0,0 +1,88 @@
  27727. +/*******************************************************************************
  27728. +Copyright (C) Marvell International Ltd. and its affiliates
  27729. +
  27730. +This software file (the "File") is owned and distributed by Marvell
  27731. +International Ltd. and/or its affiliates ("Marvell") under the following
  27732. +alternative licensing terms. Once you have made an election to distribute the
  27733. +File under one of the following license alternatives, please (i) delete this
  27734. +introductory statement regarding license alternatives, (ii) delete the two
  27735. +license alternatives that you have not elected to use and (iii) preserve the
  27736. +Marvell copyright notice above.
  27737. +
  27738. +********************************************************************************
  27739. +Marvell Commercial License Option
  27740. +
  27741. +If you received this File from Marvell and you have entered into a commercial
  27742. +license agreement (a "Commercial License") with Marvell, the File is licensed
  27743. +to you under the terms of the applicable Commercial License.
  27744. +
  27745. +********************************************************************************
  27746. +Marvell GPL License Option
  27747. +
  27748. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27749. +modify this File in accordance with the terms and conditions of the General
  27750. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  27751. +available along with the File in the license.txt file or by writing to the Free
  27752. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  27753. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  27754. +
  27755. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  27756. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  27757. +DISCLAIMED. The GPL License provides additional details about this warranty
  27758. +disclaimer.
  27759. +********************************************************************************
  27760. +Marvell BSD License Option
  27761. +
  27762. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27763. +modify this File under the following licensing terms.
  27764. +Redistribution and use in source and binary forms, with or without modification,
  27765. +are permitted provided that the following conditions are met:
  27766. +
  27767. + * Redistributions of source code must retain the above copyright notice,
  27768. + this list of conditions and the following disclaimer.
  27769. +
  27770. + * Redistributions in binary form must reproduce the above copyright
  27771. + notice, this list of conditions and the following disclaimer in the
  27772. + documentation and/or other materials provided with the distribution.
  27773. +
  27774. + * Neither the name of Marvell nor the names of its contributors may be
  27775. + used to endorse or promote products derived from this software without
  27776. + specific prior written permission.
  27777. +
  27778. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  27779. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  27780. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27781. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  27782. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27783. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27784. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  27785. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27786. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27787. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27788. +
  27789. +*******************************************************************************/
  27790. +
  27791. +#ifndef __mvSHA1_h__
  27792. +#define __mvSHA1_h__
  27793. +
  27794. +#include "mvSHA1.h"
  27795. +
  27796. +#define MV_SHA1_MAC_LEN 20
  27797. +
  27798. +
  27799. +typedef struct
  27800. +{
  27801. + MV_U32 state[5];
  27802. + MV_U32 count[2];
  27803. + MV_U8 buffer[64];
  27804. +
  27805. +} MV_SHA1_CTX;
  27806. +
  27807. +void mvSHA1Init(MV_SHA1_CTX *context);
  27808. +void mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *buf, unsigned int len);
  27809. +void mvSHA1Final(MV_U8* digest, MV_SHA1_CTX *context);
  27810. +
  27811. +void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest);
  27812. +
  27813. +
  27814. +#endif /* __mvSHA1_h__ */
  27815. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa_ocf_drv.c linux-2.6.36/crypto/ocf/kirkwood/cesa_ocf_drv.c
  27816. --- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa_ocf_drv.c 1970-01-01 01:00:00.000000000 +0100
  27817. +++ linux-2.6.36/crypto/ocf/kirkwood/cesa_ocf_drv.c 2010-11-09 20:28:06.052495403 +0100
  27818. @@ -0,0 +1,1296 @@
  27819. +/*******************************************************************************
  27820. +Copyright (C) Marvell International Ltd. and its affiliates
  27821. +
  27822. +This software file (the "File") is owned and distributed by Marvell
  27823. +International Ltd. and/or its affiliates ("Marvell") under the following
  27824. +alternative licensing terms. Once you have made an election to distribute the
  27825. +File under one of the following license alternatives, please (i) delete this
  27826. +introductory statement regarding license alternatives, (ii) delete the two
  27827. +license alternatives that you have not elected to use and (iii) preserve the
  27828. +Marvell copyright notice above.
  27829. +
  27830. +
  27831. +********************************************************************************
  27832. +Marvell GPL License Option
  27833. +
  27834. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27835. +modify this File in accordance with the terms and conditions of the General
  27836. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  27837. +available along with the File in the license.txt file or by writing to the Free
  27838. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  27839. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  27840. +
  27841. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  27842. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  27843. +DISCLAIMED. The GPL License provides additional details about this warranty
  27844. +disclaimer.
  27845. +*******************************************************************************/
  27846. +
  27847. +#ifndef AUTOCONF_INCLUDED
  27848. +#include <linux/config.h>
  27849. +#endif
  27850. +#include <linux/module.h>
  27851. +#include <linux/init.h>
  27852. +#include <linux/list.h>
  27853. +#include <linux/slab.h>
  27854. +#include <linux/sched.h>
  27855. +#include <linux/wait.h>
  27856. +#include <linux/crypto.h>
  27857. +#include <linux/mm.h>
  27858. +#include <linux/skbuff.h>
  27859. +#include <linux/random.h>
  27860. +#include <linux/platform_device.h>
  27861. +#include <asm/scatterlist.h>
  27862. +#include <linux/spinlock.h>
  27863. +#include "ctrlEnv/sys/mvSysCesa.h"
  27864. +#include "cesa/mvCesa.h" /* moved here before cryptodev.h due to include dependencies */
  27865. +#include <cryptodev.h>
  27866. +#include <uio.h>
  27867. +#include <plat/mv_cesa.h>
  27868. +#include <linux/mbus.h>
  27869. +#include "mvDebug.h"
  27870. +
  27871. +#include "cesa/mvMD5.h"
  27872. +#include "cesa/mvSHA1.h"
  27873. +
  27874. +#include "cesa/mvCesaRegs.h"
  27875. +#include "cesa/AES/mvAes.h"
  27876. +#include "cesa/mvLru.h"
  27877. +
  27878. +#undef RT_DEBUG
  27879. +#ifdef RT_DEBUG
  27880. +static int debug = 1;
  27881. +module_param(debug, int, 1);
  27882. +MODULE_PARM_DESC(debug, "Enable debug");
  27883. +#undef dprintk
  27884. +#define dprintk(a...) if (debug) { printk(a); } else
  27885. +#else
  27886. +static int debug = 0;
  27887. +#undef dprintk
  27888. +#define dprintk(a...)
  27889. +#endif
  27890. +
  27891. +
  27892. +/* TDMA Regs */
  27893. +#define WINDOW_BASE(i) 0xA00 + (i << 3)
  27894. +#define WINDOW_CTRL(i) 0xA04 + (i << 3)
  27895. +
  27896. +/* interrupt handling */
  27897. +#undef CESA_OCF_POLLING
  27898. +#undef CESA_OCF_TASKLET
  27899. +
  27900. +#if defined(CESA_OCF_POLLING) && defined(CESA_OCF_TASKLET)
  27901. +#error "don't use both tasklet and polling mode"
  27902. +#endif
  27903. +
  27904. +extern int cesaReqResources;
  27905. +/* support for spliting action into 2 actions */
  27906. +#define CESA_OCF_SPLIT
  27907. +
  27908. +/* general defines */
  27909. +#define CESA_OCF_MAX_SES 128
  27910. +#define CESA_Q_SIZE 64
  27911. +
  27912. +
  27913. +/* data structures */
  27914. +struct cesa_ocf_data {
  27915. + int cipher_alg;
  27916. + int auth_alg;
  27917. + int encrypt_tn_auth;
  27918. +#define auth_tn_decrypt encrypt_tn_auth
  27919. + int ivlen;
  27920. + int digestlen;
  27921. + short sid_encrypt;
  27922. + short sid_decrypt;
  27923. + /* fragment workaround sessions */
  27924. + short frag_wa_encrypt;
  27925. + short frag_wa_decrypt;
  27926. + short frag_wa_auth;
  27927. +};
  27928. +
  27929. +/* CESA device data */
  27930. +struct cesa_dev {
  27931. + void __iomem *sram;
  27932. + void __iomem *reg;
  27933. + struct mv_cesa_platform_data *plat_data;
  27934. + int irq;
  27935. +};
  27936. +
  27937. +#define DIGEST_BUF_SIZE 32
  27938. +struct cesa_ocf_process {
  27939. + MV_CESA_COMMAND cesa_cmd;
  27940. + MV_CESA_MBUF cesa_mbuf;
  27941. + MV_BUF_INFO cesa_bufs[MV_CESA_MAX_MBUF_FRAGS];
  27942. + char digest[DIGEST_BUF_SIZE];
  27943. + int digest_len;
  27944. + struct cryptop *crp;
  27945. + int need_cb;
  27946. +};
  27947. +
  27948. +/* global variables */
  27949. +static int32_t cesa_ocf_id = -1;
  27950. +static struct cesa_ocf_data *cesa_ocf_sessions[CESA_OCF_MAX_SES];
  27951. +static spinlock_t cesa_lock;
  27952. +static struct cesa_dev cesa_device;
  27953. +
  27954. +/* static APIs */
  27955. +static int cesa_ocf_process (device_t, struct cryptop *, int);
  27956. +static int cesa_ocf_newsession (device_t, u_int32_t *, struct cryptoini *);
  27957. +static int cesa_ocf_freesession (device_t, u_int64_t);
  27958. +static void cesa_callback (unsigned long);
  27959. +static irqreturn_t cesa_interrupt_handler (int, void *);
  27960. +#ifdef CESA_OCF_POLLING
  27961. +static void cesa_interrupt_polling(void);
  27962. +#endif
  27963. +#ifdef CESA_OCF_TASKLET
  27964. +static struct tasklet_struct cesa_ocf_tasklet;
  27965. +#endif
  27966. +
  27967. +static struct timeval tt_start;
  27968. +static struct timeval tt_end;
  27969. +
  27970. +/*
  27971. + * dummy device structure
  27972. + */
  27973. +
  27974. +static struct {
  27975. + softc_device_decl sc_dev;
  27976. +} mv_cesa_dev;
  27977. +
  27978. +static device_method_t mv_cesa_methods = {
  27979. + /* crypto device methods */
  27980. + DEVMETHOD(cryptodev_newsession, cesa_ocf_newsession),
  27981. + DEVMETHOD(cryptodev_freesession,cesa_ocf_freesession),
  27982. + DEVMETHOD(cryptodev_process, cesa_ocf_process),
  27983. + DEVMETHOD(cryptodev_kprocess, NULL),
  27984. +};
  27985. +
  27986. +
  27987. +
  27988. +/* Add debug Trace */
  27989. +#undef CESA_OCF_TRACE_DEBUG
  27990. +#ifdef CESA_OCF_TRACE_DEBUG
  27991. +
  27992. +#define MV_CESA_USE_TIMER_ID 0
  27993. +
  27994. +typedef struct
  27995. +{
  27996. + int type; /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */
  27997. + MV_U32 timeStamp;
  27998. + MV_U32 cause;
  27999. + MV_U32 realCause;
  28000. + MV_U32 dmaCause;
  28001. + int resources;
  28002. + MV_CESA_REQ* pReqReady;
  28003. + MV_CESA_REQ* pReqEmpty;
  28004. + MV_CESA_REQ* pReqProcess;
  28005. +} MV_CESA_TEST_TRACE;
  28006. +
  28007. +#define MV_CESA_TEST_TRACE_SIZE 50
  28008. +
  28009. +static int cesaTestTraceIdx = 0;
  28010. +static MV_CESA_TEST_TRACE cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];
  28011. +
  28012. +static void cesaTestTraceAdd(int type)
  28013. +{
  28014. + cesaTestTrace[cesaTestTraceIdx].type = type;
  28015. + cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  28016. + //cesaTestTrace[cesaTestTraceIdx].idmaCause = MV_REG_READ(IDMA_CAUSE_REG);
  28017. + cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;
  28018. + cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;
  28019. + cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;
  28020. + cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;
  28021. + cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);
  28022. + cesaTestTraceIdx++;
  28023. + if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)
  28024. + cesaTestTraceIdx = 0;
  28025. +}
  28026. +
  28027. +#else /* CESA_OCF_TRACE_DEBUG */
  28028. +
  28029. +#define cesaTestTraceAdd(x)
  28030. +
  28031. +#endif /* CESA_OCF_TRACE_DEBUG */
  28032. +
  28033. +unsigned int
  28034. +get_usec(unsigned int start)
  28035. +{
  28036. + if(start) {
  28037. + do_gettimeofday (&tt_start);
  28038. + return 0;
  28039. + }
  28040. + else {
  28041. + do_gettimeofday (&tt_end);
  28042. + tt_end.tv_sec -= tt_start.tv_sec;
  28043. + tt_end.tv_usec -= tt_start.tv_usec;
  28044. + if (tt_end.tv_usec < 0) {
  28045. + tt_end.tv_usec += 1000 * 1000;
  28046. + tt_end.tv_sec -= 1;
  28047. + }
  28048. + }
  28049. + printk("time taken is %d\n", (unsigned int)(tt_end.tv_usec + tt_end.tv_sec * 1000000));
  28050. + return (tt_end.tv_usec + tt_end.tv_sec * 1000000);
  28051. +}
  28052. +
  28053. +#ifdef RT_DEBUG
  28054. +/*
  28055. + * check that the crp action match the current session
  28056. + */
  28057. +static int
  28058. +ocf_check_action(struct cryptop *crp, struct cesa_ocf_data *cesa_ocf_cur_ses) {
  28059. + int count = 0;
  28060. + int encrypt = 0, decrypt = 0, auth = 0;
  28061. + struct cryptodesc *crd;
  28062. +
  28063. + /* Go through crypto descriptors, processing as we go */
  28064. + for (crd = crp->crp_desc; crd; crd = crd->crd_next, count++) {
  28065. + if(count > 2) {
  28066. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  28067. + return 1;
  28068. + }
  28069. +
  28070. + /* Encryption /Decryption */
  28071. + if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
  28072. + /* check that the action is compatible with session */
  28073. + if(encrypt || decrypt) {
  28074. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  28075. + return 1;
  28076. + }
  28077. +
  28078. + if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  28079. + if( (count == 2) && (cesa_ocf_cur_ses->encrypt_tn_auth) ) {
  28080. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  28081. + return 1;
  28082. + }
  28083. + encrypt++;
  28084. + }
  28085. + else { /* decrypt */
  28086. + if( (count == 2) && !(cesa_ocf_cur_ses->auth_tn_decrypt) ) {
  28087. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  28088. + return 1;
  28089. + }
  28090. + decrypt++;
  28091. + }
  28092. +
  28093. + }
  28094. + /* Authentication */
  28095. + else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
  28096. + /* check that the action is compatible with session */
  28097. + if(auth) {
  28098. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  28099. + return 1;
  28100. + }
  28101. + if( (count == 2) && (decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
  28102. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  28103. + return 1;
  28104. + }
  28105. + if( (count == 2) && (encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)) {
  28106. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  28107. + return 1;
  28108. + }
  28109. + auth++;
  28110. + }
  28111. + else {
  28112. + printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
  28113. + return 1;
  28114. + }
  28115. + }
  28116. + return 0;
  28117. +
  28118. +}
  28119. +#endif
  28120. +
  28121. +/*
  28122. + * Process a request.
  28123. + */
  28124. +static int
  28125. +cesa_ocf_process(device_t dev, struct cryptop *crp, int hint)
  28126. +{
  28127. + struct cesa_ocf_process *cesa_ocf_cmd = NULL;
  28128. + struct cesa_ocf_process *cesa_ocf_cmd_wa = NULL;
  28129. + MV_CESA_COMMAND *cesa_cmd;
  28130. + struct cryptodesc *crd;
  28131. + struct cesa_ocf_data *cesa_ocf_cur_ses;
  28132. + int sid = 0, temp_len = 0, i;
  28133. + int encrypt = 0, decrypt = 0, auth = 0;
  28134. + int status;
  28135. + struct sk_buff *skb = NULL;
  28136. + struct uio *uiop = NULL;
  28137. + unsigned char *ivp;
  28138. + MV_BUF_INFO *p_buf_info;
  28139. + MV_CESA_MBUF *p_mbuf_info;
  28140. + unsigned long flags;
  28141. +
  28142. + dprintk("%s()\n", __FUNCTION__);
  28143. +
  28144. + if( cesaReqResources <= 1 ) {
  28145. + dprintk("%s,%d: ERESTART\n", __FILE__, __LINE__);
  28146. + return ERESTART;
  28147. + }
  28148. +
  28149. +#ifdef RT_DEBUG
  28150. + /* Sanity check */
  28151. + if (crp == NULL) {
  28152. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  28153. + return EINVAL;
  28154. + }
  28155. +
  28156. + if (crp->crp_desc == NULL || crp->crp_buf == NULL ) {
  28157. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  28158. + crp->crp_etype = EINVAL;
  28159. + return EINVAL;
  28160. + }
  28161. +
  28162. + sid = crp->crp_sid & 0xffffffff;
  28163. + if ((sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL)) {
  28164. + crp->crp_etype = ENOENT;
  28165. + printk("%s,%d: ENOENT session %d \n", __FILE__, __LINE__, sid);
  28166. + return EINVAL;
  28167. + }
  28168. +#endif
  28169. +
  28170. + sid = crp->crp_sid & 0xffffffff;
  28171. + crp->crp_etype = 0;
  28172. + cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
  28173. +
  28174. +#ifdef RT_DEBUG
  28175. + if(ocf_check_action(crp, cesa_ocf_cur_ses)){
  28176. + goto p_error;
  28177. + }
  28178. +#endif
  28179. +
  28180. + /* malloc a new cesa process */
  28181. + cesa_ocf_cmd = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
  28182. +
  28183. + if (cesa_ocf_cmd == NULL) {
  28184. + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
  28185. + goto p_error;
  28186. + }
  28187. + memset(cesa_ocf_cmd, 0, sizeof(struct cesa_ocf_process));
  28188. +
  28189. + /* init cesa_process */
  28190. + cesa_ocf_cmd->crp = crp;
  28191. + /* always call callback */
  28192. + cesa_ocf_cmd->need_cb = 1;
  28193. +
  28194. + /* init cesa_cmd for usage of the HALs */
  28195. + cesa_cmd = &cesa_ocf_cmd->cesa_cmd;
  28196. + cesa_cmd->pReqPrv = (void *)cesa_ocf_cmd;
  28197. + cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_encrypt; /* defualt use encrypt */
  28198. +
  28199. + /* prepare src buffer */
  28200. + /* we send the entire buffer to the HAL, even if only part of it should be encrypt/auth. */
  28201. + /* if not using seesions for both encrypt and auth, then it will be wiser to to copy only */
  28202. + /* from skip to crd_len. */
  28203. + p_buf_info = cesa_ocf_cmd->cesa_bufs;
  28204. + p_mbuf_info = &cesa_ocf_cmd->cesa_mbuf;
  28205. +
  28206. + p_buf_info += 2; /* save 2 first buffers for IV and digest -
  28207. + we won't append them to the end since, they
  28208. + might be places in an unaligned addresses. */
  28209. +
  28210. + p_mbuf_info->pFrags = p_buf_info;
  28211. + temp_len = 0;
  28212. +
  28213. + /* handle SKB */
  28214. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  28215. +
  28216. + dprintk("%s,%d: handle SKB.\n", __FILE__, __LINE__);
  28217. + skb = (struct sk_buff *) crp->crp_buf;
  28218. +
  28219. + if (skb_shinfo(skb)->nr_frags >= (MV_CESA_MAX_MBUF_FRAGS - 1)) {
  28220. + printk("%s,%d: %d nr_frags > MV_CESA_MAX_MBUF_FRAGS", __FILE__, __LINE__, skb_shinfo(skb)->nr_frags);
  28221. + goto p_error;
  28222. + }
  28223. +
  28224. + p_mbuf_info->mbufSize = skb->len;
  28225. + temp_len = skb->len;
  28226. + /* first skb fragment */
  28227. + p_buf_info->bufSize = skb_headlen(skb);
  28228. + p_buf_info->bufVirtPtr = skb->data;
  28229. + p_buf_info++;
  28230. +
  28231. + /* now handle all other skb fragments */
  28232. + for ( i = 0; i < skb_shinfo(skb)->nr_frags; i++ ) {
  28233. + skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
  28234. + p_buf_info->bufSize = frag->size;
  28235. + p_buf_info->bufVirtPtr = page_address(frag->page) + frag->page_offset;
  28236. + p_buf_info++;
  28237. + }
  28238. + p_mbuf_info->numFrags = skb_shinfo(skb)->nr_frags + 1;
  28239. + }
  28240. + /* handle UIO */
  28241. + else if(crp->crp_flags & CRYPTO_F_IOV) {
  28242. +
  28243. + dprintk("%s,%d: handle UIO.\n", __FILE__, __LINE__);
  28244. + uiop = (struct uio *) crp->crp_buf;
  28245. +
  28246. + if (uiop->uio_iovcnt > (MV_CESA_MAX_MBUF_FRAGS - 1)) {
  28247. + printk("%s,%d: %d uio_iovcnt > MV_CESA_MAX_MBUF_FRAGS \n", __FILE__, __LINE__, uiop->uio_iovcnt);
  28248. + goto p_error;
  28249. + }
  28250. +
  28251. + p_mbuf_info->mbufSize = crp->crp_ilen;
  28252. + p_mbuf_info->numFrags = uiop->uio_iovcnt;
  28253. + for(i = 0; i < uiop->uio_iovcnt; i++) {
  28254. + p_buf_info->bufVirtPtr = uiop->uio_iov[i].iov_base;
  28255. + p_buf_info->bufSize = uiop->uio_iov[i].iov_len;
  28256. + temp_len += p_buf_info->bufSize;
  28257. + dprintk("%s,%d: buf %x-> addr %x, size %x \n"
  28258. + , __FILE__, __LINE__, i, (unsigned int)p_buf_info->bufVirtPtr, p_buf_info->bufSize);
  28259. + p_buf_info++;
  28260. + }
  28261. +
  28262. + }
  28263. + /* handle CONTIG */
  28264. + else {
  28265. + dprintk("%s,%d: handle CONTIG.\n", __FILE__, __LINE__);
  28266. + p_mbuf_info->numFrags = 1;
  28267. + p_mbuf_info->mbufSize = crp->crp_ilen;
  28268. + p_buf_info->bufVirtPtr = crp->crp_buf;
  28269. + p_buf_info->bufSize = crp->crp_ilen;
  28270. + temp_len = crp->crp_ilen;
  28271. + p_buf_info++;
  28272. + }
  28273. +
  28274. + /* Support up to 64K why? cause! */
  28275. + if(crp->crp_ilen > 64*1024) {
  28276. + printk("%s,%d: buf too big %x \n", __FILE__, __LINE__, crp->crp_ilen);
  28277. + goto p_error;
  28278. + }
  28279. +
  28280. + if( temp_len != crp->crp_ilen ) {
  28281. + printk("%s,%d: warning size don't match.(%x %x) \n", __FILE__, __LINE__, temp_len, crp->crp_ilen);
  28282. + }
  28283. +
  28284. + cesa_cmd->pSrc = p_mbuf_info;
  28285. + cesa_cmd->pDst = p_mbuf_info;
  28286. +
  28287. + /* restore p_buf_info to point to first available buf */
  28288. + p_buf_info = cesa_ocf_cmd->cesa_bufs;
  28289. + p_buf_info += 1;
  28290. +
  28291. +
  28292. + /* Go through crypto descriptors, processing as we go */
  28293. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  28294. +
  28295. + /* Encryption /Decryption */
  28296. + if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
  28297. +
  28298. + dprintk("%s,%d: cipher", __FILE__, __LINE__);
  28299. +
  28300. + cesa_cmd->cryptoOffset = crd->crd_skip;
  28301. + cesa_cmd->cryptoLength = crd->crd_len;
  28302. +
  28303. + if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  28304. + dprintk(" encrypt \n");
  28305. + encrypt++;
  28306. +
  28307. + /* handle IV */
  28308. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) { /* IV from USER */
  28309. + dprintk("%s,%d: IV from USER (offset %x) \n", __FILE__, __LINE__, crd->crd_inject);
  28310. + cesa_cmd->ivFromUser = 1;
  28311. + ivp = crd->crd_iv;
  28312. +
  28313. + /*
  28314. + * do we have to copy the IV back to the buffer ?
  28315. + */
  28316. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  28317. + dprintk("%s,%d: copy the IV back to the buffer\n", __FILE__, __LINE__);
  28318. + cesa_cmd->ivOffset = crd->crd_inject;
  28319. + crypto_copy_bits_back(crp->crp_buf, crd->crd_inject, ivp, cesa_ocf_cur_ses->ivlen);
  28320. + }
  28321. + else {
  28322. + dprintk("%s,%d: don't copy the IV back to the buffer \n", __FILE__, __LINE__);
  28323. + p_mbuf_info->numFrags++;
  28324. + p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
  28325. + p_mbuf_info->pFrags = p_buf_info;
  28326. +
  28327. + p_buf_info->bufVirtPtr = ivp;
  28328. + p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
  28329. + p_buf_info--;
  28330. +
  28331. + /* offsets */
  28332. + cesa_cmd->ivOffset = 0;
  28333. + cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
  28334. + if(auth) {
  28335. + cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
  28336. + cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
  28337. + }
  28338. + }
  28339. + }
  28340. + else { /* random IV */
  28341. + dprintk("%s,%d: random IV \n", __FILE__, __LINE__);
  28342. + cesa_cmd->ivFromUser = 0;
  28343. +
  28344. + /*
  28345. + * do we have to copy the IV back to the buffer ?
  28346. + */
  28347. + /* in this mode the HAL will always copy the IV */
  28348. + /* given by the session to the ivOffset */
  28349. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  28350. + cesa_cmd->ivOffset = crd->crd_inject;
  28351. + }
  28352. + else {
  28353. + /* if IV isn't copy, then how will the user know which IV did we use??? */
  28354. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  28355. + goto p_error;
  28356. + }
  28357. + }
  28358. + }
  28359. + else { /* decrypt */
  28360. + dprintk(" decrypt \n");
  28361. + decrypt++;
  28362. + cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_decrypt;
  28363. +
  28364. + /* handle IV */
  28365. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  28366. + dprintk("%s,%d: IV from USER \n", __FILE__, __LINE__);
  28367. + /* append the IV buf to the mbuf */
  28368. + cesa_cmd->ivFromUser = 1;
  28369. + p_mbuf_info->numFrags++;
  28370. + p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
  28371. + p_mbuf_info->pFrags = p_buf_info;
  28372. +
  28373. + p_buf_info->bufVirtPtr = crd->crd_iv;
  28374. + p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
  28375. + p_buf_info--;
  28376. +
  28377. + /* offsets */
  28378. + cesa_cmd->ivOffset = 0;
  28379. + cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
  28380. + if(auth) {
  28381. + cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
  28382. + cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
  28383. + }
  28384. + }
  28385. + else {
  28386. + dprintk("%s,%d: IV inside the buffer \n", __FILE__, __LINE__);
  28387. + cesa_cmd->ivFromUser = 0;
  28388. + cesa_cmd->ivOffset = crd->crd_inject;
  28389. + }
  28390. + }
  28391. +
  28392. + }
  28393. + /* Authentication */
  28394. + else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
  28395. + dprintk("%s,%d: Authentication \n", __FILE__, __LINE__);
  28396. + auth++;
  28397. + cesa_cmd->macOffset = crd->crd_skip;
  28398. + cesa_cmd->macLength = crd->crd_len;
  28399. +
  28400. + /* digest + mac */
  28401. + cesa_cmd->digestOffset = crd->crd_inject;
  28402. + }
  28403. + else {
  28404. + printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
  28405. + goto p_error;
  28406. + }
  28407. + }
  28408. +
  28409. + dprintk("\n");
  28410. + dprintk("%s,%d: Sending Action: \n", __FILE__, __LINE__);
  28411. + dprintk("%s,%d: IV from user: %d. IV offset %x \n", __FILE__, __LINE__, cesa_cmd->ivFromUser, cesa_cmd->ivOffset);
  28412. + dprintk("%s,%d: crypt offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->cryptoOffset, cesa_cmd->cryptoLength);
  28413. + dprintk("%s,%d: Auth offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->macOffset, cesa_cmd->macLength);
  28414. + dprintk("%s,%d: set digest in offset %x . \n", __FILE__, __LINE__, cesa_cmd->digestOffset);
  28415. + if(debug) {
  28416. + mvCesaDebugMbuf("SRC BUFFER", cesa_cmd->pSrc, 0, cesa_cmd->pSrc->mbufSize);
  28417. + }
  28418. +
  28419. +
  28420. + /* send action to HAL */
  28421. + spin_lock_irqsave(&cesa_lock, flags);
  28422. + status = mvCesaAction(cesa_cmd);
  28423. + spin_unlock_irqrestore(&cesa_lock, flags);
  28424. +
  28425. + /* action not allowed */
  28426. + if(status == MV_NOT_ALLOWED) {
  28427. +#ifdef CESA_OCF_SPLIT
  28428. + /* if both encrypt and auth try to split */
  28429. + if(auth && (encrypt || decrypt)) {
  28430. + MV_CESA_COMMAND *cesa_cmd_wa;
  28431. +
  28432. + /* malloc a new cesa process and init it */
  28433. + cesa_ocf_cmd_wa = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
  28434. +
  28435. + if (cesa_ocf_cmd_wa == NULL) {
  28436. + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
  28437. + goto p_error;
  28438. + }
  28439. + memcpy(cesa_ocf_cmd_wa, cesa_ocf_cmd, sizeof(struct cesa_ocf_process));
  28440. + cesa_cmd_wa = &cesa_ocf_cmd_wa->cesa_cmd;
  28441. + cesa_cmd_wa->pReqPrv = (void *)cesa_ocf_cmd_wa;
  28442. + cesa_ocf_cmd_wa->need_cb = 0;
  28443. +
  28444. + /* break requests to two operation, first operation completion won't call callback */
  28445. + if((decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
  28446. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  28447. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
  28448. + }
  28449. + else if((decrypt) && !(cesa_ocf_cur_ses->auth_tn_decrypt)) {
  28450. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
  28451. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  28452. + }
  28453. + else if((encrypt) && (cesa_ocf_cur_ses->encrypt_tn_auth)) {
  28454. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
  28455. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  28456. + }
  28457. + else if((encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)){
  28458. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  28459. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
  28460. + }
  28461. + else {
  28462. + printk("%s,%d: Unsupporterd fragment wa mode \n", __FILE__, __LINE__);
  28463. + goto p_error;
  28464. + }
  28465. +
  28466. + /* send the 2 actions to the HAL */
  28467. + spin_lock_irqsave(&cesa_lock, flags);
  28468. + status = mvCesaAction(cesa_cmd_wa);
  28469. + spin_unlock_irqrestore(&cesa_lock, flags);
  28470. +
  28471. + if((status != MV_NO_MORE) && (status != MV_OK)) {
  28472. + printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
  28473. + goto p_error;
  28474. + }
  28475. + spin_lock_irqsave(&cesa_lock, flags);
  28476. + status = mvCesaAction(cesa_cmd);
  28477. + spin_unlock_irqrestore(&cesa_lock, flags);
  28478. +
  28479. + }
  28480. + /* action not allowed and can't split */
  28481. + else
  28482. +#endif
  28483. + {
  28484. + goto p_error;
  28485. + }
  28486. + }
  28487. +
  28488. + /* Hal Q is full, send again. This should never happen */
  28489. + if(status == MV_NO_RESOURCE) {
  28490. + printk("%s,%d: cesa no more resources \n", __FILE__, __LINE__);
  28491. + if(cesa_ocf_cmd)
  28492. + kfree(cesa_ocf_cmd);
  28493. + if(cesa_ocf_cmd_wa)
  28494. + kfree(cesa_ocf_cmd_wa);
  28495. + return ERESTART;
  28496. + }
  28497. + else if((status != MV_NO_MORE) && (status != MV_OK)) {
  28498. + printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
  28499. + goto p_error;
  28500. + }
  28501. +
  28502. +
  28503. +#ifdef CESA_OCF_POLLING
  28504. + cesa_interrupt_polling();
  28505. +#endif
  28506. + cesaTestTraceAdd(5);
  28507. +
  28508. + return 0;
  28509. +p_error:
  28510. + crp->crp_etype = EINVAL;
  28511. + if(cesa_ocf_cmd)
  28512. + kfree(cesa_ocf_cmd);
  28513. + if(cesa_ocf_cmd_wa)
  28514. + kfree(cesa_ocf_cmd_wa);
  28515. + return EINVAL;
  28516. +}
  28517. +
  28518. +/*
  28519. + * cesa callback.
  28520. + */
  28521. +static void
  28522. +cesa_callback(unsigned long dummy)
  28523. +{
  28524. + struct cesa_ocf_process *cesa_ocf_cmd = NULL;
  28525. + struct cryptop *crp = NULL;
  28526. + MV_CESA_RESULT result[MV_CESA_MAX_CHAN];
  28527. + int res_idx = 0,i;
  28528. + MV_STATUS status;
  28529. +
  28530. + dprintk("%s()\n", __FUNCTION__);
  28531. +
  28532. +#ifdef CESA_OCF_TASKLET
  28533. + disable_irq(cesa_device.irq);
  28534. +#endif
  28535. + while(MV_TRUE) {
  28536. +
  28537. + /* Get Ready requests */
  28538. + spin_lock(&cesa_lock);
  28539. + status = mvCesaReadyGet(&result[res_idx]);
  28540. + spin_unlock(&cesa_lock);
  28541. +
  28542. + cesaTestTraceAdd(2);
  28543. +
  28544. + if(status != MV_OK) {
  28545. +#ifdef CESA_OCF_POLLING
  28546. + if(status == MV_BUSY) { /* Fragment */
  28547. + cesa_interrupt_polling();
  28548. + return;
  28549. + }
  28550. +#endif
  28551. + break;
  28552. + }
  28553. + res_idx++;
  28554. + break;
  28555. + }
  28556. +
  28557. + for(i = 0; i < res_idx; i++) {
  28558. +
  28559. + if(!result[i].pReqPrv) {
  28560. + printk("%s,%d: warning private is NULL\n", __FILE__, __LINE__);
  28561. + break;
  28562. + }
  28563. +
  28564. + cesa_ocf_cmd = result[i].pReqPrv;
  28565. + crp = cesa_ocf_cmd->crp;
  28566. +
  28567. + // ignore HMAC error.
  28568. + //if(result->retCode)
  28569. + // crp->crp_etype = EIO;
  28570. +
  28571. +#if defined(CESA_OCF_POLLING)
  28572. + if(!cesa_ocf_cmd->need_cb){
  28573. + cesa_interrupt_polling();
  28574. + }
  28575. +#endif
  28576. + if(cesa_ocf_cmd->need_cb) {
  28577. + if(debug) {
  28578. + mvCesaDebugMbuf("DST BUFFER", cesa_ocf_cmd->cesa_cmd.pDst, 0, cesa_ocf_cmd->cesa_cmd.pDst->mbufSize);
  28579. + }
  28580. + crypto_done(crp);
  28581. + }
  28582. + kfree(cesa_ocf_cmd);
  28583. + }
  28584. +#ifdef CESA_OCF_TASKLET
  28585. + enable_irq(cesa_device.irq);
  28586. +#endif
  28587. +
  28588. + cesaTestTraceAdd(3);
  28589. +
  28590. + return;
  28591. +}
  28592. +
  28593. +#ifdef CESA_OCF_POLLING
  28594. +static void
  28595. +cesa_interrupt_polling(void)
  28596. +{
  28597. + u32 cause;
  28598. +
  28599. + dprintk("%s()\n", __FUNCTION__);
  28600. +
  28601. + /* Read cause register */
  28602. + do {
  28603. + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  28604. + cause &= MV_CESA_CAUSE_ACC_DMA_ALL_MASK;
  28605. +
  28606. + } while (cause == 0);
  28607. +
  28608. + /* clear interrupts */
  28609. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  28610. +
  28611. + cesa_callback(0);
  28612. +
  28613. + return;
  28614. +}
  28615. +
  28616. +#endif
  28617. +
  28618. +/*
  28619. + * cesa Interrupt polling routine.
  28620. + */
  28621. +static irqreturn_t
  28622. +cesa_interrupt_handler(int irq, void *arg)
  28623. +{
  28624. + u32 cause;
  28625. +
  28626. + dprintk("%s()\n", __FUNCTION__);
  28627. +
  28628. + cesaTestTraceAdd(0);
  28629. +
  28630. + /* Read cause register */
  28631. + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  28632. +
  28633. + if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)
  28634. + {
  28635. + /* Empty interrupt */
  28636. + dprintk("%s,%d: cesaTestReadyIsr: cause=0x%x\n", __FILE__, __LINE__, cause);
  28637. + return IRQ_HANDLED;
  28638. + }
  28639. +
  28640. + /* clear interrupts */
  28641. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  28642. +
  28643. + cesaTestTraceAdd(1);
  28644. +#ifdef CESA_OCF_TASKLET
  28645. + tasklet_hi_schedule(&cesa_ocf_tasklet);
  28646. +#else
  28647. + cesa_callback(0);
  28648. +#endif
  28649. + return IRQ_HANDLED;
  28650. +}
  28651. +
  28652. +/*
  28653. + * Open a session.
  28654. + */
  28655. +static int
  28656. +/*cesa_ocf_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)*/
  28657. +cesa_ocf_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  28658. +{
  28659. + u32 status = 0, i;
  28660. + u32 count = 0, auth = 0, encrypt =0;
  28661. + struct cesa_ocf_data *cesa_ocf_cur_ses;
  28662. + MV_CESA_OPEN_SESSION cesa_session;
  28663. + MV_CESA_OPEN_SESSION *cesa_ses = &cesa_session;
  28664. +
  28665. +
  28666. + dprintk("%s()\n", __FUNCTION__);
  28667. + if (sid == NULL || cri == NULL) {
  28668. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  28669. + return EINVAL;
  28670. + }
  28671. +
  28672. + /* leave first empty like in other implementations */
  28673. + for (i = 1; i < CESA_OCF_MAX_SES; i++) {
  28674. + if (cesa_ocf_sessions[i] == NULL)
  28675. + break;
  28676. + }
  28677. +
  28678. + if(i >= CESA_OCF_MAX_SES) {
  28679. + printk("%s,%d: no more sessions \n", __FILE__, __LINE__);
  28680. + return EINVAL;
  28681. + }
  28682. +
  28683. + cesa_ocf_sessions[i] = (struct cesa_ocf_data *) kmalloc(sizeof(struct cesa_ocf_data), GFP_ATOMIC);
  28684. + if (cesa_ocf_sessions[i] == NULL) {
  28685. + cesa_ocf_freesession(NULL, i);
  28686. + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
  28687. + return ENOBUFS;
  28688. + }
  28689. + dprintk("%s,%d: new session %d \n", __FILE__, __LINE__, i);
  28690. +
  28691. + *sid = i;
  28692. + cesa_ocf_cur_ses = cesa_ocf_sessions[i];
  28693. + memset(cesa_ocf_cur_ses, 0, sizeof(struct cesa_ocf_data));
  28694. + cesa_ocf_cur_ses->sid_encrypt = -1;
  28695. + cesa_ocf_cur_ses->sid_decrypt = -1;
  28696. + cesa_ocf_cur_ses->frag_wa_encrypt = -1;
  28697. + cesa_ocf_cur_ses->frag_wa_decrypt = -1;
  28698. + cesa_ocf_cur_ses->frag_wa_auth = -1;
  28699. +
  28700. + /* init the session */
  28701. + memset(cesa_ses, 0, sizeof(MV_CESA_OPEN_SESSION));
  28702. + count = 1;
  28703. + while (cri) {
  28704. + if(count > 2) {
  28705. + printk("%s,%d: don't support more then 2 operations\n", __FILE__, __LINE__);
  28706. + goto error;
  28707. + }
  28708. + switch (cri->cri_alg) {
  28709. + case CRYPTO_AES_CBC:
  28710. + dprintk("%s,%d: (%d) AES CBC \n", __FILE__, __LINE__, count);
  28711. + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
  28712. + cesa_ocf_cur_ses->ivlen = MV_CESA_AES_BLOCK_SIZE;
  28713. + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_AES;
  28714. + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
  28715. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  28716. + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
  28717. + goto error;
  28718. + }
  28719. + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
  28720. + dprintk("%s,%d: key length %d \n", __FILE__, __LINE__, cri->cri_klen/8);
  28721. + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
  28722. + encrypt += count;
  28723. + break;
  28724. + case CRYPTO_3DES_CBC:
  28725. + dprintk("%s,%d: (%d) 3DES CBC \n", __FILE__, __LINE__, count);
  28726. + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
  28727. + cesa_ocf_cur_ses->ivlen = MV_CESA_3DES_BLOCK_SIZE;
  28728. + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_3DES;
  28729. + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
  28730. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  28731. + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
  28732. + goto error;
  28733. + }
  28734. + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
  28735. + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
  28736. + encrypt += count;
  28737. + break;
  28738. + case CRYPTO_DES_CBC:
  28739. + dprintk("%s,%d: (%d) DES CBC \n", __FILE__, __LINE__, count);
  28740. + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
  28741. + cesa_ocf_cur_ses->ivlen = MV_CESA_DES_BLOCK_SIZE;
  28742. + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_DES;
  28743. + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
  28744. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  28745. + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
  28746. + goto error;
  28747. + }
  28748. + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
  28749. + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
  28750. + encrypt += count;
  28751. + break;
  28752. + case CRYPTO_MD5:
  28753. + case CRYPTO_MD5_HMAC:
  28754. + dprintk("%s,%d: (%d) %sMD5 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_MD5)? "H-":" ");
  28755. + cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
  28756. + cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MD5_DIGEST_SIZE : 12;
  28757. + cesa_ses->macMode = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MAC_MD5 : MV_CESA_MAC_HMAC_MD5;
  28758. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  28759. + printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
  28760. + goto error;
  28761. + }
  28762. + cesa_ses->macKeyLength = cri->cri_klen/8;
  28763. + memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
  28764. + cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
  28765. + auth += count;
  28766. + break;
  28767. + case CRYPTO_SHA1:
  28768. + case CRYPTO_SHA1_HMAC:
  28769. + dprintk("%s,%d: (%d) %sSHA1 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_SHA1)? "H-":" ");
  28770. + cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
  28771. + cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_SHA1_DIGEST_SIZE : 12;
  28772. + cesa_ses->macMode = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_MAC_SHA1 : MV_CESA_MAC_HMAC_SHA1;
  28773. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  28774. + printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
  28775. + goto error;
  28776. + }
  28777. + cesa_ses->macKeyLength = cri->cri_klen/8;
  28778. + memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
  28779. + cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
  28780. + auth += count;
  28781. + break;
  28782. + default:
  28783. + printk("%s,%d: unknown algo 0x%x\n", __FILE__, __LINE__, cri->cri_alg);
  28784. + goto error;
  28785. + }
  28786. + cri = cri->cri_next;
  28787. + count++;
  28788. + }
  28789. +
  28790. + if((encrypt > 2) || (auth > 2)) {
  28791. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  28792. + goto error;
  28793. + }
  28794. + /* create new sessions in HAL */
  28795. + if(encrypt) {
  28796. + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
  28797. + /* encrypt session */
  28798. + if(auth == 1) {
  28799. + cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
  28800. + }
  28801. + else if(auth == 2) {
  28802. + cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
  28803. + cesa_ocf_cur_ses->encrypt_tn_auth = 1;
  28804. + }
  28805. + else {
  28806. + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
  28807. + }
  28808. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  28809. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
  28810. + if(status != MV_OK) {
  28811. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  28812. + goto error;
  28813. + }
  28814. + /* decrypt session */
  28815. + if( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) {
  28816. + cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
  28817. + }
  28818. + else if( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC ) {
  28819. + cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
  28820. + }
  28821. + cesa_ses->direction = MV_CESA_DIR_DECODE;
  28822. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_decrypt);
  28823. + if(status != MV_OK) {
  28824. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  28825. + goto error;
  28826. + }
  28827. +
  28828. + /* preapre one action sessions for case we will need to split an action */
  28829. +#ifdef CESA_OCF_SPLIT
  28830. + if(( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) ||
  28831. + ( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC )) {
  28832. + /* open one session for encode and one for decode */
  28833. + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
  28834. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  28835. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_encrypt);
  28836. + if(status != MV_OK) {
  28837. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  28838. + goto error;
  28839. + }
  28840. +
  28841. + cesa_ses->direction = MV_CESA_DIR_DECODE;
  28842. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_decrypt);
  28843. + if(status != MV_OK) {
  28844. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  28845. + goto error;
  28846. + }
  28847. + /* open one session for auth */
  28848. + cesa_ses->operation = MV_CESA_MAC_ONLY;
  28849. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  28850. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_auth);
  28851. + if(status != MV_OK) {
  28852. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  28853. + goto error;
  28854. + }
  28855. + }
  28856. +#endif
  28857. + }
  28858. + else { /* only auth */
  28859. + cesa_ses->operation = MV_CESA_MAC_ONLY;
  28860. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  28861. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
  28862. + if(status != MV_OK) {
  28863. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  28864. + goto error;
  28865. + }
  28866. + }
  28867. +
  28868. + return 0;
  28869. +error:
  28870. + cesa_ocf_freesession(NULL, *sid);
  28871. + return EINVAL;
  28872. +
  28873. +}
  28874. +
  28875. +
  28876. +/*
  28877. + * Free a session.
  28878. + */
  28879. +static int
  28880. +cesa_ocf_freesession(device_t dev, u_int64_t tid)
  28881. +{
  28882. + struct cesa_ocf_data *cesa_ocf_cur_ses;
  28883. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  28884. + //unsigned long flags;
  28885. +
  28886. + dprintk("%s() %d \n", __FUNCTION__, sid);
  28887. + if ( (sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL) ) {
  28888. + printk("%s,%d: EINVAL can't free session %d \n", __FILE__, __LINE__, sid);
  28889. + return(EINVAL);
  28890. + }
  28891. +
  28892. + /* Silently accept and return */
  28893. + if (sid == 0)
  28894. + return(0);
  28895. +
  28896. + /* release session from HAL */
  28897. + cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
  28898. + if (cesa_ocf_cur_ses->sid_encrypt != -1) {
  28899. + mvCesaSessionClose(cesa_ocf_cur_ses->sid_encrypt);
  28900. + }
  28901. + if (cesa_ocf_cur_ses->sid_decrypt != -1) {
  28902. + mvCesaSessionClose(cesa_ocf_cur_ses->sid_decrypt);
  28903. + }
  28904. + if (cesa_ocf_cur_ses->frag_wa_encrypt != -1) {
  28905. + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_encrypt);
  28906. + }
  28907. + if (cesa_ocf_cur_ses->frag_wa_decrypt != -1) {
  28908. + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_decrypt);
  28909. + }
  28910. + if (cesa_ocf_cur_ses->frag_wa_auth != -1) {
  28911. + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_auth);
  28912. + }
  28913. +
  28914. + kfree(cesa_ocf_cur_ses);
  28915. + cesa_ocf_sessions[sid] = NULL;
  28916. +
  28917. + return 0;
  28918. +}
  28919. +
  28920. +
  28921. +/* TDMA Window setup */
  28922. +
  28923. +static void __init
  28924. +setup_tdma_mbus_windows(struct cesa_dev *dev)
  28925. +{
  28926. + int i;
  28927. +
  28928. + for (i = 0; i < 4; i++) {
  28929. + writel(0, dev->reg + WINDOW_BASE(i));
  28930. + writel(0, dev->reg + WINDOW_CTRL(i));
  28931. + }
  28932. +
  28933. + for (i = 0; i < dev->plat_data->dram->num_cs; i++) {
  28934. + struct mbus_dram_window *cs = dev->plat_data->dram->cs + i;
  28935. + writel(
  28936. + ((cs->size - 1) & 0xffff0000) |
  28937. + (cs->mbus_attr << 8) |
  28938. + (dev->plat_data->dram->mbus_dram_target_id << 4) | 1,
  28939. + dev->reg + WINDOW_CTRL(i)
  28940. + );
  28941. + writel(cs->base, dev->reg + WINDOW_BASE(i));
  28942. + }
  28943. +}
  28944. +
  28945. +/*
  28946. + * our driver startup and shutdown routines
  28947. + */
  28948. +static int
  28949. +mv_cesa_ocf_init(struct platform_device *pdev)
  28950. +{
  28951. +#if defined(CONFIG_MV78200) || defined(CONFIG_MV632X)
  28952. + if (MV_FALSE == mvSocUnitIsMappedToThisCpu(CESA))
  28953. + {
  28954. + dprintk("CESA is not mapped to this CPU\n");
  28955. + return -ENODEV;
  28956. + }
  28957. +#endif
  28958. +
  28959. + dprintk("%s\n", __FUNCTION__);
  28960. + memset(&mv_cesa_dev, 0, sizeof(mv_cesa_dev));
  28961. + softc_device_init(&mv_cesa_dev, "MV CESA", 0, mv_cesa_methods);
  28962. + cesa_ocf_id = crypto_get_driverid(softc_get_device(&mv_cesa_dev),CRYPTOCAP_F_HARDWARE);
  28963. +
  28964. + if (cesa_ocf_id < 0)
  28965. + panic("MV CESA crypto device cannot initialize!");
  28966. +
  28967. + dprintk("%s,%d: cesa ocf device id is %d \n", __FILE__, __LINE__, cesa_ocf_id);
  28968. +
  28969. + /* CESA unit is auto power on off */
  28970. +#if 0
  28971. + if (MV_FALSE == mvCtrlPwrClckGet(CESA_UNIT_ID,0))
  28972. + {
  28973. + printk("\nWarning CESA %d is Powered Off\n",0);
  28974. + return EINVAL;
  28975. + }
  28976. +#endif
  28977. +
  28978. + memset(&cesa_device, 0, sizeof(struct cesa_dev));
  28979. + /* Get the IRQ, and crypto memory regions */
  28980. + {
  28981. + struct resource *res;
  28982. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
  28983. +
  28984. + if (!res)
  28985. + return -ENXIO;
  28986. +
  28987. + cesa_device.sram = ioremap(res->start, res->end - res->start + 1);
  28988. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
  28989. +
  28990. + if (!res) {
  28991. + iounmap(cesa_device.sram);
  28992. + return -ENXIO;
  28993. + }
  28994. + cesa_device.reg = ioremap(res->start, res->end - res->start + 1);
  28995. + cesa_device.irq = platform_get_irq(pdev, 0);
  28996. + cesa_device.plat_data = pdev->dev.platform_data;
  28997. + setup_tdma_mbus_windows(&cesa_device);
  28998. +
  28999. + }
  29000. +
  29001. +
  29002. + if( MV_OK != mvCesaInit(CESA_OCF_MAX_SES*5, CESA_Q_SIZE, cesa_device.reg,
  29003. + NULL) ) {
  29004. + printk("%s,%d: mvCesaInit Failed. \n", __FILE__, __LINE__);
  29005. + return EINVAL;
  29006. + }
  29007. +
  29008. + /* clear and unmask Int */
  29009. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  29010. +#ifndef CESA_OCF_POLLING
  29011. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);
  29012. +#endif
  29013. +#ifdef CESA_OCF_TASKLET
  29014. + tasklet_init(&cesa_ocf_tasklet, cesa_callback, (unsigned int) 0);
  29015. +#endif
  29016. + /* register interrupt */
  29017. + if( request_irq( cesa_device.irq, cesa_interrupt_handler,
  29018. + (IRQF_DISABLED) , "cesa", &cesa_ocf_id) < 0) {
  29019. + printk("%s,%d: cannot assign irq %x\n", __FILE__, __LINE__, cesa_device.reg);
  29020. + return EINVAL;
  29021. + }
  29022. +
  29023. +
  29024. + memset(cesa_ocf_sessions, 0, sizeof(struct cesa_ocf_data *) * CESA_OCF_MAX_SES);
  29025. +
  29026. +#define REGISTER(alg) \
  29027. + crypto_register(cesa_ocf_id, alg, 0,0)
  29028. + REGISTER(CRYPTO_AES_CBC);
  29029. + REGISTER(CRYPTO_DES_CBC);
  29030. + REGISTER(CRYPTO_3DES_CBC);
  29031. + REGISTER(CRYPTO_MD5);
  29032. + REGISTER(CRYPTO_MD5_HMAC);
  29033. + REGISTER(CRYPTO_SHA1);
  29034. + REGISTER(CRYPTO_SHA1_HMAC);
  29035. +#undef REGISTER
  29036. +
  29037. + return 0;
  29038. +}
  29039. +
  29040. +static void
  29041. +mv_cesa_ocf_exit(struct platform_device *pdev)
  29042. +{
  29043. + dprintk("%s()\n", __FUNCTION__);
  29044. +
  29045. + crypto_unregister_all(cesa_ocf_id);
  29046. + cesa_ocf_id = -1;
  29047. + iounmap(cesa_device.reg);
  29048. + iounmap(cesa_device.sram);
  29049. + free_irq(cesa_device.irq, NULL);
  29050. +
  29051. + /* mask and clear Int */
  29052. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
  29053. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  29054. +
  29055. +
  29056. + if( MV_OK != mvCesaFinish() ) {
  29057. + printk("%s,%d: mvCesaFinish Failed. \n", __FILE__, __LINE__);
  29058. + return;
  29059. + }
  29060. +}
  29061. +
  29062. +
  29063. +void cesa_ocf_debug(void)
  29064. +{
  29065. +
  29066. +#ifdef CESA_OCF_TRACE_DEBUG
  29067. + {
  29068. + int i, j;
  29069. + j = cesaTestTraceIdx;
  29070. + mvOsPrintf("No Type rCause iCause Proc Isr Res Time pReady pProc pEmpty\n");
  29071. + for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)
  29072. + {
  29073. + mvOsPrintf("%02d. %d 0x%04x 0x%04x 0x%02x 0x%02x %02d 0x%06x %p %p %p\n",
  29074. + j, cesaTestTrace[j].type, cesaTestTrace[j].realCause,
  29075. + cesaTestTrace[j].idmaCause,
  29076. + cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,
  29077. + cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);
  29078. + j++;
  29079. + if(j == MV_CESA_TEST_TRACE_SIZE)
  29080. + j = 0;
  29081. + }
  29082. + }
  29083. +#endif
  29084. +
  29085. +}
  29086. +
  29087. +static struct platform_driver marvell_cesa = {
  29088. + .probe = mv_cesa_ocf_init,
  29089. + .remove = mv_cesa_ocf_exit,
  29090. + .driver = {
  29091. + .owner = THIS_MODULE,
  29092. + .name = "mv_crypto",
  29093. + },
  29094. +};
  29095. +
  29096. +MODULE_ALIAS("platform:mv_crypto");
  29097. +
  29098. +static int __init mv_cesa_init(void)
  29099. +{
  29100. + return platform_driver_register(&marvell_cesa);
  29101. +}
  29102. +
  29103. +module_init(mv_cesa_init);
  29104. +
  29105. +static void __exit mv_cesa_exit(void)
  29106. +{
  29107. + platform_driver_unregister(&marvell_cesa);
  29108. +}
  29109. +
  29110. +module_exit(mv_cesa_exit);
  29111. +
  29112. +MODULE_LICENSE("GPL");
  29113. +MODULE_AUTHOR("Ronen Shitrit");
  29114. +MODULE_DESCRIPTION("OCF module for Orion CESA crypto");
  29115. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/Makefile linux-2.6.36/crypto/ocf/kirkwood/Makefile
  29116. --- linux-2.6.36.orig/crypto/ocf/kirkwood/Makefile 1970-01-01 01:00:00.000000000 +0100
  29117. +++ linux-2.6.36/crypto/ocf/kirkwood/Makefile 2010-11-09 20:28:06.092495440 +0100
  29118. @@ -0,0 +1,19 @@
  29119. +# for SGlinux builds
  29120. +-include $(ROOTDIR)/modules/.config
  29121. +
  29122. +obj-$(CONFIG_OCF_KIRKWOOD) += mv_cesa.o
  29123. +
  29124. +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
  29125. +
  29126. +# Extra objects required by the CESA driver
  29127. +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
  29128. +
  29129. +ifdef src
  29130. +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)
  29131. +endif
  29132. +
  29133. +EXTRA_CFLAGS += -DMV_LINUX -DMV_CPU_LE -DMV_ARM -DMV_INCLUDE_CESA -DMV_INCLUDE_PEX -DMV_CACHE_COHERENCY=3
  29134. +ifdef TOPDIR
  29135. +-include $(TOPDIR)/Rules.make
  29136. +endif
  29137. +
  29138. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mv802_3.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mv802_3.h
  29139. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mv802_3.h 1970-01-01 01:00:00.000000000 +0100
  29140. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mv802_3.h 2010-11-09 20:28:06.131247793 +0100
  29141. @@ -0,0 +1,213 @@
  29142. +/*******************************************************************************
  29143. +Copyright (C) Marvell International Ltd. and its affiliates
  29144. +
  29145. +This software file (the "File") is owned and distributed by Marvell
  29146. +International Ltd. and/or its affiliates ("Marvell") under the following
  29147. +alternative licensing terms. Once you have made an election to distribute the
  29148. +File under one of the following license alternatives, please (i) delete this
  29149. +introductory statement regarding license alternatives, (ii) delete the two
  29150. +license alternatives that you have not elected to use and (iii) preserve the
  29151. +Marvell copyright notice above.
  29152. +
  29153. +********************************************************************************
  29154. +Marvell Commercial License Option
  29155. +
  29156. +If you received this File from Marvell and you have entered into a commercial
  29157. +license agreement (a "Commercial License") with Marvell, the File is licensed
  29158. +to you under the terms of the applicable Commercial License.
  29159. +
  29160. +********************************************************************************
  29161. +Marvell GPL License Option
  29162. +
  29163. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29164. +modify this File in accordance with the terms and conditions of the General
  29165. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  29166. +available along with the File in the license.txt file or by writing to the Free
  29167. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  29168. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  29169. +
  29170. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  29171. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  29172. +DISCLAIMED. The GPL License provides additional details about this warranty
  29173. +disclaimer.
  29174. +********************************************************************************
  29175. +Marvell BSD License Option
  29176. +
  29177. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29178. +modify this File under the following licensing terms.
  29179. +Redistribution and use in source and binary forms, with or without modification,
  29180. +are permitted provided that the following conditions are met:
  29181. +
  29182. + * Redistributions of source code must retain the above copyright notice,
  29183. + this list of conditions and the following disclaimer.
  29184. +
  29185. + * Redistributions in binary form must reproduce the above copyright
  29186. + notice, this list of conditions and the following disclaimer in the
  29187. + documentation and/or other materials provided with the distribution.
  29188. +
  29189. + * Neither the name of Marvell nor the names of its contributors may be
  29190. + used to endorse or promote products derived from this software without
  29191. + specific prior written permission.
  29192. +
  29193. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  29194. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  29195. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  29196. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  29197. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  29198. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29199. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  29200. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29201. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29202. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29203. +
  29204. +*******************************************************************************/
  29205. +
  29206. +
  29207. +#ifndef __INCmv802_3h
  29208. +#define __INCmv802_3h
  29209. +
  29210. +
  29211. +/* includes */
  29212. +#include "mvTypes.h"
  29213. +
  29214. +/* Defines */
  29215. +#define MV_MAX_ETH_DATA 1500
  29216. +
  29217. +/* 802.3 types */
  29218. +#define MV_IP_TYPE 0x0800
  29219. +#define MV_IP_ARP_TYPE 0x0806
  29220. +#define MV_APPLE_TALK_ARP_TYPE 0x80F3
  29221. +#define MV_NOVELL_IPX_TYPE 0x8137
  29222. +#define MV_EAPOL_TYPE 0x888e
  29223. +
  29224. +
  29225. +
  29226. +/* Encapsulation header for RFC1042 and Ethernet_tunnel */
  29227. +
  29228. +#define MV_RFC1042_SNAP_HEADER {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}
  29229. +
  29230. +#define MV_ETH_SNAP_LSB 0xF8
  29231. +
  29232. +
  29233. +#define MV_MAC_ADDR_SIZE (6)
  29234. +#define MV_MAC_STR_SIZE (20)
  29235. +#define MV_VLAN_HLEN (4)
  29236. +
  29237. +/* This macro checks for a multicast mac address */
  29238. +#define MV_IS_MULTICAST_MAC(mac) (((mac)[0] & 0x1) == 1)
  29239. +
  29240. +
  29241. +/* This macro checks for an broadcast mac address */
  29242. +#define MV_IS_BROADCAST_MAC(mac) \
  29243. + (((mac)[0] == 0xFF) && \
  29244. + ((mac)[1] == 0xFF) && \
  29245. + ((mac)[2] == 0xFF) && \
  29246. + ((mac)[3] == 0xFF) && \
  29247. + ((mac)[4] == 0xFF) && \
  29248. + ((mac)[5] == 0xFF))
  29249. +
  29250. +
  29251. +/* Typedefs */
  29252. +typedef struct
  29253. +{
  29254. + MV_U8 pDA[MV_MAC_ADDR_SIZE];
  29255. + MV_U8 pSA[MV_MAC_ADDR_SIZE];
  29256. + MV_U16 typeOrLen;
  29257. +
  29258. +} MV_802_3_HEADER;
  29259. +
  29260. +enum {
  29261. + MV_IP_PROTO_NULL = 0, /* Dummy protocol for TCP */
  29262. + MV_IP_PROTO_ICMP = 1, /* Internet Control Message Protocol */
  29263. + MV_IP_PROTO_IGMP = 2, /* Internet Group Management Protocol */
  29264. + MV_IP_PROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
  29265. + MV_IP_PROTO_TCP = 6, /* Transmission Control Protocol */
  29266. + MV_IP_PROTO_EGP = 8, /* Exterior Gateway Protocol */
  29267. + MV_IP_PROTO_PUP = 12, /* PUP protocol */
  29268. + MV_IP_PROTO_UDP = 17, /* User Datagram Protocol */
  29269. + MV_IP_PROTO_IDP = 22, /* XNS IDP protocol */
  29270. + MV_IP_PROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
  29271. + MV_IP_PROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
  29272. + MV_IP_PROTO_RSVP = 46, /* RSVP protocol */
  29273. + MV_IP_PROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
  29274. + MV_IP_PROTO_ESP = 50, /* Encapsulation Security Payload protocol */
  29275. + MV_IP_PROTO_AH = 51, /* Authentication Header protocol */
  29276. + MV_IP_PROTO_BEETPH = 94, /* IP option pseudo header for BEET */
  29277. + MV_IP_PROTO_PIM = 103,
  29278. + MV_IP_PROTO_COMP = 108, /* Compression Header protocol */
  29279. + MV_IP_PROTO_ZERO_HOP = 114, /* Any 0 hop protocol (IANA) */
  29280. + MV_IP_PROTO_SCTP = 132, /* Stream Control Transport Protocol */
  29281. + MV_IP_PROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
  29282. +
  29283. + MV_IP_PROTO_RAW = 255, /* Raw IP packets */
  29284. + MV_IP_PROTO_MAX
  29285. +};
  29286. +
  29287. +typedef struct
  29288. +{
  29289. + MV_U8 version;
  29290. + MV_U8 tos;
  29291. + MV_U16 totalLength;
  29292. + MV_U16 identifier;
  29293. + MV_U16 fragmentCtrl;
  29294. + MV_U8 ttl;
  29295. + MV_U8 protocol;
  29296. + MV_U16 checksum;
  29297. + MV_U32 srcIP;
  29298. + MV_U32 dstIP;
  29299. +
  29300. +} MV_IP_HEADER;
  29301. +
  29302. +typedef struct
  29303. +{
  29304. + MV_U32 spi;
  29305. + MV_U32 seqNum;
  29306. +} MV_ESP_HEADER;
  29307. +
  29308. +#define MV_ICMP_ECHOREPLY 0 /* Echo Reply */
  29309. +#define MV_ICMP_DEST_UNREACH 3 /* Destination Unreachable */
  29310. +#define MV_ICMP_SOURCE_QUENCH 4 /* Source Quench */
  29311. +#define MV_ICMP_REDIRECT 5 /* Redirect (change route) */
  29312. +#define MV_ICMP_ECHO 8 /* Echo Request */
  29313. +#define MV_ICMP_TIME_EXCEEDED 11 /* Time Exceeded */
  29314. +#define MV_ICMP_PARAMETERPROB 12 /* Parameter Problem */
  29315. +#define MV_ICMP_TIMESTAMP 13 /* Timestamp Request */
  29316. +#define MV_ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */
  29317. +#define MV_ICMP_INFO_REQUEST 15 /* Information Request */
  29318. +#define MV_ICMP_INFO_REPLY 16 /* Information Reply */
  29319. +#define MV_ICMP_ADDRESS 17 /* Address Mask Request */
  29320. +#define MV_ICMP_ADDRESSREPLY 18 /* Address Mask Reply */
  29321. +
  29322. +typedef struct
  29323. +{
  29324. + MV_U8 type;
  29325. + MV_U8 code;
  29326. + MV_U16 checksum;
  29327. + MV_U16 id;
  29328. + MV_U16 sequence;
  29329. +
  29330. +} MV_ICMP_ECHO_HEADER;
  29331. +
  29332. +typedef struct
  29333. +{
  29334. + MV_U16 source;
  29335. + MV_U16 dest;
  29336. + MV_U32 seq;
  29337. + MV_U32 ack_seq;
  29338. + MV_U16 flags;
  29339. + MV_U16 window;
  29340. + MV_U16 chksum;
  29341. + MV_U16 urg_offset;
  29342. +
  29343. +} MV_TCP_HEADER;
  29344. +
  29345. +typedef struct
  29346. +{
  29347. + MV_U16 source;
  29348. + MV_U16 dest;
  29349. + MV_U16 len;
  29350. + MV_U16 check;
  29351. +
  29352. +} MV_UDP_HEADER;
  29353. +
  29354. +#endif /* __INCmv802_3h */
  29355. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvCommon.c
  29356. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.c 1970-01-01 01:00:00.000000000 +0100
  29357. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvCommon.c 2010-11-09 20:28:06.172495450 +0100
  29358. @@ -0,0 +1,277 @@
  29359. +/*******************************************************************************
  29360. +Copyright (C) Marvell International Ltd. and its affiliates
  29361. +
  29362. +This software file (the "File") is owned and distributed by Marvell
  29363. +International Ltd. and/or its affiliates ("Marvell") under the following
  29364. +alternative licensing terms. Once you have made an election to distribute the
  29365. +File under one of the following license alternatives, please (i) delete this
  29366. +introductory statement regarding license alternatives, (ii) delete the two
  29367. +license alternatives that you have not elected to use and (iii) preserve the
  29368. +Marvell copyright notice above.
  29369. +
  29370. +********************************************************************************
  29371. +Marvell Commercial License Option
  29372. +
  29373. +If you received this File from Marvell and you have entered into a commercial
  29374. +license agreement (a "Commercial License") with Marvell, the File is licensed
  29375. +to you under the terms of the applicable Commercial License.
  29376. +
  29377. +********************************************************************************
  29378. +Marvell GPL License Option
  29379. +
  29380. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29381. +modify this File in accordance with the terms and conditions of the General
  29382. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  29383. +available along with the File in the license.txt file or by writing to the Free
  29384. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  29385. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  29386. +
  29387. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  29388. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  29389. +DISCLAIMED. The GPL License provides additional details about this warranty
  29390. +disclaimer.
  29391. +********************************************************************************
  29392. +Marvell BSD License Option
  29393. +
  29394. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29395. +modify this File under the following licensing terms.
  29396. +Redistribution and use in source and binary forms, with or without modification,
  29397. +are permitted provided that the following conditions are met:
  29398. +
  29399. + * Redistributions of source code must retain the above copyright notice,
  29400. + this list of conditions and the following disclaimer.
  29401. +
  29402. + * Redistributions in binary form must reproduce the above copyright
  29403. + notice, this list of conditions and the following disclaimer in the
  29404. + documentation and/or other materials provided with the distribution.
  29405. +
  29406. + * Neither the name of Marvell nor the names of its contributors may be
  29407. + used to endorse or promote products derived from this software without
  29408. + specific prior written permission.
  29409. +
  29410. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  29411. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  29412. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  29413. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  29414. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  29415. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29416. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  29417. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29418. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29419. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29420. +
  29421. +*******************************************************************************/
  29422. +
  29423. +#include "mvOs.h"
  29424. +#include "mv802_3.h"
  29425. +#include "mvCommon.h"
  29426. +
  29427. +
  29428. +/*******************************************************************************
  29429. +* mvMacStrToHex - Convert MAC format string to hex.
  29430. +*
  29431. +* DESCRIPTION:
  29432. +* This function convert MAC format string to hex.
  29433. +*
  29434. +* INPUT:
  29435. +* macStr - MAC address string. Fornat of address string is
  29436. +* uu:vv:ww:xx:yy:zz, where ":" can be any delimiter.
  29437. +*
  29438. +* OUTPUT:
  29439. +* macHex - MAC in hex format.
  29440. +*
  29441. +* RETURN:
  29442. +* None.
  29443. +*
  29444. +*******************************************************************************/
  29445. +MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex)
  29446. +{
  29447. + int i;
  29448. + char tmp[3];
  29449. +
  29450. + for(i = 0; i < MV_MAC_ADDR_SIZE; i++)
  29451. + {
  29452. + tmp[0] = macStr[(i * 3) + 0];
  29453. + tmp[1] = macStr[(i * 3) + 1];
  29454. + tmp[2] = '\0';
  29455. + macHex[i] = (MV_U8) (strtol(tmp, NULL, 16));
  29456. + }
  29457. + return MV_OK;
  29458. +}
  29459. +
  29460. +/*******************************************************************************
  29461. +* mvMacHexToStr - Convert MAC in hex format to string format.
  29462. +*
  29463. +* DESCRIPTION:
  29464. +* This function convert MAC in hex format to string format.
  29465. +*
  29466. +* INPUT:
  29467. +* macHex - MAC in hex format.
  29468. +*
  29469. +* OUTPUT:
  29470. +* macStr - MAC address string. String format is uu:vv:ww:xx:yy:zz.
  29471. +*
  29472. +* RETURN:
  29473. +* None.
  29474. +*
  29475. +*******************************************************************************/
  29476. +MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr)
  29477. +{
  29478. + int i;
  29479. +
  29480. + for(i = 0; i < MV_MAC_ADDR_SIZE; i++)
  29481. + {
  29482. + mvOsSPrintf(&macStr[i * 3], "%02x:", macHex[i]);
  29483. + }
  29484. + macStr[(i * 3) - 1] = '\0';
  29485. +
  29486. + return MV_OK;
  29487. +}
  29488. +
  29489. +/*******************************************************************************
  29490. +* mvSizePrint - Print the given size with size unit description.
  29491. +*
  29492. +* DESCRIPTION:
  29493. +* This function print the given size with size unit description.
  29494. +* FOr example when size paramter is 0x180000, the function prints:
  29495. +* "size 1MB+500KB"
  29496. +*
  29497. +* INPUT:
  29498. +* size - Size in bytes.
  29499. +*
  29500. +* OUTPUT:
  29501. +* None.
  29502. +*
  29503. +* RETURN:
  29504. +* None.
  29505. +*
  29506. +*******************************************************************************/
  29507. +MV_VOID mvSizePrint(MV_U32 size)
  29508. +{
  29509. + mvOsOutput("size ");
  29510. +
  29511. + if(size >= _1G)
  29512. + {
  29513. + mvOsOutput("%3dGB ", size / _1G);
  29514. + size %= _1G;
  29515. + if(size)
  29516. + mvOsOutput("+");
  29517. + }
  29518. + if(size >= _1M )
  29519. + {
  29520. + mvOsOutput("%3dMB ", size / _1M);
  29521. + size %= _1M;
  29522. + if(size)
  29523. + mvOsOutput("+");
  29524. + }
  29525. + if(size >= _1K)
  29526. + {
  29527. + mvOsOutput("%3dKB ", size / _1K);
  29528. + size %= _1K;
  29529. + if(size)
  29530. + mvOsOutput("+");
  29531. + }
  29532. + if(size > 0)
  29533. + {
  29534. + mvOsOutput("%3dB ", size);
  29535. + }
  29536. +}
  29537. +
  29538. +/*******************************************************************************
  29539. +* mvHexToBin - Convert hex to binary
  29540. +*
  29541. +* DESCRIPTION:
  29542. +* This function Convert hex to binary.
  29543. +*
  29544. +* INPUT:
  29545. +* pHexStr - hex buffer pointer.
  29546. +* size - Size to convert.
  29547. +*
  29548. +* OUTPUT:
  29549. +* pBin - Binary buffer pointer.
  29550. +*
  29551. +* RETURN:
  29552. +* None.
  29553. +*
  29554. +*******************************************************************************/
  29555. +MV_VOID mvHexToBin(const char* pHexStr, MV_U8* pBin, int size)
  29556. +{
  29557. + int j, i;
  29558. + char tmp[3];
  29559. + MV_U8 byte;
  29560. +
  29561. + for(j=0, i=0; j<size; j++, i+=2)
  29562. + {
  29563. + tmp[0] = pHexStr[i];
  29564. + tmp[1] = pHexStr[i+1];
  29565. + tmp[2] = '\0';
  29566. + byte = (MV_U8) (strtol(tmp, NULL, 16) & 0xFF);
  29567. + pBin[j] = byte;
  29568. + }
  29569. +}
  29570. +
  29571. +void mvAsciiToHex(const char* asciiStr, char* hexStr)
  29572. +{
  29573. + int i=0;
  29574. +
  29575. + while(asciiStr[i] != 0)
  29576. + {
  29577. + mvOsSPrintf(&hexStr[i*2], "%02x", asciiStr[i]);
  29578. + i++;
  29579. + }
  29580. + hexStr[i*2] = 0;
  29581. +}
  29582. +
  29583. +
  29584. +void mvBinToHex(const MV_U8* bin, char* hexStr, int size)
  29585. +{
  29586. + int i;
  29587. +
  29588. + for(i=0; i<size; i++)
  29589. + {
  29590. + mvOsSPrintf(&hexStr[i*2], "%02x", bin[i]);
  29591. + }
  29592. + hexStr[i*2] = '\0';
  29593. +}
  29594. +
  29595. +void mvBinToAscii(const MV_U8* bin, char* asciiStr, int size)
  29596. +{
  29597. + int i;
  29598. +
  29599. + for(i=0; i<size; i++)
  29600. + {
  29601. + mvOsSPrintf(&asciiStr[i*2], "%c", bin[i]);
  29602. + }
  29603. + asciiStr[i*2] = '\0';
  29604. +}
  29605. +
  29606. +/*******************************************************************************
  29607. +* mvLog2 -
  29608. +*
  29609. +* DESCRIPTION:
  29610. +* Calculate the Log2 of a given number.
  29611. +*
  29612. +* INPUT:
  29613. +* num - A number to calculate the Log2 for.
  29614. +*
  29615. +* OUTPUT:
  29616. +* None.
  29617. +*
  29618. +* RETURN:
  29619. +* Log 2 of the input number, or 0xFFFFFFFF if input is 0.
  29620. +*
  29621. +*******************************************************************************/
  29622. +MV_U32 mvLog2(MV_U32 num)
  29623. +{
  29624. + MV_U32 result = 0;
  29625. + if(num == 0)
  29626. + return 0xFFFFFFFF;
  29627. + while(num != 1)
  29628. + {
  29629. + num = num >> 1;
  29630. + result++;
  29631. + }
  29632. + return result;
  29633. +}
  29634. +
  29635. +
  29636. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvCommon.h
  29637. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.h 1970-01-01 01:00:00.000000000 +0100
  29638. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvCommon.h 2010-11-09 20:28:06.212495496 +0100
  29639. @@ -0,0 +1,308 @@
  29640. +/*******************************************************************************
  29641. +Copyright (C) Marvell International Ltd. and its affiliates
  29642. +
  29643. +This software file (the "File") is owned and distributed by Marvell
  29644. +International Ltd. and/or its affiliates ("Marvell") under the following
  29645. +alternative licensing terms. Once you have made an election to distribute the
  29646. +File under one of the following license alternatives, please (i) delete this
  29647. +introductory statement regarding license alternatives, (ii) delete the two
  29648. +license alternatives that you have not elected to use and (iii) preserve the
  29649. +Marvell copyright notice above.
  29650. +
  29651. +********************************************************************************
  29652. +Marvell Commercial License Option
  29653. +
  29654. +If you received this File from Marvell and you have entered into a commercial
  29655. +license agreement (a "Commercial License") with Marvell, the File is licensed
  29656. +to you under the terms of the applicable Commercial License.
  29657. +
  29658. +********************************************************************************
  29659. +Marvell GPL License Option
  29660. +
  29661. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29662. +modify this File in accordance with the terms and conditions of the General
  29663. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  29664. +available along with the File in the license.txt file or by writing to the Free
  29665. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  29666. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  29667. +
  29668. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  29669. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  29670. +DISCLAIMED. The GPL License provides additional details about this warranty
  29671. +disclaimer.
  29672. +********************************************************************************
  29673. +Marvell BSD License Option
  29674. +
  29675. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29676. +modify this File under the following licensing terms.
  29677. +Redistribution and use in source and binary forms, with or without modification,
  29678. +are permitted provided that the following conditions are met:
  29679. +
  29680. + * Redistributions of source code must retain the above copyright notice,
  29681. + this list of conditions and the following disclaimer.
  29682. +
  29683. + * Redistributions in binary form must reproduce the above copyright
  29684. + notice, this list of conditions and the following disclaimer in the
  29685. + documentation and/or other materials provided with the distribution.
  29686. +
  29687. + * Neither the name of Marvell nor the names of its contributors may be
  29688. + used to endorse or promote products derived from this software without
  29689. + specific prior written permission.
  29690. +
  29691. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  29692. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  29693. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  29694. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  29695. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  29696. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29697. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  29698. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29699. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29700. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29701. +
  29702. +*******************************************************************************/
  29703. +
  29704. +
  29705. +
  29706. +#ifndef __INCmvCommonh
  29707. +#define __INCmvCommonh
  29708. +
  29709. +#include "mvTypes.h"
  29710. +
  29711. +/* Swap tool */
  29712. +
  29713. +/* 16bit nibble swap. For example 0x1234 -> 0x2143 */
  29714. +#define MV_NIBBLE_SWAP_16BIT(X) (((X&0xf) << 4) | \
  29715. + ((X&0xf0) >> 4) | \
  29716. + ((X&0xf00) << 4) | \
  29717. + ((X&0xf000) >> 4))
  29718. +
  29719. +/* 32bit nibble swap. For example 0x12345678 -> 0x21436587 */
  29720. +#define MV_NIBBLE_SWAP_32BIT(X) (((X&0xf) << 4) | \
  29721. + ((X&0xf0) >> 4) | \
  29722. + ((X&0xf00) << 4) | \
  29723. + ((X&0xf000) >> 4) | \
  29724. + ((X&0xf0000) << 4) | \
  29725. + ((X&0xf00000) >> 4) | \
  29726. + ((X&0xf000000) << 4) | \
  29727. + ((X&0xf0000000) >> 4))
  29728. +
  29729. +/* 16bit byte swap. For example 0x1122 -> 0x2211 */
  29730. +#define MV_BYTE_SWAP_16BIT(X) ((((X)&0xff)<<8) | (((X)&0xff00)>>8))
  29731. +
  29732. +/* 32bit byte swap. For example 0x11223344 -> 0x44332211 */
  29733. +#define MV_BYTE_SWAP_32BIT(X) ((((X)&0xff)<<24) | \
  29734. + (((X)&0xff00)<<8) | \
  29735. + (((X)&0xff0000)>>8) | \
  29736. + (((X)&0xff000000)>>24))
  29737. +
  29738. +/* 64bit byte swap. For example 0x11223344.55667788 -> 0x88776655.44332211 */
  29739. +#define MV_BYTE_SWAP_64BIT(X) ((l64) ((((X)&0xffULL)<<56) | \
  29740. + (((X)&0xff00ULL)<<40) | \
  29741. + (((X)&0xff0000ULL)<<24) | \
  29742. + (((X)&0xff000000ULL)<<8) | \
  29743. + (((X)&0xff00000000ULL)>>8) | \
  29744. + (((X)&0xff0000000000ULL)>>24) | \
  29745. + (((X)&0xff000000000000ULL)>>40) | \
  29746. + (((X)&0xff00000000000000ULL)>>56)))
  29747. +
  29748. +/* Endianess macros. */
  29749. +#if defined(MV_CPU_LE)
  29750. + #define MV_16BIT_LE(X) (X)
  29751. + #define MV_32BIT_LE(X) (X)
  29752. + #define MV_64BIT_LE(X) (X)
  29753. + #define MV_16BIT_BE(X) MV_BYTE_SWAP_16BIT(X)
  29754. + #define MV_32BIT_BE(X) MV_BYTE_SWAP_32BIT(X)
  29755. + #define MV_64BIT_BE(X) MV_BYTE_SWAP_64BIT(X)
  29756. +#elif defined(MV_CPU_BE)
  29757. + #define MV_16BIT_LE(X) MV_BYTE_SWAP_16BIT(X)
  29758. + #define MV_32BIT_LE(X) MV_BYTE_SWAP_32BIT(X)
  29759. + #define MV_64BIT_LE(X) MV_BYTE_SWAP_64BIT(X)
  29760. + #define MV_16BIT_BE(X) (X)
  29761. + #define MV_32BIT_BE(X) (X)
  29762. + #define MV_64BIT_BE(X) (X)
  29763. +#else
  29764. + #error "CPU endianess isn't defined!\n"
  29765. +#endif
  29766. +
  29767. +
  29768. +/* Bit field definitions */
  29769. +#define NO_BIT 0x00000000
  29770. +#define BIT0 0x00000001
  29771. +#define BIT1 0x00000002
  29772. +#define BIT2 0x00000004
  29773. +#define BIT3 0x00000008
  29774. +#define BIT4 0x00000010
  29775. +#define BIT5 0x00000020
  29776. +#define BIT6 0x00000040
  29777. +#define BIT7 0x00000080
  29778. +#define BIT8 0x00000100
  29779. +#define BIT9 0x00000200
  29780. +#define BIT10 0x00000400
  29781. +#define BIT11 0x00000800
  29782. +#define BIT12 0x00001000
  29783. +#define BIT13 0x00002000
  29784. +#define BIT14 0x00004000
  29785. +#define BIT15 0x00008000
  29786. +#define BIT16 0x00010000
  29787. +#define BIT17 0x00020000
  29788. +#define BIT18 0x00040000
  29789. +#define BIT19 0x00080000
  29790. +#define BIT20 0x00100000
  29791. +#define BIT21 0x00200000
  29792. +#define BIT22 0x00400000
  29793. +#define BIT23 0x00800000
  29794. +#define BIT24 0x01000000
  29795. +#define BIT25 0x02000000
  29796. +#define BIT26 0x04000000
  29797. +#define BIT27 0x08000000
  29798. +#define BIT28 0x10000000
  29799. +#define BIT29 0x20000000
  29800. +#define BIT30 0x40000000
  29801. +#define BIT31 0x80000000
  29802. +
  29803. +/* Handy sizes */
  29804. +#define _1K 0x00000400
  29805. +#define _2K 0x00000800
  29806. +#define _4K 0x00001000
  29807. +#define _8K 0x00002000
  29808. +#define _16K 0x00004000
  29809. +#define _32K 0x00008000
  29810. +#define _64K 0x00010000
  29811. +#define _128K 0x00020000
  29812. +#define _256K 0x00040000
  29813. +#define _512K 0x00080000
  29814. +
  29815. +#define _1M 0x00100000
  29816. +#define _2M 0x00200000
  29817. +#define _4M 0x00400000
  29818. +#define _8M 0x00800000
  29819. +#define _16M 0x01000000
  29820. +#define _32M 0x02000000
  29821. +#define _64M 0x04000000
  29822. +#define _128M 0x08000000
  29823. +#define _256M 0x10000000
  29824. +#define _512M 0x20000000
  29825. +
  29826. +#define _1G 0x40000000
  29827. +#define _2G 0x80000000
  29828. +
  29829. +/* Tclock and Sys clock define */
  29830. +#define _100MHz 100000000
  29831. +#define _125MHz 125000000
  29832. +#define _133MHz 133333334
  29833. +#define _150MHz 150000000
  29834. +#define _160MHz 160000000
  29835. +#define _166MHz 166666667
  29836. +#define _175MHz 175000000
  29837. +#define _178MHz 178000000
  29838. +#define _183MHz 183333334
  29839. +#define _187MHz 187000000
  29840. +#define _192MHz 192000000
  29841. +#define _194MHz 194000000
  29842. +#define _200MHz 200000000
  29843. +#define _233MHz 233333334
  29844. +#define _250MHz 250000000
  29845. +#define _266MHz 266666667
  29846. +#define _300MHz 300000000
  29847. +
  29848. +/* For better address window table readability */
  29849. +#define EN MV_TRUE
  29850. +#define DIS MV_FALSE
  29851. +#define N_A -1 /* Not applicable */
  29852. +
  29853. +/* Cache configuration options for memory (DRAM, SRAM, ... ) */
  29854. +
  29855. +/* Memory uncached, HW or SW cache coherency is not needed */
  29856. +#define MV_UNCACHED 0
  29857. +/* Memory cached, HW cache coherency supported in WriteThrough mode */
  29858. +#define MV_CACHE_COHER_HW_WT 1
  29859. +/* Memory cached, HW cache coherency supported in WriteBack mode */
  29860. +#define MV_CACHE_COHER_HW_WB 2
  29861. +/* Memory cached, No HW cache coherency, Cache coherency must be in SW */
  29862. +#define MV_CACHE_COHER_SW 3
  29863. +
  29864. +
  29865. +/* Macro for testing aligment. Positive if number is NOT aligned */
  29866. +#define MV_IS_NOT_ALIGN(number, align) ((number) & ((align) - 1))
  29867. +
  29868. +/* Macro for alignment up. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0340 */
  29869. +#define MV_ALIGN_UP(number, align) \
  29870. +(((number) & ((align) - 1)) ? (((number) + (align)) & ~((align)-1)) : (number))
  29871. +
  29872. +/* Macro for alignment down. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0320 */
  29873. +#define MV_ALIGN_DOWN(number, align) ((number) & ~((align)-1))
  29874. +
  29875. +/* This macro returns absolute value */
  29876. +#define MV_ABS(number) (((int)(number) < 0) ? -(int)(number) : (int)(number))
  29877. +
  29878. +
  29879. +/* Bit fields manipulation macros */
  29880. +
  29881. +/* An integer word which its 'x' bit is set */
  29882. +#define MV_BIT_MASK(bitNum) (1 << (bitNum) )
  29883. +
  29884. +/* Checks wheter bit 'x' in integer word is set */
  29885. +#define MV_BIT_CHECK(word, bitNum) ( (word) & MV_BIT_MASK(bitNum) )
  29886. +
  29887. +/* Clear (reset) bit 'x' in integer word (RMW - Read-Modify-Write) */
  29888. +#define MV_BIT_CLEAR(word, bitNum) ( (word) &= ~(MV_BIT_MASK(bitNum)) )
  29889. +
  29890. +/* Set bit 'x' in integer word (RMW) */
  29891. +#define MV_BIT_SET(word, bitNum) ( (word) |= MV_BIT_MASK(bitNum) )
  29892. +
  29893. +/* Invert bit 'x' in integer word (RMW) */
  29894. +#define MV_BIT_INV(word, bitNum) ( (word) ^= MV_BIT_MASK(bitNum) )
  29895. +
  29896. +/* Get the min between 'a' or 'b' */
  29897. +#define MV_MIN(a,b) (((a) < (b)) ? (a) : (b))
  29898. +
  29899. +/* Get the max between 'a' or 'b' */
  29900. +#define MV_MAX(a,b) (((a) < (b)) ? (b) : (a))
  29901. +
  29902. +/* Temporary */
  29903. +#define mvOsDivide(num, div) \
  29904. +({ \
  29905. + int i=0, rem=(num); \
  29906. + \
  29907. + while(rem >= (div)) \
  29908. + { \
  29909. + rem -= (div); \
  29910. + i++; \
  29911. + } \
  29912. + (i); \
  29913. +})
  29914. +
  29915. +/* Temporary */
  29916. +#define mvOsReminder(num, div) \
  29917. +({ \
  29918. + int rem = (num); \
  29919. + \
  29920. + while(rem >= (div)) \
  29921. + rem -= (div); \
  29922. + (rem); \
  29923. +})
  29924. +
  29925. +#define MV_IP_QUAD(ipAddr) ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF), \
  29926. + ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF)
  29927. +
  29928. +#define MV_IS_POWER_OF_2(num) ((num != 0) && ((num & (num - 1)) == 0))
  29929. +
  29930. +#ifndef MV_ASMLANGUAGE
  29931. +/* mvCommon API list */
  29932. +
  29933. +MV_VOID mvHexToBin(const char* pHexStr, MV_U8* pBin, int size);
  29934. +void mvAsciiToHex(const char* asciiStr, char* hexStr);
  29935. +void mvBinToHex(const MV_U8* bin, char* hexStr, int size);
  29936. +void mvBinToAscii(const MV_U8* bin, char* asciiStr, int size);
  29937. +
  29938. +MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex);
  29939. +MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr);
  29940. +void mvSizePrint(MV_U32);
  29941. +
  29942. +MV_U32 mvLog2(MV_U32 num);
  29943. +
  29944. +#endif /* MV_ASMLANGUAGE */
  29945. +
  29946. +
  29947. +#endif /* __INCmvCommonh */
  29948. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDebug.c
  29949. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.c 1970-01-01 01:00:00.000000000 +0100
  29950. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDebug.c 2010-11-09 20:28:06.252495437 +0100
  29951. @@ -0,0 +1,326 @@
  29952. +/*******************************************************************************
  29953. +Copyright (C) Marvell International Ltd. and its affiliates
  29954. +
  29955. +This software file (the "File") is owned and distributed by Marvell
  29956. +International Ltd. and/or its affiliates ("Marvell") under the following
  29957. +alternative licensing terms. Once you have made an election to distribute the
  29958. +File under one of the following license alternatives, please (i) delete this
  29959. +introductory statement regarding license alternatives, (ii) delete the two
  29960. +license alternatives that you have not elected to use and (iii) preserve the
  29961. +Marvell copyright notice above.
  29962. +
  29963. +********************************************************************************
  29964. +Marvell Commercial License Option
  29965. +
  29966. +If you received this File from Marvell and you have entered into a commercial
  29967. +license agreement (a "Commercial License") with Marvell, the File is licensed
  29968. +to you under the terms of the applicable Commercial License.
  29969. +
  29970. +********************************************************************************
  29971. +Marvell GPL License Option
  29972. +
  29973. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29974. +modify this File in accordance with the terms and conditions of the General
  29975. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  29976. +available along with the File in the license.txt file or by writing to the Free
  29977. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  29978. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  29979. +
  29980. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  29981. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  29982. +DISCLAIMED. The GPL License provides additional details about this warranty
  29983. +disclaimer.
  29984. +********************************************************************************
  29985. +Marvell BSD License Option
  29986. +
  29987. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29988. +modify this File under the following licensing terms.
  29989. +Redistribution and use in source and binary forms, with or without modification,
  29990. +are permitted provided that the following conditions are met:
  29991. +
  29992. + * Redistributions of source code must retain the above copyright notice,
  29993. + this list of conditions and the following disclaimer.
  29994. +
  29995. + * Redistributions in binary form must reproduce the above copyright
  29996. + notice, this list of conditions and the following disclaimer in the
  29997. + documentation and/or other materials provided with the distribution.
  29998. +
  29999. + * Neither the name of Marvell nor the names of its contributors may be
  30000. + used to endorse or promote products derived from this software without
  30001. + specific prior written permission.
  30002. +
  30003. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30004. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30005. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30006. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30007. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30008. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30009. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30010. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30011. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30012. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30013. +
  30014. +*******************************************************************************/
  30015. +
  30016. +
  30017. +
  30018. +/* includes */
  30019. +#include "mvOs.h"
  30020. +#include "mv802_3.h"
  30021. +#include "mvCommon.h"
  30022. +#include "mvDebug.h"
  30023. +
  30024. +/* Global variables effect on behave MV_DEBUG_PRINT and MV_DEBUG_CODE macros
  30025. + * mvDebug - map of bits (one for each module) bit=1 means enable
  30026. + * debug code and messages for this module
  30027. + * mvModuleDebug - array of 32 bits varables one for each module
  30028. + */
  30029. +MV_U32 mvDebug = 0;
  30030. +MV_U32 mvDebugModules[MV_MODULE_MAX];
  30031. +
  30032. +/* Init mvModuleDebug array to default values */
  30033. +void mvDebugInit(void)
  30034. +{
  30035. + int bit;
  30036. +
  30037. + mvDebug = 0;
  30038. + for(bit=0; bit<MV_MODULE_MAX; bit++)
  30039. + {
  30040. + mvDebugModules[bit] = MV_DEBUG_FLAG_ERR | MV_DEBUG_FLAG_STATS;
  30041. + mvDebug |= MV_BIT_MASK(bit);
  30042. + }
  30043. +}
  30044. +
  30045. +void mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable)
  30046. +{
  30047. + if (isEnable)
  30048. + {
  30049. + MV_BIT_SET(mvDebug, module);
  30050. + }
  30051. + else
  30052. + MV_BIT_CLEAR(mvDebug, module);
  30053. +}
  30054. +
  30055. +void mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags)
  30056. +{
  30057. + mvDebugModules[module] |= flags;
  30058. +}
  30059. +
  30060. +void mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags)
  30061. +{
  30062. + mvDebugModules[module] &= ~flags;
  30063. +}
  30064. +
  30065. +/* Dump memory in specific format:
  30066. + * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8
  30067. + */
  30068. +void mvDebugMemDump(void* addr, int size, int access)
  30069. +{
  30070. + int i, j;
  30071. + MV_U32 memAddr = (MV_U32)addr;
  30072. +
  30073. + if(access == 0)
  30074. + access = 1;
  30075. +
  30076. + if( (access != 4) && (access != 2) && (access != 1) )
  30077. + {
  30078. + mvOsPrintf("%d wrong access size. Access must be 1 or 2 or 4\n",
  30079. + access);
  30080. + return;
  30081. + }
  30082. + memAddr = MV_ALIGN_DOWN( (unsigned int)addr, 4);
  30083. + size = MV_ALIGN_UP(size, 4);
  30084. + addr = (void*)MV_ALIGN_DOWN( (unsigned int)addr, access);
  30085. + while(size > 0)
  30086. + {
  30087. + mvOsPrintf("%08x: ", memAddr);
  30088. + i = 0;
  30089. + /* 32 bytes in the line */
  30090. + while(i < 32)
  30091. + {
  30092. + if(memAddr >= (MV_U32)addr)
  30093. + {
  30094. + switch(access)
  30095. + {
  30096. + case 1:
  30097. + if( memAddr == CPU_PHY_MEM(memAddr) )
  30098. + {
  30099. + mvOsPrintf("%02x ", MV_MEMIO8_READ(memAddr));
  30100. + }
  30101. + else
  30102. + {
  30103. + mvOsPrintf("%02x ", *((MV_U8*)memAddr));
  30104. + }
  30105. + break;
  30106. +
  30107. + case 2:
  30108. + if( memAddr == CPU_PHY_MEM(memAddr) )
  30109. + {
  30110. + mvOsPrintf("%04x ", MV_MEMIO16_READ(memAddr));
  30111. + }
  30112. + else
  30113. + {
  30114. + mvOsPrintf("%04x ", *((MV_U16*)memAddr));
  30115. + }
  30116. + break;
  30117. +
  30118. + case 4:
  30119. + if( memAddr == CPU_PHY_MEM(memAddr) )
  30120. + {
  30121. + mvOsPrintf("%08x ", MV_MEMIO32_READ(memAddr));
  30122. + }
  30123. + else
  30124. + {
  30125. + mvOsPrintf("%08x ", *((MV_U32*)memAddr));
  30126. + }
  30127. + break;
  30128. + }
  30129. + }
  30130. + else
  30131. + {
  30132. + for(j=0; j<(access*2+1); j++)
  30133. + mvOsPrintf(" ");
  30134. + }
  30135. + i += access;
  30136. + memAddr += access;
  30137. + size -= access;
  30138. + if(size <= 0)
  30139. + break;
  30140. + }
  30141. + mvOsPrintf("\n");
  30142. + }
  30143. +}
  30144. +
  30145. +void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access)
  30146. +{
  30147. + if(pBufInfo == NULL)
  30148. + {
  30149. + mvOsPrintf("\n!!! pBufInfo = NULL\n");
  30150. + return;
  30151. + }
  30152. + mvOsPrintf("\n*** pBufInfo=0x%x, cmdSts=0x%08x, pBuf=0x%x, bufSize=%d\n",
  30153. + (unsigned int)pBufInfo,
  30154. + (unsigned int)pBufInfo->cmdSts,
  30155. + (unsigned int)pBufInfo->pBuff,
  30156. + (unsigned int)pBufInfo->bufSize);
  30157. + mvOsPrintf("pData=0x%x, byteCnt=%d, pNext=0x%x, uInfo1=0x%x, uInfo2=0x%x\n",
  30158. + (unsigned int)pBufInfo->pData,
  30159. + (unsigned int)pBufInfo->byteCnt,
  30160. + (unsigned int)pBufInfo->pNextBufInfo,
  30161. + (unsigned int)pBufInfo->userInfo1,
  30162. + (unsigned int)pBufInfo->userInfo2);
  30163. + if(pBufInfo->pData != NULL)
  30164. + {
  30165. + if(size > pBufInfo->byteCnt)
  30166. + size = pBufInfo->byteCnt;
  30167. + mvDebugMemDump(pBufInfo->pData, size, access);
  30168. + }
  30169. +}
  30170. +
  30171. +void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access)
  30172. +{
  30173. + int frag, len;
  30174. +
  30175. + if(pPktInfo == NULL)
  30176. + {
  30177. + mvOsPrintf("\n!!! pPktInfo = NULL\n");
  30178. + return;
  30179. + }
  30180. + mvOsPrintf("\npPkt=%p, stat=0x%08x, numFr=%d, size=%d, pFr=%p, osInfo=0x%lx\n",
  30181. + pPktInfo, pPktInfo->status, pPktInfo->numFrags, pPktInfo->pktSize,
  30182. + pPktInfo->pFrags, pPktInfo->osInfo);
  30183. +
  30184. + for(frag=0; frag<pPktInfo->numFrags; frag++)
  30185. + {
  30186. + mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n",
  30187. + frag, pPktInfo->pFrags[frag].bufVirtPtr,
  30188. + pPktInfo->pFrags[frag].bufSize);
  30189. + if(size > 0)
  30190. + {
  30191. + len = MV_MIN((int)pPktInfo->pFrags[frag].bufSize, size);
  30192. + mvDebugMemDump(pPktInfo->pFrags[frag].bufVirtPtr, len, access);
  30193. + size -= len;
  30194. + }
  30195. + }
  30196. +
  30197. +}
  30198. +
  30199. +void mvDebugPrintIpAddr(MV_U32 ipAddr)
  30200. +{
  30201. + mvOsPrintf("%d.%d.%d.%d", ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF),
  30202. + ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF));
  30203. +}
  30204. +
  30205. +void mvDebugPrintMacAddr(const MV_U8* pMacAddr)
  30206. +{
  30207. + int i;
  30208. +
  30209. + mvOsPrintf("%02x", (unsigned int)pMacAddr[0]);
  30210. + for(i=1; i<MV_MAC_ADDR_SIZE; i++)
  30211. + {
  30212. + mvOsPrintf(":%02x", pMacAddr[i]);
  30213. + }
  30214. + /* mvOsPrintf("\n");*/
  30215. +}
  30216. +
  30217. +
  30218. +/******* There are three functions deals with MV_DEBUG_TIMES structure ********/
  30219. +
  30220. +/* Reset MV_DEBUG_TIMES entry */
  30221. +void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* pName)
  30222. +{
  30223. + pTimeEntry->begin = 0;
  30224. + pTimeEntry->count = count;
  30225. + pTimeEntry->end = 0;
  30226. + pTimeEntry->left = pTimeEntry->count;
  30227. + pTimeEntry->total = 0;
  30228. + pTimeEntry->min = 0xFFFFFFFF;
  30229. + pTimeEntry->max = 0x0;
  30230. + strncpy(pTimeEntry->name, pName, sizeof(pTimeEntry->name)-1);
  30231. + pTimeEntry->name[sizeof(pTimeEntry->name)-1] = '\0';
  30232. +}
  30233. +
  30234. +/* Print out MV_DEBUG_TIMES entry */
  30235. +void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle)
  30236. +{
  30237. + int num;
  30238. +
  30239. + if(isTitle == MV_TRUE)
  30240. + mvOsPrintf("Event NumOfEvents TotalTime Average Min Max\n");
  30241. +
  30242. + num = pTimeEntry->count-pTimeEntry->left;
  30243. + if(num > 0)
  30244. + {
  30245. + mvOsPrintf("%-11s %6u 0x%08lx %6lu %6lu %6lu\n",
  30246. + pTimeEntry->name, num, pTimeEntry->total, pTimeEntry->total/num,
  30247. + pTimeEntry->min, pTimeEntry->max);
  30248. + }
  30249. +}
  30250. +
  30251. +/* Update MV_DEBUG_TIMES entry */
  30252. +void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry)
  30253. +{
  30254. + MV_U32 delta;
  30255. +
  30256. + if(pTimeEntry->left > 0)
  30257. + {
  30258. + if(pTimeEntry->end <= pTimeEntry->begin)
  30259. + {
  30260. + delta = pTimeEntry->begin - pTimeEntry->end;
  30261. + }
  30262. + else
  30263. + {
  30264. + delta = ((MV_U32)0x10000 - pTimeEntry->end) + pTimeEntry->begin;
  30265. + }
  30266. + pTimeEntry->total += delta;
  30267. +
  30268. + if(delta < pTimeEntry->min)
  30269. + pTimeEntry->min = delta;
  30270. +
  30271. + if(delta > pTimeEntry->max)
  30272. + pTimeEntry->max = delta;
  30273. +
  30274. + pTimeEntry->left--;
  30275. + }
  30276. +}
  30277. +
  30278. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDebug.h
  30279. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.h 1970-01-01 01:00:00.000000000 +0100
  30280. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDebug.h 2010-11-09 20:28:06.292495404 +0100
  30281. @@ -0,0 +1,178 @@
  30282. +/*******************************************************************************
  30283. +Copyright (C) Marvell International Ltd. and its affiliates
  30284. +
  30285. +This software file (the "File") is owned and distributed by Marvell
  30286. +International Ltd. and/or its affiliates ("Marvell") under the following
  30287. +alternative licensing terms. Once you have made an election to distribute the
  30288. +File under one of the following license alternatives, please (i) delete this
  30289. +introductory statement regarding license alternatives, (ii) delete the two
  30290. +license alternatives that you have not elected to use and (iii) preserve the
  30291. +Marvell copyright notice above.
  30292. +
  30293. +********************************************************************************
  30294. +Marvell Commercial License Option
  30295. +
  30296. +If you received this File from Marvell and you have entered into a commercial
  30297. +license agreement (a "Commercial License") with Marvell, the File is licensed
  30298. +to you under the terms of the applicable Commercial License.
  30299. +
  30300. +********************************************************************************
  30301. +Marvell GPL License Option
  30302. +
  30303. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30304. +modify this File in accordance with the terms and conditions of the General
  30305. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  30306. +available along with the File in the license.txt file or by writing to the Free
  30307. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  30308. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  30309. +
  30310. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  30311. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  30312. +DISCLAIMED. The GPL License provides additional details about this warranty
  30313. +disclaimer.
  30314. +********************************************************************************
  30315. +Marvell BSD License Option
  30316. +
  30317. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30318. +modify this File under the following licensing terms.
  30319. +Redistribution and use in source and binary forms, with or without modification,
  30320. +are permitted provided that the following conditions are met:
  30321. +
  30322. + * Redistributions of source code must retain the above copyright notice,
  30323. + this list of conditions and the following disclaimer.
  30324. +
  30325. + * Redistributions in binary form must reproduce the above copyright
  30326. + notice, this list of conditions and the following disclaimer in the
  30327. + documentation and/or other materials provided with the distribution.
  30328. +
  30329. + * Neither the name of Marvell nor the names of its contributors may be
  30330. + used to endorse or promote products derived from this software without
  30331. + specific prior written permission.
  30332. +
  30333. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30334. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30335. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30336. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30337. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30338. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30339. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30340. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30341. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30342. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30343. +
  30344. +*******************************************************************************/
  30345. +
  30346. +
  30347. +
  30348. +#ifndef __INCmvDebugh
  30349. +#define __INCmvDebugh
  30350. +
  30351. +/* includes */
  30352. +#include "mvTypes.h"
  30353. +
  30354. +typedef enum
  30355. +{
  30356. + MV_MODULE_INVALID = -1,
  30357. + MV_MODULE_ETH = 0,
  30358. + MV_MODULE_IDMA,
  30359. + MV_MODULE_XOR,
  30360. + MV_MODULE_TWASI,
  30361. + MV_MODULE_MGI,
  30362. + MV_MODULE_USB,
  30363. + MV_MODULE_CESA,
  30364. +
  30365. + MV_MODULE_MAX
  30366. +}MV_MODULE_ID;
  30367. +
  30368. +/* Define generic flags useful for most of modules */
  30369. +#define MV_DEBUG_FLAG_ALL (0)
  30370. +#define MV_DEBUG_FLAG_INIT (1 << 0)
  30371. +#define MV_DEBUG_FLAG_RX (1 << 1)
  30372. +#define MV_DEBUG_FLAG_TX (1 << 2)
  30373. +#define MV_DEBUG_FLAG_ERR (1 << 3)
  30374. +#define MV_DEBUG_FLAG_TRACE (1 << 4)
  30375. +#define MV_DEBUG_FLAG_DUMP (1 << 5)
  30376. +#define MV_DEBUG_FLAG_CACHE (1 << 6)
  30377. +#define MV_DEBUG_FLAG_IOCTL (1 << 7)
  30378. +#define MV_DEBUG_FLAG_STATS (1 << 8)
  30379. +
  30380. +extern MV_U32 mvDebug;
  30381. +extern MV_U32 mvDebugModules[MV_MODULE_MAX];
  30382. +
  30383. +#ifdef MV_DEBUG
  30384. +# define MV_DEBUG_PRINT(module, flags, msg) mvOsPrintf msg
  30385. +# define MV_DEBUG_CODE(module, flags, code) code
  30386. +#elif defined(MV_RT_DEBUG)
  30387. +# define MV_DEBUG_PRINT(module, flags, msg) \
  30388. + if( (mvDebug & (1<<(module))) && \
  30389. + ((mvDebugModules[(module)] & (flags)) == (flags)) ) \
  30390. + mvOsPrintf msg
  30391. +# define MV_DEBUG_CODE(module, flags, code) \
  30392. + if( (mvDebug & (1<<(module))) && \
  30393. + ((mvDebugModules[(module)] & (flags)) == (flags)) ) \
  30394. + code
  30395. +#else
  30396. +# define MV_DEBUG_PRINT(module, flags, msg)
  30397. +# define MV_DEBUG_CODE(module, flags, code)
  30398. +#endif
  30399. +
  30400. +
  30401. +
  30402. +/* typedefs */
  30403. +
  30404. +/* time measurement structure used to check how much time pass between
  30405. + * two points
  30406. + */
  30407. +typedef struct {
  30408. + char name[20]; /* name of the entry */
  30409. + unsigned long begin; /* time measured on begin point */
  30410. + unsigned long end; /* time measured on end point */
  30411. + unsigned long total; /* Accumulated time */
  30412. + unsigned long left; /* The rest measurement actions */
  30413. + unsigned long count; /* Maximum measurement actions */
  30414. + unsigned long min; /* Minimum time from begin to end */
  30415. + unsigned long max; /* Maximum time from begin to end */
  30416. +} MV_DEBUG_TIMES;
  30417. +
  30418. +
  30419. +/* mvDebug.h API list */
  30420. +
  30421. +/****** Error Recording ******/
  30422. +
  30423. +/* Dump memory in specific format:
  30424. + * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8
  30425. + */
  30426. +void mvDebugMemDump(void* addr, int size, int access);
  30427. +
  30428. +void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access);
  30429. +
  30430. +void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access);
  30431. +
  30432. +void mvDebugPrintIpAddr(MV_U32 ipAddr);
  30433. +
  30434. +void mvDebugPrintMacAddr(const MV_U8* pMacAddr);
  30435. +
  30436. +/**** There are three functions deals with MV_DEBUG_TIMES structure ****/
  30437. +
  30438. +/* Reset MV_DEBUG_TIMES entry */
  30439. +void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* name);
  30440. +
  30441. +/* Update MV_DEBUG_TIMES entry */
  30442. +void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry);
  30443. +
  30444. +/* Print out MV_DEBUG_TIMES entry */
  30445. +void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle);
  30446. +
  30447. +
  30448. +/******** General ***********/
  30449. +
  30450. +/* Change value of mvDebugPrint global variable */
  30451. +
  30452. +void mvDebugInit(void);
  30453. +void mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable);
  30454. +void mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags);
  30455. +void mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags);
  30456. +
  30457. +
  30458. +#endif /* __INCmvDebug.h */
  30459. +
  30460. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h
  30461. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h 1970-01-01 01:00:00.000000000 +0100
  30462. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h 2010-11-09 20:28:06.332495486 +0100
  30463. @@ -0,0 +1,225 @@
  30464. +/*******************************************************************************
  30465. +Copyright (C) Marvell International Ltd. and its affiliates
  30466. +
  30467. +This software file (the "File") is owned and distributed by Marvell
  30468. +International Ltd. and/or its affiliates ("Marvell") under the following
  30469. +alternative licensing terms. Once you have made an election to distribute the
  30470. +File under one of the following license alternatives, please (i) delete this
  30471. +introductory statement regarding license alternatives, (ii) delete the two
  30472. +license alternatives that you have not elected to use and (iii) preserve the
  30473. +Marvell copyright notice above.
  30474. +
  30475. +********************************************************************************
  30476. +Marvell Commercial License Option
  30477. +
  30478. +If you received this File from Marvell and you have entered into a commercial
  30479. +license agreement (a "Commercial License") with Marvell, the File is licensed
  30480. +to you under the terms of the applicable Commercial License.
  30481. +
  30482. +********************************************************************************
  30483. +Marvell GPL License Option
  30484. +
  30485. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30486. +modify this File in accordance with the terms and conditions of the General
  30487. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  30488. +available along with the File in the license.txt file or by writing to the Free
  30489. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  30490. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  30491. +
  30492. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  30493. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  30494. +DISCLAIMED. The GPL License provides additional details about this warranty
  30495. +disclaimer.
  30496. +********************************************************************************
  30497. +Marvell BSD License Option
  30498. +
  30499. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30500. +modify this File under the following licensing terms.
  30501. +Redistribution and use in source and binary forms, with or without modification,
  30502. +are permitted provided that the following conditions are met:
  30503. +
  30504. + * Redistributions of source code must retain the above copyright notice,
  30505. + this list of conditions and the following disclaimer.
  30506. +
  30507. + * Redistributions in binary form must reproduce the above copyright
  30508. + notice, this list of conditions and the following disclaimer in the
  30509. + documentation and/or other materials provided with the distribution.
  30510. +
  30511. + * Neither the name of Marvell nor the names of its contributors may be
  30512. + used to endorse or promote products derived from this software without
  30513. + specific prior written permission.
  30514. +
  30515. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30516. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30517. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30518. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30519. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30520. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30521. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30522. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30523. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30524. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30525. +
  30526. +*******************************************************************************/
  30527. +
  30528. +#ifndef __INCmvDeviceIdh
  30529. +#define __INCmvDeviceIdh
  30530. +
  30531. +#ifdef __cplusplus
  30532. +extern "C" {
  30533. +#endif /* __cplusplus */
  30534. +
  30535. +/* defines */
  30536. +#define MARVELL_VEN_ID 0x11ab
  30537. +
  30538. +/* Disco-3 */
  30539. +#define MV64460_DEV_ID 0x6480
  30540. +#define MV64460B_DEV_ID 0x6485
  30541. +#define MV64430_DEV_ID 0x6420
  30542. +
  30543. +/* Disco-5 */
  30544. +#define MV64560_DEV_ID 0x6450
  30545. +
  30546. +/* Disco-6 */
  30547. +#define MV64660_DEV_ID 0x6460
  30548. +
  30549. +/* Orion */
  30550. +#define MV_1181_DEV_ID 0x1181
  30551. +#define MV_5181_DEV_ID 0x5181
  30552. +#define MV_5281_DEV_ID 0x5281
  30553. +#define MV_5182_DEV_ID 0x5182
  30554. +#define MV_8660_DEV_ID 0x8660
  30555. +#define MV_5180_DEV_ID 0x5180
  30556. +#define MV_5082_DEV_ID 0x5082
  30557. +#define MV_1281_DEV_ID 0x1281
  30558. +#define MV_6082_DEV_ID 0x6082
  30559. +#define MV_6183_DEV_ID 0x6183
  30560. +#define MV_6183L_DEV_ID 0x6083
  30561. +
  30562. +#define MV_5281_D0_REV 0x4
  30563. +#define MV_5281_D0_ID ((MV_5281_DEV_ID << 16) | MV_5281_D0_REV)
  30564. +#define MV_5281_D0_NAME "88F5281 D0"
  30565. +
  30566. +#define MV_5281_D1_REV 0x5
  30567. +#define MV_5281_D1_ID ((MV_5281_DEV_ID << 16) | MV_5281_D1_REV)
  30568. +#define MV_5281_D1_NAME "88F5281 D1"
  30569. +
  30570. +#define MV_5281_D2_REV 0x6
  30571. +#define MV_5281_D2_ID ((MV_5281_DEV_ID << 16) | MV_5281_D2_REV)
  30572. +#define MV_5281_D2_NAME "88F5281 D2"
  30573. +
  30574. +
  30575. +#define MV_5181L_A0_REV 0x8 /* need for PCIE Er */
  30576. +#define MV_5181_A1_REV 0x1 /* for USB Er ..*/
  30577. +#define MV_5181_B0_REV 0x2
  30578. +#define MV_5181_B1_REV 0x3
  30579. +#define MV_5182_A1_REV 0x1
  30580. +#define MV_5180N_B1_REV 0x3
  30581. +#define MV_5181L_A0_ID ((MV_5181_DEV_ID << 16) | MV_5181L_A0_REV)
  30582. +
  30583. +
  30584. +
  30585. +/* kw */
  30586. +#define MV_6281_DEV_ID 0x6281
  30587. +#define MV_6192_DEV_ID 0x6192
  30588. +#define MV_6190_DEV_ID 0x6190
  30589. +#define MV_6180_DEV_ID 0x6180
  30590. +
  30591. +#define MV_6281_A0_REV 0x2
  30592. +#define MV_6281_A0_ID ((MV_6281_DEV_ID << 16) | MV_6281_A0_REV)
  30593. +#define MV_6281_A0_NAME "88F6281 A0"
  30594. +
  30595. +#define MV_6192_A0_REV 0x2
  30596. +#define MV_6192_A0_ID ((MV_6192_DEV_ID << 16) | MV_6192_A0_REV)
  30597. +#define MV_6192_A0_NAME "88F6192 A0"
  30598. +
  30599. +#define MV_6190_A0_REV 0x2
  30600. +#define MV_6190_A0_ID ((MV_6190_DEV_ID << 16) | MV_6190_A0_REV)
  30601. +#define MV_6190_A0_NAME "88F6190 A0"
  30602. +
  30603. +#define MV_6180_A0_REV 0x2
  30604. +#define MV_6180_A0_ID ((MV_6180_DEV_ID << 16) | MV_6180_A0_REV)
  30605. +#define MV_6180_A0_NAME "88F6180 A0"
  30606. +
  30607. +#define MV_6281_A1_REV 0x3
  30608. +#define MV_6281_A1_ID ((MV_6281_DEV_ID << 16) | MV_6281_A1_REV)
  30609. +#define MV_6281_A1_NAME "88F6281 A1"
  30610. +
  30611. +#define MV_6192_A1_REV 0x3
  30612. +#define MV_6192_A1_ID ((MV_6192_DEV_ID << 16) | MV_6192_A1_REV)
  30613. +#define MV_6192_A1_NAME "88F6192 A1"
  30614. +
  30615. +#define MV_6190_A1_REV 0x3
  30616. +#define MV_6190_A1_ID ((MV_6190_DEV_ID << 16) | MV_6190_A1_REV)
  30617. +#define MV_6190_A1_NAME "88F6190 A1"
  30618. +
  30619. +#define MV_6180_A1_REV 0x3
  30620. +#define MV_6180_A1_ID ((MV_6180_DEV_ID << 16) | MV_6180_A1_REV)
  30621. +#define MV_6180_A1_NAME "88F6180 A1"
  30622. +
  30623. +#define MV_88F6XXX_A0_REV 0x2
  30624. +#define MV_88F6XXX_A1_REV 0x3
  30625. +/* Disco-Duo */
  30626. +#define MV_78XX0_ZY_DEV_ID 0x6381
  30627. +#define MV_78XX0_ZY_NAME "MV78X00"
  30628. +
  30629. +#define MV_78XX0_Z0_REV 0x1
  30630. +#define MV_78XX0_Z0_ID ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Z0_REV)
  30631. +#define MV_78XX0_Z0_NAME "78X00 Z0"
  30632. +
  30633. +#define MV_78XX0_Y0_REV 0x2
  30634. +#define MV_78XX0_Y0_ID ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Y0_REV)
  30635. +#define MV_78XX0_Y0_NAME "78X00 Y0"
  30636. +
  30637. +#define MV_78XX0_DEV_ID 0x7800
  30638. +#define MV_78XX0_NAME "MV78X00"
  30639. +
  30640. +#define MV_76100_DEV_ID 0x7610
  30641. +#define MV_78200_DEV_ID 0x7820
  30642. +#define MV_78100_DEV_ID 0x7810
  30643. +#define MV_78XX0_A0_REV 0x1
  30644. +#define MV_78XX0_A1_REV 0x2
  30645. +
  30646. +#define MV_76100_NAME "MV76100"
  30647. +#define MV_78100_NAME "MV78100"
  30648. +#define MV_78200_NAME "MV78200"
  30649. +
  30650. +#define MV_76100_A0_ID ((MV_76100_DEV_ID << 16) | MV_78XX0_A0_REV)
  30651. +#define MV_78100_A0_ID ((MV_78100_DEV_ID << 16) | MV_78XX0_A0_REV)
  30652. +#define MV_78200_A0_ID ((MV_78200_DEV_ID << 16) | MV_78XX0_A0_REV)
  30653. +
  30654. +#define MV_76100_A1_ID ((MV_76100_DEV_ID << 16) | MV_78XX0_A1_REV)
  30655. +#define MV_78100_A1_ID ((MV_78100_DEV_ID << 16) | MV_78XX0_A1_REV)
  30656. +#define MV_78200_A1_ID ((MV_78200_DEV_ID << 16) | MV_78XX0_A1_REV)
  30657. +
  30658. +#define MV_76100_A0_NAME "MV76100 A0"
  30659. +#define MV_78100_A0_NAME "MV78100 A0"
  30660. +#define MV_78200_A0_NAME "MV78200 A0"
  30661. +#define MV_78XX0_A0_NAME "MV78XX0 A0"
  30662. +
  30663. +#define MV_76100_A1_NAME "MV76100 A1"
  30664. +#define MV_78100_A1_NAME "MV78100 A1"
  30665. +#define MV_78200_A1_NAME "MV78200 A1"
  30666. +#define MV_78XX0_A1_NAME "MV78XX0 A1"
  30667. +
  30668. +/*MV88F632X family*/
  30669. +#define MV_6321_DEV_ID 0x6321
  30670. +#define MV_6322_DEV_ID 0x6322
  30671. +#define MV_6323_DEV_ID 0x6323
  30672. +
  30673. +#define MV_6321_NAME "88F6321"
  30674. +#define MV_6322_NAME "88F6322"
  30675. +#define MV_6323_NAME "88F6323"
  30676. +
  30677. +#define MV_632X_A1_REV 0x2
  30678. +
  30679. +#define MV_6321_A1_ID ((MV_6321_DEV_ID << 16) | MV_632X_A1_REV)
  30680. +#define MV_6322_A1_ID ((MV_6322_DEV_ID << 16) | MV_632X_A1_REV)
  30681. +#define MV_6323_A1_ID ((MV_6323_DEV_ID << 16) | MV_632X_A1_REV)
  30682. +
  30683. +#define MV_6321_A1_NAME "88F6321 A1"
  30684. +#define MV_6322_A1_NAME "88F6322 A1"
  30685. +#define MV_6323_A1_NAME "88F6323 A1"
  30686. +
  30687. +
  30688. +#endif /* __INCmvDeviceIdh */
  30689. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h
  30690. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h 1970-01-01 01:00:00.000000000 +0100
  30691. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h 2010-11-09 20:28:07.069296580 +0100
  30692. @@ -0,0 +1,73 @@
  30693. +/*******************************************************************************
  30694. +Copyright (C) Marvell International Ltd. and its affiliates
  30695. +
  30696. +This software file (the "File") is owned and distributed by Marvell
  30697. +International Ltd. and/or its affiliates ("Marvell") under the following
  30698. +alternative licensing terms. Once you have made an election to distribute the
  30699. +File under one of the following license alternatives, please (i) delete this
  30700. +introductory statement regarding license alternatives, (ii) delete the two
  30701. +license alternatives that you have not elected to use and (iii) preserve the
  30702. +Marvell copyright notice above.
  30703. +
  30704. +********************************************************************************
  30705. +Marvell Commercial License Option
  30706. +
  30707. +If you received this File from Marvell and you have entered into a commercial
  30708. +license agreement (a "Commercial License") with Marvell, the File is licensed
  30709. +to you under the terms of the applicable Commercial License.
  30710. +
  30711. +********************************************************************************
  30712. +Marvell GPL License Option
  30713. +
  30714. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30715. +modify this File in accordance with the terms and conditions of the General
  30716. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  30717. +available along with the File in the license.txt file or by writing to the Free
  30718. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  30719. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  30720. +
  30721. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  30722. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  30723. +DISCLAIMED. The GPL License provides additional details about this warranty
  30724. +disclaimer.
  30725. +********************************************************************************
  30726. +Marvell BSD License Option
  30727. +
  30728. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30729. +modify this File under the following licensing terms.
  30730. +Redistribution and use in source and binary forms, with or without modification,
  30731. +are permitted provided that the following conditions are met:
  30732. +
  30733. + * Redistributions of source code must retain the above copyright notice,
  30734. + this list of conditions and the following disclaimer.
  30735. +
  30736. + * Redistributions in binary form must reproduce the above copyright
  30737. + notice, this list of conditions and the following disclaimer in the
  30738. + documentation and/or other materials provided with the distribution.
  30739. +
  30740. + * Neither the name of Marvell nor the names of its contributors may be
  30741. + used to endorse or promote products derived from this software without
  30742. + specific prior written permission.
  30743. +
  30744. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30745. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30746. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30747. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30748. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30749. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30750. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30751. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30752. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30753. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30754. +
  30755. +*******************************************************************************/
  30756. +
  30757. +
  30758. +#ifndef __INCmvHalVerh
  30759. +#define __INCmvHalVerh
  30760. +
  30761. +/* Defines */
  30762. +#define MV_HAL_VERSION "FEROCEON_HAL_3_1_7"
  30763. +#define MV_RELEASE_BASELINE "SoCandControllers_FEROCEON_RELEASE_7_9_2009_KW_4_3_4_DD_2_1_4_6183_1_1_4"
  30764. +
  30765. +#endif /* __INCmvHalVerh */
  30766. \ No newline at end of file
  30767. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvStack.c
  30768. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.c 1970-01-01 01:00:00.000000000 +0100
  30769. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvStack.c 2010-11-09 20:28:07.102606889 +0100
  30770. @@ -0,0 +1,100 @@
  30771. +/*******************************************************************************
  30772. +* Copyright 2003, Marvell Semiconductor Israel LTD. *
  30773. +* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL. *
  30774. +* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT *
  30775. +* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE *
  30776. +* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL. *
  30777. +* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED, *
  30778. +* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE. *
  30779. +* *
  30780. +* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, *
  30781. +* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL *
  30782. +* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K. *
  30783. +* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL). *
  30784. +********************************************************************************
  30785. +* mvQueue.c
  30786. +*
  30787. +* FILENAME: $Workfile: mvStack.c $
  30788. +* REVISION: $Revision: 1.1 $
  30789. +* LAST UPDATE: $Modtime: $
  30790. +*
  30791. +* DESCRIPTION:
  30792. +* This file implements simple Stack LIFO functionality.
  30793. +*******************************************************************************/
  30794. +
  30795. +/* includes */
  30796. +#include "mvOs.h"
  30797. +#include "mvTypes.h"
  30798. +#include "mvDebug.h"
  30799. +#include "mvStack.h"
  30800. +
  30801. +/* defines */
  30802. +
  30803. +
  30804. +/* Public functions */
  30805. +
  30806. +
  30807. +/* Purpose: Create new stack
  30808. + * Inputs:
  30809. + * - MV_U32 noOfElements - maximum number of elements in the stack.
  30810. + * Each element 4 bytes size
  30811. + * Return: void* - pointer to created stack.
  30812. + */
  30813. +void* mvStackCreate(int numOfElements)
  30814. +{
  30815. + MV_STACK* pStack;
  30816. + MV_U32* pStackElements;
  30817. +
  30818. + pStack = (MV_STACK*)mvOsMalloc(sizeof(MV_STACK));
  30819. + pStackElements = (MV_U32*)mvOsMalloc(numOfElements*sizeof(MV_U32));
  30820. + if( (pStack == NULL) || (pStackElements == NULL) )
  30821. + {
  30822. + mvOsPrintf("mvStack: Can't create new stack\n");
  30823. + return NULL;
  30824. + }
  30825. + memset(pStackElements, 0, numOfElements*sizeof(MV_U32));
  30826. + pStack->numOfElements = numOfElements;
  30827. + pStack->stackIdx = 0;
  30828. + pStack->stackElements = pStackElements;
  30829. +
  30830. + return pStack;
  30831. +}
  30832. +
  30833. +/* Purpose: Delete existing stack
  30834. + * Inputs:
  30835. + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function
  30836. + *
  30837. + * Return: MV_STATUS MV_NOT_FOUND - Failure. StackHandle is not valid.
  30838. + * MV_OK - Success.
  30839. + */
  30840. +MV_STATUS mvStackDelete(void* stackHndl)
  30841. +{
  30842. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30843. +
  30844. + if( (pStack == NULL) || (pStack->stackElements == NULL) )
  30845. + return MV_NOT_FOUND;
  30846. +
  30847. + mvOsFree(pStack->stackElements);
  30848. + mvOsFree(pStack);
  30849. +
  30850. + return MV_OK;
  30851. +}
  30852. +
  30853. +
  30854. +/* PrintOut status of the stack */
  30855. +void mvStackStatus(void* stackHndl, MV_BOOL isPrintElements)
  30856. +{
  30857. + int i;
  30858. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30859. +
  30860. + mvOsPrintf("StackHandle=%p, pElements=%p, numElements=%d, stackIdx=%d\n",
  30861. + stackHndl, pStack->stackElements, pStack->numOfElements,
  30862. + pStack->stackIdx);
  30863. + if(isPrintElements == MV_TRUE)
  30864. + {
  30865. + for(i=0; i<pStack->stackIdx; i++)
  30866. + {
  30867. + mvOsPrintf("%3d. Value=0x%x\n", i, pStack->stackElements[i]);
  30868. + }
  30869. + }
  30870. +}
  30871. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvStack.h
  30872. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.h 1970-01-01 01:00:00.000000000 +0100
  30873. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvStack.h 2010-11-09 20:28:07.160842220 +0100
  30874. @@ -0,0 +1,140 @@
  30875. +/*******************************************************************************
  30876. +* Copyright 2003, Marvell Semiconductor Israel LTD. *
  30877. +* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL. *
  30878. +* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT *
  30879. +* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE *
  30880. +* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL. *
  30881. +* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED, *
  30882. +* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE. *
  30883. +* *
  30884. +* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, *
  30885. +* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL *
  30886. +* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K. *
  30887. +* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL). *
  30888. +********************************************************************************
  30889. +* mvStack.h - Header File for :
  30890. +*
  30891. +* FILENAME: $Workfile: mvStack.h $
  30892. +* REVISION: $Revision: 1.1 $
  30893. +* LAST UPDATE: $Modtime: $
  30894. +*
  30895. +* DESCRIPTION:
  30896. +* This file defines simple Stack (LIFO) functionality.
  30897. +*
  30898. +*******************************************************************************/
  30899. +
  30900. +#ifndef __mvStack_h__
  30901. +#define __mvStack_h__
  30902. +
  30903. +
  30904. +/* includes */
  30905. +#include "mvTypes.h"
  30906. +
  30907. +
  30908. +/* defines */
  30909. +
  30910. +
  30911. +/* typedefs */
  30912. +/* Data structure describes general purpose Stack */
  30913. +typedef struct
  30914. +{
  30915. + int stackIdx;
  30916. + int numOfElements;
  30917. + MV_U32* stackElements;
  30918. +} MV_STACK;
  30919. +
  30920. +static INLINE MV_BOOL mvStackIsFull(void* stackHndl)
  30921. +{
  30922. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30923. +
  30924. + if(pStack->stackIdx == pStack->numOfElements)
  30925. + return MV_TRUE;
  30926. +
  30927. + return MV_FALSE;
  30928. +}
  30929. +
  30930. +static INLINE MV_BOOL mvStackIsEmpty(void* stackHndl)
  30931. +{
  30932. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30933. +
  30934. + if(pStack->stackIdx == 0)
  30935. + return MV_TRUE;
  30936. +
  30937. + return MV_FALSE;
  30938. +}
  30939. +/* Purpose: Push new element to stack
  30940. + * Inputs:
  30941. + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function.
  30942. + * - MV_U32 value - New element.
  30943. + *
  30944. + * Return: MV_STATUS MV_FULL - Failure. Stack is full.
  30945. + * MV_OK - Success. Element is put to stack.
  30946. + */
  30947. +static INLINE void mvStackPush(void* stackHndl, MV_U32 value)
  30948. +{
  30949. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30950. +
  30951. +#ifdef MV_RT_DEBUG
  30952. + if(pStack->stackIdx == pStack->numOfElements)
  30953. + {
  30954. + mvOsPrintf("mvStackPush: Stack is FULL\n");
  30955. + return;
  30956. + }
  30957. +#endif /* MV_RT_DEBUG */
  30958. +
  30959. + pStack->stackElements[pStack->stackIdx] = value;
  30960. + pStack->stackIdx++;
  30961. +}
  30962. +
  30963. +/* Purpose: Pop element from the top of stack and copy it to "pValue"
  30964. + * Inputs:
  30965. + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function.
  30966. + * - MV_U32 value - Element in the top of stack.
  30967. + *
  30968. + * Return: MV_STATUS MV_EMPTY - Failure. Stack is empty.
  30969. + * MV_OK - Success. Element is removed from the stack and
  30970. + * copied to pValue argument
  30971. + */
  30972. +static INLINE MV_U32 mvStackPop(void* stackHndl)
  30973. +{
  30974. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30975. +
  30976. +#ifdef MV_RT_DEBUG
  30977. + if(pStack->stackIdx == 0)
  30978. + {
  30979. + mvOsPrintf("mvStackPop: Stack is EMPTY\n");
  30980. + return 0;
  30981. + }
  30982. +#endif /* MV_RT_DEBUG */
  30983. +
  30984. + pStack->stackIdx--;
  30985. + return pStack->stackElements[pStack->stackIdx];
  30986. +}
  30987. +
  30988. +static INLINE int mvStackIndex(void* stackHndl)
  30989. +{
  30990. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30991. +
  30992. + return pStack->stackIdx;
  30993. +}
  30994. +
  30995. +static INLINE int mvStackFreeElements(void* stackHndl)
  30996. +{
  30997. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30998. +
  30999. + return (pStack->numOfElements - pStack->stackIdx);
  31000. +}
  31001. +
  31002. +/* mvStack.h API list */
  31003. +
  31004. +/* Create new Stack */
  31005. +void* mvStackCreate(int numOfElements);
  31006. +
  31007. +/* Delete existing stack */
  31008. +MV_STATUS mvStackDelete(void* stackHndl);
  31009. +
  31010. +/* Print status of the stack */
  31011. +void mvStackStatus(void* stackHndl, MV_BOOL isPrintElements);
  31012. +
  31013. +#endif /* __mvStack_h__ */
  31014. +
  31015. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvTypes.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvTypes.h
  31016. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvTypes.h 1970-01-01 01:00:00.000000000 +0100
  31017. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvTypes.h 2010-11-09 20:28:07.191385803 +0100
  31018. @@ -0,0 +1,245 @@
  31019. +/*******************************************************************************
  31020. +Copyright (C) Marvell International Ltd. and its affiliates
  31021. +
  31022. +This software file (the "File") is owned and distributed by Marvell
  31023. +International Ltd. and/or its affiliates ("Marvell") under the following
  31024. +alternative licensing terms. Once you have made an election to distribute the
  31025. +File under one of the following license alternatives, please (i) delete this
  31026. +introductory statement regarding license alternatives, (ii) delete the two
  31027. +license alternatives that you have not elected to use and (iii) preserve the
  31028. +Marvell copyright notice above.
  31029. +
  31030. +********************************************************************************
  31031. +Marvell Commercial License Option
  31032. +
  31033. +If you received this File from Marvell and you have entered into a commercial
  31034. +license agreement (a "Commercial License") with Marvell, the File is licensed
  31035. +to you under the terms of the applicable Commercial License.
  31036. +
  31037. +********************************************************************************
  31038. +Marvell GPL License Option
  31039. +
  31040. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31041. +modify this File in accordance with the terms and conditions of the General
  31042. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  31043. +available along with the File in the license.txt file or by writing to the Free
  31044. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  31045. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  31046. +
  31047. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  31048. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  31049. +DISCLAIMED. The GPL License provides additional details about this warranty
  31050. +disclaimer.
  31051. +********************************************************************************
  31052. +Marvell BSD License Option
  31053. +
  31054. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31055. +modify this File under the following licensing terms.
  31056. +Redistribution and use in source and binary forms, with or without modification,
  31057. +are permitted provided that the following conditions are met:
  31058. +
  31059. + * Redistributions of source code must retain the above copyright notice,
  31060. + this list of conditions and the following disclaimer.
  31061. +
  31062. + * Redistributions in binary form must reproduce the above copyright
  31063. + notice, this list of conditions and the following disclaimer in the
  31064. + documentation and/or other materials provided with the distribution.
  31065. +
  31066. + * Neither the name of Marvell nor the names of its contributors may be
  31067. + used to endorse or promote products derived from this software without
  31068. + specific prior written permission.
  31069. +
  31070. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  31071. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  31072. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31073. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  31074. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  31075. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31076. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  31077. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31078. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31079. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31080. +
  31081. +*******************************************************************************/
  31082. +
  31083. +
  31084. +#ifndef __INCmvTypesh
  31085. +#define __INCmvTypesh
  31086. +
  31087. +/* Defines */
  31088. +
  31089. +/* The following is a list of Marvell status */
  31090. +#define MV_ERROR (-1)
  31091. +#define MV_OK (0x00) /* Operation succeeded */
  31092. +#define MV_FAIL (0x01) /* Operation failed */
  31093. +#define MV_BAD_VALUE (0x02) /* Illegal value (general) */
  31094. +#define MV_OUT_OF_RANGE (0x03) /* The value is out of range */
  31095. +#define MV_BAD_PARAM (0x04) /* Illegal parameter in function called */
  31096. +#define MV_BAD_PTR (0x05) /* Illegal pointer value */
  31097. +#define MV_BAD_SIZE (0x06) /* Illegal size */
  31098. +#define MV_BAD_STATE (0x07) /* Illegal state of state machine */
  31099. +#define MV_SET_ERROR (0x08) /* Set operation failed */
  31100. +#define MV_GET_ERROR (0x09) /* Get operation failed */
  31101. +#define MV_CREATE_ERROR (0x0A) /* Fail while creating an item */
  31102. +#define MV_NOT_FOUND (0x0B) /* Item not found */
  31103. +#define MV_NO_MORE (0x0C) /* No more items found */
  31104. +#define MV_NO_SUCH (0x0D) /* No such item */
  31105. +#define MV_TIMEOUT (0x0E) /* Time Out */
  31106. +#define MV_NO_CHANGE (0x0F) /* Parameter(s) is already in this value */
  31107. +#define MV_NOT_SUPPORTED (0x10) /* This request is not support */
  31108. +#define MV_NOT_IMPLEMENTED (0x11) /* Request supported but not implemented */
  31109. +#define MV_NOT_INITIALIZED (0x12) /* The item is not initialized */
  31110. +#define MV_NO_RESOURCE (0x13) /* Resource not available (memory ...) */
  31111. +#define MV_FULL (0x14) /* Item is full (Queue or table etc...) */
  31112. +#define MV_EMPTY (0x15) /* Item is empty (Queue or table etc...) */
  31113. +#define MV_INIT_ERROR (0x16) /* Error occured while INIT process */
  31114. +#define MV_HW_ERROR (0x17) /* Hardware error */
  31115. +#define MV_TX_ERROR (0x18) /* Transmit operation not succeeded */
  31116. +#define MV_RX_ERROR (0x19) /* Recieve operation not succeeded */
  31117. +#define MV_NOT_READY (0x1A) /* The other side is not ready yet */
  31118. +#define MV_ALREADY_EXIST (0x1B) /* Tried to create existing item */
  31119. +#define MV_OUT_OF_CPU_MEM (0x1C) /* Cpu memory allocation failed. */
  31120. +#define MV_NOT_STARTED (0x1D) /* Not started yet */
  31121. +#define MV_BUSY (0x1E) /* Item is busy. */
  31122. +#define MV_TERMINATE (0x1F) /* Item terminates it's work. */
  31123. +#define MV_NOT_ALIGNED (0x20) /* Wrong alignment */
  31124. +#define MV_NOT_ALLOWED (0x21) /* Operation NOT allowed */
  31125. +#define MV_WRITE_PROTECT (0x22) /* Write protected */
  31126. +
  31127. +
  31128. +#define MV_INVALID (int)(-1)
  31129. +
  31130. +#define MV_FALSE 0
  31131. +#define MV_TRUE (!(MV_FALSE))
  31132. +
  31133. +
  31134. +#ifndef NULL
  31135. +#define NULL ((void*)0)
  31136. +#endif
  31137. +
  31138. +
  31139. +#ifndef MV_ASMLANGUAGE
  31140. +/* typedefs */
  31141. +
  31142. +typedef char MV_8;
  31143. +typedef unsigned char MV_U8;
  31144. +
  31145. +typedef int MV_32;
  31146. +typedef unsigned int MV_U32;
  31147. +
  31148. +typedef short MV_16;
  31149. +typedef unsigned short MV_U16;
  31150. +
  31151. +#ifdef MV_PPC64
  31152. +typedef long MV_64;
  31153. +typedef unsigned long MV_U64;
  31154. +#else
  31155. +typedef long long MV_64;
  31156. +typedef unsigned long long MV_U64;
  31157. +#endif
  31158. +
  31159. +typedef long MV_LONG; /* 32/64 */
  31160. +typedef unsigned long MV_ULONG; /* 32/64 */
  31161. +
  31162. +typedef int MV_STATUS;
  31163. +typedef int MV_BOOL;
  31164. +typedef void MV_VOID;
  31165. +typedef float MV_FLOAT;
  31166. +
  31167. +typedef int (*MV_FUNCPTR) (void); /* ptr to function returning int */
  31168. +typedef void (*MV_VOIDFUNCPTR) (void); /* ptr to function returning void */
  31169. +typedef double (*MV_DBLFUNCPTR) (void); /* ptr to function returning double*/
  31170. +typedef float (*MV_FLTFUNCPTR) (void); /* ptr to function returning float */
  31171. +
  31172. +typedef MV_U32 MV_KHZ;
  31173. +typedef MV_U32 MV_MHZ;
  31174. +typedef MV_U32 MV_HZ;
  31175. +
  31176. +
  31177. +/* This enumerator describes the set of commands that can be applied on */
  31178. +/* an engine (e.g. IDMA, XOR). Appling a comman depends on the current */
  31179. +/* status (see MV_STATE enumerator) */
  31180. +/* Start can be applied only when status is IDLE */
  31181. +/* Stop can be applied only when status is IDLE, ACTIVE or PAUSED */
  31182. +/* Pause can be applied only when status is ACTIVE */
  31183. +/* Restart can be applied only when status is PAUSED */
  31184. +typedef enum _mvCommand
  31185. +{
  31186. + MV_START, /* Start */
  31187. + MV_STOP, /* Stop */
  31188. + MV_PAUSE, /* Pause */
  31189. + MV_RESTART /* Restart */
  31190. +} MV_COMMAND;
  31191. +
  31192. +/* This enumerator describes the set of state conditions. */
  31193. +/* Moving from one state to other is stricted. */
  31194. +typedef enum _mvState
  31195. +{
  31196. + MV_IDLE,
  31197. + MV_ACTIVE,
  31198. + MV_PAUSED,
  31199. + MV_UNDEFINED_STATE
  31200. +} MV_STATE;
  31201. +
  31202. +
  31203. +/* This structure describes address space window. Window base can be */
  31204. +/* 64 bit, window size up to 4GB */
  31205. +typedef struct _mvAddrWin
  31206. +{
  31207. + MV_U32 baseLow; /* 32bit base low */
  31208. + MV_U32 baseHigh; /* 32bit base high */
  31209. + MV_U32 size; /* 32bit size */
  31210. +}MV_ADDR_WIN;
  31211. +
  31212. +/* This binary enumerator describes protection attribute status */
  31213. +typedef enum _mvProtRight
  31214. +{
  31215. + ALLOWED, /* Protection attribute allowed */
  31216. + FORBIDDEN /* Protection attribute forbidden */
  31217. +}MV_PROT_RIGHT;
  31218. +
  31219. +/* Unified struct for Rx and Tx packet operations. The user is required to */
  31220. +/* be familier only with Tx/Rx descriptor command status. */
  31221. +typedef struct _bufInfo
  31222. +{
  31223. + MV_U32 cmdSts; /* Tx/Rx command status */
  31224. + MV_U16 byteCnt; /* Size of valid data in the buffer */
  31225. + MV_U16 bufSize; /* Total size of the buffer */
  31226. + MV_U8 *pBuff; /* Pointer to Buffer */
  31227. + MV_U8 *pData; /* Pointer to data in the Buffer */
  31228. + MV_U32 userInfo1; /* Tx/Rx attached user information 1 */
  31229. + MV_U32 userInfo2; /* Tx/Rx attached user information 2 */
  31230. + struct _bufInfo *pNextBufInfo; /* Next buffer in packet */
  31231. +} BUF_INFO;
  31232. +
  31233. +/* This structure contains information describing one of buffers
  31234. + * (fragments) they are built Ethernet packet.
  31235. + */
  31236. +typedef struct
  31237. +{
  31238. + MV_U8* bufVirtPtr;
  31239. + MV_ULONG bufPhysAddr;
  31240. + MV_U32 bufSize;
  31241. + MV_U32 dataSize;
  31242. + MV_U32 memHandle;
  31243. + MV_32 bufAddrShift;
  31244. +} MV_BUF_INFO;
  31245. +
  31246. +/* This structure contains information describing Ethernet packet.
  31247. + * The packet can be divided for few buffers (fragments)
  31248. + */
  31249. +typedef struct
  31250. +{
  31251. + MV_ULONG osInfo;
  31252. + MV_BUF_INFO *pFrags;
  31253. + MV_U32 status;
  31254. + MV_U16 pktSize;
  31255. + MV_U16 numFrags;
  31256. + MV_U32 ownerId;
  31257. + MV_U32 fragIP;
  31258. +} MV_PKT_INFO;
  31259. +
  31260. +#endif /* MV_ASMLANGUAGE */
  31261. +
  31262. +#endif /* __INCmvTypesh */
  31263. +
  31264. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/dbg-trace.c
  31265. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.c 1970-01-01 01:00:00.000000000 +0100
  31266. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/dbg-trace.c 2010-11-09 20:28:07.232495685 +0100
  31267. @@ -0,0 +1,110 @@
  31268. +#include <linux/kernel.h>
  31269. +#include <linux/slab.h>
  31270. +#include <linux/time.h>
  31271. +#include "dbg-trace.h"
  31272. +
  31273. +#define TRACE_ARR_LEN 800
  31274. +#define STR_LEN 128
  31275. +struct trace {
  31276. + struct timeval tv;
  31277. + char str[STR_LEN];
  31278. + unsigned int callback_val1;
  31279. + unsigned int callback_val2;
  31280. + char valid;
  31281. +};
  31282. +static unsigned int (*trc_callback1) (unsigned char) = NULL;
  31283. +static unsigned int (*trc_callback2) (unsigned char) = NULL;
  31284. +static unsigned char trc_param1 = 0;
  31285. +static unsigned char trc_param2 = 0;
  31286. +struct trace *trc_arr;
  31287. +static int trc_index;
  31288. +static int trc_active = 0;
  31289. +
  31290. +void TRC_START()
  31291. +{
  31292. + trc_active = 1;
  31293. +}
  31294. +
  31295. +void TRC_STOP()
  31296. +{
  31297. + trc_active = 0;
  31298. +}
  31299. +
  31300. +void TRC_INIT(void *callback1, void *callback2, unsigned char callback1_param, unsigned char callback2_param)
  31301. +{
  31302. + printk("Marvell debug tracing is on\n");
  31303. + trc_arr = (struct trace *)kmalloc(TRACE_ARR_LEN*sizeof(struct trace),GFP_KERNEL);
  31304. + if(trc_arr == NULL)
  31305. + {
  31306. + printk("Can't allocate Debug Trace buffer\n");
  31307. + return;
  31308. + }
  31309. + memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));
  31310. + trc_index = 0;
  31311. + trc_callback1 = callback1;
  31312. + trc_callback2 = callback2;
  31313. + trc_param1 = callback1_param;
  31314. + trc_param2 = callback2_param;
  31315. +}
  31316. +void TRC_REC(char *fmt,...)
  31317. +{
  31318. + va_list args;
  31319. + struct trace *trc = &trc_arr[trc_index];
  31320. +
  31321. + if(trc_active == 0)
  31322. + return;
  31323. +
  31324. + do_gettimeofday(&trc->tv);
  31325. + if(trc_callback1)
  31326. + trc->callback_val1 = trc_callback1(trc_param1);
  31327. + if(trc_callback2)
  31328. + trc->callback_val2 = trc_callback2(trc_param2);
  31329. + va_start(args, fmt);
  31330. + vsprintf(trc->str,fmt,args);
  31331. + va_end(args);
  31332. + trc->valid = 1;
  31333. + if((++trc_index) == TRACE_ARR_LEN) {
  31334. + trc_index = 0;
  31335. + }
  31336. +}
  31337. +void TRC_OUTPUT(void)
  31338. +{
  31339. + int i,j;
  31340. + struct trace *p;
  31341. + printk("\n\nTrace %d items\n",TRACE_ARR_LEN);
  31342. + for(i=0,j=trc_index; i<TRACE_ARR_LEN; i++,j++) {
  31343. + if(j == TRACE_ARR_LEN)
  31344. + j = 0;
  31345. + p = &trc_arr[j];
  31346. + if(p->valid) {
  31347. + unsigned long uoffs;
  31348. + struct trace *plast;
  31349. + if(p == &trc_arr[0])
  31350. + plast = &trc_arr[TRACE_ARR_LEN-1];
  31351. + else
  31352. + plast = p-1;
  31353. + if(p->tv.tv_sec == ((plast)->tv.tv_sec))
  31354. + uoffs = (p->tv.tv_usec - ((plast)->tv.tv_usec));
  31355. + else
  31356. + uoffs = (1000000 - ((plast)->tv.tv_usec)) +
  31357. + ((p->tv.tv_sec - ((plast)->tv.tv_sec) - 1) * 1000000) +
  31358. + p->tv.tv_usec;
  31359. + printk("%03d: [+%ld usec]", j, (unsigned long)uoffs);
  31360. + if(trc_callback1)
  31361. + printk("[%u]",p->callback_val1);
  31362. + if(trc_callback2)
  31363. + printk("[%u]",p->callback_val2);
  31364. + printk(": %s",p->str);
  31365. + }
  31366. + p->valid = 0;
  31367. + }
  31368. + memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));
  31369. + trc_index = 0;
  31370. +}
  31371. +void TRC_RELEASE(void)
  31372. +{
  31373. + kfree(trc_arr);
  31374. + trc_index = 0;
  31375. +}
  31376. +
  31377. +
  31378. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/dbg-trace.h
  31379. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.h 1970-01-01 01:00:00.000000000 +0100
  31380. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/dbg-trace.h 2010-11-09 20:28:07.276291416 +0100
  31381. @@ -0,0 +1,24 @@
  31382. +
  31383. +#ifndef _MV_DBG_TRCE_H_
  31384. +#define _MV_DBG_TRCE_H_
  31385. +
  31386. +#ifdef CONFIG_MV_DBG_TRACE
  31387. +void TRC_INIT(void *callback1, void *callback2,
  31388. + unsigned char callback1_param, unsigned char callback2_param);
  31389. +void TRC_REC(char *fmt,...);
  31390. +void TRC_OUTPUT(void);
  31391. +void TRC_RELEASE(void);
  31392. +void TRC_START(void);
  31393. +void TRC_STOP(void);
  31394. +
  31395. +#else
  31396. +#define TRC_INIT(x1,x2,x3,x4)
  31397. +#define TRC_REC(X...)
  31398. +#define TRC_OUTPUT()
  31399. +#define TRC_RELEASE()
  31400. +#define TRC_START()
  31401. +#define TRC_STOP()
  31402. +#endif
  31403. +
  31404. +
  31405. +#endif
  31406. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c
  31407. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c 1970-01-01 01:00:00.000000000 +0100
  31408. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c 2010-11-09 20:28:07.327371127 +0100
  31409. @@ -0,0 +1,2513 @@
  31410. +/*******************************************************************************
  31411. +Copyright (C) Marvell International Ltd. and its affiliates
  31412. +
  31413. +This software file (the "File") is owned and distributed by Marvell
  31414. +International Ltd. and/or its affiliates ("Marvell") under the following
  31415. +alternative licensing terms. Once you have made an election to distribute the
  31416. +File under one of the following license alternatives, please (i) delete this
  31417. +introductory statement regarding license alternatives, (ii) delete the two
  31418. +license alternatives that you have not elected to use and (iii) preserve the
  31419. +Marvell copyright notice above.
  31420. +
  31421. +********************************************************************************
  31422. +Marvell Commercial License Option
  31423. +
  31424. +If you received this File from Marvell and you have entered into a commercial
  31425. +license agreement (a "Commercial License") with Marvell, the File is licensed
  31426. +to you under the terms of the applicable Commercial License.
  31427. +
  31428. +********************************************************************************
  31429. +Marvell GPL License Option
  31430. +
  31431. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31432. +modify this File in accordance with the terms and conditions of the General
  31433. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  31434. +available along with the File in the license.txt file or by writing to the Free
  31435. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  31436. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  31437. +
  31438. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  31439. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  31440. +DISCLAIMED. The GPL License provides additional details about this warranty
  31441. +disclaimer.
  31442. +********************************************************************************
  31443. +Marvell BSD License Option
  31444. +
  31445. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31446. +modify this File under the following licensing terms.
  31447. +Redistribution and use in source and binary forms, with or without modification,
  31448. +are permitted provided that the following conditions are met:
  31449. +
  31450. + * Redistributions of source code must retain the above copyright notice,
  31451. + this list of conditions and the following disclaimer.
  31452. +
  31453. + * Redistributions in binary form must reproduce the above copyright
  31454. + notice, this list of conditions and the following disclaimer in the
  31455. + documentation and/or other materials provided with the distribution.
  31456. +
  31457. + * Neither the name of Marvell nor the names of its contributors may be
  31458. + used to endorse or promote products derived from this software without
  31459. + specific prior written permission.
  31460. +
  31461. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  31462. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  31463. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31464. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  31465. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  31466. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31467. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  31468. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31469. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31470. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31471. +
  31472. +*******************************************************************************/
  31473. +
  31474. +#include "boardEnv/mvBoardEnvLib.h"
  31475. +#include "ctrlEnv/mvCtrlEnvLib.h"
  31476. +#include "ctrlEnv/sys/mvCpuIf.h"
  31477. +#include "cpu/mvCpu.h"
  31478. +#include "cntmr/mvCntmr.h"
  31479. +#include "gpp/mvGpp.h"
  31480. +#include "twsi/mvTwsi.h"
  31481. +#include "pex/mvPex.h"
  31482. +#include "device/mvDevice.h"
  31483. +#include "eth/gbe/mvEthRegs.h"
  31484. +
  31485. +/* defines */
  31486. +/* #define MV_DEBUG */
  31487. +#ifdef MV_DEBUG
  31488. + #define DB(x) x
  31489. +#else
  31490. + #define DB(x)
  31491. +#endif
  31492. +
  31493. +extern MV_CPU_ARM_CLK _cpuARMDDRCLK[];
  31494. +
  31495. +#define CODE_IN_ROM MV_FALSE
  31496. +#define CODE_IN_RAM MV_TRUE
  31497. +
  31498. +extern MV_BOARD_INFO* boardInfoTbl[];
  31499. +#define BOARD_INFO(boardId) boardInfoTbl[boardId - BOARD_ID_BASE]
  31500. +
  31501. +/* Locals */
  31502. +static MV_DEV_CS_INFO* boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  31503. +
  31504. +MV_U32 tClkRate = -1;
  31505. +
  31506. +
  31507. +/*******************************************************************************
  31508. +* mvBoardEnvInit - Init board
  31509. +*
  31510. +* DESCRIPTION:
  31511. +* In this function the board environment take care of device bank
  31512. +* initialization.
  31513. +*
  31514. +* INPUT:
  31515. +* None.
  31516. +*
  31517. +* OUTPUT:
  31518. +* None.
  31519. +*
  31520. +* RETURN:
  31521. +* None.
  31522. +*
  31523. +*******************************************************************************/
  31524. +MV_VOID mvBoardEnvInit(MV_VOID)
  31525. +{
  31526. + MV_U32 boardId= mvBoardIdGet();
  31527. +
  31528. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31529. + {
  31530. + mvOsPrintf("mvBoardEnvInit:Board unknown.\n");
  31531. + return;
  31532. +
  31533. + }
  31534. +
  31535. + /* Set GPP Out value */
  31536. + MV_REG_WRITE(GPP_DATA_OUT_REG(0), BOARD_INFO(boardId)->gppOutValLow);
  31537. + MV_REG_WRITE(GPP_DATA_OUT_REG(1), BOARD_INFO(boardId)->gppOutValHigh);
  31538. +
  31539. + /* set GPP polarity */
  31540. + mvGppPolaritySet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValLow);
  31541. + mvGppPolaritySet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValHigh);
  31542. +
  31543. + /* Workaround for Erratum FE-MISC-70*/
  31544. + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV)
  31545. + {
  31546. + BOARD_INFO(boardId)->gppOutEnValLow &= 0xfffffffd;
  31547. + BOARD_INFO(boardId)->gppOutEnValLow |= (BOARD_INFO(boardId)->gppOutEnValHigh) & 0x00000002;
  31548. + } /*End of WA*/
  31549. +
  31550. + /* Set GPP Out Enable*/
  31551. + mvGppTypeSet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValLow);
  31552. + mvGppTypeSet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValHigh);
  31553. +
  31554. + /* Nand CE */
  31555. + MV_REG_BIT_SET(NAND_CTRL_REG, NAND_ACTCEBOOT_BIT);
  31556. +}
  31557. +
  31558. +/*******************************************************************************
  31559. +* mvBoardModelGet - Get Board model
  31560. +*
  31561. +* DESCRIPTION:
  31562. +* This function returns 16bit describing board model.
  31563. +* Board model is constructed of one byte major and minor numbers in the
  31564. +* following manner:
  31565. +*
  31566. +* INPUT:
  31567. +* None.
  31568. +*
  31569. +* OUTPUT:
  31570. +* None.
  31571. +*
  31572. +* RETURN:
  31573. +* String describing board model.
  31574. +*
  31575. +*******************************************************************************/
  31576. +MV_U16 mvBoardModelGet(MV_VOID)
  31577. +{
  31578. + return (mvBoardIdGet() >> 16);
  31579. +}
  31580. +
  31581. +/*******************************************************************************
  31582. +* mbBoardRevlGet - Get Board revision
  31583. +*
  31584. +* DESCRIPTION:
  31585. +* This function returns a 32bit describing the board revision.
  31586. +* Board revision is constructed of 4bytes. 2bytes describes major number
  31587. +* and the other 2bytes describes minor munber.
  31588. +* For example for board revision 3.4 the function will return
  31589. +* 0x00030004.
  31590. +*
  31591. +* INPUT:
  31592. +* None.
  31593. +*
  31594. +* OUTPUT:
  31595. +* None.
  31596. +*
  31597. +* RETURN:
  31598. +* String describing board model.
  31599. +*
  31600. +*******************************************************************************/
  31601. +MV_U16 mvBoardRevGet(MV_VOID)
  31602. +{
  31603. + return (mvBoardIdGet() & 0xFFFF);
  31604. +}
  31605. +
  31606. +/*******************************************************************************
  31607. +* mvBoardNameGet - Get Board name
  31608. +*
  31609. +* DESCRIPTION:
  31610. +* This function returns a string describing the board model and revision.
  31611. +* String is extracted from board I2C EEPROM.
  31612. +*
  31613. +* INPUT:
  31614. +* None.
  31615. +*
  31616. +* OUTPUT:
  31617. +* pNameBuff - Buffer to contain board name string. Minimum size 32 chars.
  31618. +*
  31619. +* RETURN:
  31620. +*
  31621. +* MV_ERROR if informantion can not be read.
  31622. +*******************************************************************************/
  31623. +MV_STATUS mvBoardNameGet(char *pNameBuff)
  31624. +{
  31625. + MV_U32 boardId= mvBoardIdGet();
  31626. +
  31627. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31628. + {
  31629. + mvOsSPrintf (pNameBuff, "Board unknown.\n");
  31630. + return MV_ERROR;
  31631. +
  31632. + }
  31633. +
  31634. + mvOsSPrintf (pNameBuff, "%s",BOARD_INFO(boardId)->boardName);
  31635. +
  31636. + return MV_OK;
  31637. +}
  31638. +
  31639. +/*******************************************************************************
  31640. +* mvBoardIsPortInSgmii -
  31641. +*
  31642. +* DESCRIPTION:
  31643. +* This routine returns MV_TRUE for port number works in SGMII or MV_FALSE
  31644. +* For all other options.
  31645. +*
  31646. +* INPUT:
  31647. +* ethPortNum - Ethernet port number.
  31648. +*
  31649. +* OUTPUT:
  31650. +* None.
  31651. +*
  31652. +* RETURN:
  31653. +* MV_TRUE - port in SGMII.
  31654. +* MV_FALSE - other.
  31655. +*
  31656. +*******************************************************************************/
  31657. +MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum)
  31658. +{
  31659. + MV_BOOL ethPortSgmiiSupport[BOARD_ETH_PORT_NUM] = MV_ETH_PORT_SGMII;
  31660. +
  31661. + if(ethPortNum >= BOARD_ETH_PORT_NUM)
  31662. + {
  31663. + mvOsPrintf ("Invalid portNo=%d\n", ethPortNum);
  31664. + return MV_FALSE;
  31665. + }
  31666. + return ethPortSgmiiSupport[ethPortNum];
  31667. +}
  31668. +
  31669. +/*******************************************************************************
  31670. +* mvBoardIsPortInGmii -
  31671. +*
  31672. +* DESCRIPTION:
  31673. +* This routine returns MV_TRUE for port number works in GMII or MV_FALSE
  31674. +* For all other options.
  31675. +*
  31676. +* INPUT:
  31677. +*
  31678. +* OUTPUT:
  31679. +* None.
  31680. +*
  31681. +* RETURN:
  31682. +* MV_TRUE - port in GMII.
  31683. +* MV_FALSE - other.
  31684. +*
  31685. +*******************************************************************************/
  31686. +MV_BOOL mvBoardIsPortInGmii(MV_VOID)
  31687. +{
  31688. + MV_U32 devClassId, devClass = 0;
  31689. + if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)
  31690. + {
  31691. + /* Get MPP module ID */
  31692. + devClassId = mvBoarModuleTypeGet(devClass);
  31693. + if (MV_BOARD_MODULE_GMII_ID == devClassId)
  31694. + return MV_TRUE;
  31695. + }
  31696. + else if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII)
  31697. + return MV_TRUE;
  31698. +
  31699. + return MV_FALSE;
  31700. +}
  31701. +/*******************************************************************************
  31702. +* mvBoardPhyAddrGet - Get the phy address
  31703. +*
  31704. +* DESCRIPTION:
  31705. +* This routine returns the Phy address of a given ethernet port.
  31706. +*
  31707. +* INPUT:
  31708. +* ethPortNum - Ethernet port number.
  31709. +*
  31710. +* OUTPUT:
  31711. +* None.
  31712. +*
  31713. +* RETURN:
  31714. +* 32bit describing Phy address, -1 if the port number is wrong.
  31715. +*
  31716. +*******************************************************************************/
  31717. +MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum)
  31718. +{
  31719. + MV_U32 boardId= mvBoardIdGet();
  31720. +
  31721. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31722. + {
  31723. + mvOsPrintf("mvBoardPhyAddrGet: Board unknown.\n");
  31724. + return MV_ERROR;
  31725. + }
  31726. +
  31727. + return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardEthSmiAddr;
  31728. +}
  31729. +
  31730. +/*******************************************************************************
  31731. +* mvBoardMacSpeedGet - Get the Mac speed
  31732. +*
  31733. +* DESCRIPTION:
  31734. +* This routine returns the Mac speed if pre define of a given ethernet port.
  31735. +*
  31736. +* INPUT:
  31737. +* ethPortNum - Ethernet port number.
  31738. +*
  31739. +* OUTPUT:
  31740. +* None.
  31741. +*
  31742. +* RETURN:
  31743. +* MV_BOARD_MAC_SPEED, -1 if the port number is wrong.
  31744. +*
  31745. +*******************************************************************************/
  31746. +MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum)
  31747. +{
  31748. + MV_U32 boardId= mvBoardIdGet();
  31749. +
  31750. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31751. + {
  31752. + mvOsPrintf("mvBoardMacSpeedGet: Board unknown.\n");
  31753. + return MV_ERROR;
  31754. + }
  31755. +
  31756. + return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardMacSpeed;
  31757. +}
  31758. +
  31759. +/*******************************************************************************
  31760. +* mvBoardLinkStatusIrqGet - Get the IRQ number for the link status indication
  31761. +*
  31762. +* DESCRIPTION:
  31763. +* This routine returns the IRQ number for the link status indication.
  31764. +*
  31765. +* INPUT:
  31766. +* ethPortNum - Ethernet port number.
  31767. +*
  31768. +* OUTPUT:
  31769. +* None.
  31770. +*
  31771. +* RETURN:
  31772. +* the number of the IRQ for the link status indication, -1 if the port
  31773. +* number is wrong or if not relevant.
  31774. +*
  31775. +*******************************************************************************/
  31776. +MV_32 mvBoardLinkStatusIrqGet(MV_U32 ethPortNum)
  31777. +{
  31778. + MV_U32 boardId = mvBoardIdGet();
  31779. +
  31780. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31781. + {
  31782. + mvOsPrintf("mvBoardLinkStatusIrqGet: Board unknown.\n");
  31783. + return MV_ERROR;
  31784. + }
  31785. +
  31786. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].linkStatusIrq;
  31787. +}
  31788. +
  31789. +/*******************************************************************************
  31790. +* mvBoardSwitchPortGet - Get the mapping between the board connector and the
  31791. +* Ethernet Switch port
  31792. +*
  31793. +* DESCRIPTION:
  31794. +* This routine returns the matching Switch port.
  31795. +*
  31796. +* INPUT:
  31797. +* ethPortNum - Ethernet port number.
  31798. +* boardPortNum - logical number of the connector on the board
  31799. +*
  31800. +* OUTPUT:
  31801. +* None.
  31802. +*
  31803. +* RETURN:
  31804. +* the matching Switch port, -1 if the port number is wrong or if not relevant.
  31805. +*
  31806. +*******************************************************************************/
  31807. +MV_32 mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum)
  31808. +{
  31809. + MV_U32 boardId = mvBoardIdGet();
  31810. +
  31811. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31812. + {
  31813. + mvOsPrintf("mvBoardSwitchPortGet: Board unknown.\n");
  31814. + return MV_ERROR;
  31815. + }
  31816. + if (boardPortNum >= BOARD_ETH_SWITCH_PORT_NUM)
  31817. + {
  31818. + mvOsPrintf("mvBoardSwitchPortGet: Illegal board port number.\n");
  31819. + return MV_ERROR;
  31820. + }
  31821. +
  31822. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdPort[boardPortNum];
  31823. +}
  31824. +
  31825. +/*******************************************************************************
  31826. +* mvBoardSwitchCpuPortGet - Get the the Ethernet Switch CPU port
  31827. +*
  31828. +* DESCRIPTION:
  31829. +* This routine returns the Switch CPU port.
  31830. +*
  31831. +* INPUT:
  31832. +* ethPortNum - Ethernet port number.
  31833. +*
  31834. +* OUTPUT:
  31835. +* None.
  31836. +*
  31837. +* RETURN:
  31838. +* the Switch CPU port, -1 if the port number is wrong or if not relevant.
  31839. +*
  31840. +*******************************************************************************/
  31841. +MV_32 mvBoardSwitchCpuPortGet(MV_U32 ethPortNum)
  31842. +{
  31843. + MV_U32 boardId = mvBoardIdGet();
  31844. +
  31845. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31846. + {
  31847. + mvOsPrintf("mvBoardSwitchCpuPortGet: Board unknown.\n");
  31848. + return MV_ERROR;
  31849. + }
  31850. +
  31851. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdCpuPort;
  31852. +}
  31853. +
  31854. +/*******************************************************************************
  31855. +* mvBoardIsSwitchConnected - Get switch connection status
  31856. +* DESCRIPTION:
  31857. +* This routine returns port's connection status
  31858. +*
  31859. +* INPUT:
  31860. +* ethPortNum - Ethernet port number.
  31861. +*
  31862. +* OUTPUT:
  31863. +* None.
  31864. +*
  31865. +* RETURN:
  31866. +* 1 - if ethPortNum is connected to switch, 0 otherwise
  31867. +*
  31868. +*******************************************************************************/
  31869. +MV_32 mvBoardIsSwitchConnected(MV_U32 ethPortNum)
  31870. +{
  31871. + MV_U32 boardId = mvBoardIdGet();
  31872. +
  31873. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31874. + {
  31875. + mvOsPrintf("mvBoardIsSwitchConnected: Board unknown.\n");
  31876. + return MV_ERROR;
  31877. + }
  31878. +
  31879. + if(ethPortNum >= BOARD_INFO(boardId)->numBoardMacInfo)
  31880. + {
  31881. + mvOsPrintf("mvBoardIsSwitchConnected: Illegal port number(%u)\n", ethPortNum);
  31882. + return MV_ERROR;
  31883. + }
  31884. +
  31885. + if((MV_32)(BOARD_INFO(boardId)->pSwitchInfo))
  31886. + return (MV_32)(BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].switchOnPort == ethPortNum);
  31887. + else
  31888. + return 0;
  31889. +}
  31890. +/*******************************************************************************
  31891. +* mvBoardSmiScanModeGet - Get Switch SMI scan mode
  31892. +*
  31893. +* DESCRIPTION:
  31894. +* This routine returns Switch SMI scan mode.
  31895. +*
  31896. +* INPUT:
  31897. +* ethPortNum - Ethernet port number.
  31898. +*
  31899. +* OUTPUT:
  31900. +* None.
  31901. +*
  31902. +* RETURN:
  31903. +* 1 for SMI_MANUAL_MODE, -1 if the port number is wrong or if not relevant.
  31904. +*
  31905. +*******************************************************************************/
  31906. +MV_32 mvBoardSmiScanModeGet(MV_U32 ethPortNum)
  31907. +{
  31908. + MV_U32 boardId = mvBoardIdGet();
  31909. +
  31910. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31911. + {
  31912. + mvOsPrintf("mvBoardSmiScanModeGet: Board unknown.\n");
  31913. + return MV_ERROR;
  31914. + }
  31915. +
  31916. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].smiScanMode;
  31917. +}
  31918. +/*******************************************************************************
  31919. +* mvBoardSpecInitGet -
  31920. +*
  31921. +* DESCRIPTION:
  31922. +*
  31923. +* INPUT:
  31924. +*
  31925. +* OUTPUT:
  31926. +* None.
  31927. +*
  31928. +* RETURN: Return MV_TRUE and parameters in case board need spesific phy init,
  31929. +* otherwise return MV_FALSE.
  31930. +*
  31931. +*
  31932. +*******************************************************************************/
  31933. +
  31934. +MV_BOOL mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data)
  31935. +{
  31936. + return MV_FALSE;
  31937. +}
  31938. +
  31939. +/*******************************************************************************
  31940. +* mvBoardTclkGet - Get the board Tclk (Controller clock)
  31941. +*
  31942. +* DESCRIPTION:
  31943. +* This routine extract the controller core clock.
  31944. +* This function uses the controller counters to make identification.
  31945. +* Note: In order to avoid interference, make sure task context switch
  31946. +* and interrupts will not occure during this function operation
  31947. +*
  31948. +* INPUT:
  31949. +* countNum - Counter number.
  31950. +*
  31951. +* OUTPUT:
  31952. +* None.
  31953. +*
  31954. +* RETURN:
  31955. +* 32bit clock cycles in Hertz.
  31956. +*
  31957. +*******************************************************************************/
  31958. +MV_U32 mvBoardTclkGet(MV_VOID)
  31959. +{
  31960. + if(mvCtrlModelGet()==MV_6281_DEV_ID)
  31961. + {
  31962. +#if defined(TCLK_AUTO_DETECT)
  31963. + MV_U32 tmpTClkRate = MV_BOARD_TCLK_166MHZ;
  31964. +
  31965. + tmpTClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  31966. + tmpTClkRate &= MSAR_TCLCK_MASK;
  31967. +
  31968. + switch (tmpTClkRate)
  31969. + {
  31970. + case MSAR_TCLCK_166:
  31971. + return MV_BOARD_TCLK_166MHZ;
  31972. + break;
  31973. + case MSAR_TCLCK_200:
  31974. + return MV_BOARD_TCLK_200MHZ;
  31975. + break;
  31976. + }
  31977. +#else
  31978. + return MV_BOARD_TCLK_200MHZ;
  31979. +#endif
  31980. + }
  31981. +
  31982. + return MV_BOARD_TCLK_166MHZ;
  31983. +
  31984. +}
  31985. +/*******************************************************************************
  31986. +* mvBoardSysClkGet - Get the board SysClk (CPU bus clock)
  31987. +*
  31988. +* DESCRIPTION:
  31989. +* This routine extract the CPU bus clock.
  31990. +*
  31991. +* INPUT:
  31992. +* countNum - Counter number.
  31993. +*
  31994. +* OUTPUT:
  31995. +* None.
  31996. +*
  31997. +* RETURN:
  31998. +* 32bit clock cycles in Hertz.
  31999. +*
  32000. +*******************************************************************************/
  32001. +static MV_U32 mvBoard6180SysClkGet(MV_VOID)
  32002. +{
  32003. + MV_U32 sysClkRate=0;
  32004. + MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
  32005. +
  32006. + sysClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  32007. + sysClkRate = sysClkRate & MSAR_CPUCLCK_MASK_6180;
  32008. + sysClkRate = sysClkRate >> MSAR_CPUCLCK_OFFS_6180;
  32009. +
  32010. + sysClkRate = _cpu6180_ddr_l2_CLK[sysClkRate].ddrClk;
  32011. +
  32012. + return sysClkRate;
  32013. +
  32014. +}
  32015. +
  32016. +MV_U32 mvBoardSysClkGet(MV_VOID)
  32017. +{
  32018. +#ifdef SYSCLK_AUTO_DETECT
  32019. + MV_U32 sysClkRate, tmp, pClkRate, indexDdrRtio;
  32020. + MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;
  32021. + MV_U32 ddrRtio[][2] = MV_DDR_CLCK_RTIO_TBL;
  32022. +
  32023. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  32024. + return mvBoard6180SysClkGet();
  32025. +
  32026. + tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  32027. + pClkRate = MSAR_CPUCLCK_EXTRACT(tmp);
  32028. + pClkRate = cpuCLK[pClkRate];
  32029. +
  32030. + indexDdrRtio = tmp & MSAR_DDRCLCK_RTIO_MASK;
  32031. + indexDdrRtio = indexDdrRtio >> MSAR_DDRCLCK_RTIO_OFFS;
  32032. + if(ddrRtio[indexDdrRtio][0] != 0)
  32033. + sysClkRate = ((pClkRate * ddrRtio[indexDdrRtio][1]) / ddrRtio[indexDdrRtio][0]);
  32034. + else
  32035. + sysClkRate = 0;
  32036. + return sysClkRate;
  32037. +#else
  32038. + return MV_BOARD_DEFAULT_SYSCLK;
  32039. +#endif
  32040. +}
  32041. +
  32042. +
  32043. +/*******************************************************************************
  32044. +* mvBoardPexBridgeIntPinGet - Get PEX to PCI bridge interrupt pin number
  32045. +*
  32046. +* DESCRIPTION:
  32047. +* Multi-ported PCI Express bridges that is implemented on the board
  32048. +* collapse interrupts across multiple conventional PCI/PCI-X buses.
  32049. +* A dual-headed PCI Express bridge would map (or "swizzle") the
  32050. +* interrupts per the following table (in accordance with the respective
  32051. +* logical PCI/PCI-X bridge's Device Number), collapse the INTA#-INTD#
  32052. +* signals from its two logical PCI/PCI-X bridges, collapse the
  32053. +* INTA#-INTD# signals from any internal sources, and convert the
  32054. +* signals to in-band PCI Express messages. 10
  32055. +* This function returns the upstream interrupt as it was converted by
  32056. +* the bridge, according to board configuration and the following table:
  32057. +* PCI dev num
  32058. +* Interrupt pin 7, 8, 9
  32059. +* A -> A D C
  32060. +* B -> B A D
  32061. +* C -> C B A
  32062. +* D -> D C B
  32063. +*
  32064. +*
  32065. +* INPUT:
  32066. +* devNum - PCI/PCIX device number.
  32067. +* intPin - PCI Int pin
  32068. +*
  32069. +* OUTPUT:
  32070. +* None.
  32071. +*
  32072. +* RETURN:
  32073. +* Int pin connected to the Interrupt controller
  32074. +*
  32075. +*******************************************************************************/
  32076. +MV_U32 mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin)
  32077. +{
  32078. + MV_U32 realIntPin = ((intPin + (3 - (devNum % 4))) %4 );
  32079. +
  32080. + if (realIntPin == 0) return 4;
  32081. + else return realIntPin;
  32082. +
  32083. +}
  32084. +
  32085. +/*******************************************************************************
  32086. +* mvBoardDebugLedNumGet - Get number of debug Leds
  32087. +*
  32088. +* DESCRIPTION:
  32089. +* INPUT:
  32090. +* boardId
  32091. +*
  32092. +* OUTPUT:
  32093. +* None.
  32094. +*
  32095. +* RETURN:
  32096. +* None.
  32097. +*
  32098. +*******************************************************************************/
  32099. +MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId)
  32100. +{
  32101. + return BOARD_INFO(boardId)->activeLedsNumber;
  32102. +}
  32103. +
  32104. +/*******************************************************************************
  32105. +* mvBoardDebugLeg - Set the board debug Leds
  32106. +*
  32107. +* DESCRIPTION: turn on/off status leds.
  32108. +* Note: assume MPP leds are part of group 0 only.
  32109. +*
  32110. +* INPUT:
  32111. +* hexNum - Number to be displied in hex by Leds.
  32112. +*
  32113. +* OUTPUT:
  32114. +* None.
  32115. +*
  32116. +* RETURN:
  32117. +* None.
  32118. +*
  32119. +*******************************************************************************/
  32120. +MV_VOID mvBoardDebugLed(MV_U32 hexNum)
  32121. +{
  32122. + MV_U32 val = 0,totalMask, currentBitMask = 1,i;
  32123. + MV_U32 boardId= mvBoardIdGet();
  32124. +
  32125. + if (BOARD_INFO(boardId)->pLedGppPin == NULL)
  32126. + return;
  32127. +
  32128. + totalMask = (1 << BOARD_INFO(boardId)->activeLedsNumber) -1;
  32129. + hexNum &= totalMask;
  32130. + totalMask = 0;
  32131. +
  32132. + for (i = 0 ; i < BOARD_INFO(boardId)->activeLedsNumber ; i++)
  32133. + {
  32134. + if (hexNum & currentBitMask)
  32135. + {
  32136. + val |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);
  32137. + }
  32138. +
  32139. + totalMask |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);
  32140. +
  32141. + currentBitMask = (currentBitMask << 1);
  32142. + }
  32143. +
  32144. + if (BOARD_INFO(boardId)->ledsPolarity)
  32145. + {
  32146. + mvGppValueSet(0, totalMask, val);
  32147. + }
  32148. + else
  32149. + {
  32150. + mvGppValueSet(0, totalMask, ~val);
  32151. + }
  32152. +}
  32153. +
  32154. +
  32155. +/*******************************************************************************
  32156. +* mvBoarGpioPinGet - mvBoarGpioPinGet
  32157. +*
  32158. +* DESCRIPTION:
  32159. +*
  32160. +* INPUT:
  32161. +* class - MV_BOARD_GPP_CLASS enum.
  32162. +*
  32163. +* OUTPUT:
  32164. +* None.
  32165. +*
  32166. +* RETURN:
  32167. +* GPIO pin number. The function return -1 for bad parameters.
  32168. +*
  32169. +*******************************************************************************/
  32170. +MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index)
  32171. +{
  32172. + MV_U32 boardId, i;
  32173. + MV_U32 indexFound = 0;
  32174. +
  32175. + boardId = mvBoardIdGet();
  32176. +
  32177. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32178. + {
  32179. + mvOsPrintf("mvBoardRTCGpioPinGet:Board unknown.\n");
  32180. + return MV_ERROR;
  32181. +
  32182. + }
  32183. +
  32184. + for (i = 0; i < BOARD_INFO(boardId)->numBoardGppInfo; i++)
  32185. + if (BOARD_INFO(boardId)->pBoardGppInfo[i].devClass == class) {
  32186. + if (indexFound == index)
  32187. + return (MV_U32)BOARD_INFO(boardId)->pBoardGppInfo[i].gppPinNum;
  32188. + else
  32189. + indexFound++;
  32190. +
  32191. + }
  32192. +
  32193. + return MV_ERROR;
  32194. +}
  32195. +
  32196. +
  32197. +/*******************************************************************************
  32198. +* mvBoardRTCGpioPinGet - mvBoardRTCGpioPinGet
  32199. +*
  32200. +* DESCRIPTION:
  32201. +*
  32202. +* INPUT:
  32203. +* None.
  32204. +*
  32205. +* OUTPUT:
  32206. +* None.
  32207. +*
  32208. +* RETURN:
  32209. +* GPIO pin number. The function return -1 for bad parameters.
  32210. +*
  32211. +*******************************************************************************/
  32212. +MV_32 mvBoardRTCGpioPinGet(MV_VOID)
  32213. +{
  32214. + return mvBoarGpioPinNumGet(BOARD_GPP_RTC, 0);
  32215. +}
  32216. +
  32217. +
  32218. +/*******************************************************************************
  32219. +* mvBoardReset - mvBoardReset
  32220. +*
  32221. +* DESCRIPTION:
  32222. +* Reset the board
  32223. +* INPUT:
  32224. +* None.
  32225. +*
  32226. +* OUTPUT:
  32227. +* None.
  32228. +*
  32229. +* RETURN:
  32230. +* None
  32231. +*
  32232. +*******************************************************************************/
  32233. +MV_VOID mvBoardReset(MV_VOID)
  32234. +{
  32235. + MV_32 resetPin;
  32236. +
  32237. + /* Get gpp reset pin if define */
  32238. + resetPin = mvBoardResetGpioPinGet();
  32239. + if (resetPin != MV_ERROR)
  32240. + {
  32241. + MV_REG_BIT_RESET( GPP_DATA_OUT_REG(0) ,(1 << resetPin));
  32242. + MV_REG_BIT_RESET( GPP_DATA_OUT_EN_REG(0) ,(1 << resetPin));
  32243. +
  32244. + }
  32245. + else
  32246. + {
  32247. + /* No gpp reset pin was found, try to reset ussing
  32248. + system reset out */
  32249. + MV_REG_BIT_SET( CPU_RSTOUTN_MASK_REG , BIT2);
  32250. + MV_REG_BIT_SET( CPU_SYS_SOFT_RST_REG , BIT0);
  32251. + }
  32252. +}
  32253. +
  32254. +/*******************************************************************************
  32255. +* mvBoardResetGpioPinGet - mvBoardResetGpioPinGet
  32256. +*
  32257. +* DESCRIPTION:
  32258. +*
  32259. +* INPUT:
  32260. +* None.
  32261. +*
  32262. +* OUTPUT:
  32263. +* None.
  32264. +*
  32265. +* RETURN:
  32266. +* GPIO pin number. The function return -1 for bad parameters.
  32267. +*
  32268. +*******************************************************************************/
  32269. +MV_32 mvBoardResetGpioPinGet(MV_VOID)
  32270. +{
  32271. + return mvBoarGpioPinNumGet(BOARD_GPP_RESET, 0);
  32272. +}
  32273. +/*******************************************************************************
  32274. +* mvBoardSDIOGpioPinGet - mvBoardSDIOGpioPinGet
  32275. +*
  32276. +* DESCRIPTION:
  32277. +* used for hotswap detection
  32278. +* INPUT:
  32279. +* None.
  32280. +*
  32281. +* OUTPUT:
  32282. +* None.
  32283. +*
  32284. +* RETURN:
  32285. +* GPIO pin number. The function return -1 for bad parameters.
  32286. +*
  32287. +*******************************************************************************/
  32288. +MV_32 mvBoardSDIOGpioPinGet(MV_VOID)
  32289. +{
  32290. + return mvBoarGpioPinNumGet(BOARD_GPP_SDIO_DETECT, 0);
  32291. +}
  32292. +
  32293. +/*******************************************************************************
  32294. +* mvBoardUSBVbusGpioPinGet - return Vbus input GPP
  32295. +*
  32296. +* DESCRIPTION:
  32297. +*
  32298. +* INPUT:
  32299. +* int devNo.
  32300. +*
  32301. +* OUTPUT:
  32302. +* None.
  32303. +*
  32304. +* RETURN:
  32305. +* GPIO pin number. The function return -1 for bad parameters.
  32306. +*
  32307. +*******************************************************************************/
  32308. +MV_32 mvBoardUSBVbusGpioPinGet(MV_32 devId)
  32309. +{
  32310. + return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS, devId);
  32311. +}
  32312. +
  32313. +/*******************************************************************************
  32314. +* mvBoardUSBVbusEnGpioPinGet - return Vbus Enable output GPP
  32315. +*
  32316. +* DESCRIPTION:
  32317. +*
  32318. +* INPUT:
  32319. +* int devNo.
  32320. +*
  32321. +* OUTPUT:
  32322. +* None.
  32323. +*
  32324. +* RETURN:
  32325. +* GPIO pin number. The function return -1 for bad parameters.
  32326. +*
  32327. +*******************************************************************************/
  32328. +MV_32 mvBoardUSBVbusEnGpioPinGet(MV_32 devId)
  32329. +{
  32330. + return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS_EN, devId);
  32331. +}
  32332. +
  32333. +
  32334. +/*******************************************************************************
  32335. +* mvBoardGpioIntMaskGet - Get GPIO mask for interrupt pins
  32336. +*
  32337. +* DESCRIPTION:
  32338. +* This function returns a 32-bit mask of GPP pins that connected to
  32339. +* interrupt generating sources on board.
  32340. +* For example if UART channel A is hardwired to GPP pin 8 and
  32341. +* UART channel B is hardwired to GPP pin 4 the fuinction will return
  32342. +* the value 0x000000110
  32343. +*
  32344. +* INPUT:
  32345. +* None.
  32346. +*
  32347. +* OUTPUT:
  32348. +* None.
  32349. +*
  32350. +* RETURN:
  32351. +* See description. The function return -1 if board is not identified.
  32352. +*
  32353. +*******************************************************************************/
  32354. +MV_32 mvBoardGpioIntMaskLowGet(MV_VOID)
  32355. +{
  32356. + MV_U32 boardId;
  32357. +
  32358. + boardId = mvBoardIdGet();
  32359. +
  32360. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32361. + {
  32362. + mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");
  32363. + return MV_ERROR;
  32364. +
  32365. + }
  32366. +
  32367. + return BOARD_INFO(boardId)->intsGppMaskLow;
  32368. +}
  32369. +MV_32 mvBoardGpioIntMaskHighGet(MV_VOID)
  32370. +{
  32371. + MV_U32 boardId;
  32372. +
  32373. + boardId = mvBoardIdGet();
  32374. +
  32375. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32376. + {
  32377. + mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");
  32378. + return MV_ERROR;
  32379. +
  32380. + }
  32381. +
  32382. + return BOARD_INFO(boardId)->intsGppMaskHigh;
  32383. +}
  32384. +
  32385. +
  32386. +/*******************************************************************************
  32387. +* mvBoardMppGet - Get board dependent MPP register value
  32388. +*
  32389. +* DESCRIPTION:
  32390. +* MPP settings are derived from board design.
  32391. +* MPP group consist of 8 MPPs. An MPP group represent MPP
  32392. +* control register.
  32393. +* This function retrieves board dependend MPP register value.
  32394. +*
  32395. +* INPUT:
  32396. +* mppGroupNum - MPP group number.
  32397. +*
  32398. +* OUTPUT:
  32399. +* None.
  32400. +*
  32401. +* RETURN:
  32402. +* 32bit value describing MPP control register value.
  32403. +*
  32404. +*******************************************************************************/
  32405. +MV_32 mvBoardMppGet(MV_U32 mppGroupNum)
  32406. +{
  32407. + MV_U32 boardId;
  32408. +
  32409. + boardId = mvBoardIdGet();
  32410. +
  32411. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32412. + {
  32413. + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
  32414. + return MV_ERROR;
  32415. +
  32416. + }
  32417. +
  32418. + return BOARD_INFO(boardId)->pBoardMppConfigValue[0].mppGroup[mppGroupNum];
  32419. +}
  32420. +
  32421. +
  32422. +/*******************************************************************************
  32423. +* mvBoardMppGroupId - If MPP group type is AUTO then identify it using twsi
  32424. +*
  32425. +* DESCRIPTION:
  32426. +*
  32427. +* INPUT:
  32428. +*
  32429. +* OUTPUT:
  32430. +* None.
  32431. +*
  32432. +* RETURN:
  32433. +*
  32434. +*******************************************************************************/
  32435. +MV_VOID mvBoardMppGroupIdUpdate(MV_VOID)
  32436. +{
  32437. +
  32438. + MV_BOARD_MPP_GROUP_CLASS devClass;
  32439. + MV_BOARD_MODULE_ID_CLASS devClassId;
  32440. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  32441. + MV_U32 devId;
  32442. + MV_U32 maxMppGrp = 1;
  32443. +
  32444. + devId = mvCtrlModelGet();
  32445. +
  32446. + switch(devId){
  32447. + case MV_6281_DEV_ID:
  32448. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  32449. + break;
  32450. + case MV_6192_DEV_ID:
  32451. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  32452. + break;
  32453. + case MV_6190_DEV_ID:
  32454. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  32455. + break;
  32456. + case MV_6180_DEV_ID:
  32457. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  32458. + break;
  32459. + }
  32460. +
  32461. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  32462. + {
  32463. + /* If MPP group can be defined by the module connected to it */
  32464. + if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)
  32465. + {
  32466. + /* Get MPP module ID */
  32467. + devClassId = mvBoarModuleTypeGet(devClass);
  32468. + if (MV_ERROR != devClassId)
  32469. + {
  32470. + switch(devClassId)
  32471. + {
  32472. + case MV_BOARD_MODULE_TDM_ID:
  32473. + case MV_BOARD_MODULE_TDM_5CHAN_ID:
  32474. + mppGroupType = MV_BOARD_TDM;
  32475. + break;
  32476. + case MV_BOARD_MODULE_AUDIO_ID:
  32477. + mppGroupType = MV_BOARD_AUDIO;
  32478. + break;
  32479. + case MV_BOARD_MODULE_RGMII_ID:
  32480. + mppGroupType = MV_BOARD_RGMII;
  32481. + break;
  32482. + case MV_BOARD_MODULE_GMII_ID:
  32483. + mppGroupType = MV_BOARD_GMII;
  32484. + break;
  32485. + case MV_BOARD_MODULE_TS_ID:
  32486. + mppGroupType = MV_BOARD_TS;
  32487. + break;
  32488. + case MV_BOARD_MODULE_MII_ID:
  32489. + mppGroupType = MV_BOARD_MII;
  32490. + break;
  32491. + default:
  32492. + mppGroupType = MV_BOARD_OTHER;
  32493. + break;
  32494. + }
  32495. + }
  32496. + else
  32497. + /* The module bay is empty */
  32498. + mppGroupType = MV_BOARD_OTHER;
  32499. +
  32500. + /* Update MPP group type */
  32501. + mvBoardMppGroupTypeSet(devClass, mppGroupType);
  32502. + }
  32503. +
  32504. + /* Update MPP output voltage for RGMII 1.8V. Set port to GMII for GMII module */
  32505. + if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_RGMII))
  32506. + MV_REG_BIT_SET(MPP_OUTPUT_DRIVE_REG,MPP_1_8_RGMII1_OUTPUT_DRIVE | MPP_1_8_RGMII0_OUTPUT_DRIVE);
  32507. + else
  32508. + {
  32509. + if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII))
  32510. + {
  32511. + MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);
  32512. + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(0),BIT3);
  32513. + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);
  32514. + }
  32515. + else if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_MII))
  32516. + {
  32517. + /* Assumption that the MDC & MDIO should be 3.3V */
  32518. + MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);
  32519. + /* Assumption that only ETH1 can be MII when using modules on DB */
  32520. + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);
  32521. + }
  32522. + }
  32523. + }
  32524. +}
  32525. +
  32526. +/*******************************************************************************
  32527. +* mvBoardMppGroupTypeGet
  32528. +*
  32529. +* DESCRIPTION:
  32530. +*
  32531. +* INPUT:
  32532. +* mppGroupClass - MPP group number 0 for MPP[35:20] or 1 for MPP[49:36].
  32533. +*
  32534. +* OUTPUT:
  32535. +* None.
  32536. +*
  32537. +* RETURN:
  32538. +*
  32539. +*******************************************************************************/
  32540. +MV_BOARD_MPP_TYPE_CLASS mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass)
  32541. +{
  32542. + MV_U32 boardId;
  32543. +
  32544. + boardId = mvBoardIdGet();
  32545. +
  32546. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32547. + {
  32548. + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
  32549. + return MV_ERROR;
  32550. +
  32551. + }
  32552. +
  32553. + if (mppGroupClass == MV_BOARD_MPP_GROUP_1)
  32554. + return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1;
  32555. + else
  32556. + return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2;
  32557. +}
  32558. +
  32559. +/*******************************************************************************
  32560. +* mvBoardMppGroupTypeSet
  32561. +*
  32562. +* DESCRIPTION:
  32563. +*
  32564. +* INPUT:
  32565. +* mppGroupClass - MPP group number 0 for MPP[35:20] or 1 for MPP[49:36].
  32566. +* mppGroupType - MPP group type for MPP[35:20] or for MPP[49:36].
  32567. +*
  32568. +* OUTPUT:
  32569. +* None.
  32570. +*
  32571. +* RETURN:
  32572. +*
  32573. +*******************************************************************************/
  32574. +MV_VOID mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,
  32575. + MV_BOARD_MPP_TYPE_CLASS mppGroupType)
  32576. +{
  32577. + MV_U32 boardId;
  32578. +
  32579. + boardId = mvBoardIdGet();
  32580. +
  32581. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32582. + {
  32583. + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
  32584. + }
  32585. +
  32586. + if (mppGroupClass == MV_BOARD_MPP_GROUP_1)
  32587. + BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1 = mppGroupType;
  32588. + else
  32589. + BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2 = mppGroupType;
  32590. +
  32591. +}
  32592. +
  32593. +/*******************************************************************************
  32594. +* mvBoardMppMuxSet - Update MPP mux
  32595. +*
  32596. +* DESCRIPTION:
  32597. +*
  32598. +* INPUT:
  32599. +*
  32600. +* OUTPUT:
  32601. +* None.
  32602. +*
  32603. +* RETURN:
  32604. +*
  32605. +*******************************************************************************/
  32606. +MV_VOID mvBoardMppMuxSet(MV_VOID)
  32607. +{
  32608. +
  32609. + MV_BOARD_MPP_GROUP_CLASS devClass;
  32610. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  32611. + MV_U32 devId;
  32612. + MV_U8 muxVal = 0xf;
  32613. + MV_U32 maxMppGrp = 1;
  32614. + MV_TWSI_SLAVE twsiSlave;
  32615. + MV_TWSI_ADDR slave;
  32616. +
  32617. + devId = mvCtrlModelGet();
  32618. +
  32619. + switch(devId){
  32620. + case MV_6281_DEV_ID:
  32621. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  32622. + break;
  32623. + case MV_6192_DEV_ID:
  32624. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  32625. + break;
  32626. + case MV_6190_DEV_ID:
  32627. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  32628. + break;
  32629. + case MV_6180_DEV_ID:
  32630. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  32631. + break;
  32632. + }
  32633. +
  32634. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  32635. + {
  32636. + mppGroupType = mvBoardMppGroupTypeGet(devClass);
  32637. +
  32638. + switch(mppGroupType)
  32639. + {
  32640. + case MV_BOARD_TDM:
  32641. + muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);
  32642. + break;
  32643. + case MV_BOARD_AUDIO:
  32644. + muxVal &= ~(devClass ? 0x7 : 0x0); /*old Z0 value 0xd:0x0*/
  32645. + break;
  32646. + case MV_BOARD_TS:
  32647. + muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);
  32648. + break;
  32649. + default:
  32650. + muxVal |= (devClass ? 0xf : 0);
  32651. + break;
  32652. + }
  32653. + }
  32654. +
  32655. + /* TWSI init */
  32656. + slave.type = ADDR7_BIT;
  32657. + slave.address = 0;
  32658. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  32659. +
  32660. + /* Read MPP module ID */
  32661. + DB(mvOsPrintf("Board: twsi exp set\n"));
  32662. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);
  32663. + twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);
  32664. + twsiSlave.validOffset = MV_TRUE;
  32665. + /* Offset is the first command after the address which indicate the register number to be read
  32666. + in next operation */
  32667. + twsiSlave.offset = 2;
  32668. + twsiSlave.moreThen256 = MV_FALSE;
  32669. +
  32670. +
  32671. +
  32672. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32673. + {
  32674. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  32675. + return;
  32676. + }
  32677. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  32678. +
  32679. + /* Change twsi exp to output */
  32680. + twsiSlave.offset = 6;
  32681. + muxVal = 0;
  32682. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32683. + {
  32684. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  32685. + return;
  32686. + }
  32687. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  32688. +
  32689. +}
  32690. +
  32691. +/*******************************************************************************
  32692. +* mvBoardTdmMppSet - set MPPs in TDM module
  32693. +*
  32694. +* DESCRIPTION:
  32695. +*
  32696. +* INPUT: type of second telephony device
  32697. +*
  32698. +* OUTPUT:
  32699. +* None.
  32700. +*
  32701. +* RETURN:
  32702. +*
  32703. +*******************************************************************************/
  32704. +MV_VOID mvBoardTdmMppSet(MV_32 chType)
  32705. +{
  32706. +
  32707. + MV_BOARD_MPP_GROUP_CLASS devClass;
  32708. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  32709. + MV_U32 devId;
  32710. + MV_U8 muxVal = 1;
  32711. + MV_U8 muxValMask = 1;
  32712. + MV_U8 twsiVal;
  32713. + MV_U32 maxMppGrp = 1;
  32714. + MV_TWSI_SLAVE twsiSlave;
  32715. + MV_TWSI_ADDR slave;
  32716. +
  32717. + devId = mvCtrlModelGet();
  32718. +
  32719. + switch(devId){
  32720. + case MV_6281_DEV_ID:
  32721. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  32722. + break;
  32723. + case MV_6192_DEV_ID:
  32724. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  32725. + break;
  32726. + case MV_6190_DEV_ID:
  32727. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  32728. + break;
  32729. + case MV_6180_DEV_ID:
  32730. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  32731. + break;
  32732. + }
  32733. +
  32734. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  32735. + {
  32736. + mppGroupType = mvBoardMppGroupTypeGet(devClass);
  32737. + if(mppGroupType == MV_BOARD_TDM)
  32738. + break;
  32739. + }
  32740. +
  32741. + if(devClass == maxMppGrp)
  32742. + return; /* TDM module not found */
  32743. +
  32744. + /* TWSI init */
  32745. + slave.type = ADDR7_BIT;
  32746. + slave.address = 0;
  32747. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  32748. +
  32749. + /* Read MPP module ID */
  32750. + DB(mvOsPrintf("Board: twsi exp set\n"));
  32751. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);
  32752. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  32753. + twsiSlave.validOffset = MV_TRUE;
  32754. + /* Offset is the first command after the address which indicate the register number to be read
  32755. + in next operation */
  32756. + twsiSlave.offset = 3;
  32757. + twsiSlave.moreThen256 = MV_FALSE;
  32758. +
  32759. + if(mvBoardIdGet() == RD_88F6281A_ID)
  32760. + {
  32761. + muxVal = 0xc;
  32762. + muxValMask = 0xf3;
  32763. + }
  32764. +
  32765. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  32766. + muxVal = (twsiVal & muxValMask) | muxVal;
  32767. +
  32768. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32769. + {
  32770. + mvOsPrintf("Board: twsi exp out val fail\n");
  32771. + return;
  32772. + }
  32773. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  32774. +
  32775. + /* Change twsi exp to output */
  32776. + twsiSlave.offset = 7;
  32777. + muxVal = 0xfe;
  32778. + if(mvBoardIdGet() == RD_88F6281A_ID)
  32779. + muxVal = 0xf3;
  32780. +
  32781. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  32782. + muxVal = (twsiVal & muxVal);
  32783. +
  32784. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32785. + {
  32786. + mvOsPrintf("Board: twsi exp change to out fail\n");
  32787. + return;
  32788. + }
  32789. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  32790. + /* reset the line to 0 */
  32791. + twsiSlave.offset = 3;
  32792. + muxVal = 0;
  32793. + muxValMask = 1;
  32794. +
  32795. + if(mvBoardIdGet() == RD_88F6281A_ID) {
  32796. + muxVal = 0x0;
  32797. + muxValMask = 0xf3;
  32798. + }
  32799. +
  32800. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  32801. + muxVal = (twsiVal & muxValMask) | muxVal;
  32802. +
  32803. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32804. + {
  32805. + mvOsPrintf("Board: twsi exp out val fail\n");
  32806. + return;
  32807. + }
  32808. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  32809. +
  32810. + mvOsDelay(20);
  32811. +
  32812. + /* set the line to 1 */
  32813. + twsiSlave.offset = 3;
  32814. + muxVal = 1;
  32815. + muxValMask = 1;
  32816. +
  32817. + if(mvBoardIdGet() == RD_88F6281A_ID)
  32818. + {
  32819. + muxVal = 0xc;
  32820. + muxValMask = 0xf3;
  32821. + if(chType) /* FXS - issue reset properly */
  32822. + {
  32823. + MV_REG_BIT_SET(GPP_DATA_OUT_REG(1), MV_GPP12);
  32824. + mvOsDelay(50);
  32825. + MV_REG_BIT_RESET(GPP_DATA_OUT_REG(1), MV_GPP12);
  32826. + }
  32827. + else /* FXO - issue reset via TDM_CODEC_RST*/
  32828. + {
  32829. + /* change MPP44 type to TDM_CODEC_RST(0x2) */
  32830. + MV_REG_WRITE(MPP_CONTROL_REG5, ((MV_REG_READ(MPP_CONTROL_REG5) & 0xFFF0FFFF) | BIT17));
  32831. + }
  32832. + }
  32833. +
  32834. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  32835. + muxVal = (twsiVal & muxValMask) | muxVal;
  32836. +
  32837. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32838. + {
  32839. + mvOsPrintf("Board: twsi exp out val fail\n");
  32840. + return;
  32841. + }
  32842. +
  32843. + /* TBD - 5 channels */
  32844. +#if defined(MV_TDM_5CHANNELS)
  32845. + /* change MPP38 type to GPIO(0x0) & polarity for TDM_STROBE */
  32846. + MV_REG_WRITE(MPP_CONTROL_REG4, (MV_REG_READ(MPP_CONTROL_REG4) & 0xF0FFFFFF));
  32847. + mvGppPolaritySet(1, MV_GPP6, 0);
  32848. +
  32849. + twsiSlave.offset = 6;
  32850. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(2);
  32851. +
  32852. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  32853. + muxVal = (twsiVal & ~BIT2);
  32854. +
  32855. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32856. + {
  32857. + mvOsPrintf("Board: twsi exp change to out fail\n");
  32858. + return;
  32859. + }
  32860. +
  32861. +
  32862. + twsiSlave.offset = 2;
  32863. +
  32864. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  32865. + muxVal = (twsiVal & ~BIT2);
  32866. +
  32867. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32868. + {
  32869. + mvOsPrintf("Board: twsi exp change to out fail\n");
  32870. + return;
  32871. + }
  32872. +#endif
  32873. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  32874. +
  32875. +
  32876. +}
  32877. +/*******************************************************************************
  32878. +* mvBoardVoiceConnModeGet - return SLIC/DAA connection & interrupt modes
  32879. +*
  32880. +* DESCRIPTION:
  32881. +*
  32882. +* INPUT:
  32883. +*
  32884. +* OUTPUT:
  32885. +* None.
  32886. +*
  32887. +* RETURN:
  32888. +*
  32889. +*******************************************************************************/
  32890. +
  32891. +MV_VOID mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode)
  32892. +{
  32893. + switch(mvBoardIdGet())
  32894. + {
  32895. + case RD_88F6281A_ID:
  32896. + *connMode = DAISY_CHAIN_MODE;
  32897. + *irqMode = INTERRUPT_TO_TDM;
  32898. + break;
  32899. + case DB_88F6281A_BP_ID:
  32900. + *connMode = DUAL_CHIP_SELECT_MODE;
  32901. + *irqMode = INTERRUPT_TO_TDM;
  32902. + break;
  32903. + case RD_88F6192A_ID:
  32904. + *connMode = DUAL_CHIP_SELECT_MODE;
  32905. + *irqMode = INTERRUPT_TO_TDM;
  32906. + break;
  32907. + case DB_88F6192A_BP_ID:
  32908. + *connMode = DUAL_CHIP_SELECT_MODE;
  32909. + *irqMode = INTERRUPT_TO_TDM;
  32910. + break;
  32911. + default:
  32912. + *connMode = *irqMode = -1;
  32913. + mvOsPrintf("mvBoardVoiceAssembleModeGet: TDM not supported(boardId=0x%x)\n",mvBoardIdGet());
  32914. + }
  32915. + return;
  32916. +
  32917. +}
  32918. +
  32919. +/*******************************************************************************
  32920. +* mvBoardMppModuleTypePrint - print module detect
  32921. +*
  32922. +* DESCRIPTION:
  32923. +*
  32924. +* INPUT:
  32925. +*
  32926. +* OUTPUT:
  32927. +* None.
  32928. +*
  32929. +* RETURN:
  32930. +*
  32931. +*******************************************************************************/
  32932. +MV_VOID mvBoardMppModuleTypePrint(MV_VOID)
  32933. +{
  32934. +
  32935. + MV_BOARD_MPP_GROUP_CLASS devClass;
  32936. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  32937. + MV_U32 devId;
  32938. + MV_U32 maxMppGrp = 1;
  32939. +
  32940. + devId = mvCtrlModelGet();
  32941. +
  32942. + switch(devId){
  32943. + case MV_6281_DEV_ID:
  32944. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  32945. + break;
  32946. + case MV_6192_DEV_ID:
  32947. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  32948. + break;
  32949. + case MV_6190_DEV_ID:
  32950. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  32951. + break;
  32952. + case MV_6180_DEV_ID:
  32953. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  32954. + break;
  32955. + }
  32956. +
  32957. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  32958. + {
  32959. + mppGroupType = mvBoardMppGroupTypeGet(devClass);
  32960. +
  32961. + switch(mppGroupType)
  32962. + {
  32963. + case MV_BOARD_TDM:
  32964. + if(devId != MV_6190_DEV_ID)
  32965. + mvOsPrintf("Module %d is TDM\n", devClass);
  32966. + break;
  32967. + case MV_BOARD_AUDIO:
  32968. + if(devId != MV_6190_DEV_ID)
  32969. + mvOsPrintf("Module %d is AUDIO\n", devClass);
  32970. + break;
  32971. + case MV_BOARD_RGMII:
  32972. + if(devId != MV_6190_DEV_ID)
  32973. + mvOsPrintf("Module %d is RGMII\n", devClass);
  32974. + break;
  32975. + case MV_BOARD_GMII:
  32976. + if(devId != MV_6190_DEV_ID)
  32977. + mvOsPrintf("Module %d is GMII\n", devClass);
  32978. + break;
  32979. + case MV_BOARD_TS:
  32980. + if(devId != MV_6190_DEV_ID)
  32981. + mvOsPrintf("Module %d is TS\n", devClass);
  32982. + break;
  32983. + default:
  32984. + break;
  32985. + }
  32986. + }
  32987. +}
  32988. +
  32989. +/* Board devices API managments */
  32990. +
  32991. +/*******************************************************************************
  32992. +* mvBoardGetDeviceNumber - Get number of device of some type on the board
  32993. +*
  32994. +* DESCRIPTION:
  32995. +*
  32996. +* INPUT:
  32997. +* devType - The device type ( Flash,RTC , etc .. )
  32998. +*
  32999. +* OUTPUT:
  33000. +* None.
  33001. +*
  33002. +* RETURN:
  33003. +* If the device is found on the board the then the functions returns the
  33004. +* number of those devices else the function returns 0
  33005. +*
  33006. +*
  33007. +*******************************************************************************/
  33008. +MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass)
  33009. +{
  33010. + MV_U32 foundIndex=0,devNum;
  33011. + MV_U32 boardId= mvBoardIdGet();
  33012. +
  33013. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33014. + {
  33015. + mvOsPrintf("mvBoardGetDeviceNumber:Board unknown.\n");
  33016. + return 0xFFFFFFFF;
  33017. +
  33018. + }
  33019. +
  33020. + for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)
  33021. + {
  33022. + if (BOARD_INFO(boardId)->pDevCsInfo[devNum].devClass == devClass)
  33023. + {
  33024. + foundIndex++;
  33025. + }
  33026. + }
  33027. +
  33028. + return foundIndex;
  33029. +
  33030. +}
  33031. +
  33032. +/*******************************************************************************
  33033. +* mvBoardGetDeviceBaseAddr - Get base address of a device existing on the board
  33034. +*
  33035. +* DESCRIPTION:
  33036. +*
  33037. +* INPUT:
  33038. +* devIndex - The device sequential number on the board
  33039. +* devType - The device type ( Flash,RTC , etc .. )
  33040. +*
  33041. +* OUTPUT:
  33042. +* None.
  33043. +*
  33044. +* RETURN:
  33045. +* If the device is found on the board the then the functions returns the
  33046. +* Base address else the function returns 0xffffffff
  33047. +*
  33048. +*
  33049. +*******************************************************************************/
  33050. +MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  33051. +{
  33052. + MV_DEV_CS_INFO* devEntry;
  33053. + devEntry = boardGetDevEntry(devNum,devClass);
  33054. + if (devEntry != NULL)
  33055. + {
  33056. + return mvCpuIfTargetWinBaseLowGet(DEV_TO_TARGET(devEntry->deviceCS));
  33057. +
  33058. + }
  33059. +
  33060. + return 0xFFFFFFFF;
  33061. +}
  33062. +
  33063. +/*******************************************************************************
  33064. +* mvBoardGetDeviceBusWidth - Get Bus width of a device existing on the board
  33065. +*
  33066. +* DESCRIPTION:
  33067. +*
  33068. +* INPUT:
  33069. +* devIndex - The device sequential number on the board
  33070. +* devType - The device type ( Flash,RTC , etc .. )
  33071. +*
  33072. +* OUTPUT:
  33073. +* None.
  33074. +*
  33075. +* RETURN:
  33076. +* If the device is found on the board the then the functions returns the
  33077. +* Bus width else the function returns 0xffffffff
  33078. +*
  33079. +*
  33080. +*******************************************************************************/
  33081. +MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  33082. +{
  33083. + MV_DEV_CS_INFO* devEntry;
  33084. +
  33085. + devEntry = boardGetDevEntry(devNum,devClass);
  33086. + if (devEntry != NULL)
  33087. + {
  33088. + return 8;
  33089. + }
  33090. +
  33091. + return 0xFFFFFFFF;
  33092. +
  33093. +}
  33094. +
  33095. +/*******************************************************************************
  33096. +* mvBoardGetDeviceWidth - Get dev width of a device existing on the board
  33097. +*
  33098. +* DESCRIPTION:
  33099. +*
  33100. +* INPUT:
  33101. +* devIndex - The device sequential number on the board
  33102. +* devType - The device type ( Flash,RTC , etc .. )
  33103. +*
  33104. +* OUTPUT:
  33105. +* None.
  33106. +*
  33107. +* RETURN:
  33108. +* If the device is found on the board the then the functions returns the
  33109. +* dev width else the function returns 0xffffffff
  33110. +*
  33111. +*
  33112. +*******************************************************************************/
  33113. +MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  33114. +{
  33115. + MV_DEV_CS_INFO* devEntry;
  33116. + MV_U32 boardId= mvBoardIdGet();
  33117. +
  33118. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33119. + {
  33120. + mvOsPrintf("Board unknown.\n");
  33121. + return 0xFFFFFFFF;
  33122. + }
  33123. +
  33124. + devEntry = boardGetDevEntry(devNum,devClass);
  33125. + if (devEntry != NULL)
  33126. + return devEntry->devWidth;
  33127. +
  33128. + return MV_ERROR;
  33129. +
  33130. +}
  33131. +
  33132. +/*******************************************************************************
  33133. +* mvBoardGetDeviceWinSize - Get the window size of a device existing on the board
  33134. +*
  33135. +* DESCRIPTION:
  33136. +*
  33137. +* INPUT:
  33138. +* devIndex - The device sequential number on the board
  33139. +* devType - The device type ( Flash,RTC , etc .. )
  33140. +*
  33141. +* OUTPUT:
  33142. +* None.
  33143. +*
  33144. +* RETURN:
  33145. +* If the device is found on the board the then the functions returns the
  33146. +* window size else the function returns 0xffffffff
  33147. +*
  33148. +*
  33149. +*******************************************************************************/
  33150. +MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  33151. +{
  33152. + MV_DEV_CS_INFO* devEntry;
  33153. + MV_U32 boardId = mvBoardIdGet();
  33154. +
  33155. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33156. + {
  33157. + mvOsPrintf("Board unknown.\n");
  33158. + return 0xFFFFFFFF;
  33159. + }
  33160. +
  33161. + devEntry = boardGetDevEntry(devNum,devClass);
  33162. + if (devEntry != NULL)
  33163. + {
  33164. + return mvCpuIfTargetWinSizeGet(DEV_TO_TARGET(devEntry->deviceCS));
  33165. + }
  33166. +
  33167. + return 0xFFFFFFFF;
  33168. +}
  33169. +
  33170. +
  33171. +/*******************************************************************************
  33172. +* boardGetDevEntry - returns the entry pointer of a device on the board
  33173. +*
  33174. +* DESCRIPTION:
  33175. +*
  33176. +* INPUT:
  33177. +* devIndex - The device sequential number on the board
  33178. +* devType - The device type ( Flash,RTC , etc .. )
  33179. +*
  33180. +* OUTPUT:
  33181. +* None.
  33182. +*
  33183. +* RETURN:
  33184. +* If the device is found on the board the then the functions returns the
  33185. +* dev number else the function returns 0x0
  33186. +*
  33187. +*
  33188. +*******************************************************************************/
  33189. +static MV_DEV_CS_INFO* boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  33190. +{
  33191. + MV_U32 foundIndex=0,devIndex;
  33192. + MV_U32 boardId= mvBoardIdGet();
  33193. +
  33194. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33195. + {
  33196. + mvOsPrintf("boardGetDevEntry: Board unknown.\n");
  33197. + return NULL;
  33198. +
  33199. + }
  33200. +
  33201. + for (devIndex = START_DEV_CS; devIndex < BOARD_INFO(boardId)->numBoardDeviceIf; devIndex++)
  33202. + {
  33203. + /* TBR */
  33204. + /*if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].deviceCS == MV_BOOTDEVICE_INDEX)
  33205. + continue;*/
  33206. +
  33207. + if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].devClass == devClass)
  33208. + {
  33209. + if (foundIndex == devNum)
  33210. + {
  33211. + return &(BOARD_INFO(boardId)->pDevCsInfo[devIndex]);
  33212. + }
  33213. + foundIndex++;
  33214. + }
  33215. + }
  33216. +
  33217. + /* device not found */
  33218. + return NULL;
  33219. +}
  33220. +
  33221. +/* Get device CS number */
  33222. +
  33223. +MV_U32 boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  33224. +{
  33225. + MV_DEV_CS_INFO* devEntry;
  33226. + MV_U32 boardId= mvBoardIdGet();
  33227. +
  33228. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33229. + {
  33230. + mvOsPrintf("Board unknown.\n");
  33231. + return 0xFFFFFFFF;
  33232. +
  33233. + }
  33234. +
  33235. +
  33236. + devEntry = boardGetDevEntry(devNum,devClass);
  33237. + if (devEntry != NULL)
  33238. + return devEntry->deviceCS;
  33239. +
  33240. + return 0xFFFFFFFF;
  33241. +
  33242. +}
  33243. +
  33244. +/*******************************************************************************
  33245. +* mvBoardRtcTwsiAddrTypeGet -
  33246. +*
  33247. +* DESCRIPTION:
  33248. +*
  33249. +* INPUT:
  33250. +*
  33251. +* OUTPUT:
  33252. +* None.
  33253. +*
  33254. +* RETURN:
  33255. +*
  33256. +*
  33257. +*******************************************************************************/
  33258. +MV_U8 mvBoardRtcTwsiAddrTypeGet()
  33259. +{
  33260. + int i;
  33261. + MV_U32 boardId= mvBoardIdGet();
  33262. +
  33263. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33264. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)
  33265. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  33266. + return (MV_ERROR);
  33267. +}
  33268. +
  33269. +/*******************************************************************************
  33270. +* mvBoardRtcTwsiAddrGet -
  33271. +*
  33272. +* DESCRIPTION:
  33273. +*
  33274. +* INPUT:
  33275. +*
  33276. +* OUTPUT:
  33277. +* None.
  33278. +*
  33279. +* RETURN:
  33280. +*
  33281. +*
  33282. +*******************************************************************************/
  33283. +MV_U8 mvBoardRtcTwsiAddrGet()
  33284. +{
  33285. + int i;
  33286. + MV_U32 boardId= mvBoardIdGet();
  33287. +
  33288. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33289. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)
  33290. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  33291. + return (0xFF);
  33292. +}
  33293. +
  33294. +/*******************************************************************************
  33295. +* mvBoardA2DTwsiAddrTypeGet -
  33296. +*
  33297. +* DESCRIPTION:
  33298. +*
  33299. +* INPUT:
  33300. +*
  33301. +* OUTPUT:
  33302. +* None.
  33303. +*
  33304. +* RETURN:
  33305. +*
  33306. +*
  33307. +*******************************************************************************/
  33308. +MV_U8 mvBoardA2DTwsiAddrTypeGet()
  33309. +{
  33310. + int i;
  33311. + MV_U32 boardId= mvBoardIdGet();
  33312. +
  33313. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33314. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)
  33315. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  33316. + return (MV_ERROR);
  33317. +}
  33318. +
  33319. +/*******************************************************************************
  33320. +* mvBoardA2DTwsiAddrGet -
  33321. +*
  33322. +* DESCRIPTION:
  33323. +*
  33324. +* INPUT:
  33325. +*
  33326. +* OUTPUT:
  33327. +* None.
  33328. +*
  33329. +* RETURN:
  33330. +*
  33331. +*
  33332. +*******************************************************************************/
  33333. +MV_U8 mvBoardA2DTwsiAddrGet()
  33334. +{
  33335. + int i;
  33336. + MV_U32 boardId= mvBoardIdGet();
  33337. +
  33338. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33339. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)
  33340. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  33341. + return (0xFF);
  33342. +}
  33343. +
  33344. +/*******************************************************************************
  33345. +* mvBoardTwsiExpAddrTypeGet -
  33346. +*
  33347. +* DESCRIPTION:
  33348. +*
  33349. +* INPUT:
  33350. +*
  33351. +* OUTPUT:
  33352. +* None.
  33353. +*
  33354. +* RETURN:
  33355. +*
  33356. +*
  33357. +*******************************************************************************/
  33358. +MV_U8 mvBoardTwsiExpAddrTypeGet(MV_U32 index)
  33359. +{
  33360. + int i;
  33361. + MV_U32 indexFound = 0;
  33362. + MV_U32 boardId= mvBoardIdGet();
  33363. +
  33364. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33365. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)
  33366. + {
  33367. + if (indexFound == index)
  33368. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  33369. + else
  33370. + indexFound++;
  33371. + }
  33372. +
  33373. + return (MV_ERROR);
  33374. +}
  33375. +
  33376. +/*******************************************************************************
  33377. +* mvBoardTwsiExpAddrGet -
  33378. +*
  33379. +* DESCRIPTION:
  33380. +*
  33381. +* INPUT:
  33382. +*
  33383. +* OUTPUT:
  33384. +* None.
  33385. +*
  33386. +* RETURN:
  33387. +*
  33388. +*
  33389. +*******************************************************************************/
  33390. +MV_U8 mvBoardTwsiExpAddrGet(MV_U32 index)
  33391. +{
  33392. + int i;
  33393. + MV_U32 indexFound = 0;
  33394. + MV_U32 boardId= mvBoardIdGet();
  33395. +
  33396. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33397. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)
  33398. + {
  33399. + if (indexFound == index)
  33400. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  33401. + else
  33402. + indexFound++;
  33403. + }
  33404. +
  33405. + return (0xFF);
  33406. +}
  33407. +
  33408. +
  33409. +/*******************************************************************************
  33410. +* mvBoardTwsiSatRAddrTypeGet -
  33411. +*
  33412. +* DESCRIPTION:
  33413. +*
  33414. +* INPUT:
  33415. +*
  33416. +* OUTPUT:
  33417. +* None.
  33418. +*
  33419. +* RETURN:
  33420. +*
  33421. +*
  33422. +*******************************************************************************/
  33423. +MV_U8 mvBoardTwsiSatRAddrTypeGet(MV_U32 index)
  33424. +{
  33425. + int i;
  33426. + MV_U32 indexFound = 0;
  33427. + MV_U32 boardId= mvBoardIdGet();
  33428. +
  33429. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33430. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)
  33431. + {
  33432. + if (indexFound == index)
  33433. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  33434. + else
  33435. + indexFound++;
  33436. + }
  33437. +
  33438. + return (MV_ERROR);
  33439. +}
  33440. +
  33441. +/*******************************************************************************
  33442. +* mvBoardTwsiSatRAddrGet -
  33443. +*
  33444. +* DESCRIPTION:
  33445. +*
  33446. +* INPUT:
  33447. +*
  33448. +* OUTPUT:
  33449. +* None.
  33450. +*
  33451. +* RETURN:
  33452. +*
  33453. +*
  33454. +*******************************************************************************/
  33455. +MV_U8 mvBoardTwsiSatRAddrGet(MV_U32 index)
  33456. +{
  33457. + int i;
  33458. + MV_U32 indexFound = 0;
  33459. + MV_U32 boardId= mvBoardIdGet();
  33460. +
  33461. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33462. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)
  33463. + {
  33464. + if (indexFound == index)
  33465. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  33466. + else
  33467. + indexFound++;
  33468. + }
  33469. +
  33470. + return (0xFF);
  33471. +}
  33472. +
  33473. +/*******************************************************************************
  33474. +* mvBoardNandWidthGet -
  33475. +*
  33476. +* DESCRIPTION: Get the width of the first NAND device in byte.
  33477. +*
  33478. +* INPUT:
  33479. +*
  33480. +* OUTPUT:
  33481. +* None.
  33482. +*
  33483. +* RETURN: 1, 2, 4 or MV_ERROR
  33484. +*
  33485. +*
  33486. +*******************************************************************************/
  33487. +/* */
  33488. +MV_32 mvBoardNandWidthGet(void)
  33489. +{
  33490. + MV_U32 devNum;
  33491. + MV_U32 devWidth;
  33492. + MV_U32 boardId= mvBoardIdGet();
  33493. +
  33494. + for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)
  33495. + {
  33496. + devWidth = mvBoardGetDeviceWidth(devNum, BOARD_DEV_NAND_FLASH);
  33497. + if (devWidth != MV_ERROR)
  33498. + return (devWidth / 8);
  33499. + }
  33500. +
  33501. + /* NAND wasn't found */
  33502. + return MV_ERROR;
  33503. +}
  33504. +
  33505. +MV_U32 gBoardId = -1;
  33506. +
  33507. +/*******************************************************************************
  33508. +* mvBoardIdGet - Get Board model
  33509. +*
  33510. +* DESCRIPTION:
  33511. +* This function returns board ID.
  33512. +* Board ID is 32bit word constructed of board model (16bit) and
  33513. +* board revision (16bit) in the following way: 0xMMMMRRRR.
  33514. +*
  33515. +* INPUT:
  33516. +* None.
  33517. +*
  33518. +* OUTPUT:
  33519. +* None.
  33520. +*
  33521. +* RETURN:
  33522. +* 32bit board ID number, '-1' if board is undefined.
  33523. +*
  33524. +*******************************************************************************/
  33525. +MV_U32 mvBoardIdGet(MV_VOID)
  33526. +{
  33527. + MV_U32 tmpBoardId = -1;
  33528. +
  33529. + if(gBoardId == -1)
  33530. + {
  33531. + #if defined(DB_88F6281A)
  33532. + tmpBoardId = DB_88F6281A_BP_ID;
  33533. + #elif defined(RD_88F6281A)
  33534. + tmpBoardId = RD_88F6281A_ID;
  33535. + #elif defined(DB_88F6192A)
  33536. + tmpBoardId = DB_88F6192A_BP_ID;
  33537. + #elif defined(DB_88F6190A)
  33538. + tmpBoardId = DB_88F6190A_BP_ID;
  33539. + #elif defined(RD_88F6192A)
  33540. + tmpBoardId = RD_88F6192A_ID;
  33541. + #elif defined(RD_88F6190A)
  33542. + tmpBoardId = RD_88F6190A_ID;
  33543. + #elif defined(DB_88F6180A)
  33544. + tmpBoardId = DB_88F6180A_BP_ID;
  33545. + #elif defined(RD_88F6281A_PCAC)
  33546. + tmpBoardId = RD_88F6281A_PCAC_ID;
  33547. + #elif defined(RD_88F6281A_SHEEVA_PLUG)
  33548. + tmpBoardId = SHEEVA_PLUG_ID;
  33549. + #elif defined(DB_CUSTOMER)
  33550. + tmpBoardId = DB_CUSTOMER_ID;
  33551. + #endif
  33552. + gBoardId = tmpBoardId;
  33553. + }
  33554. +
  33555. + return gBoardId;
  33556. +}
  33557. +
  33558. +
  33559. +/*******************************************************************************
  33560. +* mvBoarModuleTypeGet - mvBoarModuleTypeGet
  33561. +*
  33562. +* DESCRIPTION:
  33563. +*
  33564. +* INPUT:
  33565. +* group num - MV_BOARD_MPP_GROUP_CLASS enum
  33566. +*
  33567. +* OUTPUT:
  33568. +* None.
  33569. +*
  33570. +* RETURN:
  33571. +* module num - MV_BOARD_MODULE_CLASS enum
  33572. +*
  33573. +*******************************************************************************/
  33574. +MV_BOARD_MODULE_ID_CLASS mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass)
  33575. +{
  33576. + MV_TWSI_SLAVE twsiSlave;
  33577. + MV_TWSI_ADDR slave;
  33578. + MV_U8 data;
  33579. +
  33580. + /* TWSI init */
  33581. + slave.type = ADDR7_BIT;
  33582. + slave.address = 0;
  33583. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33584. +
  33585. + /* Read MPP module ID */
  33586. + DB(mvOsPrintf("Board: Read MPP module ID\n"));
  33587. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);
  33588. + twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(devClass);
  33589. + twsiSlave.validOffset = MV_TRUE;
  33590. + /* Offset is the first command after the address which indicate the register number to be read
  33591. + in next operation */
  33592. + twsiSlave.offset = 0;
  33593. + twsiSlave.moreThen256 = MV_FALSE;
  33594. +
  33595. +
  33596. +
  33597. + if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )
  33598. + {
  33599. + DB(mvOsPrintf("Board: Read MPP module ID fail\n"));
  33600. + return MV_ERROR;
  33601. + }
  33602. + DB(mvOsPrintf("Board: Read MPP module ID succeded\n"));
  33603. +
  33604. + return data;
  33605. +}
  33606. +
  33607. +/*******************************************************************************
  33608. +* mvBoarTwsiSatRGet -
  33609. +*
  33610. +* DESCRIPTION:
  33611. +*
  33612. +* INPUT:
  33613. +* device num - one of three devices
  33614. +* reg num - 0 or 1
  33615. +*
  33616. +* OUTPUT:
  33617. +* None.
  33618. +*
  33619. +* RETURN:
  33620. +* reg value
  33621. +*
  33622. +*******************************************************************************/
  33623. +MV_U8 mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum)
  33624. +{
  33625. + MV_TWSI_SLAVE twsiSlave;
  33626. + MV_TWSI_ADDR slave;
  33627. + MV_U8 data;
  33628. +
  33629. + /* TWSI init */
  33630. + slave.type = ADDR7_BIT;
  33631. + slave.address = 0;
  33632. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33633. +
  33634. + /* Read MPP module ID */
  33635. + DB(mvOsPrintf("Board: Read S@R device read\n"));
  33636. + twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);
  33637. + twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);
  33638. + twsiSlave.validOffset = MV_TRUE;
  33639. + /* Use offset as command */
  33640. + twsiSlave.offset = regNum;
  33641. + twsiSlave.moreThen256 = MV_FALSE;
  33642. +
  33643. + if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )
  33644. + {
  33645. + DB(mvOsPrintf("Board: Read S@R fail\n"));
  33646. + return MV_ERROR;
  33647. + }
  33648. + DB(mvOsPrintf("Board: Read S@R succeded\n"));
  33649. +
  33650. + return data;
  33651. +}
  33652. +
  33653. +/*******************************************************************************
  33654. +* mvBoarTwsiSatRSet -
  33655. +*
  33656. +* DESCRIPTION:
  33657. +*
  33658. +* INPUT:
  33659. +* devNum - one of three devices
  33660. +* regNum - 0 or 1
  33661. +* regVal - value
  33662. +*
  33663. +*
  33664. +* OUTPUT:
  33665. +* None.
  33666. +*
  33667. +* RETURN:
  33668. +* reg value
  33669. +*
  33670. +*******************************************************************************/
  33671. +MV_STATUS mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal)
  33672. +{
  33673. + MV_TWSI_SLAVE twsiSlave;
  33674. + MV_TWSI_ADDR slave;
  33675. +
  33676. + /* TWSI init */
  33677. + slave.type = ADDR7_BIT;
  33678. + slave.address = 0;
  33679. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33680. +
  33681. + /* Read MPP module ID */
  33682. + twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);
  33683. + twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);
  33684. + twsiSlave.validOffset = MV_TRUE;
  33685. + DB(mvOsPrintf("Board: Write S@R device addr %x, type %x, data %x\n", twsiSlave.slaveAddr.address,\
  33686. + twsiSlave.slaveAddr.type, regVal));
  33687. + /* Use offset as command */
  33688. + twsiSlave.offset = regNum;
  33689. + twsiSlave.moreThen256 = MV_FALSE;
  33690. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &regVal, 1) )
  33691. + {
  33692. + DB(mvOsPrintf("Board: Write S@R fail\n"));
  33693. + return MV_ERROR;
  33694. + }
  33695. + DB(mvOsPrintf("Board: Write S@R succeded\n"));
  33696. +
  33697. + return MV_OK;
  33698. +}
  33699. +
  33700. +/*******************************************************************************
  33701. +* mvBoardSlicGpioPinGet -
  33702. +*
  33703. +* DESCRIPTION:
  33704. +*
  33705. +* INPUT:
  33706. +*
  33707. +* OUTPUT:
  33708. +* None.
  33709. +*
  33710. +* RETURN:
  33711. +*
  33712. +*
  33713. +*******************************************************************************/
  33714. +MV_32 mvBoardSlicGpioPinGet(MV_U32 slicNum)
  33715. +{
  33716. + MV_U32 boardId;
  33717. + boardId = mvBoardIdGet();
  33718. +
  33719. + switch (boardId)
  33720. + {
  33721. + case DB_88F6281A_BP_ID:
  33722. + case RD_88F6281A_ID:
  33723. + default:
  33724. + return MV_ERROR;
  33725. + break;
  33726. +
  33727. + }
  33728. +}
  33729. +
  33730. +/*******************************************************************************
  33731. +* mvBoardFanPowerControl - Turn on/off the fan power control on the RD-6281A
  33732. +*
  33733. +* DESCRIPTION:
  33734. +*
  33735. +* INPUT:
  33736. +* mode - MV_TRUE = on ; MV_FALSE = off
  33737. +*
  33738. +* OUTPUT:
  33739. +* MV_STATUS - MV_OK , MV_ERROR.
  33740. +*
  33741. +* RETURN:
  33742. +*
  33743. +*******************************************************************************/
  33744. +MV_STATUS mvBoardFanPowerControl(MV_BOOL mode)
  33745. +{
  33746. +
  33747. + MV_U8 val = 1, twsiVal;
  33748. + MV_TWSI_SLAVE twsiSlave;
  33749. + MV_TWSI_ADDR slave;
  33750. +
  33751. + if(mvBoardIdGet() != RD_88F6281A_ID)
  33752. + return MV_ERROR;
  33753. +
  33754. + /* TWSI init */
  33755. + slave.type = ADDR7_BIT;
  33756. + slave.address = 0;
  33757. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33758. +
  33759. + /* Read MPP module ID */
  33760. + DB(mvOsPrintf("Board: twsi exp set\n"));
  33761. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);
  33762. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  33763. + twsiSlave.validOffset = MV_TRUE;
  33764. + /* Offset is the first command after the address which indicate the register number to be read
  33765. + in next operation */
  33766. + twsiSlave.offset = 3;
  33767. + twsiSlave.moreThen256 = MV_FALSE;
  33768. + if(mode == MV_TRUE)
  33769. + val = 0x1;
  33770. + else
  33771. + val = 0;
  33772. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33773. + val = (twsiVal & 0xfe) | val;
  33774. +
  33775. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  33776. + {
  33777. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  33778. + return MV_ERROR;
  33779. + }
  33780. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  33781. +
  33782. + /* Change twsi exp to output */
  33783. + twsiSlave.offset = 7;
  33784. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33785. + val = (twsiVal & 0xfe);
  33786. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  33787. + {
  33788. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  33789. + return MV_ERROR;
  33790. + }
  33791. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  33792. + return MV_OK;
  33793. +}
  33794. +
  33795. +/*******************************************************************************
  33796. +* mvBoardHDDPowerControl - Turn on/off the HDD power control on the RD-6281A
  33797. +*
  33798. +* DESCRIPTION:
  33799. +*
  33800. +* INPUT:
  33801. +* mode - MV_TRUE = on ; MV_FALSE = off
  33802. +*
  33803. +* OUTPUT:
  33804. +* MV_STATUS - MV_OK , MV_ERROR.
  33805. +*
  33806. +* RETURN:
  33807. +*
  33808. +*******************************************************************************/
  33809. +MV_STATUS mvBoardHDDPowerControl(MV_BOOL mode)
  33810. +{
  33811. +
  33812. + MV_U8 val = 1, twsiVal;
  33813. + MV_TWSI_SLAVE twsiSlave;
  33814. + MV_TWSI_ADDR slave;
  33815. +
  33816. + if(mvBoardIdGet() != RD_88F6281A_ID)
  33817. + return MV_ERROR;
  33818. +
  33819. + /* TWSI init */
  33820. + slave.type = ADDR7_BIT;
  33821. + slave.address = 0;
  33822. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33823. +
  33824. + /* Read MPP module ID */
  33825. + DB(mvOsPrintf("Board: twsi exp set\n"));
  33826. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);
  33827. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  33828. + twsiSlave.validOffset = MV_TRUE;
  33829. + /* Offset is the first command after the address which indicate the register number to be read
  33830. + in next operation */
  33831. + twsiSlave.offset = 3;
  33832. + twsiSlave.moreThen256 = MV_FALSE;
  33833. + if(mode == MV_TRUE)
  33834. + val = 0x2;
  33835. + else
  33836. + val = 0;
  33837. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33838. + val = (twsiVal & 0xfd) | val;
  33839. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  33840. + {
  33841. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  33842. + return MV_ERROR;
  33843. + }
  33844. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  33845. +
  33846. + /* Change twsi exp to output */
  33847. + twsiSlave.offset = 7;
  33848. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33849. + val = (twsiVal & 0xfd);
  33850. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  33851. + {
  33852. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  33853. + return MV_ERROR;
  33854. + }
  33855. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  33856. + return MV_OK;
  33857. +}
  33858. +
  33859. +/*******************************************************************************
  33860. +* mvBoardSDioWPControl - Turn on/off the SDIO WP on the RD-6281A
  33861. +*
  33862. +* DESCRIPTION:
  33863. +*
  33864. +* INPUT:
  33865. +* mode - MV_TRUE = on ; MV_FALSE = off
  33866. +*
  33867. +* OUTPUT:
  33868. +* MV_STATUS - MV_OK , MV_ERROR.
  33869. +*
  33870. +* RETURN:
  33871. +*
  33872. +*******************************************************************************/
  33873. +MV_STATUS mvBoardSDioWPControl(MV_BOOL mode)
  33874. +{
  33875. +
  33876. + MV_U8 val = 1, twsiVal;
  33877. + MV_TWSI_SLAVE twsiSlave;
  33878. + MV_TWSI_ADDR slave;
  33879. +
  33880. + if(mvBoardIdGet() != RD_88F6281A_ID)
  33881. + return MV_ERROR;
  33882. +
  33883. + /* TWSI init */
  33884. + slave.type = ADDR7_BIT;
  33885. + slave.address = 0;
  33886. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33887. +
  33888. + /* Read MPP module ID */
  33889. + DB(mvOsPrintf("Board: twsi exp set\n"));
  33890. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(0);
  33891. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  33892. + twsiSlave.validOffset = MV_TRUE;
  33893. + /* Offset is the first command after the address which indicate the register number to be read
  33894. + in next operation */
  33895. + twsiSlave.offset = 3;
  33896. + twsiSlave.moreThen256 = MV_FALSE;
  33897. + if(mode == MV_TRUE)
  33898. + val = 0x10;
  33899. + else
  33900. + val = 0;
  33901. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33902. + val = (twsiVal & 0xef) | val;
  33903. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  33904. + {
  33905. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  33906. + return MV_ERROR;
  33907. + }
  33908. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  33909. +
  33910. + /* Change twsi exp to output */
  33911. + twsiSlave.offset = 7;
  33912. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33913. + val = (twsiVal & 0xef);
  33914. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  33915. + {
  33916. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  33917. + return MV_ERROR;
  33918. + }
  33919. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  33920. + return MV_OK;
  33921. +}
  33922. +
  33923. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h
  33924. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h 1970-01-01 01:00:00.000000000 +0100
  33925. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h 2010-11-09 20:28:07.362495449 +0100
  33926. @@ -0,0 +1,376 @@
  33927. +/*******************************************************************************
  33928. +Copyright (C) Marvell International Ltd. and its affiliates
  33929. +
  33930. +This software file (the "File") is owned and distributed by Marvell
  33931. +International Ltd. and/or its affiliates ("Marvell") under the following
  33932. +alternative licensing terms. Once you have made an election to distribute the
  33933. +File under one of the following license alternatives, please (i) delete this
  33934. +introductory statement regarding license alternatives, (ii) delete the two
  33935. +license alternatives that you have not elected to use and (iii) preserve the
  33936. +Marvell copyright notice above.
  33937. +
  33938. +********************************************************************************
  33939. +Marvell Commercial License Option
  33940. +
  33941. +If you received this File from Marvell and you have entered into a commercial
  33942. +license agreement (a "Commercial License") with Marvell, the File is licensed
  33943. +to you under the terms of the applicable Commercial License.
  33944. +
  33945. +********************************************************************************
  33946. +Marvell GPL License Option
  33947. +
  33948. +If you received this File from Marvell, you may opt to use, redistribute and/or
  33949. +modify this File in accordance with the terms and conditions of the General
  33950. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  33951. +available along with the File in the license.txt file or by writing to the Free
  33952. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  33953. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  33954. +
  33955. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  33956. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  33957. +DISCLAIMED. The GPL License provides additional details about this warranty
  33958. +disclaimer.
  33959. +********************************************************************************
  33960. +Marvell BSD License Option
  33961. +
  33962. +If you received this File from Marvell, you may opt to use, redistribute and/or
  33963. +modify this File under the following licensing terms.
  33964. +Redistribution and use in source and binary forms, with or without modification,
  33965. +are permitted provided that the following conditions are met:
  33966. +
  33967. + * Redistributions of source code must retain the above copyright notice,
  33968. + this list of conditions and the following disclaimer.
  33969. +
  33970. + * Redistributions in binary form must reproduce the above copyright
  33971. + notice, this list of conditions and the following disclaimer in the
  33972. + documentation and/or other materials provided with the distribution.
  33973. +
  33974. + * Neither the name of Marvell nor the names of its contributors may be
  33975. + used to endorse or promote products derived from this software without
  33976. + specific prior written permission.
  33977. +
  33978. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  33979. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  33980. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  33981. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  33982. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  33983. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  33984. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  33985. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33986. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  33987. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33988. +
  33989. +*******************************************************************************/
  33990. +#ifndef __INCmvBoardEnvLibh
  33991. +#define __INCmvBoardEnvLibh
  33992. +
  33993. +/* defines */
  33994. +/* The below constant macros defines the board I2C EEPROM data offsets */
  33995. +
  33996. +
  33997. +
  33998. +#include "ctrlEnv/mvCtrlEnvLib.h"
  33999. +#include "mvSysHwConfig.h"
  34000. +#include "boardEnv/mvBoardEnvSpec.h"
  34001. +
  34002. +
  34003. +/* DUART stuff for Tclk detection only */
  34004. +#define DUART_BAUD_RATE 115200
  34005. +#define MAX_CLOCK_MARGINE 5000000 /* Maximum detected clock margine */
  34006. +
  34007. +/* Voice devices assembly modes */
  34008. +#define DAISY_CHAIN_MODE 1
  34009. +#define DUAL_CHIP_SELECT_MODE 0
  34010. +#define INTERRUPT_TO_MPP 1
  34011. +#define INTERRUPT_TO_TDM 0
  34012. +
  34013. +
  34014. +#define BOARD_ETH_PORT_NUM MV_ETH_MAX_PORTS
  34015. +#define BOARD_ETH_SWITCH_PORT_NUM 5
  34016. +
  34017. +#define MV_BOARD_MAX_USB_IF 1
  34018. +#define MV_BOARD_MAX_MPP 7
  34019. +#define MV_BOARD_NAME_LEN 0x20
  34020. +
  34021. +typedef struct _boardData
  34022. +{
  34023. + MV_U32 magic;
  34024. + MV_U16 boardId;
  34025. + MV_U8 boardVer;
  34026. + MV_U8 boardRev;
  34027. + MV_U32 reserved1;
  34028. + MV_U32 reserved2;
  34029. +
  34030. +}BOARD_DATA;
  34031. +
  34032. +typedef enum _devBoardMppGroupClass
  34033. +{
  34034. + MV_BOARD_MPP_GROUP_1,
  34035. + MV_BOARD_MPP_GROUP_2,
  34036. + MV_BOARD_MAX_MPP_GROUP
  34037. +}MV_BOARD_MPP_GROUP_CLASS;
  34038. +
  34039. +typedef enum _devBoardMppTypeClass
  34040. +{
  34041. + MV_BOARD_AUTO,
  34042. + MV_BOARD_TDM,
  34043. + MV_BOARD_AUDIO,
  34044. + MV_BOARD_RGMII,
  34045. + MV_BOARD_GMII,
  34046. + MV_BOARD_TS,
  34047. + MV_BOARD_MII,
  34048. + MV_BOARD_OTHER
  34049. +}MV_BOARD_MPP_TYPE_CLASS;
  34050. +
  34051. +typedef enum _devBoardModuleIdClass
  34052. +{
  34053. + MV_BOARD_MODULE_TDM_ID = 1,
  34054. + MV_BOARD_MODULE_AUDIO_ID,
  34055. + MV_BOARD_MODULE_RGMII_ID,
  34056. + MV_BOARD_MODULE_GMII_ID,
  34057. + MV_BOARD_MODULE_TS_ID,
  34058. + MV_BOARD_MODULE_MII_ID,
  34059. + MV_BOARD_MODULE_TDM_5CHAN_ID,
  34060. + MV_BOARD_MODULE_OTHER_ID
  34061. +}MV_BOARD_MODULE_ID_CLASS;
  34062. +
  34063. +typedef struct _boardMppTypeInfo
  34064. +{
  34065. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup1;
  34066. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2;
  34067. +
  34068. +}MV_BOARD_MPP_TYPE_INFO;
  34069. +
  34070. +
  34071. +typedef enum _devBoardClass
  34072. +{
  34073. + BOARD_DEV_NOR_FLASH,
  34074. + BOARD_DEV_NAND_FLASH,
  34075. + BOARD_DEV_SEVEN_SEG,
  34076. + BOARD_DEV_FPGA,
  34077. + BOARD_DEV_SRAM,
  34078. + BOARD_DEV_SPI_FLASH,
  34079. + BOARD_DEV_OTHER,
  34080. +}MV_BOARD_DEV_CLASS;
  34081. +
  34082. +typedef enum _devTwsiBoardClass
  34083. +{
  34084. + BOARD_TWSI_RTC,
  34085. + BOARD_DEV_TWSI_EXP,
  34086. + BOARD_DEV_TWSI_SATR,
  34087. + BOARD_TWSI_AUDIO_DEC,
  34088. + BOARD_TWSI_OTHER
  34089. +}MV_BOARD_TWSI_CLASS;
  34090. +
  34091. +typedef enum _devGppBoardClass
  34092. +{
  34093. + BOARD_GPP_RTC,
  34094. + BOARD_GPP_MV_SWITCH,
  34095. + BOARD_GPP_USB_VBUS,
  34096. + BOARD_GPP_USB_VBUS_EN,
  34097. + BOARD_GPP_USB_OC,
  34098. + BOARD_GPP_USB_HOST_DEVICE,
  34099. + BOARD_GPP_REF_CLCK,
  34100. + BOARD_GPP_VOIP_SLIC,
  34101. + BOARD_GPP_LIFELINE,
  34102. + BOARD_GPP_BUTTON,
  34103. + BOARD_GPP_TS_BUTTON_C,
  34104. + BOARD_GPP_TS_BUTTON_U,
  34105. + BOARD_GPP_TS_BUTTON_D,
  34106. + BOARD_GPP_TS_BUTTON_L,
  34107. + BOARD_GPP_TS_BUTTON_R,
  34108. + BOARD_GPP_POWER_BUTTON,
  34109. + BOARD_GPP_RESTOR_BUTTON,
  34110. + BOARD_GPP_WPS_BUTTON,
  34111. + BOARD_GPP_HDD0_POWER,
  34112. + BOARD_GPP_HDD1_POWER,
  34113. + BOARD_GPP_FAN_POWER,
  34114. + BOARD_GPP_RESET,
  34115. + BOARD_GPP_POWER_ON_LED,
  34116. + BOARD_GPP_HDD_POWER,
  34117. + BOARD_GPP_SDIO_POWER,
  34118. + BOARD_GPP_SDIO_DETECT,
  34119. + BOARD_GPP_SDIO_WP,
  34120. + BOARD_GPP_SWITCH_PHY_INT,
  34121. + BOARD_GPP_TSU_DIRCTION,
  34122. + BOARD_GPP_OTHER
  34123. +}MV_BOARD_GPP_CLASS;
  34124. +
  34125. +
  34126. +typedef struct _devCsInfo
  34127. +{
  34128. + MV_U8 deviceCS;
  34129. + MV_U32 params;
  34130. + MV_U32 devClass; /* MV_BOARD_DEV_CLASS */
  34131. + MV_U8 devWidth;
  34132. +
  34133. +}MV_DEV_CS_INFO;
  34134. +
  34135. +
  34136. +#define MV_BOARD_PHY_FORCE_10MB 0x0
  34137. +#define MV_BOARD_PHY_FORCE_100MB 0x1
  34138. +#define MV_BOARD_PHY_FORCE_1000MB 0x2
  34139. +#define MV_BOARD_PHY_SPEED_AUTO 0x3
  34140. +
  34141. +typedef struct _boardSwitchInfo
  34142. +{
  34143. + MV_32 linkStatusIrq;
  34144. + MV_32 qdPort[BOARD_ETH_SWITCH_PORT_NUM];
  34145. + MV_32 qdCpuPort;
  34146. + MV_32 smiScanMode; /* 1 for SMI_MANUAL_MODE, 0 otherwise */
  34147. + MV_32 switchOnPort;
  34148. +
  34149. +}MV_BOARD_SWITCH_INFO;
  34150. +
  34151. +typedef struct _boardLedInfo
  34152. +{
  34153. + MV_U8 activeLedsNumber;
  34154. + MV_U8 ledsPolarity; /* '0' or '1' to turn on led */
  34155. + MV_U8* gppPinNum; /* Pointer to GPP values */
  34156. +
  34157. +}MV_BOARD_LED_INFO;
  34158. +
  34159. +typedef struct _boardGppInfo
  34160. +{
  34161. + MV_BOARD_GPP_CLASS devClass;
  34162. + MV_U8 gppPinNum;
  34163. +
  34164. +}MV_BOARD_GPP_INFO;
  34165. +
  34166. +
  34167. +typedef struct _boardTwsiInfo
  34168. +{
  34169. + MV_BOARD_TWSI_CLASS devClass;
  34170. + MV_U8 twsiDevAddr;
  34171. + MV_U8 twsiDevAddrType;
  34172. +
  34173. +}MV_BOARD_TWSI_INFO;
  34174. +
  34175. +
  34176. +typedef enum _boardMacSpeed
  34177. +{
  34178. + BOARD_MAC_SPEED_10M,
  34179. + BOARD_MAC_SPEED_100M,
  34180. + BOARD_MAC_SPEED_1000M,
  34181. + BOARD_MAC_SPEED_AUTO,
  34182. +
  34183. +}MV_BOARD_MAC_SPEED;
  34184. +
  34185. +typedef struct _boardMacInfo
  34186. +{
  34187. + MV_BOARD_MAC_SPEED boardMacSpeed;
  34188. + MV_U8 boardEthSmiAddr;
  34189. +
  34190. +}MV_BOARD_MAC_INFO;
  34191. +
  34192. +typedef struct _boardMppInfo
  34193. +{
  34194. + MV_U32 mppGroup[MV_BOARD_MAX_MPP];
  34195. +
  34196. +}MV_BOARD_MPP_INFO;
  34197. +
  34198. +typedef struct _boardInfo
  34199. +{
  34200. + char boardName[MV_BOARD_NAME_LEN];
  34201. + MV_U8 numBoardMppTypeValue;
  34202. + MV_BOARD_MPP_TYPE_INFO* pBoardMppTypeValue;
  34203. + MV_U8 numBoardMppConfigValue;
  34204. + MV_BOARD_MPP_INFO* pBoardMppConfigValue;
  34205. + MV_U32 intsGppMaskLow;
  34206. + MV_U32 intsGppMaskHigh;
  34207. + MV_U8 numBoardDeviceIf;
  34208. + MV_DEV_CS_INFO* pDevCsInfo;
  34209. + MV_U8 numBoardTwsiDev;
  34210. + MV_BOARD_TWSI_INFO* pBoardTwsiDev;
  34211. + MV_U8 numBoardMacInfo;
  34212. + MV_BOARD_MAC_INFO* pBoardMacInfo;
  34213. + MV_U8 numBoardGppInfo;
  34214. + MV_BOARD_GPP_INFO* pBoardGppInfo;
  34215. + MV_U8 activeLedsNumber;
  34216. + MV_U8* pLedGppPin;
  34217. + MV_U8 ledsPolarity; /* '0' or '1' to turn on led */
  34218. + /* GPP values */
  34219. + MV_U32 gppOutEnValLow;
  34220. + MV_U32 gppOutEnValHigh;
  34221. + MV_U32 gppOutValLow;
  34222. + MV_U32 gppOutValHigh;
  34223. + MV_U32 gppPolarityValLow;
  34224. + MV_U32 gppPolarityValHigh;
  34225. +
  34226. + /* Switch Configuration */
  34227. + MV_BOARD_SWITCH_INFO* pSwitchInfo;
  34228. +}MV_BOARD_INFO;
  34229. +
  34230. +
  34231. +
  34232. +MV_VOID mvBoardEnvInit(MV_VOID);
  34233. +MV_U32 mvBoardIdGet(MV_VOID);
  34234. +MV_U16 mvBoardModelGet(MV_VOID);
  34235. +MV_U16 mvBoardRevGet(MV_VOID);
  34236. +MV_STATUS mvBoardNameGet(char *pNameBuff);
  34237. +MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum);
  34238. +MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum);
  34239. +MV_32 mvBoardLinkStatusIrqGet(MV_U32 ethPortNum);
  34240. +MV_32 mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum);
  34241. +MV_32 mvBoardSwitchCpuPortGet(MV_U32 ethPortNum);
  34242. +MV_32 mvBoardIsSwitchConnected(MV_U32 ethPortNum);
  34243. +MV_32 mvBoardSmiScanModeGet(MV_U32 ethPortNum);
  34244. +MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum);
  34245. +MV_BOOL mvBoardIsPortInGmii(MV_VOID);
  34246. +MV_U32 mvBoardTclkGet(MV_VOID);
  34247. +MV_U32 mvBoardSysClkGet(MV_VOID);
  34248. +MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId);
  34249. +MV_VOID mvBoardDebugLed(MV_U32 hexNum);
  34250. +MV_32 mvBoardMppGet(MV_U32 mppGroupNum);
  34251. +
  34252. +MV_U8 mvBoardRtcTwsiAddrTypeGet(MV_VOID);
  34253. +MV_U8 mvBoardRtcTwsiAddrGet(MV_VOID);
  34254. +
  34255. +MV_U8 mvBoardA2DTwsiAddrTypeGet(MV_VOID);
  34256. +MV_U8 mvBoardA2DTwsiAddrGet(MV_VOID);
  34257. +
  34258. +MV_U8 mvBoardTwsiExpAddrGet(MV_U32 index);
  34259. +MV_U8 mvBoardTwsiSatRAddrTypeGet(MV_U32 index);
  34260. +MV_U8 mvBoardTwsiSatRAddrGet(MV_U32 index);
  34261. +MV_U8 mvBoardTwsiExpAddrTypeGet(MV_U32 index);
  34262. +MV_BOARD_MODULE_ID_CLASS mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass);
  34263. +MV_BOARD_MPP_TYPE_CLASS mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass);
  34264. +MV_VOID mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,
  34265. + MV_BOARD_MPP_TYPE_CLASS mppGroupType);
  34266. +MV_VOID mvBoardMppGroupIdUpdate(MV_VOID);
  34267. +MV_VOID mvBoardMppMuxSet(MV_VOID);
  34268. +MV_VOID mvBoardTdmMppSet(MV_32 chType);
  34269. +MV_VOID mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode);
  34270. +
  34271. +MV_VOID mvBoardMppModuleTypePrint(MV_VOID);
  34272. +MV_VOID mvBoardReset(MV_VOID);
  34273. +MV_U8 mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum);
  34274. +MV_STATUS mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal);
  34275. +MV_BOOL mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data);
  34276. +/* Board devices API managments */
  34277. +MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass);
  34278. +MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  34279. +MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  34280. +MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  34281. +MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  34282. +MV_U32 boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  34283. +
  34284. +/* Gpio Pin Connections API */
  34285. +MV_32 mvBoardUSBVbusGpioPinGet(int devId);
  34286. +MV_32 mvBoardUSBVbusEnGpioPinGet(int devId);
  34287. +MV_U32 mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin);
  34288. +
  34289. +MV_32 mvBoardResetGpioPinGet(MV_VOID);
  34290. +MV_32 mvBoardRTCGpioPinGet(MV_VOID);
  34291. +MV_32 mvBoardGpioIntMaskLowGet(MV_VOID);
  34292. +MV_32 mvBoardGpioIntMaskHighGet(MV_VOID);
  34293. +MV_32 mvBoardSlicGpioPinGet(MV_U32 slicNum);
  34294. +
  34295. +MV_32 mvBoardSDIOGpioPinGet(MV_VOID);
  34296. +MV_STATUS mvBoardSDioWPControl(MV_BOOL mode);
  34297. +MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index);
  34298. +
  34299. +MV_32 mvBoardNandWidthGet(void);
  34300. +MV_STATUS mvBoardFanPowerControl(MV_BOOL mode);
  34301. +MV_STATUS mvBoardHDDPowerControl(MV_BOOL mode);
  34302. +#endif /* __INCmvBoardEnvLibh */
  34303. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c
  34304. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c 1970-01-01 01:00:00.000000000 +0100
  34305. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c 2010-11-09 20:28:07.443751783 +0100
  34306. @@ -0,0 +1,848 @@
  34307. +/*******************************************************************************
  34308. +Copyright (C) Marvell International Ltd. and its affiliates
  34309. +
  34310. +This software file (the "File") is owned and distributed by Marvell
  34311. +International Ltd. and/or its affiliates ("Marvell") under the following
  34312. +alternative licensing terms. Once you have made an election to distribute the
  34313. +File under one of the following license alternatives, please (i) delete this
  34314. +introductory statement regarding license alternatives, (ii) delete the two
  34315. +license alternatives that you have not elected to use and (iii) preserve the
  34316. +Marvell copyright notice above.
  34317. +
  34318. +********************************************************************************
  34319. +Marvell Commercial License Option
  34320. +
  34321. +If you received this File from Marvell and you have entered into a commercial
  34322. +license agreement (a "Commercial License") with Marvell, the File is licensed
  34323. +to you under the terms of the applicable Commercial License.
  34324. +
  34325. +********************************************************************************
  34326. +Marvell GPL License Option
  34327. +
  34328. +If you received this File from Marvell, you may opt to use, redistribute and/or
  34329. +modify this File in accordance with the terms and conditions of the General
  34330. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  34331. +available along with the File in the license.txt file or by writing to the Free
  34332. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  34333. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  34334. +
  34335. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  34336. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  34337. +DISCLAIMED. The GPL License provides additional details about this warranty
  34338. +disclaimer.
  34339. +********************************************************************************
  34340. +Marvell BSD License Option
  34341. +
  34342. +If you received this File from Marvell, you may opt to use, redistribute and/or
  34343. +modify this File under the following licensing terms.
  34344. +Redistribution and use in source and binary forms, with or without modification,
  34345. +are permitted provided that the following conditions are met:
  34346. +
  34347. + * Redistributions of source code must retain the above copyright notice,
  34348. + this list of conditions and the following disclaimer.
  34349. +
  34350. + * Redistributions in binary form must reproduce the above copyright
  34351. + notice, this list of conditions and the following disclaimer in the
  34352. + documentation and/or other materials provided with the distribution.
  34353. +
  34354. + * Neither the name of Marvell nor the names of its contributors may be
  34355. + used to endorse or promote products derived from this software without
  34356. + specific prior written permission.
  34357. +
  34358. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  34359. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  34360. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  34361. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  34362. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  34363. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  34364. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  34365. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  34366. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  34367. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34368. +
  34369. +*******************************************************************************/
  34370. +#include "mvCommon.h"
  34371. +#include "mvBoardEnvLib.h"
  34372. +#include "mvBoardEnvSpec.h"
  34373. +#include "twsi/mvTwsi.h"
  34374. +
  34375. +#define DB_88F6281A_BOARD_PCI_IF_NUM 0x0
  34376. +#define DB_88F6281A_BOARD_TWSI_DEF_NUM 0x7
  34377. +#define DB_88F6281A_BOARD_MAC_INFO_NUM 0x2
  34378. +#define DB_88F6281A_BOARD_GPP_INFO_NUM 0x3
  34379. +#define DB_88F6281A_BOARD_MPP_CONFIG_NUM 0x1
  34380. +#define DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  34381. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34382. + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  34383. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34384. + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x2
  34385. +#else
  34386. + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  34387. +#endif
  34388. +#define DB_88F6281A_BOARD_DEBUG_LED_NUM 0x0
  34389. +
  34390. +
  34391. +MV_BOARD_TWSI_INFO db88f6281AInfoBoardTwsiDev[] =
  34392. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  34393. + {
  34394. + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
  34395. + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
  34396. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
  34397. + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
  34398. + {BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},
  34399. + {BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},
  34400. + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
  34401. + };
  34402. +
  34403. +MV_BOARD_MAC_INFO db88f6281AInfoBoardMacInfo[] =
  34404. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  34405. + {
  34406. + {BOARD_MAC_SPEED_AUTO, 0x8},
  34407. + {BOARD_MAC_SPEED_AUTO, 0x9}
  34408. + };
  34409. +
  34410. +MV_BOARD_MPP_TYPE_INFO db88f6281AInfoBoardMppTypeInfo[] =
  34411. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  34412. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  34413. + {{MV_BOARD_AUTO, MV_BOARD_AUTO}
  34414. + };
  34415. +
  34416. +MV_BOARD_GPP_INFO db88f6281AInfoBoardGppInfo[] =
  34417. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  34418. + {
  34419. + {BOARD_GPP_TSU_DIRCTION, 33}
  34420. + /*muxed with TDM/Audio module via IOexpender
  34421. + {BOARD_GPP_SDIO_DETECT, 38},
  34422. + {BOARD_GPP_USB_VBUS, 49}*/
  34423. + };
  34424. +
  34425. +MV_DEV_CS_INFO db88f6281AInfoBoardDeCsInfo[] =
  34426. + /*{deviceCS, params, devType, devWidth}*/
  34427. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34428. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  34429. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34430. + {
  34431. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  34432. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  34433. + };
  34434. +#else
  34435. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  34436. +#endif
  34437. +
  34438. +MV_BOARD_MPP_INFO db88f6281AInfoBoardMppConfigValue[] =
  34439. + {{{
  34440. + DB_88F6281A_MPP0_7,
  34441. + DB_88F6281A_MPP8_15,
  34442. + DB_88F6281A_MPP16_23,
  34443. + DB_88F6281A_MPP24_31,
  34444. + DB_88F6281A_MPP32_39,
  34445. + DB_88F6281A_MPP40_47,
  34446. + DB_88F6281A_MPP48_55
  34447. + }}};
  34448. +
  34449. +
  34450. +MV_BOARD_INFO db88f6281AInfo = {
  34451. + "DB-88F6281A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  34452. + DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34453. + db88f6281AInfoBoardMppTypeInfo,
  34454. + DB_88F6281A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34455. + db88f6281AInfoBoardMppConfigValue,
  34456. + 0, /* intsGppMaskLow */
  34457. + 0, /* intsGppMaskHigh */
  34458. + DB_88F6281A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34459. + db88f6281AInfoBoardDeCsInfo,
  34460. + DB_88F6281A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34461. + db88f6281AInfoBoardTwsiDev,
  34462. + DB_88F6281A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34463. + db88f6281AInfoBoardMacInfo,
  34464. + DB_88F6281A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34465. + db88f6281AInfoBoardGppInfo,
  34466. + DB_88F6281A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34467. + NULL,
  34468. + 0, /* ledsPolarity */
  34469. + DB_88F6281A_OE_LOW, /* gppOutEnLow */
  34470. + DB_88F6281A_OE_HIGH, /* gppOutEnHigh */
  34471. + DB_88F6281A_OE_VAL_LOW, /* gppOutValLow */
  34472. + DB_88F6281A_OE_VAL_HIGH, /* gppOutValHigh */
  34473. + 0, /* gppPolarityValLow */
  34474. + BIT6, /* gppPolarityValHigh */
  34475. + NULL /* pSwitchInfo */
  34476. +};
  34477. +
  34478. +
  34479. +#define RD_88F6281A_BOARD_PCI_IF_NUM 0x0
  34480. +#define RD_88F6281A_BOARD_TWSI_DEF_NUM 0x2
  34481. +#define RD_88F6281A_BOARD_MAC_INFO_NUM 0x2
  34482. +#define RD_88F6281A_BOARD_GPP_INFO_NUM 0x5
  34483. +#define RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  34484. +#define RD_88F6281A_BOARD_MPP_CONFIG_NUM 0x1
  34485. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34486. + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  34487. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34488. + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x2
  34489. +#else
  34490. + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  34491. +#endif
  34492. +#define RD_88F6281A_BOARD_DEBUG_LED_NUM 0x0
  34493. +
  34494. +MV_BOARD_MAC_INFO rd88f6281AInfoBoardMacInfo[] =
  34495. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  34496. + {{BOARD_MAC_SPEED_1000M, 0xa},
  34497. + {BOARD_MAC_SPEED_AUTO, 0xb}
  34498. + };
  34499. +
  34500. +MV_BOARD_SWITCH_INFO rd88f6281AInfoBoardSwitchInfo[] =
  34501. + /* MV_32 linkStatusIrq, {MV_32 qdPort0, MV_32 qdPort1, MV_32 qdPort2, MV_32 qdPort3, MV_32 qdPort4},
  34502. + MV_32 qdCpuPort, MV_32 smiScanMode, MV_32 switchOnPort} */
  34503. + {{38, {0, 1, 2, 3, -1}, 5, 2, 0},
  34504. + {-1, {-1}, -1, -1, -1}};
  34505. +
  34506. +MV_BOARD_TWSI_INFO rd88f6281AInfoBoardTwsiDev[] =
  34507. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  34508. + {
  34509. + {BOARD_DEV_TWSI_EXP, 0xFF, ADDR7_BIT}, /* dummy entry to align with modules indexes */
  34510. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT}
  34511. + };
  34512. +
  34513. +MV_BOARD_MPP_TYPE_INFO rd88f6281AInfoBoardMppTypeInfo[] =
  34514. + {{MV_BOARD_RGMII, MV_BOARD_TDM}
  34515. + };
  34516. +
  34517. +MV_DEV_CS_INFO rd88f6281AInfoBoardDeCsInfo[] =
  34518. + /*{deviceCS, params, devType, devWidth}*/
  34519. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34520. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  34521. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34522. + {
  34523. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  34524. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  34525. + };
  34526. +#else
  34527. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  34528. +#endif
  34529. +
  34530. +MV_BOARD_GPP_INFO rd88f6281AInfoBoardGppInfo[] =
  34531. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  34532. + {{BOARD_GPP_SDIO_DETECT, 28},
  34533. + {BOARD_GPP_USB_OC, 29},
  34534. + {BOARD_GPP_WPS_BUTTON, 35},
  34535. + {BOARD_GPP_MV_SWITCH, 38},
  34536. + {BOARD_GPP_USB_VBUS, 49}
  34537. + };
  34538. +
  34539. +MV_BOARD_MPP_INFO rd88f6281AInfoBoardMppConfigValue[] =
  34540. + {{{
  34541. + RD_88F6281A_MPP0_7,
  34542. + RD_88F6281A_MPP8_15,
  34543. + RD_88F6281A_MPP16_23,
  34544. + RD_88F6281A_MPP24_31,
  34545. + RD_88F6281A_MPP32_39,
  34546. + RD_88F6281A_MPP40_47,
  34547. + RD_88F6281A_MPP48_55
  34548. + }}};
  34549. +
  34550. +MV_BOARD_INFO rd88f6281AInfo = {
  34551. + "RD-88F6281A", /* boardName[MAX_BOARD_NAME_LEN] */
  34552. + RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34553. + rd88f6281AInfoBoardMppTypeInfo,
  34554. + RD_88F6281A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34555. + rd88f6281AInfoBoardMppConfigValue,
  34556. + 0, /* intsGppMaskLow */
  34557. + (1 << 3), /* intsGppMaskHigh */
  34558. + RD_88F6281A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34559. + rd88f6281AInfoBoardDeCsInfo,
  34560. + RD_88F6281A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34561. + rd88f6281AInfoBoardTwsiDev,
  34562. + RD_88F6281A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34563. + rd88f6281AInfoBoardMacInfo,
  34564. + RD_88F6281A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34565. + rd88f6281AInfoBoardGppInfo,
  34566. + RD_88F6281A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34567. + NULL,
  34568. + 0, /* ledsPolarity */
  34569. + RD_88F6281A_OE_LOW, /* gppOutEnLow */
  34570. + RD_88F6281A_OE_HIGH, /* gppOutEnHigh */
  34571. + RD_88F6281A_OE_VAL_LOW, /* gppOutValLow */
  34572. + RD_88F6281A_OE_VAL_HIGH, /* gppOutValHigh */
  34573. + 0, /* gppPolarityValLow */
  34574. + BIT6, /* gppPolarityValHigh */
  34575. + rd88f6281AInfoBoardSwitchInfo /* pSwitchInfo */
  34576. +};
  34577. +
  34578. +
  34579. +#define DB_88F6192A_BOARD_PCI_IF_NUM 0x0
  34580. +#define DB_88F6192A_BOARD_TWSI_DEF_NUM 0x7
  34581. +#define DB_88F6192A_BOARD_MAC_INFO_NUM 0x2
  34582. +#define DB_88F6192A_BOARD_GPP_INFO_NUM 0x3
  34583. +#define DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  34584. +#define DB_88F6192A_BOARD_MPP_CONFIG_NUM 0x1
  34585. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34586. + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
  34587. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34588. + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x2
  34589. +#else
  34590. + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
  34591. +#endif
  34592. +#define DB_88F6192A_BOARD_DEBUG_LED_NUM 0x0
  34593. +
  34594. +MV_BOARD_TWSI_INFO db88f6192AInfoBoardTwsiDev[] =
  34595. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  34596. + {
  34597. + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
  34598. + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
  34599. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
  34600. + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
  34601. + {BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},
  34602. + {BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},
  34603. + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
  34604. + };
  34605. +
  34606. +MV_BOARD_MAC_INFO db88f6192AInfoBoardMacInfo[] =
  34607. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  34608. + {
  34609. + {BOARD_MAC_SPEED_AUTO, 0x8},
  34610. + {BOARD_MAC_SPEED_AUTO, 0x9}
  34611. + };
  34612. +
  34613. +MV_BOARD_MPP_TYPE_INFO db88f6192AInfoBoardMppTypeInfo[] =
  34614. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  34615. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  34616. + {{MV_BOARD_AUTO, MV_BOARD_OTHER}
  34617. + };
  34618. +
  34619. +MV_DEV_CS_INFO db88f6192AInfoBoardDeCsInfo[] =
  34620. + /*{deviceCS, params, devType, devWidth}*/
  34621. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34622. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  34623. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34624. + {
  34625. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  34626. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  34627. + };
  34628. +#else
  34629. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  34630. +#endif
  34631. +
  34632. +MV_BOARD_GPP_INFO db88f6192AInfoBoardGppInfo[] =
  34633. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  34634. + {
  34635. + {BOARD_GPP_SDIO_WP, 20},
  34636. + {BOARD_GPP_USB_VBUS, 22},
  34637. + {BOARD_GPP_SDIO_DETECT, 23},
  34638. + };
  34639. +
  34640. +MV_BOARD_MPP_INFO db88f6192AInfoBoardMppConfigValue[] =
  34641. + {{{
  34642. + DB_88F6192A_MPP0_7,
  34643. + DB_88F6192A_MPP8_15,
  34644. + DB_88F6192A_MPP16_23,
  34645. + DB_88F6192A_MPP24_31,
  34646. + DB_88F6192A_MPP32_35
  34647. + }}};
  34648. +
  34649. +MV_BOARD_INFO db88f6192AInfo = {
  34650. + "DB-88F6192A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  34651. + DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34652. + db88f6192AInfoBoardMppTypeInfo,
  34653. + DB_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34654. + db88f6192AInfoBoardMppConfigValue,
  34655. + 0, /* intsGppMaskLow */
  34656. + (1 << 3), /* intsGppMaskHigh */
  34657. + DB_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34658. + db88f6192AInfoBoardDeCsInfo,
  34659. + DB_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34660. + db88f6192AInfoBoardTwsiDev,
  34661. + DB_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34662. + db88f6192AInfoBoardMacInfo,
  34663. + DB_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34664. + db88f6192AInfoBoardGppInfo,
  34665. + DB_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34666. + NULL,
  34667. + 0, /* ledsPolarity */
  34668. + DB_88F6192A_OE_LOW, /* gppOutEnLow */
  34669. + DB_88F6192A_OE_HIGH, /* gppOutEnHigh */
  34670. + DB_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  34671. + DB_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  34672. + 0, /* gppPolarityValLow */
  34673. + 0, /* gppPolarityValHigh */
  34674. + NULL /* pSwitchInfo */
  34675. +};
  34676. +
  34677. +#define DB_88F6190A_BOARD_MAC_INFO_NUM 0x1
  34678. +
  34679. +MV_BOARD_INFO db88f6190AInfo = {
  34680. + "DB-88F6190A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  34681. + DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34682. + db88f6192AInfoBoardMppTypeInfo,
  34683. + DB_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34684. + db88f6192AInfoBoardMppConfigValue,
  34685. + 0, /* intsGppMaskLow */
  34686. + (1 << 3), /* intsGppMaskHigh */
  34687. + DB_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34688. + db88f6192AInfoBoardDeCsInfo,
  34689. + DB_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34690. + db88f6192AInfoBoardTwsiDev,
  34691. + DB_88F6190A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34692. + db88f6192AInfoBoardMacInfo,
  34693. + DB_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34694. + db88f6192AInfoBoardGppInfo,
  34695. + DB_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34696. + NULL,
  34697. + 0, /* ledsPolarity */
  34698. + DB_88F6192A_OE_LOW, /* gppOutEnLow */
  34699. + DB_88F6192A_OE_HIGH, /* gppOutEnHigh */
  34700. + DB_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  34701. + DB_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  34702. + 0, /* gppPolarityValLow */
  34703. + 0, /* gppPolarityValHigh */
  34704. + NULL /* pSwitchInfo */
  34705. +};
  34706. +
  34707. +#define RD_88F6192A_BOARD_PCI_IF_NUM 0x0
  34708. +#define RD_88F6192A_BOARD_TWSI_DEF_NUM 0x0
  34709. +#define RD_88F6192A_BOARD_MAC_INFO_NUM 0x1
  34710. +#define RD_88F6192A_BOARD_GPP_INFO_NUM 0xE
  34711. +#define RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  34712. +#define RD_88F6192A_BOARD_MPP_CONFIG_NUM 0x1
  34713. +#define RD_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
  34714. +#define RD_88F6192A_BOARD_DEBUG_LED_NUM 0x3
  34715. +
  34716. +MV_U8 rd88f6192AInfoBoardDebugLedIf[] =
  34717. + {17, 28, 29};
  34718. +
  34719. +MV_BOARD_MAC_INFO rd88f6192AInfoBoardMacInfo[] =
  34720. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  34721. + {{BOARD_MAC_SPEED_AUTO, 0x8}
  34722. + };
  34723. +
  34724. +MV_BOARD_MPP_TYPE_INFO rd88f6192AInfoBoardMppTypeInfo[] =
  34725. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  34726. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  34727. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  34728. + };
  34729. +
  34730. +MV_DEV_CS_INFO rd88f6192AInfoBoardDeCsInfo[] =
  34731. + /*{deviceCS, params, devType, devWidth}*/
  34732. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  34733. +
  34734. +MV_BOARD_GPP_INFO rd88f6192AInfoBoardGppInfo[] =
  34735. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  34736. + {
  34737. + {BOARD_GPP_USB_VBUS_EN, 10},
  34738. + {BOARD_GPP_USB_HOST_DEVICE, 11},
  34739. + {BOARD_GPP_RESET, 14},
  34740. + {BOARD_GPP_POWER_ON_LED, 15},
  34741. + {BOARD_GPP_HDD_POWER, 16},
  34742. + {BOARD_GPP_WPS_BUTTON, 24},
  34743. + {BOARD_GPP_TS_BUTTON_C, 25},
  34744. + {BOARD_GPP_USB_VBUS, 26},
  34745. + {BOARD_GPP_USB_OC, 27},
  34746. + {BOARD_GPP_TS_BUTTON_U, 30},
  34747. + {BOARD_GPP_TS_BUTTON_R, 31},
  34748. + {BOARD_GPP_TS_BUTTON_L, 32},
  34749. + {BOARD_GPP_TS_BUTTON_D, 34},
  34750. + {BOARD_GPP_FAN_POWER, 35}
  34751. + };
  34752. +
  34753. +MV_BOARD_MPP_INFO rd88f6192AInfoBoardMppConfigValue[] =
  34754. + {{{
  34755. + RD_88F6192A_MPP0_7,
  34756. + RD_88F6192A_MPP8_15,
  34757. + RD_88F6192A_MPP16_23,
  34758. + RD_88F6192A_MPP24_31,
  34759. + RD_88F6192A_MPP32_35
  34760. + }}};
  34761. +
  34762. +MV_BOARD_INFO rd88f6192AInfo = {
  34763. + "RD-88F6192A-NAS", /* boardName[MAX_BOARD_NAME_LEN] */
  34764. + RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34765. + rd88f6192AInfoBoardMppTypeInfo,
  34766. + RD_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34767. + rd88f6192AInfoBoardMppConfigValue,
  34768. + 0, /* intsGppMaskLow */
  34769. + (1 << 3), /* intsGppMaskHigh */
  34770. + RD_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34771. + rd88f6192AInfoBoardDeCsInfo,
  34772. + RD_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34773. + NULL,
  34774. + RD_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34775. + rd88f6192AInfoBoardMacInfo,
  34776. + RD_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34777. + rd88f6192AInfoBoardGppInfo,
  34778. + RD_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34779. + rd88f6192AInfoBoardDebugLedIf,
  34780. + 0, /* ledsPolarity */
  34781. + RD_88F6192A_OE_LOW, /* gppOutEnLow */
  34782. + RD_88F6192A_OE_HIGH, /* gppOutEnHigh */
  34783. + RD_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  34784. + RD_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  34785. + 0, /* gppPolarityValLow */
  34786. + 0, /* gppPolarityValHigh */
  34787. + NULL /* pSwitchInfo */
  34788. +};
  34789. +
  34790. +MV_BOARD_INFO rd88f6190AInfo = {
  34791. + "RD-88F6190A-NAS", /* boardName[MAX_BOARD_NAME_LEN] */
  34792. + RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34793. + rd88f6192AInfoBoardMppTypeInfo,
  34794. + RD_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34795. + rd88f6192AInfoBoardMppConfigValue,
  34796. + 0, /* intsGppMaskLow */
  34797. + (1 << 3), /* intsGppMaskHigh */
  34798. + RD_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34799. + rd88f6192AInfoBoardDeCsInfo,
  34800. + RD_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34801. + NULL,
  34802. + RD_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34803. + rd88f6192AInfoBoardMacInfo,
  34804. + RD_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34805. + rd88f6192AInfoBoardGppInfo,
  34806. + RD_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34807. + rd88f6192AInfoBoardDebugLedIf,
  34808. + 0, /* ledsPolarity */
  34809. + RD_88F6192A_OE_LOW, /* gppOutEnLow */
  34810. + RD_88F6192A_OE_HIGH, /* gppOutEnHigh */
  34811. + RD_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  34812. + RD_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  34813. + 0, /* gppPolarityValLow */
  34814. + 0, /* gppPolarityValHigh */
  34815. + NULL /* pSwitchInfo */
  34816. +};
  34817. +
  34818. +#define DB_88F6180A_BOARD_PCI_IF_NUM 0x0
  34819. +#define DB_88F6180A_BOARD_TWSI_DEF_NUM 0x5
  34820. +#define DB_88F6180A_BOARD_MAC_INFO_NUM 0x1
  34821. +#define DB_88F6180A_BOARD_GPP_INFO_NUM 0x0
  34822. +#define DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM 0x2
  34823. +#define DB_88F6180A_BOARD_MPP_CONFIG_NUM 0x1
  34824. +#define DB_88F6180A_BOARD_DEVICE_CONFIG_NUM 0x1
  34825. +#define DB_88F6180A_BOARD_DEBUG_LED_NUM 0x0
  34826. +
  34827. +MV_BOARD_TWSI_INFO db88f6180AInfoBoardTwsiDev[] =
  34828. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  34829. + {
  34830. + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
  34831. + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
  34832. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
  34833. + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
  34834. + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
  34835. + };
  34836. +
  34837. +MV_BOARD_MAC_INFO db88f6180AInfoBoardMacInfo[] =
  34838. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  34839. + {{BOARD_MAC_SPEED_AUTO, 0x8}
  34840. + };
  34841. +
  34842. +MV_BOARD_GPP_INFO db88f6180AInfoBoardGppInfo[] =
  34843. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  34844. + {
  34845. + /* Muxed with TDM/Audio module via IOexpender
  34846. + {BOARD_GPP_USB_VBUS, 6} */
  34847. + };
  34848. +
  34849. +MV_BOARD_MPP_TYPE_INFO db88f6180AInfoBoardMppTypeInfo[] =
  34850. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  34851. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  34852. + {{MV_BOARD_OTHER, MV_BOARD_AUTO}
  34853. + };
  34854. +
  34855. +MV_DEV_CS_INFO db88f6180AInfoBoardDeCsInfo[] =
  34856. + /*{deviceCS, params, devType, devWidth}*/
  34857. +#if defined(MV_NAND_BOOT)
  34858. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  34859. +#else
  34860. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  34861. +#endif
  34862. +
  34863. +MV_BOARD_MPP_INFO db88f6180AInfoBoardMppConfigValue[] =
  34864. + {{{
  34865. + DB_88F6180A_MPP0_7,
  34866. + DB_88F6180A_MPP8_15,
  34867. + DB_88F6180A_MPP16_23,
  34868. + DB_88F6180A_MPP24_31,
  34869. + DB_88F6180A_MPP32_39,
  34870. + DB_88F6180A_MPP40_44
  34871. + }}};
  34872. +
  34873. +MV_BOARD_INFO db88f6180AInfo = {
  34874. + "DB-88F6180A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  34875. + DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34876. + db88f6180AInfoBoardMppTypeInfo,
  34877. + DB_88F6180A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34878. + db88f6180AInfoBoardMppConfigValue,
  34879. + 0, /* intsGppMaskLow */
  34880. + 0, /* intsGppMaskHigh */
  34881. + DB_88F6180A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34882. + db88f6180AInfoBoardDeCsInfo,
  34883. + DB_88F6180A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34884. + db88f6180AInfoBoardTwsiDev,
  34885. + DB_88F6180A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34886. + db88f6180AInfoBoardMacInfo,
  34887. + DB_88F6180A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34888. + NULL,
  34889. + DB_88F6180A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34890. + NULL,
  34891. + 0, /* ledsPolarity */
  34892. + DB_88F6180A_OE_LOW, /* gppOutEnLow */
  34893. + DB_88F6180A_OE_HIGH, /* gppOutEnHigh */
  34894. + DB_88F6180A_OE_VAL_LOW, /* gppOutValLow */
  34895. + DB_88F6180A_OE_VAL_HIGH, /* gppOutValHigh */
  34896. + 0, /* gppPolarityValLow */
  34897. + 0, /* gppPolarityValHigh */
  34898. + NULL /* pSwitchInfo */
  34899. +};
  34900. +
  34901. +
  34902. +#define RD_88F6281A_PCAC_BOARD_PCI_IF_NUM 0x0
  34903. +#define RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM 0x1
  34904. +#define RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM 0x1
  34905. +#define RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM 0x0
  34906. +#define RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM 0x1
  34907. +#define RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM 0x1
  34908. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34909. + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x1
  34910. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34911. + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x2
  34912. +#else
  34913. + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x1
  34914. +#endif
  34915. +#define RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM 0x4
  34916. +
  34917. +MV_U8 rd88f6281APcacInfoBoardDebugLedIf[] =
  34918. + {38, 39, 40, 41};
  34919. +
  34920. +MV_BOARD_MAC_INFO rd88f6281APcacInfoBoardMacInfo[] =
  34921. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  34922. + {{BOARD_MAC_SPEED_AUTO, 0x8}
  34923. + };
  34924. +
  34925. +MV_BOARD_TWSI_INFO rd88f6281APcacInfoBoardTwsiDev[] =
  34926. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  34927. + {
  34928. + {BOARD_TWSI_OTHER, 0xa7, ADDR7_BIT}
  34929. + };
  34930. +
  34931. +MV_BOARD_MPP_TYPE_INFO rd88f6281APcacInfoBoardMppTypeInfo[] =
  34932. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  34933. + };
  34934. +
  34935. +MV_DEV_CS_INFO rd88f6281APcacInfoBoardDeCsInfo[] =
  34936. + /*{deviceCS, params, devType, devWidth}*/
  34937. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34938. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  34939. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34940. + {
  34941. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  34942. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  34943. + };
  34944. +#else
  34945. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  34946. +#endif
  34947. +
  34948. +MV_BOARD_MPP_INFO rd88f6281APcacInfoBoardMppConfigValue[] =
  34949. + {{{
  34950. + RD_88F6281A_PCAC_MPP0_7,
  34951. + RD_88F6281A_PCAC_MPP8_15,
  34952. + RD_88F6281A_PCAC_MPP16_23,
  34953. + RD_88F6281A_PCAC_MPP24_31,
  34954. + RD_88F6281A_PCAC_MPP32_39,
  34955. + RD_88F6281A_PCAC_MPP40_47,
  34956. + RD_88F6281A_PCAC_MPP48_55
  34957. + }}};
  34958. +
  34959. +MV_BOARD_INFO rd88f6281APcacInfo = {
  34960. + "RD-88F6281A-PCAC", /* boardName[MAX_BOARD_NAME_LEN] */
  34961. + RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34962. + rd88f6281APcacInfoBoardMppTypeInfo,
  34963. + RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34964. + rd88f6281APcacInfoBoardMppConfigValue,
  34965. + 0, /* intsGppMaskLow */
  34966. + (1 << 3), /* intsGppMaskHigh */
  34967. + RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34968. + rd88f6281APcacInfoBoardDeCsInfo,
  34969. + RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34970. + rd88f6281APcacInfoBoardTwsiDev,
  34971. + RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34972. + rd88f6281APcacInfoBoardMacInfo,
  34973. + RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34974. + 0,
  34975. + RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34976. + NULL,
  34977. + 0, /* ledsPolarity */
  34978. + RD_88F6281A_PCAC_OE_LOW, /* gppOutEnLow */
  34979. + RD_88F6281A_PCAC_OE_HIGH, /* gppOutEnHigh */
  34980. + RD_88F6281A_PCAC_OE_VAL_LOW, /* gppOutValLow */
  34981. + RD_88F6281A_PCAC_OE_VAL_HIGH, /* gppOutValHigh */
  34982. + 0, /* gppPolarityValLow */
  34983. + 0, /* gppPolarityValHigh */
  34984. + NULL /* pSwitchInfo */
  34985. +};
  34986. +
  34987. +
  34988. +/* 6281 Sheeva Plug*/
  34989. +
  34990. +#define SHEEVA_PLUG_BOARD_PCI_IF_NUM 0x0
  34991. +#define SHEEVA_PLUG_BOARD_TWSI_DEF_NUM 0x0
  34992. +#define SHEEVA_PLUG_BOARD_MAC_INFO_NUM 0x1
  34993. +#define SHEEVA_PLUG_BOARD_GPP_INFO_NUM 0x0
  34994. +#define SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN 0x1
  34995. +#define SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM 0x1
  34996. +#define SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM 0x1
  34997. +#define SHEEVA_PLUG_BOARD_DEBUG_LED_NUM 0x1
  34998. +
  34999. +MV_U8 sheevaPlugInfoBoardDebugLedIf[] =
  35000. + {49};
  35001. +
  35002. +MV_BOARD_MAC_INFO sheevaPlugInfoBoardMacInfo[] =
  35003. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35004. + {{BOARD_MAC_SPEED_AUTO, 0x0}};
  35005. +
  35006. +MV_BOARD_TWSI_INFO sheevaPlugInfoBoardTwsiDev[] =
  35007. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  35008. + {{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};
  35009. +
  35010. +MV_BOARD_MPP_TYPE_INFO sheevaPlugInfoBoardMppTypeInfo[] =
  35011. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  35012. + };
  35013. +
  35014. +MV_DEV_CS_INFO sheevaPlugInfoBoardDeCsInfo[] =
  35015. + /*{deviceCS, params, devType, devWidth}*/
  35016. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  35017. +
  35018. +MV_BOARD_MPP_INFO sheevaPlugInfoBoardMppConfigValue[] =
  35019. + {{{
  35020. + RD_SHEEVA_PLUG_MPP0_7,
  35021. + RD_SHEEVA_PLUG_MPP8_15,
  35022. + RD_SHEEVA_PLUG_MPP16_23,
  35023. + RD_SHEEVA_PLUG_MPP24_31,
  35024. + RD_SHEEVA_PLUG_MPP32_39,
  35025. + RD_SHEEVA_PLUG_MPP40_47,
  35026. + RD_SHEEVA_PLUG_MPP48_55
  35027. + }}};
  35028. +
  35029. +MV_BOARD_INFO sheevaPlugInfo = {
  35030. + "SHEEVA PLUG", /* boardName[MAX_BOARD_NAME_LEN] */
  35031. + SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN, /* numBoardMppGroupType */
  35032. + sheevaPlugInfoBoardMppTypeInfo,
  35033. + SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35034. + sheevaPlugInfoBoardMppConfigValue,
  35035. + 0, /* intsGppMaskLow */
  35036. + 0, /* intsGppMaskHigh */
  35037. + SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35038. + sheevaPlugInfoBoardDeCsInfo,
  35039. + SHEEVA_PLUG_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35040. + sheevaPlugInfoBoardTwsiDev,
  35041. + SHEEVA_PLUG_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35042. + sheevaPlugInfoBoardMacInfo,
  35043. + SHEEVA_PLUG_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35044. + 0,
  35045. + SHEEVA_PLUG_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35046. + sheevaPlugInfoBoardDebugLedIf,
  35047. + 0, /* ledsPolarity */
  35048. + RD_SHEEVA_PLUG_OE_LOW, /* gppOutEnLow */
  35049. + RD_SHEEVA_PLUG_OE_HIGH, /* gppOutEnHigh */
  35050. + RD_SHEEVA_PLUG_OE_VAL_LOW, /* gppOutValLow */
  35051. + RD_SHEEVA_PLUG_OE_VAL_HIGH, /* gppOutValHigh */
  35052. + 0, /* gppPolarityValLow */
  35053. + 0, /* gppPolarityValHigh */
  35054. + NULL /* pSwitchInfo */
  35055. +};
  35056. +
  35057. +/* Customer specific board place holder*/
  35058. +
  35059. +#define DB_CUSTOMER_BOARD_PCI_IF_NUM 0x0
  35060. +#define DB_CUSTOMER_BOARD_TWSI_DEF_NUM 0x0
  35061. +#define DB_CUSTOMER_BOARD_MAC_INFO_NUM 0x0
  35062. +#define DB_CUSTOMER_BOARD_GPP_INFO_NUM 0x0
  35063. +#define DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN 0x0
  35064. +#define DB_CUSTOMER_BOARD_MPP_CONFIG_NUM 0x0
  35065. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35066. + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
  35067. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35068. + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
  35069. +#else
  35070. + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
  35071. +#endif
  35072. +#define DB_CUSTOMER_BOARD_DEBUG_LED_NUM 0x0
  35073. +
  35074. +MV_U8 dbCustomerInfoBoardDebugLedIf[] =
  35075. + {0};
  35076. +
  35077. +MV_BOARD_MAC_INFO dbCustomerInfoBoardMacInfo[] =
  35078. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35079. + {{BOARD_MAC_SPEED_AUTO, 0x0}};
  35080. +
  35081. +MV_BOARD_TWSI_INFO dbCustomerInfoBoardTwsiDev[] =
  35082. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  35083. + {{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};
  35084. +
  35085. +MV_BOARD_MPP_TYPE_INFO dbCustomerInfoBoardMppTypeInfo[] =
  35086. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  35087. + };
  35088. +
  35089. +MV_DEV_CS_INFO dbCustomerInfoBoardDeCsInfo[] =
  35090. + /*{deviceCS, params, devType, devWidth}*/
  35091. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35092. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  35093. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35094. + {
  35095. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  35096. + {2, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  35097. + };
  35098. +#else
  35099. + {{2, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  35100. +#endif
  35101. +
  35102. +MV_BOARD_MPP_INFO dbCustomerInfoBoardMppConfigValue[] =
  35103. + {{{
  35104. + DB_CUSTOMER_MPP0_7,
  35105. + DB_CUSTOMER_MPP8_15,
  35106. + DB_CUSTOMER_MPP16_23,
  35107. + DB_CUSTOMER_MPP24_31,
  35108. + DB_CUSTOMER_MPP32_39,
  35109. + DB_CUSTOMER_MPP40_47,
  35110. + DB_CUSTOMER_MPP48_55
  35111. + }}};
  35112. +
  35113. +MV_BOARD_INFO dbCustomerInfo = {
  35114. + "DB-CUSTOMER", /* boardName[MAX_BOARD_NAME_LEN] */
  35115. + DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN, /* numBoardMppGroupType */
  35116. + dbCustomerInfoBoardMppTypeInfo,
  35117. + DB_CUSTOMER_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35118. + dbCustomerInfoBoardMppConfigValue,
  35119. + 0, /* intsGppMaskLow */
  35120. + 0, /* intsGppMaskHigh */
  35121. + DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35122. + dbCustomerInfoBoardDeCsInfo,
  35123. + DB_CUSTOMER_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35124. + dbCustomerInfoBoardTwsiDev,
  35125. + DB_CUSTOMER_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35126. + dbCustomerInfoBoardMacInfo,
  35127. + DB_CUSTOMER_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35128. + 0,
  35129. + DB_CUSTOMER_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35130. + NULL,
  35131. + 0, /* ledsPolarity */
  35132. + DB_CUSTOMER_OE_LOW, /* gppOutEnLow */
  35133. + DB_CUSTOMER_OE_HIGH, /* gppOutEnHigh */
  35134. + DB_CUSTOMER_OE_VAL_LOW, /* gppOutValLow */
  35135. + DB_CUSTOMER_OE_VAL_HIGH, /* gppOutValHigh */
  35136. + 0, /* gppPolarityValLow */
  35137. + 0, /* gppPolarityValHigh */
  35138. + NULL /* pSwitchInfo */
  35139. +};
  35140. +
  35141. +MV_BOARD_INFO* boardInfoTbl[] = {
  35142. + &db88f6281AInfo,
  35143. + &rd88f6281AInfo,
  35144. + &db88f6192AInfo,
  35145. + &rd88f6192AInfo,
  35146. + &db88f6180AInfo,
  35147. + &db88f6190AInfo,
  35148. + &rd88f6190AInfo,
  35149. + &rd88f6281APcacInfo,
  35150. + &dbCustomerInfo,
  35151. + &sheevaPlugInfo
  35152. + };
  35153. +
  35154. +
  35155. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h
  35156. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h 1970-01-01 01:00:00.000000000 +0100
  35157. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h 2010-11-09 20:28:07.482495476 +0100
  35158. @@ -0,0 +1,262 @@
  35159. +/*******************************************************************************
  35160. +Copyright (C) Marvell International Ltd. and its affiliates
  35161. +
  35162. +This software file (the "File") is owned and distributed by Marvell
  35163. +International Ltd. and/or its affiliates ("Marvell") under the following
  35164. +alternative licensing terms. Once you have made an election to distribute the
  35165. +File under one of the following license alternatives, please (i) delete this
  35166. +introductory statement regarding license alternatives, (ii) delete the two
  35167. +license alternatives that you have not elected to use and (iii) preserve the
  35168. +Marvell copyright notice above.
  35169. +
  35170. +********************************************************************************
  35171. +Marvell Commercial License Option
  35172. +
  35173. +If you received this File from Marvell and you have entered into a commercial
  35174. +license agreement (a "Commercial License") with Marvell, the File is licensed
  35175. +to you under the terms of the applicable Commercial License.
  35176. +
  35177. +********************************************************************************
  35178. +Marvell GPL License Option
  35179. +
  35180. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35181. +modify this File in accordance with the terms and conditions of the General
  35182. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  35183. +available along with the File in the license.txt file or by writing to the Free
  35184. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  35185. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  35186. +
  35187. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  35188. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  35189. +DISCLAIMED. The GPL License provides additional details about this warranty
  35190. +disclaimer.
  35191. +********************************************************************************
  35192. +Marvell BSD License Option
  35193. +
  35194. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35195. +modify this File under the following licensing terms.
  35196. +Redistribution and use in source and binary forms, with or without modification,
  35197. +are permitted provided that the following conditions are met:
  35198. +
  35199. + * Redistributions of source code must retain the above copyright notice,
  35200. + this list of conditions and the following disclaimer.
  35201. +
  35202. + * Redistributions in binary form must reproduce the above copyright
  35203. + notice, this list of conditions and the following disclaimer in the
  35204. + documentation and/or other materials provided with the distribution.
  35205. +
  35206. + * Neither the name of Marvell nor the names of its contributors may be
  35207. + used to endorse or promote products derived from this software without
  35208. + specific prior written permission.
  35209. +
  35210. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  35211. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  35212. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35213. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  35214. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  35215. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35216. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  35217. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35218. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35219. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35220. +
  35221. +*******************************************************************************/
  35222. +
  35223. +
  35224. +#ifndef __INCmvBoardEnvSpech
  35225. +#define __INCmvBoardEnvSpech
  35226. +
  35227. +#include "mvSysHwConfig.h"
  35228. +
  35229. +
  35230. +/* For future use */
  35231. +#define BD_ID_DATA_START_OFFS 0x0
  35232. +#define BD_DETECT_SEQ_OFFS 0x0
  35233. +#define BD_SYS_NUM_OFFS 0x4
  35234. +#define BD_NAME_OFFS 0x8
  35235. +
  35236. +/* I2C bus addresses */
  35237. +#define MV_BOARD_CTRL_I2C_ADDR 0x0 /* Controller slave addr */
  35238. +#define MV_BOARD_CTRL_I2C_ADDR_TYPE ADDR7_BIT
  35239. +#define MV_BOARD_DIMM0_I2C_ADDR 0x56
  35240. +#define MV_BOARD_DIMM0_I2C_ADDR_TYPE ADDR7_BIT
  35241. +#define MV_BOARD_DIMM1_I2C_ADDR 0x54
  35242. +#define MV_BOARD_DIMM1_I2C_ADDR_TYPE ADDR7_BIT
  35243. +#define MV_BOARD_EEPROM_I2C_ADDR 0x51
  35244. +#define MV_BOARD_EEPROM_I2C_ADDR_TYPE ADDR7_BIT
  35245. +#define MV_BOARD_MAIN_EEPROM_I2C_ADDR 0x50
  35246. +#define MV_BOARD_MAIN_EEPROM_I2C_ADDR_TYPE ADDR7_BIT
  35247. +#define MV_BOARD_MUX_I2C_ADDR_ENTRY 0x2
  35248. +#define MV_BOARD_DIMM_I2C_CHANNEL 0x0
  35249. +
  35250. +#define BOOT_FLASH_INDEX 0
  35251. +#define MAIN_FLASH_INDEX 1
  35252. +
  35253. +#define BOARD_ETH_START_PORT_NUM 0
  35254. +
  35255. +/* Supported clocks */
  35256. +#define MV_BOARD_TCLK_100MHZ 100000000
  35257. +#define MV_BOARD_TCLK_125MHZ 125000000
  35258. +#define MV_BOARD_TCLK_133MHZ 133333333
  35259. +#define MV_BOARD_TCLK_150MHZ 150000000
  35260. +#define MV_BOARD_TCLK_166MHZ 166666667
  35261. +#define MV_BOARD_TCLK_200MHZ 200000000
  35262. +
  35263. +#define MV_BOARD_SYSCLK_100MHZ 100000000
  35264. +#define MV_BOARD_SYSCLK_125MHZ 125000000
  35265. +#define MV_BOARD_SYSCLK_133MHZ 133333333
  35266. +#define MV_BOARD_SYSCLK_150MHZ 150000000
  35267. +#define MV_BOARD_SYSCLK_166MHZ 166666667
  35268. +#define MV_BOARD_SYSCLK_200MHZ 200000000
  35269. +#define MV_BOARD_SYSCLK_233MHZ 233333333
  35270. +#define MV_BOARD_SYSCLK_250MHZ 250000000
  35271. +#define MV_BOARD_SYSCLK_267MHZ 266666667
  35272. +#define MV_BOARD_SYSCLK_300MHZ 300000000
  35273. +#define MV_BOARD_SYSCLK_333MHZ 333333334
  35274. +#define MV_BOARD_SYSCLK_400MHZ 400000000
  35275. +
  35276. +#define MV_BOARD_REFCLK_25MHZ 25000000
  35277. +
  35278. +/* Board specific */
  35279. +/* =============================== */
  35280. +
  35281. +/* boards ID numbers */
  35282. +
  35283. +#define BOARD_ID_BASE 0x0
  35284. +
  35285. +/* New board ID numbers */
  35286. +#define DB_88F6281A_BP_ID (BOARD_ID_BASE)
  35287. +#define DB_88F6281_BP_MLL_ID 1680
  35288. +#define RD_88F6281A_ID (BOARD_ID_BASE+0x1)
  35289. +#define RD_88F6281_MLL_ID 1682
  35290. +#define DB_88F6192A_BP_ID (BOARD_ID_BASE+0x2)
  35291. +#define RD_88F6192A_ID (BOARD_ID_BASE+0x3)
  35292. +#define RD_88F6192_MLL_ID 1681
  35293. +#define DB_88F6180A_BP_ID (BOARD_ID_BASE+0x4)
  35294. +#define DB_88F6190A_BP_ID (BOARD_ID_BASE+0x5)
  35295. +#define RD_88F6190A_ID (BOARD_ID_BASE+0x6)
  35296. +#define RD_88F6281A_PCAC_ID (BOARD_ID_BASE+0x7)
  35297. +#define DB_CUSTOMER_ID (BOARD_ID_BASE+0x8)
  35298. +#define SHEEVA_PLUG_ID (BOARD_ID_BASE+0x9)
  35299. +#define MV_MAX_BOARD_ID (SHEEVA_PLUG_ID + 1)
  35300. +
  35301. +/* DB-88F6281A-BP */
  35302. +#if defined(MV_NAND)
  35303. + #define DB_88F6281A_MPP0_7 0x21111111
  35304. +#else
  35305. + #define DB_88F6281A_MPP0_7 0x21112220
  35306. +#endif
  35307. +#define DB_88F6281A_MPP8_15 0x11113311
  35308. +#define DB_88F6281A_MPP16_23 0x00551111
  35309. +#define DB_88F6281A_MPP24_31 0x00000000
  35310. +#define DB_88F6281A_MPP32_39 0x00000000
  35311. +#define DB_88F6281A_MPP40_47 0x00000000
  35312. +#define DB_88F6281A_MPP48_55 0x00000000
  35313. +#define DB_88F6281A_OE_LOW 0x0
  35314. +#if defined(MV_TDM_5CHANNELS)
  35315. + #define DB_88F6281A_OE_HIGH (BIT6)
  35316. +#else
  35317. +#define DB_88F6281A_OE_HIGH 0x0
  35318. +#endif
  35319. +#define DB_88F6281A_OE_VAL_LOW 0x0
  35320. +#define DB_88F6281A_OE_VAL_HIGH 0x0
  35321. +
  35322. +/* RD-88F6281A */
  35323. +#if defined(MV_NAND)
  35324. + #define RD_88F6281A_MPP0_7 0x21111111
  35325. +#else
  35326. + #define RD_88F6281A_MPP0_7 0x21112220
  35327. +#endif
  35328. +#define RD_88F6281A_MPP8_15 0x11113311
  35329. +#define RD_88F6281A_MPP16_23 0x33331111
  35330. +#define RD_88F6281A_MPP24_31 0x33003333
  35331. +#define RD_88F6281A_MPP32_39 0x20440533
  35332. +#define RD_88F6281A_MPP40_47 0x22202222
  35333. +#define RD_88F6281A_MPP48_55 0x00000002
  35334. +#define RD_88F6281A_OE_LOW (BIT28 | BIT29)
  35335. +#define RD_88F6281A_OE_HIGH (BIT3 | BIT6 | BIT17)
  35336. +#define RD_88F6281A_OE_VAL_LOW 0x0
  35337. +#define RD_88F6281A_OE_VAL_HIGH 0x0
  35338. +
  35339. +/* DB-88F6192A-BP */
  35340. +#if defined(MV_NAND)
  35341. + #define DB_88F6192A_MPP0_7 0x21111111
  35342. +#else
  35343. + #define DB_88F6192A_MPP0_7 0x21112220
  35344. +#endif
  35345. +#define DB_88F6192A_MPP8_15 0x11113311
  35346. +#define DB_88F6192A_MPP16_23 0x00501111
  35347. +#define DB_88F6192A_MPP24_31 0x00000000
  35348. +#define DB_88F6192A_MPP32_35 0x00000000
  35349. +#define DB_88F6192A_OE_LOW (BIT22 | BIT23)
  35350. +#define DB_88F6192A_OE_HIGH 0x0
  35351. +#define DB_88F6192A_OE_VAL_LOW 0x0
  35352. +#define DB_88F6192A_OE_VAL_HIGH 0x0
  35353. +
  35354. +/* RD-88F6192A */
  35355. +#define RD_88F6192A_MPP0_7 0x01222222
  35356. +#define RD_88F6192A_MPP8_15 0x00000011
  35357. +#define RD_88F6192A_MPP16_23 0x05550000
  35358. +#define RD_88F6192A_MPP24_31 0x0
  35359. +#define RD_88F6192A_MPP32_35 0x0
  35360. +#define RD_88F6192A_OE_LOW (BIT11 | BIT14 | BIT24 | BIT25 | BIT26 | BIT27 | BIT30 | BIT31)
  35361. +#define RD_88F6192A_OE_HIGH (BIT0 | BIT2)
  35362. +#define RD_88F6192A_OE_VAL_LOW 0x18400
  35363. +#define RD_88F6192A_OE_VAL_HIGH 0x8
  35364. +
  35365. +/* DB-88F6180A-BP */
  35366. +#if defined(MV_NAND)
  35367. + #define DB_88F6180A_MPP0_7 0x21111111
  35368. +#else
  35369. + #define DB_88F6180A_MPP0_7 0x01112222
  35370. +#endif
  35371. +#define DB_88F6180A_MPP8_15 0x11113311
  35372. +#define DB_88F6180A_MPP16_23 0x00001111
  35373. +#define DB_88F6180A_MPP24_31 0x0
  35374. +#define DB_88F6180A_MPP32_39 0x4444c000
  35375. +#define DB_88F6180A_MPP40_44 0x00044444
  35376. +#define DB_88F6180A_OE_LOW 0x0
  35377. +#define DB_88F6180A_OE_HIGH 0x0
  35378. +#define DB_88F6180A_OE_VAL_LOW 0x0
  35379. +#define DB_88F6180A_OE_VAL_HIGH 0x0
  35380. +
  35381. +/* RD-88F6281A_PCAC */
  35382. +#define RD_88F6281A_PCAC_MPP0_7 0x21111111
  35383. +#define RD_88F6281A_PCAC_MPP8_15 0x00003311
  35384. +#define RD_88F6281A_PCAC_MPP16_23 0x00001100
  35385. +#define RD_88F6281A_PCAC_MPP24_31 0x00000000
  35386. +#define RD_88F6281A_PCAC_MPP32_39 0x00000000
  35387. +#define RD_88F6281A_PCAC_MPP40_47 0x00000000
  35388. +#define RD_88F6281A_PCAC_MPP48_55 0x00000000
  35389. +#define RD_88F6281A_PCAC_OE_LOW 0x0
  35390. +#define RD_88F6281A_PCAC_OE_HIGH 0x0
  35391. +#define RD_88F6281A_PCAC_OE_VAL_LOW 0x0
  35392. +#define RD_88F6281A_PCAC_OE_VAL_HIGH 0x0
  35393. +
  35394. +/* SHEEVA PLUG */
  35395. +#define RD_SHEEVA_PLUG_MPP0_7 0x01111111
  35396. +#define RD_SHEEVA_PLUG_MPP8_15 0x11113322
  35397. +#define RD_SHEEVA_PLUG_MPP16_23 0x00001111
  35398. +#define RD_SHEEVA_PLUG_MPP24_31 0x00100000
  35399. +#define RD_SHEEVA_PLUG_MPP32_39 0x00000000
  35400. +#define RD_SHEEVA_PLUG_MPP40_47 0x00000000
  35401. +#define RD_SHEEVA_PLUG_MPP48_55 0x00000000
  35402. +#define RD_SHEEVA_PLUG_OE_LOW 0x0
  35403. +#define RD_SHEEVA_PLUG_OE_HIGH 0x0
  35404. +#define RD_SHEEVA_PLUG_OE_VAL_LOW (BIT29)
  35405. +#define RD_SHEEVA_PLUG_OE_VAL_HIGH ((~(BIT17 | BIT16 | BIT15)) | BIT14)
  35406. +
  35407. +/* DB-CUSTOMER */
  35408. +#define DB_CUSTOMER_MPP0_7 0x21111111
  35409. +#define DB_CUSTOMER_MPP8_15 0x00003311
  35410. +#define DB_CUSTOMER_MPP16_23 0x00001100
  35411. +#define DB_CUSTOMER_MPP24_31 0x00000000
  35412. +#define DB_CUSTOMER_MPP32_39 0x00000000
  35413. +#define DB_CUSTOMER_MPP40_47 0x00000000
  35414. +#define DB_CUSTOMER_MPP48_55 0x00000000
  35415. +#define DB_CUSTOMER_OE_LOW 0x0
  35416. +#define DB_CUSTOMER_OE_HIGH (~((BIT6) | (BIT7) | (BIT8) | (BIT9)))
  35417. +#define DB_CUSTOMER_OE_VAL_LOW 0x0
  35418. +#define DB_CUSTOMER_OE_VAL_HIGH 0x0
  35419. +
  35420. +#endif /* __INCmvBoardEnvSpech */
  35421. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c
  35422. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c 1970-01-01 01:00:00.000000000 +0100
  35423. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c 2010-11-09 20:28:07.522495500 +0100
  35424. @@ -0,0 +1,320 @@
  35425. +/*******************************************************************************
  35426. +Copyright (C) Marvell International Ltd. and its affiliates
  35427. +
  35428. +This software file (the "File") is owned and distributed by Marvell
  35429. +International Ltd. and/or its affiliates ("Marvell") under the following
  35430. +alternative licensing terms. Once you have made an election to distribute the
  35431. +File under one of the following license alternatives, please (i) delete this
  35432. +introductory statement regarding license alternatives, (ii) delete the two
  35433. +license alternatives that you have not elected to use and (iii) preserve the
  35434. +Marvell copyright notice above.
  35435. +
  35436. +********************************************************************************
  35437. +Marvell Commercial License Option
  35438. +
  35439. +If you received this File from Marvell and you have entered into a commercial
  35440. +license agreement (a "Commercial License") with Marvell, the File is licensed
  35441. +to you under the terms of the applicable Commercial License.
  35442. +
  35443. +********************************************************************************
  35444. +Marvell GPL License Option
  35445. +
  35446. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35447. +modify this File in accordance with the terms and conditions of the General
  35448. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  35449. +available along with the File in the license.txt file or by writing to the Free
  35450. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  35451. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  35452. +
  35453. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  35454. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  35455. +DISCLAIMED. The GPL License provides additional details about this warranty
  35456. +disclaimer.
  35457. +********************************************************************************
  35458. +Marvell BSD License Option
  35459. +
  35460. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35461. +modify this File under the following licensing terms.
  35462. +Redistribution and use in source and binary forms, with or without modification,
  35463. +are permitted provided that the following conditions are met:
  35464. +
  35465. + * Redistributions of source code must retain the above copyright notice,
  35466. + this list of conditions and the following disclaimer.
  35467. +
  35468. + * Redistributions in binary form must reproduce the above copyright
  35469. + notice, this list of conditions and the following disclaimer in the
  35470. + documentation and/or other materials provided with the distribution.
  35471. +
  35472. + * Neither the name of Marvell nor the names of its contributors may be
  35473. + used to endorse or promote products derived from this software without
  35474. + specific prior written permission.
  35475. +
  35476. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  35477. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  35478. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35479. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  35480. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  35481. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35482. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  35483. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35484. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35485. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35486. +
  35487. +*******************************************************************************/
  35488. +
  35489. +
  35490. +#include "cpu/mvCpu.h"
  35491. +#include "ctrlEnv/mvCtrlEnvLib.h"
  35492. +#include "ctrlEnv/mvCtrlEnvRegs.h"
  35493. +#include "ctrlEnv/sys/mvCpuIfRegs.h"
  35494. +
  35495. +/* defines */
  35496. +#ifdef MV_DEBUG
  35497. + #define DB(x) x
  35498. +#else
  35499. + #define DB(x)
  35500. +#endif
  35501. +
  35502. +/* locals */
  35503. +
  35504. +/*******************************************************************************
  35505. +* mvCpuPclkGet - Get the CPU pClk (pipe clock)
  35506. +*
  35507. +* DESCRIPTION:
  35508. +* This routine extract the CPU core clock.
  35509. +*
  35510. +* INPUT:
  35511. +* None.
  35512. +*
  35513. +* OUTPUT:
  35514. +* None.
  35515. +*
  35516. +* RETURN:
  35517. +* 32bit clock cycles in MHertz.
  35518. +*
  35519. +*******************************************************************************/
  35520. +/* 6180 have different clk reset sampling */
  35521. +
  35522. +static MV_U32 mvCpu6180PclkGet(MV_VOID)
  35523. +{
  35524. + MV_U32 tmpPClkRate=0;
  35525. + MV_CPU_ARM_CLK cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
  35526. +
  35527. + tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  35528. + tmpPClkRate = tmpPClkRate & MSAR_CPUCLCK_MASK_6180;
  35529. + tmpPClkRate = tmpPClkRate >> MSAR_CPUCLCK_OFFS_6180;
  35530. +
  35531. + tmpPClkRate = cpu6180_ddr_l2_CLK[tmpPClkRate].cpuClk;
  35532. +
  35533. + return tmpPClkRate;
  35534. +}
  35535. +
  35536. +
  35537. +MV_U32 mvCpuPclkGet(MV_VOID)
  35538. +{
  35539. +#if defined(PCLCK_AUTO_DETECT)
  35540. + MV_U32 tmpPClkRate=0;
  35541. + MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;
  35542. +
  35543. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  35544. + return mvCpu6180PclkGet();
  35545. +
  35546. + tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  35547. + tmpPClkRate = MSAR_CPUCLCK_EXTRACT(tmpPClkRate);
  35548. + tmpPClkRate = cpuCLK[tmpPClkRate];
  35549. +
  35550. + return tmpPClkRate;
  35551. +#else
  35552. + return MV_DEFAULT_PCLK
  35553. +#endif
  35554. +}
  35555. +
  35556. +/*******************************************************************************
  35557. +* mvCpuL2ClkGet - Get the CPU L2 (CPU bus clock)
  35558. +*
  35559. +* DESCRIPTION:
  35560. +* This routine extract the CPU L2 clock.
  35561. +*
  35562. +* RETURN:
  35563. +* 32bit clock cycles in Hertz.
  35564. +*
  35565. +*******************************************************************************/
  35566. +static MV_U32 mvCpu6180L2ClkGet(MV_VOID)
  35567. +{
  35568. + MV_U32 L2ClkRate=0;
  35569. + MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
  35570. +
  35571. + L2ClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  35572. + L2ClkRate = L2ClkRate & MSAR_CPUCLCK_MASK_6180;
  35573. + L2ClkRate = L2ClkRate >> MSAR_CPUCLCK_OFFS_6180;
  35574. +
  35575. + L2ClkRate = _cpu6180_ddr_l2_CLK[L2ClkRate].l2Clk;
  35576. +
  35577. + return L2ClkRate;
  35578. +
  35579. +}
  35580. +
  35581. +MV_U32 mvCpuL2ClkGet(MV_VOID)
  35582. +{
  35583. +#ifdef L2CLK_AUTO_DETECT
  35584. + MV_U32 L2ClkRate, tmp, pClkRate, indexL2Rtio;
  35585. + MV_U32 L2Rtio[][2] = MV_L2_CLCK_RTIO_TBL;
  35586. +
  35587. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  35588. + return mvCpu6180L2ClkGet();
  35589. +
  35590. + pClkRate = mvCpuPclkGet();
  35591. +
  35592. + tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  35593. + indexL2Rtio = MSAR_L2CLCK_EXTRACT(tmp);
  35594. +
  35595. + L2ClkRate = ((pClkRate * L2Rtio[indexL2Rtio][1]) / L2Rtio[indexL2Rtio][0]);
  35596. +
  35597. + return L2ClkRate;
  35598. +#else
  35599. + return MV_BOARD_DEFAULT_L2CLK;
  35600. +#endif
  35601. +}
  35602. +
  35603. +
  35604. +/*******************************************************************************
  35605. +* mvCpuNameGet - Get CPU name
  35606. +*
  35607. +* DESCRIPTION:
  35608. +* This function returns a string describing the CPU model and revision.
  35609. +*
  35610. +* INPUT:
  35611. +* None.
  35612. +*
  35613. +* OUTPUT:
  35614. +* pNameBuff - Buffer to contain board name string. Minimum size 32 chars.
  35615. +*
  35616. +* RETURN:
  35617. +* None.
  35618. +*******************************************************************************/
  35619. +MV_VOID mvCpuNameGet(char *pNameBuff)
  35620. +{
  35621. + MV_U32 cpuModel;
  35622. +
  35623. + cpuModel = mvOsCpuPartGet();
  35624. +
  35625. + /* The CPU module is indicated in the Processor Version Register (PVR) */
  35626. + switch(cpuModel)
  35627. + {
  35628. + case CPU_PART_MRVL131:
  35629. + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "Marvell Feroceon",mvOsCpuRevGet());
  35630. + break;
  35631. + case CPU_PART_ARM926:
  35632. + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM926",mvOsCpuRevGet());
  35633. + break;
  35634. + case CPU_PART_ARM946:
  35635. + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM946",mvOsCpuRevGet());
  35636. + break;
  35637. + default:
  35638. + mvOsSPrintf(pNameBuff,"??? (0x%04x) (Rev %d)",cpuModel,mvOsCpuRevGet());
  35639. + break;
  35640. + } /* switch */
  35641. +
  35642. + return;
  35643. +}
  35644. +
  35645. +
  35646. +#define MV_PROC_STR_SIZE 50
  35647. +
  35648. +static void mvCpuIfGetL2EccMode(MV_8 *buf)
  35649. +{
  35650. + MV_U32 regVal = MV_REG_READ(CPU_L2_CONFIG_REG);
  35651. + if (regVal & BIT2)
  35652. + mvOsSPrintf(buf, "L2 ECC Enabled");
  35653. + else
  35654. + mvOsSPrintf(buf, "L2 ECC Disabled");
  35655. +}
  35656. +
  35657. +static void mvCpuIfGetL2Mode(MV_8 *buf)
  35658. +{
  35659. + MV_U32 regVal = 0;
  35660. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  35661. + if (regVal & BIT22)
  35662. + mvOsSPrintf(buf, "L2 Enabled");
  35663. + else
  35664. + mvOsSPrintf(buf, "L2 Disabled");
  35665. +}
  35666. +
  35667. +static void mvCpuIfGetL2PrefetchMode(MV_8 *buf)
  35668. +{
  35669. + MV_U32 regVal = 0;
  35670. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  35671. + if (regVal & BIT24)
  35672. + mvOsSPrintf(buf, "L2 Prefetch Disabled");
  35673. + else
  35674. + mvOsSPrintf(buf, "L2 Prefetch Enabled");
  35675. +}
  35676. +
  35677. +static void mvCpuIfGetWriteAllocMode(MV_8 *buf)
  35678. +{
  35679. + MV_U32 regVal = 0;
  35680. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  35681. + if (regVal & BIT28)
  35682. + mvOsSPrintf(buf, "Write Allocate Enabled");
  35683. + else
  35684. + mvOsSPrintf(buf, "Write Allocate Disabled");
  35685. +}
  35686. +
  35687. +static void mvCpuIfGetCpuStreamMode(MV_8 *buf)
  35688. +{
  35689. + MV_U32 regVal = 0;
  35690. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  35691. + if (regVal & BIT29)
  35692. + mvOsSPrintf(buf, "CPU Streaming Enabled");
  35693. + else
  35694. + mvOsSPrintf(buf, "CPU Streaming Disabled");
  35695. +}
  35696. +
  35697. +static void mvCpuIfPrintCpuRegs(void)
  35698. +{
  35699. + MV_U32 regVal = 0;
  35700. +
  35701. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  35702. + mvOsPrintf("Extra Feature Reg = 0x%x\n",regVal);
  35703. +
  35704. + __asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (regVal)); /* Read Control register */
  35705. + mvOsPrintf("Control Reg = 0x%x\n",regVal);
  35706. +
  35707. + __asm volatile ("mrc p15, 0, %0, c0, c0, 0" : "=r" (regVal)); /* Read ID Code register */
  35708. + mvOsPrintf("ID Code Reg = 0x%x\n",regVal);
  35709. +
  35710. + __asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r" (regVal)); /* Read Cache Type register */
  35711. + mvOsPrintf("Cache Type Reg = 0x%x\n",regVal);
  35712. +
  35713. +}
  35714. +
  35715. +MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index)
  35716. +{
  35717. + MV_U32 count = 0;
  35718. +
  35719. + MV_8 L2_ECC_str[MV_PROC_STR_SIZE];
  35720. + MV_8 L2_En_str[MV_PROC_STR_SIZE];
  35721. + MV_8 L2_Prefetch_str[MV_PROC_STR_SIZE];
  35722. + MV_8 Write_Alloc_str[MV_PROC_STR_SIZE];
  35723. + MV_8 Cpu_Stream_str[MV_PROC_STR_SIZE];
  35724. +
  35725. + mvCpuIfGetL2Mode(L2_En_str);
  35726. + mvCpuIfGetL2EccMode(L2_ECC_str);
  35727. + mvCpuIfGetL2PrefetchMode(L2_Prefetch_str);
  35728. + mvCpuIfGetWriteAllocMode(Write_Alloc_str);
  35729. + mvCpuIfGetCpuStreamMode(Cpu_Stream_str);
  35730. + mvCpuIfPrintCpuRegs();
  35731. +
  35732. + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_En_str);
  35733. + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_ECC_str);
  35734. + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_Prefetch_str);
  35735. + count += mvOsSPrintf(buffer + count + index, "%s\n", Write_Alloc_str);
  35736. + count += mvOsSPrintf(buffer + count + index, "%s\n", Cpu_Stream_str);
  35737. + return count;
  35738. +}
  35739. +
  35740. +MV_U32 whoAmI(MV_VOID)
  35741. +{
  35742. + return 0;
  35743. +}
  35744. +
  35745. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h
  35746. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h 1970-01-01 01:00:00.000000000 +0100
  35747. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h 2010-11-09 20:28:07.562495452 +0100
  35748. @@ -0,0 +1,99 @@
  35749. +/*******************************************************************************
  35750. +Copyright (C) Marvell International Ltd. and its affiliates
  35751. +
  35752. +This software file (the "File") is owned and distributed by Marvell
  35753. +International Ltd. and/or its affiliates ("Marvell") under the following
  35754. +alternative licensing terms. Once you have made an election to distribute the
  35755. +File under one of the following license alternatives, please (i) delete this
  35756. +introductory statement regarding license alternatives, (ii) delete the two
  35757. +license alternatives that you have not elected to use and (iii) preserve the
  35758. +Marvell copyright notice above.
  35759. +
  35760. +********************************************************************************
  35761. +Marvell Commercial License Option
  35762. +
  35763. +If you received this File from Marvell and you have entered into a commercial
  35764. +license agreement (a "Commercial License") with Marvell, the File is licensed
  35765. +to you under the terms of the applicable Commercial License.
  35766. +
  35767. +********************************************************************************
  35768. +Marvell GPL License Option
  35769. +
  35770. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35771. +modify this File in accordance with the terms and conditions of the General
  35772. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  35773. +available along with the File in the license.txt file or by writing to the Free
  35774. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  35775. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  35776. +
  35777. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  35778. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  35779. +DISCLAIMED. The GPL License provides additional details about this warranty
  35780. +disclaimer.
  35781. +********************************************************************************
  35782. +Marvell BSD License Option
  35783. +
  35784. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35785. +modify this File under the following licensing terms.
  35786. +Redistribution and use in source and binary forms, with or without modification,
  35787. +are permitted provided that the following conditions are met:
  35788. +
  35789. + * Redistributions of source code must retain the above copyright notice,
  35790. + this list of conditions and the following disclaimer.
  35791. +
  35792. + * Redistributions in binary form must reproduce the above copyright
  35793. + notice, this list of conditions and the following disclaimer in the
  35794. + documentation and/or other materials provided with the distribution.
  35795. +
  35796. + * Neither the name of Marvell nor the names of its contributors may be
  35797. + used to endorse or promote products derived from this software without
  35798. + specific prior written permission.
  35799. +
  35800. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  35801. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  35802. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35803. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  35804. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  35805. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35806. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  35807. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35808. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35809. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35810. +
  35811. +*******************************************************************************/
  35812. +
  35813. +
  35814. +#ifndef __INCmvCpuh
  35815. +#define __INCmvCpuh
  35816. +
  35817. +#include "mvCommon.h"
  35818. +#include "mvOs.h"
  35819. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  35820. +
  35821. +/* defines */
  35822. +#define CPU_PART_MRVL131 0x131
  35823. +#define CPU_PART_ARM926 0x926
  35824. +#define CPU_PART_ARM946 0x946
  35825. +#define MV_CPU_ARM_CLK_ELM_SIZE 12
  35826. +#define MV_CPU_ARM_CLK_RATIO_OFF 8
  35827. +#define MV_CPU_ARM_CLK_DDR_OFF 4
  35828. +
  35829. +#ifndef MV_ASMLANGUAGE
  35830. +typedef struct _mvCpuArmClk
  35831. +{
  35832. + MV_U32 cpuClk; /* CPU clock in MHz */
  35833. + MV_U32 ddrClk; /* DDR clock in MHz */
  35834. + MV_U32 l2Clk; /* CPU DDR clock ratio */
  35835. +
  35836. +}MV_CPU_ARM_CLK;
  35837. +
  35838. +MV_U32 mvCpuPclkGet(MV_VOID);
  35839. +MV_VOID mvCpuNameGet(char *pNameBuff);
  35840. +MV_U32 mvCpuL2ClkGet(MV_VOID);
  35841. +MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index);
  35842. +MV_U32 whoAmI(MV_VOID);
  35843. +
  35844. +#endif /* MV_ASMLANGUAGE */
  35845. +
  35846. +
  35847. +#endif /* __INCmvCpuh */
  35848. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c
  35849. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c 1970-01-01 01:00:00.000000000 +0100
  35850. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c 2010-11-09 20:28:07.602495466 +0100
  35851. @@ -0,0 +1,296 @@
  35852. +/*******************************************************************************
  35853. +Copyright (C) Marvell International Ltd. and its affiliates
  35854. +
  35855. +This software file (the "File") is owned and distributed by Marvell
  35856. +International Ltd. and/or its affiliates ("Marvell") under the following
  35857. +alternative licensing terms. Once you have made an election to distribute the
  35858. +File under one of the following license alternatives, please (i) delete this
  35859. +introductory statement regarding license alternatives, (ii) delete the two
  35860. +license alternatives that you have not elected to use and (iii) preserve the
  35861. +Marvell copyright notice above.
  35862. +
  35863. +********************************************************************************
  35864. +Marvell Commercial License Option
  35865. +
  35866. +If you received this File from Marvell and you have entered into a commercial
  35867. +license agreement (a "Commercial License") with Marvell, the File is licensed
  35868. +to you under the terms of the applicable Commercial License.
  35869. +
  35870. +********************************************************************************
  35871. +Marvell GPL License Option
  35872. +
  35873. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35874. +modify this File in accordance with the terms and conditions of the General
  35875. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  35876. +available along with the File in the license.txt file or by writing to the Free
  35877. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  35878. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  35879. +
  35880. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  35881. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  35882. +DISCLAIMED. The GPL License provides additional details about this warranty
  35883. +disclaimer.
  35884. +********************************************************************************
  35885. +Marvell BSD License Option
  35886. +
  35887. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35888. +modify this File under the following licensing terms.
  35889. +Redistribution and use in source and binary forms, with or without modification,
  35890. +are permitted provided that the following conditions are met:
  35891. +
  35892. + * Redistributions of source code must retain the above copyright notice,
  35893. + this list of conditions and the following disclaimer.
  35894. +
  35895. + * Redistributions in binary form must reproduce the above copyright
  35896. + notice, this list of conditions and the following disclaimer in the
  35897. + documentation and/or other materials provided with the distribution.
  35898. +
  35899. + * Neither the name of Marvell nor the names of its contributors may be
  35900. + used to endorse or promote products derived from this software without
  35901. + specific prior written permission.
  35902. +
  35903. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  35904. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  35905. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35906. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  35907. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  35908. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35909. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  35910. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35911. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35912. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35913. +
  35914. +*******************************************************************************/
  35915. +
  35916. +/*******************************************************************************
  35917. +* mvCtrlEnvAddrDec.h - Marvell controller address decode library
  35918. +*
  35919. +* DESCRIPTION:
  35920. +*
  35921. +* DEPENDENCIES:
  35922. +* None.
  35923. +*
  35924. +*******************************************************************************/
  35925. +
  35926. +/* includes */
  35927. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  35928. +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
  35929. +#include "ddr2/mvDramIfRegs.h"
  35930. +#include "pex/mvPexRegs.h"
  35931. +
  35932. +#define MV_DEBUG
  35933. +
  35934. +/* defines */
  35935. +#ifdef MV_DEBUG
  35936. + #define DB(x) x
  35937. +#else
  35938. + #define DB(x)
  35939. +#endif
  35940. +
  35941. +/* Default Attributes array */
  35942. +MV_TARGET_ATTRIB mvTargetDefaultsArray[] = TARGETS_DEF_ARRAY;
  35943. +extern MV_TARGET *sampleAtResetTargetArray;
  35944. +/* Dram\AHBToMbus\PEX share regsiter */
  35945. +
  35946. +#define CTRL_DEC_BASE_OFFS 16
  35947. +#define CTRL_DEC_BASE_MASK (0xffff << CTRL_DEC_BASE_OFFS)
  35948. +#define CTRL_DEC_BASE_ALIGNMENT 0x10000
  35949. +
  35950. +#define CTRL_DEC_SIZE_OFFS 16
  35951. +#define CTRL_DEC_SIZE_MASK (0xffff << CTRL_DEC_SIZE_OFFS)
  35952. +#define CTRL_DEC_SIZE_ALIGNMENT 0x10000
  35953. +
  35954. +#define CTRL_DEC_WIN_EN BIT0
  35955. +
  35956. +
  35957. +
  35958. +/*******************************************************************************
  35959. +* mvCtrlAddrDecToReg - Get address decode register format values
  35960. +*
  35961. +* DESCRIPTION:
  35962. +*
  35963. +* INPUT:
  35964. +*
  35965. +* OUTPUT:
  35966. +*
  35967. +* RETURN:
  35968. +*
  35969. +*******************************************************************************/
  35970. +MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin, MV_DEC_REGS *pAddrDecRegs)
  35971. +{
  35972. +
  35973. + MV_U32 baseToReg=0 , sizeToReg=0;
  35974. +
  35975. + /* BaseLow[31:16] => base register [31:16] */
  35976. + baseToReg = pAddrDecWin->baseLow & CTRL_DEC_BASE_MASK;
  35977. +
  35978. + /* Write to address decode Base Address Register */
  35979. + pAddrDecRegs->baseReg &= ~CTRL_DEC_BASE_MASK;
  35980. + pAddrDecRegs->baseReg |= baseToReg;
  35981. +
  35982. + /* Get size register value according to window size */
  35983. + sizeToReg = ctrlSizeToReg(pAddrDecWin->size, CTRL_DEC_SIZE_ALIGNMENT);
  35984. +
  35985. + /* Size parameter validity check. */
  35986. + if (-1 == sizeToReg)
  35987. + {
  35988. + return MV_BAD_PARAM;
  35989. + }
  35990. +
  35991. + /* set size */
  35992. + pAddrDecRegs->sizeReg &= ~CTRL_DEC_SIZE_MASK;
  35993. + pAddrDecRegs->sizeReg |= (sizeToReg << CTRL_DEC_SIZE_OFFS);
  35994. +
  35995. +
  35996. + return MV_OK;
  35997. +
  35998. +}
  35999. +
  36000. +/*******************************************************************************
  36001. +* mvCtrlRegToAddrDec - Extract address decode struct from registers.
  36002. +*
  36003. +* DESCRIPTION:
  36004. +* This function extract address decode struct from address decode
  36005. +* registers given as parameters.
  36006. +*
  36007. +* INPUT:
  36008. +* pAddrDecRegs - Address decode register struct.
  36009. +*
  36010. +* OUTPUT:
  36011. +* pAddrDecWin - Target window data structure.
  36012. +*
  36013. +* RETURN:
  36014. +* MV_BAD_PARAM if address decode registers data is invalid.
  36015. +*
  36016. +*******************************************************************************/
  36017. +MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs, MV_ADDR_WIN *pAddrDecWin)
  36018. +{
  36019. + MV_U32 sizeRegVal;
  36020. +
  36021. + sizeRegVal = (pAddrDecRegs->sizeReg & CTRL_DEC_SIZE_MASK) >>
  36022. + CTRL_DEC_SIZE_OFFS;
  36023. +
  36024. + pAddrDecWin->size = ctrlRegToSize(sizeRegVal, CTRL_DEC_SIZE_ALIGNMENT);
  36025. +
  36026. +
  36027. + /* Extract base address */
  36028. + /* Base register [31:16] ==> baseLow[31:16] */
  36029. + pAddrDecWin->baseLow = pAddrDecRegs->baseReg & CTRL_DEC_BASE_MASK;
  36030. +
  36031. + pAddrDecWin->baseHigh = 0;
  36032. +
  36033. + return MV_OK;
  36034. +
  36035. +}
  36036. +
  36037. +/*******************************************************************************
  36038. +* mvCtrlAttribGet -
  36039. +*
  36040. +* DESCRIPTION:
  36041. +*
  36042. +* INPUT:
  36043. +*
  36044. +* OUTPUT:
  36045. +*
  36046. +* RETURN:
  36047. +*
  36048. +*******************************************************************************/
  36049. +
  36050. +MV_STATUS mvCtrlAttribGet(MV_TARGET target,
  36051. + MV_TARGET_ATTRIB *targetAttrib)
  36052. +{
  36053. +
  36054. + targetAttrib->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].attrib;
  36055. + targetAttrib->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId;
  36056. +
  36057. + return MV_OK;
  36058. +
  36059. +}
  36060. +
  36061. +/*******************************************************************************
  36062. +* mvCtrlGetAttrib -
  36063. +*
  36064. +* DESCRIPTION:
  36065. +*
  36066. +* INPUT:
  36067. +*
  36068. +* OUTPUT:
  36069. +*
  36070. +* RETURN:
  36071. +*
  36072. +*******************************************************************************/
  36073. +MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib)
  36074. +{
  36075. + MV_TARGET target;
  36076. + MV_TARGET x;
  36077. + for (target = SDRAM_CS0; target < MAX_TARGETS ; target ++)
  36078. + {
  36079. + x = MV_CHANGE_BOOT_CS(target);
  36080. + if ((mvTargetDefaultsArray[x].attrib == targetAttrib->attrib) &&
  36081. + (mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId == targetAttrib->targetId))
  36082. + {
  36083. + /* found it */
  36084. + break;
  36085. + }
  36086. + }
  36087. +
  36088. + return target;
  36089. +}
  36090. +
  36091. +MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin,
  36092. + MV_DEC_WIN_PARAMS *pWinParam)
  36093. +{
  36094. + MV_U32 baseToReg=0, sizeToReg=0;
  36095. +
  36096. + /* BaseLow[31:16] => base register [31:16] */
  36097. + baseToReg = pAddrDecWin->addrWin.baseLow & CTRL_DEC_BASE_MASK;
  36098. +
  36099. + /* Write to address decode Base Address Register */
  36100. + pWinParam->baseAddr &= ~CTRL_DEC_BASE_MASK;
  36101. + pWinParam->baseAddr |= baseToReg;
  36102. +
  36103. + /* Get size register value according to window size */
  36104. + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, CTRL_DEC_SIZE_ALIGNMENT);
  36105. +
  36106. + /* Size parameter validity check. */
  36107. + if (-1 == sizeToReg)
  36108. + {
  36109. + mvOsPrintf("mvCtrlAddrDecToParams: ERR. ctrlSizeToReg failed.\n");
  36110. + return MV_BAD_PARAM;
  36111. + }
  36112. + pWinParam->size = sizeToReg;
  36113. +
  36114. + pWinParam->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].attrib;
  36115. + pWinParam->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].targetId;
  36116. +
  36117. + return MV_OK;
  36118. +}
  36119. +
  36120. +MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam,
  36121. + MV_DEC_WIN *pAddrDecWin)
  36122. +{
  36123. + MV_TARGET_ATTRIB targetAttrib;
  36124. +
  36125. + pAddrDecWin->addrWin.baseLow = pWinParam->baseAddr;
  36126. +
  36127. + /* Upper 32bit address base is supported under PCI High Address remap */
  36128. + pAddrDecWin->addrWin.baseHigh = 0;
  36129. +
  36130. + /* Prepare sizeReg to ctrlRegToSize function */
  36131. + pAddrDecWin->addrWin.size = ctrlRegToSize(pWinParam->size, CTRL_DEC_SIZE_ALIGNMENT);
  36132. +
  36133. + if (-1 == pAddrDecWin->addrWin.size)
  36134. + {
  36135. + DB(mvOsPrintf("mvCtrlParamsToAddrDec: ERR. ctrlRegToSize failed.\n"));
  36136. + return MV_BAD_PARAM;
  36137. + }
  36138. + targetAttrib.targetId = pWinParam->targetId;
  36139. + targetAttrib.attrib = pWinParam->attrib;
  36140. +
  36141. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  36142. +
  36143. + return MV_OK;
  36144. +}
  36145. +
  36146. +
  36147. +
  36148. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h
  36149. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h 1970-01-01 01:00:00.000000000 +0100
  36150. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h 2010-11-09 20:28:07.642495620 +0100
  36151. @@ -0,0 +1,203 @@
  36152. +/*******************************************************************************
  36153. +Copyright (C) Marvell International Ltd. and its affiliates
  36154. +
  36155. +This software file (the "File") is owned and distributed by Marvell
  36156. +International Ltd. and/or its affiliates ("Marvell") under the following
  36157. +alternative licensing terms. Once you have made an election to distribute the
  36158. +File under one of the following license alternatives, please (i) delete this
  36159. +introductory statement regarding license alternatives, (ii) delete the two
  36160. +license alternatives that you have not elected to use and (iii) preserve the
  36161. +Marvell copyright notice above.
  36162. +
  36163. +********************************************************************************
  36164. +Marvell Commercial License Option
  36165. +
  36166. +If you received this File from Marvell and you have entered into a commercial
  36167. +license agreement (a "Commercial License") with Marvell, the File is licensed
  36168. +to you under the terms of the applicable Commercial License.
  36169. +
  36170. +********************************************************************************
  36171. +Marvell GPL License Option
  36172. +
  36173. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36174. +modify this File in accordance with the terms and conditions of the General
  36175. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  36176. +available along with the File in the license.txt file or by writing to the Free
  36177. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  36178. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  36179. +
  36180. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  36181. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  36182. +DISCLAIMED. The GPL License provides additional details about this warranty
  36183. +disclaimer.
  36184. +********************************************************************************
  36185. +Marvell BSD License Option
  36186. +
  36187. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36188. +modify this File under the following licensing terms.
  36189. +Redistribution and use in source and binary forms, with or without modification,
  36190. +are permitted provided that the following conditions are met:
  36191. +
  36192. + * Redistributions of source code must retain the above copyright notice,
  36193. + this list of conditions and the following disclaimer.
  36194. +
  36195. + * Redistributions in binary form must reproduce the above copyright
  36196. + notice, this list of conditions and the following disclaimer in the
  36197. + documentation and/or other materials provided with the distribution.
  36198. +
  36199. + * Neither the name of Marvell nor the names of its contributors may be
  36200. + used to endorse or promote products derived from this software without
  36201. + specific prior written permission.
  36202. +
  36203. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  36204. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  36205. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  36206. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  36207. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36208. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36209. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  36210. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36211. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36212. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36213. +
  36214. +*******************************************************************************/
  36215. +
  36216. +
  36217. +#ifndef __INCmvCtrlEnvAddrDech
  36218. +#define __INCmvCtrlEnvAddrDech
  36219. +
  36220. +/* includes */
  36221. +#include "ctrlEnv/mvCtrlEnvLib.h"
  36222. +#include "ctrlEnv/mvCtrlEnvRegs.h"
  36223. +
  36224. +
  36225. +/* defines */
  36226. +/* DUnit attributes */
  36227. +#define ATMWCR_WIN_DUNIT_CS0_OFFS 0
  36228. +#define ATMWCR_WIN_DUNIT_CS0_MASK BIT0
  36229. +#define ATMWCR_WIN_DUNIT_CS0_REQ (0 << ATMWCR_WIN_DUNIT_CS0_OFFS)
  36230. +
  36231. +#define ATMWCR_WIN_DUNIT_CS1_OFFS 1
  36232. +#define ATMWCR_WIN_DUNIT_CS1_MASK BIT1
  36233. +#define ATMWCR_WIN_DUNIT_CS1_REQ (0 << ATMWCR_WIN_DUNIT_CS1_OFFS)
  36234. +
  36235. +#define ATMWCR_WIN_DUNIT_CS2_OFFS 2
  36236. +#define ATMWCR_WIN_DUNIT_CS2_MASK BIT2
  36237. +#define ATMWCR_WIN_DUNIT_CS2_REQ (0 << ATMWCR_WIN_DUNIT_CS2_OFFS)
  36238. +
  36239. +#define ATMWCR_WIN_DUNIT_CS3_OFFS 3
  36240. +#define ATMWCR_WIN_DUNIT_CS3_MASK BIT3
  36241. +#define ATMWCR_WIN_DUNIT_CS3_REQ (0 << ATMWCR_WIN_DUNIT_CS3_OFFS)
  36242. +
  36243. +/* RUnit (Device) attributes */
  36244. +#define ATMWCR_WIN_RUNIT_DEVCS0_OFFS 0
  36245. +#define ATMWCR_WIN_RUNIT_DEVCS0_MASK BIT0
  36246. +#define ATMWCR_WIN_RUNIT_DEVCS0_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS0_OFFS)
  36247. +
  36248. +#define ATMWCR_WIN_RUNIT_DEVCS1_OFFS 1
  36249. +#define ATMWCR_WIN_RUNIT_DEVCS1_MASK BIT1
  36250. +#define ATMWCR_WIN_RUNIT_DEVCS1_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS1_OFFS)
  36251. +
  36252. +#define ATMWCR_WIN_RUNIT_DEVCS2_OFFS 2
  36253. +#define ATMWCR_WIN_RUNIT_DEVCS2_MASK BIT2
  36254. +#define ATMWCR_WIN_RUNIT_DEVCS2_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS2_OFFS)
  36255. +
  36256. +#define ATMWCR_WIN_RUNIT_BOOTCS_OFFS 4
  36257. +#define ATMWCR_WIN_RUNIT_BOOTCS_MASK BIT4
  36258. +#define ATMWCR_WIN_RUNIT_BOOTCS_REQ (0 << ATMWCR_WIN_RUNIT_BOOTCS_OFFS)
  36259. +
  36260. +/* LMaster (PCI) attributes */
  36261. +#define ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS 0
  36262. +#define ATMWCR_WIN_LUNIT_BYTE_SWP_MASK BIT0
  36263. +#define ATMWCR_WIN_LUNIT_BYTE_SWP (0 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)
  36264. +#define ATMWCR_WIN_LUNIT_BYTE_NO_SWP (1 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)
  36265. +
  36266. +
  36267. +#define ATMWCR_WIN_LUNIT_WORD_SWP_OFFS 1
  36268. +#define ATMWCR_WIN_LUNIT_WORD_SWP_MASK BIT1
  36269. +#define ATMWCR_WIN_LUNIT_WORD_SWP (0 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)
  36270. +#define ATMWCR_WIN_LUNIT_WORD_NO_SWP (1 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)
  36271. +
  36272. +#define ATMWCR_WIN_LUNIT_NO_SNOOP BIT2
  36273. +
  36274. +#define ATMWCR_WIN_LUNIT_TYPE_OFFS 3
  36275. +#define ATMWCR_WIN_LUNIT_TYPE_MASK BIT3
  36276. +#define ATMWCR_WIN_LUNIT_TYPE_IO (0 << ATMWCR_WIN_LUNIT_TYPE_OFFS)
  36277. +#define ATMWCR_WIN_LUNIT_TYPE_MEM (1 << ATMWCR_WIN_LUNIT_TYPE_OFFS)
  36278. +
  36279. +#define ATMWCR_WIN_LUNIT_FORCE64_OFFS 4
  36280. +#define ATMWCR_WIN_LUNIT_FORCE64_MASK BIT4
  36281. +#define ATMWCR_WIN_LUNIT_FORCE64 (0 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)
  36282. +
  36283. +#define ATMWCR_WIN_LUNIT_ORDERING_OFFS 6
  36284. +#define ATMWCR_WIN_LUNIT_ORDERING_MASK BIT6
  36285. +#define ATMWCR_WIN_LUNIT_ORDERING (1 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)
  36286. +
  36287. +/* PEX Attributes */
  36288. +#define ATMWCR_WIN_PEX_TYPE_OFFS 3
  36289. +#define ATMWCR_WIN_PEX_TYPE_MASK BIT3
  36290. +#define ATMWCR_WIN_PEX_TYPE_IO (0 << ATMWCR_WIN_PEX_TYPE_OFFS)
  36291. +#define ATMWCR_WIN_PEX_TYPE_MEM (1 << ATMWCR_WIN_PEX_TYPE_OFFS)
  36292. +
  36293. +/* typedefs */
  36294. +
  36295. +/* Unsupported attributes for address decode: */
  36296. +/* 2) PCI0/1_REQ64n control */
  36297. +
  36298. +typedef struct _mvDecRegs
  36299. +{
  36300. + MV_U32 baseReg;
  36301. + MV_U32 baseRegHigh;
  36302. + MV_U32 sizeReg;
  36303. +
  36304. +}MV_DEC_REGS;
  36305. +
  36306. +typedef struct _mvTargetAttrib
  36307. +{
  36308. + MV_U8 attrib; /* chip select attributes */
  36309. + MV_TARGET_ID targetId; /* Target Id of this MV_TARGET */
  36310. +
  36311. +}MV_TARGET_ATTRIB;
  36312. +
  36313. +
  36314. +/* This structure describes address decode window */
  36315. +typedef struct _mvDecWin
  36316. +{
  36317. + MV_TARGET target; /* Target for addr decode window */
  36318. + MV_ADDR_WIN addrWin; /* Address window of target */
  36319. + MV_BOOL enable; /* Window enable/disable */
  36320. +}MV_DEC_WIN;
  36321. +
  36322. +typedef struct _mvDecWinParams
  36323. +{
  36324. + MV_TARGET_ID targetId; /* Target ID field */
  36325. + MV_U8 attrib; /* Attribute field */
  36326. + MV_U32 baseAddr; /* Base address in register format */
  36327. + MV_U32 size; /* Size in register format */
  36328. +}MV_DEC_WIN_PARAMS;
  36329. +
  36330. +
  36331. +/* mvCtrlEnvAddrDec API list */
  36332. +
  36333. +MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin,
  36334. + MV_DEC_REGS *pAddrDecRegs);
  36335. +
  36336. +MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs,
  36337. + MV_ADDR_WIN *pAddrDecWin);
  36338. +
  36339. +MV_STATUS mvCtrlAttribGet(MV_TARGET target,
  36340. + MV_TARGET_ATTRIB *targetAttrib);
  36341. +
  36342. +MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib);
  36343. +
  36344. +
  36345. +MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin,
  36346. + MV_DEC_WIN_PARAMS *pWinParam);
  36347. +
  36348. +MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam,
  36349. + MV_DEC_WIN *pAddrDecWin);
  36350. +
  36351. +
  36352. +
  36353. +
  36354. +#endif /* __INCmvCtrlEnvAddrDech */
  36355. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h
  36356. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h 1970-01-01 01:00:00.000000000 +0100
  36357. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h 2010-11-09 20:28:07.682495401 +0100
  36358. @@ -0,0 +1,98 @@
  36359. +/*******************************************************************************
  36360. +Copyright (C) Marvell International Ltd. and its affiliates
  36361. +
  36362. +This software file (the "File") is owned and distributed by Marvell
  36363. +International Ltd. and/or its affiliates ("Marvell") under the following
  36364. +alternative licensing terms. Once you have made an election to distribute the
  36365. +File under one of the following license alternatives, please (i) delete this
  36366. +introductory statement regarding license alternatives, (ii) delete the two
  36367. +license alternatives that you have not elected to use and (iii) preserve the
  36368. +Marvell copyright notice above.
  36369. +
  36370. +********************************************************************************
  36371. +Marvell Commercial License Option
  36372. +
  36373. +If you received this File from Marvell and you have entered into a commercial
  36374. +license agreement (a "Commercial License") with Marvell, the File is licensed
  36375. +to you under the terms of the applicable Commercial License.
  36376. +
  36377. +********************************************************************************
  36378. +Marvell GPL License Option
  36379. +
  36380. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36381. +modify this File in accordance with the terms and conditions of the General
  36382. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  36383. +available along with the File in the license.txt file or by writing to the Free
  36384. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  36385. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  36386. +
  36387. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  36388. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  36389. +DISCLAIMED. The GPL License provides additional details about this warranty
  36390. +disclaimer.
  36391. +********************************************************************************
  36392. +Marvell BSD License Option
  36393. +
  36394. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36395. +modify this File under the following licensing terms.
  36396. +Redistribution and use in source and binary forms, with or without modification,
  36397. +are permitted provided that the following conditions are met:
  36398. +
  36399. + * Redistributions of source code must retain the above copyright notice,
  36400. + this list of conditions and the following disclaimer.
  36401. +
  36402. + * Redistributions in binary form must reproduce the above copyright
  36403. + notice, this list of conditions and the following disclaimer in the
  36404. + documentation and/or other materials provided with the distribution.
  36405. +
  36406. + * Neither the name of Marvell nor the names of its contributors may be
  36407. + used to endorse or promote products derived from this software without
  36408. + specific prior written permission.
  36409. +
  36410. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  36411. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  36412. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  36413. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  36414. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36415. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36416. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  36417. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36418. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36419. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36420. +
  36421. +*******************************************************************************/
  36422. +
  36423. +
  36424. +#ifndef __INCmvCtrlEnvAsmh
  36425. +#define __INCmvCtrlEnvAsmh
  36426. +#include "pex/mvPexRegs.h"
  36427. +
  36428. +#define CHIP_BOND_REG 0x10034
  36429. +#define PCKG_OPT_MASK_AS #3
  36430. +#define PXCCARI_REVID_MASK_AS #PXCCARI_REVID_MASK
  36431. +
  36432. +/* Read device ID into toReg bits 15:0 from 0xd0000000 */
  36433. +/* defines */
  36434. +#define MV_DV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \
  36435. + MV_DV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\
  36436. + and toReg, toReg, PCKG_OPT_MASK_AS /* Mask for package ID */
  36437. +
  36438. +/* Read device ID into toReg bits 15:0 from 0xf1000000*/
  36439. +#define MV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \
  36440. + MV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\
  36441. + and toReg, toReg, PCKG_OPT_MASK_AS /* Mask for package ID */
  36442. +
  36443. +/* Read Revision into toReg bits 7:0 0xd0000000*/
  36444. +#define MV_DV_CTRL_REV_GET_ASM(toReg, tmpReg) \
  36445. + /* Read device revision */ \
  36446. + MV_DV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\
  36447. + and toReg, toReg, PXCCARI_REVID_MASK_AS /* Mask for calss ID */
  36448. +
  36449. +/* Read Revision into toReg bits 7:0 0xf1000000*/
  36450. +#define MV_CTRL_REV_GET_ASM(toReg, tmpReg) \
  36451. + /* Read device revision */ \
  36452. + MV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\
  36453. + and toReg, toReg, PXCCARI_REVID_MASK_AS /* Mask for calss ID */
  36454. +
  36455. +
  36456. +#endif /* __INCmvCtrlEnvAsmh */
  36457. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c
  36458. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c 1970-01-01 01:00:00.000000000 +0100
  36459. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c 2010-11-09 20:28:07.712495488 +0100
  36460. @@ -0,0 +1,1825 @@
  36461. +/*******************************************************************************
  36462. +Copyright (C) Marvell International Ltd. and its affiliates
  36463. +
  36464. +This software file (the "File") is owned and distributed by Marvell
  36465. +International Ltd. and/or its affiliates ("Marvell") under the following
  36466. +alternative licensing terms. Once you have made an election to distribute the
  36467. +File under one of the following license alternatives, please (i) delete this
  36468. +introductory statement regarding license alternatives, (ii) delete the two
  36469. +license alternatives that you have not elected to use and (iii) preserve the
  36470. +Marvell copyright notice above.
  36471. +
  36472. +********************************************************************************
  36473. +Marvell Commercial License Option
  36474. +
  36475. +If you received this File from Marvell and you have entered into a commercial
  36476. +license agreement (a "Commercial License") with Marvell, the File is licensed
  36477. +to you under the terms of the applicable Commercial License.
  36478. +
  36479. +********************************************************************************
  36480. +Marvell GPL License Option
  36481. +
  36482. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36483. +modify this File in accordance with the terms and conditions of the General
  36484. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  36485. +available along with the File in the license.txt file or by writing to the Free
  36486. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  36487. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  36488. +
  36489. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  36490. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  36491. +DISCLAIMED. The GPL License provides additional details about this warranty
  36492. +disclaimer.
  36493. +********************************************************************************
  36494. +Marvell BSD License Option
  36495. +
  36496. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36497. +modify this File under the following licensing terms.
  36498. +Redistribution and use in source and binary forms, with or without modification,
  36499. +are permitted provided that the following conditions are met:
  36500. +
  36501. + * Redistributions of source code must retain the above copyright notice,
  36502. + this list of conditions and the following disclaimer.
  36503. +
  36504. + * Redistributions in binary form must reproduce the above copyright
  36505. + notice, this list of conditions and the following disclaimer in the
  36506. + documentation and/or other materials provided with the distribution.
  36507. +
  36508. + * Neither the name of Marvell nor the names of its contributors may be
  36509. + used to endorse or promote products derived from this software without
  36510. + specific prior written permission.
  36511. +
  36512. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  36513. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  36514. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  36515. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  36516. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36517. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36518. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  36519. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36520. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36521. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36522. +
  36523. +*******************************************************************************/
  36524. +
  36525. +
  36526. +/* includes */
  36527. +#include "mvCommon.h"
  36528. +#include "mvCtrlEnvLib.h"
  36529. +#include "ctrlEnv/sys/mvCpuIf.h"
  36530. +
  36531. +#if defined(MV_INCLUDE_PEX)
  36532. +#include "pex/mvPex.h"
  36533. +#include "ctrlEnv/sys/mvSysPex.h"
  36534. +#endif
  36535. +
  36536. +#if defined(MV_INCLUDE_GIG_ETH)
  36537. +#include "ctrlEnv/sys/mvSysGbe.h"
  36538. +#endif
  36539. +
  36540. +#if defined(MV_INCLUDE_XOR)
  36541. +#include "ctrlEnv/sys/mvSysXor.h"
  36542. +#endif
  36543. +
  36544. +#if defined(MV_INCLUDE_SATA)
  36545. +#include "ctrlEnv/sys/mvSysSata.h"
  36546. +#endif
  36547. +
  36548. +#if defined(MV_INCLUDE_USB)
  36549. +#include "ctrlEnv/sys/mvSysUsb.h"
  36550. +#endif
  36551. +
  36552. +#if defined(MV_INCLUDE_AUDIO)
  36553. +#include "ctrlEnv/sys/mvSysAudio.h"
  36554. +#endif
  36555. +
  36556. +#if defined(MV_INCLUDE_CESA)
  36557. +#include "ctrlEnv/sys/mvSysCesa.h"
  36558. +#endif
  36559. +
  36560. +#if defined(MV_INCLUDE_TS)
  36561. +#include "ctrlEnv/sys/mvSysTs.h"
  36562. +#endif
  36563. +
  36564. +/* defines */
  36565. +#ifdef MV_DEBUG
  36566. + #define DB(x) x
  36567. +#else
  36568. + #define DB(x)
  36569. +#endif
  36570. +
  36571. +/*******************************************************************************
  36572. +* mvCtrlEnvInit - Initialize Marvell controller environment.
  36573. +*
  36574. +* DESCRIPTION:
  36575. +* This function get environment information and initialize controller
  36576. +* internal/external environment. For example
  36577. +* 1) MPP settings according to board MPP macros.
  36578. +* NOTE: It is the user responsibility to shut down all DMA channels
  36579. +* in device and disable controller sub units interrupts during
  36580. +* boot process.
  36581. +*
  36582. +* INPUT:
  36583. +* None.
  36584. +*
  36585. +* OUTPUT:
  36586. +* None.
  36587. +*
  36588. +* RETURN:
  36589. +* None.
  36590. +*
  36591. +*******************************************************************************/
  36592. +MV_STATUS mvCtrlEnvInit(MV_VOID)
  36593. +{
  36594. + MV_U32 mppGroup;
  36595. + MV_U32 devId;
  36596. + MV_U32 boardId;
  36597. + MV_U32 i;
  36598. + MV_U32 maxMppGrp = 1;
  36599. + MV_U32 mppVal = 0;
  36600. + MV_U32 bootVal = 0;
  36601. + MV_U32 mppGroupType = 0;
  36602. + MV_U32 mppGroup1[][3] = MPP_GROUP_1_TYPE;
  36603. + MV_U32 mppGroup2[][3] = MPP_GROUP_2_TYPE;
  36604. +
  36605. + devId = mvCtrlModelGet();
  36606. + boardId= mvBoardIdGet();
  36607. +
  36608. + switch(devId){
  36609. + case MV_6281_DEV_ID:
  36610. + maxMppGrp = MV_6281_MPP_MAX_GROUP;
  36611. + break;
  36612. + case MV_6192_DEV_ID:
  36613. + maxMppGrp = MV_6192_MPP_MAX_GROUP;
  36614. + break;
  36615. + case MV_6190_DEV_ID:
  36616. + maxMppGrp = MV_6190_MPP_MAX_GROUP;
  36617. + break;
  36618. + case MV_6180_DEV_ID:
  36619. + maxMppGrp = MV_6180_MPP_MAX_GROUP;
  36620. + break;
  36621. + }
  36622. +
  36623. + /* MPP Init */
  36624. + /* We split mpp init to 3 phases:
  36625. + * 1. We init mpp[19:0] from the board info. mpp[23:20] will be over write
  36626. + * in phase 2.
  36627. + * 2. We detect the mpp group type and according the mpp values [35:20].
  36628. + * 3. We detect the mpp group type and according the mpp values [49:36].
  36629. + */
  36630. + /* Mpp phase 1 mpp[19:0] */
  36631. + /* Read MPP group from board level and assign to MPP register */
  36632. + for (mppGroup = 0; mppGroup < 3; mppGroup++)
  36633. + {
  36634. + mppVal = mvBoardMppGet(mppGroup);
  36635. + if (mppGroup == 0)
  36636. + {
  36637. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  36638. + if (mvCtrlIsBootFromSPI())
  36639. + {
  36640. + mppVal &= ~0xffff;
  36641. + bootVal &= 0xffff;
  36642. + mppVal |= bootVal;
  36643. + }
  36644. + else if (mvCtrlIsBootFromSPIUseNAND())
  36645. + {
  36646. + mppVal &= ~0xf0000000;
  36647. + bootVal &= 0xf0000000;
  36648. + mppVal |= bootVal;
  36649. + }
  36650. + else if (mvCtrlIsBootFromNAND())
  36651. + {
  36652. + mppVal &= ~0xffffff;
  36653. + bootVal &= 0xffffff;
  36654. + mppVal |= bootVal;
  36655. + }
  36656. + }
  36657. +
  36658. + if (mppGroup == 2)
  36659. + {
  36660. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  36661. + if (mvCtrlIsBootFromNAND())
  36662. + {
  36663. + mppVal &= ~0xff00;
  36664. + bootVal &= 0xff00;
  36665. + mppVal |= bootVal;
  36666. + }
  36667. + }
  36668. +
  36669. + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
  36670. + }
  36671. +
  36672. + /* Identify MPPs group */
  36673. + mvBoardMppGroupIdUpdate();
  36674. +
  36675. + /* Update MPPs mux relevent only on Marvell DB */
  36676. + if ((boardId == DB_88F6281A_BP_ID) ||
  36677. + (boardId == DB_88F6180A_BP_ID))
  36678. + mvBoardMppMuxSet();
  36679. +
  36680. + mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_1);
  36681. +
  36682. + /* Mpp phase 2 */
  36683. + /* Read MPP group from board level and assign to MPP register */
  36684. + if (devId != MV_6180_DEV_ID)
  36685. + {
  36686. + i = 0;
  36687. + for (mppGroup = 2; mppGroup < 5; mppGroup++)
  36688. + {
  36689. + if ((mppGroupType == MV_BOARD_OTHER) ||
  36690. + (boardId == RD_88F6281A_ID) ||
  36691. + (boardId == RD_88F6192A_ID) ||
  36692. + (boardId == RD_88F6190A_ID) ||
  36693. + (boardId == RD_88F6281A_PCAC_ID) ||
  36694. + (boardId == SHEEVA_PLUG_ID))
  36695. + mppVal = mvBoardMppGet(mppGroup);
  36696. + else
  36697. + {
  36698. + mppVal = mppGroup1[mppGroupType][i];
  36699. + i++;
  36700. + }
  36701. +
  36702. + /* Group 2 is shared mpp[23:16] */
  36703. + if (mppGroup == 2)
  36704. + {
  36705. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  36706. + mppVal &= ~0xffff;
  36707. + bootVal &= 0xffff;
  36708. + mppVal |= bootVal;
  36709. + }
  36710. +
  36711. + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
  36712. + }
  36713. + }
  36714. +
  36715. + if ((devId == MV_6192_DEV_ID) || (devId == MV_6190_DEV_ID))
  36716. + return MV_OK;
  36717. +
  36718. + /* Mpp phase 3 */
  36719. + mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_2);
  36720. + /* Read MPP group from board level and assign to MPP register */
  36721. + i = 0;
  36722. + for (mppGroup = 4; mppGroup < 7; mppGroup++)
  36723. + {
  36724. + if ((mppGroupType == MV_BOARD_OTHER) ||
  36725. + (boardId == RD_88F6281A_ID) ||
  36726. + (boardId == RD_88F6281A_PCAC_ID) ||
  36727. + (boardId == SHEEVA_PLUG_ID))
  36728. + mppVal = mvBoardMppGet(mppGroup);
  36729. + else
  36730. + {
  36731. + mppVal = mppGroup2[mppGroupType][i];
  36732. + i++;
  36733. + }
  36734. +
  36735. + /* Group 4 is shared mpp[35:32] */
  36736. + if (mppGroup == 4)
  36737. + {
  36738. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  36739. + mppVal &= ~0xffff;
  36740. + bootVal &= 0xffff;
  36741. + mppVal |= bootVal;
  36742. + }
  36743. +
  36744. + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
  36745. + }
  36746. + /* Update SSCG configuration register*/
  36747. + if(mvBoardIdGet() == DB_88F6281A_BP_ID || mvBoardIdGet() == DB_88F6192A_BP_ID ||
  36748. + mvBoardIdGet() == DB_88F6190A_BP_ID || mvBoardIdGet() == DB_88F6180A_BP_ID)
  36749. + MV_REG_WRITE(0x100d8, 0x53);
  36750. +
  36751. + return MV_OK;
  36752. +}
  36753. +
  36754. +/*******************************************************************************
  36755. +* mvCtrlMppRegGet - return reg address of mpp group
  36756. +*
  36757. +* DESCRIPTION:
  36758. +*
  36759. +* INPUT:
  36760. +* mppGroup - MPP group.
  36761. +*
  36762. +* OUTPUT:
  36763. +* None.
  36764. +*
  36765. +* RETURN:
  36766. +* MV_U32 - Register address.
  36767. +*
  36768. +*******************************************************************************/
  36769. +MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup)
  36770. +{
  36771. + MV_U32 ret;
  36772. +
  36773. + switch(mppGroup){
  36774. + case (0): ret = MPP_CONTROL_REG0;
  36775. + break;
  36776. + case (1): ret = MPP_CONTROL_REG1;
  36777. + break;
  36778. + case (2): ret = MPP_CONTROL_REG2;
  36779. + break;
  36780. + case (3): ret = MPP_CONTROL_REG3;
  36781. + break;
  36782. + case (4): ret = MPP_CONTROL_REG4;
  36783. + break;
  36784. + case (5): ret = MPP_CONTROL_REG5;
  36785. + break;
  36786. + case (6): ret = MPP_CONTROL_REG6;
  36787. + break;
  36788. + default: ret = MPP_CONTROL_REG0;
  36789. + break;
  36790. + }
  36791. + return ret;
  36792. +}
  36793. +#if defined(MV_INCLUDE_PEX)
  36794. +/*******************************************************************************
  36795. +* mvCtrlPexMaxIfGet - Get Marvell controller number of PEX interfaces.
  36796. +*
  36797. +* DESCRIPTION:
  36798. +* This function returns Marvell controller number of PEX interfaces.
  36799. +*
  36800. +* INPUT:
  36801. +* None.
  36802. +*
  36803. +* OUTPUT:
  36804. +* None.
  36805. +*
  36806. +* RETURN:
  36807. +* Marvell controller number of PEX interfaces. If controller
  36808. +* ID is undefined the function returns '0'.
  36809. +*
  36810. +*******************************************************************************/
  36811. +MV_U32 mvCtrlPexMaxIfGet(MV_VOID)
  36812. +{
  36813. +
  36814. + return MV_PEX_MAX_IF;
  36815. +}
  36816. +#endif
  36817. +
  36818. +#if defined(MV_INCLUDE_GIG_ETH)
  36819. +/*******************************************************************************
  36820. +* mvCtrlEthMaxPortGet - Get Marvell controller number of etherent ports.
  36821. +*
  36822. +* DESCRIPTION:
  36823. +* This function returns Marvell controller number of etherent port.
  36824. +*
  36825. +* INPUT:
  36826. +* None.
  36827. +*
  36828. +* OUTPUT:
  36829. +* None.
  36830. +*
  36831. +* RETURN:
  36832. +* Marvell controller number of etherent port.
  36833. +*
  36834. +*******************************************************************************/
  36835. +MV_U32 mvCtrlEthMaxPortGet(MV_VOID)
  36836. +{
  36837. + MV_U32 devId;
  36838. +
  36839. + devId = mvCtrlModelGet();
  36840. +
  36841. + switch(devId){
  36842. + case MV_6281_DEV_ID:
  36843. + return MV_6281_ETH_MAX_PORTS;
  36844. + break;
  36845. + case MV_6192_DEV_ID:
  36846. + return MV_6192_ETH_MAX_PORTS;
  36847. + break;
  36848. + case MV_6190_DEV_ID:
  36849. + return MV_6190_ETH_MAX_PORTS;
  36850. + break;
  36851. + case MV_6180_DEV_ID:
  36852. + return MV_6180_ETH_MAX_PORTS;
  36853. + break;
  36854. + }
  36855. + return 0;
  36856. +
  36857. +}
  36858. +#endif
  36859. +
  36860. +#if defined(MV_INCLUDE_XOR)
  36861. +/*******************************************************************************
  36862. +* mvCtrlXorMaxChanGet - Get Marvell controller number of XOR channels.
  36863. +*
  36864. +* DESCRIPTION:
  36865. +* This function returns Marvell controller number of XOR channels.
  36866. +*
  36867. +* INPUT:
  36868. +* None.
  36869. +*
  36870. +* OUTPUT:
  36871. +* None.
  36872. +*
  36873. +* RETURN:
  36874. +* Marvell controller number of XOR channels.
  36875. +*
  36876. +*******************************************************************************/
  36877. +MV_U32 mvCtrlXorMaxChanGet(MV_VOID)
  36878. +{
  36879. + return MV_XOR_MAX_CHAN;
  36880. +}
  36881. +#endif
  36882. +
  36883. +#if defined(MV_INCLUDE_USB)
  36884. +/*******************************************************************************
  36885. +* mvCtrlUsbHostMaxGet - Get number of Marvell Usb controllers
  36886. +*
  36887. +* DESCRIPTION:
  36888. +*
  36889. +* INPUT:
  36890. +* None.
  36891. +*
  36892. +* OUTPUT:
  36893. +* None.
  36894. +*
  36895. +* RETURN:
  36896. +* returns number of Marvell USB controllers.
  36897. +*
  36898. +*******************************************************************************/
  36899. +MV_U32 mvCtrlUsbMaxGet(void)
  36900. +{
  36901. + return MV_USB_MAX_PORTS;
  36902. +}
  36903. +#endif
  36904. +
  36905. +
  36906. +#if defined(MV_INCLUDE_NAND)
  36907. +/*******************************************************************************
  36908. +* mvCtrlNandSupport - Return if this controller has integrated NAND flash support
  36909. +*
  36910. +* DESCRIPTION:
  36911. +*
  36912. +* INPUT:
  36913. +* None.
  36914. +*
  36915. +* OUTPUT:
  36916. +* None.
  36917. +*
  36918. +* RETURN:
  36919. +* MV_TRUE if NAND is supported and MV_FALSE otherwise
  36920. +*
  36921. +*******************************************************************************/
  36922. +MV_U32 mvCtrlNandSupport(MV_VOID)
  36923. +{
  36924. + MV_U32 devId;
  36925. +
  36926. + devId = mvCtrlModelGet();
  36927. +
  36928. + switch(devId){
  36929. + case MV_6281_DEV_ID:
  36930. + return MV_6281_NAND;
  36931. + break;
  36932. + case MV_6192_DEV_ID:
  36933. + return MV_6192_NAND;
  36934. + break;
  36935. + case MV_6190_DEV_ID:
  36936. + return MV_6190_NAND;
  36937. + break;
  36938. + case MV_6180_DEV_ID:
  36939. + return MV_6180_NAND;
  36940. + break;
  36941. + }
  36942. + return 0;
  36943. +
  36944. +}
  36945. +#endif
  36946. +
  36947. +#if defined(MV_INCLUDE_SDIO)
  36948. +/*******************************************************************************
  36949. +* mvCtrlSdioSupport - Return if this controller has integrated SDIO flash support
  36950. +*
  36951. +* DESCRIPTION:
  36952. +*
  36953. +* INPUT:
  36954. +* None.
  36955. +*
  36956. +* OUTPUT:
  36957. +* None.
  36958. +*
  36959. +* RETURN:
  36960. +* MV_TRUE if SDIO is supported and MV_FALSE otherwise
  36961. +*
  36962. +*******************************************************************************/
  36963. +MV_U32 mvCtrlSdioSupport(MV_VOID)
  36964. +{
  36965. + MV_U32 devId;
  36966. +
  36967. + devId = mvCtrlModelGet();
  36968. +
  36969. + switch(devId){
  36970. + case MV_6281_DEV_ID:
  36971. + return MV_6281_SDIO;
  36972. + break;
  36973. + case MV_6192_DEV_ID:
  36974. + return MV_6192_SDIO;
  36975. + break;
  36976. + case MV_6190_DEV_ID:
  36977. + return MV_6190_SDIO;
  36978. + break;
  36979. + case MV_6180_DEV_ID:
  36980. + return MV_6180_SDIO;
  36981. + break;
  36982. + }
  36983. + return 0;
  36984. +
  36985. +}
  36986. +#endif
  36987. +
  36988. +#if defined(MV_INCLUDE_TS)
  36989. +/*******************************************************************************
  36990. +* mvCtrlTsSupport - Return if this controller has integrated TS flash support
  36991. +*
  36992. +* DESCRIPTION:
  36993. +*
  36994. +* INPUT:
  36995. +* None.
  36996. +*
  36997. +* OUTPUT:
  36998. +* None.
  36999. +*
  37000. +* RETURN:
  37001. +* MV_TRUE if TS is supported and MV_FALSE otherwise
  37002. +*
  37003. +*******************************************************************************/
  37004. +MV_U32 mvCtrlTsSupport(MV_VOID)
  37005. +{
  37006. + MV_U32 devId;
  37007. +
  37008. + devId = mvCtrlModelGet();
  37009. +
  37010. + switch(devId){
  37011. + case MV_6281_DEV_ID:
  37012. + return MV_6281_TS;
  37013. + break;
  37014. + case MV_6192_DEV_ID:
  37015. + return MV_6192_TS;
  37016. + break;
  37017. + case MV_6190_DEV_ID:
  37018. + return MV_6190_TS;
  37019. + break;
  37020. + case MV_6180_DEV_ID:
  37021. + return MV_6180_TS;
  37022. + break;
  37023. + }
  37024. + return 0;
  37025. +}
  37026. +#endif
  37027. +
  37028. +#if defined(MV_INCLUDE_AUDIO)
  37029. +/*******************************************************************************
  37030. +* mvCtrlAudioSupport - Return if this controller has integrated AUDIO flash support
  37031. +*
  37032. +* DESCRIPTION:
  37033. +*
  37034. +* INPUT:
  37035. +* None.
  37036. +*
  37037. +* OUTPUT:
  37038. +* None.
  37039. +*
  37040. +* RETURN:
  37041. +* MV_TRUE if AUDIO is supported and MV_FALSE otherwise
  37042. +*
  37043. +*******************************************************************************/
  37044. +MV_U32 mvCtrlAudioSupport(MV_VOID)
  37045. +{
  37046. + MV_U32 devId;
  37047. +
  37048. + devId = mvCtrlModelGet();
  37049. +
  37050. + switch(devId){
  37051. + case MV_6281_DEV_ID:
  37052. + return MV_6281_AUDIO;
  37053. + break;
  37054. + case MV_6192_DEV_ID:
  37055. + return MV_6192_AUDIO;
  37056. + break;
  37057. + case MV_6190_DEV_ID:
  37058. + return MV_6190_AUDIO;
  37059. + break;
  37060. + case MV_6180_DEV_ID:
  37061. + return MV_6180_AUDIO;
  37062. + break;
  37063. + }
  37064. + return 0;
  37065. +
  37066. +}
  37067. +#endif
  37068. +
  37069. +#if defined(MV_INCLUDE_TDM)
  37070. +/*******************************************************************************
  37071. +* mvCtrlTdmSupport - Return if this controller has integrated TDM flash support
  37072. +*
  37073. +* DESCRIPTION:
  37074. +*
  37075. +* INPUT:
  37076. +* None.
  37077. +*
  37078. +* OUTPUT:
  37079. +* None.
  37080. +*
  37081. +* RETURN:
  37082. +* MV_TRUE if TDM is supported and MV_FALSE otherwise
  37083. +*
  37084. +*******************************************************************************/
  37085. +MV_U32 mvCtrlTdmSupport(MV_VOID)
  37086. +{
  37087. + MV_U32 devId;
  37088. +
  37089. + devId = mvCtrlModelGet();
  37090. +
  37091. + switch(devId){
  37092. + case MV_6281_DEV_ID:
  37093. + return MV_6281_TDM;
  37094. + break;
  37095. + case MV_6192_DEV_ID:
  37096. + return MV_6192_TDM;
  37097. + break;
  37098. + case MV_6190_DEV_ID:
  37099. + return MV_6190_TDM;
  37100. + break;
  37101. + case MV_6180_DEV_ID:
  37102. + return MV_6180_TDM;
  37103. + break;
  37104. + }
  37105. + return 0;
  37106. +
  37107. +}
  37108. +#endif
  37109. +
  37110. +/*******************************************************************************
  37111. +* mvCtrlModelGet - Get Marvell controller device model (Id)
  37112. +*
  37113. +* DESCRIPTION:
  37114. +* This function returns 16bit describing the device model (ID) as defined
  37115. +* in PCI Device and Vendor ID configuration register offset 0x0.
  37116. +*
  37117. +* INPUT:
  37118. +* None.
  37119. +*
  37120. +* OUTPUT:
  37121. +* None.
  37122. +*
  37123. +* RETURN:
  37124. +* 16bit desscribing Marvell controller ID
  37125. +*
  37126. +*******************************************************************************/
  37127. +MV_U16 mvCtrlModelGet(MV_VOID)
  37128. +{
  37129. + MV_U32 devId;
  37130. +
  37131. + devId = MV_REG_READ(CHIP_BOND_REG);
  37132. + devId &= PCKG_OPT_MASK;
  37133. +
  37134. + switch(devId){
  37135. + case 2:
  37136. + return MV_6281_DEV_ID;
  37137. + break;
  37138. + case 1:
  37139. + if (((MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PEX_DEVICE_AND_VENDOR_ID))& 0xffff0000) >> 16)
  37140. + == MV_6190_DEV_ID)
  37141. + return MV_6190_DEV_ID;
  37142. + else
  37143. + return MV_6192_DEV_ID;
  37144. + break;
  37145. + case 0:
  37146. + return MV_6180_DEV_ID;
  37147. + break;
  37148. + }
  37149. +
  37150. + return 0;
  37151. +}
  37152. +/*******************************************************************************
  37153. +* mvCtrlRevGet - Get Marvell controller device revision number
  37154. +*
  37155. +* DESCRIPTION:
  37156. +* This function returns 8bit describing the device revision as defined
  37157. +* in PCI Express Class Code and Revision ID Register.
  37158. +*
  37159. +* INPUT:
  37160. +* None.
  37161. +*
  37162. +* OUTPUT:
  37163. +* None.
  37164. +*
  37165. +* RETURN:
  37166. +* 8bit desscribing Marvell controller revision number
  37167. +*
  37168. +*******************************************************************************/
  37169. +MV_U8 mvCtrlRevGet(MV_VOID)
  37170. +{
  37171. + MV_U8 revNum;
  37172. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  37173. + /* Check pex power state */
  37174. + MV_U32 pexPower;
  37175. + pexPower = mvCtrlPwrClckGet(PEX_UNIT_ID,0);
  37176. + if (pexPower == MV_FALSE)
  37177. + mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_TRUE);
  37178. +#endif
  37179. + revNum = (MV_U8)MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PCI_CLASS_CODE_AND_REVISION_ID));
  37180. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  37181. + /* Return to power off state */
  37182. + if (pexPower == MV_FALSE)
  37183. + mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_FALSE);
  37184. +#endif
  37185. + return ((revNum & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS);
  37186. +}
  37187. +
  37188. +/*******************************************************************************
  37189. +* mvCtrlNameGet - Get Marvell controller name
  37190. +*
  37191. +* DESCRIPTION:
  37192. +* This function returns a string describing the device model and revision.
  37193. +*
  37194. +* INPUT:
  37195. +* None.
  37196. +*
  37197. +* OUTPUT:
  37198. +* pNameBuff - Buffer to contain device name string. Minimum size 30 chars.
  37199. +*
  37200. +* RETURN:
  37201. +*
  37202. +* MV_ERROR if informantion can not be read.
  37203. +*******************************************************************************/
  37204. +MV_STATUS mvCtrlNameGet(char *pNameBuff)
  37205. +{
  37206. + mvOsSPrintf (pNameBuff, "%s%x Rev %d", SOC_NAME_PREFIX,
  37207. + mvCtrlModelGet(), mvCtrlRevGet());
  37208. +
  37209. + return MV_OK;
  37210. +}
  37211. +
  37212. +/*******************************************************************************
  37213. +* mvCtrlModelRevGet - Get Controller Model (Device ID) and Revision
  37214. +*
  37215. +* DESCRIPTION:
  37216. +* This function returns 32bit value describing both Device ID and Revision
  37217. +* as defined in PCI Express Device and Vendor ID Register and device revision
  37218. +* as defined in PCI Express Class Code and Revision ID Register.
  37219. +
  37220. +*
  37221. +* INPUT:
  37222. +* None.
  37223. +*
  37224. +* OUTPUT:
  37225. +* None.
  37226. +*
  37227. +* RETURN:
  37228. +* 32bit describing both controller device ID and revision number
  37229. +*
  37230. +*******************************************************************************/
  37231. +MV_U32 mvCtrlModelRevGet(MV_VOID)
  37232. +{
  37233. + return ((mvCtrlModelGet() << 16) | mvCtrlRevGet());
  37234. +}
  37235. +
  37236. +/*******************************************************************************
  37237. +* mvCtrlModelRevNameGet - Get Marvell controller name
  37238. +*
  37239. +* DESCRIPTION:
  37240. +* This function returns a string describing the device model and revision.
  37241. +*
  37242. +* INPUT:
  37243. +* None.
  37244. +*
  37245. +* OUTPUT:
  37246. +* pNameBuff - Buffer to contain device name string. Minimum size 30 chars.
  37247. +*
  37248. +* RETURN:
  37249. +*
  37250. +* MV_ERROR if informantion can not be read.
  37251. +*******************************************************************************/
  37252. +
  37253. +MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff)
  37254. +{
  37255. +
  37256. + switch (mvCtrlModelRevGet())
  37257. + {
  37258. + case MV_6281_A0_ID:
  37259. + mvOsSPrintf (pNameBuff, "%s",MV_6281_A0_NAME);
  37260. + break;
  37261. + case MV_6192_A0_ID:
  37262. + mvOsSPrintf (pNameBuff, "%s",MV_6192_A0_NAME);
  37263. + break;
  37264. + case MV_6180_A0_ID:
  37265. + mvOsSPrintf (pNameBuff, "%s",MV_6180_A0_NAME);
  37266. + break;
  37267. + case MV_6190_A0_ID:
  37268. + mvOsSPrintf (pNameBuff, "%s",MV_6190_A0_NAME);
  37269. + break;
  37270. + case MV_6281_A1_ID:
  37271. + mvOsSPrintf (pNameBuff, "%s",MV_6281_A1_NAME);
  37272. + break;
  37273. + case MV_6192_A1_ID:
  37274. + mvOsSPrintf (pNameBuff, "%s",MV_6192_A1_NAME);
  37275. + break;
  37276. + case MV_6180_A1_ID:
  37277. + mvOsSPrintf (pNameBuff, "%s",MV_6180_A1_NAME);
  37278. + break;
  37279. + case MV_6190_A1_ID:
  37280. + mvOsSPrintf (pNameBuff, "%s",MV_6190_A1_NAME);
  37281. + break;
  37282. + default:
  37283. + mvCtrlNameGet(pNameBuff);
  37284. + break;
  37285. + }
  37286. +
  37287. + return MV_OK;
  37288. +}
  37289. +
  37290. +
  37291. +/*******************************************************************************
  37292. +* ctrlWinOverlapTest - Test address windows for overlaping.
  37293. +*
  37294. +* DESCRIPTION:
  37295. +* This function checks the given two address windows for overlaping.
  37296. +*
  37297. +* INPUT:
  37298. +* pAddrWin1 - Address window 1.
  37299. +* pAddrWin2 - Address window 2.
  37300. +*
  37301. +* OUTPUT:
  37302. +* None.
  37303. +*
  37304. +* RETURN:
  37305. +*
  37306. +* MV_TRUE if address window overlaps, MV_FALSE otherwise.
  37307. +*******************************************************************************/
  37308. +MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)
  37309. +{
  37310. + MV_U32 winBase1, winBase2;
  37311. + MV_U32 winTop1, winTop2;
  37312. +
  37313. + /* check if we have overflow than 4G*/
  37314. + if (((0xffffffff - pAddrWin1->baseLow) < pAddrWin1->size-1)||
  37315. + ((0xffffffff - pAddrWin2->baseLow) < pAddrWin2->size-1))
  37316. + {
  37317. + return MV_TRUE;
  37318. + }
  37319. +
  37320. + winBase1 = pAddrWin1->baseLow;
  37321. + winBase2 = pAddrWin2->baseLow;
  37322. + winTop1 = winBase1 + pAddrWin1->size-1;
  37323. + winTop2 = winBase2 + pAddrWin2->size-1;
  37324. +
  37325. +
  37326. + if (((winBase1 <= winTop2 ) && ( winTop2 <= winTop1)) ||
  37327. + ((winBase1 <= winBase2) && (winBase2 <= winTop1)))
  37328. + {
  37329. + return MV_TRUE;
  37330. + }
  37331. + else
  37332. + {
  37333. + return MV_FALSE;
  37334. + }
  37335. +}
  37336. +
  37337. +/*******************************************************************************
  37338. +* ctrlWinWithinWinTest - Test address windows for overlaping.
  37339. +*
  37340. +* DESCRIPTION:
  37341. +* This function checks the given win1 boundries is within
  37342. +* win2 boundries.
  37343. +*
  37344. +* INPUT:
  37345. +* pAddrWin1 - Address window 1.
  37346. +* pAddrWin2 - Address window 2.
  37347. +*
  37348. +* OUTPUT:
  37349. +* None.
  37350. +*
  37351. +* RETURN:
  37352. +*
  37353. +* MV_TRUE if found win1 inside win2, MV_FALSE otherwise.
  37354. +*******************************************************************************/
  37355. +MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)
  37356. +{
  37357. + MV_U32 winBase1, winBase2;
  37358. + MV_U32 winTop1, winTop2;
  37359. +
  37360. + winBase1 = pAddrWin1->baseLow;
  37361. + winBase2 = pAddrWin2->baseLow;
  37362. + winTop1 = winBase1 + pAddrWin1->size -1;
  37363. + winTop2 = winBase2 + pAddrWin2->size -1;
  37364. +
  37365. + if (((winBase1 >= winBase2 ) && ( winBase1 <= winTop2)) ||
  37366. + ((winTop1 >= winBase2) && (winTop1 <= winTop2)))
  37367. + {
  37368. + return MV_TRUE;
  37369. + }
  37370. + else
  37371. + {
  37372. + return MV_FALSE;
  37373. + }
  37374. +}
  37375. +
  37376. +static const char* cntrlName[] = TARGETS_NAME_ARRAY;
  37377. +
  37378. +/*******************************************************************************
  37379. +* mvCtrlTargetNameGet - Get Marvell controller target name
  37380. +*
  37381. +* DESCRIPTION:
  37382. +* This function convert the trget enumeration to string.
  37383. +*
  37384. +* INPUT:
  37385. +* None.
  37386. +*
  37387. +* OUTPUT:
  37388. +* None.
  37389. +*
  37390. +* RETURN:
  37391. +* Target name (const MV_8 *)
  37392. +*******************************************************************************/
  37393. +const MV_8* mvCtrlTargetNameGet( MV_TARGET target )
  37394. +{
  37395. +
  37396. + if (target >= MAX_TARGETS)
  37397. + {
  37398. + return "target unknown";
  37399. + }
  37400. +
  37401. + return cntrlName[target];
  37402. +}
  37403. +
  37404. +/*******************************************************************************
  37405. +* mvCtrlAddrDecShow - Print the Controller units address decode map.
  37406. +*
  37407. +* DESCRIPTION:
  37408. +* This function the Controller units address decode map.
  37409. +*
  37410. +* INPUT:
  37411. +* None.
  37412. +*
  37413. +* OUTPUT:
  37414. +* None.
  37415. +*
  37416. +* RETURN:
  37417. +* None.
  37418. +*
  37419. +*******************************************************************************/
  37420. +MV_VOID mvCtrlAddrDecShow(MV_VOID)
  37421. +{
  37422. + mvCpuIfAddDecShow();
  37423. + mvAhbToMbusAddDecShow();
  37424. +#if defined(MV_INCLUDE_PEX)
  37425. + mvPexAddrDecShow();
  37426. +#endif
  37427. +#if defined(MV_INCLUDE_USB)
  37428. + mvUsbAddrDecShow();
  37429. +#endif
  37430. +#if defined(MV_INCLUDE_GIG_ETH)
  37431. + mvEthAddrDecShow();
  37432. +#endif
  37433. +#if defined(MV_INCLUDE_XOR)
  37434. + mvXorAddrDecShow();
  37435. +#endif
  37436. +#if defined(MV_INCLUDE_SATA)
  37437. + mvSataAddrDecShow();
  37438. +#endif
  37439. +#if defined(MV_INCLUDE_AUDIO)
  37440. + mvAudioAddrDecShow();
  37441. +#endif
  37442. +#if defined(MV_INCLUDE_TS)
  37443. + mvTsuAddrDecShow();
  37444. +#endif
  37445. +}
  37446. +
  37447. +/*******************************************************************************
  37448. +* ctrlSizeToReg - Extract size value for register assignment.
  37449. +*
  37450. +* DESCRIPTION:
  37451. +* Address decode size parameter must be programed from LSB to MSB as
  37452. +* sequence of 1's followed by sequence of 0's. The number of 1's
  37453. +* specifies the size of the window in 64 KB granularity (e.g. a
  37454. +* value of 0x00ff specifies 256x64k = 16 MB).
  37455. +* This function extract the size value from the size parameter according
  37456. +* to given aligment paramter. For example for size 0x1000000 (16MB) and
  37457. +* aligment 0x10000 (64KB) the function will return 0x00FF.
  37458. +*
  37459. +* INPUT:
  37460. +* size - Size.
  37461. +* alignment - Size alignment. Note that alignment must be power of 2!
  37462. +*
  37463. +* OUTPUT:
  37464. +* None.
  37465. +*
  37466. +* RETURN:
  37467. +* 32bit describing size register value correspond to size parameter.
  37468. +* If value is '-1' size parameter or aligment are invalid.
  37469. +*******************************************************************************/
  37470. +MV_U32 ctrlSizeToReg(MV_U32 size, MV_U32 alignment)
  37471. +{
  37472. + MV_U32 retVal;
  37473. +
  37474. + /* Check size parameter alignment */
  37475. + if ((0 == size) || (MV_IS_NOT_ALIGN(size, alignment)))
  37476. + {
  37477. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Size is zero or not aligned.\n"));
  37478. + return -1;
  37479. + }
  37480. +
  37481. + /* Take out the "alignment" portion out of the size parameter */
  37482. + alignment--; /* Now the alignmet is a sequance of '1' (e.g. 0xffff) */
  37483. + /* and size is 0x1000000 (16MB) for example */
  37484. + while(alignment & 1) /* Check that alignmet LSB is set */
  37485. + {
  37486. + size = (size >> 1); /* If LSB is set, move 'size' one bit to right */
  37487. + alignment = (alignment >> 1);
  37488. + }
  37489. +
  37490. + /* If after the alignment first '0' was met we still have '1' in */
  37491. + /* it then aligment is invalid (not power of 2) */
  37492. + if (alignment)
  37493. + {
  37494. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n",
  37495. + (MV_U32)alignment));
  37496. + return -1;
  37497. + }
  37498. +
  37499. + /* Now the size is shifted right according to aligment: 0x0100 */
  37500. + size--; /* Now the size is a sequance of '1': 0x00ff */
  37501. +
  37502. + retVal = size ;
  37503. +
  37504. + /* Check that LSB to MSB is sequence of 1's followed by sequence of 0's */
  37505. + while(size & 1) /* Check that LSB is set */
  37506. + {
  37507. + size = (size >> 1); /* If LSB is set, move one bit to the right */
  37508. + }
  37509. +
  37510. + if (size) /* Sequance of 1's is over. Check that we have no other 1's */
  37511. + {
  37512. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Size parameter 0x%x invalid.\n",
  37513. + size));
  37514. + return -1;
  37515. + }
  37516. +
  37517. + return retVal;
  37518. +
  37519. +}
  37520. +
  37521. +/*******************************************************************************
  37522. +* ctrlRegToSize - Extract size value from register value.
  37523. +*
  37524. +* DESCRIPTION:
  37525. +* This function extract a size value from the register size parameter
  37526. +* according to given aligment paramter. For example for register size
  37527. +* value 0xff and aligment 0x10000 the function will return 0x01000000.
  37528. +*
  37529. +* INPUT:
  37530. +* regSize - Size as in register format. See ctrlSizeToReg.
  37531. +* alignment - Size alignment. Note that alignment must be power of 2!
  37532. +*
  37533. +* OUTPUT:
  37534. +* None.
  37535. +*
  37536. +* RETURN:
  37537. +* 32bit describing size.
  37538. +* If value is '-1' size parameter or aligment are invalid.
  37539. +*******************************************************************************/
  37540. +MV_U32 ctrlRegToSize(MV_U32 regSize, MV_U32 alignment)
  37541. +{
  37542. + MV_U32 temp;
  37543. +
  37544. + /* Check that LSB to MSB is sequence of 1's followed by sequence of 0's */
  37545. + temp = regSize; /* Now the size is a sequance of '1': 0x00ff */
  37546. +
  37547. + while(temp & 1) /* Check that LSB is set */
  37548. + {
  37549. + temp = (temp >> 1); /* If LSB is set, move one bit to the right */
  37550. + }
  37551. +
  37552. + if (temp) /* Sequance of 1's is over. Check that we have no other 1's */
  37553. + {
  37554. + DB(mvOsPrintf("ctrlRegToSize: ERR. Size parameter 0x%x invalid.\n",
  37555. + regSize));
  37556. + return -1;
  37557. + }
  37558. +
  37559. +
  37560. + /* Check that aligment is a power of two */
  37561. + temp = alignment - 1;/* Now the alignmet is a sequance of '1' (0xffff) */
  37562. +
  37563. + while(temp & 1) /* Check that alignmet LSB is set */
  37564. + {
  37565. + temp = (temp >> 1); /* If LSB is set, move 'size' one bit to right */
  37566. + }
  37567. +
  37568. + /* If after the 'temp' first '0' was met we still have '1' in 'temp' */
  37569. + /* then 'temp' is invalid (not power of 2) */
  37570. + if (temp)
  37571. + {
  37572. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n",
  37573. + alignment));
  37574. + return -1;
  37575. + }
  37576. +
  37577. + regSize++; /* Now the size is 0x0100 */
  37578. +
  37579. + /* Add in the "alignment" portion to the register size parameter */
  37580. + alignment--; /* Now the alignmet is a sequance of '1' (e.g. 0xffff) */
  37581. +
  37582. + while(alignment & 1) /* Check that alignmet LSB is set */
  37583. + {
  37584. + regSize = (regSize << 1); /* LSB is set, move 'size' one bit left */
  37585. + alignment = (alignment >> 1);
  37586. + }
  37587. +
  37588. + return regSize;
  37589. +}
  37590. +
  37591. +
  37592. +/*******************************************************************************
  37593. +* ctrlSizeRegRoundUp - Round up given size
  37594. +*
  37595. +* DESCRIPTION:
  37596. +* This function round up a given size to a size that fits the
  37597. +* restrictions of size format given an aligment parameter.
  37598. +* to given aligment paramter. For example for size parameter 0xa1000 and
  37599. +* aligment 0x1000 the function will return 0xFF000.
  37600. +*
  37601. +* INPUT:
  37602. +* size - Size.
  37603. +* alignment - Size alignment. Note that alignment must be power of 2!
  37604. +*
  37605. +* OUTPUT:
  37606. +* None.
  37607. +*
  37608. +* RETURN:
  37609. +* 32bit describing size value correspond to size in register.
  37610. +*******************************************************************************/
  37611. +MV_U32 ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment)
  37612. +{
  37613. + MV_U32 msbBit = 0;
  37614. + MV_U32 retSize;
  37615. +
  37616. + /* Check if size parameter is already comply with restriction */
  37617. + if (!(-1 == ctrlSizeToReg(size, alignment)))
  37618. + {
  37619. + return size;
  37620. + }
  37621. +
  37622. + while(size)
  37623. + {
  37624. + size = (size >> 1);
  37625. + msbBit++;
  37626. + }
  37627. +
  37628. + retSize = (1 << msbBit);
  37629. +
  37630. + if (retSize < alignment)
  37631. + {
  37632. + return alignment;
  37633. + }
  37634. + else
  37635. + {
  37636. + return retSize;
  37637. + }
  37638. +}
  37639. +/*******************************************************************************
  37640. +* mvCtrlSysRstLengthCounterGet - Return number of milliseconds the reset button
  37641. +* was pressed and clear counter
  37642. +*
  37643. +* DESCRIPTION:
  37644. +*
  37645. +* INPUT:
  37646. +*
  37647. +* OUTPUT:
  37648. +*
  37649. +* RETURN: number of milliseconds the reset button was pressed
  37650. +*******************************************************************************/
  37651. +MV_U32 mvCtrlSysRstLengthCounterGet(MV_VOID)
  37652. +{
  37653. + static volatile MV_U32 Count = 0;
  37654. +
  37655. + if(!Count) {
  37656. + Count = (MV_REG_READ(SYSRST_LENGTH_COUNTER_REG) & SLCR_COUNT_MASK);
  37657. + Count = (Count / (MV_BOARD_REFCLK_25MHZ / 1000));
  37658. + /* clear counter for next boot */
  37659. + MV_REG_BIT_SET(SYSRST_LENGTH_COUNTER_REG, SLCR_CLR_MASK);
  37660. + }
  37661. +
  37662. + DB(mvOsPrintf("mvCtrlSysRstLengthCounterGet: Reset button was pressed for %u milliseconds\n", Count));
  37663. +
  37664. + return Count;
  37665. +}
  37666. +
  37667. +MV_BOOL mvCtrlIsBootFromSPI(MV_VOID)
  37668. +{
  37669. + MV_U32 satr = 0;
  37670. + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  37671. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  37672. + {
  37673. + if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_SPI_WITH_BOOTROM_6180)
  37674. + return MV_TRUE;
  37675. + else
  37676. + return MV_FALSE;
  37677. + }
  37678. + satr = satr & MSAR_BOOT_MODE_MASK;
  37679. + if (satr == MSAR_BOOT_SPI_WITH_BOOTROM)
  37680. + return MV_TRUE;
  37681. + else
  37682. + return MV_FALSE;
  37683. +}
  37684. +
  37685. +MV_BOOL mvCtrlIsBootFromSPIUseNAND(MV_VOID)
  37686. +{
  37687. + MV_U32 satr = 0;
  37688. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  37689. + return MV_FALSE;
  37690. + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  37691. + satr = satr & MSAR_BOOT_MODE_MASK;
  37692. +
  37693. + if (satr == MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM)
  37694. + return MV_TRUE;
  37695. + else
  37696. + return MV_FALSE;
  37697. +}
  37698. +
  37699. +MV_BOOL mvCtrlIsBootFromNAND(MV_VOID)
  37700. +{
  37701. + MV_U32 satr = 0;
  37702. + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  37703. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  37704. + {
  37705. + if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_NAND_WITH_BOOTROM_6180)
  37706. + return MV_TRUE;
  37707. + else
  37708. + return MV_FALSE;
  37709. + }
  37710. + satr = satr & MSAR_BOOT_MODE_MASK;
  37711. + if ((satr == MSAR_BOOT_NAND_WITH_BOOTROM))
  37712. + return MV_TRUE;
  37713. + else
  37714. + return MV_FALSE;
  37715. +}
  37716. +
  37717. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  37718. +/*******************************************************************************
  37719. +* mvCtrlPwrSaveOn - Set Power save mode
  37720. +*
  37721. +* DESCRIPTION:
  37722. +*
  37723. +* INPUT:
  37724. +*
  37725. +* OUTPUT:
  37726. +*
  37727. +* RETURN:
  37728. +*******************************************************************************/
  37729. +MV_VOID mvCtrlPwrSaveOn(MV_VOID)
  37730. +{
  37731. + unsigned long old,temp;
  37732. + /* Disable int */
  37733. + __asm__ __volatile__("mrs %0, cpsr\n"
  37734. + "orr %1, %0, #0xc0\n"
  37735. + "msr cpsr_c, %1"
  37736. + : "=r" (old), "=r" (temp)
  37737. + :
  37738. + : "memory");
  37739. +
  37740. + /* Set SoC in power save */
  37741. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, BIT11);
  37742. + /* Wait for int */
  37743. + __asm__ __volatile__("mcr p15, 0, r0, c7, c0, 4");
  37744. +
  37745. + /* Enabled int */
  37746. + __asm__ __volatile__("msr cpsr_c, %0"
  37747. + :
  37748. + : "r" (old)
  37749. + : "memory");
  37750. +}
  37751. +
  37752. +
  37753. +
  37754. +/*******************************************************************************
  37755. +* mvCtrlPwrSaveOff - Go out of power save mode
  37756. +*
  37757. +* DESCRIPTION:
  37758. +*
  37759. +* INPUT:
  37760. +*
  37761. +* OUTPUT:
  37762. +*
  37763. +* RETURN:
  37764. +*******************************************************************************/
  37765. +MV_VOID mvCtrlPwrSaveOff(MV_VOID)
  37766. +{
  37767. + unsigned long old,temp;
  37768. + /* Disable int */
  37769. + __asm__ __volatile__("mrs %0, cpsr\n"
  37770. + "orr %1, %0, #0xc0\n"
  37771. + "msr cpsr_c, %1"
  37772. + : "=r" (old), "=r" (temp)
  37773. + :
  37774. + : "memory");
  37775. +
  37776. + /* Set SoC in power save */
  37777. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, BIT11);
  37778. + /* Wait for int */
  37779. + __asm__ __volatile__("mcr p15, 0, r0, c7, c0, 4");
  37780. +
  37781. + /* Enabled int */
  37782. + __asm__ __volatile__("msr cpsr_c, %0"
  37783. + :
  37784. + : "r" (old)
  37785. + : "memory");
  37786. +}
  37787. +
  37788. +/*******************************************************************************
  37789. +* mvCtrlPwrClckSet - Set Power State for specific Unit
  37790. +*
  37791. +* DESCRIPTION:
  37792. +*
  37793. +* INPUT:
  37794. +*
  37795. +* OUTPUT:
  37796. +*
  37797. +* RETURN:
  37798. +*******************************************************************************/
  37799. +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)
  37800. +{
  37801. + switch (unitId)
  37802. + {
  37803. +#if defined(MV_INCLUDE_PEX)
  37804. + case PEX_UNIT_ID:
  37805. + if (enable == MV_FALSE)
  37806. + {
  37807. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
  37808. + }
  37809. + else
  37810. + {
  37811. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
  37812. + }
  37813. + break;
  37814. +#endif
  37815. +#if defined(MV_INCLUDE_GIG_ETH)
  37816. + case ETH_GIG_UNIT_ID:
  37817. + if (enable == MV_FALSE)
  37818. + {
  37819. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
  37820. + }
  37821. + else
  37822. + {
  37823. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
  37824. + }
  37825. + break;
  37826. +#endif
  37827. +#if defined(MV_INCLUDE_INTEG_SATA)
  37828. + case SATA_UNIT_ID:
  37829. + if (enable == MV_FALSE)
  37830. + {
  37831. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));
  37832. + }
  37833. + else
  37834. + {
  37835. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));
  37836. + }
  37837. + break;
  37838. +#endif
  37839. +#if defined(MV_INCLUDE_CESA)
  37840. + case CESA_UNIT_ID:
  37841. + if (enable == MV_FALSE)
  37842. + {
  37843. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);
  37844. + }
  37845. + else
  37846. + {
  37847. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);
  37848. + }
  37849. + break;
  37850. +#endif
  37851. +#if defined(MV_INCLUDE_USB)
  37852. + case USB_UNIT_ID:
  37853. + if (enable == MV_FALSE)
  37854. + {
  37855. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);
  37856. + }
  37857. + else
  37858. + {
  37859. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);
  37860. + }
  37861. + break;
  37862. +#endif
  37863. +#if defined(MV_INCLUDE_AUDIO)
  37864. + case AUDIO_UNIT_ID:
  37865. + if (enable == MV_FALSE)
  37866. + {
  37867. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);
  37868. + }
  37869. + else
  37870. + {
  37871. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);
  37872. + }
  37873. + break;
  37874. +#endif
  37875. +#if defined(MV_INCLUDE_TS)
  37876. + case TS_UNIT_ID:
  37877. + if (enable == MV_FALSE)
  37878. + {
  37879. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);
  37880. + }
  37881. + else
  37882. + {
  37883. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);
  37884. + }
  37885. + break;
  37886. +#endif
  37887. +#if defined(MV_INCLUDE_SDIO)
  37888. + case SDIO_UNIT_ID:
  37889. + if (enable == MV_FALSE)
  37890. + {
  37891. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
  37892. + }
  37893. + else
  37894. + {
  37895. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
  37896. + }
  37897. + break;
  37898. +#endif
  37899. +#if defined(MV_INCLUDE_TDM)
  37900. + case TDM_UNIT_ID:
  37901. + if (enable == MV_FALSE)
  37902. + {
  37903. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);
  37904. + }
  37905. + else
  37906. + {
  37907. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);
  37908. + }
  37909. + break;
  37910. +#endif
  37911. +
  37912. + default:
  37913. +
  37914. + break;
  37915. +
  37916. + }
  37917. +}
  37918. +
  37919. +/*******************************************************************************
  37920. +* mvCtrlPwrClckGet - Get Power State of specific Unit
  37921. +*
  37922. +* DESCRIPTION:
  37923. +*
  37924. +* INPUT:
  37925. +*
  37926. +* OUTPUT:
  37927. +*
  37928. +* RETURN:
  37929. +******************************************************************************/
  37930. +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index)
  37931. +{
  37932. + MV_U32 reg = MV_REG_READ(POWER_MNG_CTRL_REG);
  37933. + MV_BOOL state = MV_TRUE;
  37934. +
  37935. + switch (unitId)
  37936. + {
  37937. +#if defined(MV_INCLUDE_PEX)
  37938. + case PEX_UNIT_ID:
  37939. + if ((reg & PMC_PEXSTOPCLOCK_MASK) == PMC_PEXSTOPCLOCK_STOP)
  37940. + {
  37941. + state = MV_FALSE;
  37942. + }
  37943. + else state = MV_TRUE;
  37944. +
  37945. + break;
  37946. +#endif
  37947. +#if defined(MV_INCLUDE_GIG_ETH)
  37948. + case ETH_GIG_UNIT_ID:
  37949. + if ((reg & PMC_GESTOPCLOCK_MASK(index)) == PMC_GESTOPCLOCK_STOP(index))
  37950. + {
  37951. + state = MV_FALSE;
  37952. + }
  37953. + else state = MV_TRUE;
  37954. + break;
  37955. +#endif
  37956. +#if defined(MV_INCLUDE_SATA)
  37957. + case SATA_UNIT_ID:
  37958. + if ((reg & PMC_SATASTOPCLOCK_MASK(index)) == PMC_SATASTOPCLOCK_STOP(index))
  37959. + {
  37960. + state = MV_FALSE;
  37961. + }
  37962. + else state = MV_TRUE;
  37963. + break;
  37964. +#endif
  37965. +#if defined(MV_INCLUDE_CESA)
  37966. + case CESA_UNIT_ID:
  37967. + if ((reg & PMC_SESTOPCLOCK_MASK) == PMC_SESTOPCLOCK_STOP)
  37968. + {
  37969. + state = MV_FALSE;
  37970. + }
  37971. + else state = MV_TRUE;
  37972. + break;
  37973. +#endif
  37974. +#if defined(MV_INCLUDE_USB)
  37975. + case USB_UNIT_ID:
  37976. + if ((reg & PMC_USBSTOPCLOCK_MASK) == PMC_USBSTOPCLOCK_STOP)
  37977. + {
  37978. + state = MV_FALSE;
  37979. + }
  37980. + else state = MV_TRUE;
  37981. + break;
  37982. +#endif
  37983. +#if defined(MV_INCLUDE_AUDIO)
  37984. + case AUDIO_UNIT_ID:
  37985. + if ((reg & PMC_AUDIOSTOPCLOCK_MASK) == PMC_AUDIOSTOPCLOCK_STOP)
  37986. + {
  37987. + state = MV_FALSE;
  37988. + }
  37989. + else state = MV_TRUE;
  37990. + break;
  37991. +#endif
  37992. +#if defined(MV_INCLUDE_TS)
  37993. + case TS_UNIT_ID:
  37994. + if ((reg & PMC_TSSTOPCLOCK_MASK) == PMC_TSSTOPCLOCK_STOP)
  37995. + {
  37996. + state = MV_FALSE;
  37997. + }
  37998. + else state = MV_TRUE;
  37999. + break;
  38000. +#endif
  38001. +#if defined(MV_INCLUDE_SDIO)
  38002. + case SDIO_UNIT_ID:
  38003. + if ((reg & PMC_SDIOSTOPCLOCK_MASK)== PMC_SDIOSTOPCLOCK_STOP)
  38004. + {
  38005. + state = MV_FALSE;
  38006. + }
  38007. + else state = MV_TRUE;
  38008. + break;
  38009. +#endif
  38010. +#if defined(MV_INCLUDE_TDM)
  38011. + case TDM_UNIT_ID:
  38012. + if ((reg & PMC_TDMSTOPCLOCK_MASK) == PMC_TDMSTOPCLOCK_STOP)
  38013. + {
  38014. + state = MV_FALSE;
  38015. + }
  38016. + else state = MV_TRUE;
  38017. + break;
  38018. +#endif
  38019. +
  38020. + default:
  38021. + state = MV_TRUE;
  38022. + break;
  38023. + }
  38024. +
  38025. +
  38026. + return state;
  38027. +}
  38028. +/*******************************************************************************
  38029. +* mvCtrlPwrMemSet - Set Power State for memory on specific Unit
  38030. +*
  38031. +* DESCRIPTION:
  38032. +*
  38033. +* INPUT:
  38034. +*
  38035. +* OUTPUT:
  38036. +*
  38037. +* RETURN:
  38038. +*******************************************************************************/
  38039. +MV_VOID mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)
  38040. +{
  38041. + switch (unitId)
  38042. + {
  38043. +#if defined(MV_INCLUDE_PEX)
  38044. + case PEX_UNIT_ID:
  38045. + if (enable == MV_FALSE)
  38046. + {
  38047. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);
  38048. + }
  38049. + else
  38050. + {
  38051. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);
  38052. + }
  38053. + break;
  38054. +#endif
  38055. +#if defined(MV_INCLUDE_GIG_ETH)
  38056. + case ETH_GIG_UNIT_ID:
  38057. + if (enable == MV_FALSE)
  38058. + {
  38059. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));
  38060. + }
  38061. + else
  38062. + {
  38063. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));
  38064. + }
  38065. + break;
  38066. +#endif
  38067. +#if defined(MV_INCLUDE_INTEG_SATA)
  38068. + case SATA_UNIT_ID:
  38069. + if (enable == MV_FALSE)
  38070. + {
  38071. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));
  38072. + }
  38073. + else
  38074. + {
  38075. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));
  38076. + }
  38077. + break;
  38078. +#endif
  38079. +#if defined(MV_INCLUDE_CESA)
  38080. + case CESA_UNIT_ID:
  38081. + if (enable == MV_FALSE)
  38082. + {
  38083. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);
  38084. + }
  38085. + else
  38086. + {
  38087. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);
  38088. + }
  38089. + break;
  38090. +#endif
  38091. +#if defined(MV_INCLUDE_USB)
  38092. + case USB_UNIT_ID:
  38093. + if (enable == MV_FALSE)
  38094. + {
  38095. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);
  38096. + }
  38097. + else
  38098. + {
  38099. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);
  38100. + }
  38101. + break;
  38102. +#endif
  38103. +#if defined(MV_INCLUDE_AUDIO)
  38104. + case AUDIO_UNIT_ID:
  38105. + if (enable == MV_FALSE)
  38106. + {
  38107. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);
  38108. + }
  38109. + else
  38110. + {
  38111. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);
  38112. + }
  38113. + break;
  38114. +#endif
  38115. +#if defined(MV_INCLUDE_XOR)
  38116. + case XOR_UNIT_ID:
  38117. + if (enable == MV_FALSE)
  38118. + {
  38119. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));
  38120. + }
  38121. + else
  38122. + {
  38123. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));
  38124. + }
  38125. + break;
  38126. +#endif
  38127. + default:
  38128. +
  38129. + break;
  38130. +
  38131. + }
  38132. +}
  38133. +
  38134. +/*******************************************************************************
  38135. +* mvCtrlPwrMemGet - Get Power State of memory on specific Unit
  38136. +*
  38137. +* DESCRIPTION:
  38138. +*
  38139. +* INPUT:
  38140. +*
  38141. +* OUTPUT:
  38142. +*
  38143. +* RETURN:
  38144. +******************************************************************************/
  38145. +MV_BOOL mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index)
  38146. +{
  38147. + MV_U32 reg = MV_REG_READ(POWER_MNG_MEM_CTRL_REG);
  38148. + MV_BOOL state = MV_TRUE;
  38149. +
  38150. + switch (unitId)
  38151. + {
  38152. +#if defined(MV_INCLUDE_PEX)
  38153. + case PEX_UNIT_ID:
  38154. + if ((reg & PMC_PEXSTOPMEM_MASK) == PMC_PEXSTOPMEM_STOP)
  38155. + {
  38156. + state = MV_FALSE;
  38157. + }
  38158. + else state = MV_TRUE;
  38159. +
  38160. + break;
  38161. +#endif
  38162. +#if defined(MV_INCLUDE_GIG_ETH)
  38163. + case ETH_GIG_UNIT_ID:
  38164. + if ((reg & PMC_GESTOPMEM_MASK(index)) == PMC_GESTOPMEM_STOP(index))
  38165. + {
  38166. + state = MV_FALSE;
  38167. + }
  38168. + else state = MV_TRUE;
  38169. + break;
  38170. +#endif
  38171. +#if defined(MV_INCLUDE_SATA)
  38172. + case SATA_UNIT_ID:
  38173. + if ((reg & PMC_SATASTOPMEM_MASK(index)) == PMC_SATASTOPMEM_STOP(index))
  38174. + {
  38175. + state = MV_FALSE;
  38176. + }
  38177. + else state = MV_TRUE;
  38178. + break;
  38179. +#endif
  38180. +#if defined(MV_INCLUDE_CESA)
  38181. + case CESA_UNIT_ID:
  38182. + if ((reg & PMC_SESTOPMEM_MASK) == PMC_SESTOPMEM_STOP)
  38183. + {
  38184. + state = MV_FALSE;
  38185. + }
  38186. + else state = MV_TRUE;
  38187. + break;
  38188. +#endif
  38189. +#if defined(MV_INCLUDE_USB)
  38190. + case USB_UNIT_ID:
  38191. + if ((reg & PMC_USBSTOPMEM_MASK) == PMC_USBSTOPMEM_STOP)
  38192. + {
  38193. + state = MV_FALSE;
  38194. + }
  38195. + else state = MV_TRUE;
  38196. + break;
  38197. +#endif
  38198. +#if defined(MV_INCLUDE_AUDIO)
  38199. + case AUDIO_UNIT_ID:
  38200. + if ((reg & PMC_AUDIOSTOPMEM_MASK) == PMC_AUDIOSTOPMEM_STOP)
  38201. + {
  38202. + state = MV_FALSE;
  38203. + }
  38204. + else state = MV_TRUE;
  38205. + break;
  38206. +#endif
  38207. +#if defined(MV_INCLUDE_XOR)
  38208. + case XOR_UNIT_ID:
  38209. + if ((reg & PMC_XORSTOPMEM_MASK(index)) == PMC_XORSTOPMEM_STOP(index))
  38210. + {
  38211. + state = MV_FALSE;
  38212. + }
  38213. + else state = MV_TRUE;
  38214. + break;
  38215. +#endif
  38216. +
  38217. + default:
  38218. + state = MV_TRUE;
  38219. + break;
  38220. + }
  38221. +
  38222. +
  38223. + return state;
  38224. +}
  38225. +#else
  38226. +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable) {return;}
  38227. +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index) {return MV_TRUE;}
  38228. +#endif /* #if defined(MV_INCLUDE_CLK_PWR_CNTRL) */
  38229. +
  38230. +
  38231. +/*******************************************************************************
  38232. +* mvMPPConfigToSPI - Change MPP[3:0] configuration to SPI mode
  38233. +*
  38234. +* DESCRIPTION:
  38235. +*
  38236. +* INPUT:
  38237. +*
  38238. +* OUTPUT:
  38239. +*
  38240. +* RETURN:
  38241. +******************************************************************************/
  38242. +MV_VOID mvMPPConfigToSPI(MV_VOID)
  38243. +{
  38244. + MV_U32 mppVal = 0;
  38245. + MV_U32 bootVal = 0;
  38246. +
  38247. + if(!mvCtrlIsBootFromSPIUseNAND())
  38248. + return;
  38249. + mppVal = 0x00002220; /* Set MPP [3:1] to SPI mode */
  38250. + bootVal = MV_REG_READ(mvCtrlMppRegGet(0));
  38251. + bootVal &= 0xffff000f;
  38252. + mppVal |= bootVal;
  38253. +
  38254. + MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);
  38255. +}
  38256. +
  38257. +
  38258. +/*******************************************************************************
  38259. +* mvMPPConfigToDefault - Change MPP[7:0] configuration to default configuration
  38260. +*
  38261. +* DESCRIPTION:
  38262. +*
  38263. +* INPUT:
  38264. +*
  38265. +* OUTPUT:
  38266. +*
  38267. +* RETURN:
  38268. +******************************************************************************/
  38269. +MV_VOID mvMPPConfigToDefault(MV_VOID)
  38270. +{
  38271. + MV_U32 mppVal = 0;
  38272. + MV_U32 bootVal = 0;
  38273. +
  38274. + if(!mvCtrlIsBootFromSPIUseNAND())
  38275. + return;
  38276. + mppVal = mvBoardMppGet(0);
  38277. + bootVal = MV_REG_READ(mvCtrlMppRegGet(0));
  38278. + mppVal &= ~0xffff000f;
  38279. + bootVal &= 0xffff000f;
  38280. + mppVal |= bootVal;
  38281. +
  38282. + MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);
  38283. +}
  38284. +
  38285. +
  38286. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h
  38287. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h 1970-01-01 01:00:00.000000000 +0100
  38288. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h 2010-11-09 20:28:07.742495476 +0100
  38289. @@ -0,0 +1,185 @@
  38290. +/*******************************************************************************
  38291. +Copyright (C) Marvell International Ltd. and its affiliates
  38292. +
  38293. +This software file (the "File") is owned and distributed by Marvell
  38294. +International Ltd. and/or its affiliates ("Marvell") under the following
  38295. +alternative licensing terms. Once you have made an election to distribute the
  38296. +File under one of the following license alternatives, please (i) delete this
  38297. +introductory statement regarding license alternatives, (ii) delete the two
  38298. +license alternatives that you have not elected to use and (iii) preserve the
  38299. +Marvell copyright notice above.
  38300. +
  38301. +********************************************************************************
  38302. +Marvell Commercial License Option
  38303. +
  38304. +If you received this File from Marvell and you have entered into a commercial
  38305. +license agreement (a "Commercial License") with Marvell, the File is licensed
  38306. +to you under the terms of the applicable Commercial License.
  38307. +
  38308. +********************************************************************************
  38309. +Marvell GPL License Option
  38310. +
  38311. +If you received this File from Marvell, you may opt to use, redistribute and/or
  38312. +modify this File in accordance with the terms and conditions of the General
  38313. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  38314. +available along with the File in the license.txt file or by writing to the Free
  38315. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  38316. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  38317. +
  38318. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  38319. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  38320. +DISCLAIMED. The GPL License provides additional details about this warranty
  38321. +disclaimer.
  38322. +********************************************************************************
  38323. +Marvell BSD License Option
  38324. +
  38325. +If you received this File from Marvell, you may opt to use, redistribute and/or
  38326. +modify this File under the following licensing terms.
  38327. +Redistribution and use in source and binary forms, with or without modification,
  38328. +are permitted provided that the following conditions are met:
  38329. +
  38330. + * Redistributions of source code must retain the above copyright notice,
  38331. + this list of conditions and the following disclaimer.
  38332. +
  38333. + * Redistributions in binary form must reproduce the above copyright
  38334. + notice, this list of conditions and the following disclaimer in the
  38335. + documentation and/or other materials provided with the distribution.
  38336. +
  38337. + * Neither the name of Marvell nor the names of its contributors may be
  38338. + used to endorse or promote products derived from this software without
  38339. + specific prior written permission.
  38340. +
  38341. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  38342. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  38343. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38344. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  38345. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  38346. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38347. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  38348. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38349. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  38350. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38351. +
  38352. +*******************************************************************************/
  38353. +
  38354. +
  38355. +#ifndef __INCmvCtrlEnvLibh
  38356. +#define __INCmvCtrlEnvLibh
  38357. +
  38358. +/* includes */
  38359. +#include "mvSysHwConfig.h"
  38360. +#include "mvCommon.h"
  38361. +#include "mvTypes.h"
  38362. +#include "mvOs.h"
  38363. +#include "boardEnv/mvBoardEnvLib.h"
  38364. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  38365. +#include "ctrlEnv/mvCtrlEnvRegs.h"
  38366. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  38367. +
  38368. +
  38369. +/* typedefs */
  38370. +
  38371. +/* This enumerator describes the possible HW cache coherency policies the */
  38372. +/* controllers supports. */
  38373. +typedef enum _mvCachePolicy
  38374. +{
  38375. + NO_COHERENCY, /* No HW cache coherency support */
  38376. + WT_COHERENCY, /* HW cache coherency supported in Write Through policy */
  38377. + WB_COHERENCY /* HW cache coherency supported in Write Back policy */
  38378. +}MV_CACHE_POLICY;
  38379. +
  38380. +
  38381. +/* The swapping is referred to a 64-bit words (as this is the controller */
  38382. +/* internal data path width). This enumerator describes the possible */
  38383. +/* data swap types. Below is an example of the data 0x0011223344556677 */
  38384. +typedef enum _mvSwapType
  38385. +{
  38386. + MV_BYTE_SWAP, /* Byte Swap 77 66 55 44 33 22 11 00 */
  38387. + MV_NO_SWAP, /* No swapping 00 11 22 33 44 55 66 77 */
  38388. + MV_BYTE_WORD_SWAP, /* Both byte and word swap 33 22 11 00 77 66 55 44 */
  38389. + MV_WORD_SWAP, /* Word swap 44 55 66 77 00 11 22 33 */
  38390. + SWAP_TYPE_MAX /* Delimiter for this enumerator */
  38391. +}MV_SWAP_TYPE;
  38392. +
  38393. +/* This structure describes access rights for Access protection windows */
  38394. +/* that can be found in IDMA, XOR, Ethernet and MPSC units. */
  38395. +/* Note that the permission enumerator coresponds to its register format. */
  38396. +/* For example, Read only premission is presented as "1" in register field. */
  38397. +typedef enum _mvAccessRights
  38398. +{
  38399. + NO_ACCESS_ALLOWED = 0, /* No access allowed */
  38400. + READ_ONLY = 1, /* Read only permission */
  38401. + ACC_RESERVED = 2, /* Reserved access right */
  38402. + FULL_ACCESS = 3, /* Read and Write permission */
  38403. + MAX_ACC_RIGHTS
  38404. +}MV_ACCESS_RIGHTS;
  38405. +
  38406. +
  38407. +/* mcspLib.h API list */
  38408. +
  38409. +MV_STATUS mvCtrlEnvInit(MV_VOID);
  38410. +MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup);
  38411. +
  38412. +#if defined(MV_INCLUDE_PEX)
  38413. +MV_U32 mvCtrlPexMaxIfGet(MV_VOID);
  38414. +#else
  38415. +#define mvCtrlPexMaxIfGet() (0)
  38416. +#endif
  38417. +
  38418. +#define mvCtrlPciIfMaxIfGet() (0)
  38419. +
  38420. +#if defined(MV_INCLUDE_GIG_ETH)
  38421. +MV_U32 mvCtrlEthMaxPortGet(MV_VOID);
  38422. +#endif
  38423. +#if defined(MV_INCLUDE_XOR)
  38424. +MV_U32 mvCtrlXorMaxChanGet(MV_VOID);
  38425. +#endif
  38426. +#if defined(MV_INCLUDE_USB)
  38427. +MV_U32 mvCtrlUsbMaxGet(MV_VOID);
  38428. +#endif
  38429. +#if defined(MV_INCLUDE_NAND)
  38430. +MV_U32 mvCtrlNandSupport(MV_VOID);
  38431. +#endif
  38432. +#if defined(MV_INCLUDE_SDIO)
  38433. +MV_U32 mvCtrlSdioSupport(MV_VOID);
  38434. +#endif
  38435. +#if defined(MV_INCLUDE_TS)
  38436. +MV_U32 mvCtrlTsSupport(MV_VOID);
  38437. +#endif
  38438. +#if defined(MV_INCLUDE_AUDIO)
  38439. +MV_U32 mvCtrlAudioSupport(MV_VOID);
  38440. +#endif
  38441. +#if defined(MV_INCLUDE_TDM)
  38442. +MV_U32 mvCtrlTdmSupport(MV_VOID);
  38443. +#endif
  38444. +
  38445. +MV_U16 mvCtrlModelGet(MV_VOID);
  38446. +MV_U8 mvCtrlRevGet(MV_VOID);
  38447. +MV_STATUS mvCtrlNameGet(char *pNameBuff);
  38448. +MV_U32 mvCtrlModelRevGet(MV_VOID);
  38449. +MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff);
  38450. +MV_VOID mvCtrlAddrDecShow(MV_VOID);
  38451. +const MV_8* mvCtrlTargetNameGet(MV_TARGET target);
  38452. +MV_U32 ctrlSizeToReg(MV_U32 size, MV_U32 alignment);
  38453. +MV_U32 ctrlRegToSize(MV_U32 regSize, MV_U32 alignment);
  38454. +MV_U32 ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment);
  38455. +MV_U32 mvCtrlSysRstLengthCounterGet(MV_VOID);
  38456. +MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);
  38457. +MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);
  38458. +
  38459. +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);
  38460. +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index);
  38461. +MV_VOID mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);
  38462. +MV_BOOL mvCtrlIsBootFromSPI(MV_VOID);
  38463. +MV_BOOL mvCtrlIsBootFromSPIUseNAND(MV_VOID);
  38464. +MV_BOOL mvCtrlIsBootFromNAND(MV_VOID);
  38465. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  38466. +MV_VOID mvCtrlPwrSaveOn(MV_VOID);
  38467. +MV_VOID mvCtrlPwrSaveOff(MV_VOID);
  38468. +#endif
  38469. +MV_BOOL mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index);
  38470. +MV_VOID mvMPPConfigToSPI(MV_VOID);
  38471. +MV_VOID mvMPPConfigToDefault(MV_VOID);
  38472. +
  38473. +
  38474. +#endif /* __INCmvCtrlEnvLibh */
  38475. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h
  38476. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h 1970-01-01 01:00:00.000000000 +0100
  38477. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h 2010-11-09 20:28:07.772495664 +0100
  38478. @@ -0,0 +1,419 @@
  38479. +/*******************************************************************************
  38480. +Copyright (C) Marvell International Ltd. and its affiliates
  38481. +
  38482. +This software file (the "File") is owned and distributed by Marvell
  38483. +International Ltd. and/or its affiliates ("Marvell") under the following
  38484. +alternative licensing terms. Once you have made an election to distribute the
  38485. +File under one of the following license alternatives, please (i) delete this
  38486. +introductory statement regarding license alternatives, (ii) delete the two
  38487. +license alternatives that you have not elected to use and (iii) preserve the
  38488. +Marvell copyright notice above.
  38489. +
  38490. +********************************************************************************
  38491. +Marvell Commercial License Option
  38492. +
  38493. +If you received this File from Marvell and you have entered into a commercial
  38494. +license agreement (a "Commercial License") with Marvell, the File is licensed
  38495. +to you under the terms of the applicable Commercial License.
  38496. +
  38497. +********************************************************************************
  38498. +Marvell GPL License Option
  38499. +
  38500. +If you received this File from Marvell, you may opt to use, redistribute and/or
  38501. +modify this File in accordance with the terms and conditions of the General
  38502. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  38503. +available along with the File in the license.txt file or by writing to the Free
  38504. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  38505. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  38506. +
  38507. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  38508. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  38509. +DISCLAIMED. The GPL License provides additional details about this warranty
  38510. +disclaimer.
  38511. +********************************************************************************
  38512. +Marvell BSD License Option
  38513. +
  38514. +If you received this File from Marvell, you may opt to use, redistribute and/or
  38515. +modify this File under the following licensing terms.
  38516. +Redistribution and use in source and binary forms, with or without modification,
  38517. +are permitted provided that the following conditions are met:
  38518. +
  38519. + * Redistributions of source code must retain the above copyright notice,
  38520. + this list of conditions and the following disclaimer.
  38521. +
  38522. + * Redistributions in binary form must reproduce the above copyright
  38523. + notice, this list of conditions and the following disclaimer in the
  38524. + documentation and/or other materials provided with the distribution.
  38525. +
  38526. + * Neither the name of Marvell nor the names of its contributors may be
  38527. + used to endorse or promote products derived from this software without
  38528. + specific prior written permission.
  38529. +
  38530. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  38531. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  38532. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38533. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  38534. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  38535. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38536. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  38537. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38538. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  38539. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38540. +
  38541. +*******************************************************************************/
  38542. +
  38543. +#ifndef __INCmvCtrlEnvRegsh
  38544. +#define __INCmvCtrlEnvRegsh
  38545. +
  38546. +#ifdef __cplusplus
  38547. +extern "C" {
  38548. +#endif /* __cplusplus */
  38549. +
  38550. +/* CV Support */
  38551. +#define PEX0_MEM0 PEX0_MEM
  38552. +#define PCI0_MEM0 PEX0_MEM
  38553. +
  38554. +/* Controller revision info */
  38555. +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008
  38556. +#define PCCRIR_REVID_OFFS 0 /* Revision ID */
  38557. +#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS)
  38558. +
  38559. +/* Controler environment registers offsets */
  38560. +
  38561. +/* Power Managment Control */
  38562. +#define POWER_MNG_MEM_CTRL_REG 0x20118
  38563. +
  38564. +#define PMC_GESTOPMEM_OFFS(port) ((port)? 13 : 0)
  38565. +#define PMC_GESTOPMEM_MASK(port) (1 << PMC_GESTOPMEM_OFFS(port))
  38566. +#define PMC_GESTOPMEM_EN(port) (0 << PMC_GESTOPMEM_OFFS(port))
  38567. +#define PMC_GESTOPMEM_STOP(port) (1 << PMC_GESTOPMEM_OFFS(port))
  38568. +
  38569. +#define PMC_PEXSTOPMEM_OFFS 1
  38570. +#define PMC_PEXSTOPMEM_MASK (1 << PMC_PEXSTOPMEM_OFFS)
  38571. +#define PMC_PEXSTOPMEM_EN (0 << PMC_PEXSTOPMEM_OFFS)
  38572. +#define PMC_PEXSTOPMEM_STOP (1 << PMC_PEXSTOPMEM_OFFS)
  38573. +
  38574. +#define PMC_USBSTOPMEM_OFFS 2
  38575. +#define PMC_USBSTOPMEM_MASK (1 << PMC_USBSTOPMEM_OFFS)
  38576. +#define PMC_USBSTOPMEM_EN (0 << PMC_USBSTOPMEM_OFFS)
  38577. +#define PMC_USBSTOPMEM_STOP (1 << PMC_USBSTOPMEM_OFFS)
  38578. +
  38579. +#define PMC_DUNITSTOPMEM_OFFS 3
  38580. +#define PMC_DUNITSTOPMEM_MASK (1 << PMC_DUNITSTOPMEM_OFFS)
  38581. +#define PMC_DUNITSTOPMEM_EN (0 << PMC_DUNITSTOPMEM_OFFS)
  38582. +#define PMC_DUNITSTOPMEM_STOP (1 << PMC_DUNITSTOPMEM_OFFS)
  38583. +
  38584. +#define PMC_RUNITSTOPMEM_OFFS 4
  38585. +#define PMC_RUNITSTOPMEM_MASK (1 << PMC_RUNITSTOPMEM_OFFS)
  38586. +#define PMC_RUNITSTOPMEM_EN (0 << PMC_RUNITSTOPMEM_OFFS)
  38587. +#define PMC_RUNITSTOPMEM_STOP (1 << PMC_RUNITSTOPMEM_OFFS)
  38588. +
  38589. +#define PMC_XORSTOPMEM_OFFS(port) (5+(port*2))
  38590. +#define PMC_XORSTOPMEM_MASK(port) (1 << PMC_XORSTOPMEM_OFFS(port))
  38591. +#define PMC_XORSTOPMEM_EN(port) (0 << PMC_XORSTOPMEM_OFFS(port))
  38592. +#define PMC_XORSTOPMEM_STOP(port) (1 << PMC_XORSTOPMEM_OFFS(port))
  38593. +
  38594. +#define PMC_SATASTOPMEM_OFFS(port) (6+(port*5))
  38595. +#define PMC_SATASTOPMEM_MASK(port) (1 << PMC_SATASTOPMEM_OFFS(port))
  38596. +#define PMC_SATASTOPMEM_EN(port) (0 << PMC_SATASTOPMEM_OFFS(port))
  38597. +#define PMC_SATASTOPMEM_STOP(port) (1 << PMC_SATASTOPMEM_OFFS(port))
  38598. +
  38599. +#define PMC_SESTOPMEM_OFFS 8
  38600. +#define PMC_SESTOPMEM_MASK (1 << PMC_SESTOPMEM_OFFS)
  38601. +#define PMC_SESTOPMEM_EN (0 << PMC_SESTOPMEM_OFFS)
  38602. +#define PMC_SESTOPMEM_STOP (1 << PMC_SESTOPMEM_OFFS)
  38603. +
  38604. +#define PMC_AUDIOSTOPMEM_OFFS 9
  38605. +#define PMC_AUDIOSTOPMEM_MASK (1 << PMC_AUDIOSTOPMEM_OFFS)
  38606. +#define PMC_AUDIOSTOPMEM_EN (0 << PMC_AUDIOSTOPMEM_OFFS)
  38607. +#define PMC_AUDIOSTOPMEM_STOP (1 << PMC_AUDIOSTOPMEM_OFFS)
  38608. +
  38609. +#define POWER_MNG_CTRL_REG 0x2011C
  38610. +
  38611. +#define PMC_GESTOPCLOCK_OFFS(port) ((port)? 19 : 0)
  38612. +#define PMC_GESTOPCLOCK_MASK(port) (1 << PMC_GESTOPCLOCK_OFFS(port))
  38613. +#define PMC_GESTOPCLOCK_EN(port) (1 << PMC_GESTOPCLOCK_OFFS(port))
  38614. +#define PMC_GESTOPCLOCK_STOP(port) (0 << PMC_GESTOPCLOCK_OFFS(port))
  38615. +
  38616. +#define PMC_PEXPHYSTOPCLOCK_OFFS 1
  38617. +#define PMC_PEXPHYSTOPCLOCK_MASK (1 << PMC_PEXPHYSTOPCLOCK_OFFS)
  38618. +#define PMC_PEXPHYSTOPCLOCK_EN (1 << PMC_PEXPHYSTOPCLOCK_OFFS)
  38619. +#define PMC_PEXPHYSTOPCLOCK_STOP (0 << PMC_PEXPHYSTOPCLOCK_OFFS)
  38620. +
  38621. +#define PMC_PEXSTOPCLOCK_OFFS 2
  38622. +#define PMC_PEXSTOPCLOCK_MASK (1 << PMC_PEXSTOPCLOCK_OFFS)
  38623. +#define PMC_PEXSTOPCLOCK_EN (1 << PMC_PEXSTOPCLOCK_OFFS)
  38624. +#define PMC_PEXSTOPCLOCK_STOP (0 << PMC_PEXSTOPCLOCK_OFFS)
  38625. +
  38626. +#define PMC_USBSTOPCLOCK_OFFS 3
  38627. +#define PMC_USBSTOPCLOCK_MASK (1 << PMC_USBSTOPCLOCK_OFFS)
  38628. +#define PMC_USBSTOPCLOCK_EN (1 << PMC_USBSTOPCLOCK_OFFS)
  38629. +#define PMC_USBSTOPCLOCK_STOP (0 << PMC_USBSTOPCLOCK_OFFS)
  38630. +
  38631. +#define PMC_SDIOSTOPCLOCK_OFFS 4
  38632. +#define PMC_SDIOSTOPCLOCK_MASK (1 << PMC_SDIOSTOPCLOCK_OFFS)
  38633. +#define PMC_SDIOSTOPCLOCK_EN (1 << PMC_SDIOSTOPCLOCK_OFFS)
  38634. +#define PMC_SDIOSTOPCLOCK_STOP (0 << PMC_SDIOSTOPCLOCK_OFFS)
  38635. +
  38636. +#define PMC_TSSTOPCLOCK_OFFS 5
  38637. +#define PMC_TSSTOPCLOCK_MASK (1 << PMC_TSSTOPCLOCK_OFFS)
  38638. +#define PMC_TSSTOPCLOCK_EN (1 << PMC_TSSTOPCLOCK_OFFS)
  38639. +#define PMC_TSSTOPCLOCK_STOP (0 << PMC_TSSTOPCLOCK_OFFS)
  38640. +
  38641. +#define PMC_AUDIOSTOPCLOCK_OFFS 9
  38642. +#define PMC_AUDIOSTOPCLOCK_MASK (1 << PMC_AUDIOSTOPCLOCK_OFFS)
  38643. +#define PMC_AUDIOSTOPCLOCK_EN (1 << PMC_AUDIOSTOPCLOCK_OFFS)
  38644. +#define PMC_AUDIOSTOPCLOCK_STOP (0 << PMC_AUDIOSTOPCLOCK_OFFS)
  38645. +
  38646. +#define PMC_POWERSAVE_OFFS 11
  38647. +#define PMC_POWERSAVE_MASK (1 << PMC_POWERSAVE_OFFS)
  38648. +#define PMC_POWERSAVE_EN (1 << PMC_POWERSAVE_OFFS)
  38649. +#define PMC_POWERSAVE_STOP (0 << PMC_POWERSAVE_OFFS)
  38650. +
  38651. +
  38652. +
  38653. +
  38654. +#define PMC_SATASTOPCLOCK_OFFS(port) (14+(port))
  38655. +#define PMC_SATASTOPCLOCK_MASK(port) (1 << PMC_SATASTOPCLOCK_OFFS(port))
  38656. +#define PMC_SATASTOPCLOCK_EN(port) (1 << PMC_SATASTOPCLOCK_OFFS(port))
  38657. +#define PMC_SATASTOPCLOCK_STOP(port) (0 << PMC_SATASTOPCLOCK_OFFS(port))
  38658. +
  38659. +#define PMC_SESTOPCLOCK_OFFS 17
  38660. +#define PMC_SESTOPCLOCK_MASK (1 << PMC_SESTOPCLOCK_OFFS)
  38661. +#define PMC_SESTOPCLOCK_EN (1 << PMC_SESTOPCLOCK_OFFS)
  38662. +#define PMC_SESTOPCLOCK_STOP (0 << PMC_SESTOPCLOCK_OFFS)
  38663. +
  38664. +#define PMC_TDMSTOPCLOCK_OFFS 20
  38665. +#define PMC_TDMSTOPCLOCK_MASK (1 << PMC_TDMSTOPCLOCK_OFFS)
  38666. +#define PMC_TDMSTOPCLOCK_EN (1 << PMC_TDMSTOPCLOCK_OFFS)
  38667. +#define PMC_TDMSTOPCLOCK_STOP (0 << PMC_TDMSTOPCLOCK_OFFS)
  38668. +
  38669. +
  38670. +/* Controler environment registers offsets */
  38671. +#define MPP_CONTROL_REG0 0x10000
  38672. +#define MPP_CONTROL_REG1 0x10004
  38673. +#define MPP_CONTROL_REG2 0x10008
  38674. +#define MPP_CONTROL_REG3 0x1000C
  38675. +#define MPP_CONTROL_REG4 0x10010
  38676. +#define MPP_CONTROL_REG5 0x10014
  38677. +#define MPP_CONTROL_REG6 0x10018
  38678. +#define MPP_SAMPLE_AT_RESET 0x10030
  38679. +#define CHIP_BOND_REG 0x10034
  38680. +#define SYSRST_LENGTH_COUNTER_REG 0x10050
  38681. +#define SLCR_COUNT_OFFS 0
  38682. +#define SLCR_COUNT_MASK (0x1FFFFFFF << SLCR_COUNT_OFFS)
  38683. +#define SLCR_CLR_OFFS 31
  38684. +#define SLCR_CLR_MASK (1 << SLCR_CLR_OFFS)
  38685. +#define PCKG_OPT_MASK 0x3
  38686. +#define MPP_OUTPUT_DRIVE_REG 0x100E0
  38687. +#define MPP_RGMII0_OUTPUT_DRIVE_OFFS 7
  38688. +#define MPP_3_3_RGMII0_OUTPUT_DRIVE (0x0 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)
  38689. +#define MPP_1_8_RGMII0_OUTPUT_DRIVE (0x1 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)
  38690. +#define MPP_RGMII1_OUTPUT_DRIVE_OFFS 15
  38691. +#define MPP_3_3_RGMII1_OUTPUT_DRIVE (0x0 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)
  38692. +#define MPP_1_8_RGMII1_OUTPUT_DRIVE (0x1 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)
  38693. +
  38694. +#define MSAR_BOOT_MODE_OFFS 12
  38695. +#define MSAR_BOOT_MODE_MASK (0x7 << MSAR_BOOT_MODE_OFFS)
  38696. +#define MSAR_BOOT_NAND_WITH_BOOTROM (0x5 << MSAR_BOOT_MODE_OFFS)
  38697. +#define MSAR_BOOT_SPI_WITH_BOOTROM (0x4 << MSAR_BOOT_MODE_OFFS)
  38698. +#define MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM (0x2 << MSAR_BOOT_MODE_OFFS)
  38699. +
  38700. +#define MSAR_BOOT_MODE_6180(X) (((X & 0x3000) >> 12) | \
  38701. + ((X & 0x2) << 1))
  38702. +#define MSAR_BOOT_SPI_WITH_BOOTROM_6180 0x1
  38703. +#define MSAR_BOOT_NAND_WITH_BOOTROM_6180 0x5
  38704. +
  38705. +#define MSAR_TCLCK_OFFS 21
  38706. +#define MSAR_TCLCK_MASK (0x1 << MSAR_TCLCK_OFFS)
  38707. +#define MSAR_TCLCK_166 (0x1 << MSAR_TCLCK_OFFS)
  38708. +#define MSAR_TCLCK_200 (0x0 << MSAR_TCLCK_OFFS)
  38709. +
  38710. +
  38711. +#define MSAR_CPUCLCK_EXTRACT(X) (((X & 0x2) >> 1) | ((X & 0x400000) >> 21) | \
  38712. + ((X & 0x18) >> 1))
  38713. +
  38714. +#define MSAR_CPUCLCK_OFFS_6180 2
  38715. +#define MSAR_CPUCLCK_MASK_6180 (0x7 << MSAR_CPUCLCK_OFFS_6180)
  38716. +
  38717. +#define MSAR_DDRCLCK_RTIO_OFFS 5
  38718. +#define MSAR_DDRCLCK_RTIO_MASK (0xF << MSAR_DDRCLCK_RTIO_OFFS)
  38719. +
  38720. +#define MSAR_L2CLCK_EXTRACT(X) (((X & 0x600) >> 9) | ((X & 0x80000) >> 17))
  38721. +
  38722. +#ifndef MV_ASMLANGUAGE
  38723. +/* CPU clock for 6281,6192 0->Resereved */
  38724. +#define MV_CPU_CLCK_TBL { 0, 0, 0, 0, \
  38725. + 600000000, 0, 800000000, 1000000000, \
  38726. + 0, 1200000000, 0, 0, \
  38727. + 1500000000, 0, 0, 0}
  38728. +
  38729. +/* DDR clock RATIO for 6281,6192 {0,0}->Reserved */
  38730. +#define MV_DDR_CLCK_RTIO_TBL {\
  38731. + {0, 0}, {0, 0}, {2, 1}, {0, 0}, \
  38732. + {3, 1}, {0, 0}, {4, 1}, {9, 2}, \
  38733. + {5, 1}, {6, 1}, {0, 0}, {0, 0}, \
  38734. + {0, 0}, {0, 0}, {0, 0}, {0, 0} \
  38735. +}
  38736. +
  38737. +/* L2 clock RATIO for 6281,6192 {1,1}->Reserved */
  38738. +#define MV_L2_CLCK_RTIO_TBL {\
  38739. + {0, 0}, {2, 1}, {0, 0}, {3, 1}, \
  38740. + {0, 0}, {0, 0}, {0, 0}, {0, 0} \
  38741. +}
  38742. +
  38743. +/* 6180 have different clk reset sampling */
  38744. +/* ARM CPU, DDR, L2 clock for 6180 {0,0,0}->Reserved */
  38745. +#define MV_CPU6180_DDR_L2_CLCK_TBL { \
  38746. + {0, 0, 0 },\
  38747. + {0, 0, 0 },\
  38748. + {0, 0, 0 },\
  38749. + {0, 0, 0 },\
  38750. + {0, 0, 0 },\
  38751. + {600000000, 200000000, 300000000 },\
  38752. + {800000000, 200000000, 400000000 },\
  38753. + {0, 0, 0 }\
  38754. +}
  38755. +
  38756. +
  38757. +
  38758. +/* These macros help units to identify a target Mbus Arbiter group */
  38759. +#define MV_TARGET_IS_DRAM(target) \
  38760. + ((target >= SDRAM_CS0) && (target <= SDRAM_CS3))
  38761. +
  38762. +#define MV_TARGET_IS_PEX0(target) \
  38763. + ((target >= PEX0_MEM) && (target <= PEX0_IO))
  38764. +
  38765. +#define MV_TARGET_IS_PEX1(target) 0
  38766. +
  38767. +#define MV_TARGET_IS_PEX(target) (MV_TARGET_IS_PEX0(target) || MV_TARGET_IS_PEX1(target))
  38768. +
  38769. +#define MV_TARGET_IS_DEVICE(target) \
  38770. + ((target >= DEVICE_CS0) && (target <= DEVICE_CS3))
  38771. +
  38772. +#define MV_PCI_DRAM_BAR_TO_DRAM_TARGET(bar) 0
  38773. +
  38774. +#define MV_TARGET_IS_AS_BOOT(target) ((target) == (sampleAtResetTargetArray[ \
  38775. + (mvCtrlModelGet() == MV_6180_DEV_ID)? MSAR_BOOT_MODE_6180 \
  38776. + (MV_REG_READ(MPP_SAMPLE_AT_RESET)):((MV_REG_READ(MPP_SAMPLE_AT_RESET)\
  38777. + & MSAR_BOOT_MODE_MASK) >> MSAR_BOOT_MODE_OFFS)]))
  38778. +
  38779. +
  38780. +#define MV_CHANGE_BOOT_CS(target) (((target) == DEV_BOOCS)?\
  38781. + sampleAtResetTargetArray[(mvCtrlModelGet() == MV_6180_DEV_ID)? \
  38782. + MSAR_BOOT_MODE_6180(MV_REG_READ(MPP_SAMPLE_AT_RESET)): \
  38783. + ((MV_REG_READ(MPP_SAMPLE_AT_RESET) & MSAR_BOOT_MODE_MASK)\
  38784. + >> MSAR_BOOT_MODE_OFFS)]:(target))
  38785. +
  38786. +#define TCLK_TO_COUNTER_RATIO 1 /* counters running in Tclk */
  38787. +
  38788. +#define BOOT_TARGETS_NAME_ARRAY { \
  38789. + TBL_TERM, \
  38790. + TBL_TERM, \
  38791. + BOOT_ROM_CS, \
  38792. + TBL_TERM, \
  38793. + BOOT_ROM_CS, \
  38794. + BOOT_ROM_CS, \
  38795. + TBL_TERM, \
  38796. + TBL_TERM \
  38797. +}
  38798. +
  38799. +#define BOOT_TARGETS_NAME_ARRAY_6180 { \
  38800. + TBL_TERM, \
  38801. + BOOT_ROM_CS, \
  38802. + TBL_TERM, \
  38803. + TBL_TERM, \
  38804. + TBL_TERM, \
  38805. + BOOT_ROM_CS, \
  38806. + TBL_TERM, \
  38807. + TBL_TERM \
  38808. +}
  38809. +
  38810. +
  38811. +/* For old competability */
  38812. +#define DEVICE_CS0 NFLASH_CS
  38813. +#define DEVICE_CS1 SPI_CS
  38814. +#define DEVICE_CS2 BOOT_ROM_CS
  38815. +#define DEVICE_CS3 DEV_BOOCS
  38816. +#define MV_BOOTDEVICE_INDEX 0
  38817. +
  38818. +#define START_DEV_CS DEV_CS0
  38819. +#define DEV_TO_TARGET(dev) ((dev) + DEVICE_CS0)
  38820. +
  38821. +#define PCI_IF0_MEM0 PEX0_MEM
  38822. +#define PCI_IF0_IO PEX0_IO
  38823. +
  38824. +
  38825. +/* This enumerator defines the Marvell controller target ID */
  38826. +typedef enum _mvTargetId
  38827. +{
  38828. + DRAM_TARGET_ID = 0 , /* Port 0 -> DRAM interface */
  38829. + DEV_TARGET_ID = 1, /* Port 1 -> Nand/SPI */
  38830. + PEX0_TARGET_ID = 4 , /* Port 4 -> PCI Express0 */
  38831. + CRYPT_TARGET_ID = 3 , /* Port 3 --> Crypto Engine */
  38832. + SAGE_TARGET_ID = 12 , /* Port 12 -> SAGE Unit */
  38833. + MAX_TARGETS_ID
  38834. +}MV_TARGET_ID;
  38835. +
  38836. +
  38837. +/* This enumerator described the possible Controller paripheral targets. */
  38838. +/* Controller peripherals are designated memory/IO address spaces that the */
  38839. +/* controller can access. They are also refered as "targets" */
  38840. +typedef enum _mvTarget
  38841. +{
  38842. + TBL_TERM = -1, /* none valid target, used as targets list terminator*/
  38843. + SDRAM_CS0, /* SDRAM chip select 0 */
  38844. + SDRAM_CS1, /* SDRAM chip select 1 */
  38845. + SDRAM_CS2, /* SDRAM chip select 2 */
  38846. + SDRAM_CS3, /* SDRAM chip select 3 */
  38847. + PEX0_MEM, /* PCI Express 0 Memory */
  38848. + PEX0_IO, /* PCI Express 0 IO */
  38849. + INTER_REGS, /* Internal registers */
  38850. + NFLASH_CS, /* NFLASH_CS */
  38851. + SPI_CS, /* SPI_CS */
  38852. + BOOT_ROM_CS, /* BOOT_ROM_CS */
  38853. + DEV_BOOCS, /* DEV_BOOCS */
  38854. + CRYPT_ENG, /* Crypto Engine */
  38855. +#ifdef MV_INCLUDE_SAGE
  38856. + SAGE_UNIT, /* SAGE Unit */
  38857. +#endif
  38858. + MAX_TARGETS
  38859. +
  38860. +}MV_TARGET;
  38861. +
  38862. +#define TARGETS_DEF_ARRAY { \
  38863. + {0x0E, DRAM_TARGET_ID }, /* SDRAM_CS0 */ \
  38864. + {0x0D, DRAM_TARGET_ID }, /* SDRAM_CS1 */ \
  38865. + {0x0B, DRAM_TARGET_ID }, /* SDRAM_CS0 */ \
  38866. + {0x07, DRAM_TARGET_ID }, /* SDRAM_CS1 */ \
  38867. + {0xE8, PEX0_TARGET_ID }, /* PEX0_MEM */ \
  38868. + {0xE0, PEX0_TARGET_ID }, /* PEX0_IO */ \
  38869. + {0xFF, 0xFF }, /* INTER_REGS */ \
  38870. + {0x2F, DEV_TARGET_ID }, /* NFLASH_CS */ \
  38871. + {0x1E, DEV_TARGET_ID }, /* SPI_CS */ \
  38872. + {0x1D, DEV_TARGET_ID }, /* BOOT_ROM_CS */ \
  38873. + {0x1E, DEV_TARGET_ID }, /* DEV_BOOCS */ \
  38874. + {0x01, CRYPT_TARGET_ID}, /* CRYPT_ENG */ \
  38875. + {0x00, SAGE_TARGET_ID } \
  38876. +}
  38877. +
  38878. +
  38879. +#define TARGETS_NAME_ARRAY { \
  38880. + "SDRAM_CS0", /* SDRAM_CS0 */ \
  38881. + "SDRAM_CS1", /* SDRAM_CS1 */ \
  38882. + "SDRAM_CS2", /* SDRAM_CS2 */ \
  38883. + "SDRAM_CS3", /* SDRAM_CS3 */ \
  38884. + "PEX0_MEM", /* PEX0_MEM */ \
  38885. + "PEX0_IO", /* PEX0_IO */ \
  38886. + "INTER_REGS", /* INTER_REGS */ \
  38887. + "NFLASH_CS", /* NFLASH_CS */ \
  38888. + "SPI_CS", /* SPI_CS */ \
  38889. + "BOOT_ROM_CS", /* BOOT_ROM_CS */ \
  38890. + "DEV_BOOTCS", /* DEV_BOOCS */ \
  38891. + "CRYPT_ENG", /* CRYPT_ENG */ \
  38892. + "SAGE_UNIT" /* SAGE_UNIT */ \
  38893. +}
  38894. +#endif /* MV_ASMLANGUAGE */
  38895. +
  38896. +
  38897. +#endif
  38898. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h
  38899. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h 1970-01-01 01:00:00.000000000 +0100
  38900. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h 2010-11-09 20:28:07.802495420 +0100
  38901. @@ -0,0 +1,257 @@
  38902. +/*******************************************************************************
  38903. +Copyright (C) Marvell International Ltd. and its affiliates
  38904. +
  38905. +This software file (the "File") is owned and distributed by Marvell
  38906. +International Ltd. and/or its affiliates ("Marvell") under the following
  38907. +alternative licensing terms. Once you have made an election to distribute the
  38908. +File under one of the following license alternatives, please (i) delete this
  38909. +introductory statement regarding license alternatives, (ii) delete the two
  38910. +license alternatives that you have not elected to use and (iii) preserve the
  38911. +Marvell copyright notice above.
  38912. +
  38913. +********************************************************************************
  38914. +Marvell Commercial License Option
  38915. +
  38916. +If you received this File from Marvell and you have entered into a commercial
  38917. +license agreement (a "Commercial License") with Marvell, the File is licensed
  38918. +to you under the terms of the applicable Commercial License.
  38919. +
  38920. +********************************************************************************
  38921. +Marvell GPL License Option
  38922. +
  38923. +If you received this File from Marvell, you may opt to use, redistribute and/or
  38924. +modify this File in accordance with the terms and conditions of the General
  38925. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  38926. +available along with the File in the license.txt file or by writing to the Free
  38927. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  38928. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  38929. +
  38930. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  38931. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  38932. +DISCLAIMED. The GPL License provides additional details about this warranty
  38933. +disclaimer.
  38934. +********************************************************************************
  38935. +Marvell BSD License Option
  38936. +
  38937. +If you received this File from Marvell, you may opt to use, redistribute and/or
  38938. +modify this File under the following licensing terms.
  38939. +Redistribution and use in source and binary forms, with or without modification,
  38940. +are permitted provided that the following conditions are met:
  38941. +
  38942. + * Redistributions of source code must retain the above copyright notice,
  38943. + this list of conditions and the following disclaimer.
  38944. +
  38945. + * Redistributions in binary form must reproduce the above copyright
  38946. + notice, this list of conditions and the following disclaimer in the
  38947. + documentation and/or other materials provided with the distribution.
  38948. +
  38949. + * Neither the name of Marvell nor the names of its contributors may be
  38950. + used to endorse or promote products derived from this software without
  38951. + specific prior written permission.
  38952. +
  38953. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  38954. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  38955. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38956. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  38957. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  38958. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38959. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  38960. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38961. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  38962. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38963. +
  38964. +*******************************************************************************/
  38965. +
  38966. +#ifndef __INCmvCtrlEnvSpech
  38967. +#define __INCmvCtrlEnvSpech
  38968. +
  38969. +#include "mvDeviceId.h"
  38970. +#include "mvSysHwConfig.h"
  38971. +
  38972. +#ifdef __cplusplus
  38973. +extern "C" {
  38974. +#endif /* __cplusplus */
  38975. +
  38976. +#define MV_ARM_SOC
  38977. +#define SOC_NAME_PREFIX "MV88F"
  38978. +
  38979. +
  38980. +/* units base and port numbers */
  38981. +#ifdef MV_ASMLANGUAGE
  38982. +#define XOR_UNIT_BASE(unit) 0x60800
  38983. +#else
  38984. +#define MV_XOR_REG_BASE 0x60000
  38985. +#define XOR_UNIT_BASE(unit) ((unit)? 0x60900:0x60800)
  38986. +#endif
  38987. +
  38988. +#define TDM_REG_BASE 0xD0000
  38989. +#define USB_REG_BASE(dev) 0x50000
  38990. +#define AUDIO_REG_BASE 0xA0000
  38991. +#define SATA_REG_BASE 0x80000
  38992. +#define MV_CESA_REG_BASE 0x3D000
  38993. +#define MV_CESA_TDMA_REG_BASE 0x30000
  38994. +#define MV_SDIO_REG_BASE 0x90000
  38995. +#define MV_ETH_REG_BASE(port) (((port) == 0) ? 0x72000 : 0x76000)
  38996. +#define MV_UART_CHAN_BASE(chanNum) (0x12000 + (chanNum * 0x100))
  38997. +#define DRAM_BASE 0x0
  38998. +#define CNTMR_BASE 0x20300
  38999. +#define TWSI_SLAVE_BASE(chanNum) 0x11000
  39000. +#define PEX_IF_BASE(pexIf) 0x40000
  39001. +#define MPP_REG_BASE 0x10000
  39002. +#define TSU_GLOBAL_REG_BASE 0xB4000
  39003. +#define MAX_AHB_TO_MBUS_REG_BASE 0x20000
  39004. +
  39005. +#define INTER_REGS_SIZE _1M
  39006. +/* This define describes the TWSI interrupt bit and location */
  39007. +#define TWSI_CPU_MAIN_INT_CAUSE_REG 0x20200
  39008. +#define TWSI0_CPU_MAIN_INT_BIT (1<<29)
  39009. +#define TWSI_SPEED 100000
  39010. +
  39011. +#define MV_GPP_MAX_GROUP 2
  39012. +#define MV_CNTMR_MAX_COUNTER 2
  39013. +#define MV_UART_MAX_CHAN 2
  39014. +#define MV_XOR_MAX_UNIT 2
  39015. +#define MV_XOR_MAX_CHAN 4 /* total channels for all units together*/
  39016. +#define MV_XOR_MAX_CHAN_PER_UNIT 2 /* channels for units */
  39017. +#define MV_SATA_MAX_CHAN 2
  39018. +
  39019. +#define MV_6281_MPP_MAX_MODULE 2
  39020. +#define MV_6192_MPP_MAX_MODULE 1
  39021. +#define MV_6190_MPP_MAX_MODULE 1
  39022. +#define MV_6180_MPP_MAX_MODULE 2
  39023. +#define MV_6281_MPP_MAX_GROUP 7
  39024. +#define MV_6192_MPP_MAX_GROUP 4
  39025. +#define MV_6190_MPP_MAX_GROUP 4
  39026. +#define MV_6180_MPP_MAX_GROUP 3
  39027. +
  39028. +#define MV_DRAM_MAX_CS 4
  39029. +
  39030. +/* This define describes the maximum number of supported PCI\PCIX Interfaces*/
  39031. +#define MV_PCI_MAX_IF 0
  39032. +#define MV_PCI_START_IF 0
  39033. +
  39034. +/* This define describes the maximum number of supported PEX Interfaces */
  39035. +#define MV_INCLUDE_PEX0
  39036. +#define MV_DISABLE_PEX_DEVICE_BAR
  39037. +#define MV_PEX_MAX_IF 1
  39038. +#define MV_PEX_START_IF MV_PCI_MAX_IF
  39039. +
  39040. +/* This define describes the maximum number of supported PCI Interfaces */
  39041. +#define MV_PCI_IF_MAX_IF (MV_PEX_MAX_IF+MV_PCI_MAX_IF)
  39042. +
  39043. +#define MV_ETH_MAX_PORTS 2
  39044. +#define MV_6281_ETH_MAX_PORTS 2
  39045. +#define MV_6192_ETH_MAX_PORTS 2
  39046. +#define MV_6190_ETH_MAX_PORTS 1
  39047. +#define MV_6180_ETH_MAX_PORTS 1
  39048. +
  39049. +#define MV_IDMA_MAX_CHAN 0
  39050. +
  39051. +#define MV_USB_MAX_PORTS 1
  39052. +
  39053. +#define MV_USB_VERSION 1
  39054. +
  39055. +
  39056. +#define MV_6281_NAND 1
  39057. +#define MV_6192_NAND 1
  39058. +#define MV_6190_NAND 1
  39059. +#define MV_6180_NAND 0
  39060. +
  39061. +#define MV_6281_SDIO 1
  39062. +#define MV_6192_SDIO 1
  39063. +#define MV_6190_SDIO 1
  39064. +#define MV_6180_SDIO 1
  39065. +
  39066. +#define MV_6281_TS 1
  39067. +#define MV_6192_TS 1
  39068. +#define MV_6190_TS 0
  39069. +#define MV_6180_TS 0
  39070. +
  39071. +#define MV_6281_AUDIO 1
  39072. +#define MV_6192_AUDIO 1
  39073. +#define MV_6190_AUDIO 0
  39074. +#define MV_6180_AUDIO 1
  39075. +
  39076. +#define MV_6281_TDM 1
  39077. +#define MV_6192_TDM 1
  39078. +#define MV_6190_TDM 0
  39079. +#define MV_6180_TDM 0
  39080. +
  39081. +#define MV_DEVICE_MAX_CS 4
  39082. +
  39083. +/* Others */
  39084. +#define PEX_HOST_BUS_NUM(pciIf) (pciIf)
  39085. +#define PEX_HOST_DEV_NUM(pciIf) 0
  39086. +
  39087. +#define PCI_IO(pciIf) (PEX0_IO)
  39088. +#define PCI_MEM(pciIf, memNum) (PEX0_MEM0)
  39089. +/* CESA version #2: One channel, 2KB SRAM, TDMA */
  39090. +#if defined(MV_CESA_CHAIN_MODE_SUPPORT)
  39091. + #define MV_CESA_VERSION 3
  39092. +#else
  39093. +#define MV_CESA_VERSION 2
  39094. +#endif
  39095. +#define MV_CESA_SRAM_SIZE 2*1024
  39096. +/* This define describes the maximum number of supported Ethernet ports */
  39097. +#define MV_ETH_VERSION 4
  39098. +#define MV_ETH_MAX_RXQ 8
  39099. +#define MV_ETH_MAX_TXQ 8
  39100. +#define MV_ETH_PORT_SGMII { MV_FALSE, MV_FALSE }
  39101. +/* This define describes the the support of USB */
  39102. +#define MV_USB_VERSION 1
  39103. +
  39104. +#define MV_INCLUDE_SDRAM_CS0
  39105. +#define MV_INCLUDE_SDRAM_CS1
  39106. +#define MV_INCLUDE_SDRAM_CS2
  39107. +#define MV_INCLUDE_SDRAM_CS3
  39108. +
  39109. +#define MV_INCLUDE_DEVICE_CS0
  39110. +#define MV_INCLUDE_DEVICE_CS1
  39111. +#define MV_INCLUDE_DEVICE_CS2
  39112. +#define MV_INCLUDE_DEVICE_CS3
  39113. +
  39114. +#define MPP_GROUP_1_TYPE {\
  39115. + {0, 0, 0}, /* Reserved for AUTO */ \
  39116. + {0x22220000, 0x22222222, 0x2222}, /* TDM */ \
  39117. + {0x44440000, 0x00044444, 0x0000}, /* AUDIO */ \
  39118. + {0x33330000, 0x33003333, 0x0033}, /* RGMII */ \
  39119. + {0x33330000, 0x03333333, 0x0033}, /* GMII */ \
  39120. + {0x11110000, 0x11111111, 0x0001}, /* TS */ \
  39121. + {0x33330000, 0x33333333, 0x3333} /* MII */ \
  39122. +}
  39123. +
  39124. +#define MPP_GROUP_2_TYPE {\
  39125. + {0, 0, 0}, /* Reserved for AUTO */ \
  39126. + {0x22220000, 0x22222222, 0x22}, /* TDM */ \
  39127. + {0x44440000, 0x00044444, 0x0}, /* AUDIO */ \
  39128. + {0, 0, 0}, /* N_A */ \
  39129. + {0, 0, 0}, /* N_A */ \
  39130. + {0x11110000, 0x11111111, 0x01} /* TS */ \
  39131. +}
  39132. +
  39133. +#ifndef MV_ASMLANGUAGE
  39134. +
  39135. +/* This enumerator defines the Marvell Units ID */
  39136. +typedef enum _mvUnitId
  39137. +{
  39138. + DRAM_UNIT_ID,
  39139. + PEX_UNIT_ID,
  39140. + ETH_GIG_UNIT_ID,
  39141. + USB_UNIT_ID,
  39142. + IDMA_UNIT_ID,
  39143. + XOR_UNIT_ID,
  39144. + SATA_UNIT_ID,
  39145. + TDM_UNIT_ID,
  39146. + UART_UNIT_ID,
  39147. + CESA_UNIT_ID,
  39148. + SPI_UNIT_ID,
  39149. + AUDIO_UNIT_ID,
  39150. + SDIO_UNIT_ID,
  39151. + TS_UNIT_ID,
  39152. + MAX_UNITS_ID
  39153. +
  39154. +}MV_UNIT_ID;
  39155. +
  39156. +#endif
  39157. +
  39158. +#endif /* __INCmvCtrlEnvSpech */
  39159. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c
  39160. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c 1970-01-01 01:00:00.000000000 +0100
  39161. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c 2010-11-09 20:28:07.842495395 +0100
  39162. @@ -0,0 +1,1048 @@
  39163. +/*******************************************************************************
  39164. +Copyright (C) Marvell International Ltd. and its affiliates
  39165. +
  39166. +This software file (the "File") is owned and distributed by Marvell
  39167. +International Ltd. and/or its affiliates ("Marvell") under the following
  39168. +alternative licensing terms. Once you have made an election to distribute the
  39169. +File under one of the following license alternatives, please (i) delete this
  39170. +introductory statement regarding license alternatives, (ii) delete the two
  39171. +license alternatives that you have not elected to use and (iii) preserve the
  39172. +Marvell copyright notice above.
  39173. +
  39174. +********************************************************************************
  39175. +Marvell Commercial License Option
  39176. +
  39177. +If you received this File from Marvell and you have entered into a commercial
  39178. +license agreement (a "Commercial License") with Marvell, the File is licensed
  39179. +to you under the terms of the applicable Commercial License.
  39180. +
  39181. +********************************************************************************
  39182. +Marvell GPL License Option
  39183. +
  39184. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39185. +modify this File in accordance with the terms and conditions of the General
  39186. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  39187. +available along with the File in the license.txt file or by writing to the Free
  39188. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  39189. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  39190. +
  39191. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  39192. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  39193. +DISCLAIMED. The GPL License provides additional details about this warranty
  39194. +disclaimer.
  39195. +********************************************************************************
  39196. +Marvell BSD License Option
  39197. +
  39198. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39199. +modify this File under the following licensing terms.
  39200. +Redistribution and use in source and binary forms, with or without modification,
  39201. +are permitted provided that the following conditions are met:
  39202. +
  39203. + * Redistributions of source code must retain the above copyright notice,
  39204. + this list of conditions and the following disclaimer.
  39205. +
  39206. + * Redistributions in binary form must reproduce the above copyright
  39207. + notice, this list of conditions and the following disclaimer in the
  39208. + documentation and/or other materials provided with the distribution.
  39209. +
  39210. + * Neither the name of Marvell nor the names of its contributors may be
  39211. + used to endorse or promote products derived from this software without
  39212. + specific prior written permission.
  39213. +
  39214. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  39215. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  39216. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39217. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  39218. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  39219. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  39220. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  39221. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  39222. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  39223. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39224. +
  39225. +*******************************************************************************/
  39226. +
  39227. +
  39228. +/* includes */
  39229. +#include "ctrlEnv/sys/mvAhbToMbus.h"
  39230. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  39231. +
  39232. +#undef MV_DEBUG
  39233. +/* defines */
  39234. +#ifdef MV_DEBUG
  39235. + #define DB(x) x
  39236. +#else
  39237. + #define DB(x)
  39238. +#endif
  39239. +
  39240. +/* typedefs */
  39241. +
  39242. +
  39243. +/* CPU address remap registers offsets are inconsecutive. This struct */
  39244. +/* describes address remap register offsets */
  39245. +typedef struct _ahbToMbusRemapRegOffs
  39246. +{
  39247. + MV_U32 lowRegOffs; /* Low 32-bit remap register offset */
  39248. + MV_U32 highRegOffs; /* High 32 bit remap register offset */
  39249. +}AHB_TO_MBUS_REMAP_REG_OFFS;
  39250. +
  39251. +/* locals */
  39252. +static MV_STATUS ahbToMbusRemapRegOffsGet (MV_U32 winNum,
  39253. + AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs);
  39254. +
  39255. +/*******************************************************************************
  39256. +* mvAhbToMbusInit - Initialize Ahb To Mbus Address Map !
  39257. +*
  39258. +* DESCRIPTION:
  39259. +*
  39260. +* INPUT:
  39261. +* None.
  39262. +*
  39263. +* OUTPUT:
  39264. +* None.
  39265. +*
  39266. +* RETURN:
  39267. +* MV_OK laways.
  39268. +*
  39269. +*******************************************************************************/
  39270. +MV_STATUS mvAhbToMbusInit(void)
  39271. +{
  39272. + return MV_OK;
  39273. +
  39274. +}
  39275. +
  39276. +/*******************************************************************************
  39277. +* mvAhbToMbusWinSet - Set CPU-to-peripheral winNum address window
  39278. +*
  39279. +* DESCRIPTION:
  39280. +* This function sets
  39281. +* address window, also known as address decode window.
  39282. +* A new address decode window is set for specified winNum address window.
  39283. +* If address decode window parameter structure enables the window,
  39284. +* the routine will also enable the winNum window, allowing CPU to access
  39285. +* the winNum window.
  39286. +*
  39287. +* INPUT:
  39288. +* winNum - Windows number.
  39289. +* pAddrDecWin - CPU winNum window data structure.
  39290. +*
  39291. +* OUTPUT:
  39292. +* N/A
  39293. +*
  39294. +* RETURN:
  39295. +* MV_OK if CPU winNum window was set correctly, MV_ERROR in case of
  39296. +* address window overlapps with other active CPU winNum window or
  39297. +* trying to assign 36bit base address while CPU does not support that.
  39298. +* The function returns MV_NOT_SUPPORTED, if the winNum is unsupported.
  39299. +*
  39300. +*******************************************************************************/
  39301. +MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
  39302. +{
  39303. + MV_TARGET_ATTRIB targetAttribs;
  39304. + MV_DEC_REGS decRegs;
  39305. +
  39306. + /* Parameter checking */
  39307. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  39308. + {
  39309. + mvOsPrintf("mvAhbToMbusWinSet: ERR. Invalid winNum %d\n", winNum);
  39310. + return MV_NOT_SUPPORTED;
  39311. + }
  39312. +
  39313. +
  39314. + /* read base register*/
  39315. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39316. + {
  39317. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
  39318. + }
  39319. + else
  39320. + {
  39321. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
  39322. + }
  39323. +
  39324. + /* check if address is aligned to the size */
  39325. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  39326. + {
  39327. + mvOsPrintf("mvAhbToMbusWinSet:Error setting AHB to MBUS window %d to "\
  39328. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  39329. + winNum,
  39330. + mvCtrlTargetNameGet(pAddrDecWin->target),
  39331. + pAddrDecWin->addrWin.baseLow,
  39332. + pAddrDecWin->addrWin.size);
  39333. + return MV_ERROR;
  39334. + }
  39335. +
  39336. + /* read control register*/
  39337. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39338. + {
  39339. + decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
  39340. + }
  39341. +
  39342. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  39343. + {
  39344. + mvOsPrintf("mvAhbToMbusWinSet:mvCtrlAddrDecToReg Failed\n");
  39345. + return MV_ERROR;
  39346. + }
  39347. +
  39348. + /* enable\Disable */
  39349. + if (MV_TRUE == pAddrDecWin->enable)
  39350. + {
  39351. + decRegs.sizeReg |= ATMWCR_WIN_ENABLE;
  39352. + }
  39353. + else
  39354. + {
  39355. + decRegs.sizeReg &= ~ATMWCR_WIN_ENABLE;
  39356. + }
  39357. +
  39358. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  39359. +
  39360. + /* set attributes */
  39361. + decRegs.sizeReg &= ~ATMWCR_WIN_ATTR_MASK;
  39362. + decRegs.sizeReg |= targetAttribs.attrib << ATMWCR_WIN_ATTR_OFFS;
  39363. + /* set target ID */
  39364. + decRegs.sizeReg &= ~ATMWCR_WIN_TARGET_MASK;
  39365. + decRegs.sizeReg |= targetAttribs.targetId << ATMWCR_WIN_TARGET_OFFS;
  39366. +
  39367. +#if !defined(MV_RUN_FROM_FLASH)
  39368. + /* To be on the safe side we disable the window before writing the */
  39369. + /* new values. */
  39370. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39371. + {
  39372. + mvAhbToMbusWinEnable(winNum,MV_FALSE);
  39373. + }
  39374. +#endif
  39375. +
  39376. + /* 3) Write to address decode Base Address Register */
  39377. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39378. + {
  39379. + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum), decRegs.baseReg);
  39380. + }
  39381. + else
  39382. + {
  39383. + MV_REG_WRITE(AHB_TO_MBUS_WIN_INTEREG_REG, decRegs.baseReg);
  39384. + }
  39385. +
  39386. +
  39387. + /* Internal register space have no size */
  39388. + /* register. Do not perform size register assigment for those targets */
  39389. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39390. + {
  39391. + /* Write to address decode Size Register */
  39392. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), decRegs.sizeReg);
  39393. + }
  39394. +
  39395. + return MV_OK;
  39396. +}
  39397. +
  39398. +/*******************************************************************************
  39399. +* mvAhbToMbusWinGet - Get CPU-to-peripheral winNum address window
  39400. +*
  39401. +* DESCRIPTION:
  39402. +* Get the CPU peripheral winNum address window.
  39403. +*
  39404. +* INPUT:
  39405. +* winNum - Peripheral winNum enumerator
  39406. +*
  39407. +* OUTPUT:
  39408. +* pAddrDecWin - CPU winNum window information data structure.
  39409. +*
  39410. +* RETURN:
  39411. +* MV_OK if winNum exist, MV_ERROR otherwise.
  39412. +*
  39413. +*******************************************************************************/
  39414. +MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
  39415. +{
  39416. + MV_DEC_REGS decRegs;
  39417. + MV_TARGET_ATTRIB targetAttrib;
  39418. +
  39419. +
  39420. + /* Parameter checking */
  39421. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  39422. + {
  39423. + mvOsPrintf("mvAhbToMbusWinGet: ERR. Invalid winNum %d\n", winNum);
  39424. + return MV_NOT_SUPPORTED;
  39425. + }
  39426. +
  39427. +
  39428. + /* Internal register space size have no size register*/
  39429. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39430. + {
  39431. + decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
  39432. + }
  39433. + else
  39434. + {
  39435. + decRegs.sizeReg = 0;
  39436. + }
  39437. +
  39438. +
  39439. + /* Read base and size */
  39440. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39441. + {
  39442. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
  39443. + }
  39444. + else
  39445. + {
  39446. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
  39447. + }
  39448. +
  39449. +
  39450. +
  39451. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  39452. + {
  39453. + mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");
  39454. + return MV_ERROR;
  39455. + }
  39456. +
  39457. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  39458. + {
  39459. + pAddrDecWin->addrWin.size = INTER_REGS_SIZE;
  39460. + pAddrDecWin->target = INTER_REGS;
  39461. + pAddrDecWin->enable = MV_TRUE;
  39462. +
  39463. + return MV_OK;
  39464. + }
  39465. +
  39466. +
  39467. + if (decRegs.sizeReg & ATMWCR_WIN_ENABLE)
  39468. + {
  39469. + pAddrDecWin->enable = MV_TRUE;
  39470. + }
  39471. + else
  39472. + {
  39473. + pAddrDecWin->enable = MV_FALSE;
  39474. +
  39475. + }
  39476. +
  39477. +
  39478. +
  39479. + if (-1 == pAddrDecWin->addrWin.size)
  39480. + {
  39481. + return MV_ERROR;
  39482. + }
  39483. +
  39484. + /* attrib and targetId */
  39485. + targetAttrib.attrib = (decRegs.sizeReg & ATMWCR_WIN_ATTR_MASK) >>
  39486. + ATMWCR_WIN_ATTR_OFFS;
  39487. + targetAttrib.targetId = (decRegs.sizeReg & ATMWCR_WIN_TARGET_MASK) >>
  39488. + ATMWCR_WIN_TARGET_OFFS;
  39489. +
  39490. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  39491. +
  39492. + return MV_OK;
  39493. +}
  39494. +
  39495. +/*******************************************************************************
  39496. +* mvAhbToMbusWinTargetGet - Get Window number associated with target
  39497. +*
  39498. +* DESCRIPTION:
  39499. +*
  39500. +* INPUT:
  39501. +*
  39502. +* OUTPUT:
  39503. +*
  39504. +* RETURN:
  39505. +*
  39506. +*******************************************************************************/
  39507. +MV_U32 mvAhbToMbusWinTargetGet(MV_TARGET target)
  39508. +{
  39509. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  39510. + MV_U32 winNum;
  39511. +
  39512. + /* Check parameters */
  39513. + if (target >= MAX_TARGETS)
  39514. + {
  39515. + mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);
  39516. + return 0xffffffff;
  39517. + }
  39518. +
  39519. + if (INTER_REGS == target)
  39520. + {
  39521. + return MV_AHB_TO_MBUS_INTREG_WIN;
  39522. + }
  39523. +
  39524. + for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)
  39525. + {
  39526. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  39527. + continue;
  39528. +
  39529. + if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)
  39530. + {
  39531. + mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");
  39532. + return 0xffffffff;
  39533. +
  39534. + }
  39535. +
  39536. + if (decWin.enable == MV_TRUE)
  39537. + {
  39538. + if (decWin.target == target)
  39539. + {
  39540. + return winNum;
  39541. + }
  39542. +
  39543. + }
  39544. +
  39545. + }
  39546. +
  39547. + return 0xFFFFFFFF;
  39548. +
  39549. +
  39550. +}
  39551. +
  39552. +/*******************************************************************************
  39553. +* mvAhbToMbusWinAvailGet - Get First Available window number.
  39554. +*
  39555. +* DESCRIPTION:
  39556. +*
  39557. +* INPUT:
  39558. +*
  39559. +* OUTPUT:
  39560. +*
  39561. +* RETURN:
  39562. +*
  39563. +*******************************************************************************/
  39564. +MV_U32 mvAhbToMbusWinAvailGet(MV_VOID)
  39565. +{
  39566. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  39567. + MV_U32 winNum;
  39568. +
  39569. + for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)
  39570. + {
  39571. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  39572. + continue;
  39573. +
  39574. + if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)
  39575. + {
  39576. + mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");
  39577. + return 0xffffffff;
  39578. +
  39579. + }
  39580. +
  39581. + if (decWin.enable == MV_FALSE)
  39582. + {
  39583. + return winNum;
  39584. + }
  39585. +
  39586. + }
  39587. +
  39588. + return 0xFFFFFFFF;
  39589. +}
  39590. +
  39591. +
  39592. +/*******************************************************************************
  39593. +* mvAhbToMbusWinEnable - Enable/disable a CPU address decode window
  39594. +*
  39595. +* DESCRIPTION:
  39596. +* This function enable/disable a CPU address decode window.
  39597. +* if parameter 'enable' == MV_TRUE the routine will enable the
  39598. +* window, thus enabling CPU accesses (before enabling the window it is
  39599. +* tested for overlapping). Otherwise, the window will be disabled.
  39600. +*
  39601. +* INPUT:
  39602. +* winNum - Peripheral winNum enumerator.
  39603. +* enable - Enable/disable parameter.
  39604. +*
  39605. +* OUTPUT:
  39606. +* N/A
  39607. +*
  39608. +* RETURN:
  39609. +* MV_ERROR if protection window number was wrong, or the window
  39610. +* overlapps other winNum window.
  39611. +*
  39612. +*******************************************************************************/
  39613. +MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum, MV_BOOL enable)
  39614. +{
  39615. +
  39616. + /* Parameter checking */
  39617. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  39618. + {
  39619. + mvOsPrintf("mvAhbToMbusWinEnable: ERR. Invalid winNum %d\n", winNum);
  39620. + return MV_NOT_SUPPORTED;
  39621. + }
  39622. +
  39623. + /* Internal registers bar can't be disable or enabled */
  39624. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  39625. + {
  39626. + return (enable ? MV_OK : MV_ERROR);
  39627. + }
  39628. +
  39629. + if (enable == MV_TRUE)
  39630. + {
  39631. + /* enable the window */
  39632. + MV_REG_BIT_SET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
  39633. + }
  39634. + else
  39635. + { /* Disable address decode winNum window */
  39636. + MV_REG_BIT_RESET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
  39637. + }
  39638. +
  39639. + return MV_OK;
  39640. +}
  39641. +
  39642. +
  39643. +/*******************************************************************************
  39644. +* mvAhbToMbusWinRemap - Set CPU remap register for address windows.
  39645. +*
  39646. +* DESCRIPTION:
  39647. +* After a CPU address hits one of PCI address decode windows there is an
  39648. +* option to remap the address to a different one. For example, CPU
  39649. +* executes a read from PCI winNum window address 0x1200.0000. This
  39650. +* can be modified so the address on the PCI bus would be 0x1400.0000
  39651. +* Using the PCI address remap mechanism.
  39652. +*
  39653. +* INPUT:
  39654. +* winNum - Peripheral winNum enumerator. Must be a PCI winNum.
  39655. +* pAddrDecWin - CPU winNum window information data structure.
  39656. +* Note that caller has to fill in the base field only. The
  39657. +* size field is ignored.
  39658. +*
  39659. +* OUTPUT:
  39660. +* None.
  39661. +*
  39662. +* RETURN:
  39663. +* MV_ERROR if winNum is not a PCI one, MV_OK otherwise.
  39664. +*
  39665. +*******************************************************************************/
  39666. +MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  39667. +{
  39668. + MV_U32 baseAddr;
  39669. + AHB_TO_MBUS_REMAP_REG_OFFS remapRegOffs;
  39670. +
  39671. + MV_U32 effectiveBaseAddress=0,
  39672. + baseAddrValue=0,windowSizeValue=0;
  39673. +
  39674. +
  39675. + /* Get registers offsets of given winNum */
  39676. + if (MV_NO_SUCH == ahbToMbusRemapRegOffsGet(winNum, &remapRegOffs))
  39677. + {
  39678. + return 0xffffffff;
  39679. + }
  39680. +
  39681. + /* 1) Set address remap low */
  39682. + baseAddr = pAddrWin->baseLow;
  39683. +
  39684. + /* Check base address aligment */
  39685. + /*
  39686. + if (MV_IS_NOT_ALIGN(baseAddr, ATMWRLR_REMAP_LOW_ALIGNMENT))
  39687. + {
  39688. + mvOsPrintf("mvAhbToMbusPciRemap: Warning. Target base 0x%x unaligned\n",
  39689. + baseAddr);
  39690. + return MV_ERROR;
  39691. + }
  39692. + */
  39693. +
  39694. + /* BaseLow[31:16] => base register [31:16] */
  39695. + baseAddr = baseAddr & ATMWRLR_REMAP_LOW_MASK;
  39696. +
  39697. + MV_REG_WRITE(remapRegOffs.lowRegOffs, baseAddr);
  39698. +
  39699. + MV_REG_WRITE(remapRegOffs.highRegOffs, pAddrWin->baseHigh);
  39700. +
  39701. +
  39702. + baseAddrValue = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
  39703. + windowSizeValue = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
  39704. +
  39705. + baseAddrValue &= ATMWBR_BASE_MASK;
  39706. + windowSizeValue &=ATMWCR_WIN_SIZE_MASK;
  39707. +
  39708. + /* Start calculating the effective Base Address */
  39709. + effectiveBaseAddress = baseAddrValue ;
  39710. +
  39711. + /* The effective base address will be combined from the chopped (if any)
  39712. + remap value (according to the size value and remap mechanism) and the
  39713. + window's base address */
  39714. + effectiveBaseAddress |= (((windowSizeValue) | 0xffff) & pAddrWin->baseLow);
  39715. + /* If the effectiveBaseAddress exceed the window boundaries return an
  39716. + invalid value. */
  39717. +
  39718. + if (effectiveBaseAddress > (baseAddrValue + (windowSizeValue | 0xffff)))
  39719. + {
  39720. + mvOsPrintf("mvAhbToMbusPciRemap: Error\n");
  39721. + return 0xffffffff;
  39722. + }
  39723. +
  39724. + return effectiveBaseAddress;
  39725. +
  39726. +
  39727. +}
  39728. +/*******************************************************************************
  39729. +* mvAhbToMbusWinTargetSwap - Swap AhbToMbus windows between targets
  39730. +*
  39731. +* DESCRIPTION:
  39732. +*
  39733. +* INPUT:
  39734. +* target1 - CPU Interface target 1
  39735. +* target2 - CPU Interface target 2
  39736. +*
  39737. +* OUTPUT:
  39738. +* None.
  39739. +*
  39740. +* RETURN:
  39741. +* MV_ERROR if targets are illigal, or if one of the targets is not
  39742. +* associated to a valid window .
  39743. +* MV_OK otherwise.
  39744. +*
  39745. +*******************************************************************************/
  39746. +
  39747. +
  39748. +MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2)
  39749. +{
  39750. + MV_U32 winNum1,winNum2;
  39751. + MV_AHB_TO_MBUS_DEC_WIN winDec1,winDec2,winDecTemp;
  39752. + AHB_TO_MBUS_REMAP_REG_OFFS remapRegs1,remapRegs2;
  39753. + MV_U32 remapBaseLow1=0,remapBaseLow2=0;
  39754. + MV_U32 remapBaseHigh1=0,remapBaseHigh2=0;
  39755. +
  39756. +
  39757. + /* Check parameters */
  39758. + if (target1 >= MAX_TARGETS)
  39759. + {
  39760. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);
  39761. + return MV_ERROR;
  39762. + }
  39763. +
  39764. + if (target2 >= MAX_TARGETS)
  39765. + {
  39766. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);
  39767. + return MV_ERROR;
  39768. + }
  39769. +
  39770. +
  39771. + /* get window associated with this target */
  39772. + winNum1 = mvAhbToMbusWinTargetGet(target1);
  39773. +
  39774. + if (winNum1 == 0xffffffff)
  39775. + {
  39776. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",
  39777. + target1,winNum1);
  39778. + return MV_ERROR;
  39779. +
  39780. + }
  39781. +
  39782. + /* get window associated with this target */
  39783. + winNum2 = mvAhbToMbusWinTargetGet(target2);
  39784. +
  39785. + if (winNum2 == 0xffffffff)
  39786. + {
  39787. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",
  39788. + target2,winNum2);
  39789. + return MV_ERROR;
  39790. +
  39791. + }
  39792. +
  39793. + /* now Get original values of both Windows */
  39794. + if (MV_OK != mvAhbToMbusWinGet(winNum1,&winDec1))
  39795. + {
  39796. + mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",
  39797. + winNum1);
  39798. + return MV_ERROR;
  39799. +
  39800. + }
  39801. + if (MV_OK != mvAhbToMbusWinGet(winNum2,&winDec2))
  39802. + {
  39803. + mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",
  39804. + winNum2);
  39805. + return MV_ERROR;
  39806. +
  39807. + }
  39808. +
  39809. +
  39810. + /* disable both windows */
  39811. + if (MV_OK != mvAhbToMbusWinEnable(winNum1,MV_FALSE))
  39812. + {
  39813. + mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable window %d\n",
  39814. + winNum1);
  39815. + return MV_ERROR;
  39816. +
  39817. + }
  39818. + if (MV_OK != mvAhbToMbusWinEnable(winNum2,MV_FALSE))
  39819. + {
  39820. + mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable windo %d\n",
  39821. + winNum2);
  39822. + return MV_ERROR;
  39823. +
  39824. + }
  39825. +
  39826. +
  39827. + /* now swap targets */
  39828. +
  39829. + /* first save winDec2 values */
  39830. + winDecTemp.addrWin.baseHigh = winDec2.addrWin.baseHigh;
  39831. + winDecTemp.addrWin.baseLow = winDec2.addrWin.baseLow;
  39832. + winDecTemp.addrWin.size = winDec2.addrWin.size;
  39833. + winDecTemp.enable = winDec2.enable;
  39834. + winDecTemp.target = winDec2.target;
  39835. +
  39836. + /* winDec2 = winDec1 */
  39837. + winDec2.addrWin.baseHigh = winDec1.addrWin.baseHigh;
  39838. + winDec2.addrWin.baseLow = winDec1.addrWin.baseLow;
  39839. + winDec2.addrWin.size = winDec1.addrWin.size;
  39840. + winDec2.enable = winDec1.enable;
  39841. + winDec2.target = winDec1.target;
  39842. +
  39843. +
  39844. + /* winDec1 = winDecTemp */
  39845. + winDec1.addrWin.baseHigh = winDecTemp.addrWin.baseHigh;
  39846. + winDec1.addrWin.baseLow = winDecTemp.addrWin.baseLow;
  39847. + winDec1.addrWin.size = winDecTemp.addrWin.size;
  39848. + winDec1.enable = winDecTemp.enable;
  39849. + winDec1.target = winDecTemp.target;
  39850. +
  39851. +
  39852. + /* now set the new values */
  39853. +
  39854. +
  39855. + mvAhbToMbusWinSet(winNum1,&winDec1);
  39856. + mvAhbToMbusWinSet(winNum2,&winDec2);
  39857. +
  39858. +
  39859. +
  39860. +
  39861. +
  39862. + /* now we will treat the remap windows if exist */
  39863. +
  39864. +
  39865. + /* now check if one or both windows has a remap window
  39866. + as well after the swap ! */
  39867. +
  39868. + /* if a window had a remap value differnt than the base value
  39869. + before the swap , then after the swap the remap value will be
  39870. + equal to the base value unless both windows has a remap windows*/
  39871. +
  39872. + /* first get old values */
  39873. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))
  39874. + {
  39875. + remapBaseLow1 = MV_REG_READ(remapRegs1.lowRegOffs);
  39876. + remapBaseHigh1 = MV_REG_READ(remapRegs1.highRegOffs);
  39877. +
  39878. + }
  39879. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
  39880. + {
  39881. + remapBaseLow2 = MV_REG_READ(remapRegs2.lowRegOffs);
  39882. + remapBaseHigh2 = MV_REG_READ(remapRegs2.highRegOffs);
  39883. +
  39884. +
  39885. + }
  39886. +
  39887. + /* now do the swap */
  39888. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))
  39889. + {
  39890. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
  39891. + {
  39892. + /* Two windows has a remap !!! so swap */
  39893. +
  39894. + MV_REG_WRITE(remapRegs2.highRegOffs,remapBaseHigh1);
  39895. + MV_REG_WRITE(remapRegs2.lowRegOffs,remapBaseLow1);
  39896. +
  39897. + MV_REG_WRITE(remapRegs1.highRegOffs,remapBaseHigh2);
  39898. + MV_REG_WRITE(remapRegs1.lowRegOffs,remapBaseLow2);
  39899. +
  39900. +
  39901. +
  39902. + }
  39903. + else
  39904. + {
  39905. + /* remap == base */
  39906. + MV_REG_WRITE(remapRegs1.highRegOffs,winDec1.addrWin.baseHigh);
  39907. + MV_REG_WRITE(remapRegs1.lowRegOffs,winDec1.addrWin.baseLow);
  39908. +
  39909. + }
  39910. +
  39911. + }
  39912. + else if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
  39913. + {
  39914. + /* remap == base */
  39915. + MV_REG_WRITE(remapRegs2.highRegOffs,winDec2.addrWin.baseHigh);
  39916. + MV_REG_WRITE(remapRegs2.lowRegOffs,winDec2.addrWin.baseLow);
  39917. +
  39918. + }
  39919. +
  39920. +
  39921. +
  39922. + return MV_OK;
  39923. +
  39924. +
  39925. +}
  39926. +
  39927. +
  39928. +
  39929. +#if defined(MV_88F1181)
  39930. +
  39931. +/*******************************************************************************
  39932. +* mvAhbToMbusXbarCtrlSet - Set The CPU master Xbar arbitration.
  39933. +*
  39934. +* DESCRIPTION:
  39935. +* This function sets CPU Mbus Arbiter
  39936. +*
  39937. +* INPUT:
  39938. +* pPizzaArbArray - A priority Structure describing 16 "pizza slices". At
  39939. +* each clock cycle, the crossbar arbiter samples all
  39940. +* requests and gives the bus to the next agent according
  39941. +* to the "pizza".
  39942. +*
  39943. +* OUTPUT:
  39944. +* N/A
  39945. +*
  39946. +* RETURN:
  39947. +* MV_ERROR if paramers to function invalid.
  39948. +*
  39949. +*******************************************************************************/
  39950. +MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray)
  39951. +{
  39952. + MV_U32 sliceNum;
  39953. + MV_U32 xbarCtrl = 0;
  39954. + MV_MBUS_ARB_TARGET xbarTarget;
  39955. +
  39956. + /* 1) Set crossbar control low register */
  39957. + for (sliceNum = 0; sliceNum < MRLR_SLICE_NUM; sliceNum++)
  39958. + {
  39959. + xbarTarget = pPizzaArbArray[sliceNum];
  39960. +
  39961. + /* sliceNum parameter check */
  39962. + if (xbarTarget > MAX_MBUS_ARB_TARGETS)
  39963. + {
  39964. + mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",
  39965. + xbarTarget);
  39966. + return MV_ERROR;
  39967. + }
  39968. + xbarCtrl |= (xbarTarget << MRLR_LOW_ARB_OFFS(sliceNum));
  39969. + }
  39970. + /* Write to crossbar control low register */
  39971. + MV_REG_WRITE(MBUS_ARBITER_LOW_REG, xbarCtrl);
  39972. +
  39973. + xbarCtrl = 0;
  39974. +
  39975. + /* 2) Set crossbar control high register */
  39976. + for (sliceNum = MRLR_SLICE_NUM;
  39977. + sliceNum < MRLR_SLICE_NUM+MRHR_SLICE_NUM;
  39978. + sliceNum++)
  39979. + {
  39980. +
  39981. + xbarTarget = pPizzaArbArray[sliceNum];
  39982. +
  39983. + /* sliceNum parameter check */
  39984. + if (xbarTarget > MAX_MBUS_ARB_TARGETS)
  39985. + {
  39986. + mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",
  39987. + xbarTarget);
  39988. + return MV_ERROR;
  39989. + }
  39990. + xbarCtrl |= (xbarTarget << MRHR_HIGH_ARB_OFFS(sliceNum));
  39991. + }
  39992. + /* Write to crossbar control high register */
  39993. + MV_REG_WRITE(MBUS_ARBITER_HIGH_REG, xbarCtrl);
  39994. +
  39995. + return MV_OK;
  39996. +}
  39997. +
  39998. +/*******************************************************************************
  39999. +* mvMbusArbCtrlSet - Set MBus Arbiter control register
  40000. +*
  40001. +* DESCRIPTION:
  40002. +*
  40003. +* INPUT:
  40004. +* ctrl - pointer to MV_MBUS_ARB_CTRL register
  40005. +*
  40006. +* OUTPUT:
  40007. +* N/A
  40008. +*
  40009. +* RETURN:
  40010. +* MV_ERROR if paramers to function invalid.
  40011. +*
  40012. +*******************************************************************************/
  40013. +MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl)
  40014. +{
  40015. +
  40016. + if (ctrl->highPrio == MV_FALSE)
  40017. + {
  40018. + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);
  40019. + }
  40020. + else
  40021. + {
  40022. + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);
  40023. + }
  40024. +
  40025. + if (ctrl->fixedRoundRobin == MV_FALSE)
  40026. + {
  40027. + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);
  40028. + }
  40029. + else
  40030. + {
  40031. + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);
  40032. + }
  40033. +
  40034. + if (ctrl->starvEn == MV_FALSE)
  40035. + {
  40036. + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);
  40037. + }
  40038. + else
  40039. + {
  40040. + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);
  40041. + }
  40042. +
  40043. + return MV_OK;
  40044. +}
  40045. +
  40046. +/*******************************************************************************
  40047. +* mvMbusArbCtrlGet - Get MBus Arbiter control register
  40048. +*
  40049. +* DESCRIPTION:
  40050. +*
  40051. +* INPUT:
  40052. +* ctrl - pointer to MV_MBUS_ARB_CTRL register
  40053. +*
  40054. +* OUTPUT:
  40055. +* ctrl - pointer to MV_MBUS_ARB_CTRL register
  40056. +*
  40057. +* RETURN:
  40058. +* MV_ERROR if paramers to function invalid.
  40059. +*
  40060. +*******************************************************************************/
  40061. +MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl)
  40062. +{
  40063. +
  40064. + MV_U32 ctrlReg = MV_REG_READ(MBUS_ARBITER_CTRL_REG);
  40065. +
  40066. + if (ctrlReg & MACR_ARB_ARM_TOP)
  40067. + {
  40068. + ctrl->highPrio = MV_TRUE;
  40069. + }
  40070. + else
  40071. + {
  40072. + ctrl->highPrio = MV_FALSE;
  40073. + }
  40074. +
  40075. + if (ctrlReg & MACR_ARB_TARGET_FIXED)
  40076. + {
  40077. + ctrl->fixedRoundRobin = MV_TRUE;
  40078. + }
  40079. + else
  40080. + {
  40081. + ctrl->fixedRoundRobin = MV_FALSE;
  40082. + }
  40083. +
  40084. + if (ctrlReg & MACR_ARB_REQ_CTRL_EN)
  40085. + {
  40086. + ctrl->starvEn = MV_TRUE;
  40087. + }
  40088. + else
  40089. + {
  40090. + ctrl->starvEn = MV_FALSE;
  40091. + }
  40092. +
  40093. +
  40094. + return MV_OK;
  40095. +}
  40096. +
  40097. +#endif /* #if defined(MV_88F1181) */
  40098. +
  40099. +
  40100. +
  40101. +/*******************************************************************************
  40102. +* ahbToMbusRemapRegOffsGet - Get CPU address remap register offsets
  40103. +*
  40104. +* DESCRIPTION:
  40105. +* CPU to PCI address remap registers offsets are inconsecutive.
  40106. +* This function returns PCI address remap registers offsets.
  40107. +*
  40108. +* INPUT:
  40109. +* winNum - Address decode window number. See MV_U32 enumerator.
  40110. +*
  40111. +* OUTPUT:
  40112. +* None.
  40113. +*
  40114. +* RETURN:
  40115. +* MV_ERROR if winNum is not a PCI one.
  40116. +*
  40117. +*******************************************************************************/
  40118. +static MV_STATUS ahbToMbusRemapRegOffsGet(MV_U32 winNum,
  40119. + AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs)
  40120. +{
  40121. + switch (winNum)
  40122. + {
  40123. + case 0:
  40124. + case 1:
  40125. + pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);
  40126. + pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);
  40127. + break;
  40128. + case 2:
  40129. + case 3:
  40130. + if((mvCtrlModelGet() == MV_5281_DEV_ID) ||
  40131. + (mvCtrlModelGet() == MV_1281_DEV_ID) ||
  40132. + (mvCtrlModelGet() == MV_6183_DEV_ID) ||
  40133. + (mvCtrlModelGet() == MV_6183L_DEV_ID))
  40134. + {
  40135. + pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);
  40136. + pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);
  40137. + break;
  40138. + }
  40139. + else
  40140. + {
  40141. + pRemapRegs->lowRegOffs = 0;
  40142. + pRemapRegs->highRegOffs = 0;
  40143. +
  40144. + DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",
  40145. + winNum));
  40146. + return MV_NO_SUCH;
  40147. + }
  40148. + default:
  40149. + {
  40150. + pRemapRegs->lowRegOffs = 0;
  40151. + pRemapRegs->highRegOffs = 0;
  40152. +
  40153. + DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",
  40154. + winNum));
  40155. + return MV_NO_SUCH;
  40156. + }
  40157. + }
  40158. +
  40159. + return MV_OK;
  40160. +}
  40161. +
  40162. +/*******************************************************************************
  40163. +* mvAhbToMbusAddDecShow - Print the AHB to MBus bridge address decode map.
  40164. +*
  40165. +* DESCRIPTION:
  40166. +* This function print the CPU address decode map.
  40167. +*
  40168. +* INPUT:
  40169. +* None.
  40170. +*
  40171. +* OUTPUT:
  40172. +* None.
  40173. +*
  40174. +* RETURN:
  40175. +* None.
  40176. +*
  40177. +*******************************************************************************/
  40178. +MV_VOID mvAhbToMbusAddDecShow(MV_VOID)
  40179. +{
  40180. + MV_AHB_TO_MBUS_DEC_WIN win;
  40181. + MV_U32 winNum;
  40182. + mvOsOutput( "\n" );
  40183. + mvOsOutput( "AHB To MBUS Bridge:\n" );
  40184. + mvOsOutput( "-------------------\n" );
  40185. +
  40186. + for( winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS; winNum++ )
  40187. + {
  40188. + memset( &win, 0, sizeof(MV_AHB_TO_MBUS_DEC_WIN) );
  40189. +
  40190. + mvOsOutput( "win%d - ", winNum );
  40191. +
  40192. + if( mvAhbToMbusWinGet( winNum, &win ) == MV_OK )
  40193. + {
  40194. + if( win.enable )
  40195. + {
  40196. + mvOsOutput( "%s base %08x, ",
  40197. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  40198. + mvOsOutput( "...." );
  40199. + mvSizePrint( win.addrWin.size );
  40200. +
  40201. + mvOsOutput( "\n" );
  40202. +
  40203. + }
  40204. + else
  40205. + mvOsOutput( "disable\n" );
  40206. + }
  40207. + }
  40208. +
  40209. +}
  40210. +
  40211. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h
  40212. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h 1970-01-01 01:00:00.000000000 +0100
  40213. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h 2010-11-09 20:28:07.872495394 +0100
  40214. @@ -0,0 +1,130 @@
  40215. +/*******************************************************************************
  40216. +Copyright (C) Marvell International Ltd. and its affiliates
  40217. +
  40218. +This software file (the "File") is owned and distributed by Marvell
  40219. +International Ltd. and/or its affiliates ("Marvell") under the following
  40220. +alternative licensing terms. Once you have made an election to distribute the
  40221. +File under one of the following license alternatives, please (i) delete this
  40222. +introductory statement regarding license alternatives, (ii) delete the two
  40223. +license alternatives that you have not elected to use and (iii) preserve the
  40224. +Marvell copyright notice above.
  40225. +
  40226. +********************************************************************************
  40227. +Marvell Commercial License Option
  40228. +
  40229. +If you received this File from Marvell and you have entered into a commercial
  40230. +license agreement (a "Commercial License") with Marvell, the File is licensed
  40231. +to you under the terms of the applicable Commercial License.
  40232. +
  40233. +********************************************************************************
  40234. +Marvell GPL License Option
  40235. +
  40236. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40237. +modify this File in accordance with the terms and conditions of the General
  40238. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  40239. +available along with the File in the license.txt file or by writing to the Free
  40240. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  40241. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  40242. +
  40243. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  40244. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  40245. +DISCLAIMED. The GPL License provides additional details about this warranty
  40246. +disclaimer.
  40247. +********************************************************************************
  40248. +Marvell BSD License Option
  40249. +
  40250. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40251. +modify this File under the following licensing terms.
  40252. +Redistribution and use in source and binary forms, with or without modification,
  40253. +are permitted provided that the following conditions are met:
  40254. +
  40255. + * Redistributions of source code must retain the above copyright notice,
  40256. + this list of conditions and the following disclaimer.
  40257. +
  40258. + * Redistributions in binary form must reproduce the above copyright
  40259. + notice, this list of conditions and the following disclaimer in the
  40260. + documentation and/or other materials provided with the distribution.
  40261. +
  40262. + * Neither the name of Marvell nor the names of its contributors may be
  40263. + used to endorse or promote products derived from this software without
  40264. + specific prior written permission.
  40265. +
  40266. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  40267. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  40268. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  40269. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  40270. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  40271. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  40272. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  40273. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  40274. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  40275. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40276. +
  40277. +*******************************************************************************/
  40278. +
  40279. +
  40280. +#ifndef __INCmvAhbToMbush
  40281. +#define __INCmvAhbToMbush
  40282. +
  40283. +/* includes */
  40284. +#include "ctrlEnv/mvCtrlEnvLib.h"
  40285. +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
  40286. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  40287. +
  40288. +/* defines */
  40289. +
  40290. +#if defined(MV_88F1181)
  40291. +/* This enumerator defines the Marvell controller possible MBUS arbiter */
  40292. +/* target ports. It is used to define crossbar priority scheame (pizza) */
  40293. +typedef enum _mvMBusArbTargetId
  40294. +{
  40295. + DRAM_MBUS_ARB_TARGET = 0, /* Port 0 -> DRAM interface */
  40296. + TWSI_MBUS_ARB_TARGET = 1, /* Port 1 -> TWSI */
  40297. + ARM_MBUS_ARB_TARGET = 2, /* Port 2 -> ARM */
  40298. + PEX1_MBUS_ARB_TARGET = 3, /* Port 3 -> PCI Express 1 */
  40299. + PEX0_MBUS_ARB_TARGET = 4, /* Port 4 -> PCI Express0 */
  40300. + MAX_MBUS_ARB_TARGETS
  40301. +}MV_MBUS_ARB_TARGET;
  40302. +
  40303. +typedef struct _mvMBusArbCtrl
  40304. +{
  40305. + MV_BOOL starvEn;
  40306. + MV_BOOL highPrio;
  40307. + MV_BOOL fixedRoundRobin;
  40308. +
  40309. +}MV_MBUS_ARB_CTRL;
  40310. +
  40311. +#endif /* #if defined(MV_88F1181) */
  40312. +
  40313. +typedef struct _mvAhbtoMbusDecWin
  40314. +{
  40315. + MV_TARGET target;
  40316. + MV_ADDR_WIN addrWin; /* An address window*/
  40317. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  40318. +
  40319. +}MV_AHB_TO_MBUS_DEC_WIN;
  40320. +
  40321. +/* mvAhbToMbus.h API list */
  40322. +
  40323. +MV_STATUS mvAhbToMbusInit(MV_VOID);
  40324. +MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);
  40325. +MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);
  40326. +MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum,MV_BOOL enable);
  40327. +MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrDecWin);
  40328. +MV_U32 mvAhbToMbusWinTargetGet(MV_TARGET target);
  40329. +MV_U32 mvAhbToMbusWinAvailGet(MV_VOID);
  40330. +MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2);
  40331. +
  40332. +#if defined(MV_88F1181)
  40333. +
  40334. +MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray);
  40335. +MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl);
  40336. +MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl);
  40337. +
  40338. +#endif /* #if defined(MV_88F1181) */
  40339. +
  40340. +
  40341. +MV_VOID mvAhbToMbusAddDecShow(MV_VOID);
  40342. +
  40343. +
  40344. +#endif /* __INCmvAhbToMbush */
  40345. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h
  40346. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h 1970-01-01 01:00:00.000000000 +0100
  40347. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h 2010-11-09 20:28:07.902495495 +0100
  40348. @@ -0,0 +1,143 @@
  40349. +/*******************************************************************************
  40350. +Copyright (C) Marvell International Ltd. and its affiliates
  40351. +
  40352. +This software file (the "File") is owned and distributed by Marvell
  40353. +International Ltd. and/or its affiliates ("Marvell") under the following
  40354. +alternative licensing terms. Once you have made an election to distribute the
  40355. +File under one of the following license alternatives, please (i) delete this
  40356. +introductory statement regarding license alternatives, (ii) delete the two
  40357. +license alternatives that you have not elected to use and (iii) preserve the
  40358. +Marvell copyright notice above.
  40359. +
  40360. +********************************************************************************
  40361. +Marvell Commercial License Option
  40362. +
  40363. +If you received this File from Marvell and you have entered into a commercial
  40364. +license agreement (a "Commercial License") with Marvell, the File is licensed
  40365. +to you under the terms of the applicable Commercial License.
  40366. +
  40367. +********************************************************************************
  40368. +Marvell GPL License Option
  40369. +
  40370. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40371. +modify this File in accordance with the terms and conditions of the General
  40372. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  40373. +available along with the File in the license.txt file or by writing to the Free
  40374. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  40375. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  40376. +
  40377. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  40378. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  40379. +DISCLAIMED. The GPL License provides additional details about this warranty
  40380. +disclaimer.
  40381. +********************************************************************************
  40382. +Marvell BSD License Option
  40383. +
  40384. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40385. +modify this File under the following licensing terms.
  40386. +Redistribution and use in source and binary forms, with or without modification,
  40387. +are permitted provided that the following conditions are met:
  40388. +
  40389. + * Redistributions of source code must retain the above copyright notice,
  40390. + this list of conditions and the following disclaimer.
  40391. +
  40392. + * Redistributions in binary form must reproduce the above copyright
  40393. + notice, this list of conditions and the following disclaimer in the
  40394. + documentation and/or other materials provided with the distribution.
  40395. +
  40396. + * Neither the name of Marvell nor the names of its contributors may be
  40397. + used to endorse or promote products derived from this software without
  40398. + specific prior written permission.
  40399. +
  40400. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  40401. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  40402. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  40403. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  40404. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  40405. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  40406. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  40407. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  40408. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  40409. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40410. +
  40411. +*******************************************************************************/
  40412. +
  40413. +
  40414. +#ifndef __INCmvAhbToMbusRegsh
  40415. +#define __INCmvAhbToMbusRegsh
  40416. +
  40417. +/******************************/
  40418. +/* ARM Address Map Registers */
  40419. +/******************************/
  40420. +
  40421. +#define MAX_AHB_TO_MBUS_WINS 9
  40422. +#define MV_AHB_TO_MBUS_INTREG_WIN 8
  40423. +
  40424. +
  40425. +#define AHB_TO_MBUS_WIN_CTRL_REG(winNum) (0x20000 + (winNum)*0x10)
  40426. +#define AHB_TO_MBUS_WIN_BASE_REG(winNum) (0x20004 + (winNum)*0x10)
  40427. +#define AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum) (0x20008 + (winNum)*0x10)
  40428. +#define AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum) (0x2000C + (winNum)*0x10)
  40429. +#define AHB_TO_MBUS_WIN_INTEREG_REG 0x20080
  40430. +
  40431. +/* Window Control Register */
  40432. +/* AHB_TO_MBUS_WIN_CTRL_REG (ATMWCR)*/
  40433. +#define ATMWCR_WIN_ENABLE BIT0 /* Window Enable */
  40434. +
  40435. +#define ATMWCR_WIN_TARGET_OFFS 4 /* The target interface associated
  40436. + with this window*/
  40437. +#define ATMWCR_WIN_TARGET_MASK (0xf << ATMWCR_WIN_TARGET_OFFS)
  40438. +
  40439. +#define ATMWCR_WIN_ATTR_OFFS 8 /* The target interface attributes
  40440. + Associated with this window */
  40441. +#define ATMWCR_WIN_ATTR_MASK (0xff << ATMWCR_WIN_ATTR_OFFS)
  40442. +
  40443. +
  40444. +/*
  40445. +Used with the Base register to set the address window size and location
  40446. +Must be programed from LSB to MSB as sequence of 1’s followed
  40447. +by sequence of 0’s. The number of 1’s specifies the size of the window
  40448. +in 64 KB granularity (e.g. a value of 0x00FF specifies 256 = 16 MB).
  40449. +
  40450. +NOTE: A value of 0x0 specifies 64KB size.
  40451. +*/
  40452. +#define ATMWCR_WIN_SIZE_OFFS 16 /* Window Size */
  40453. +#define ATMWCR_WIN_SIZE_MASK (0xffff << ATMWCR_WIN_SIZE_OFFS)
  40454. +#define ATMWCR_WIN_SIZE_ALIGNMENT 0x10000
  40455. +
  40456. +/* Window Base Register */
  40457. +/* AHB_TO_MBUS_WIN_BASE_REG (ATMWBR) */
  40458. +
  40459. +/*
  40460. +Used with the size field to set the address window size and location.
  40461. +Corresponds to transaction address[31:16]
  40462. +*/
  40463. +#define ATMWBR_BASE_OFFS 16 /* Base Address */
  40464. +#define ATMWBR_BASE_MASK (0xffff << ATMWBR_BASE_OFFS)
  40465. +#define ATMWBR_BASE_ALIGNMENT 0x10000
  40466. +
  40467. +/* Window Remap Low Register */
  40468. +/* AHB_TO_MBUS_WIN_REMAP_LOW_REG (ATMWRLR) */
  40469. +
  40470. +/*
  40471. +Used with the size field to specifies address bits[31:0] to be driven to
  40472. +the target interface.:
  40473. +target_addr[31:16] = (addr[31:16] & size[15:0]) | (remap[31:16] & ~size[15:0])
  40474. +*/
  40475. +#define ATMWRLR_REMAP_LOW_OFFS 16 /* Remap Address */
  40476. +#define ATMWRLR_REMAP_LOW_MASK (0xffff << ATMWRLR_REMAP_LOW_OFFS)
  40477. +#define ATMWRLR_REMAP_LOW_ALIGNMENT 0x10000
  40478. +
  40479. +/* Window Remap High Register */
  40480. +/* AHB_TO_MBUS_WIN_REMAP_HIGH_REG (ATMWRHR) */
  40481. +
  40482. +/*
  40483. +Specifies address bits[63:32] to be driven to the target interface.
  40484. +target_addr[63:32] = (RemapHigh[31:0]
  40485. +*/
  40486. +#define ATMWRHR_REMAP_HIGH_OFFS 0 /* Remap Address */
  40487. +#define ATMWRHR_REMAP_HIGH_MASK (0xffffffff << ATMWRHR_REMAP_HIGH_OFFS)
  40488. +
  40489. +
  40490. +#endif /* __INCmvAhbToMbusRegsh */
  40491. +
  40492. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c
  40493. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c 1970-01-01 01:00:00.000000000 +0100
  40494. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c 2010-11-09 20:28:07.942495425 +0100
  40495. @@ -0,0 +1,1036 @@
  40496. +/*******************************************************************************
  40497. +Copyright (C) Marvell International Ltd. and its affiliates
  40498. +
  40499. +This software file (the "File") is owned and distributed by Marvell
  40500. +International Ltd. and/or its affiliates ("Marvell") under the following
  40501. +alternative licensing terms. Once you have made an election to distribute the
  40502. +File under one of the following license alternatives, please (i) delete this
  40503. +introductory statement regarding license alternatives, (ii) delete the two
  40504. +license alternatives that you have not elected to use and (iii) preserve the
  40505. +Marvell copyright notice above.
  40506. +
  40507. +********************************************************************************
  40508. +Marvell Commercial License Option
  40509. +
  40510. +If you received this File from Marvell and you have entered into a commercial
  40511. +license agreement (a "Commercial License") with Marvell, the File is licensed
  40512. +to you under the terms of the applicable Commercial License.
  40513. +
  40514. +********************************************************************************
  40515. +Marvell GPL License Option
  40516. +
  40517. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40518. +modify this File in accordance with the terms and conditions of the General
  40519. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  40520. +available along with the File in the license.txt file or by writing to the Free
  40521. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  40522. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  40523. +
  40524. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  40525. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  40526. +DISCLAIMED. The GPL License provides additional details about this warranty
  40527. +disclaimer.
  40528. +********************************************************************************
  40529. +Marvell BSD License Option
  40530. +
  40531. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40532. +modify this File under the following licensing terms.
  40533. +Redistribution and use in source and binary forms, with or without modification,
  40534. +are permitted provided that the following conditions are met:
  40535. +
  40536. + * Redistributions of source code must retain the above copyright notice,
  40537. + this list of conditions and the following disclaimer.
  40538. +
  40539. + * Redistributions in binary form must reproduce the above copyright
  40540. + notice, this list of conditions and the following disclaimer in the
  40541. + documentation and/or other materials provided with the distribution.
  40542. +
  40543. + * Neither the name of Marvell nor the names of its contributors may be
  40544. + used to endorse or promote products derived from this software without
  40545. + specific prior written permission.
  40546. +
  40547. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  40548. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  40549. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  40550. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  40551. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  40552. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  40553. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  40554. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  40555. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  40556. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40557. +
  40558. +*******************************************************************************/
  40559. +
  40560. +
  40561. +/* includes */
  40562. +#include "ctrlEnv/sys/mvCpuIf.h"
  40563. +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
  40564. +#include "cpu/mvCpu.h"
  40565. +#include "ctrlEnv/mvCtrlEnvLib.h"
  40566. +#include "mvSysHwConfig.h"
  40567. +#include "mvSysDram.h"
  40568. +
  40569. +/*#define MV_DEBUG*/
  40570. +/* defines */
  40571. +
  40572. +#ifdef MV_DEBUG
  40573. + #define DB(x) x
  40574. +#else
  40575. + #define DB(x)
  40576. +#endif
  40577. +
  40578. +/* locals */
  40579. +/* static functions */
  40580. +static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
  40581. +
  40582. +MV_TARGET * sampleAtResetTargetArray;
  40583. +MV_TARGET sampleAtResetTargetArrayP[] = BOOT_TARGETS_NAME_ARRAY;
  40584. +MV_TARGET sampleAtResetTargetArray6180P[] = BOOT_TARGETS_NAME_ARRAY_6180;
  40585. +/*******************************************************************************
  40586. +* mvCpuIfInit - Initialize Controller CPU interface
  40587. +*
  40588. +* DESCRIPTION:
  40589. +* This function initialize Controller CPU interface:
  40590. +* 1. Set CPU interface configuration registers.
  40591. +* 2. Set CPU master Pizza arbiter control according to static
  40592. +* configuration described in configuration file.
  40593. +* 3. Opens CPU address decode windows. DRAM windows are assumed to be
  40594. +* already set (auto detection).
  40595. +*
  40596. +* INPUT:
  40597. +* None.
  40598. +*
  40599. +* OUTPUT:
  40600. +* None.
  40601. +*
  40602. +* RETURN:
  40603. +* None.
  40604. +*
  40605. +*******************************************************************************/
  40606. +MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap)
  40607. +{
  40608. + MV_U32 regVal;
  40609. + MV_TARGET target;
  40610. + MV_ADDR_WIN addrWin;
  40611. +
  40612. + if (cpuAddrWinMap == NULL)
  40613. + {
  40614. + DB(mvOsPrintf("mvCpuIfInit:ERR. cpuAddrWinMap == NULL\n"));
  40615. + return MV_ERROR;
  40616. + }
  40617. +
  40618. + /*Initialize the boot target array according to device type*/
  40619. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  40620. + sampleAtResetTargetArray = sampleAtResetTargetArray6180P;
  40621. + else
  40622. + sampleAtResetTargetArray = sampleAtResetTargetArrayP;
  40623. +
  40624. + /* Set ARM Configuration register */
  40625. + regVal = MV_REG_READ(CPU_CONFIG_REG);
  40626. + regVal &= ~CPU_CONFIG_DEFAULT_MASK;
  40627. + regVal |= CPU_CONFIG_DEFAULT;
  40628. + MV_REG_WRITE(CPU_CONFIG_REG,regVal);
  40629. +
  40630. + /* First disable all CPU target windows */
  40631. + for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
  40632. + {
  40633. + if ((MV_TARGET_IS_DRAM(target))||(target == INTER_REGS))
  40634. + {
  40635. + continue;
  40636. + }
  40637. +
  40638. +#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
  40639. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  40640. + if (MV_TARGET_IS_PCI(target))
  40641. + {
  40642. + continue;
  40643. + }
  40644. +#endif
  40645. +
  40646. +#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
  40647. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  40648. + if (MV_TARGET_IS_PEX(target))
  40649. + {
  40650. + continue;
  40651. + }
  40652. +#endif
  40653. +#if defined(MV_RUN_FROM_FLASH)
  40654. + /* Don't disable the boot device. */
  40655. + if (target == DEV_BOOCS)
  40656. + {
  40657. + continue;
  40658. + }
  40659. +#endif /* MV_RUN_FROM_FLASH */
  40660. + mvCpuIfTargetWinEnable(MV_CHANGE_BOOT_CS(target),MV_FALSE);
  40661. + }
  40662. +
  40663. +#if defined(MV_RUN_FROM_FLASH)
  40664. + /* Resize the bootcs windows before other windows, because this */
  40665. + /* window is enabled and will cause an overlap if not resized. */
  40666. + target = DEV_BOOCS;
  40667. +
  40668. + if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
  40669. + {
  40670. + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
  40671. + return MV_ERROR;
  40672. + }
  40673. +
  40674. + addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
  40675. + addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
  40676. + if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
  40677. + {
  40678. + DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
  40679. + cpuAddrWinMap[target].winNum));
  40680. + }
  40681. +
  40682. +#endif /* MV_RUN_FROM_FLASH */
  40683. +
  40684. + /* Go through all targets in user table until table terminator */
  40685. + for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
  40686. + {
  40687. +
  40688. +#if defined(MV_RUN_FROM_FLASH)
  40689. + if (target == DEV_BOOCS)
  40690. + {
  40691. + continue;
  40692. + }
  40693. +#endif /* MV_RUN_FROM_FLASH */
  40694. +
  40695. + /* if DRAM auto sizing is used do not initialized DRAM target windows, */
  40696. + /* assuming this already has been done earlier. */
  40697. +#ifdef MV_DRAM_AUTO_SIZE
  40698. + if (MV_TARGET_IS_DRAM(target))
  40699. + {
  40700. + continue;
  40701. + }
  40702. +#endif
  40703. +
  40704. +#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
  40705. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  40706. + if (MV_TARGET_IS_PCI(target))
  40707. + {
  40708. + continue;
  40709. + }
  40710. +#endif
  40711. +
  40712. +#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
  40713. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  40714. + if (MV_TARGET_IS_PEX(target))
  40715. + {
  40716. + continue;
  40717. + }
  40718. +#endif
  40719. + /* If the target attribute is the same as the boot device attribute */
  40720. + /* then it's stays disable */
  40721. + if (MV_TARGET_IS_AS_BOOT(target))
  40722. + {
  40723. + continue;
  40724. + }
  40725. +
  40726. + if((0 == cpuAddrWinMap[target].addrWin.size) ||
  40727. + (DIS == cpuAddrWinMap[target].enable))
  40728. +
  40729. + {
  40730. + if (MV_OK != mvCpuIfTargetWinEnable(target, MV_FALSE))
  40731. + {
  40732. + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinEnable fail\n"));
  40733. + return MV_ERROR;
  40734. + }
  40735. +
  40736. + }
  40737. + else
  40738. + {
  40739. + if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
  40740. + {
  40741. + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
  40742. + return MV_ERROR;
  40743. + }
  40744. +
  40745. + addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
  40746. + addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
  40747. + if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
  40748. + {
  40749. + DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
  40750. + cpuAddrWinMap[target].winNum));
  40751. + }
  40752. +
  40753. +
  40754. + }
  40755. + }
  40756. +
  40757. + return MV_OK;
  40758. +
  40759. +
  40760. +}
  40761. +
  40762. +
  40763. +/*******************************************************************************
  40764. +* mvCpuIfTargetWinSet - Set CPU-to-peripheral target address window
  40765. +*
  40766. +* DESCRIPTION:
  40767. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI0_MEM0)
  40768. +* address window, also known as address decode window.
  40769. +* A new address decode window is set for specified target address window.
  40770. +* If address decode window parameter structure enables the window,
  40771. +* the routine will also enable the target window, allowing CPU to access
  40772. +* the target window.
  40773. +*
  40774. +* INPUT:
  40775. +* target - Peripheral target enumerator.
  40776. +* pAddrDecWin - CPU target window data structure.
  40777. +*
  40778. +* OUTPUT:
  40779. +* N/A
  40780. +*
  40781. +* RETURN:
  40782. +* MV_OK if CPU target window was set correctly, MV_ERROR in case of
  40783. +* address window overlapps with other active CPU target window or
  40784. +* trying to assign 36bit base address while CPU does not support that.
  40785. +* The function returns MV_NOT_SUPPORTED, if the target is unsupported.
  40786. +*
  40787. +*******************************************************************************/
  40788. +MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)
  40789. +{
  40790. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  40791. + MV_U32 existingWinNum;
  40792. + MV_DRAM_DEC_WIN addrDecWin;
  40793. +
  40794. + target = MV_CHANGE_BOOT_CS(target);
  40795. +
  40796. + /* Check parameters */
  40797. + if (target >= MAX_TARGETS)
  40798. + {
  40799. + mvOsPrintf("mvCpuIfTargetWinSet: target %d is Illigal\n", target);
  40800. + return MV_ERROR;
  40801. + }
  40802. +
  40803. + /* 2) Check if the requested window overlaps with current windows */
  40804. + if (MV_TRUE == cpuTargetWinOverlap(target, &pAddrDecWin->addrWin))
  40805. + {
  40806. + mvOsPrintf("mvCpuIfTargetWinSet: ERR. Target %d overlap\n", target);
  40807. + return MV_BAD_PARAM;
  40808. + }
  40809. +
  40810. + if (MV_TARGET_IS_DRAM(target))
  40811. + {
  40812. + /* copy relevant data to MV_DRAM_DEC_WIN structure */
  40813. + addrDecWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
  40814. + addrDecWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
  40815. + addrDecWin.addrWin.size = pAddrDecWin->addrWin.size;
  40816. + addrDecWin.enable = pAddrDecWin->enable;
  40817. +
  40818. +
  40819. + if (mvDramIfWinSet(target,&addrDecWin) != MV_OK);
  40820. + {
  40821. + mvOsPrintf("mvCpuIfTargetWinSet: mvDramIfWinSet Failed\n");
  40822. + return MV_ERROR;
  40823. + }
  40824. +
  40825. + }
  40826. + else
  40827. + {
  40828. + /* copy relevant data to MV_AHB_TO_MBUS_DEC_WIN structure */
  40829. + decWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
  40830. + decWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
  40831. + decWin.addrWin.size = pAddrDecWin->addrWin.size;
  40832. + decWin.enable = pAddrDecWin->enable;
  40833. + decWin.target = target;
  40834. +
  40835. + existingWinNum = mvAhbToMbusWinTargetGet(target);
  40836. +
  40837. + /* check if there is already another Window configured
  40838. + for this target */
  40839. + if ((existingWinNum < MAX_AHB_TO_MBUS_WINS )&&
  40840. + (existingWinNum != pAddrDecWin->winNum))
  40841. + {
  40842. + /* if we want to enable the new winow number
  40843. + passed by the user , then the old one should
  40844. + be disabled */
  40845. + if (MV_TRUE == pAddrDecWin->enable)
  40846. + {
  40847. + /* be sure it is disabled */
  40848. + mvAhbToMbusWinEnable(existingWinNum , MV_FALSE);
  40849. + }
  40850. + }
  40851. +
  40852. + if (mvAhbToMbusWinSet(pAddrDecWin->winNum,&decWin) != MV_OK)
  40853. + {
  40854. + mvOsPrintf("mvCpuIfTargetWinSet: mvAhbToMbusWinSet Failed\n");
  40855. + return MV_ERROR;
  40856. + }
  40857. +
  40858. + }
  40859. +
  40860. + return MV_OK;
  40861. +}
  40862. +
  40863. +/*******************************************************************************
  40864. +* mvCpuIfTargetWinGet - Get CPU-to-peripheral target address window
  40865. +*
  40866. +* DESCRIPTION:
  40867. +* Get the CPU peripheral target address window.
  40868. +*
  40869. +* INPUT:
  40870. +* target - Peripheral target enumerator
  40871. +*
  40872. +* OUTPUT:
  40873. +* pAddrDecWin - CPU target window information data structure.
  40874. +*
  40875. +* RETURN:
  40876. +* MV_OK if target exist, MV_ERROR otherwise.
  40877. +*
  40878. +*******************************************************************************/
  40879. +MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)
  40880. +{
  40881. +
  40882. + MV_U32 winNum=0xffffffff;
  40883. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  40884. + MV_DRAM_DEC_WIN addrDecWin;
  40885. +
  40886. + target = MV_CHANGE_BOOT_CS(target);
  40887. +
  40888. + /* Check parameters */
  40889. + if (target >= MAX_TARGETS)
  40890. + {
  40891. + mvOsPrintf("mvCpuIfTargetWinGet: target %d is Illigal\n", target);
  40892. + return MV_ERROR;
  40893. + }
  40894. +
  40895. + if (MV_TARGET_IS_DRAM(target))
  40896. + {
  40897. + if (mvDramIfWinGet(target,&addrDecWin) != MV_OK)
  40898. + {
  40899. + mvOsPrintf("mvCpuIfTargetWinGet: Failed to get window target %d\n",
  40900. + target);
  40901. + return MV_ERROR;
  40902. + }
  40903. +
  40904. + /* copy relevant data to MV_CPU_DEC_WIN structure */
  40905. + pAddrDecWin->addrWin.baseLow = addrDecWin.addrWin.baseLow;
  40906. + pAddrDecWin->addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  40907. + pAddrDecWin->addrWin.size = addrDecWin.addrWin.size;
  40908. + pAddrDecWin->enable = addrDecWin.enable;
  40909. + pAddrDecWin->winNum = 0xffffffff;
  40910. +
  40911. + }
  40912. + else
  40913. + {
  40914. + /* get the Window number associated with this target */
  40915. +
  40916. + winNum = mvAhbToMbusWinTargetGet(target);
  40917. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  40918. + {
  40919. + return MV_NO_SUCH;
  40920. +
  40921. + }
  40922. +
  40923. + if (mvAhbToMbusWinGet(winNum , &decWin) != MV_OK)
  40924. + {
  40925. + mvOsPrintf("%s: mvAhbToMbusWinGet Failed at winNum = %d\n",
  40926. + __FUNCTION__, winNum);
  40927. + return MV_ERROR;
  40928. +
  40929. + }
  40930. +
  40931. + /* copy relevant data to MV_CPU_DEC_WIN structure */
  40932. + pAddrDecWin->addrWin.baseLow = decWin.addrWin.baseLow;
  40933. + pAddrDecWin->addrWin.baseHigh = decWin.addrWin.baseHigh;
  40934. + pAddrDecWin->addrWin.size = decWin.addrWin.size;
  40935. + pAddrDecWin->enable = decWin.enable;
  40936. + pAddrDecWin->winNum = winNum;
  40937. +
  40938. + }
  40939. +
  40940. +
  40941. +
  40942. +
  40943. + return MV_OK;
  40944. +}
  40945. +
  40946. +
  40947. +/*******************************************************************************
  40948. +* mvCpuIfTargetWinEnable - Enable/disable a CPU address decode window
  40949. +*
  40950. +* DESCRIPTION:
  40951. +* This function enable/disable a CPU address decode window.
  40952. +* if parameter 'enable' == MV_TRUE the routine will enable the
  40953. +* window, thus enabling CPU accesses (before enabling the window it is
  40954. +* tested for overlapping). Otherwise, the window will be disabled.
  40955. +*
  40956. +* INPUT:
  40957. +* target - Peripheral target enumerator.
  40958. +* enable - Enable/disable parameter.
  40959. +*
  40960. +* OUTPUT:
  40961. +* N/A
  40962. +*
  40963. +* RETURN:
  40964. +* MV_ERROR if protection window number was wrong, or the window
  40965. +* overlapps other target window.
  40966. +*
  40967. +*******************************************************************************/
  40968. +MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable)
  40969. +{
  40970. + MV_U32 winNum, temp;
  40971. + MV_CPU_DEC_WIN addrDecWin;
  40972. +
  40973. + target = MV_CHANGE_BOOT_CS(target);
  40974. +
  40975. + /* Check parameters */
  40976. + if (target >= MAX_TARGETS)
  40977. + {
  40978. + mvOsPrintf("mvCpuIfTargetWinEnable: target %d is Illigal\n", target);
  40979. + return MV_ERROR;
  40980. + }
  40981. +
  40982. + /* get the window and check if it exist */
  40983. + temp = mvCpuIfTargetWinGet(target, &addrDecWin);
  40984. + if (MV_NO_SUCH == temp)
  40985. + {
  40986. + return (enable? MV_ERROR: MV_OK);
  40987. + }
  40988. + else if( MV_OK != temp)
  40989. + {
  40990. + mvOsPrintf("%s: ERR. Getting target %d failed.\n",__FUNCTION__, target);
  40991. + return MV_ERROR;
  40992. + }
  40993. +
  40994. +
  40995. + /* check overlap */
  40996. +
  40997. + if (MV_TRUE == enable)
  40998. + {
  40999. + if (MV_TRUE == cpuTargetWinOverlap(target, &addrDecWin.addrWin))
  41000. + {
  41001. + DB(mvOsPrintf("%s: ERR. Target %d overlap\n",__FUNCTION__, target));
  41002. + return MV_ERROR;
  41003. + }
  41004. +
  41005. + }
  41006. +
  41007. +
  41008. + if (MV_TARGET_IS_DRAM(target))
  41009. + {
  41010. + if (mvDramIfWinEnable(target , enable) != MV_OK)
  41011. + {
  41012. + mvOsPrintf("mvCpuIfTargetWinGet: mvDramIfWinEnable Failed at \n");
  41013. + return MV_ERROR;
  41014. +
  41015. + }
  41016. +
  41017. + }
  41018. + else
  41019. + {
  41020. + /* get the Window number associated with this target */
  41021. +
  41022. + winNum = mvAhbToMbusWinTargetGet(target);
  41023. +
  41024. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  41025. + {
  41026. + return (enable? MV_ERROR: MV_OK);
  41027. + }
  41028. +
  41029. + if (mvAhbToMbusWinEnable(winNum , enable) != MV_OK)
  41030. + {
  41031. + mvOsPrintf("mvCpuIfTargetWinGet: Failed to enable window = %d\n",
  41032. + winNum);
  41033. + return MV_ERROR;
  41034. +
  41035. + }
  41036. +
  41037. + }
  41038. +
  41039. + return MV_OK;
  41040. +}
  41041. +
  41042. +
  41043. +/*******************************************************************************
  41044. +* mvCpuIfTargetWinSizeGet - Get CPU target address window size
  41045. +*
  41046. +* DESCRIPTION:
  41047. +* Get the size of CPU-to-peripheral target window.
  41048. +*
  41049. +* INPUT:
  41050. +* target - Peripheral target enumerator
  41051. +*
  41052. +* OUTPUT:
  41053. +* None.
  41054. +*
  41055. +* RETURN:
  41056. +* 32bit size. Function also returns '0' if window is closed.
  41057. +* Function returns 0xFFFFFFFF in case of an error.
  41058. +*
  41059. +*******************************************************************************/
  41060. +MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target)
  41061. +{
  41062. + MV_CPU_DEC_WIN addrDecWin;
  41063. +
  41064. + target = MV_CHANGE_BOOT_CS(target);
  41065. +
  41066. + /* Check parameters */
  41067. + if (target >= MAX_TARGETS)
  41068. + {
  41069. + mvOsPrintf("mvCpuIfTargetWinSizeGet: target %d is Illigal\n", target);
  41070. + return 0;
  41071. + }
  41072. +
  41073. + /* Get the winNum window */
  41074. + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
  41075. + {
  41076. + mvOsPrintf("mvCpuIfTargetWinSizeGet:ERR. Getting target %d failed.\n",
  41077. + target);
  41078. + return 0;
  41079. + }
  41080. +
  41081. + /* Check if window is enabled */
  41082. + if (addrDecWin.enable == MV_TRUE)
  41083. + {
  41084. + return (addrDecWin.addrWin.size);
  41085. + }
  41086. + else
  41087. + {
  41088. + return 0; /* Window disabled. return 0 */
  41089. + }
  41090. +}
  41091. +
  41092. +/*******************************************************************************
  41093. +* mvCpuIfTargetWinBaseLowGet - Get CPU target address window base low
  41094. +*
  41095. +* DESCRIPTION:
  41096. +* CPU-to-peripheral target address window base is constructed of
  41097. +* two parts: Low and high.
  41098. +* This function gets the CPU peripheral target low base address.
  41099. +*
  41100. +* INPUT:
  41101. +* target - Peripheral target enumerator
  41102. +*
  41103. +* OUTPUT:
  41104. +* None.
  41105. +*
  41106. +* RETURN:
  41107. +* 32bit low base address.
  41108. +*
  41109. +*******************************************************************************/
  41110. +MV_U32 mvCpuIfTargetWinBaseLowGet(MV_TARGET target)
  41111. +{
  41112. + MV_CPU_DEC_WIN addrDecWin;
  41113. +
  41114. + target = MV_CHANGE_BOOT_CS(target);
  41115. +
  41116. + /* Check parameters */
  41117. + if (target >= MAX_TARGETS)
  41118. + {
  41119. + mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);
  41120. + return 0xffffffff;
  41121. + }
  41122. +
  41123. + /* Get the target window */
  41124. + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
  41125. + {
  41126. + mvOsPrintf("mvCpuIfTargetWinBaseLowGet:ERR. Getting target %d failed.\n",
  41127. + target);
  41128. + return 0xffffffff;
  41129. + }
  41130. +
  41131. + if (MV_FALSE == addrDecWin.enable)
  41132. + {
  41133. + return 0xffffffff;
  41134. + }
  41135. + return (addrDecWin.addrWin.baseLow);
  41136. +}
  41137. +
  41138. +/*******************************************************************************
  41139. +* mvCpuIfTargetWinBaseHighGet - Get CPU target address window base high
  41140. +*
  41141. +* DESCRIPTION:
  41142. +* CPU-to-peripheral target address window base is constructed of
  41143. +* two parts: Low and high.
  41144. +* This function gets the CPU peripheral target high base address.
  41145. +*
  41146. +* INPUT:
  41147. +* target - Peripheral target enumerator
  41148. +*
  41149. +* OUTPUT:
  41150. +* None.
  41151. +*
  41152. +* RETURN:
  41153. +* 32bit high base address.
  41154. +*
  41155. +*******************************************************************************/
  41156. +MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target)
  41157. +{
  41158. + MV_CPU_DEC_WIN addrDecWin;
  41159. +
  41160. + target = MV_CHANGE_BOOT_CS(target);
  41161. +
  41162. + /* Check parameters */
  41163. + if (target >= MAX_TARGETS)
  41164. + {
  41165. + mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);
  41166. + return 0xffffffff;
  41167. + }
  41168. +
  41169. + /* Get the target window */
  41170. + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
  41171. + {
  41172. + mvOsPrintf("mvCpuIfTargetWinBaseHighGet:ERR. Getting target %d failed.\n",
  41173. + target);
  41174. + return 0xffffffff;
  41175. + }
  41176. +
  41177. + if (MV_FALSE == addrDecWin.enable)
  41178. + {
  41179. + return 0;
  41180. + }
  41181. +
  41182. + return (addrDecWin.addrWin.baseHigh);
  41183. +}
  41184. +
  41185. +#if defined(MV_INCLUDE_PEX)
  41186. +/*******************************************************************************
  41187. +* mvCpuIfPexRemap - Set CPU remap register for address windows.
  41188. +*
  41189. +* DESCRIPTION:
  41190. +*
  41191. +* INPUT:
  41192. +* pexTarget - Peripheral target enumerator. Must be a PEX target.
  41193. +* pAddrDecWin - CPU target window information data structure.
  41194. +* Note that caller has to fill in the base field only. The
  41195. +* size field is ignored.
  41196. +*
  41197. +* OUTPUT:
  41198. +* None.
  41199. +*
  41200. +* RETURN:
  41201. +* MV_ERROR if target is not a PEX one, MV_OK otherwise.
  41202. +*
  41203. +*******************************************************************************/
  41204. +MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin)
  41205. +{
  41206. + MV_U32 winNum;
  41207. +
  41208. + /* Check parameters */
  41209. +
  41210. + if (mvCtrlPexMaxIfGet() > 1)
  41211. + {
  41212. + if ((!MV_TARGET_IS_PEX1(pexTarget))&&(!MV_TARGET_IS_PEX0(pexTarget)))
  41213. + {
  41214. + mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);
  41215. + return 0xffffffff;
  41216. + }
  41217. +
  41218. + }
  41219. + else
  41220. + {
  41221. + if (!MV_TARGET_IS_PEX0(pexTarget))
  41222. + {
  41223. + mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);
  41224. + return 0xffffffff;
  41225. + }
  41226. +
  41227. + }
  41228. +
  41229. + /* get the Window number associated with this target */
  41230. + winNum = mvAhbToMbusWinTargetGet(pexTarget);
  41231. +
  41232. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  41233. + {
  41234. + mvOsPrintf("mvCpuIfPexRemap: mvAhbToMbusWinTargetGet Failed\n");
  41235. + return 0xffffffff;
  41236. +
  41237. + }
  41238. +
  41239. + return mvAhbToMbusWinRemap(winNum , pAddrDecWin);
  41240. +}
  41241. +
  41242. +#endif
  41243. +
  41244. +#if defined(MV_INCLUDE_PCI)
  41245. +/*******************************************************************************
  41246. +* mvCpuIfPciRemap - Set CPU remap register for address windows.
  41247. +*
  41248. +* DESCRIPTION:
  41249. +*
  41250. +* INPUT:
  41251. +* pciTarget - Peripheral target enumerator. Must be a PCI target.
  41252. +* pAddrDecWin - CPU target window information data structure.
  41253. +* Note that caller has to fill in the base field only. The
  41254. +* size field is ignored.
  41255. +*
  41256. +* OUTPUT:
  41257. +* None.
  41258. +*
  41259. +* RETURN:
  41260. +* MV_ERROR if target is not a PCI one, MV_OK otherwise.
  41261. +*
  41262. +*******************************************************************************/
  41263. +MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin)
  41264. +{
  41265. + MV_U32 winNum;
  41266. +
  41267. + /* Check parameters */
  41268. + if (!MV_TARGET_IS_PCI(pciTarget))
  41269. + {
  41270. + mvOsPrintf("mvCpuIfPciRemap: target %d is Illigal\n",pciTarget);
  41271. + return 0xffffffff;
  41272. + }
  41273. +
  41274. + /* get the Window number associated with this target */
  41275. + winNum = mvAhbToMbusWinTargetGet(pciTarget);
  41276. +
  41277. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  41278. + {
  41279. + mvOsPrintf("mvCpuIfPciRemap: mvAhbToMbusWinTargetGet Failed\n");
  41280. + return 0xffffffff;
  41281. +
  41282. + }
  41283. +
  41284. + return mvAhbToMbusWinRemap(winNum , pAddrDecWin);
  41285. +}
  41286. +#endif /* MV_INCLUDE_PCI */
  41287. +
  41288. +
  41289. +/*******************************************************************************
  41290. +* mvCpuIfPciIfRemap - Set CPU remap register for address windows.
  41291. +*
  41292. +* DESCRIPTION:
  41293. +*
  41294. +* INPUT:
  41295. +* pciTarget - Peripheral target enumerator. Must be a PCI target.
  41296. +* pAddrDecWin - CPU target window information data structure.
  41297. +* Note that caller has to fill in the base field only. The
  41298. +* size field is ignored.
  41299. +*
  41300. +* OUTPUT:
  41301. +* None.
  41302. +*
  41303. +* RETURN:
  41304. +* MV_ERROR if target is not a PCI one, MV_OK otherwise.
  41305. +*
  41306. +*******************************************************************************/
  41307. +MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciIfTarget, MV_ADDR_WIN *pAddrDecWin)
  41308. +{
  41309. +#if defined(MV_INCLUDE_PEX)
  41310. + if (MV_TARGET_IS_PEX(pciIfTarget))
  41311. + {
  41312. + return mvCpuIfPexRemap(pciIfTarget,pAddrDecWin);
  41313. + }
  41314. +#endif
  41315. +#if defined(MV_INCLUDE_PCI)
  41316. +
  41317. + if (MV_TARGET_IS_PCI(pciIfTarget))
  41318. + {
  41319. + return mvCpuIfPciRemap(pciIfTarget,pAddrDecWin);
  41320. + }
  41321. +#endif
  41322. + return 0;
  41323. +}
  41324. +
  41325. +
  41326. +
  41327. +/*******************************************************************************
  41328. +* mvCpuIfTargetOfBaseAddressGet - Get the target according to base address
  41329. +*
  41330. +* DESCRIPTION:
  41331. +*
  41332. +* INPUT:
  41333. +* baseAddress - base address to be checked
  41334. +*
  41335. +* OUTPUT:
  41336. +* None.
  41337. +*
  41338. +* RETURN:
  41339. +* the target number that baseAddress belongs to or MAX_TARGETS is not
  41340. +* found
  41341. +*
  41342. +*******************************************************************************/
  41343. +
  41344. +MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress)
  41345. +{
  41346. + MV_CPU_DEC_WIN win;
  41347. + MV_U32 target;
  41348. +
  41349. + for( target = 0; target < MAX_TARGETS; target++ )
  41350. + {
  41351. + if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )
  41352. + {
  41353. + if( win.enable )
  41354. + {
  41355. + if ((baseAddress >= win.addrWin.baseLow) &&
  41356. + (baseAddress < win.addrWin.baseLow + win.addrWin.size)) break;
  41357. + }
  41358. + }
  41359. + else return MAX_TARGETS;
  41360. +
  41361. + }
  41362. +
  41363. + return target;
  41364. +}
  41365. +/*******************************************************************************
  41366. +* cpuTargetWinOverlap - Detect CPU address decode windows overlapping
  41367. +*
  41368. +* DESCRIPTION:
  41369. +* An unpredicted behaviur is expected in case CPU address decode
  41370. +* windows overlapps.
  41371. +* This function detects CPU address decode windows overlapping of a
  41372. +* specified target. The function does not check the target itself for
  41373. +* overlapping. The function also skipps disabled address decode windows.
  41374. +*
  41375. +* INPUT:
  41376. +* target - Peripheral target enumerator.
  41377. +* pAddrDecWin - An address decode window struct.
  41378. +*
  41379. +* OUTPUT:
  41380. +* None.
  41381. +*
  41382. +* RETURN:
  41383. +* MV_TRUE if the given address window overlaps current address
  41384. +* decode map, MV_FALSE otherwise.
  41385. +*
  41386. +*******************************************************************************/
  41387. +static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
  41388. +{
  41389. + MV_U32 targetNum;
  41390. + MV_CPU_DEC_WIN addrDecWin;
  41391. + MV_STATUS status;
  41392. +
  41393. +
  41394. + for(targetNum = 0; targetNum < MAX_TARGETS; targetNum++)
  41395. + {
  41396. +#if defined(MV_RUN_FROM_FLASH)
  41397. + if(MV_TARGET_IS_AS_BOOT(target))
  41398. + {
  41399. + if (MV_CHANGE_BOOT_CS(targetNum) == target)
  41400. + continue;
  41401. + }
  41402. +#endif /* MV_RUN_FROM_FLASH */
  41403. +
  41404. + /* don't check our target or illegal targets */
  41405. + if (targetNum == target)
  41406. + {
  41407. + continue;
  41408. + }
  41409. +
  41410. + /* Get window parameters */
  41411. + status = mvCpuIfTargetWinGet(targetNum, &addrDecWin);
  41412. + if(MV_NO_SUCH == status)
  41413. + {
  41414. + continue;
  41415. + }
  41416. + if(MV_OK != status)
  41417. + {
  41418. + DB(mvOsPrintf("cpuTargetWinOverlap: ERR. TargetWinGet failed\n"));
  41419. + return MV_TRUE;
  41420. + }
  41421. +
  41422. + /* Do not check disabled windows */
  41423. + if (MV_FALSE == addrDecWin.enable)
  41424. + {
  41425. + continue;
  41426. + }
  41427. +
  41428. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  41429. + {
  41430. + DB(mvOsPrintf(
  41431. + "cpuTargetWinOverlap: Required target %d overlap current %d\n",
  41432. + target, targetNum));
  41433. + return MV_TRUE;
  41434. + }
  41435. + }
  41436. +
  41437. + return MV_FALSE;
  41438. +
  41439. +}
  41440. +
  41441. +/*******************************************************************************
  41442. +* mvCpuIfAddDecShow - Print the CPU address decode map.
  41443. +*
  41444. +* DESCRIPTION:
  41445. +* This function print the CPU address decode map.
  41446. +*
  41447. +* INPUT:
  41448. +* None.
  41449. +*
  41450. +* OUTPUT:
  41451. +* None.
  41452. +*
  41453. +* RETURN:
  41454. +* None.
  41455. +*
  41456. +*******************************************************************************/
  41457. +MV_VOID mvCpuIfAddDecShow(MV_VOID)
  41458. +{
  41459. + MV_CPU_DEC_WIN win;
  41460. + MV_U32 target;
  41461. + mvOsOutput( "\n" );
  41462. + mvOsOutput( "CPU Interface\n" );
  41463. + mvOsOutput( "-------------\n" );
  41464. +
  41465. + for( target = 0; target < MAX_TARGETS; target++ )
  41466. + {
  41467. +
  41468. + memset( &win, 0, sizeof(MV_CPU_DEC_WIN) );
  41469. +
  41470. + mvOsOutput( "%s ",mvCtrlTargetNameGet(target));
  41471. + mvOsOutput( "...." );
  41472. +
  41473. + if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )
  41474. + {
  41475. + if( win.enable )
  41476. + {
  41477. + mvOsOutput( "base %08x, ", win.addrWin.baseLow );
  41478. + mvSizePrint( win.addrWin.size );
  41479. + mvOsOutput( "\n" );
  41480. +
  41481. + }
  41482. + else
  41483. + mvOsOutput( "disable\n" );
  41484. + }
  41485. + else if( mvCpuIfTargetWinGet( target, &win ) == MV_NO_SUCH )
  41486. + {
  41487. + mvOsOutput( "no such\n" );
  41488. + }
  41489. + }
  41490. +}
  41491. +
  41492. +/*******************************************************************************
  41493. +* mvCpuIfEnablePex - Enable PCI Express.
  41494. +*
  41495. +* DESCRIPTION:
  41496. +* This function Enable PCI Express.
  41497. +*
  41498. +* INPUT:
  41499. +* pexIf - PEX interface number.
  41500. +* pexType - MV_PEX_ROOT_COMPLEX - root complex device
  41501. +* MV_PEX_END_POINT - end point device
  41502. +* OUTPUT:
  41503. +* None.
  41504. +*
  41505. +* RETURN:
  41506. +* None.
  41507. +*
  41508. +*******************************************************************************/
  41509. +#if defined(MV_INCLUDE_PEX)
  41510. +MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType)
  41511. +{
  41512. + /* Set pex mode incase S@R not exist */
  41513. + if( pexType == MV_PEX_END_POINT)
  41514. + {
  41515. + MV_REG_BIT_RESET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
  41516. + /* Change pex mode in capability reg */
  41517. + MV_REG_BIT_RESET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT22);
  41518. + MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT20);
  41519. +
  41520. + }
  41521. + else
  41522. + {
  41523. + MV_REG_BIT_SET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
  41524. + }
  41525. +
  41526. + /* CPU config register Pex enable */
  41527. + MV_REG_BIT_SET(CPU_CTRL_STAT_REG,CCSR_PCI_ACCESS_MASK);
  41528. +}
  41529. +#endif
  41530. +
  41531. +
  41532. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h
  41533. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h 1970-01-01 01:00:00.000000000 +0100
  41534. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h 2010-11-09 20:28:07.982495689 +0100
  41535. @@ -0,0 +1,120 @@
  41536. +/*******************************************************************************
  41537. +Copyright (C) Marvell International Ltd. and its affiliates
  41538. +
  41539. +This software file (the "File") is owned and distributed by Marvell
  41540. +International Ltd. and/or its affiliates ("Marvell") under the following
  41541. +alternative licensing terms. Once you have made an election to distribute the
  41542. +File under one of the following license alternatives, please (i) delete this
  41543. +introductory statement regarding license alternatives, (ii) delete the two
  41544. +license alternatives that you have not elected to use and (iii) preserve the
  41545. +Marvell copyright notice above.
  41546. +
  41547. +********************************************************************************
  41548. +Marvell Commercial License Option
  41549. +
  41550. +If you received this File from Marvell and you have entered into a commercial
  41551. +license agreement (a "Commercial License") with Marvell, the File is licensed
  41552. +to you under the terms of the applicable Commercial License.
  41553. +
  41554. +********************************************************************************
  41555. +Marvell GPL License Option
  41556. +
  41557. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41558. +modify this File in accordance with the terms and conditions of the General
  41559. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  41560. +available along with the File in the license.txt file or by writing to the Free
  41561. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  41562. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  41563. +
  41564. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  41565. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  41566. +DISCLAIMED. The GPL License provides additional details about this warranty
  41567. +disclaimer.
  41568. +********************************************************************************
  41569. +Marvell BSD License Option
  41570. +
  41571. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41572. +modify this File under the following licensing terms.
  41573. +Redistribution and use in source and binary forms, with or without modification,
  41574. +are permitted provided that the following conditions are met:
  41575. +
  41576. + * Redistributions of source code must retain the above copyright notice,
  41577. + this list of conditions and the following disclaimer.
  41578. +
  41579. + * Redistributions in binary form must reproduce the above copyright
  41580. + notice, this list of conditions and the following disclaimer in the
  41581. + documentation and/or other materials provided with the distribution.
  41582. +
  41583. + * Neither the name of Marvell nor the names of its contributors may be
  41584. + used to endorse or promote products derived from this software without
  41585. + specific prior written permission.
  41586. +
  41587. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  41588. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  41589. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41590. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  41591. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  41592. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  41593. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41594. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  41595. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  41596. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  41597. +
  41598. +*******************************************************************************/
  41599. +
  41600. +
  41601. +#ifndef __INCmvCpuIfh
  41602. +#define __INCmvCpuIfh
  41603. +
  41604. +/* includes */
  41605. +#include "ctrlEnv/mvCtrlEnvLib.h"
  41606. +#include "ctrlEnv/sys/mvCpuIfRegs.h"
  41607. +#include "ctrlEnv/sys/mvAhbToMbus.h"
  41608. +#include "ddr2/mvDramIf.h"
  41609. +#include "ctrlEnv/sys/mvSysDram.h"
  41610. +#if defined(MV_INCLUDE_PEX)
  41611. +#include "pex/mvPex.h"
  41612. +#endif
  41613. +
  41614. +/* defines */
  41615. +
  41616. +/* typedefs */
  41617. +/* This structure describes CPU interface address decode window */
  41618. +typedef struct _mvCpuIfDecWin
  41619. +{
  41620. + MV_ADDR_WIN addrWin; /* An address window*/
  41621. + MV_U32 winNum; /* Window Number in the AHB To Mbus bridge */
  41622. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  41623. +
  41624. +}MV_CPU_DEC_WIN;
  41625. +
  41626. +
  41627. +
  41628. +/* mvCpuIfLib.h API list */
  41629. +
  41630. +/* mvCpuIfLib.h API list */
  41631. +
  41632. +MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap);
  41633. +MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);
  41634. +MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);
  41635. +MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable);
  41636. +MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target);
  41637. +MV_U32 mvCpuIfTargetWinBaseLowGet(MV_TARGET target);
  41638. +MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target);
  41639. +MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress);
  41640. +#if defined(MV_INCLUDE_PEX)
  41641. +MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin);
  41642. +MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType);
  41643. +#endif
  41644. +#if defined(MV_INCLUDE_PCI)
  41645. +MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);
  41646. +#endif
  41647. +MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);
  41648. +
  41649. +MV_VOID mvCpuIfAddDecShow(MV_VOID);
  41650. +
  41651. +#if defined(MV88F6281)
  41652. +MV_STATUS mvCpuIfBridgeReorderWAInit(void);
  41653. +#endif
  41654. +
  41655. +#endif /* __INCmvCpuIfh */
  41656. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h
  41657. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  41658. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h 2010-11-09 20:28:08.012495399 +0100
  41659. @@ -0,0 +1,304 @@
  41660. +/*******************************************************************************
  41661. +Copyright (C) Marvell International Ltd. and its affiliates
  41662. +
  41663. +This software file (the "File") is owned and distributed by Marvell
  41664. +International Ltd. and/or its affiliates ("Marvell") under the following
  41665. +alternative licensing terms. Once you have made an election to distribute the
  41666. +File under one of the following license alternatives, please (i) delete this
  41667. +introductory statement regarding license alternatives, (ii) delete the two
  41668. +license alternatives that you have not elected to use and (iii) preserve the
  41669. +Marvell copyright notice above.
  41670. +
  41671. +********************************************************************************
  41672. +Marvell Commercial License Option
  41673. +
  41674. +If you received this File from Marvell and you have entered into a commercial
  41675. +license agreement (a "Commercial License") with Marvell, the File is licensed
  41676. +to you under the terms of the applicable Commercial License.
  41677. +
  41678. +********************************************************************************
  41679. +Marvell GPL License Option
  41680. +
  41681. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41682. +modify this File in accordance with the terms and conditions of the General
  41683. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  41684. +available along with the File in the license.txt file or by writing to the Free
  41685. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  41686. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  41687. +
  41688. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  41689. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  41690. +DISCLAIMED. The GPL License provides additional details about this warranty
  41691. +disclaimer.
  41692. +********************************************************************************
  41693. +Marvell BSD License Option
  41694. +
  41695. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41696. +modify this File under the following licensing terms.
  41697. +Redistribution and use in source and binary forms, with or without modification,
  41698. +are permitted provided that the following conditions are met:
  41699. +
  41700. + * Redistributions of source code must retain the above copyright notice,
  41701. + this list of conditions and the following disclaimer.
  41702. +
  41703. + * Redistributions in binary form must reproduce the above copyright
  41704. + notice, this list of conditions and the following disclaimer in the
  41705. + documentation and/or other materials provided with the distribution.
  41706. +
  41707. + * Neither the name of Marvell nor the names of its contributors may be
  41708. + used to endorse or promote products derived from this software without
  41709. + specific prior written permission.
  41710. +
  41711. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  41712. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  41713. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41714. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  41715. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  41716. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  41717. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41718. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  41719. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  41720. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  41721. +
  41722. +*******************************************************************************/
  41723. +
  41724. +
  41725. +#ifndef __INCmvCpuIfRegsh
  41726. +#define __INCmvCpuIfRegsh
  41727. +
  41728. +/****************************************/
  41729. +/* ARM Control and Status Registers Map */
  41730. +/****************************************/
  41731. +
  41732. +#define CPU_CONFIG_REG 0x20100
  41733. +#define CPU_CTRL_STAT_REG 0x20104
  41734. +#define CPU_RSTOUTN_MASK_REG 0x20108
  41735. +#define CPU_SYS_SOFT_RST_REG 0x2010C
  41736. +#define CPU_AHB_MBUS_CAUSE_INT_REG 0x20110
  41737. +#define CPU_AHB_MBUS_MASK_INT_REG 0x20114
  41738. +#define CPU_FTDLL_CONFIG_REG 0x20120
  41739. +#define CPU_L2_CONFIG_REG 0x20128
  41740. +
  41741. +
  41742. +
  41743. +/* ARM Configuration register */
  41744. +/* CPU_CONFIG_REG (CCR) */
  41745. +
  41746. +
  41747. +/* Reset vector location */
  41748. +#define CCR_VEC_INIT_LOC_OFFS 1
  41749. +#define CCR_VEC_INIT_LOC_MASK BIT1
  41750. +/* reset at 0x00000000 */
  41751. +#define CCR_VEC_INIT_LOC_0000 (0 << CCR_VEC_INIT_LOC_OFFS)
  41752. +/* reset at 0xFFFF0000 */
  41753. +#define CCR_VEC_INIT_LOC_FF00 (1 << CCR_VEC_INIT_LOC_OFFS)
  41754. +
  41755. +
  41756. +#define CCR_AHB_ERROR_PROP_OFFS 2
  41757. +#define CCR_AHB_ERROR_PROP_MASK BIT2
  41758. +/* Erros are not propogated to AHB */
  41759. +#define CCR_AHB_ERROR_PROP_NO_INDICATE (0 << CCR_AHB_ERROR_PROP_OFFS)
  41760. +/* Erros are propogated to AHB */
  41761. +#define CCR_AHB_ERROR_PROP_INDICATE (1 << CCR_AHB_ERROR_PROP_OFFS)
  41762. +
  41763. +
  41764. +#define CCR_ENDIAN_INIT_OFFS 3
  41765. +#define CCR_ENDIAN_INIT_MASK BIT3
  41766. +#define CCR_ENDIAN_INIT_LITTLE (0 << CCR_ENDIAN_INIT_OFFS)
  41767. +#define CCR_ENDIAN_INIT_BIG (1 << CCR_ENDIAN_INIT_OFFS)
  41768. +
  41769. +
  41770. +#define CCR_INCR_EN_OFFS 4
  41771. +#define CCR_INCR_EN_MASK BIT4
  41772. +#define CCR_INCR_EN BIT4
  41773. +
  41774. +
  41775. +#define CCR_NCB_BLOCKING_OFFS 5
  41776. +#define CCR_NCB_BLOCKING_MASK (1 << CCR_NCB_BLOCKING_OFFS)
  41777. +#define CCR_NCB_BLOCKING_NON (0 << CCR_NCB_BLOCKING_OFFS)
  41778. +#define CCR_NCB_BLOCKING_EN (1 << CCR_NCB_BLOCKING_OFFS)
  41779. +
  41780. +#define CCR_CPU_2_MBUSL_TICK_DRV_OFFS 8
  41781. +#define CCR_CPU_2_MBUSL_TICK_DRV_MASK (0xF << CCR_CPU_2_MBUSL_TICK_DRV_OFFS)
  41782. +#define CCR_CPU_2_MBUSL_TICK_SMPL_OFFS 12
  41783. +#define CCR_CPU_2_MBUSL_TICK_SMPL_MASK (0xF << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS)
  41784. +#define CCR_ICACH_PREF_BUF_ENABLE BIT16
  41785. +#define CCR_DCACH_PREF_BUF_ENABLE BIT17
  41786. +
  41787. +/* Ratio options for CPU to DDR for 6281/6192/6190 */
  41788. +#define CPU_2_DDR_CLK_1x3 4
  41789. +#define CPU_2_DDR_CLK_1x4 6
  41790. +
  41791. +/* Ratio options for CPU to DDR for 6281 only */
  41792. +#define CPU_2_DDR_CLK_2x9 7
  41793. +#define CPU_2_DDR_CLK_1x5 8
  41794. +#define CPU_2_DDR_CLK_1x6 9
  41795. +
  41796. +/* Ratio options for CPU to DDR for 6180 only */
  41797. +#define CPU_2_DDR_CLK_1x3_1 0x5
  41798. +#define CPU_2_DDR_CLK_1x4_1 0x6
  41799. +
  41800. +/* Default values for CPU to Mbus-L DDR Interface Tick Driver and */
  41801. +/* CPU to Mbus-L Tick Sample fields in CPU config register */
  41802. +
  41803. +#define TICK_DRV_1x1 0
  41804. +#define TICK_DRV_1x2 0
  41805. +#define TICK_DRV_1x3 1
  41806. +#define TICK_DRV_1x4 2
  41807. +#define TICK_SMPL_1x1 0
  41808. +#define TICK_SMPL_1x2 1
  41809. +#define TICK_SMPL_1x3 0
  41810. +#define TICK_SMPL_1x4 0
  41811. +
  41812. +#define CPU_2_MBUSL_DDR_CLK_1x2 \
  41813. + ((TICK_DRV_1x2 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
  41814. + (TICK_SMPL_1x2 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
  41815. +#define CPU_2_MBUSL_DDR_CLK_1x3 \
  41816. + ((TICK_DRV_1x3 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
  41817. + (TICK_SMPL_1x3 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
  41818. +#define CPU_2_MBUSL_DDR_CLK_1x4 \
  41819. + ((TICK_DRV_1x4 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
  41820. + (TICK_SMPL_1x4 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
  41821. +
  41822. +/* ARM Control and Status register */
  41823. +/* CPU_CTRL_STAT_REG (CCSR) */
  41824. +
  41825. +
  41826. +/*
  41827. +This is used to block PCI express\PCI from access Socrates/Feroceon GP
  41828. +while ARM boot is still in progress
  41829. +*/
  41830. +
  41831. +#define CCSR_PCI_ACCESS_OFFS 0
  41832. +#define CCSR_PCI_ACCESS_MASK BIT0
  41833. +#define CCSR_PCI_ACCESS_ENABLE (0 << CCSR_PCI_ACCESS_OFFS)
  41834. +#define CCSR_PCI_ACCESS_DISBALE (1 << CCSR_PCI_ACCESS_OFFS)
  41835. +
  41836. +#define CCSR_ARM_RESET BIT1
  41837. +#define CCSR_SELF_INT BIT2
  41838. +#define CCSR_BIG_ENDIAN BIT15
  41839. +
  41840. +
  41841. +/* RSTOUTn Mask Register */
  41842. +/* CPU_RSTOUTN_MASK_REG (CRMR) */
  41843. +
  41844. +#define CRMR_PEX_RST_OUT_OFFS 0
  41845. +#define CRMR_PEX_RST_OUT_MASK BIT0
  41846. +#define CRMR_PEX_RST_OUT_ENABLE (1 << CRMR_PEX_RST_OUT_OFFS)
  41847. +#define CRMR_PEX_RST_OUT_DISABLE (0 << CRMR_PEX_RST_OUT_OFFS)
  41848. +
  41849. +#define CRMR_WD_RST_OUT_OFFS 1
  41850. +#define CRMR_WD_RST_OUT_MASK BIT1
  41851. +#define CRMR_WD_RST_OUT_ENABLE (1 << CRMR_WD_RST_OUT_OFFS)
  41852. +#define CRMR_WD_RST_OUT_DISBALE (0 << CRMR_WD_RST_OUT_OFFS)
  41853. +
  41854. +#define CRMR_SOFT_RST_OUT_OFFS 2
  41855. +#define CRMR_SOFT_RST_OUT_MASK BIT2
  41856. +#define CRMR_SOFT_RST_OUT_ENABLE (1 << CRMR_SOFT_RST_OUT_OFFS)
  41857. +#define CRMR_SOFT_RST_OUT_DISBALE (0 << CRMR_SOFT_RST_OUT_OFFS)
  41858. +
  41859. +/* System Software Reset Register */
  41860. +/* CPU_SYS_SOFT_RST_REG (CSSRR) */
  41861. +
  41862. +#define CSSRR_SYSTEM_SOFT_RST BIT0
  41863. +
  41864. +/* AHB to Mbus Bridge Interrupt Cause Register*/
  41865. +/* CPU_AHB_MBUS_CAUSE_INT_REG (CAMCIR) */
  41866. +
  41867. +#define CAMCIR_ARM_SELF_INT BIT0
  41868. +#define CAMCIR_ARM_TIMER0_INT_REQ BIT1
  41869. +#define CAMCIR_ARM_TIMER1_INT_REQ BIT2
  41870. +#define CAMCIR_ARM_WD_TIMER_INT_REQ BIT3
  41871. +
  41872. +
  41873. +/* AHB to Mbus Bridge Interrupt Mask Register*/
  41874. +/* CPU_AHB_MBUS_MASK_INT_REG (CAMMIR) */
  41875. +
  41876. +#define CAMCIR_ARM_SELF_INT_OFFS 0
  41877. +#define CAMCIR_ARM_SELF_INT_MASK BIT0
  41878. +#define CAMCIR_ARM_SELF_INT_EN (1 << CAMCIR_ARM_SELF_INT_OFFS)
  41879. +#define CAMCIR_ARM_SELF_INT_DIS (0 << CAMCIR_ARM_SELF_INT_OFFS)
  41880. +
  41881. +
  41882. +#define CAMCIR_ARM_TIMER0_INT_REQ_OFFS 1
  41883. +#define CAMCIR_ARM_TIMER0_INT_REQ_MASK BIT1
  41884. +#define CAMCIR_ARM_TIMER0_INT_REQ_EN (1 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS)
  41885. +#define CAMCIR_ARM_TIMER0_INT_REQ_DIS (0 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS)
  41886. +
  41887. +#define CAMCIR_ARM_TIMER1_INT_REQ_OFFS 2
  41888. +#define CAMCIR_ARM_TIMER1_INT_REQ_MASK BIT2
  41889. +#define CAMCIR_ARM_TIMER1_INT_REQ_EN (1 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS)
  41890. +#define CAMCIR_ARM_TIMER1_INT_REQ_DIS (0 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS)
  41891. +
  41892. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS 3
  41893. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_MASK BIT3
  41894. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_EN (1 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS)
  41895. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_DIS (0 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS)
  41896. +
  41897. +/* CPU FTDLL Config register (CFCR) fields */
  41898. +#define CFCR_FTDLL_ICACHE_TAG_OFFS 0
  41899. +#define CFCR_FTDLL_ICACHE_TAG_MASK (0x7F << CFCR_FTDLL_ICACHE_TAG_OFFS)
  41900. +#define CFCR_FTDLL_DCACHE_TAG_OFFS 8
  41901. +#define CFCR_FTDLL_DCACHE_TAG_MASK (0x7F << CFCR_FTDLL_DCACHE_TAG_OFFS)
  41902. +#define CFCR_FTDLL_OVERWRITE_ENABLE (1 << 15)
  41903. +/* For Orion 2 D2 only */
  41904. +#define CFCR_MRVL_CPU_ID_OFFS 16
  41905. +#define CFCR_MRVL_CPU_ID_MASK (0x1 << CFCR_MRVL_CPU_ID_OFFS)
  41906. +#define CFCR_ARM_CPU_ID (0x0 << CFCR_MRVL_CPU_ID_OFFS)
  41907. +#define CFCR_MRVL_CPU_ID (0x1 << CFCR_MRVL_CPU_ID_OFFS)
  41908. +#define CFCR_VFP_SUB_ARC_NUM_OFFS 7
  41909. +#define CFCR_VFP_SUB_ARC_NUM_MASK (0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)
  41910. +#define CFCR_VFP_SUB_ARC_NUM_1 (0x0 << CFCR_VFP_SUB_ARC_NUM_OFFS)
  41911. +#define CFCR_VFP_SUB_ARC_NUM_2 (0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)
  41912. +
  41913. +/* CPU_L2_CONFIG_REG fields */
  41914. +#ifdef MV_CPU_LE
  41915. +#define CL2CR_L2_ECC_EN_OFFS 2
  41916. +#define CL2CR_L2_WT_MODE_OFFS 4
  41917. +#else
  41918. +#define CL2CR_L2_ECC_EN_OFFS 26
  41919. +#define CL2CR_L2_WT_MODE_OFFS 28
  41920. +#endif
  41921. +
  41922. +#define CL2CR_L2_ECC_EN_MASK (1 << CL2CR_L2_ECC_EN_OFFS)
  41923. +#define CL2CR_L2_WT_MODE_MASK (1 << CL2CR_L2_WT_MODE_OFFS)
  41924. +
  41925. +/*******************************************/
  41926. +/* Main Interrupt Controller Registers Map */
  41927. +/*******************************************/
  41928. +
  41929. +#define CPU_MAIN_INT_CAUSE_REG 0x20200
  41930. +#define CPU_MAIN_IRQ_MASK_REG 0x20204
  41931. +#define CPU_MAIN_FIQ_MASK_REG 0x20208
  41932. +#define CPU_ENPOINT_MASK_REG 0x2020C
  41933. +#define CPU_MAIN_INT_CAUSE_HIGH_REG 0x20210
  41934. +#define CPU_MAIN_IRQ_MASK_HIGH_REG 0x20214
  41935. +#define CPU_MAIN_FIQ_MASK_HIGH_REG 0x20218
  41936. +#define CPU_ENPOINT_MASK_HIGH_REG 0x2021C
  41937. +
  41938. +
  41939. +/*******************************************/
  41940. +/* ARM Doorbell Registers Map */
  41941. +/*******************************************/
  41942. +
  41943. +#define CPU_HOST_TO_ARM_DRBL_REG 0x20400
  41944. +#define CPU_HOST_TO_ARM_MASK_REG 0x20404
  41945. +#define CPU_ARM_TO_HOST_DRBL_REG 0x20408
  41946. +#define CPU_ARM_TO_HOST_MASK_REG 0x2040C
  41947. +
  41948. +
  41949. +
  41950. +/* CPU control register map */
  41951. +/* Set bits means value is about to change according to new value */
  41952. +#define CPU_CONFIG_DEFAULT_MASK (CCR_VEC_INIT_LOC_MASK | CCR_AHB_ERROR_PROP_MASK)
  41953. +
  41954. +#define CPU_CONFIG_DEFAULT (CCR_VEC_INIT_LOC_FF00)
  41955. +
  41956. +/* CPU Control and status defaults */
  41957. +#define CPU_CTRL_STAT_DEFAULT_MASK (CCSR_PCI_ACCESS_MASK)
  41958. +
  41959. +
  41960. +#define CPU_CTRL_STAT_DEFAULT (CCSR_PCI_ACCESS_ENABLE)
  41961. +
  41962. +#endif /* __INCmvCpuIfRegsh */
  41963. +
  41964. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c
  41965. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c 1970-01-01 01:00:00.000000000 +0100
  41966. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c 2010-11-09 20:28:08.042495347 +0100
  41967. @@ -0,0 +1,324 @@
  41968. +/*******************************************************************************
  41969. +Copyright (C) Marvell International Ltd. and its affiliates
  41970. +
  41971. +This software file (the "File") is owned and distributed by Marvell
  41972. +International Ltd. and/or its affiliates ("Marvell") under the following
  41973. +alternative licensing terms. Once you have made an election to distribute the
  41974. +File under one of the following license alternatives, please (i) delete this
  41975. +introductory statement regarding license alternatives, (ii) delete the two
  41976. +license alternatives that you have not elected to use and (iii) preserve the
  41977. +Marvell copyright notice above.
  41978. +
  41979. +********************************************************************************
  41980. +Marvell Commercial License Option
  41981. +
  41982. +If you received this File from Marvell and you have entered into a commercial
  41983. +license agreement (a "Commercial License") with Marvell, the File is licensed
  41984. +to you under the terms of the applicable Commercial License.
  41985. +
  41986. +********************************************************************************
  41987. +Marvell GPL License Option
  41988. +
  41989. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41990. +modify this File in accordance with the terms and conditions of the General
  41991. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  41992. +available along with the File in the license.txt file or by writing to the Free
  41993. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  41994. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  41995. +
  41996. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  41997. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  41998. +DISCLAIMED. The GPL License provides additional details about this warranty
  41999. +disclaimer.
  42000. +********************************************************************************
  42001. +Marvell BSD License Option
  42002. +
  42003. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42004. +modify this File under the following licensing terms.
  42005. +Redistribution and use in source and binary forms, with or without modification,
  42006. +are permitted provided that the following conditions are met:
  42007. +
  42008. + * Redistributions of source code must retain the above copyright notice,
  42009. + this list of conditions and the following disclaimer.
  42010. +
  42011. + * Redistributions in binary form must reproduce the above copyright
  42012. + notice, this list of conditions and the following disclaimer in the
  42013. + documentation and/or other materials provided with the distribution.
  42014. +
  42015. + * Neither the name of Marvell nor the names of its contributors may be
  42016. + used to endorse or promote products derived from this software without
  42017. + specific prior written permission.
  42018. +
  42019. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42020. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42021. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42022. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42023. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42024. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42025. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42026. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42027. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42028. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42029. +
  42030. +*******************************************************************************/
  42031. +#include "mvSysAudio.h"
  42032. +
  42033. +/*******************************************************************************
  42034. +* mvAudioWinSet - Set AUDIO target address window
  42035. +*
  42036. +* DESCRIPTION:
  42037. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  42038. +* address window, also known as address decode window.
  42039. +* After setting this target window, the AUDIO will be able to access the
  42040. +* target within the address window.
  42041. +*
  42042. +* INPUT:
  42043. +* winNum - AUDIO target address decode window number.
  42044. +* pAddrDecWin - AUDIO target window data structure.
  42045. +*
  42046. +* OUTPUT:
  42047. +* None.
  42048. +*
  42049. +* RETURN:
  42050. +* MV_ERROR if address window overlapps with other address decode windows.
  42051. +* MV_BAD_PARAM if base address is invalid parameter or target is
  42052. +* unknown.
  42053. +*
  42054. +*******************************************************************************/
  42055. +MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)
  42056. +{
  42057. + MV_TARGET_ATTRIB targetAttribs;
  42058. + MV_DEC_REGS decRegs;
  42059. +
  42060. + /* Parameter checking */
  42061. + if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)
  42062. + {
  42063. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  42064. + return MV_BAD_PARAM;
  42065. + }
  42066. +
  42067. + /* check if address is aligned to the size */
  42068. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  42069. + {
  42070. + mvOsPrintf("mvAudioWinSet:Error setting AUDIO window %d to "\
  42071. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  42072. + winNum,
  42073. + mvCtrlTargetNameGet(pAddrDecWin->target),
  42074. + pAddrDecWin->addrWin.baseLow,
  42075. + pAddrDecWin->addrWin.size);
  42076. + return MV_ERROR;
  42077. + }
  42078. +
  42079. + decRegs.baseReg = 0;
  42080. + decRegs.sizeReg = 0;
  42081. +
  42082. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  42083. + {
  42084. + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
  42085. + return MV_ERROR;
  42086. + }
  42087. +
  42088. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  42089. +
  42090. + /* set attributes */
  42091. + decRegs.sizeReg &= ~MV_AUDIO_WIN_ATTR_MASK;
  42092. + decRegs.sizeReg |= (targetAttribs.attrib << MV_AUDIO_WIN_ATTR_OFFSET);
  42093. +
  42094. + /* set target ID */
  42095. + decRegs.sizeReg &= ~MV_AUDIO_WIN_TARGET_MASK;
  42096. + decRegs.sizeReg |= (targetAttribs.targetId << MV_AUDIO_WIN_TARGET_OFFSET);
  42097. +
  42098. + if (pAddrDecWin->enable == MV_TRUE)
  42099. + {
  42100. + decRegs.sizeReg |= MV_AUDIO_WIN_ENABLE_MASK;
  42101. + }
  42102. + else
  42103. + {
  42104. + decRegs.sizeReg &= ~MV_AUDIO_WIN_ENABLE_MASK;
  42105. + }
  42106. +
  42107. + MV_REG_WRITE( MV_AUDIO_WIN_CTRL_REG(winNum), decRegs.sizeReg);
  42108. + MV_REG_WRITE( MV_AUDIO_WIN_BASE_REG(winNum), decRegs.baseReg);
  42109. +
  42110. + return MV_OK;
  42111. +}
  42112. +
  42113. +/*******************************************************************************
  42114. +* mvAudioWinGet - Get AUDIO peripheral target address window.
  42115. +*
  42116. +* DESCRIPTION:
  42117. +* Get AUDIO peripheral target address window.
  42118. +*
  42119. +* INPUT:
  42120. +* winNum - AUDIO target address decode window number.
  42121. +*
  42122. +* OUTPUT:
  42123. +* pAddrDecWin - AUDIO target window data structure.
  42124. +*
  42125. +* RETURN:
  42126. +* MV_ERROR if register parameters are invalid.
  42127. +*
  42128. +*******************************************************************************/
  42129. +MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)
  42130. +{
  42131. + MV_DEC_REGS decRegs;
  42132. + MV_TARGET_ATTRIB targetAttrib;
  42133. +
  42134. + /* Parameter checking */
  42135. + if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)
  42136. + {
  42137. + mvOsPrintf("%s : ERR. Invalid winNum %d\n",
  42138. + __FUNCTION__, winNum);
  42139. + return MV_NOT_SUPPORTED;
  42140. + }
  42141. +
  42142. + decRegs.baseReg = MV_REG_READ( MV_AUDIO_WIN_BASE_REG(winNum) );
  42143. + decRegs.sizeReg = MV_REG_READ( MV_AUDIO_WIN_CTRL_REG(winNum) );
  42144. +
  42145. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
  42146. + {
  42147. + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
  42148. + return MV_ERROR;
  42149. + }
  42150. +
  42151. + /* attrib and targetId */
  42152. + targetAttrib.attrib = (decRegs.sizeReg & MV_AUDIO_WIN_ATTR_MASK) >>
  42153. + MV_AUDIO_WIN_ATTR_OFFSET;
  42154. + targetAttrib.targetId = (decRegs.sizeReg & MV_AUDIO_WIN_TARGET_MASK) >>
  42155. + MV_AUDIO_WIN_TARGET_OFFSET;
  42156. +
  42157. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  42158. +
  42159. + /* Check if window is enabled */
  42160. + if(decRegs.sizeReg & MV_AUDIO_WIN_ENABLE_MASK)
  42161. + {
  42162. + pAddrDecWin->enable = MV_TRUE;
  42163. + }
  42164. + else
  42165. + {
  42166. + pAddrDecWin->enable = MV_FALSE;
  42167. + }
  42168. + return MV_OK;
  42169. +}
  42170. +/*******************************************************************************
  42171. +* mvAudioAddrDecShow - Print the AUDIO address decode map.
  42172. +*
  42173. +* DESCRIPTION:
  42174. +* This function print the AUDIO address decode map.
  42175. +*
  42176. +* INPUT:
  42177. +* None.
  42178. +*
  42179. +* OUTPUT:
  42180. +* None.
  42181. +*
  42182. +* RETURN:
  42183. +* None.
  42184. +*
  42185. +*******************************************************************************/
  42186. +MV_VOID mvAudioAddrDecShow(MV_VOID)
  42187. +{
  42188. +
  42189. + MV_AUDIO_DEC_WIN win;
  42190. + int i;
  42191. +
  42192. + if (MV_FALSE == mvCtrlPwrClckGet(AUDIO_UNIT_ID, 0))
  42193. + return;
  42194. +
  42195. +
  42196. + mvOsOutput( "\n" );
  42197. + mvOsOutput( "AUDIO:\n" );
  42198. + mvOsOutput( "----\n" );
  42199. +
  42200. + for( i = 0; i < MV_AUDIO_MAX_ADDR_DECODE_WIN; i++ )
  42201. + {
  42202. + memset( &win, 0, sizeof(MV_AUDIO_DEC_WIN) );
  42203. +
  42204. + mvOsOutput( "win%d - ", i );
  42205. +
  42206. + if( mvAudioWinGet( i, &win ) == MV_OK )
  42207. + {
  42208. + if( win.enable )
  42209. + {
  42210. + mvOsOutput( "%s base %08x, ",
  42211. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  42212. + mvOsOutput( "...." );
  42213. +
  42214. + mvSizePrint( win.addrWin.size );
  42215. +
  42216. + mvOsOutput( "\n" );
  42217. + }
  42218. + else
  42219. + mvOsOutput( "disable\n" );
  42220. + }
  42221. + }
  42222. +}
  42223. +
  42224. +
  42225. +/*******************************************************************************
  42226. +* mvAudioWinInit - Initialize the integrated AUDIO target address window.
  42227. +*
  42228. +* DESCRIPTION:
  42229. +* Initialize the AUDIO peripheral target address window.
  42230. +*
  42231. +* INPUT:
  42232. +*
  42233. +*
  42234. +* OUTPUT:
  42235. +*
  42236. +*
  42237. +* RETURN:
  42238. +* MV_ERROR if register parameters are invalid.
  42239. +*
  42240. +*******************************************************************************/
  42241. +MV_STATUS mvAudioInit(MV_VOID)
  42242. +{
  42243. + int winNum;
  42244. + MV_AUDIO_DEC_WIN audioWin;
  42245. + MV_CPU_DEC_WIN cpuAddrDecWin;
  42246. + MV_U32 status;
  42247. +
  42248. + mvAudioHalInit();
  42249. +
  42250. + /* Initiate Audio address decode */
  42251. +
  42252. + /* First disable all address decode windows */
  42253. + for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)
  42254. + {
  42255. + MV_U32 regVal = MV_REG_READ(MV_AUDIO_WIN_CTRL_REG(winNum));
  42256. + regVal &= ~MV_AUDIO_WIN_ENABLE_MASK;
  42257. + MV_REG_WRITE(MV_AUDIO_WIN_CTRL_REG(winNum), regVal);
  42258. + }
  42259. +
  42260. + for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)
  42261. + {
  42262. +
  42263. + /* We will set the Window to DRAM_CS0 in default */
  42264. + /* first get attributes from CPU If */
  42265. + status = mvCpuIfTargetWinGet(SDRAM_CS0,
  42266. + &cpuAddrDecWin);
  42267. +
  42268. + if (MV_OK != status)
  42269. + {
  42270. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  42271. + return MV_ERROR;
  42272. + }
  42273. +
  42274. + if (cpuAddrDecWin.enable == MV_TRUE)
  42275. + {
  42276. + audioWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  42277. + audioWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  42278. + audioWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  42279. + audioWin.enable = MV_TRUE;
  42280. + audioWin.target = SDRAM_CS0;
  42281. +
  42282. + if(MV_OK != mvAudioWinSet(winNum, &audioWin))
  42283. + {
  42284. + return MV_ERROR;
  42285. + }
  42286. + }
  42287. + }
  42288. +
  42289. + return MV_OK;
  42290. +}
  42291. +
  42292. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h
  42293. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h 1970-01-01 01:00:00.000000000 +0100
  42294. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h 2010-11-09 20:28:08.082495466 +0100
  42295. @@ -0,0 +1,123 @@
  42296. +/*******************************************************************************
  42297. +Copyright (C) Marvell International Ltd. and its affiliates
  42298. +
  42299. +This software file (the "File") is owned and distributed by Marvell
  42300. +International Ltd. and/or its affiliates ("Marvell") under the following
  42301. +alternative licensing terms. Once you have made an election to distribute the
  42302. +File under one of the following license alternatives, please (i) delete this
  42303. +introductory statement regarding license alternatives, (ii) delete the two
  42304. +license alternatives that you have not elected to use and (iii) preserve the
  42305. +Marvell copyright notice above.
  42306. +
  42307. +********************************************************************************
  42308. +Marvell Commercial License Option
  42309. +
  42310. +If you received this File from Marvell and you have entered into a commercial
  42311. +license agreement (a "Commercial License") with Marvell, the File is licensed
  42312. +to you under the terms of the applicable Commercial License.
  42313. +
  42314. +********************************************************************************
  42315. +Marvell GPL License Option
  42316. +
  42317. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42318. +modify this File in accordance with the terms and conditions of the General
  42319. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  42320. +available along with the File in the license.txt file or by writing to the Free
  42321. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  42322. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  42323. +
  42324. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  42325. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  42326. +DISCLAIMED. The GPL License provides additional details about this warranty
  42327. +disclaimer.
  42328. +********************************************************************************
  42329. +Marvell BSD License Option
  42330. +
  42331. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42332. +modify this File under the following licensing terms.
  42333. +Redistribution and use in source and binary forms, with or without modification,
  42334. +are permitted provided that the following conditions are met:
  42335. +
  42336. + * Redistributions of source code must retain the above copyright notice,
  42337. + this list of conditions and the following disclaimer.
  42338. +
  42339. + * Redistributions in binary form must reproduce the above copyright
  42340. + notice, this list of conditions and the following disclaimer in the
  42341. + documentation and/or other materials provided with the distribution.
  42342. +
  42343. + * Neither the name of Marvell nor the names of its contributors may be
  42344. + used to endorse or promote products derived from this software without
  42345. + specific prior written permission.
  42346. +
  42347. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42348. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42349. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42350. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42351. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42352. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42353. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42354. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42355. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42356. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42357. +
  42358. +*******************************************************************************/
  42359. +#ifndef __INCMVSysAudioH
  42360. +#define __INCMVSysAudioH
  42361. +
  42362. +#include "mvCommon.h"
  42363. +#include "audio/mvAudio.h"
  42364. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  42365. +#include "ctrlEnv/sys/mvCpuIf.h"
  42366. +
  42367. +/***********************************/
  42368. +/* Audio Address Decoding registers*/
  42369. +/***********************************/
  42370. +
  42371. +#define MV_AUDIO_MAX_ADDR_DECODE_WIN 2
  42372. +#define MV_AUDIO_RECORD_WIN_NUM 0
  42373. +#define MV_AUDIO_PLAYBACK_WIN_NUM 1
  42374. +
  42375. +#define MV_AUDIO_WIN_CTRL_REG(win) (AUDIO_REG_BASE + 0xA04 + ((win)<<3))
  42376. +#define MV_AUDIO_WIN_BASE_REG(win) (AUDIO_REG_BASE + 0xA00 + ((win)<<3))
  42377. +
  42378. +#define MV_AUDIO_RECORD_WIN_CTRL_REG MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_RECORD_WIN_NUM)
  42379. +#define MV_AUDIO_RECORD_WIN_BASE_REG MV_AUDIO_WIN_BASE_REG(MV_AUDIO_RECORD_WIN_NUM)
  42380. +#define MV_AUDIO_PLAYBACK_WIN_CTRL_REG MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_PLAYBACK_WIN_NUM)
  42381. +#define MV_AUDIO_PLAYBACK_WIN_BASE_REG MV_AUDIO_WIN_BASE_REG(MV_AUDIO_PLAYBACK_WIN_NUM)
  42382. +
  42383. +
  42384. +/* BITs in Windows 0-3 Control and Base Registers */
  42385. +#define MV_AUDIO_WIN_ENABLE_BIT 0
  42386. +#define MV_AUDIO_WIN_ENABLE_MASK (1<<MV_AUDIO_WIN_ENABLE_BIT)
  42387. +
  42388. +#define MV_AUDIO_WIN_TARGET_OFFSET 4
  42389. +#define MV_AUDIO_WIN_TARGET_MASK (0xF<<MV_AUDIO_WIN_TARGET_OFFSET)
  42390. +
  42391. +#define MV_AUDIO_WIN_ATTR_OFFSET 8
  42392. +#define MV_AUDIO_WIN_ATTR_MASK (0xFF<<MV_AUDIO_WIN_ATTR_OFFSET)
  42393. +
  42394. +#define MV_AUDIO_WIN_SIZE_OFFSET 16
  42395. +#define MV_AUDIO_WIN_SIZE_MASK (0xFFFF<<MV_AUDIO_WIN_SIZE_OFFSET)
  42396. +
  42397. +#define MV_AUDIO_WIN_BASE_OFFSET 16
  42398. +#define MV_AUDIO_WIN_BASE_MASK (0xFFFF<<MV_AUDIO_WIN_BASE_OFFSET)
  42399. +
  42400. +
  42401. +typedef struct _mvAudioDecWin
  42402. +{
  42403. + MV_TARGET target;
  42404. + MV_ADDR_WIN addrWin; /* An address window*/
  42405. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  42406. +
  42407. +} MV_AUDIO_DEC_WIN;
  42408. +
  42409. +
  42410. +MV_STATUS mvAudioInit(MV_VOID);
  42411. +MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);
  42412. +MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);
  42413. +MV_STATUS mvAudioWinInit(MV_VOID);
  42414. +MV_VOID mvAudioAddrDecShow(MV_VOID);
  42415. +
  42416. +
  42417. +#endif
  42418. +
  42419. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c
  42420. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c 1970-01-01 01:00:00.000000000 +0100
  42421. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c 2010-11-09 20:28:08.121241788 +0100
  42422. @@ -0,0 +1,382 @@
  42423. +/*******************************************************************************
  42424. +Copyright (C) Marvell International Ltd. and its affiliates
  42425. +
  42426. +This software file (the "File") is owned and distributed by Marvell
  42427. +International Ltd. and/or its affiliates ("Marvell") under the following
  42428. +alternative licensing terms. Once you have made an election to distribute the
  42429. +File under one of the following license alternatives, please (i) delete this
  42430. +introductory statement regarding license alternatives, (ii) delete the two
  42431. +license alternatives that you have not elected to use and (iii) preserve the
  42432. +Marvell copyright notice above.
  42433. +
  42434. +********************************************************************************
  42435. +Marvell Commercial License Option
  42436. +
  42437. +If you received this File from Marvell and you have entered into a commercial
  42438. +license agreement (a "Commercial License") with Marvell, the File is licensed
  42439. +to you under the terms of the applicable Commercial License.
  42440. +
  42441. +********************************************************************************
  42442. +Marvell GPL License Option
  42443. +
  42444. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42445. +modify this File in accordance with the terms and conditions of the General
  42446. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  42447. +available along with the File in the license.txt file or by writing to the Free
  42448. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  42449. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  42450. +
  42451. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  42452. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  42453. +DISCLAIMED. The GPL License provides additional details about this warranty
  42454. +disclaimer.
  42455. +********************************************************************************
  42456. +Marvell BSD License Option
  42457. +
  42458. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42459. +modify this File under the following licensing terms.
  42460. +Redistribution and use in source and binary forms, with or without modification,
  42461. +are permitted provided that the following conditions are met:
  42462. +
  42463. + * Redistributions of source code must retain the above copyright notice,
  42464. + this list of conditions and the following disclaimer.
  42465. +
  42466. + * Redistributions in binary form must reproduce the above copyright
  42467. + notice, this list of conditions and the following disclaimer in the
  42468. + documentation and/or other materials provided with the distribution.
  42469. +
  42470. + * Neither the name of Marvell nor the names of its contributors may be
  42471. + used to endorse or promote products derived from this software without
  42472. + specific prior written permission.
  42473. +
  42474. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42475. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42476. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42477. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42478. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42479. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42480. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42481. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42482. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42483. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42484. +
  42485. +*******************************************************************************/
  42486. +
  42487. +#include "mvSysCesa.h"
  42488. +
  42489. +#if (MV_CESA_VERSION >= 2)
  42490. +MV_TARGET tdmaAddrDecPrioTable[] =
  42491. +{
  42492. +#if defined(MV_INCLUDE_SDRAM_CS0)
  42493. + SDRAM_CS0,
  42494. +#endif
  42495. +#if defined(MV_INCLUDE_SDRAM_CS1)
  42496. + SDRAM_CS1,
  42497. +#endif
  42498. +#if defined(MV_INCLUDE_SDRAM_CS2)
  42499. + SDRAM_CS2,
  42500. +#endif
  42501. +#if defined(MV_INCLUDE_SDRAM_CS3)
  42502. + SDRAM_CS3,
  42503. +#endif
  42504. +#if defined(MV_INCLUDE_PEX)
  42505. + PEX0_MEM,
  42506. +#endif
  42507. +
  42508. + TBL_TERM
  42509. +};
  42510. +
  42511. +/*******************************************************************************
  42512. +* mvCesaWinGet - Get TDMA target address window.
  42513. +*
  42514. +* DESCRIPTION:
  42515. +* Get TDMA target address window.
  42516. +*
  42517. +* INPUT:
  42518. +* winNum - TDMA target address decode window number.
  42519. +*
  42520. +* OUTPUT:
  42521. +* pDecWin - TDMA target window data structure.
  42522. +*
  42523. +* RETURN:
  42524. +* MV_ERROR if register parameters are invalid.
  42525. +*
  42526. +*******************************************************************************/
  42527. +static MV_STATUS mvCesaWinGet(MV_U32 winNum, MV_DEC_WIN *pDecWin)
  42528. +{
  42529. + MV_DEC_WIN_PARAMS winParam;
  42530. + MV_U32 sizeReg, baseReg;
  42531. +
  42532. + /* Parameter checking */
  42533. + if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)
  42534. + {
  42535. + mvOsPrintf("%s : ERR. Invalid winNum %d\n",
  42536. + __FUNCTION__, winNum);
  42537. + return MV_NOT_SUPPORTED;
  42538. + }
  42539. +
  42540. + baseReg = MV_REG_READ( MV_CESA_TDMA_BASE_ADDR_REG(winNum) );
  42541. + sizeReg = MV_REG_READ( MV_CESA_TDMA_WIN_CTRL_REG(winNum) );
  42542. +
  42543. + /* Check if window is enabled */
  42544. + if(sizeReg & MV_CESA_TDMA_WIN_ENABLE_MASK)
  42545. + {
  42546. + pDecWin->enable = MV_TRUE;
  42547. +
  42548. + /* Extract window parameters from registers */
  42549. + winParam.targetId = (sizeReg & MV_CESA_TDMA_WIN_TARGET_MASK) >> MV_CESA_TDMA_WIN_TARGET_OFFSET;
  42550. + winParam.attrib = (sizeReg & MV_CESA_TDMA_WIN_ATTR_MASK) >> MV_CESA_TDMA_WIN_ATTR_OFFSET;
  42551. + winParam.size = (sizeReg & MV_CESA_TDMA_WIN_SIZE_MASK) >> MV_CESA_TDMA_WIN_SIZE_OFFSET;
  42552. + winParam.baseAddr = (baseReg & MV_CESA_TDMA_WIN_BASE_MASK);
  42553. +
  42554. + /* Translate the decode window parameters to address decode struct */
  42555. + if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))
  42556. + {
  42557. + mvOsPrintf("Failed to translate register parameters to CESA address" \
  42558. + " decode window structure\n");
  42559. + return MV_ERROR;
  42560. + }
  42561. + }
  42562. + else
  42563. + {
  42564. + pDecWin->enable = MV_FALSE;
  42565. + }
  42566. + return MV_OK;
  42567. +}
  42568. +
  42569. +/*******************************************************************************
  42570. +* cesaWinOverlapDetect - Detect CESA TDMA address windows overlapping
  42571. +*
  42572. +* DESCRIPTION:
  42573. +* An unpredicted behaviur is expected in case TDMA address decode
  42574. +* windows overlapps.
  42575. +* This function detects TDMA address decode windows overlapping of a
  42576. +* specified window. The function does not check the window itself for
  42577. +* overlapping. The function also skipps disabled address decode windows.
  42578. +*
  42579. +* INPUT:
  42580. +* winNum - address decode window number.
  42581. +* pAddrDecWin - An address decode window struct.
  42582. +*
  42583. +* OUTPUT:
  42584. +* None.
  42585. +*
  42586. +* RETURN:
  42587. +* MV_TRUE - if the given address window overlap current address
  42588. +* decode map,
  42589. +* MV_FALSE - otherwise, MV_ERROR if reading invalid data
  42590. +* from registers.
  42591. +*
  42592. +*******************************************************************************/
  42593. +static MV_STATUS cesaWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  42594. +{
  42595. + MV_U32 winNumIndex;
  42596. + MV_DEC_WIN addrDecWin;
  42597. +
  42598. + for(winNumIndex=0; winNumIndex<MV_CESA_TDMA_ADDR_DEC_WIN; winNumIndex++)
  42599. + {
  42600. + /* Do not check window itself */
  42601. + if (winNumIndex == winNum)
  42602. + {
  42603. + continue;
  42604. + }
  42605. +
  42606. + /* Get window parameters */
  42607. + if (MV_OK != mvCesaWinGet(winNumIndex, &addrDecWin))
  42608. + {
  42609. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  42610. + return MV_ERROR;
  42611. + }
  42612. +
  42613. + /* Do not check disabled windows */
  42614. + if(addrDecWin.enable == MV_FALSE)
  42615. + {
  42616. + continue;
  42617. + }
  42618. +
  42619. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  42620. + {
  42621. + return MV_TRUE;
  42622. + }
  42623. + }
  42624. + return MV_FALSE;
  42625. +}
  42626. +
  42627. +/*******************************************************************************
  42628. +* mvCesaTdmaWinSet - Set CESA TDMA target address window
  42629. +*
  42630. +* DESCRIPTION:
  42631. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  42632. +* address window, also known as address decode window.
  42633. +* After setting this target window, the CESA TDMA will be able to access the
  42634. +* target within the address window.
  42635. +*
  42636. +* INPUT:
  42637. +* winNum - CESA TDMA target address decode window number.
  42638. +* pAddrDecWin - CESA TDMA target window data structure.
  42639. +*
  42640. +* OUTPUT:
  42641. +* None.
  42642. +*
  42643. +* RETURN:
  42644. +* MV_ERROR - if address window overlapps with other address decode windows.
  42645. +* MV_BAD_PARAM - if base address is invalid parameter or target is
  42646. +* unknown.
  42647. +*
  42648. +*******************************************************************************/
  42649. +static MV_STATUS mvCesaTdmaWinSet(MV_U32 winNum, MV_DEC_WIN *pDecWin)
  42650. +{
  42651. + MV_DEC_WIN_PARAMS winParams;
  42652. + MV_U32 sizeReg, baseReg;
  42653. +
  42654. + /* Parameter checking */
  42655. + if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)
  42656. + {
  42657. + mvOsPrintf("mvCesaTdmaWinSet: ERR. Invalid win num %d\n",winNum);
  42658. + return MV_BAD_PARAM;
  42659. + }
  42660. +
  42661. + /* Check if the requested window overlapps with current windows */
  42662. + if (MV_TRUE == cesaWinOverlapDetect(winNum, &pDecWin->addrWin))
  42663. + {
  42664. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  42665. + return MV_ERROR;
  42666. + }
  42667. +
  42668. + /* check if address is aligned to the size */
  42669. + if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))
  42670. + {
  42671. + mvOsPrintf("mvCesaTdmaWinSet: Error setting CESA TDMA window %d to "\
  42672. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  42673. + winNum,
  42674. + mvCtrlTargetNameGet(pDecWin->target),
  42675. + pDecWin->addrWin.baseLow,
  42676. + pDecWin->addrWin.size);
  42677. + return MV_ERROR;
  42678. + }
  42679. +
  42680. + if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))
  42681. + {
  42682. + mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);
  42683. + return MV_ERROR;
  42684. + }
  42685. +
  42686. + /* set Size, Attributes and TargetID */
  42687. + sizeReg = (((winParams.targetId << MV_CESA_TDMA_WIN_TARGET_OFFSET) & MV_CESA_TDMA_WIN_TARGET_MASK) |
  42688. + ((winParams.attrib << MV_CESA_TDMA_WIN_ATTR_OFFSET) & MV_CESA_TDMA_WIN_ATTR_MASK) |
  42689. + ((winParams.size << MV_CESA_TDMA_WIN_SIZE_OFFSET) & MV_CESA_TDMA_WIN_SIZE_MASK));
  42690. +
  42691. + if (pDecWin->enable == MV_TRUE)
  42692. + {
  42693. + sizeReg |= MV_CESA_TDMA_WIN_ENABLE_MASK;
  42694. + }
  42695. + else
  42696. + {
  42697. + sizeReg &= ~MV_CESA_TDMA_WIN_ENABLE_MASK;
  42698. + }
  42699. +
  42700. + /* Update Base value */
  42701. + baseReg = (winParams.baseAddr & MV_CESA_TDMA_WIN_BASE_MASK);
  42702. +
  42703. + MV_REG_WRITE( MV_CESA_TDMA_WIN_CTRL_REG(winNum), sizeReg);
  42704. + MV_REG_WRITE( MV_CESA_TDMA_BASE_ADDR_REG(winNum), baseReg);
  42705. +
  42706. + return MV_OK;
  42707. +}
  42708. +
  42709. +
  42710. +static MV_STATUS mvCesaTdmaAddrDecInit (void)
  42711. +{
  42712. + MV_U32 winNum;
  42713. + MV_STATUS status;
  42714. + MV_CPU_DEC_WIN cpuAddrDecWin;
  42715. + MV_DEC_WIN cesaWin;
  42716. + MV_U32 winPrioIndex = 0;
  42717. +
  42718. + /* First disable all address decode windows */
  42719. + for(winNum=0; winNum<MV_CESA_TDMA_ADDR_DEC_WIN; winNum++)
  42720. + {
  42721. + MV_REG_BIT_RESET(MV_CESA_TDMA_WIN_CTRL_REG(winNum), MV_CESA_TDMA_WIN_ENABLE_MASK);
  42722. + }
  42723. +
  42724. + /* Go through all windows in user table until table terminator */
  42725. + winNum = 0;
  42726. + while( (tdmaAddrDecPrioTable[winPrioIndex] != TBL_TERM) &&
  42727. + (winNum < MV_CESA_TDMA_ADDR_DEC_WIN) ) {
  42728. +
  42729. + /* first get attributes from CPU If */
  42730. + status = mvCpuIfTargetWinGet(tdmaAddrDecPrioTable[winPrioIndex],
  42731. + &cpuAddrDecWin);
  42732. + if(MV_NO_SUCH == status){
  42733. + winPrioIndex++;
  42734. + continue;
  42735. + }
  42736. +
  42737. + if (MV_OK != status)
  42738. + {
  42739. + mvOsPrintf("cesaInit: TargetWinGet failed. winNum=%d, winIdx=%d, target=%d, status=0x%x\n",
  42740. + winNum, winPrioIndex, tdmaAddrDecPrioTable[winPrioIndex], status);
  42741. + return MV_ERROR;
  42742. + }
  42743. + if (cpuAddrDecWin.enable == MV_TRUE)
  42744. + {
  42745. + cesaWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  42746. + cesaWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  42747. + cesaWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  42748. + cesaWin.enable = MV_TRUE;
  42749. + cesaWin.target = tdmaAddrDecPrioTable[winPrioIndex];
  42750. +
  42751. +#if defined(MV646xx)
  42752. + /* Get the default attributes for that target window */
  42753. + mvCtrlDefAttribGet(cesaWin.target, &cesaWin.addrWinAttr);
  42754. +#endif /* MV646xx */
  42755. +
  42756. + if(MV_OK != mvCesaTdmaWinSet(winNum, &cesaWin))
  42757. + {
  42758. + mvOsPrintf("mvCesaTdmaWinSet FAILED: winNum=%d\n",
  42759. + winNum);
  42760. + return MV_ERROR;
  42761. + }
  42762. + winNum++;
  42763. + }
  42764. + winPrioIndex++;
  42765. + }
  42766. + return MV_OK;
  42767. +}
  42768. +#endif /* MV_CESA_VERSION >= 2 */
  42769. +
  42770. +
  42771. +
  42772. +
  42773. +MV_STATUS mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle)
  42774. +{
  42775. + MV_U32 cesaCryptEngBase;
  42776. + MV_CPU_DEC_WIN addrDecWin;
  42777. +
  42778. + if(sizeof(MV_CESA_SRAM_MAP) > MV_CESA_SRAM_SIZE)
  42779. + {
  42780. + mvOsPrintf("mvCesaInit: Wrong SRAM map - %ld > %d\n",
  42781. + sizeof(MV_CESA_SRAM_MAP), MV_CESA_SRAM_SIZE);
  42782. + return MV_FAIL;
  42783. + }
  42784. +#if 0
  42785. + if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)
  42786. + cesaCryptEngBase = addrDecWin.addrWin.baseLow;
  42787. + else
  42788. + {
  42789. + mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");
  42790. + return MV_ERROR;
  42791. + }
  42792. +#else
  42793. + cesaCryptEngBase = (MV_U32)pSramBase;
  42794. +#endif
  42795. +
  42796. +#if 0 /* Already done in the platform init */
  42797. +#if (MV_CESA_VERSION >= 2)
  42798. + mvCesaTdmaAddrDecInit();
  42799. +#endif /* MV_CESA_VERSION >= 2 */
  42800. +#endif
  42801. + return mvCesaHalInit(numOfSession, queueDepth, pSramBase, cesaCryptEngBase,
  42802. + osHandle);
  42803. +
  42804. +}
  42805. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h
  42806. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h 1970-01-01 01:00:00.000000000 +0100
  42807. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h 2010-11-09 20:28:08.152495441 +0100
  42808. @@ -0,0 +1,100 @@
  42809. +/*******************************************************************************
  42810. +Copyright (C) Marvell International Ltd. and its affiliates
  42811. +
  42812. +This software file (the "File") is owned and distributed by Marvell
  42813. +International Ltd. and/or its affiliates ("Marvell") under the following
  42814. +alternative licensing terms. Once you have made an election to distribute the
  42815. +File under one of the following license alternatives, please (i) delete this
  42816. +introductory statement regarding license alternatives, (ii) delete the two
  42817. +license alternatives that you have not elected to use and (iii) preserve the
  42818. +Marvell copyright notice above.
  42819. +
  42820. +********************************************************************************
  42821. +Marvell Commercial License Option
  42822. +
  42823. +If you received this File from Marvell and you have entered into a commercial
  42824. +license agreement (a "Commercial License") with Marvell, the File is licensed
  42825. +to you under the terms of the applicable Commercial License.
  42826. +
  42827. +********************************************************************************
  42828. +Marvell GPL License Option
  42829. +
  42830. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42831. +modify this File in accordance with the terms and conditions of the General
  42832. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  42833. +available along with the File in the license.txt file or by writing to the Free
  42834. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  42835. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  42836. +
  42837. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  42838. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  42839. +DISCLAIMED. The GPL License provides additional details about this warranty
  42840. +disclaimer.
  42841. +********************************************************************************
  42842. +Marvell BSD License Option
  42843. +
  42844. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42845. +modify this File under the following licensing terms.
  42846. +Redistribution and use in source and binary forms, with or without modification,
  42847. +are permitted provided that the following conditions are met:
  42848. +
  42849. + * Redistributions of source code must retain the above copyright notice,
  42850. + this list of conditions and the following disclaimer.
  42851. +
  42852. + * Redistributions in binary form must reproduce the above copyright
  42853. + notice, this list of conditions and the following disclaimer in the
  42854. + documentation and/or other materials provided with the distribution.
  42855. +
  42856. + * Neither the name of Marvell nor the names of its contributors may be
  42857. + used to endorse or promote products derived from this software without
  42858. + specific prior written permission.
  42859. +
  42860. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42861. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42862. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42863. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42864. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42865. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42866. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42867. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42868. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42869. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42870. +
  42871. +*******************************************************************************/
  42872. +
  42873. +#ifndef __mvSysCesa_h__
  42874. +#define __mvSysCesa_h__
  42875. +
  42876. +
  42877. +#include "mvCommon.h"
  42878. +#include "cesa/mvCesa.h"
  42879. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  42880. +#include "ctrlEnv/sys/mvCpuIf.h"
  42881. +
  42882. +/***************************** TDMA Registers *************************************/
  42883. +
  42884. +#define MV_CESA_TDMA_ADDR_DEC_WIN 4
  42885. +
  42886. +#define MV_CESA_TDMA_BASE_ADDR_REG(win) (MV_CESA_TDMA_REG_BASE + 0xa00 + (win<<3))
  42887. +
  42888. +#define MV_CESA_TDMA_WIN_CTRL_REG(win) (MV_CESA_TDMA_REG_BASE + 0xa04 + (win<<3))
  42889. +
  42890. +#define MV_CESA_TDMA_WIN_ENABLE_BIT 0
  42891. +#define MV_CESA_TDMA_WIN_ENABLE_MASK (1 << MV_CESA_TDMA_WIN_ENABLE_BIT)
  42892. +
  42893. +#define MV_CESA_TDMA_WIN_TARGET_OFFSET 4
  42894. +#define MV_CESA_TDMA_WIN_TARGET_MASK (0xf << MV_CESA_TDMA_WIN_TARGET_OFFSET)
  42895. +
  42896. +#define MV_CESA_TDMA_WIN_ATTR_OFFSET 8
  42897. +#define MV_CESA_TDMA_WIN_ATTR_MASK (0xff << MV_CESA_TDMA_WIN_ATTR_OFFSET)
  42898. +
  42899. +#define MV_CESA_TDMA_WIN_SIZE_OFFSET 16
  42900. +#define MV_CESA_TDMA_WIN_SIZE_MASK (0xFFFF << MV_CESA_TDMA_WIN_SIZE_OFFSET)
  42901. +
  42902. +#define MV_CESA_TDMA_WIN_BASE_OFFSET 16
  42903. +#define MV_CESA_TDMA_WIN_BASE_MASK (0xFFFF << MV_CESA_TDMA_WIN_BASE_OFFSET)
  42904. +
  42905. +
  42906. +MV_STATUS mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle);
  42907. +
  42908. +#endif
  42909. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c
  42910. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c 1970-01-01 01:00:00.000000000 +0100
  42911. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c 2010-11-09 20:28:08.192500699 +0100
  42912. @@ -0,0 +1,348 @@
  42913. +/*******************************************************************************
  42914. +Copyright (C) Marvell International Ltd. and its affiliates
  42915. +
  42916. +This software file (the "File") is owned and distributed by Marvell
  42917. +International Ltd. and/or its affiliates ("Marvell") under the following
  42918. +alternative licensing terms. Once you have made an election to distribute the
  42919. +File under one of the following license alternatives, please (i) delete this
  42920. +introductory statement regarding license alternatives, (ii) delete the two
  42921. +license alternatives that you have not elected to use and (iii) preserve the
  42922. +Marvell copyright notice above.
  42923. +
  42924. +********************************************************************************
  42925. +Marvell Commercial License Option
  42926. +
  42927. +If you received this File from Marvell and you have entered into a commercial
  42928. +license agreement (a "Commercial License") with Marvell, the File is licensed
  42929. +to you under the terms of the applicable Commercial License.
  42930. +
  42931. +********************************************************************************
  42932. +Marvell GPL License Option
  42933. +
  42934. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42935. +modify this File in accordance with the terms and conditions of the General
  42936. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  42937. +available along with the File in the license.txt file or by writing to the Free
  42938. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  42939. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  42940. +
  42941. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  42942. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  42943. +DISCLAIMED. The GPL License provides additional details about this warranty
  42944. +disclaimer.
  42945. +********************************************************************************
  42946. +Marvell BSD License Option
  42947. +
  42948. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42949. +modify this File under the following licensing terms.
  42950. +Redistribution and use in source and binary forms, with or without modification,
  42951. +are permitted provided that the following conditions are met:
  42952. +
  42953. + * Redistributions of source code must retain the above copyright notice,
  42954. + this list of conditions and the following disclaimer.
  42955. +
  42956. + * Redistributions in binary form must reproduce the above copyright
  42957. + notice, this list of conditions and the following disclaimer in the
  42958. + documentation and/or other materials provided with the distribution.
  42959. +
  42960. + * Neither the name of Marvell nor the names of its contributors may be
  42961. + used to endorse or promote products derived from this software without
  42962. + specific prior written permission.
  42963. +
  42964. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42965. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42966. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42967. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42968. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42969. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42970. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42971. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42972. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42973. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42974. +
  42975. +*******************************************************************************/
  42976. +
  42977. +
  42978. +/* includes */
  42979. +
  42980. +#include "ddr2/mvDramIf.h"
  42981. +#include "ctrlEnv/sys/mvCpuIf.h"
  42982. +#include "ctrlEnv/sys/mvSysDram.h"
  42983. +
  42984. +/* #define MV_DEBUG */
  42985. +#ifdef MV_DEBUG
  42986. +#define DB(x) x
  42987. +#else
  42988. +#define DB(x)
  42989. +#endif
  42990. +
  42991. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
  42992. +
  42993. +/*******************************************************************************
  42994. +* mvDramIfWinSet - Set DRAM interface address decode window
  42995. +*
  42996. +* DESCRIPTION:
  42997. +* This function sets DRAM interface address decode window.
  42998. +*
  42999. +* INPUT:
  43000. +* target - System target. Use only SDRAM targets.
  43001. +* pAddrDecWin - SDRAM address window structure.
  43002. +*
  43003. +* OUTPUT:
  43004. +* None
  43005. +*
  43006. +* RETURN:
  43007. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  43008. +* otherwise.
  43009. +*******************************************************************************/
  43010. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  43011. +{
  43012. + MV_U32 baseReg=0,sizeReg=0;
  43013. + MV_U32 baseToReg=0 , sizeToReg=0;
  43014. +
  43015. + /* Check parameters */
  43016. + if (!MV_TARGET_IS_DRAM(target))
  43017. + {
  43018. + mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
  43019. + return MV_BAD_PARAM;
  43020. + }
  43021. +
  43022. + /* Check if the requested window overlaps with current enabled windows */
  43023. + if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
  43024. + {
  43025. + mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
  43026. + return MV_BAD_PARAM;
  43027. + }
  43028. +
  43029. + /* check if address is aligned to the size */
  43030. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  43031. + {
  43032. + mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
  43033. + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
  43034. + target,
  43035. + pAddrDecWin->addrWin.baseLow,
  43036. + pAddrDecWin->addrWin.size);
  43037. + return MV_ERROR;
  43038. + }
  43039. +
  43040. + /* read base register*/
  43041. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));
  43042. +
  43043. + /* read size register */
  43044. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));
  43045. +
  43046. + /* BaseLow[31:16] => base register [31:16] */
  43047. + baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;
  43048. +
  43049. + /* Write to address decode Base Address Register */
  43050. + baseReg &= ~SCBAR_BASE_MASK;
  43051. + baseReg |= baseToReg;
  43052. +
  43053. + /* Translate the given window size to register format */
  43054. + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);
  43055. +
  43056. + /* Size parameter validity check. */
  43057. + if (-1 == sizeToReg)
  43058. + {
  43059. + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
  43060. + return MV_BAD_PARAM;
  43061. + }
  43062. +
  43063. + /* set size */
  43064. + sizeReg &= ~SCSR_SIZE_MASK;
  43065. + /* Size is located at upper 16 bits */
  43066. + sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);
  43067. +
  43068. + /* enable/Disable */
  43069. + if (MV_TRUE == pAddrDecWin->enable)
  43070. + {
  43071. + sizeReg |= SCSR_WIN_EN;
  43072. + }
  43073. + else
  43074. + {
  43075. + sizeReg &= ~SCSR_WIN_EN;
  43076. + }
  43077. +
  43078. + /* 3) Write to address decode Base Address Register */
  43079. + MV_REG_WRITE(SDRAM_BASE_ADDR_REG(0,target), baseReg);
  43080. +
  43081. + /* Write to address decode Size Register */
  43082. + MV_REG_WRITE(SDRAM_SIZE_REG(0,target), sizeReg);
  43083. +
  43084. + return MV_OK;
  43085. +}
  43086. +/*******************************************************************************
  43087. +* mvDramIfWinGet - Get DRAM interface address decode window
  43088. +*
  43089. +* DESCRIPTION:
  43090. +* This function gets DRAM interface address decode window.
  43091. +*
  43092. +* INPUT:
  43093. +* target - System target. Use only SDRAM targets.
  43094. +*
  43095. +* OUTPUT:
  43096. +* pAddrDecWin - SDRAM address window structure.
  43097. +*
  43098. +* RETURN:
  43099. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  43100. +* otherwise.
  43101. +*******************************************************************************/
  43102. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  43103. +{
  43104. + MV_U32 baseReg,sizeReg;
  43105. + MV_U32 sizeRegVal;
  43106. + /* Check parameters */
  43107. + if (!MV_TARGET_IS_DRAM(target))
  43108. + {
  43109. + mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);
  43110. + return MV_ERROR;
  43111. + }
  43112. +
  43113. + /* Read base and size registers */
  43114. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));
  43115. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));
  43116. +
  43117. + sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;
  43118. +
  43119. + pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,
  43120. + SCSR_SIZE_ALIGNMENT);
  43121. +
  43122. + /* Check if ctrlRegToSize returned OK */
  43123. + if (-1 == pAddrDecWin->addrWin.size)
  43124. + {
  43125. + mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);
  43126. + return MV_ERROR;
  43127. + }
  43128. +
  43129. + /* Extract base address */
  43130. + /* Base register [31:16] ==> baseLow[31:16] */
  43131. + pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;
  43132. +
  43133. + pAddrDecWin->addrWin.baseHigh = 0;
  43134. +
  43135. +
  43136. + if (sizeReg & SCSR_WIN_EN)
  43137. + {
  43138. + pAddrDecWin->enable = MV_TRUE;
  43139. + }
  43140. + else
  43141. + {
  43142. + pAddrDecWin->enable = MV_FALSE;
  43143. + }
  43144. +
  43145. + return MV_OK;
  43146. +}
  43147. +/*******************************************************************************
  43148. +* mvDramIfWinEnable - Enable/Disable SDRAM address decode window
  43149. +*
  43150. +* DESCRIPTION:
  43151. +* This function enable/Disable SDRAM address decode window.
  43152. +*
  43153. +* INPUT:
  43154. +* target - System target. Use only SDRAM targets.
  43155. +*
  43156. +* OUTPUT:
  43157. +* None.
  43158. +*
  43159. +* RETURN:
  43160. +* MV_ERROR in case function parameter are invalid, MV_OK otherewise.
  43161. +*
  43162. +*******************************************************************************/
  43163. +MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable)
  43164. +{
  43165. + MV_DRAM_DEC_WIN addrDecWin;
  43166. +
  43167. + /* Check parameters */
  43168. + if (!MV_TARGET_IS_DRAM(target))
  43169. + {
  43170. + mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
  43171. + return MV_ERROR;
  43172. + }
  43173. +
  43174. + if (enable == MV_TRUE)
  43175. + { /* First check for overlap with other enabled windows */
  43176. + if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
  43177. + {
  43178. + mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n",
  43179. + target);
  43180. + return MV_ERROR;
  43181. + }
  43182. + /* Check for overlapping */
  43183. + if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
  43184. + {
  43185. + /* No Overlap. Enable address decode winNum window */
  43186. + MV_REG_BIT_SET(SDRAM_SIZE_REG(0,target), SCSR_WIN_EN);
  43187. + }
  43188. + else
  43189. + { /* Overlap detected */
  43190. + mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
  43191. + target);
  43192. + return MV_ERROR;
  43193. + }
  43194. + }
  43195. + else
  43196. + { /* Disable address decode winNum window */
  43197. + MV_REG_BIT_RESET(SDRAM_SIZE_REG(0, target), SCSR_WIN_EN);
  43198. + }
  43199. +
  43200. + return MV_OK;
  43201. +}
  43202. +
  43203. +/*******************************************************************************
  43204. +* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window
  43205. +*
  43206. +* DESCRIPTION:
  43207. +* This function scan each SDRAM address decode window to test if it
  43208. +* overlapps the given address windoow
  43209. +*
  43210. +* INPUT:
  43211. +* target - SDRAM target where the function skips checking.
  43212. +* pAddrDecWin - The tested address window for overlapping with
  43213. +* SDRAM windows.
  43214. +*
  43215. +* OUTPUT:
  43216. +* None.
  43217. +*
  43218. +* RETURN:
  43219. +* MV_TRUE if the given address window overlaps any enabled address
  43220. +* decode map, MV_FALSE otherwise.
  43221. +*
  43222. +*******************************************************************************/
  43223. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
  43224. +{
  43225. + MV_TARGET targetNum;
  43226. + MV_DRAM_DEC_WIN addrDecWin;
  43227. +
  43228. + for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)
  43229. + {
  43230. + /* don't check our winNum or illegal targets */
  43231. + if (targetNum == target)
  43232. + {
  43233. + continue;
  43234. + }
  43235. +
  43236. + /* Get window parameters */
  43237. + if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))
  43238. + {
  43239. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  43240. + return MV_ERROR;
  43241. + }
  43242. +
  43243. + /* Do not check disabled windows */
  43244. + if (MV_FALSE == addrDecWin.enable)
  43245. + {
  43246. + continue;
  43247. + }
  43248. +
  43249. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  43250. + {
  43251. + mvOsPrintf(
  43252. + "sdramIfWinOverlap: Required target %d overlap winNum %d\n",
  43253. + target, targetNum);
  43254. + return MV_TRUE;
  43255. + }
  43256. + }
  43257. +
  43258. + return MV_FALSE;
  43259. +}
  43260. +
  43261. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h
  43262. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h 1970-01-01 01:00:00.000000000 +0100
  43263. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h 2010-11-09 20:28:08.232495451 +0100
  43264. @@ -0,0 +1,80 @@
  43265. +/*******************************************************************************
  43266. +Copyright (C) Marvell International Ltd. and its affiliates
  43267. +
  43268. +This software file (the "File") is owned and distributed by Marvell
  43269. +International Ltd. and/or its affiliates ("Marvell") under the following
  43270. +alternative licensing terms. Once you have made an election to distribute the
  43271. +File under one of the following license alternatives, please (i) delete this
  43272. +introductory statement regarding license alternatives, (ii) delete the two
  43273. +license alternatives that you have not elected to use and (iii) preserve the
  43274. +Marvell copyright notice above.
  43275. +
  43276. +********************************************************************************
  43277. +Marvell Commercial License Option
  43278. +
  43279. +If you received this File from Marvell and you have entered into a commercial
  43280. +license agreement (a "Commercial License") with Marvell, the File is licensed
  43281. +to you under the terms of the applicable Commercial License.
  43282. +
  43283. +********************************************************************************
  43284. +Marvell GPL License Option
  43285. +
  43286. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43287. +modify this File in accordance with the terms and conditions of the General
  43288. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  43289. +available along with the File in the license.txt file or by writing to the Free
  43290. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  43291. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  43292. +
  43293. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  43294. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  43295. +DISCLAIMED. The GPL License provides additional details about this warranty
  43296. +disclaimer.
  43297. +********************************************************************************
  43298. +Marvell BSD License Option
  43299. +
  43300. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43301. +modify this File under the following licensing terms.
  43302. +Redistribution and use in source and binary forms, with or without modification,
  43303. +are permitted provided that the following conditions are met:
  43304. +
  43305. + * Redistributions of source code must retain the above copyright notice,
  43306. + this list of conditions and the following disclaimer.
  43307. +
  43308. + * Redistributions in binary form must reproduce the above copyright
  43309. + notice, this list of conditions and the following disclaimer in the
  43310. + documentation and/or other materials provided with the distribution.
  43311. +
  43312. + * Neither the name of Marvell nor the names of its contributors may be
  43313. + used to endorse or promote products derived from this software without
  43314. + specific prior written permission.
  43315. +
  43316. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  43317. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  43318. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  43319. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  43320. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  43321. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43322. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  43323. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43324. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  43325. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43326. +
  43327. +*******************************************************************************/
  43328. +
  43329. +
  43330. +#ifndef __sysDram
  43331. +#define __sysDram
  43332. +
  43333. +/* This structure describes CPU interface address decode window */
  43334. +typedef struct _mvDramIfDecWin
  43335. +{
  43336. + MV_ADDR_WIN addrWin; /* An address window*/
  43337. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  43338. +}MV_DRAM_DEC_WIN;
  43339. +
  43340. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  43341. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  43342. +MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable);
  43343. +
  43344. +#endif
  43345. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c
  43346. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c 1970-01-01 01:00:00.000000000 +0100
  43347. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c 2010-11-09 20:28:08.262495451 +0100
  43348. @@ -0,0 +1,658 @@
  43349. +/*******************************************************************************
  43350. +Copyright (C) Marvell International Ltd. and its affiliates
  43351. +
  43352. +This software file (the "File") is owned and distributed by Marvell
  43353. +International Ltd. and/or its affiliates ("Marvell") under the following
  43354. +alternative licensing terms. Once you have made an election to distribute the
  43355. +File under one of the following license alternatives, please (i) delete this
  43356. +introductory statement regarding license alternatives, (ii) delete the two
  43357. +license alternatives that you have not elected to use and (iii) preserve the
  43358. +Marvell copyright notice above.
  43359. +
  43360. +********************************************************************************
  43361. +Marvell Commercial License Option
  43362. +
  43363. +If you received this File from Marvell and you have entered into a commercial
  43364. +license agreement (a "Commercial License") with Marvell, the File is licensed
  43365. +to you under the terms of the applicable Commercial License.
  43366. +
  43367. +********************************************************************************
  43368. +Marvell GPL License Option
  43369. +
  43370. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43371. +modify this File in accordance with the terms and conditions of the General
  43372. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  43373. +available along with the File in the license.txt file or by writing to the Free
  43374. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  43375. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  43376. +
  43377. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  43378. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  43379. +DISCLAIMED. The GPL License provides additional details about this warranty
  43380. +disclaimer.
  43381. +********************************************************************************
  43382. +Marvell BSD License Option
  43383. +
  43384. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43385. +modify this File under the following licensing terms.
  43386. +Redistribution and use in source and binary forms, with or without modification,
  43387. +are permitted provided that the following conditions are met:
  43388. +
  43389. + * Redistributions of source code must retain the above copyright notice,
  43390. + this list of conditions and the following disclaimer.
  43391. +
  43392. + * Redistributions in binary form must reproduce the above copyright
  43393. + notice, this list of conditions and the following disclaimer in the
  43394. + documentation and/or other materials provided with the distribution.
  43395. +
  43396. + * Neither the name of Marvell nor the names of its contributors may be
  43397. + used to endorse or promote products derived from this software without
  43398. + specific prior written permission.
  43399. +
  43400. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  43401. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  43402. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  43403. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  43404. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  43405. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43406. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  43407. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43408. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  43409. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43410. +
  43411. +*******************************************************************************/
  43412. +
  43413. +
  43414. +#include "ctrlEnv/sys/mvSysGbe.h"
  43415. +
  43416. +
  43417. +
  43418. +typedef struct _mvEthDecWin
  43419. +{
  43420. + MV_TARGET target;
  43421. + MV_ADDR_WIN addrWin; /* An address window*/
  43422. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  43423. +
  43424. +}MV_ETH_DEC_WIN;
  43425. +
  43426. +MV_TARGET ethAddrDecPrioTap[] =
  43427. +{
  43428. +#if defined(MV_INCLUDE_SDRAM_CS0)
  43429. + SDRAM_CS0,
  43430. +#endif
  43431. +#if defined(MV_INCLUDE_SDRAM_CS1)
  43432. + SDRAM_CS1,
  43433. +#endif
  43434. +#if defined(MV_INCLUDE_SDRAM_CS2)
  43435. + SDRAM_CS2,
  43436. +#endif
  43437. +#if defined(MV_INCLUDE_SDRAM_CS3)
  43438. + SDRAM_CS3,
  43439. +#endif
  43440. +#if defined(MV_INCLUDE_DEVICE_CS0)
  43441. + DEVICE_CS0,
  43442. +#endif
  43443. +#if defined(MV_INCLUDE_DEVICE_CS1)
  43444. + DEVICE_CS1,
  43445. +#endif
  43446. +#if defined(MV_INCLUDE_DEVICE_CS2)
  43447. + DEVICE_CS2,
  43448. +#endif
  43449. +#if defined(MV_INCLUDE_DEVICE_CS3)
  43450. + DEVICE_CS3,
  43451. +#endif
  43452. +#if defined(MV_INCLUDE_PEX)
  43453. + PEX0_IO,
  43454. +#endif
  43455. + TBL_TERM
  43456. +};
  43457. +
  43458. +static MV_STATUS ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  43459. +static MV_STATUS mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);
  43460. +static MV_STATUS mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);
  43461. +
  43462. +
  43463. +/*******************************************************************************
  43464. +* mvEthWinInit - Initialize ETH address decode windows
  43465. +*
  43466. +* DESCRIPTION:
  43467. +* This function initialize ETH window decode unit. It set the
  43468. +* default address decode windows of the unit.
  43469. +*
  43470. +* INPUT:
  43471. +* None.
  43472. +*
  43473. +* OUTPUT:
  43474. +* None.
  43475. +*
  43476. +* RETURN:
  43477. +* MV_ERROR if setting fail.
  43478. +*******************************************************************************/
  43479. +/* Configure EthDrv memory map registes. */
  43480. +MV_STATUS mvEthWinInit (int port)
  43481. +{
  43482. + MV_U32 winNum, status, winPrioIndex=0, i, regVal=0;
  43483. + MV_ETH_DEC_WIN ethWin;
  43484. + MV_CPU_DEC_WIN cpuAddrDecWin;
  43485. + static MV_U32 accessProtReg = 0;
  43486. +
  43487. +#if (MV_ETH_VERSION <= 1)
  43488. + static MV_BOOL isFirst = MV_TRUE;
  43489. +
  43490. + if(isFirst == MV_FALSE)
  43491. + {
  43492. + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);
  43493. + return MV_OK;
  43494. + }
  43495. + isFirst = MV_FALSE;
  43496. +#endif /* MV_GIGA_ETH_VERSION */
  43497. +
  43498. + /* Initiate Ethernet address decode */
  43499. +
  43500. + /* First disable all address decode windows */
  43501. + for(winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)
  43502. + {
  43503. + regVal |= MV_BIT_MASK(winNum);
  43504. + }
  43505. + MV_REG_WRITE(ETH_BASE_ADDR_ENABLE_REG(port), regVal);
  43506. +
  43507. + /* Go through all windows in user table until table terminator */
  43508. + for (winNum=0; ((ethAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  43509. + (winNum < ETH_MAX_DECODE_WIN)); )
  43510. + {
  43511. + /* first get attributes from CPU If */
  43512. + status = mvCpuIfTargetWinGet(ethAddrDecPrioTap[winPrioIndex],
  43513. + &cpuAddrDecWin);
  43514. +
  43515. + if(MV_NO_SUCH == status)
  43516. + {
  43517. + winPrioIndex++;
  43518. + continue;
  43519. + }
  43520. + if (MV_OK != status)
  43521. + {
  43522. + mvOsPrintf("mvEthWinInit: ERR. mvCpuIfTargetWinGet failed\n");
  43523. + return MV_ERROR;
  43524. + }
  43525. +
  43526. + if (cpuAddrDecWin.enable == MV_TRUE)
  43527. + {
  43528. + ethWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  43529. + ethWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  43530. + ethWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  43531. + ethWin.enable = MV_TRUE;
  43532. + ethWin.target = ethAddrDecPrioTap[winPrioIndex];
  43533. +
  43534. + if(MV_OK != mvEthWinSet(port, winNum, &ethWin))
  43535. + {
  43536. + mvOsPrintf("mvEthWinInit: ERR. mvEthWinSet failed winNum=%d\n",
  43537. + winNum);
  43538. + return MV_ERROR;
  43539. + }
  43540. + winNum++;
  43541. + }
  43542. + winPrioIndex ++;
  43543. + }
  43544. +
  43545. + /* set full access to all windows. */
  43546. + for(i=0; i<winNum; i++)
  43547. + {
  43548. + accessProtReg |= (FULL_ACCESS << (i*2));
  43549. + }
  43550. + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);
  43551. +
  43552. + return MV_OK;
  43553. +}
  43554. +
  43555. +/*******************************************************************************
  43556. +* mvEthWinSet - Set ETH target address window
  43557. +*
  43558. +* DESCRIPTION:
  43559. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  43560. +* address window, also known as address decode window.
  43561. +* After setting this target window, the ETH will be able to access the
  43562. +* target within the address window.
  43563. +*
  43564. +* INPUT:
  43565. +* winNum - ETH to target address decode window number.
  43566. +* pAddrDecWin - ETH target window data structure.
  43567. +*
  43568. +* OUTPUT:
  43569. +* None.
  43570. +*
  43571. +* RETURN:
  43572. +* MV_ERROR if address window overlapps with other address decode windows.
  43573. +* MV_BAD_PARAM if base address is invalid parameter or target is
  43574. +* unknown.
  43575. +*
  43576. +*******************************************************************************/
  43577. +MV_STATUS mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)
  43578. +{
  43579. + MV_TARGET_ATTRIB targetAttribs;
  43580. + MV_DEC_REGS decRegs;
  43581. +
  43582. + /* Parameter checking */
  43583. + if (winNum >= ETH_MAX_DECODE_WIN)
  43584. + {
  43585. + mvOsPrintf("mvEthWinSet: ERR. Invalid win num %d\n",winNum);
  43586. + return MV_BAD_PARAM;
  43587. + }
  43588. +
  43589. + /* Check if the requested window overlapps with current windows */
  43590. + if (MV_TRUE == ethWinOverlapDetect(port, winNum, &pAddrDecWin->addrWin))
  43591. + {
  43592. + mvOsPrintf("mvEthWinSet: ERR. Window %d overlap\n", winNum);
  43593. + return MV_ERROR;
  43594. + }
  43595. +
  43596. + /* check if address is aligned to the size */
  43597. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  43598. + {
  43599. + mvOsPrintf("mvEthWinSet: Error setting Ethernet window %d to "\
  43600. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  43601. + winNum,
  43602. + mvCtrlTargetNameGet(pAddrDecWin->target),
  43603. + pAddrDecWin->addrWin.baseLow,
  43604. + pAddrDecWin->addrWin.size);
  43605. + return MV_ERROR;
  43606. + }
  43607. +
  43608. +
  43609. + decRegs.baseReg = MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));
  43610. + decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));
  43611. +
  43612. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  43613. + {
  43614. + mvOsPrintf("mvEthWinSet:mvCtrlAddrDecToReg Failed\n");
  43615. + return MV_ERROR;
  43616. + }
  43617. +
  43618. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  43619. +
  43620. + /* set attributes */
  43621. + decRegs.baseReg &= ~ETH_WIN_ATTR_MASK;
  43622. + decRegs.baseReg |= targetAttribs.attrib << ETH_WIN_ATTR_OFFS;
  43623. + /* set target ID */
  43624. + decRegs.baseReg &= ~ETH_WIN_TARGET_MASK;
  43625. + decRegs.baseReg |= targetAttribs.targetId << ETH_WIN_TARGET_OFFS;
  43626. +
  43627. + /* for the safe side we disable the window before writing the new
  43628. + values */
  43629. + mvEthWinEnable(port, winNum, MV_FALSE);
  43630. + MV_REG_WRITE(ETH_WIN_BASE_REG(port, winNum), decRegs.baseReg);
  43631. +
  43632. + /* Write to address decode Size Register */
  43633. + MV_REG_WRITE(ETH_WIN_SIZE_REG(port, winNum), decRegs.sizeReg);
  43634. +
  43635. + /* Enable address decode target window */
  43636. + if (pAddrDecWin->enable == MV_TRUE)
  43637. + {
  43638. + mvEthWinEnable(port, winNum, MV_TRUE);
  43639. + }
  43640. +
  43641. + return MV_OK;
  43642. +}
  43643. +
  43644. +/*******************************************************************************
  43645. +* mvETHWinGet - Get dma peripheral target address window.
  43646. +*
  43647. +* DESCRIPTION:
  43648. +* Get ETH peripheral target address window.
  43649. +*
  43650. +* INPUT:
  43651. +* winNum - ETH to target address decode window number.
  43652. +*
  43653. +* OUTPUT:
  43654. +* pAddrDecWin - ETH target window data structure.
  43655. +*
  43656. +* RETURN:
  43657. +* MV_ERROR if register parameters are invalid.
  43658. +*
  43659. +*******************************************************************************/
  43660. +MV_STATUS mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)
  43661. +{
  43662. + MV_DEC_REGS decRegs;
  43663. + MV_TARGET_ATTRIB targetAttrib;
  43664. +
  43665. + /* Parameter checking */
  43666. + if (winNum >= ETH_MAX_DECODE_WIN)
  43667. + {
  43668. + mvOsPrintf("mvEthWinGet: ERR. Invalid winNum %d\n", winNum);
  43669. + return MV_NOT_SUPPORTED;
  43670. + }
  43671. +
  43672. + decRegs.baseReg = MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));
  43673. + decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));
  43674. +
  43675. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  43676. + {
  43677. + mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");
  43678. + return MV_ERROR;
  43679. + }
  43680. +
  43681. + /* attrib and targetId */
  43682. + targetAttrib.attrib =
  43683. + (decRegs.baseReg & ETH_WIN_ATTR_MASK) >> ETH_WIN_ATTR_OFFS;
  43684. + targetAttrib.targetId =
  43685. + (decRegs.baseReg & ETH_WIN_TARGET_MASK) >> ETH_WIN_TARGET_OFFS;
  43686. +
  43687. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  43688. +
  43689. + /* Check if window is enabled */
  43690. + if (~(MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port))) & (1 << winNum) )
  43691. + {
  43692. + pAddrDecWin->enable = MV_TRUE;
  43693. + }
  43694. + else
  43695. + {
  43696. + pAddrDecWin->enable = MV_FALSE;
  43697. + }
  43698. +
  43699. + return MV_OK;
  43700. +}
  43701. +
  43702. +/*******************************************************************************
  43703. +* mvEthWinEnable - Enable/disable a ETH to target address window
  43704. +*
  43705. +* DESCRIPTION:
  43706. +* This function enable/disable a ETH to target address window.
  43707. +* According to parameter 'enable' the routine will enable the
  43708. +* window, thus enabling ETH accesses (before enabling the window it is
  43709. +* tested for overlapping). Otherwise, the window will be disabled.
  43710. +*
  43711. +* INPUT:
  43712. +* winNum - ETH to target address decode window number.
  43713. +* enable - Enable/disable parameter.
  43714. +*
  43715. +* OUTPUT:
  43716. +* N/A
  43717. +*
  43718. +* RETURN:
  43719. +* MV_ERROR if decode window number was wrong or enabled window overlapps.
  43720. +*
  43721. +*******************************************************************************/
  43722. +MV_STATUS mvEthWinEnable(int port, MV_U32 winNum,MV_BOOL enable)
  43723. +{
  43724. + MV_ETH_DEC_WIN addrDecWin;
  43725. +
  43726. + /* Parameter checking */
  43727. + if (winNum >= ETH_MAX_DECODE_WIN)
  43728. + {
  43729. + mvOsPrintf("mvEthTargetWinEnable:ERR. Invalid winNum%d\n",winNum);
  43730. + return MV_ERROR;
  43731. + }
  43732. +
  43733. + if (enable == MV_TRUE)
  43734. + { /* First check for overlap with other enabled windows */
  43735. + /* Get current window */
  43736. + if (MV_OK != mvEthWinGet(port, winNum, &addrDecWin))
  43737. + {
  43738. + mvOsPrintf("mvEthTargetWinEnable:ERR. targetWinGet fail\n");
  43739. + return MV_ERROR;
  43740. + }
  43741. + /* Check for overlapping */
  43742. + if (MV_FALSE == ethWinOverlapDetect(port, winNum, &(addrDecWin.addrWin)))
  43743. + {
  43744. + /* No Overlap. Enable address decode target window */
  43745. + MV_REG_BIT_RESET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));
  43746. + }
  43747. + else
  43748. + { /* Overlap detected */
  43749. + mvOsPrintf("mvEthTargetWinEnable:ERR. Overlap detected\n");
  43750. + return MV_ERROR;
  43751. + }
  43752. + }
  43753. + else
  43754. + { /* Disable address decode target window */
  43755. + MV_REG_BIT_SET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));
  43756. + }
  43757. + return MV_OK;
  43758. +}
  43759. +
  43760. +/*******************************************************************************
  43761. +* mvEthWinTargetGet - Get Window number associated with target
  43762. +*
  43763. +* DESCRIPTION:
  43764. +*
  43765. +* INPUT:
  43766. +*
  43767. +* OUTPUT:
  43768. +*
  43769. +* RETURN:
  43770. +* window number
  43771. +*
  43772. +*******************************************************************************/
  43773. +MV_U32 mvEthWinTargetGet(int port, MV_TARGET target)
  43774. +{
  43775. + MV_ETH_DEC_WIN decWin;
  43776. + MV_U32 winNum;
  43777. +
  43778. + /* Check parameters */
  43779. + if (target >= MAX_TARGETS)
  43780. + {
  43781. + mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);
  43782. + return 0xffffffff;
  43783. + }
  43784. +
  43785. + for (winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)
  43786. + {
  43787. + if (mvEthWinGet(port, winNum,&decWin) != MV_OK)
  43788. + {
  43789. + mvOsPrintf("mvAhbToMbusWinTargetGet: window returned error\n");
  43790. + return 0xffffffff;
  43791. + }
  43792. +
  43793. + if (decWin.enable == MV_TRUE)
  43794. + {
  43795. + if (decWin.target == target)
  43796. + {
  43797. + return winNum;
  43798. + }
  43799. + }
  43800. + }
  43801. + return 0xFFFFFFFF;
  43802. +}
  43803. +
  43804. +/*******************************************************************************
  43805. +* mvEthProtWinSet - Set access protection of Ethernet to target window.
  43806. +*
  43807. +* DESCRIPTION:
  43808. +* Each Ethernet port can be configured with access attributes for each
  43809. +* of the Ethenret to target windows (address decode windows). This
  43810. +* function sets access attributes to a given window for the given channel.
  43811. +*
  43812. +* INPUTS:
  43813. +* ethPort - ETH channel number. See MV_ETH_CHANNEL enumerator.
  43814. +* winNum - IETH to target address decode window number.
  43815. +* access - IETH access rights. See MV_ACCESS_RIGHTS enumerator.
  43816. +*
  43817. +* OUTPUT:
  43818. +* None.
  43819. +*
  43820. +* RETURN:
  43821. +* MV_ERROR in case window number is invalid or access right reserved.
  43822. +*
  43823. +*******************************************************************************/
  43824. +MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS access)
  43825. +{
  43826. + MV_U32 protReg;
  43827. +
  43828. + /* Parameter checking */
  43829. + if(portNo >= mvCtrlEthMaxPortGet())
  43830. + {
  43831. + mvOsPrintf("mvEthProtWinSet:ERR. Invalid port number %d\n", portNo);
  43832. + return MV_ERROR;
  43833. + }
  43834. +
  43835. + if (winNum >= ETH_MAX_DECODE_WIN)
  43836. + {
  43837. + mvOsPrintf("mvEthProtWinSet:ERR. Invalid winNum%d\n",winNum);
  43838. + return MV_ERROR;
  43839. + }
  43840. +
  43841. + if((access == ACC_RESERVED) || (access >= MAX_ACC_RIGHTS))
  43842. + {
  43843. + mvOsPrintf("mvEthProtWinSet:ERR. Inv access param %d\n", access);
  43844. + return MV_ERROR;
  43845. + }
  43846. + /* Read current protection register */
  43847. + protReg = MV_REG_READ(ETH_ACCESS_PROTECT_REG(portNo));
  43848. +
  43849. + /* Clear protection window field */
  43850. + protReg &= ~(ETH_PROT_WIN_MASK(winNum));
  43851. +
  43852. + /* Set new protection field value */
  43853. + protReg |= (access << (ETH_PROT_WIN_OFFS(winNum)));
  43854. +
  43855. + /* Write protection register back */
  43856. + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(portNo), protReg);
  43857. +
  43858. + return MV_OK;
  43859. +}
  43860. +
  43861. +/*******************************************************************************
  43862. +* ethWinOverlapDetect - Detect ETH address windows overlapping
  43863. +*
  43864. +* DESCRIPTION:
  43865. +* An unpredicted behaviur is expected in case ETH address decode
  43866. +* windows overlapps.
  43867. +* This function detects ETH address decode windows overlapping of a
  43868. +* specified window. The function does not check the window itself for
  43869. +* overlapping. The function also skipps disabled address decode windows.
  43870. +*
  43871. +* INPUT:
  43872. +* winNum - address decode window number.
  43873. +* pAddrDecWin - An address decode window struct.
  43874. +*
  43875. +* OUTPUT:
  43876. +* None.
  43877. +*
  43878. +* RETURN:
  43879. +* MV_TRUE if the given address window overlap current address
  43880. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  43881. +* from registers.
  43882. +*
  43883. +*******************************************************************************/
  43884. +static MV_STATUS ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  43885. +{
  43886. + MV_U32 baseAddrEnableReg;
  43887. + MV_U32 winNumIndex;
  43888. + MV_ETH_DEC_WIN addrDecWin;
  43889. +
  43890. + /* Read base address enable register. Do not check disabled windows */
  43891. + baseAddrEnableReg = MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port));
  43892. +
  43893. + for (winNumIndex=0; winNumIndex<ETH_MAX_DECODE_WIN; winNumIndex++)
  43894. + {
  43895. + /* Do not check window itself */
  43896. + if (winNumIndex == winNum)
  43897. + {
  43898. + continue;
  43899. + }
  43900. +
  43901. + /* Do not check disabled windows */
  43902. + if (baseAddrEnableReg & (1 << winNumIndex))
  43903. + {
  43904. + continue;
  43905. + }
  43906. +
  43907. + /* Get window parameters */
  43908. + if (MV_OK != mvEthWinGet(port, winNumIndex, &addrDecWin))
  43909. + {
  43910. + mvOsPrintf("ethWinOverlapDetect: ERR. TargetWinGet failed\n");
  43911. + return MV_ERROR;
  43912. + }
  43913. +/*
  43914. + mvOsPrintf("ethWinOverlapDetect:\n
  43915. + winNumIndex =%d baseHigh =0x%x baseLow=0x%x size=0x%x enable=0x%x\n",
  43916. + winNumIndex,
  43917. + addrDecWin.addrWin.baseHigh,
  43918. + addrDecWin.addrWin.baseLow,
  43919. + addrDecWin.addrWin.size,
  43920. + addrDecWin.enable);
  43921. +*/
  43922. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  43923. + {
  43924. + return MV_TRUE;
  43925. + }
  43926. + }
  43927. + return MV_FALSE;
  43928. +}
  43929. +
  43930. +/*******************************************************************************
  43931. +* mvEthAddrDecShow - Print the Etherent address decode map.
  43932. +*
  43933. +* DESCRIPTION:
  43934. +* This function print the Etherent address decode map.
  43935. +*
  43936. +* INPUT:
  43937. +* None.
  43938. +*
  43939. +* OUTPUT:
  43940. +* None.
  43941. +*
  43942. +* RETURN:
  43943. +* None.
  43944. +*
  43945. +*******************************************************************************/
  43946. +void mvEthPortAddrDecShow(int port)
  43947. +{
  43948. + MV_ETH_DEC_WIN win;
  43949. + int i;
  43950. +
  43951. + mvOsOutput( "\n" );
  43952. + mvOsOutput( "ETH %d:\n", port );
  43953. + mvOsOutput( "----\n" );
  43954. +
  43955. + for( i = 0; i < ETH_MAX_DECODE_WIN; i++ )
  43956. + {
  43957. + memset( &win, 0, sizeof(ETH_MAX_DECODE_WIN) );
  43958. +
  43959. + mvOsOutput( "win%d - ", i );
  43960. +
  43961. + if( mvEthWinGet(port, i, &win ) == MV_OK )
  43962. + {
  43963. + if( win.enable )
  43964. + {
  43965. + mvOsOutput( "%s base %08x, ",
  43966. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  43967. + mvOsOutput( "...." );
  43968. + mvSizePrint( win.addrWin.size );
  43969. +
  43970. + mvOsOutput( "\n" );
  43971. + }
  43972. + else
  43973. + mvOsOutput( "disable\n" );
  43974. + }
  43975. + }
  43976. + return;
  43977. +}
  43978. +
  43979. +void mvEthAddrDecShow(void)
  43980. +{
  43981. + int port;
  43982. +
  43983. + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
  43984. + {
  43985. + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;
  43986. +
  43987. + mvEthPortAddrDecShow(port);
  43988. + }
  43989. +}
  43990. +
  43991. +
  43992. +void mvEthInit(void)
  43993. +{
  43994. + MV_U32 port;
  43995. +
  43996. + /* Power down all existing ports */
  43997. + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
  43998. + {
  43999. + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port))
  44000. + continue;
  44001. +
  44002. + mvEthPortPowerUp(port);
  44003. + mvEthWinInit(port);
  44004. + }
  44005. + mvEthHalInit();
  44006. +}
  44007. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h
  44008. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h 1970-01-01 01:00:00.000000000 +0100
  44009. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h 2010-11-09 20:28:08.292495558 +0100
  44010. @@ -0,0 +1,113 @@
  44011. +/*******************************************************************************
  44012. +Copyright (C) Marvell International Ltd. and its affiliates
  44013. +
  44014. +This software file (the "File") is owned and distributed by Marvell
  44015. +International Ltd. and/or its affiliates ("Marvell") under the following
  44016. +alternative licensing terms. Once you have made an election to distribute the
  44017. +File under one of the following license alternatives, please (i) delete this
  44018. +introductory statement regarding license alternatives, (ii) delete the two
  44019. +license alternatives that you have not elected to use and (iii) preserve the
  44020. +Marvell copyright notice above.
  44021. +
  44022. +********************************************************************************
  44023. +Marvell Commercial License Option
  44024. +
  44025. +If you received this File from Marvell and you have entered into a commercial
  44026. +license agreement (a "Commercial License") with Marvell, the File is licensed
  44027. +to you under the terms of the applicable Commercial License.
  44028. +
  44029. +********************************************************************************
  44030. +Marvell GPL License Option
  44031. +
  44032. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44033. +modify this File in accordance with the terms and conditions of the General
  44034. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  44035. +available along with the File in the license.txt file or by writing to the Free
  44036. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  44037. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  44038. +
  44039. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  44040. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  44041. +DISCLAIMED. The GPL License provides additional details about this warranty
  44042. +disclaimer.
  44043. +********************************************************************************
  44044. +Marvell BSD License Option
  44045. +
  44046. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44047. +modify this File under the following licensing terms.
  44048. +Redistribution and use in source and binary forms, with or without modification,
  44049. +are permitted provided that the following conditions are met:
  44050. +
  44051. + * Redistributions of source code must retain the above copyright notice,
  44052. + this list of conditions and the following disclaimer.
  44053. +
  44054. + * Redistributions in binary form must reproduce the above copyright
  44055. + notice, this list of conditions and the following disclaimer in the
  44056. + documentation and/or other materials provided with the distribution.
  44057. +
  44058. + * Neither the name of Marvell nor the names of its contributors may be
  44059. + used to endorse or promote products derived from this software without
  44060. + specific prior written permission.
  44061. +
  44062. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  44063. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  44064. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44065. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  44066. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  44067. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  44068. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  44069. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  44070. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  44071. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44072. +
  44073. +*******************************************************************************/
  44074. +
  44075. +#ifndef __INCmvSysGbeh
  44076. +#define __INCmvSysGbeh
  44077. +
  44078. +#include "mvCommon.h"
  44079. +#include "eth/mvEth.h"
  44080. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  44081. +#include "ctrlEnv/sys/mvCpuIf.h"
  44082. +
  44083. +#define ETH_WIN_BASE_REG(port, win) (MV_ETH_REG_BASE(port) + 0x200 + ((win)<<3))
  44084. +#define ETH_WIN_SIZE_REG(port, win) (MV_ETH_REG_BASE(port) + 0x204 + ((win)<<3))
  44085. +#define ETH_WIN_REMAP_REG(port, win) (MV_ETH_REG_BASE(port) + 0x280 + ((win)<<2))
  44086. +#define ETH_BASE_ADDR_ENABLE_REG(port) (MV_ETH_REG_BASE(port) + 0x290)
  44087. +#define ETH_ACCESS_PROTECT_REG(port) (MV_ETH_REG_BASE(port) + 0x294)
  44088. +
  44089. +/**** Address decode parameters ****/
  44090. +
  44091. +/* Ethernet Base Address Register bits */
  44092. +#define ETH_MAX_DECODE_WIN 6
  44093. +#define ETH_MAX_HIGH_ADDR_REMAP_WIN 4
  44094. +
  44095. +/* Ethernet Port Access Protect (EPAP) register */
  44096. +
  44097. +/* The target associated with this window*/
  44098. +#define ETH_WIN_TARGET_OFFS 0
  44099. +#define ETH_WIN_TARGET_MASK (0xf << ETH_WIN_TARGET_OFFS)
  44100. +/* The target attributes Associated with window */
  44101. +#define ETH_WIN_ATTR_OFFS 8
  44102. +#define ETH_WIN_ATTR_MASK (0xff << ETH_WIN_ATTR_OFFS)
  44103. +
  44104. +/* Ethernet Port Access Protect Register (EPAPR) */
  44105. +#define ETH_PROT_NO_ACCESS NO_ACCESS_ALLOWED
  44106. +#define ETH_PROT_READ_ONLY READ_ONLY
  44107. +#define ETH_PROT_FULL_ACCESS FULL_ACCESS
  44108. +#define ETH_PROT_WIN_OFFS(winNum) (2 * (winNum))
  44109. +#define ETH_PROT_WIN_MASK(winNum) (0x3 << ETH_PROT_WIN_OFFS(winNum))
  44110. +
  44111. +MV_STATUS mvEthWinInit (int port);
  44112. +MV_STATUS mvEthWinEnable(int port, MV_U32 winNum, MV_BOOL enable);
  44113. +MV_U32 mvEthWinTargetGet(int port, MV_TARGET target);
  44114. +MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS
  44115. + access);
  44116. +
  44117. +void mvEthPortAddrDecShow(int port);
  44118. +
  44119. +MV_VOID mvEthAddrDecShow(MV_VOID);
  44120. +
  44121. +void mvEthInit(void);
  44122. +
  44123. +#endif
  44124. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c
  44125. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c 1970-01-01 01:00:00.000000000 +0100
  44126. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c 2010-11-09 20:28:08.332495446 +0100
  44127. @@ -0,0 +1,1697 @@
  44128. +/*******************************************************************************
  44129. +Copyright (C) Marvell International Ltd. and its affiliates
  44130. +
  44131. +This software file (the "File") is owned and distributed by Marvell
  44132. +International Ltd. and/or its affiliates ("Marvell") under the following
  44133. +alternative licensing terms. Once you have made an election to distribute the
  44134. +File under one of the following license alternatives, please (i) delete this
  44135. +introductory statement regarding license alternatives, (ii) delete the two
  44136. +license alternatives that you have not elected to use and (iii) preserve the
  44137. +Marvell copyright notice above.
  44138. +
  44139. +********************************************************************************
  44140. +Marvell Commercial License Option
  44141. +
  44142. +If you received this File from Marvell and you have entered into a commercial
  44143. +license agreement (a "Commercial License") with Marvell, the File is licensed
  44144. +to you under the terms of the applicable Commercial License.
  44145. +
  44146. +********************************************************************************
  44147. +Marvell GPL License Option
  44148. +
  44149. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44150. +modify this File in accordance with the terms and conditions of the General
  44151. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  44152. +available along with the File in the license.txt file or by writing to the Free
  44153. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  44154. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  44155. +
  44156. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  44157. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  44158. +DISCLAIMED. The GPL License provides additional details about this warranty
  44159. +disclaimer.
  44160. +********************************************************************************
  44161. +Marvell BSD License Option
  44162. +
  44163. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44164. +modify this File under the following licensing terms.
  44165. +Redistribution and use in source and binary forms, with or without modification,
  44166. +are permitted provided that the following conditions are met:
  44167. +
  44168. + * Redistributions of source code must retain the above copyright notice,
  44169. + this list of conditions and the following disclaimer.
  44170. +
  44171. + * Redistributions in binary form must reproduce the above copyright
  44172. + notice, this list of conditions and the following disclaimer in the
  44173. + documentation and/or other materials provided with the distribution.
  44174. +
  44175. + * Neither the name of Marvell nor the names of its contributors may be
  44176. + used to endorse or promote products derived from this software without
  44177. + specific prior written permission.
  44178. +
  44179. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  44180. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  44181. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44182. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  44183. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  44184. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  44185. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  44186. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  44187. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  44188. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44189. +
  44190. +*******************************************************************************/
  44191. +
  44192. +#include "ctrlEnv/sys/mvSysPex.h"
  44193. +
  44194. +/* this structure describes the mapping between a Pex Window and a CPU target*/
  44195. +typedef struct _pexWinToTarget
  44196. +{
  44197. + MV_TARGET target;
  44198. + MV_BOOL enable;
  44199. +
  44200. +}PEX_WIN_TO_TARGET;
  44201. +
  44202. +/* this array is a priority array that define How Pex windows should be
  44203. +configured , We have only 6 Pex Windows that can be configured , but we
  44204. +have maximum of 9 CPU target windows ! the following array is a priority
  44205. +array where the lowest index has the highest priotiy and the highest
  44206. +index has the lowest priority of being cnfigured */
  44207. +
  44208. +MV_U32 pexDevBarPrioTable[] =
  44209. +{
  44210. +#if defined(MV_INCLUDE_DEVICE_CS0)
  44211. + DEVICE_CS0,
  44212. +#endif
  44213. +#if defined(MV_INCLUDE_DEVICE_CS1)
  44214. + DEVICE_CS1,
  44215. +#endif
  44216. +#if defined(MV_INCLUDE_DEVICE_CS2)
  44217. + DEVICE_CS2,
  44218. +#endif
  44219. +#if defined(MV_INCLUDE_DEVICE_CS3)
  44220. + DEVICE_CS3,
  44221. +#endif
  44222. +/*
  44223. +#if defined(MV_INCLUDE_DEVICE_CS4)
  44224. + DEVICE_CS4,
  44225. +#endif
  44226. +*/
  44227. + TBL_TERM
  44228. +};
  44229. +
  44230. +
  44231. +/* PEX Wins registers offsets are inconsecutive. This struct describes WIN */
  44232. +/* register offsets and its function where its is located. */
  44233. +/* Also, PEX address remap registers offsets are inconsecutive. This struct */
  44234. +/* describes address remap register offsets */
  44235. +typedef struct _pexWinRegInfo
  44236. +{
  44237. + MV_U32 baseLowRegOffs;
  44238. + MV_U32 baseHighRegOffs;
  44239. + MV_U32 sizeRegOffs;
  44240. + MV_U32 remapLowRegOffs;
  44241. + MV_U32 remapHighRegOffs;
  44242. +
  44243. +}PEX_WIN_REG_INFO;
  44244. +
  44245. +static MV_STATUS pexWinOverlapDetect(MV_U32 pexIf, MV_U32 winNum,
  44246. + MV_ADDR_WIN *pAddrWin);
  44247. +static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf, MV_U32 winNum,
  44248. + PEX_WIN_REG_INFO *pWinRegInfo);
  44249. +
  44250. +static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size);
  44251. +
  44252. +static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,MV_ADDR_WIN *pAddrWin);
  44253. +static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,MV_U32 barNum,
  44254. + MV_ADDR_WIN *pAddrWin);
  44255. +const MV_8* pexBarNameGet( MV_U32 bar );
  44256. +
  44257. +
  44258. +/*******************************************************************************
  44259. +* mvPexInit - Initialize PEX interfaces
  44260. +*
  44261. +* DESCRIPTION:
  44262. +*
  44263. +* This function is responsible of intialization of the Pex Interface , It
  44264. +* configure the Pex Bars and Windows in the following manner:
  44265. +*
  44266. +* Assumptions :
  44267. +* Bar0 is always internal registers bar
  44268. +* Bar1 is always the DRAM bar
  44269. +* Bar2 is always the Device bar
  44270. +*
  44271. +* 1) Sets the Internal registers bar base by obtaining the base from
  44272. +* the CPU Interface
  44273. +* 2) Sets the DRAM bar base and size by getting the base and size from
  44274. +* the CPU Interface when the size is the sum of all enabled DRAM
  44275. +* chip selects and the base is the base of CS0 .
  44276. +* 3) Sets the Device bar base and size by getting these values from the
  44277. +* CPU Interface when the base is the base of the lowest base of the
  44278. +* Device chip selects, and the
  44279. +*
  44280. +*
  44281. +* INPUT:
  44282. +*
  44283. +* pexIf - PEX interface number.
  44284. +*
  44285. +*
  44286. +* OUTPUT:
  44287. +* None.
  44288. +*
  44289. +* RETURN:
  44290. +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
  44291. +*
  44292. +*******************************************************************************/
  44293. +MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
  44294. +{
  44295. + MV_U32 bar;
  44296. + MV_U32 winNum;
  44297. + MV_PEX_BAR pexBar;
  44298. + MV_PEX_DEC_WIN pexWin;
  44299. + MV_CPU_DEC_WIN addrDecWin;
  44300. + MV_TARGET target;
  44301. + MV_U32 pexCurrWin=0;
  44302. + MV_U32 status;
  44303. + /* default and exapntion rom
  44304. + are always configured */
  44305. +
  44306. +#ifndef MV_DISABLE_PEX_DEVICE_BAR
  44307. + MV_U32 winIndex;
  44308. + MV_U32 maxBase=0, sizeOfMaxBase=0;
  44309. + MV_U32 pexStartWindow;
  44310. +#endif
  44311. +
  44312. + /* Parameter checking */
  44313. + if(pexIf >= mvCtrlPexMaxIfGet())
  44314. + {
  44315. + mvOsPrintf("mvPexInit: ERR. Invalid PEX interface %d\n", pexIf);
  44316. + return MV_BAD_PARAM;
  44317. + }
  44318. +
  44319. + /* Enabled CPU access to PCI-Express */
  44320. + mvCpuIfEnablePex(pexIf, pexType);
  44321. +
  44322. + /* Start with bars */
  44323. + /* First disable all PEX bars*/
  44324. + for (bar = 0; bar < PEX_MAX_BARS; bar++)
  44325. + {
  44326. + if (PEX_INTER_REGS_BAR != bar)
  44327. + {
  44328. + if (MV_OK != mvPexBarEnable(pexIf, bar, MV_FALSE))
  44329. + {
  44330. + mvOsPrintf("mvPexInit:mvPexBarEnable bar =%d failed \n",bar);
  44331. + return MV_ERROR;
  44332. + }
  44333. +
  44334. + }
  44335. +
  44336. + }
  44337. +
  44338. + /* and disable all PEX target windows */
  44339. + for (winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
  44340. + {
  44341. + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_FALSE))
  44342. + {
  44343. + mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
  44344. + winNum);
  44345. + return MV_ERROR;
  44346. +
  44347. + }
  44348. + }
  44349. +
  44350. + /* Now, go through all bars*/
  44351. +
  44352. +
  44353. +
  44354. +/******************************************************************************/
  44355. +/* Internal registers bar */
  44356. +/******************************************************************************/
  44357. + bar = PEX_INTER_REGS_BAR;
  44358. +
  44359. + /* we only open the bar , no need to open windows for this bar */
  44360. +
  44361. + /* first get the CS attribute from the CPU Interface */
  44362. + if (MV_OK !=mvCpuIfTargetWinGet(INTER_REGS,&addrDecWin))
  44363. + {
  44364. + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",INTER_REGS);
  44365. + return MV_ERROR;
  44366. + }
  44367. +
  44368. + pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  44369. + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  44370. + pexBar.addrWin.size = addrDecWin.addrWin.size;
  44371. + pexBar.enable = MV_TRUE;
  44372. +
  44373. + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
  44374. + {
  44375. + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
  44376. + return MV_ERROR;
  44377. + }
  44378. +
  44379. +/******************************************************************************/
  44380. +/* DRAM bar */
  44381. +/******************************************************************************/
  44382. +
  44383. + bar = PEX_DRAM_BAR;
  44384. +
  44385. + pexBar.addrWin.size = 0;
  44386. +
  44387. + for (target = SDRAM_CS0;target < MV_DRAM_MAX_CS; target++ )
  44388. + {
  44389. +
  44390. + status = mvCpuIfTargetWinGet(target,&addrDecWin);
  44391. +
  44392. + if((MV_NO_SUCH == status)&&(target != SDRAM_CS0))
  44393. + {
  44394. + continue;
  44395. + }
  44396. +
  44397. + /* first get attributes from CPU If */
  44398. + if (MV_OK != status)
  44399. + {
  44400. + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
  44401. + return MV_ERROR;
  44402. + }
  44403. + if (addrDecWin.enable == MV_TRUE)
  44404. + {
  44405. + /* the base is the base of DRAM CS0 always */
  44406. + if (SDRAM_CS0 == target )
  44407. + {
  44408. + pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  44409. + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  44410. +
  44411. + }
  44412. +
  44413. + /* increment the bar size to be the sum of the size of all
  44414. + DRAM chips selecs */
  44415. + pexBar.addrWin.size += addrDecWin.addrWin.size;
  44416. +
  44417. + /* set a Pex window for this target !
  44418. + DRAM CS always will have a Pex Window , and is not a
  44419. + part of the priority table */
  44420. + pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  44421. + pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  44422. + pexWin.addrWin.size = addrDecWin.addrWin.size;
  44423. +
  44424. + /* we disable the windows at first because we are not
  44425. + sure that it is witihin bar boundries */
  44426. + pexWin.enable =MV_FALSE;
  44427. + pexWin.target = target;
  44428. + pexWin.targetBar = bar;
  44429. +
  44430. + if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,&pexWin))
  44431. + {
  44432. + mvOsPrintf("mvPexInit: ERR. mvPexTargetWinSet failed\n");
  44433. + return MV_ERROR;
  44434. + }
  44435. + }
  44436. + }
  44437. +
  44438. + /* check if the size of the bar is illeggal */
  44439. + if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
  44440. + {
  44441. + /* try to get a good size */
  44442. + pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
  44443. + PXBCR_BAR_SIZE_ALIGNMENT);
  44444. + }
  44445. +
  44446. + /* check if the size and base are valid */
  44447. + if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
  44448. + {
  44449. + mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
  44450. + mvOsPrintf("it will be disabled\n");
  44451. + mvOsPrintf("please check Pex and CPU windows configuration\n");
  44452. + }
  44453. + else
  44454. + {
  44455. + pexBar.enable = MV_TRUE;
  44456. +
  44457. + /* configure the bar */
  44458. + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
  44459. + {
  44460. + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
  44461. + return MV_ERROR;
  44462. + }
  44463. +
  44464. + /* after the bar was configured then we enable the Pex windows*/
  44465. + for (winNum = 0;winNum < pexCurrWin ;winNum++)
  44466. + {
  44467. + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
  44468. + {
  44469. + mvOsPrintf("mvPexInit: Can't enable window =%d\n",winNum);
  44470. + return MV_ERROR;
  44471. + }
  44472. +
  44473. + }
  44474. + }
  44475. +
  44476. +/******************************************************************************/
  44477. +/* DEVICE bar */
  44478. +/******************************************************************************/
  44479. +
  44480. +/* Open the Device BAR for non linux only */
  44481. +#ifndef MV_DISABLE_PEX_DEVICE_BAR
  44482. +
  44483. + /* then device bar*/
  44484. + bar = PEX_DEVICE_BAR;
  44485. +
  44486. + /* save the starting window */
  44487. + pexStartWindow = pexCurrWin;
  44488. + pexBar.addrWin.size = 0;
  44489. + pexBar.addrWin.baseLow = 0xffffffff;
  44490. + pexBar.addrWin.baseHigh = 0;
  44491. + maxBase = 0;
  44492. +
  44493. + for (target = DEV_TO_TARGET(START_DEV_CS);target < DEV_TO_TARGET(MV_DEV_MAX_CS); target++ )
  44494. + {
  44495. + status = mvCpuIfTargetWinGet(target,&addrDecWin);
  44496. +
  44497. + if (MV_NO_SUCH == status)
  44498. + {
  44499. + continue;
  44500. + }
  44501. +
  44502. + if (MV_OK != status)
  44503. + {
  44504. + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
  44505. + return MV_ERROR;
  44506. + }
  44507. +
  44508. + if (addrDecWin.enable == MV_TRUE)
  44509. + {
  44510. + /* get the minimum base */
  44511. + if (addrDecWin.addrWin.baseLow < pexBar.addrWin.baseLow)
  44512. + {
  44513. + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  44514. + }
  44515. +
  44516. + /* get the maximum base */
  44517. + if (addrDecWin.addrWin.baseLow > maxBase)
  44518. + {
  44519. + maxBase = addrDecWin.addrWin.baseLow;
  44520. + sizeOfMaxBase = addrDecWin.addrWin.size;
  44521. + }
  44522. +
  44523. + /* search in the priority table for this target */
  44524. + for (winIndex = 0; pexDevBarPrioTable[winIndex] != TBL_TERM;
  44525. + winIndex++)
  44526. + {
  44527. + if (pexDevBarPrioTable[winIndex] != target)
  44528. + {
  44529. + continue;
  44530. + }
  44531. + else if (pexDevBarPrioTable[winIndex] == target)
  44532. + {
  44533. + /*found it */
  44534. +
  44535. + /* if the index of this target in the prio table is valid
  44536. + then we set the Pex window for this target, a valid index is
  44537. + an index that is lower than the number of the windows that
  44538. + was not configured yet */
  44539. +
  44540. + /* we subtract 2 always because the default and expantion
  44541. + rom windows are always configured */
  44542. + if ( pexCurrWin < PEX_MAX_TARGET_WIN - 2)
  44543. + {
  44544. + /* set a Pex window for this target ! */
  44545. + pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  44546. + pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  44547. + pexWin.addrWin.size = addrDecWin.addrWin.size;
  44548. +
  44549. + /* we disable the windows at first because we are not
  44550. + sure that it is witihin bar boundries */
  44551. + pexWin.enable = MV_FALSE;
  44552. + pexWin.target = target;
  44553. + pexWin.targetBar = bar;
  44554. +
  44555. + if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,
  44556. + &pexWin))
  44557. + {
  44558. + mvOsPrintf("mvPexInit: ERR. Window Set failed\n");
  44559. + return MV_ERROR;
  44560. + }
  44561. + }
  44562. + }
  44563. + }
  44564. + }
  44565. + }
  44566. +
  44567. + pexBar.addrWin.size = maxBase - pexBar.addrWin.baseLow + sizeOfMaxBase;
  44568. + pexBar.enable = MV_TRUE;
  44569. +
  44570. + /* check if the size of the bar is illegal */
  44571. + if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
  44572. + {
  44573. + /* try to get a good size */
  44574. + pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
  44575. + PXBCR_BAR_SIZE_ALIGNMENT);
  44576. + }
  44577. +
  44578. + /* check if the size and base are valid */
  44579. + if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
  44580. + {
  44581. + mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
  44582. + mvOsPrintf("it will be disabled\n");
  44583. + mvOsPrintf("please check Pex and CPU windows configuration\n");
  44584. + }
  44585. + else
  44586. + {
  44587. + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
  44588. + {
  44589. + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
  44590. + return MV_ERROR;
  44591. + }
  44592. +
  44593. + /* now enable the windows */
  44594. + for (winNum = pexStartWindow; winNum < pexCurrWin ; winNum++)
  44595. + {
  44596. + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
  44597. + {
  44598. + mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
  44599. + winNum);
  44600. + return MV_ERROR;
  44601. + }
  44602. + }
  44603. + }
  44604. +
  44605. +#endif
  44606. +
  44607. + return mvPexHalInit(pexIf, pexType);
  44608. +
  44609. +}
  44610. +
  44611. +/*******************************************************************************
  44612. +* mvPexTargetWinSet - Set PEX to peripheral target address window BAR
  44613. +*
  44614. +* DESCRIPTION:
  44615. +*
  44616. +* INPUT:
  44617. +*
  44618. +* OUTPUT:
  44619. +* N/A
  44620. +*
  44621. +* RETURN:
  44622. +* MV_OK if PEX BAR target window was set correctly,
  44623. +* MV_BAD_PARAM on bad params
  44624. +* MV_ERROR otherwise
  44625. +* (e.g. address window overlapps with other active PEX target window).
  44626. +*
  44627. +*******************************************************************************/
  44628. +MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum,
  44629. + MV_PEX_DEC_WIN *pAddrDecWin)
  44630. +{
  44631. +
  44632. + MV_DEC_REGS decRegs;
  44633. + PEX_WIN_REG_INFO winRegInfo;
  44634. + MV_TARGET_ATTRIB targetAttribs;
  44635. +
  44636. + /* Parameter checking */
  44637. + if(pexIf >= mvCtrlPexMaxIfGet())
  44638. + {
  44639. + mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX interface %d\n", pexIf);
  44640. + return MV_BAD_PARAM;
  44641. + }
  44642. +
  44643. + if (winNum >= PEX_MAX_TARGET_WIN)
  44644. + {
  44645. + mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX winNum %d\n", winNum);
  44646. + return MV_BAD_PARAM;
  44647. +
  44648. + }
  44649. +
  44650. + /* get the pex Window registers offsets */
  44651. + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
  44652. +
  44653. +
  44654. + if (MV_TRUE == pAddrDecWin->enable)
  44655. + {
  44656. +
  44657. + /* 2) Check if the requested window overlaps with current windows */
  44658. + if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &pAddrDecWin->addrWin))
  44659. + {
  44660. + mvOsPrintf("mvPexTargetWinSet: ERR. Target %d overlap\n", winNum);
  44661. + return MV_BAD_PARAM;
  44662. + }
  44663. +
  44664. + /* 2) Check if the requested window overlaps with current windows */
  44665. + if (MV_FALSE == pexIsWinWithinBar(pexIf,&pAddrDecWin->addrWin))
  44666. + {
  44667. + mvOsPrintf("mvPexTargetWinSet: Win %d should be in bar boundries\n",
  44668. + winNum);
  44669. + return MV_BAD_PARAM;
  44670. + }
  44671. +
  44672. + }
  44673. +
  44674. +
  44675. +
  44676. + /* read base register*/
  44677. +
  44678. + if (winRegInfo.baseLowRegOffs)
  44679. + {
  44680. + decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
  44681. + }
  44682. + else
  44683. + {
  44684. + decRegs.baseReg = 0;
  44685. + }
  44686. +
  44687. + if (winRegInfo.sizeRegOffs)
  44688. + {
  44689. + decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
  44690. + }
  44691. + else
  44692. + {
  44693. + decRegs.sizeReg =0;
  44694. + }
  44695. +
  44696. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  44697. + {
  44698. + mvOsPrintf("mvPexTargetWinSet:mvCtrlAddrDecToReg Failed\n");
  44699. + return MV_ERROR;
  44700. + }
  44701. +
  44702. + /* enable\Disable */
  44703. + if (MV_TRUE == pAddrDecWin->enable)
  44704. + {
  44705. + decRegs.sizeReg |= PXWCR_WIN_EN;
  44706. + }
  44707. + else
  44708. + {
  44709. + decRegs.sizeReg &= ~PXWCR_WIN_EN;
  44710. + }
  44711. +
  44712. +
  44713. + /* clear bit location */
  44714. + decRegs.sizeReg &= ~PXWCR_WIN_BAR_MAP_MASK;
  44715. +
  44716. + /* set bar Mapping */
  44717. + if (pAddrDecWin->targetBar == 1)
  44718. + {
  44719. + decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR1;
  44720. + }
  44721. + else if (pAddrDecWin->targetBar == 2)
  44722. + {
  44723. + decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR2;
  44724. + }
  44725. +
  44726. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  44727. +
  44728. + /* set attributes */
  44729. + decRegs.sizeReg &= ~PXWCR_ATTRIB_MASK;
  44730. + decRegs.sizeReg |= targetAttribs.attrib << PXWCR_ATTRIB_OFFS;
  44731. + /* set target ID */
  44732. + decRegs.sizeReg &= ~PXWCR_TARGET_MASK;
  44733. + decRegs.sizeReg |= targetAttribs.targetId << PXWCR_TARGET_OFFS;
  44734. +
  44735. +
  44736. + /* 3) Write to address decode Base Address Register */
  44737. +
  44738. + if (winRegInfo.baseLowRegOffs)
  44739. + {
  44740. + MV_REG_WRITE(winRegInfo.baseLowRegOffs, decRegs.baseReg);
  44741. + }
  44742. +
  44743. + /* write size reg */
  44744. + if (winRegInfo.sizeRegOffs)
  44745. + {
  44746. + if ((MV_PEX_WIN_DEFAULT == winNum)||
  44747. + (MV_PEX_WIN_EXP_ROM == winNum))
  44748. + {
  44749. + /* clear size because there is no size field*/
  44750. + decRegs.sizeReg &= ~PXWCR_SIZE_MASK;
  44751. +
  44752. + /* clear enable because there is no enable field*/
  44753. + decRegs.sizeReg &= ~PXWCR_WIN_EN;
  44754. +
  44755. + }
  44756. +
  44757. + MV_REG_WRITE(winRegInfo.sizeRegOffs, decRegs.sizeReg);
  44758. + }
  44759. +
  44760. +
  44761. + return MV_OK;
  44762. +
  44763. +}
  44764. +
  44765. +/*******************************************************************************
  44766. +* mvPexTargetWinGet - Get PEX to peripheral target address window
  44767. +*
  44768. +* DESCRIPTION:
  44769. +* Get the PEX to peripheral target address window BAR.
  44770. +*
  44771. +* INPUT:
  44772. +* pexIf - PEX interface number.
  44773. +* bar - BAR to be accessed by slave.
  44774. +*
  44775. +* OUTPUT:
  44776. +* pAddrBarWin - PEX target window information data structure.
  44777. +*
  44778. +* RETURN:
  44779. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  44780. +*
  44781. +*******************************************************************************/
  44782. +MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum,
  44783. + MV_PEX_DEC_WIN *pAddrDecWin)
  44784. +{
  44785. + MV_TARGET_ATTRIB targetAttrib;
  44786. + MV_DEC_REGS decRegs;
  44787. +
  44788. + PEX_WIN_REG_INFO winRegInfo;
  44789. +
  44790. + /* Parameter checking */
  44791. + if(pexIf >= mvCtrlPexMaxIfGet())
  44792. + {
  44793. + mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX interface %d\n", pexIf);
  44794. + return MV_BAD_PARAM;
  44795. + }
  44796. +
  44797. + if (winNum >= PEX_MAX_TARGET_WIN)
  44798. + {
  44799. + mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX winNum %d\n", winNum);
  44800. + return MV_BAD_PARAM;
  44801. +
  44802. + }
  44803. +
  44804. + /* get the pex Window registers offsets */
  44805. + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
  44806. +
  44807. + /* read base register*/
  44808. + if (winRegInfo.baseLowRegOffs)
  44809. + {
  44810. + decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
  44811. + }
  44812. + else
  44813. + {
  44814. + decRegs.baseReg = 0;
  44815. + }
  44816. +
  44817. + /* read size reg */
  44818. + if (winRegInfo.sizeRegOffs)
  44819. + {
  44820. + decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
  44821. + }
  44822. + else
  44823. + {
  44824. + decRegs.sizeReg =0;
  44825. + }
  44826. +
  44827. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  44828. + {
  44829. + mvOsPrintf("mvPexTargetWinGet: mvCtrlRegToAddrDec Failed \n");
  44830. + return MV_ERROR;
  44831. +
  44832. + }
  44833. +
  44834. + if (decRegs.sizeReg & PXWCR_WIN_EN)
  44835. + {
  44836. + pAddrDecWin->enable = MV_TRUE;
  44837. + }
  44838. + else
  44839. + {
  44840. + pAddrDecWin->enable = MV_FALSE;
  44841. +
  44842. + }
  44843. +
  44844. +
  44845. + #if 0
  44846. + if (-1 == pAddrDecWin->addrWin.size)
  44847. + {
  44848. + return MV_ERROR;
  44849. + }
  44850. + #endif
  44851. +
  44852. +
  44853. + /* get target bar */
  44854. + if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) == PXWCR_WIN_BAR_MAP_BAR1 )
  44855. + {
  44856. + pAddrDecWin->targetBar = 1;
  44857. + }
  44858. + else if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) ==
  44859. + PXWCR_WIN_BAR_MAP_BAR2 )
  44860. + {
  44861. + pAddrDecWin->targetBar = 2;
  44862. + }
  44863. +
  44864. + /* attrib and targetId */
  44865. + pAddrDecWin->attrib = (decRegs.sizeReg & PXWCR_ATTRIB_MASK) >>
  44866. + PXWCR_ATTRIB_OFFS;
  44867. + pAddrDecWin->targetId = (decRegs.sizeReg & PXWCR_TARGET_MASK) >>
  44868. + PXWCR_TARGET_OFFS;
  44869. +
  44870. + targetAttrib.attrib = pAddrDecWin->attrib;
  44871. + targetAttrib.targetId = pAddrDecWin->targetId;
  44872. +
  44873. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  44874. +
  44875. + return MV_OK;
  44876. +
  44877. +}
  44878. +
  44879. +
  44880. +/*******************************************************************************
  44881. +* mvPexTargetWinEnable - Enable/disable a PEX BAR window
  44882. +*
  44883. +* DESCRIPTION:
  44884. +* This function enable/disable a PEX BAR window.
  44885. +* if parameter 'enable' == MV_TRUE the routine will enable the
  44886. +* window, thus enabling PEX accesses for that BAR (before enabling the
  44887. +* window it is tested for overlapping). Otherwise, the window will
  44888. +* be disabled.
  44889. +*
  44890. +* INPUT:
  44891. +* pexIf - PEX interface number.
  44892. +* bar - BAR to be accessed by slave.
  44893. +* enable - Enable/disable parameter.
  44894. +*
  44895. +* OUTPUT:
  44896. +* None.
  44897. +*
  44898. +* RETURN:
  44899. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  44900. +*
  44901. +*******************************************************************************/
  44902. +MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable)
  44903. +{
  44904. + PEX_WIN_REG_INFO winRegInfo;
  44905. + MV_PEX_DEC_WIN addrDecWin;
  44906. +
  44907. + /* Parameter checking */
  44908. + if(pexIf >= mvCtrlPexMaxIfGet())
  44909. + {
  44910. + mvOsPrintf("mvPexTargetWinEnable: ERR. Invalid PEX If %d\n", pexIf);
  44911. + return MV_BAD_PARAM;
  44912. + }
  44913. +
  44914. + if (winNum >= PEX_MAX_TARGET_WIN)
  44915. + {
  44916. + mvOsPrintf("mvPexTargetWinEnable ERR. Invalid PEX winNum %d\n", winNum);
  44917. + return MV_BAD_PARAM;
  44918. +
  44919. + }
  44920. +
  44921. +
  44922. + /* get the pex Window registers offsets */
  44923. + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
  44924. +
  44925. +
  44926. + /* if the address windows is disabled , we only disable the appropriare
  44927. + pex window and ignore other settings */
  44928. +
  44929. + if (MV_FALSE == enable)
  44930. + {
  44931. +
  44932. + /* this is not relevant to default and expantion rom
  44933. + windows */
  44934. + if (winRegInfo.sizeRegOffs)
  44935. + {
  44936. + if ((MV_PEX_WIN_DEFAULT != winNum)&&
  44937. + (MV_PEX_WIN_EXP_ROM != winNum))
  44938. + {
  44939. + MV_REG_BIT_RESET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
  44940. + }
  44941. + }
  44942. +
  44943. + }
  44944. + else
  44945. + {
  44946. + if (MV_OK != mvPexTargetWinGet(pexIf,winNum, &addrDecWin))
  44947. + {
  44948. + mvOsPrintf("mvPexTargetWinEnable: mvPexTargetWinGet Failed\n");
  44949. + return MV_ERROR;
  44950. + }
  44951. +
  44952. + /* Check if the requested window overlaps with current windows */
  44953. + if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &addrDecWin.addrWin))
  44954. + {
  44955. + mvOsPrintf("mvPexTargetWinEnable: ERR. Target %d overlap\n", winNum);
  44956. + return MV_BAD_PARAM;
  44957. + }
  44958. +
  44959. + if (MV_FALSE == pexIsWinWithinBar(pexIf,&addrDecWin.addrWin))
  44960. + {
  44961. + mvOsPrintf("mvPexTargetWinEnable: Win %d should be in bar boundries\n",
  44962. + winNum);
  44963. + return MV_BAD_PARAM;
  44964. + }
  44965. +
  44966. +
  44967. + /* this is not relevant to default and expantion rom
  44968. + windows */
  44969. + if (winRegInfo.sizeRegOffs)
  44970. + {
  44971. + if ((MV_PEX_WIN_DEFAULT != winNum)&&
  44972. + (MV_PEX_WIN_EXP_ROM != winNum))
  44973. + {
  44974. + MV_REG_BIT_SET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
  44975. + }
  44976. + }
  44977. +
  44978. +
  44979. + }
  44980. +
  44981. + return MV_OK;
  44982. +
  44983. +}
  44984. +
  44985. +
  44986. +
  44987. +/*******************************************************************************
  44988. +* mvPexTargetWinRemap - Set PEX to target address window remap.
  44989. +*
  44990. +* DESCRIPTION:
  44991. +* The PEX interface supports remap of the BAR original address window.
  44992. +* For each BAR it is possible to define a remap address. For example
  44993. +* an address 0x12345678 that hits BAR 0x10 (SDRAM CS[0]) will be modified
  44994. +* according to remap register but will also be targeted to the
  44995. +* SDRAM CS[0].
  44996. +*
  44997. +* INPUT:
  44998. +* pexIf - PEX interface number.
  44999. +* bar - Peripheral target enumerator accessed by slave.
  45000. +* pAddrWin - Address window to be checked.
  45001. +*
  45002. +* OUTPUT:
  45003. +* None.
  45004. +*
  45005. +* RETURN:
  45006. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  45007. +*
  45008. +*******************************************************************************/
  45009. +MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum,
  45010. + MV_PEX_REMAP_WIN *pAddrWin)
  45011. +{
  45012. +
  45013. + PEX_WIN_REG_INFO winRegInfo;
  45014. +
  45015. + /* Parameter checking */
  45016. + if (pexIf >= mvCtrlPexMaxIfGet())
  45017. + {
  45018. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
  45019. + pexIf);
  45020. + return MV_BAD_PARAM;
  45021. + }
  45022. + if (MV_PEX_WIN_DEFAULT == winNum)
  45023. + {
  45024. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
  45025. + winNum);
  45026. + return MV_BAD_PARAM;
  45027. +
  45028. + }
  45029. +
  45030. + if (MV_IS_NOT_ALIGN(pAddrWin->addrWin.baseLow, PXWRR_REMAP_ALIGNMENT))
  45031. + {
  45032. + mvOsPrintf("mvPexTargetWinRemap: Error remap PEX interface %d win %d."\
  45033. + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
  45034. + pexIf,
  45035. + winNum,
  45036. + pAddrWin->addrWin.baseLow,
  45037. + pAddrWin->addrWin.size);
  45038. +
  45039. + return MV_ERROR;
  45040. + }
  45041. +
  45042. + pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
  45043. +
  45044. + /* Set remap low register value */
  45045. + MV_REG_WRITE(winRegInfo.remapLowRegOffs, pAddrWin->addrWin.baseLow);
  45046. +
  45047. + /* Skip base high settings if the BAR has only base low (32-bit) */
  45048. + if (0 != winRegInfo.remapHighRegOffs)
  45049. + {
  45050. + MV_REG_WRITE(winRegInfo.remapHighRegOffs, pAddrWin->addrWin.baseHigh);
  45051. + }
  45052. +
  45053. +
  45054. + if (pAddrWin->enable == MV_TRUE)
  45055. + {
  45056. + MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  45057. + }
  45058. + else
  45059. + {
  45060. + MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  45061. + }
  45062. +
  45063. + return MV_OK;
  45064. +}
  45065. +
  45066. +/*******************************************************************************
  45067. +* mvPexTargetWinRemapEnable -
  45068. +*
  45069. +* DESCRIPTION:
  45070. +*
  45071. +* INPUT:
  45072. +*
  45073. +* OUTPUT:
  45074. +*
  45075. +* RETURN:
  45076. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  45077. +*
  45078. +*******************************************************************************/
  45079. +
  45080. +MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum,
  45081. + MV_BOOL enable)
  45082. +{
  45083. + PEX_WIN_REG_INFO winRegInfo;
  45084. +
  45085. + /* Parameter checking */
  45086. + if (pexIf >= mvCtrlPexMaxIfGet())
  45087. + {
  45088. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
  45089. + pexIf);
  45090. + return MV_BAD_PARAM;
  45091. + }
  45092. + if (MV_PEX_WIN_DEFAULT == winNum)
  45093. + {
  45094. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
  45095. + winNum);
  45096. + return MV_BAD_PARAM;
  45097. +
  45098. + }
  45099. +
  45100. +
  45101. + pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
  45102. +
  45103. + if (enable == MV_TRUE)
  45104. + {
  45105. + MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  45106. + }
  45107. + else
  45108. + {
  45109. + MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  45110. + }
  45111. +
  45112. + return MV_OK;
  45113. +
  45114. +}
  45115. +
  45116. +/*******************************************************************************
  45117. +* mvPexBarSet - Set PEX bar address and size
  45118. +*
  45119. +* DESCRIPTION:
  45120. +*
  45121. +* INPUT:
  45122. +*
  45123. +* OUTPUT:
  45124. +* None.
  45125. +*
  45126. +* RETURN:
  45127. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  45128. +*
  45129. +*******************************************************************************/
  45130. +MV_STATUS mvPexBarSet(MV_U32 pexIf,
  45131. + MV_U32 barNum,
  45132. + MV_PEX_BAR *pAddrWin)
  45133. +{
  45134. + MV_U32 regBaseLow;
  45135. + MV_U32 regSize,sizeToReg;
  45136. +
  45137. +
  45138. + /* check parameters */
  45139. + if(pexIf >= mvCtrlPexMaxIfGet())
  45140. + {
  45141. + mvOsPrintf("mvPexBarSet: ERR. Invalid PEX interface %d\n", pexIf);
  45142. + return MV_BAD_PARAM;
  45143. + }
  45144. +
  45145. + if(barNum >= PEX_MAX_BARS)
  45146. + {
  45147. + mvOsPrintf("mvPexBarSet: ERR. Invalid bar number %d\n", barNum);
  45148. + return MV_BAD_PARAM;
  45149. + }
  45150. +
  45151. +
  45152. + if (pAddrWin->addrWin.size == 0)
  45153. + {
  45154. + mvOsPrintf("mvPexBarSet: Size zero is Illigal\n" );
  45155. + return MV_BAD_PARAM;
  45156. + }
  45157. +
  45158. +
  45159. + /* Check if the window complies with PEX spec */
  45160. + if (MV_TRUE != pexBarIsValid(pAddrWin->addrWin.baseLow,
  45161. + pAddrWin->addrWin.size))
  45162. + {
  45163. + mvOsPrintf("mvPexBarSet: ERR. Target %d window invalid\n", barNum);
  45164. + return MV_BAD_PARAM;
  45165. + }
  45166. +
  45167. + /* 2) Check if the requested bar overlaps with current bars */
  45168. + if (MV_TRUE == pexBarOverlapDetect(pexIf,barNum, &pAddrWin->addrWin))
  45169. + {
  45170. + mvOsPrintf("mvPexBarSet: ERR. Target %d overlap\n", barNum);
  45171. + return MV_BAD_PARAM;
  45172. + }
  45173. +
  45174. + /* Get size register value according to window size */
  45175. + sizeToReg = ctrlSizeToReg(pAddrWin->addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT);
  45176. +
  45177. + /* Read bar size */
  45178. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
  45179. + {
  45180. + regSize = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
  45181. +
  45182. + /* Size parameter validity check. */
  45183. + if (-1 == sizeToReg)
  45184. + {
  45185. + mvOsPrintf("mvPexBarSet: ERR. Target BAR %d size invalid.\n",barNum);
  45186. + return MV_BAD_PARAM;
  45187. + }
  45188. +
  45189. + regSize &= ~PXBCR_BAR_SIZE_MASK;
  45190. + regSize |= (sizeToReg << PXBCR_BAR_SIZE_OFFS) ;
  45191. +
  45192. + MV_REG_WRITE(PEX_BAR_CTRL_REG(pexIf,barNum),regSize);
  45193. +
  45194. + }
  45195. +
  45196. + /* set size */
  45197. +
  45198. +
  45199. +
  45200. + /* Read base address low */
  45201. + regBaseLow = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
  45202. + PEX_MV_BAR_BASE(barNum)));
  45203. +
  45204. + /* clear current base */
  45205. + if (PEX_INTER_REGS_BAR == barNum)
  45206. + {
  45207. + regBaseLow &= ~PXBIR_BASE_MASK;
  45208. + regBaseLow |= (pAddrWin->addrWin.baseLow & PXBIR_BASE_MASK);
  45209. + }
  45210. + else
  45211. + {
  45212. + regBaseLow &= ~PXBR_BASE_MASK;
  45213. + regBaseLow |= (pAddrWin->addrWin.baseLow & PXBR_BASE_MASK);
  45214. + }
  45215. +
  45216. + /* if we had a previous value that contain the bar type (MeM\IO), we want to
  45217. + restore it */
  45218. + regBaseLow |= PEX_BAR_DEFAULT_ATTRIB;
  45219. +
  45220. +
  45221. +
  45222. + /* write base low */
  45223. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)),
  45224. + regBaseLow);
  45225. +
  45226. + if (pAddrWin->addrWin.baseHigh != 0)
  45227. + {
  45228. + /* Read base address high */
  45229. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)),
  45230. + pAddrWin->addrWin.baseHigh);
  45231. +
  45232. + }
  45233. +
  45234. + /* lastly enable the Bar */
  45235. + if (pAddrWin->enable == MV_TRUE)
  45236. + {
  45237. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers
  45238. + are enabled always */
  45239. + {
  45240. + MV_REG_BIT_SET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
  45241. + }
  45242. + }
  45243. + else if (MV_FALSE == pAddrWin->enable)
  45244. + {
  45245. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers
  45246. + are enabled always */
  45247. + {
  45248. + MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
  45249. + }
  45250. +
  45251. + }
  45252. +
  45253. +
  45254. +
  45255. + return MV_OK;
  45256. +}
  45257. +
  45258. +
  45259. +/*******************************************************************************
  45260. +* mvPexBarGet - Get PEX bar address and size
  45261. +*
  45262. +* DESCRIPTION:
  45263. +*
  45264. +* INPUT:
  45265. +*
  45266. +* OUTPUT:
  45267. +* None.
  45268. +*
  45269. +* RETURN:
  45270. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  45271. +*
  45272. +*******************************************************************************/
  45273. +
  45274. +MV_STATUS mvPexBarGet(MV_U32 pexIf,
  45275. + MV_U32 barNum,
  45276. + MV_PEX_BAR *pAddrWin)
  45277. +{
  45278. + /* check parameters */
  45279. + if(pexIf >= mvCtrlPexMaxIfGet())
  45280. + {
  45281. + mvOsPrintf("mvPexBarGet: ERR. Invalid PEX interface %d\n", pexIf);
  45282. + return MV_BAD_PARAM;
  45283. + }
  45284. +
  45285. + if(barNum >= PEX_MAX_BARS)
  45286. + {
  45287. + mvOsPrintf("mvPexBarGet: ERR. Invalid bar number %d\n", barNum);
  45288. + return MV_BAD_PARAM;
  45289. + }
  45290. +
  45291. + /* read base low */
  45292. + pAddrWin->addrWin.baseLow =
  45293. + MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)));
  45294. +
  45295. +
  45296. + if (PEX_INTER_REGS_BAR == barNum)
  45297. + {
  45298. + pAddrWin->addrWin.baseLow &= PXBIR_BASE_MASK;
  45299. + }
  45300. + else
  45301. + {
  45302. + pAddrWin->addrWin.baseLow &= PXBR_BASE_MASK;
  45303. + }
  45304. +
  45305. +
  45306. + /* read base high */
  45307. + pAddrWin->addrWin.baseHigh =
  45308. + MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)));
  45309. +
  45310. +
  45311. + /* Read bar size */
  45312. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
  45313. + {
  45314. + pAddrWin->addrWin.size = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
  45315. +
  45316. + /* check if enable or not */
  45317. + if (pAddrWin->addrWin.size & PXBCR_BAR_EN)
  45318. + {
  45319. + pAddrWin->enable = MV_TRUE;
  45320. + }
  45321. + else
  45322. + {
  45323. + pAddrWin->enable = MV_FALSE;
  45324. + }
  45325. +
  45326. + /* now get the size */
  45327. + pAddrWin->addrWin.size &= PXBCR_BAR_SIZE_MASK;
  45328. + pAddrWin->addrWin.size >>= PXBCR_BAR_SIZE_OFFS;
  45329. +
  45330. + pAddrWin->addrWin.size = ctrlRegToSize(pAddrWin->addrWin.size,
  45331. + PXBCR_BAR_SIZE_ALIGNMENT);
  45332. +
  45333. + }
  45334. + else /* PEX_INTER_REGS_BAR */
  45335. + {
  45336. + pAddrWin->addrWin.size = INTER_REGS_SIZE;
  45337. + pAddrWin->enable = MV_TRUE;
  45338. + }
  45339. +
  45340. +
  45341. + return MV_OK;
  45342. +}
  45343. +
  45344. +/*******************************************************************************
  45345. +* mvPexBarEnable -
  45346. +*
  45347. +* DESCRIPTION:
  45348. +*
  45349. +* INPUT:
  45350. +*
  45351. +* OUTPUT:
  45352. +* None.
  45353. +*
  45354. +* RETURN:
  45355. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  45356. +*
  45357. +*******************************************************************************/
  45358. +
  45359. +
  45360. +MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable)
  45361. +{
  45362. +
  45363. + MV_PEX_BAR pexBar;
  45364. +
  45365. + /* check parameters */
  45366. + if(pexIf >= mvCtrlPexMaxIfGet())
  45367. + {
  45368. + mvOsPrintf("mvPexBarEnable: ERR. Invalid PEX interface %d\n", pexIf);
  45369. + return MV_BAD_PARAM;
  45370. + }
  45371. +
  45372. +
  45373. + if(barNum >= PEX_MAX_BARS)
  45374. + {
  45375. + mvOsPrintf("mvPexBarEnable: ERR. Invalid bar number %d\n", barNum);
  45376. + return MV_BAD_PARAM;
  45377. + }
  45378. +
  45379. + if (PEX_INTER_REGS_BAR == barNum)
  45380. + {
  45381. + if (MV_TRUE == enable)
  45382. + {
  45383. + return MV_OK;
  45384. + }
  45385. + else
  45386. + {
  45387. + return MV_ERROR;
  45388. + }
  45389. + }
  45390. +
  45391. +
  45392. + if (MV_FALSE == enable)
  45393. + {
  45394. + /* disable bar and quit */
  45395. + MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
  45396. + return MV_OK;
  45397. + }
  45398. +
  45399. + /* else */
  45400. +
  45401. + if (mvPexBarGet(pexIf,barNum,&pexBar) != MV_OK)
  45402. + {
  45403. + mvOsPrintf("mvPexBarEnable: mvPexBarGet Failed\n");
  45404. + return MV_ERROR;
  45405. +
  45406. + }
  45407. +
  45408. + if (MV_TRUE == pexBar.enable)
  45409. + {
  45410. + /* it is already enabled !!! */
  45411. + return MV_OK;
  45412. + }
  45413. +
  45414. + /* else enable the bar*/
  45415. +
  45416. + pexBar.enable = MV_TRUE;
  45417. +
  45418. + if (mvPexBarSet(pexIf,barNum,&pexBar) != MV_OK)
  45419. + {
  45420. + mvOsPrintf("mvPexBarEnable: mvPexBarSet Failed\n");
  45421. + return MV_ERROR;
  45422. +
  45423. + }
  45424. +
  45425. + return MV_OK;
  45426. +}
  45427. +
  45428. +
  45429. +/*******************************************************************************
  45430. +* pexWinOverlapDetect - Detect address windows overlapping
  45431. +*
  45432. +* DESCRIPTION:
  45433. +* This function detects address window overlapping of a given address
  45434. +* window in PEX BARs.
  45435. +*
  45436. +* INPUT:
  45437. +* pAddrWin - Address window to be checked.
  45438. +* bar - BAR to be accessed by slave.
  45439. +*
  45440. +* OUTPUT:
  45441. +* None.
  45442. +*
  45443. +* RETURN:
  45444. +* MV_TRUE if the given address window overlap current address
  45445. +* decode map, MV_FALSE otherwise.
  45446. +*
  45447. +*******************************************************************************/
  45448. +static MV_BOOL pexWinOverlapDetect(MV_U32 pexIf,
  45449. + MV_U32 winNum,
  45450. + MV_ADDR_WIN *pAddrWin)
  45451. +{
  45452. + MV_U32 win;
  45453. + MV_PEX_DEC_WIN addrDecWin;
  45454. +
  45455. +
  45456. + for(win = 0; win < PEX_MAX_TARGET_WIN -2 ; win++)
  45457. + {
  45458. + /* don't check our target or illegal targets */
  45459. + if (winNum == win)
  45460. + {
  45461. + continue;
  45462. + }
  45463. +
  45464. + /* Get window parameters */
  45465. + if (MV_OK != mvPexTargetWinGet(pexIf, win, &addrDecWin))
  45466. + {
  45467. + mvOsPrintf("pexWinOverlapDetect: ERR. TargetWinGet failed win=%x\n",
  45468. + win);
  45469. + return MV_ERROR;
  45470. + }
  45471. +
  45472. + /* Do not check disabled windows */
  45473. + if (MV_FALSE == addrDecWin.enable)
  45474. + {
  45475. + continue;
  45476. + }
  45477. +
  45478. +
  45479. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  45480. + {
  45481. + mvOsPrintf("pexWinOverlapDetect: winNum %d overlap current %d\n",
  45482. + winNum, win);
  45483. + return MV_TRUE;
  45484. + }
  45485. + }
  45486. +
  45487. + return MV_FALSE;
  45488. +}
  45489. +
  45490. +/*******************************************************************************
  45491. +* pexIsWinWithinBar - Detect if address is within PEX bar boundries
  45492. +*
  45493. +* DESCRIPTION:
  45494. +*
  45495. +* INPUT:
  45496. +*
  45497. +* OUTPUT:
  45498. +* None.
  45499. +*
  45500. +* RETURN:
  45501. +* MV_TRUE if the given address window overlap current address
  45502. +* decode map, MV_FALSE otherwise.
  45503. +*
  45504. +*******************************************************************************/
  45505. +static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,
  45506. + MV_ADDR_WIN *pAddrWin)
  45507. +{
  45508. + MV_U32 bar;
  45509. + MV_PEX_BAR addrDecWin;
  45510. +
  45511. + for(bar = 0; bar < PEX_MAX_BARS; bar++)
  45512. + {
  45513. +
  45514. + /* Get window parameters */
  45515. + if (MV_OK != mvPexBarGet(pexIf, bar, &addrDecWin))
  45516. + {
  45517. + mvOsPrintf("pexIsWinWithinBar: ERR. mvPexBarGet failed\n");
  45518. + return MV_ERROR;
  45519. + }
  45520. +
  45521. + /* Do not check disabled bars */
  45522. + if (MV_FALSE == addrDecWin.enable)
  45523. + {
  45524. + continue;
  45525. + }
  45526. +
  45527. +
  45528. + if(MV_TRUE == ctrlWinWithinWinTest(pAddrWin, &addrDecWin.addrWin))
  45529. + {
  45530. + return MV_TRUE;
  45531. + }
  45532. + }
  45533. +
  45534. + return MV_FALSE;
  45535. +
  45536. +}
  45537. +
  45538. +/*******************************************************************************
  45539. +* pexBarOverlapDetect - Detect address windows overlapping
  45540. +*
  45541. +* DESCRIPTION:
  45542. +* This function detects address window overlapping of a given address
  45543. +* window in PEX BARs.
  45544. +*
  45545. +* INPUT:
  45546. +* pAddrWin - Address window to be checked.
  45547. +* bar - BAR to be accessed by slave.
  45548. +*
  45549. +* OUTPUT:
  45550. +* None.
  45551. +*
  45552. +* RETURN:
  45553. +* MV_TRUE if the given address window overlap current address
  45554. +* decode map, MV_FALSE otherwise.
  45555. +*
  45556. +*******************************************************************************/
  45557. +static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,
  45558. + MV_U32 barNum,
  45559. + MV_ADDR_WIN *pAddrWin)
  45560. +{
  45561. + MV_U32 bar;
  45562. + MV_PEX_BAR barDecWin;
  45563. +
  45564. +
  45565. + for(bar = 0; bar < PEX_MAX_BARS; bar++)
  45566. + {
  45567. + /* don't check our target or illegal targets */
  45568. + if (barNum == bar)
  45569. + {
  45570. + continue;
  45571. + }
  45572. +
  45573. + /* Get window parameters */
  45574. + if (MV_OK != mvPexBarGet(pexIf, bar, &barDecWin))
  45575. + {
  45576. + mvOsPrintf("pexBarOverlapDetect: ERR. TargetWinGet failed\n");
  45577. + return MV_ERROR;
  45578. + }
  45579. +
  45580. + /* don'nt check disabled bars */
  45581. + if (barDecWin.enable == MV_FALSE)
  45582. + {
  45583. + continue;
  45584. + }
  45585. +
  45586. +
  45587. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &barDecWin.addrWin))
  45588. + {
  45589. + mvOsPrintf("pexBarOverlapDetect: winNum %d overlap current %d\n",
  45590. + barNum, bar);
  45591. + return MV_TRUE;
  45592. + }
  45593. + }
  45594. +
  45595. + return MV_FALSE;
  45596. +}
  45597. +
  45598. +/*******************************************************************************
  45599. +* pexBarIsValid - Check if the given address window is valid
  45600. +*
  45601. +* DESCRIPTION:
  45602. +* PEX spec restrict BAR base to be aligned to BAR size.
  45603. +* This function checks if the given address window is valid.
  45604. +*
  45605. +* INPUT:
  45606. +* baseLow - 32bit low base address.
  45607. +* size - Window size.
  45608. +*
  45609. +* OUTPUT:
  45610. +* None.
  45611. +*
  45612. +* RETURN:
  45613. +* MV_TRUE if the address window is valid, MV_FALSE otherwise.
  45614. +*
  45615. +*******************************************************************************/
  45616. +static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size)
  45617. +{
  45618. +
  45619. + /* PCI spec restrict BAR base to be aligned to BAR size */
  45620. + if(MV_IS_NOT_ALIGN(baseLow, size))
  45621. + {
  45622. + return MV_ERROR;
  45623. + }
  45624. + else
  45625. + {
  45626. + return MV_TRUE;
  45627. + }
  45628. +
  45629. + return MV_TRUE;
  45630. +}
  45631. +
  45632. +/*******************************************************************************
  45633. +* pexBarRegInfoGet - Get BAR register information
  45634. +*
  45635. +* DESCRIPTION:
  45636. +* PEX BARs registers offsets are inconsecutive.
  45637. +* This function gets a PEX BAR register information like register offsets
  45638. +* and function location of the BAR.
  45639. +*
  45640. +* INPUT:
  45641. +* pexIf - PEX interface number.
  45642. +* bar - The PEX BAR in question.
  45643. +*
  45644. +* OUTPUT:
  45645. +* pBarRegInfo - BAR register info struct.
  45646. +*
  45647. +* RETURN:
  45648. +* MV_BAD_PARAM when bad parameters ,MV_ERROR on error ,othewise MV_OK
  45649. +*
  45650. +*******************************************************************************/
  45651. +static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf,
  45652. + MV_U32 winNum,
  45653. + PEX_WIN_REG_INFO *pWinRegInfo)
  45654. +{
  45655. +
  45656. + if ((winNum >= 0)&&(winNum <=3))
  45657. + {
  45658. + pWinRegInfo->baseLowRegOffs = PEX_WIN0_3_BASE_REG(pexIf,winNum);
  45659. + pWinRegInfo->baseHighRegOffs = 0;
  45660. + pWinRegInfo->sizeRegOffs = PEX_WIN0_3_CTRL_REG(pexIf,winNum);
  45661. + pWinRegInfo->remapLowRegOffs = PEX_WIN0_3_REMAP_REG(pexIf,winNum);
  45662. + pWinRegInfo->remapHighRegOffs = 0;
  45663. + }
  45664. + else if ((winNum >= 4)&&(winNum <=5))
  45665. + {
  45666. + pWinRegInfo->baseLowRegOffs = PEX_WIN4_5_BASE_REG(pexIf,winNum);
  45667. + pWinRegInfo->baseHighRegOffs = 0;
  45668. + pWinRegInfo->sizeRegOffs = PEX_WIN4_5_CTRL_REG(pexIf,winNum);
  45669. + pWinRegInfo->remapLowRegOffs = PEX_WIN4_5_REMAP_REG(pexIf,winNum);
  45670. + pWinRegInfo->remapHighRegOffs = PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum);
  45671. +
  45672. + }
  45673. + else if (MV_PEX_WIN_DEFAULT == winNum)
  45674. + {
  45675. + pWinRegInfo->baseLowRegOffs = 0;
  45676. + pWinRegInfo->baseHighRegOffs = 0;
  45677. + pWinRegInfo->sizeRegOffs = PEX_WIN_DEFAULT_CTRL_REG(pexIf);
  45678. + pWinRegInfo->remapLowRegOffs = 0;
  45679. + pWinRegInfo->remapHighRegOffs = 0;
  45680. + }
  45681. + else if (MV_PEX_WIN_EXP_ROM == winNum)
  45682. + {
  45683. + pWinRegInfo->baseLowRegOffs = 0;
  45684. + pWinRegInfo->baseHighRegOffs = 0;
  45685. + pWinRegInfo->sizeRegOffs = PEX_WIN_EXP_ROM_CTRL_REG(pexIf);
  45686. + pWinRegInfo->remapLowRegOffs = PEX_WIN_EXP_ROM_REMAP_REG(pexIf);
  45687. + pWinRegInfo->remapHighRegOffs = 0;
  45688. +
  45689. + }
  45690. +
  45691. + return MV_OK;
  45692. +}
  45693. +
  45694. +/*******************************************************************************
  45695. +* pexBarNameGet - Get the string name of PEX BAR.
  45696. +*
  45697. +* DESCRIPTION:
  45698. +* This function get the string name of PEX BAR.
  45699. +*
  45700. +* INPUT:
  45701. +* bar - PEX bar number.
  45702. +*
  45703. +* OUTPUT:
  45704. +* None.
  45705. +*
  45706. +* RETURN:
  45707. +* pointer to the string name of PEX BAR.
  45708. +*
  45709. +*******************************************************************************/
  45710. +const MV_8* pexBarNameGet( MV_U32 bar )
  45711. +{
  45712. + switch( bar )
  45713. + {
  45714. + case PEX_INTER_REGS_BAR:
  45715. + return "Internal Regs Bar0....";
  45716. + case PEX_DRAM_BAR:
  45717. + return "DRAM Bar1.............";
  45718. + case PEX_DEVICE_BAR:
  45719. + return "Devices Bar2..........";
  45720. + default:
  45721. + return "Bar unknown";
  45722. + }
  45723. +}
  45724. +/*******************************************************************************
  45725. +* mvPexAddrDecShow - Print the PEX address decode map (BARs and windows).
  45726. +*
  45727. +* DESCRIPTION:
  45728. +* This function print the PEX address decode map (BARs and windows).
  45729. +*
  45730. +* INPUT:
  45731. +* None.
  45732. +*
  45733. +* OUTPUT:
  45734. +* None.
  45735. +*
  45736. +* RETURN:
  45737. +* None.
  45738. +*
  45739. +*******************************************************************************/
  45740. +MV_VOID mvPexAddrDecShow(MV_VOID)
  45741. +{
  45742. + MV_PEX_BAR pexBar;
  45743. + MV_PEX_DEC_WIN win;
  45744. + MV_U32 pexIf;
  45745. + MV_U32 bar,winNum;
  45746. +
  45747. + for( pexIf = 0; pexIf < mvCtrlPexMaxIfGet(); pexIf++ )
  45748. + {
  45749. + if (MV_FALSE == mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf)) continue;
  45750. + mvOsOutput( "\n" );
  45751. + mvOsOutput( "PEX%d:\n", pexIf );
  45752. + mvOsOutput( "-----\n" );
  45753. +
  45754. + mvOsOutput( "\nPex Bars \n\n");
  45755. +
  45756. + for( bar = 0; bar < PEX_MAX_BARS; bar++ )
  45757. + {
  45758. + memset( &pexBar, 0, sizeof(MV_PEX_BAR) );
  45759. +
  45760. + mvOsOutput( "%s ", pexBarNameGet(bar) );
  45761. +
  45762. + if( mvPexBarGet( pexIf, bar, &pexBar ) == MV_OK )
  45763. + {
  45764. + if( pexBar.enable )
  45765. + {
  45766. + mvOsOutput( "base %08x, ", pexBar.addrWin.baseLow );
  45767. + mvSizePrint( pexBar.addrWin.size );
  45768. + mvOsOutput( "\n" );
  45769. + }
  45770. + else
  45771. + mvOsOutput( "disable\n" );
  45772. + }
  45773. + }
  45774. + mvOsOutput( "\nPex Decode Windows\n\n");
  45775. +
  45776. + for( winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
  45777. + {
  45778. + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
  45779. +
  45780. + mvOsOutput( "win%d - ", winNum );
  45781. +
  45782. + if ( mvPexTargetWinGet(pexIf,winNum,&win) == MV_OK)
  45783. + {
  45784. + if (win.enable)
  45785. + {
  45786. + mvOsOutput( "%s base %08x, ",
  45787. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  45788. + mvOsOutput( "...." );
  45789. + mvSizePrint( win.addrWin.size );
  45790. +
  45791. + mvOsOutput( "\n" );
  45792. + }
  45793. + else
  45794. + mvOsOutput( "disable\n" );
  45795. +
  45796. +
  45797. + }
  45798. + }
  45799. +
  45800. + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
  45801. +
  45802. + mvOsOutput( "default win - " );
  45803. +
  45804. + if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_DEFAULT, &win) == MV_OK)
  45805. + {
  45806. + mvOsOutput( "%s ",
  45807. + mvCtrlTargetNameGet(win.target) );
  45808. + mvOsOutput( "\n" );
  45809. + }
  45810. + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
  45811. +
  45812. + mvOsOutput( "Expansion ROM - " );
  45813. +
  45814. + if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_EXP_ROM, &win) == MV_OK)
  45815. + {
  45816. + mvOsOutput( "%s ",
  45817. + mvCtrlTargetNameGet(win.target) );
  45818. + mvOsOutput( "\n" );
  45819. + }
  45820. +
  45821. + }
  45822. +}
  45823. +
  45824. +
  45825. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h
  45826. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h 1970-01-01 01:00:00.000000000 +0100
  45827. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h 2010-11-09 20:28:08.372495456 +0100
  45828. @@ -0,0 +1,348 @@
  45829. +/*******************************************************************************
  45830. +Copyright (C) Marvell International Ltd. and its affiliates
  45831. +
  45832. +This software file (the "File") is owned and distributed by Marvell
  45833. +International Ltd. and/or its affiliates ("Marvell") under the following
  45834. +alternative licensing terms. Once you have made an election to distribute the
  45835. +File under one of the following license alternatives, please (i) delete this
  45836. +introductory statement regarding license alternatives, (ii) delete the two
  45837. +license alternatives that you have not elected to use and (iii) preserve the
  45838. +Marvell copyright notice above.
  45839. +
  45840. +********************************************************************************
  45841. +Marvell Commercial License Option
  45842. +
  45843. +If you received this File from Marvell and you have entered into a commercial
  45844. +license agreement (a "Commercial License") with Marvell, the File is licensed
  45845. +to you under the terms of the applicable Commercial License.
  45846. +
  45847. +********************************************************************************
  45848. +Marvell GPL License Option
  45849. +
  45850. +If you received this File from Marvell, you may opt to use, redistribute and/or
  45851. +modify this File in accordance with the terms and conditions of the General
  45852. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  45853. +available along with the File in the license.txt file or by writing to the Free
  45854. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  45855. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  45856. +
  45857. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  45858. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  45859. +DISCLAIMED. The GPL License provides additional details about this warranty
  45860. +disclaimer.
  45861. +********************************************************************************
  45862. +Marvell BSD License Option
  45863. +
  45864. +If you received this File from Marvell, you may opt to use, redistribute and/or
  45865. +modify this File under the following licensing terms.
  45866. +Redistribution and use in source and binary forms, with or without modification,
  45867. +are permitted provided that the following conditions are met:
  45868. +
  45869. + * Redistributions of source code must retain the above copyright notice,
  45870. + this list of conditions and the following disclaimer.
  45871. +
  45872. + * Redistributions in binary form must reproduce the above copyright
  45873. + notice, this list of conditions and the following disclaimer in the
  45874. + documentation and/or other materials provided with the distribution.
  45875. +
  45876. + * Neither the name of Marvell nor the names of its contributors may be
  45877. + used to endorse or promote products derived from this software without
  45878. + specific prior written permission.
  45879. +
  45880. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  45881. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  45882. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  45883. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  45884. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  45885. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45886. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  45887. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  45888. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  45889. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  45890. +
  45891. +*******************************************************************************/
  45892. +
  45893. +#ifndef __INCSysPEXH
  45894. +#define __INCSysPEXH
  45895. +
  45896. +#include "mvCommon.h"
  45897. +#include "ctrlEnv/sys/mvCpuIf.h"
  45898. +#include "ctrlEnv/mvCtrlEnvLib.h"
  45899. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  45900. +
  45901. +/* 4KB granularity */
  45902. +#define MINIMUM_WINDOW_SIZE 0x1000
  45903. +#define MINIMUM_BAR_SIZE 0x1000
  45904. +#define MINIMUM_BAR_SIZE_MASK 0xFFFFF000
  45905. +#define BAR_SIZE_OFFS 12
  45906. +#define BAR_SIZE_MASK (0xFFFFF << BAR_SIZE_OFFS)
  45907. +
  45908. +
  45909. +
  45910. +#define MV_PEX_WIN_DEFAULT 6
  45911. +#define MV_PEX_WIN_EXP_ROM 7
  45912. +#define PEX_MAX_TARGET_WIN 8
  45913. +
  45914. +
  45915. +#define PEX_MAX_BARS 3
  45916. +#define PEX_INTER_REGS_BAR 0
  45917. +#define PEX_DRAM_BAR 1
  45918. +#define PEX_DEVICE_BAR 2
  45919. +
  45920. +/*************************************/
  45921. +/* PCI Express BAR Control Registers */
  45922. +/*************************************/
  45923. +#define PEX_BAR_CTRL_REG(pexIf,bar) (0x41804 + (bar-1)*4- (pexIf)*0x10000)
  45924. +#define PEX_EXP_ROM_BAR_CTRL_REG(pexIf) (0x4180C - (pexIf)*0x10000)
  45925. +
  45926. +
  45927. +/* PCI Express BAR Control Register */
  45928. +/* PEX_BAR_CTRL_REG (PXBCR) */
  45929. +
  45930. +#define PXBCR_BAR_EN BIT0
  45931. +#define PXBCR_BAR_SIZE_OFFS 16
  45932. +#define PXBCR_BAR_SIZE_MASK (0xffff << PXBCR_BAR_SIZE_OFFS)
  45933. +#define PXBCR_BAR_SIZE_ALIGNMENT 0x10000
  45934. +
  45935. +
  45936. +
  45937. +/* PCI Express Expansion ROM BAR Control Register */
  45938. +/* PEX_EXP_ROM_BAR_CTRL_REG (PXERBCR) */
  45939. +
  45940. +#define PXERBCR_EXPROM_EN BIT0
  45941. +#define PXERBCR_EXPROMSZ_OFFS 19
  45942. +#define PXERBCR_EXPROMSZ_MASK (0xf << PXERBCR_EXPROMSZ_OFFS)
  45943. +#define PXERBCR_EXPROMSZ_512KB (0x0 << PXERBCR_EXPROMSZ_OFFS)
  45944. +#define PXERBCR_EXPROMSZ_1024KB (0x1 << PXERBCR_EXPROMSZ_OFFS)
  45945. +#define PXERBCR_EXPROMSZ_2048KB (0x3 << PXERBCR_EXPROMSZ_OFFS)
  45946. +#define PXERBCR_EXPROMSZ_4096KB (0x7 << PXERBCR_EXPROMSZ_OFFS)
  45947. +
  45948. +/************************************************/
  45949. +/* PCI Express Address Window Control Registers */
  45950. +/************************************************/
  45951. +#define PEX_WIN0_3_CTRL_REG(pexIf,winNum) \
  45952. + (0x41820 + (winNum) * 0x10 - (pexIf) * 0x10000)
  45953. +#define PEX_WIN0_3_BASE_REG(pexIf,winNum) \
  45954. + (0x41824 + (winNum) * 0x10 - (pexIf) * 0x10000)
  45955. +#define PEX_WIN0_3_REMAP_REG(pexIf,winNum) \
  45956. + (0x4182C + (winNum) * 0x10 - (pexIf) * 0x10000)
  45957. +#define PEX_WIN4_5_CTRL_REG(pexIf,winNum) \
  45958. + (0x41860 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  45959. +#define PEX_WIN4_5_BASE_REG(pexIf,winNum) \
  45960. + (0x41864 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  45961. +#define PEX_WIN4_5_REMAP_REG(pexIf,winNum) \
  45962. + (0x4186C + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  45963. +#define PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum) \
  45964. + (0x41870 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  45965. +
  45966. +#define PEX_WIN_DEFAULT_CTRL_REG(pexIf) (0x418B0 - (pexIf) * 0x10000)
  45967. +#define PEX_WIN_EXP_ROM_CTRL_REG(pexIf) (0x418C0 - (pexIf) * 0x10000)
  45968. +#define PEX_WIN_EXP_ROM_REMAP_REG(pexIf) (0x418C4 - (pexIf) * 0x10000)
  45969. +
  45970. +/* PCI Express Window Control Register */
  45971. +/* PEX_WIN_CTRL_REG (PXWCR) */
  45972. +
  45973. +#define PXWCR_WIN_EN BIT0 /* Window Enable.*/
  45974. +
  45975. +#define PXWCR_WIN_BAR_MAP_OFFS 1 /* Mapping to BAR.*/
  45976. +#define PXWCR_WIN_BAR_MAP_MASK BIT1
  45977. +#define PXWCR_WIN_BAR_MAP_BAR1 (0 << PXWCR_WIN_BAR_MAP_OFFS)
  45978. +#define PXWCR_WIN_BAR_MAP_BAR2 (1 << PXWCR_WIN_BAR_MAP_OFFS)
  45979. +
  45980. +#define PXWCR_TARGET_OFFS 4 /*Unit ID */
  45981. +#define PXWCR_TARGET_MASK (0xf << PXWCR_TARGET_OFFS)
  45982. +
  45983. +#define PXWCR_ATTRIB_OFFS 8 /* target attributes */
  45984. +#define PXWCR_ATTRIB_MASK (0xff << PXWCR_ATTRIB_OFFS)
  45985. +
  45986. +#define PXWCR_SIZE_OFFS 16 /* size */
  45987. +#define PXWCR_SIZE_MASK (0xffff << PXWCR_SIZE_OFFS)
  45988. +#define PXWCR_SIZE_ALIGNMENT 0x10000
  45989. +
  45990. +/* PCI Express Window Base Register */
  45991. +/* PEX_WIN_BASE_REG (PXWBR)*/
  45992. +
  45993. +#define PXWBR_BASE_OFFS 16 /* address[31:16] */
  45994. +#define PXWBR_BASE_MASK (0xffff << PXWBR_BASE_OFFS)
  45995. +#define PXWBR_BASE_ALIGNMENT 0x10000
  45996. +
  45997. +/* PCI Express Window Remap Register */
  45998. +/* PEX_WIN_REMAP_REG (PXWRR)*/
  45999. +
  46000. +#define PXWRR_REMAP_EN BIT0
  46001. +#define PXWRR_REMAP_OFFS 16
  46002. +#define PXWRR_REMAP_MASK (0xffff << PXWRR_REMAP_OFFS)
  46003. +#define PXWRR_REMAP_ALIGNMENT 0x10000
  46004. +
  46005. +/* PCI Express Window Remap (High) Register */
  46006. +/* PEX_WIN_REMAP_HIGH_REG (PXWRHR)*/
  46007. +
  46008. +#define PXWRHR_REMAP_HIGH_OFFS 0
  46009. +#define PXWRHR_REMAP_HIGH_MASK (0xffffffff << PXWRHR_REMAP_HIGH_OFFS)
  46010. +
  46011. +/* PCI Express Default Window Control Register */
  46012. +/* PEX_WIN_DEFAULT_CTRL_REG (PXWDCR) */
  46013. +
  46014. +#define PXWDCR_TARGET_OFFS 4 /*Unit ID */
  46015. +#define PXWDCR_TARGET_MASK (0xf << PXWDCR_TARGET_OFFS)
  46016. +#define PXWDCR_ATTRIB_OFFS 8 /* target attributes */
  46017. +#define PXWDCR_ATTRIB_MASK (0xff << PXWDCR_ATTRIB_OFFS)
  46018. +
  46019. +/* PCI Express Expansion ROM Window Control Register */
  46020. +/* PEX_WIN_EXP_ROM_CTRL_REG (PXWERCR)*/
  46021. +
  46022. +#define PXWERCR_TARGET_OFFS 4 /*Unit ID */
  46023. +#define PXWERCR_TARGET_MASK (0xf << PXWERCR_TARGET_OFFS)
  46024. +#define PXWERCR_ATTRIB_OFFS 8 /* target attributes */
  46025. +#define PXWERCR_ATTRIB_MASK (0xff << PXWERCR_ATTRIB_OFFS)
  46026. +
  46027. +/* PCI Express Expansion ROM Window Remap Register */
  46028. +/* PEX_WIN_EXP_ROM_REMAP_REG (PXWERRR)*/
  46029. +
  46030. +#define PXWERRR_REMAP_EN BIT0
  46031. +#define PXWERRR_REMAP_OFFS 16
  46032. +#define PXWERRR_REMAP_MASK (0xffff << PXWERRR_REMAP_OFFS)
  46033. +#define PXWERRR_REMAP_ALIGNMENT 0x10000
  46034. +
  46035. +
  46036. +
  46037. +/*PEX_MEMORY_BAR_BASE_ADDR(barNum) (PXMBBA)*/
  46038. +/* PCI Express BAR0 Internal Register*/
  46039. +/*PEX BAR0_INTER_REG (PXBIR)*/
  46040. +
  46041. +#define PXBIR_IOSPACE BIT0 /* Memory Space Indicator */
  46042. +
  46043. +#define PXBIR_TYPE_OFFS 1 /* BAR Type/Init Val. */
  46044. +#define PXBIR_TYPE_MASK (0x3 << PXBIR_TYPE_OFFS)
  46045. +#define PXBIR_TYPE_32BIT_ADDR (0x0 << PXBIR_TYPE_OFFS)
  46046. +#define PXBIR_TYPE_64BIT_ADDR (0x2 << PXBIR_TYPE_OFFS)
  46047. +
  46048. +#define PXBIR_PREFETCH_EN BIT3 /* Prefetch Enable */
  46049. +
  46050. +#define PXBIR_BASE_OFFS 20 /* Base address. Address bits [31:20] */
  46051. +#define PXBIR_BASE_MASK (0xfff << PXBIR_BASE_OFFS)
  46052. +#define PXBIR_BASE_ALIGNMET (1 << PXBIR_BASE_OFFS)
  46053. +
  46054. +
  46055. +/* PCI Express BAR0 Internal (High) Register*/
  46056. +/*PEX BAR0_INTER_REG_HIGH (PXBIRH)*/
  46057. +
  46058. +#define PXBIRH_BASE_OFFS 0 /* Base address. Bits [63:32] */
  46059. +#define PXBIRH_BASE_MASK (0xffffffff << PBBHR_BASE_OFFS)
  46060. +
  46061. +
  46062. +#define PEX_BAR_DEFAULT_ATTRIB 0xc /* Memory - Prefetch - 64 bit address */
  46063. +#define PEX_BAR0_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
  46064. +#define PEX_BAR1_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
  46065. +#define PEX_BAR2_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
  46066. +
  46067. +
  46068. +/* PCI Express BAR1 Register */
  46069. +/* PCI Express BAR2 Register*/
  46070. +/*PEX BAR1_REG (PXBR)*/
  46071. +/*PEX BAR2_REG (PXBR)*/
  46072. +
  46073. +#define PXBR_IOSPACE BIT0 /* Memory Space Indicator */
  46074. +
  46075. +#define PXBR_TYPE_OFFS 1 /* BAR Type/Init Val. */
  46076. +#define PXBR_TYPE_MASK (0x3 << PXBR_TYPE_OFFS)
  46077. +#define PXBR_TYPE_32BIT_ADDR (0x0 << PXBR_TYPE_OFFS)
  46078. +#define PXBR_TYPE_64BIT_ADDR (0x2 << PXBR_TYPE_OFFS)
  46079. +
  46080. +#define PXBR_PREFETCH_EN BIT3 /* Prefetch Enable */
  46081. +
  46082. +#define PXBR_BASE_OFFS 16 /* Base address. Address bits [31:16] */
  46083. +#define PXBR_BASE_MASK (0xffff << PXBR_BASE_OFFS)
  46084. +#define PXBR_BASE_ALIGNMET (1 << PXBR_BASE_OFFS)
  46085. +
  46086. +
  46087. +/* PCI Express BAR1 (High) Register*/
  46088. +/* PCI Express BAR2 (High) Register*/
  46089. +/*PEX BAR1_REG_HIGH (PXBRH)*/
  46090. +/*PEX BAR2_REG_HIGH (PXBRH)*/
  46091. +
  46092. +#define PXBRH_BASE_OFFS 0 /* Base address. Address bits [63:32] */
  46093. +#define PXBRH_BASE_MASK (0xffffffff << PXBRH_BASE_OFFS)
  46094. +
  46095. +/* PCI Express Expansion ROM BAR Register*/
  46096. +/*PEX_EXPANSION_ROM_BASE_ADDR_REG (PXERBAR)*/
  46097. +
  46098. +#define PXERBAR_EXPROMEN BIT0 /* Expansion ROM Enable */
  46099. +
  46100. +#define PXERBAR_BASE_512K_OFFS 19 /* Expansion ROM Base Address */
  46101. +#define PXERBAR_BASE_512K_MASK (0x1fff << PXERBAR_BASE_512K_OFFS)
  46102. +
  46103. +#define PXERBAR_BASE_1MB_OFFS 20 /* Expansion ROM Base Address */
  46104. +#define PXERBAR_BASE_1MB_MASK (0xfff << PXERBAR_BASE_1MB_OFFS)
  46105. +
  46106. +#define PXERBAR_BASE_2MB_OFFS 21 /* Expansion ROM Base Address */
  46107. +#define PXERBAR_BASE_2MB_MASK (0x7ff << PXERBAR_BASE_2MB_OFFS)
  46108. +
  46109. +#define PXERBAR_BASE_4MB_OFFS 22 /* Expansion ROM Base Address */
  46110. +#define PXERBAR_BASE_4MB_MASK (0x3ff << PXERBAR_BASE_4MB_OFFS)
  46111. +
  46112. +/* PEX Bar attributes */
  46113. +typedef struct _mvPexBar
  46114. +{
  46115. + MV_ADDR_WIN addrWin; /* An address window*/
  46116. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  46117. +
  46118. +}MV_PEX_BAR;
  46119. +
  46120. +/* PEX Remap Window attributes */
  46121. +typedef struct _mvPexRemapWin
  46122. +{
  46123. + MV_ADDR_WIN addrWin; /* An address window*/
  46124. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  46125. +
  46126. +}MV_PEX_REMAP_WIN;
  46127. +
  46128. +/* PEX Remap Window attributes */
  46129. +typedef struct _mvPexDecWin
  46130. +{
  46131. + MV_TARGET target;
  46132. + MV_ADDR_WIN addrWin; /* An address window*/
  46133. + MV_U32 targetBar;
  46134. + MV_U8 attrib; /* chip select attributes */
  46135. + MV_TARGET_ID targetId; /* Target Id of this MV_TARGET */
  46136. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  46137. +
  46138. +}MV_PEX_DEC_WIN;
  46139. +
  46140. +/* Global Functions prototypes */
  46141. +/* mvPexHalInit - Initialize PEX interfaces*/
  46142. +MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType);
  46143. +
  46144. +
  46145. +/* mvPexTargetWinSet - Set PEX to peripheral target address window BAR*/
  46146. +MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum,
  46147. + MV_PEX_DEC_WIN *pAddrDecWin);
  46148. +
  46149. +/* mvPexTargetWinGet - Get PEX to peripheral target address window*/
  46150. +MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum,
  46151. + MV_PEX_DEC_WIN *pAddrDecWin);
  46152. +
  46153. +/* mvPexTargetWinEnable - Enable/disable a PEX BAR window*/
  46154. +MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable);
  46155. +
  46156. +/* mvPexTargetWinRemap - Set PEX to target address window remap.*/
  46157. +MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum,
  46158. + MV_PEX_REMAP_WIN *pAddrWin);
  46159. +
  46160. +/* mvPexTargetWinRemapEnable -enable\disable a PEX Window remap.*/
  46161. +MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum,
  46162. + MV_BOOL enable);
  46163. +
  46164. +/* mvPexBarSet - Set PEX bar address and size */
  46165. +MV_STATUS mvPexBarSet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);
  46166. +
  46167. +/* mvPexBarGet - Get PEX bar address and size */
  46168. +MV_STATUS mvPexBarGet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);
  46169. +
  46170. +/* mvPexBarEnable - enable\disable a PEX bar*/
  46171. +MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable);
  46172. +
  46173. +/* mvPexAddrDecShow - Display address decode windows attributes */
  46174. +MV_VOID mvPexAddrDecShow(MV_VOID);
  46175. +
  46176. +#endif
  46177. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c
  46178. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c 1970-01-01 01:00:00.000000000 +0100
  46179. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c 2010-11-09 20:28:08.402495399 +0100
  46180. @@ -0,0 +1,430 @@
  46181. +/*******************************************************************************
  46182. +Copyright (C) Marvell International Ltd. and its affiliates
  46183. +
  46184. +This software file (the "File") is owned and distributed by Marvell
  46185. +International Ltd. and/or its affiliates ("Marvell") under the following
  46186. +alternative licensing terms. Once you have made an election to distribute the
  46187. +File under one of the following license alternatives, please (i) delete this
  46188. +introductory statement regarding license alternatives, (ii) delete the two
  46189. +license alternatives that you have not elected to use and (iii) preserve the
  46190. +Marvell copyright notice above.
  46191. +
  46192. +********************************************************************************
  46193. +Marvell Commercial License Option
  46194. +
  46195. +If you received this File from Marvell and you have entered into a commercial
  46196. +license agreement (a "Commercial License") with Marvell, the File is licensed
  46197. +to you under the terms of the applicable Commercial License.
  46198. +
  46199. +********************************************************************************
  46200. +Marvell GPL License Option
  46201. +
  46202. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46203. +modify this File in accordance with the terms and conditions of the General
  46204. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  46205. +available along with the File in the license.txt file or by writing to the Free
  46206. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  46207. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  46208. +
  46209. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  46210. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  46211. +DISCLAIMED. The GPL License provides additional details about this warranty
  46212. +disclaimer.
  46213. +********************************************************************************
  46214. +Marvell BSD License Option
  46215. +
  46216. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46217. +modify this File under the following licensing terms.
  46218. +Redistribution and use in source and binary forms, with or without modification,
  46219. +are permitted provided that the following conditions are met:
  46220. +
  46221. + * Redistributions of source code must retain the above copyright notice,
  46222. + this list of conditions and the following disclaimer.
  46223. +
  46224. + * Redistributions in binary form must reproduce the above copyright
  46225. + notice, this list of conditions and the following disclaimer in the
  46226. + documentation and/or other materials provided with the distribution.
  46227. +
  46228. + * Neither the name of Marvell nor the names of its contributors may be
  46229. + used to endorse or promote products derived from this software without
  46230. + specific prior written permission.
  46231. +
  46232. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  46233. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  46234. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  46235. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  46236. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  46237. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46238. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  46239. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  46240. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  46241. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  46242. +
  46243. +*******************************************************************************/
  46244. +
  46245. +
  46246. +#include "mvTypes.h"
  46247. +#include "mvCommon.h"
  46248. +#include "mvOs.h"
  46249. +#include "ctrlEnv/mvCtrlEnvLib.h"
  46250. +#include "cpu/mvCpu.h"
  46251. +#include "ctrlEnv/sys/mvCpuIf.h"
  46252. +#include "sata/CoreDriver/mvRegs.h"
  46253. +#include "ctrlEnv/sys/mvSysSata.h"
  46254. +
  46255. +MV_TARGET sataAddrDecPrioTab[] =
  46256. +{
  46257. +#if defined(MV_INCLUDE_SDRAM_CS0)
  46258. + SDRAM_CS0,
  46259. +#endif
  46260. +#if defined(MV_INCLUDE_SDRAM_CS1)
  46261. + SDRAM_CS1,
  46262. +#endif
  46263. +#if defined(MV_INCLUDE_SDRAM_CS2)
  46264. + SDRAM_CS2,
  46265. +#endif
  46266. +#if defined(MV_INCLUDE_SDRAM_CS3)
  46267. + SDRAM_CS3,
  46268. +#endif
  46269. +#if defined(MV_INCLUDE_PEX)
  46270. + PEX0_MEM,
  46271. +#endif
  46272. + TBL_TERM
  46273. +};
  46274. +
  46275. +
  46276. +/*******************************************************************************
  46277. +* sataWinOverlapDetect - Detect SATA address windows overlapping
  46278. +*
  46279. +* DESCRIPTION:
  46280. +* An unpredicted behaviur is expected in case SATA address decode
  46281. +* windows overlapps.
  46282. +* This function detects SATA address decode windows overlapping of a
  46283. +* specified window. The function does not check the window itself for
  46284. +* overlapping. The function also skipps disabled address decode windows.
  46285. +*
  46286. +* INPUT:
  46287. +* winNum - address decode window number.
  46288. +* pAddrDecWin - An address decode window struct.
  46289. +*
  46290. +* OUTPUT:
  46291. +* None.
  46292. +*
  46293. +* RETURN:
  46294. +* MV_TRUE if the given address window overlap current address
  46295. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  46296. +* from registers.
  46297. +*
  46298. +*******************************************************************************/
  46299. +static MV_STATUS sataWinOverlapDetect(int dev, MV_U32 winNum,
  46300. + MV_ADDR_WIN *pAddrWin)
  46301. +{
  46302. + MV_U32 winNumIndex;
  46303. + MV_SATA_DEC_WIN addrDecWin;
  46304. +
  46305. + for(winNumIndex=0; winNumIndex<MV_SATA_MAX_ADDR_DECODE_WIN; winNumIndex++)
  46306. + {
  46307. + /* Do not check window itself */
  46308. + if (winNumIndex == winNum)
  46309. + {
  46310. + continue;
  46311. + }
  46312. +
  46313. + /* Get window parameters */
  46314. + if (MV_OK != mvSataWinGet(dev, winNumIndex, &addrDecWin))
  46315. + {
  46316. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  46317. + return MV_ERROR;
  46318. + }
  46319. +
  46320. + /* Do not check disabled windows */
  46321. + if(addrDecWin.enable == MV_FALSE)
  46322. + {
  46323. + continue;
  46324. + }
  46325. +
  46326. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  46327. + {
  46328. + return MV_TRUE;
  46329. + }
  46330. + }
  46331. + return MV_FALSE;
  46332. +}
  46333. +
  46334. +
  46335. +/*******************************************************************************
  46336. +* mvSataWinSet - Set SATA target address window
  46337. +*
  46338. +* DESCRIPTION:
  46339. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  46340. +* address window, also known as address decode window.
  46341. +* After setting this target window, the SATA will be able to access the
  46342. +* target within the address window.
  46343. +*
  46344. +* INPUT:
  46345. +* winNum - SATA target address decode window number.
  46346. +* pAddrDecWin - SATA target window data structure.
  46347. +*
  46348. +* OUTPUT:
  46349. +* None.
  46350. +*
  46351. +* RETURN:
  46352. +* MV_ERROR if address window overlapps with other address decode windows.
  46353. +* MV_BAD_PARAM if base address is invalid parameter or target is
  46354. +* unknown.
  46355. +*
  46356. +*******************************************************************************/
  46357. +MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)
  46358. +{
  46359. + MV_TARGET_ATTRIB targetAttribs;
  46360. + MV_DEC_REGS decRegs;
  46361. +
  46362. + /* Parameter checking */
  46363. + if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)
  46364. + {
  46365. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  46366. + return MV_BAD_PARAM;
  46367. + }
  46368. +
  46369. + /* Check if the requested window overlapps with current windows */
  46370. + if (MV_TRUE == sataWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))
  46371. + {
  46372. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  46373. + return MV_ERROR;
  46374. + }
  46375. +
  46376. + /* check if address is aligned to the size */
  46377. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  46378. + {
  46379. + mvOsPrintf("mvSataWinSet:Error setting SATA window %d to "\
  46380. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  46381. + winNum,
  46382. + mvCtrlTargetNameGet(pAddrDecWin->target),
  46383. + pAddrDecWin->addrWin.baseLow,
  46384. + pAddrDecWin->addrWin.size);
  46385. + return MV_ERROR;
  46386. + }
  46387. +
  46388. + decRegs.baseReg = 0;
  46389. + decRegs.sizeReg = 0;
  46390. +
  46391. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  46392. + {
  46393. + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
  46394. + return MV_ERROR;
  46395. + }
  46396. +
  46397. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  46398. +
  46399. + /* set attributes */
  46400. + decRegs.sizeReg &= ~MV_SATA_WIN_ATTR_MASK;
  46401. + decRegs.sizeReg |= (targetAttribs.attrib << MV_SATA_WIN_ATTR_OFFSET);
  46402. +
  46403. + /* set target ID */
  46404. + decRegs.sizeReg &= ~MV_SATA_WIN_TARGET_MASK;
  46405. + decRegs.sizeReg |= (targetAttribs.targetId << MV_SATA_WIN_TARGET_OFFSET);
  46406. +
  46407. + if (pAddrDecWin->enable == MV_TRUE)
  46408. + {
  46409. + decRegs.sizeReg |= MV_SATA_WIN_ENABLE_MASK;
  46410. + }
  46411. + else
  46412. + {
  46413. + decRegs.sizeReg &= ~MV_SATA_WIN_ENABLE_MASK;
  46414. + }
  46415. +
  46416. + MV_REG_WRITE( MV_SATA_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);
  46417. + MV_REG_WRITE( MV_SATA_WIN_BASE_REG(dev, winNum), decRegs.baseReg);
  46418. +
  46419. + return MV_OK;
  46420. +}
  46421. +
  46422. +/*******************************************************************************
  46423. +* mvSataWinGet - Get SATA peripheral target address window.
  46424. +*
  46425. +* DESCRIPTION:
  46426. +* Get SATA peripheral target address window.
  46427. +*
  46428. +* INPUT:
  46429. +* winNum - SATA target address decode window number.
  46430. +*
  46431. +* OUTPUT:
  46432. +* pAddrDecWin - SATA target window data structure.
  46433. +*
  46434. +* RETURN:
  46435. +* MV_ERROR if register parameters are invalid.
  46436. +*
  46437. +*******************************************************************************/
  46438. +MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)
  46439. +{
  46440. + MV_DEC_REGS decRegs;
  46441. + MV_TARGET_ATTRIB targetAttrib;
  46442. +
  46443. + /* Parameter checking */
  46444. + if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)
  46445. + {
  46446. + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
  46447. + __FUNCTION__, dev, winNum);
  46448. + return MV_NOT_SUPPORTED;
  46449. + }
  46450. +
  46451. + decRegs.baseReg = MV_REG_READ( MV_SATA_WIN_BASE_REG(dev, winNum) );
  46452. + decRegs.sizeReg = MV_REG_READ( MV_SATA_WIN_CTRL_REG(dev, winNum) );
  46453. +
  46454. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
  46455. + {
  46456. + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
  46457. + return MV_ERROR;
  46458. + }
  46459. +
  46460. + /* attrib and targetId */
  46461. + targetAttrib.attrib = (decRegs.sizeReg & MV_SATA_WIN_ATTR_MASK) >>
  46462. + MV_SATA_WIN_ATTR_OFFSET;
  46463. + targetAttrib.targetId = (decRegs.sizeReg & MV_SATA_WIN_TARGET_MASK) >>
  46464. + MV_SATA_WIN_TARGET_OFFSET;
  46465. +
  46466. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  46467. +
  46468. + /* Check if window is enabled */
  46469. + if(decRegs.sizeReg & MV_SATA_WIN_ENABLE_MASK)
  46470. + {
  46471. + pAddrDecWin->enable = MV_TRUE;
  46472. + }
  46473. + else
  46474. + {
  46475. + pAddrDecWin->enable = MV_FALSE;
  46476. + }
  46477. + return MV_OK;
  46478. +}
  46479. +/*******************************************************************************
  46480. +* mvSataAddrDecShow - Print the SATA address decode map.
  46481. +*
  46482. +* DESCRIPTION:
  46483. +* This function print the SATA address decode map.
  46484. +*
  46485. +* INPUT:
  46486. +* None.
  46487. +*
  46488. +* OUTPUT:
  46489. +* None.
  46490. +*
  46491. +* RETURN:
  46492. +* None.
  46493. +*
  46494. +*******************************************************************************/
  46495. +MV_VOID mvSataAddrDecShow(MV_VOID)
  46496. +{
  46497. +
  46498. + MV_SATA_DEC_WIN win;
  46499. + int i,j;
  46500. +
  46501. +
  46502. +
  46503. + for( j = 0; j < MV_SATA_MAX_CHAN; j++ )
  46504. + {
  46505. + if (MV_FALSE == mvCtrlPwrClckGet(SATA_UNIT_ID, j))
  46506. + return;
  46507. +
  46508. + mvOsOutput( "\n" );
  46509. + mvOsOutput( "SATA %d:\n", j );
  46510. + mvOsOutput( "----\n" );
  46511. +
  46512. + for( i = 0; i < MV_SATA_MAX_ADDR_DECODE_WIN; i++ )
  46513. + {
  46514. + memset( &win, 0, sizeof(MV_SATA_DEC_WIN) );
  46515. +
  46516. + mvOsOutput( "win%d - ", i );
  46517. +
  46518. + if( mvSataWinGet(j, i, &win ) == MV_OK )
  46519. + {
  46520. + if( win.enable )
  46521. + {
  46522. + mvOsOutput( "%s base %08x, ",
  46523. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  46524. + mvOsOutput( "...." );
  46525. +
  46526. + mvSizePrint( win.addrWin.size );
  46527. +
  46528. + mvOsOutput( "\n" );
  46529. + }
  46530. + else
  46531. + mvOsOutput( "disable\n" );
  46532. + }
  46533. + }
  46534. + }
  46535. +}
  46536. +
  46537. +
  46538. +/*******************************************************************************
  46539. +* mvSataWinInit - Initialize the integrated SATA target address window.
  46540. +*
  46541. +* DESCRIPTION:
  46542. +* Initialize the SATA peripheral target address window.
  46543. +*
  46544. +* INPUT:
  46545. +*
  46546. +*
  46547. +* OUTPUT:
  46548. +*
  46549. +*
  46550. +* RETURN:
  46551. +* MV_ERROR if register parameters are invalid.
  46552. +*
  46553. +*******************************************************************************/
  46554. +MV_STATUS mvSataWinInit(MV_VOID)
  46555. +{
  46556. + int winNum;
  46557. + MV_SATA_DEC_WIN sataWin;
  46558. + MV_CPU_DEC_WIN cpuAddrDecWin;
  46559. + MV_U32 status, winPrioIndex = 0;
  46560. +
  46561. + /* Initiate Sata address decode */
  46562. +
  46563. + /* First disable all address decode windows */
  46564. + for(winNum = 0; winNum < MV_SATA_MAX_ADDR_DECODE_WIN; winNum++)
  46565. + {
  46566. + MV_U32 regVal = MV_REG_READ(MV_SATA_WIN_CTRL_REG(0, winNum));
  46567. + regVal &= ~MV_SATA_WIN_ENABLE_MASK;
  46568. + MV_REG_WRITE(MV_SATA_WIN_CTRL_REG(0, winNum), regVal);
  46569. + }
  46570. +
  46571. + winNum = 0;
  46572. + while( (sataAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
  46573. + (winNum < MV_SATA_MAX_ADDR_DECODE_WIN) )
  46574. + {
  46575. + /* first get attributes from CPU If */
  46576. + status = mvCpuIfTargetWinGet(sataAddrDecPrioTab[winPrioIndex],
  46577. + &cpuAddrDecWin);
  46578. +
  46579. + if(MV_NO_SUCH == status)
  46580. + {
  46581. + winPrioIndex++;
  46582. + continue;
  46583. + }
  46584. + if (MV_OK != status)
  46585. + {
  46586. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  46587. + return MV_ERROR;
  46588. + }
  46589. +
  46590. + if (cpuAddrDecWin.enable == MV_TRUE)
  46591. + {
  46592. + sataWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  46593. + sataWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  46594. + sataWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  46595. + sataWin.enable = MV_TRUE;
  46596. + sataWin.target = sataAddrDecPrioTab[winPrioIndex];
  46597. +
  46598. + if(MV_OK != mvSataWinSet(0/*dev*/, winNum, &sataWin))
  46599. + {
  46600. + return MV_ERROR;
  46601. + }
  46602. + winNum++;
  46603. + }
  46604. + winPrioIndex++;
  46605. + }
  46606. + return MV_OK;
  46607. +}
  46608. +
  46609. +
  46610. +
  46611. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h
  46612. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h 1970-01-01 01:00:00.000000000 +0100
  46613. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h 2010-11-09 20:28:08.526524216 +0100
  46614. @@ -0,0 +1,128 @@
  46615. +
  46616. +/*******************************************************************************
  46617. +Copyright (C) Marvell International Ltd. and its affiliates
  46618. +
  46619. +This software file (the "File") is owned and distributed by Marvell
  46620. +International Ltd. and/or its affiliates ("Marvell") under the following
  46621. +alternative licensing terms. Once you have made an election to distribute the
  46622. +File under one of the following license alternatives, please (i) delete this
  46623. +introductory statement regarding license alternatives, (ii) delete the two
  46624. +license alternatives that you have not elected to use and (iii) preserve the
  46625. +Marvell copyright notice above.
  46626. +
  46627. +********************************************************************************
  46628. +Marvell Commercial License Option
  46629. +
  46630. +If you received this File from Marvell and you have entered into a commercial
  46631. +license agreement (a "Commercial License") with Marvell, the File is licensed
  46632. +to you under the terms of the applicable Commercial License.
  46633. +
  46634. +********************************************************************************
  46635. +Marvell GPL License Option
  46636. +
  46637. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46638. +modify this File in accordance with the terms and conditions of the General
  46639. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  46640. +available along with the File in the license.txt file or by writing to the Free
  46641. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  46642. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  46643. +
  46644. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  46645. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  46646. +DISCLAIMED. The GPL License provides additional details about this warranty
  46647. +disclaimer.
  46648. +********************************************************************************
  46649. +Marvell BSD License Option
  46650. +
  46651. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46652. +modify this File under the following licensing terms.
  46653. +Redistribution and use in source and binary forms, with or without modification,
  46654. +are permitted provided that the following conditions are met:
  46655. +
  46656. + * Redistributions of source code must retain the above copyright notice,
  46657. + this list of conditions and the following disclaimer.
  46658. +
  46659. + * Redistributions in binary form must reproduce the above copyright
  46660. + notice, this list of conditions and the following disclaimer in the
  46661. + documentation and/or other materials provided with the distribution.
  46662. +
  46663. + * Neither the name of Marvell nor the names of its contributors may be
  46664. + used to endorse or promote products derived from this software without
  46665. + specific prior written permission.
  46666. +
  46667. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  46668. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  46669. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  46670. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  46671. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  46672. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46673. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  46674. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  46675. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  46676. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  46677. +
  46678. +*******************************************************************************/
  46679. +#ifndef __INCMVSysSataAddrDech
  46680. +#define __INCMVSysSataAddrDech
  46681. +
  46682. +#include "mvCommon.h"
  46683. +#include "ctrlEnv/mvCtrlEnvLib.h"
  46684. +#include "ctrlEnv/sys/mvCpuIf.h"
  46685. +
  46686. +
  46687. +#ifdef __cplusplus
  46688. +extern "C" {
  46689. +#endif
  46690. +
  46691. +typedef struct _mvSataDecWin
  46692. +{
  46693. + MV_TARGET target;
  46694. + MV_ADDR_WIN addrWin; /* An address window*/
  46695. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  46696. +
  46697. +} MV_SATA_DEC_WIN;
  46698. +
  46699. +
  46700. +#define MV_SATA_MAX_ADDR_DECODE_WIN 4
  46701. +
  46702. +#define MV_SATA_WIN_CTRL_REG(dev, win) (SATA_REG_BASE + 0x30 + ((win)<<4))
  46703. +#define MV_SATA_WIN_BASE_REG(dev, win) (SATA_REG_BASE + 0x34 + ((win)<<4))
  46704. +
  46705. +/* BITs in Bridge Interrupt Cause and Mask registers */
  46706. +#define MV_SATA_ADDR_DECODE_ERROR_BIT 0
  46707. +#define MV_SATA_ADDR_DECODE_ERROR_MASK (1<<MV_SATA_ADDR_DECODE_ERROR_BIT)
  46708. +
  46709. +/* BITs in Windows 0-3 Control and Base Registers */
  46710. +#define MV_SATA_WIN_ENABLE_BIT 0
  46711. +#define MV_SATA_WIN_ENABLE_MASK (1<<MV_SATA_WIN_ENABLE_BIT)
  46712. +
  46713. +#define MV_SATA_WIN_TARGET_OFFSET 4
  46714. +#define MV_SATA_WIN_TARGET_MASK (0xF<<MV_SATA_WIN_TARGET_OFFSET)
  46715. +
  46716. +#define MV_SATA_WIN_ATTR_OFFSET 8
  46717. +#define MV_SATA_WIN_ATTR_MASK (0xFF<<MV_SATA_WIN_ATTR_OFFSET)
  46718. +
  46719. +#define MV_SATA_WIN_SIZE_OFFSET 16
  46720. +#define MV_SATA_WIN_SIZE_MASK (0xFFFF<<MV_SATA_WIN_SIZE_OFFSET)
  46721. +
  46722. +#define MV_SATA_WIN_BASE_OFFSET 16
  46723. +#define MV_SATA_WIN_BASE_MASK (0xFFFF<<MV_SATA_WIN_BASE_OFFSET)
  46724. +
  46725. +MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);
  46726. +MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);
  46727. +MV_STATUS mvSataWinByTargetGet(MV_TARGET target, MV_SATA_DEC_WIN *pAddrDecWin);
  46728. +MV_STATUS mvSataWinInit(MV_VOID);
  46729. +MV_VOID mvSataAddrDecShow(MV_VOID);
  46730. +
  46731. +
  46732. +#ifdef __cplusplus
  46733. +}
  46734. +#endif
  46735. +
  46736. +
  46737. +#endif
  46738. +
  46739. +
  46740. +
  46741. +
  46742. +
  46743. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c
  46744. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c 1970-01-01 01:00:00.000000000 +0100
  46745. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c 2010-11-09 20:28:08.633445891 +0100
  46746. @@ -0,0 +1,427 @@
  46747. +/*******************************************************************************
  46748. +Copyright (C) Marvell International Ltd. and its affiliates
  46749. +
  46750. +This software file (the "File") is owned and distributed by Marvell
  46751. +International Ltd. and/or its affiliates ("Marvell") under the following
  46752. +alternative licensing terms. Once you have made an election to distribute the
  46753. +File under one of the following license alternatives, please (i) delete this
  46754. +introductory statement regarding license alternatives, (ii) delete the two
  46755. +license alternatives that you have not elected to use and (iii) preserve the
  46756. +Marvell copyright notice above.
  46757. +
  46758. +********************************************************************************
  46759. +Marvell Commercial License Option
  46760. +
  46761. +If you received this File from Marvell and you have entered into a commercial
  46762. +license agreement (a "Commercial License") with Marvell, the File is licensed
  46763. +to you under the terms of the applicable Commercial License.
  46764. +
  46765. +********************************************************************************
  46766. +Marvell GPL License Option
  46767. +
  46768. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46769. +modify this File in accordance with the terms and conditions of the General
  46770. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  46771. +available along with the File in the license.txt file or by writing to the Free
  46772. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  46773. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  46774. +
  46775. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  46776. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  46777. +DISCLAIMED. The GPL License provides additional details about this warranty
  46778. +disclaimer.
  46779. +********************************************************************************
  46780. +Marvell BSD License Option
  46781. +
  46782. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46783. +modify this File under the following licensing terms.
  46784. +Redistribution and use in source and binary forms, with or without modification,
  46785. +are permitted provided that the following conditions are met:
  46786. +
  46787. + * Redistributions of source code must retain the above copyright notice,
  46788. + this list of conditions and the following disclaimer.
  46789. +
  46790. + * Redistributions in binary form must reproduce the above copyright
  46791. + notice, this list of conditions and the following disclaimer in the
  46792. + documentation and/or other materials provided with the distribution.
  46793. +
  46794. + * Neither the name of Marvell nor the names of its contributors may be
  46795. + used to endorse or promote products derived from this software without
  46796. + specific prior written permission.
  46797. +
  46798. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  46799. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  46800. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  46801. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  46802. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  46803. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46804. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  46805. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  46806. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  46807. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  46808. +
  46809. +*******************************************************************************/
  46810. +
  46811. +
  46812. +#include "mvTypes.h"
  46813. +#include "mvCommon.h"
  46814. +#include "mvOs.h"
  46815. +#include "ctrlEnv/mvCtrlEnvLib.h"
  46816. +#include "cpu/mvCpu.h"
  46817. +#include "ctrlEnv/sys/mvCpuIf.h"
  46818. +#include "mvRegs.h"
  46819. +#include "ctrlEnv/sys/mvSysSdmmc.h"
  46820. +
  46821. +MV_TARGET sdmmcAddrDecPrioTab[] =
  46822. +{
  46823. +#if defined(MV_INCLUDE_SDRAM_CS0)
  46824. + SDRAM_CS0,
  46825. +#endif
  46826. +#if defined(MV_INCLUDE_SDRAM_CS1)
  46827. + SDRAM_CS1,
  46828. +#endif
  46829. +#if defined(MV_INCLUDE_SDRAM_CS2)
  46830. + SDRAM_CS2,
  46831. +#endif
  46832. +#if defined(MV_INCLUDE_SDRAM_CS3)
  46833. + SDRAM_CS3,
  46834. +#endif
  46835. +#if defined(MV_INCLUDE_PEX)
  46836. + PEX0_MEM,
  46837. +#endif
  46838. + TBL_TERM
  46839. +};
  46840. +
  46841. +
  46842. +/*******************************************************************************
  46843. +* sdmmcWinOverlapDetect - Detect SDMMC address windows overlapping
  46844. +*
  46845. +* DESCRIPTION:
  46846. +* An unpredicted behaviur is expected in case SDMMC address decode
  46847. +* windows overlapps.
  46848. +* This function detects SDMMC address decode windows overlapping of a
  46849. +* specified window. The function does not check the window itself for
  46850. +* overlapping. The function also skipps disabled address decode windows.
  46851. +*
  46852. +* INPUT:
  46853. +* winNum - address decode window number.
  46854. +* pAddrDecWin - An address decode window struct.
  46855. +*
  46856. +* OUTPUT:
  46857. +* None.
  46858. +*
  46859. +* RETURN:
  46860. +* MV_TRUE if the given address window overlap current address
  46861. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  46862. +* from registers.
  46863. +*
  46864. +*******************************************************************************/
  46865. +static MV_STATUS sdmmcWinOverlapDetect(int dev, MV_U32 winNum,
  46866. + MV_ADDR_WIN *pAddrWin)
  46867. +{
  46868. + MV_U32 winNumIndex;
  46869. + MV_SDMMC_DEC_WIN addrDecWin;
  46870. +
  46871. + for(winNumIndex=0; winNumIndex<MV_SDMMC_MAX_ADDR_DECODE_WIN; winNumIndex++)
  46872. + {
  46873. + /* Do not check window itself */
  46874. + if (winNumIndex == winNum)
  46875. + {
  46876. + continue;
  46877. + }
  46878. +
  46879. + /* Get window parameters */
  46880. + if (MV_OK != mvSdmmcWinGet(dev, winNumIndex, &addrDecWin))
  46881. + {
  46882. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  46883. + return MV_ERROR;
  46884. + }
  46885. +
  46886. + /* Do not check disabled windows */
  46887. + if(addrDecWin.enable == MV_FALSE)
  46888. + {
  46889. + continue;
  46890. + }
  46891. +
  46892. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  46893. + {
  46894. + return MV_TRUE;
  46895. + }
  46896. + }
  46897. + return MV_FALSE;
  46898. +}
  46899. +
  46900. +
  46901. +/*******************************************************************************
  46902. +* mvSdmmcWinSet - Set SDMMC target address window
  46903. +*
  46904. +* DESCRIPTION:
  46905. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  46906. +* address window, also known as address decode window.
  46907. +* After setting this target window, the SDMMC will be able to access the
  46908. +* target within the address window.
  46909. +*
  46910. +* INPUT:
  46911. +* winNum - SDMMC target address decode window number.
  46912. +* pAddrDecWin - SDMMC target window data structure.
  46913. +*
  46914. +* OUTPUT:
  46915. +* None.
  46916. +*
  46917. +* RETURN:
  46918. +* MV_ERROR if address window overlapps with other address decode windows.
  46919. +* MV_BAD_PARAM if base address is invalid parameter or target is
  46920. +* unknown.
  46921. +*
  46922. +*******************************************************************************/
  46923. +MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
  46924. +{
  46925. + MV_TARGET_ATTRIB targetAttribs;
  46926. + MV_DEC_REGS decRegs;
  46927. +
  46928. + /* Parameter checking */
  46929. + if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
  46930. + {
  46931. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  46932. + return MV_BAD_PARAM;
  46933. + }
  46934. +
  46935. + /* Check if the requested window overlapps with current windows */
  46936. + if (MV_TRUE == sdmmcWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))
  46937. + {
  46938. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  46939. + return MV_ERROR;
  46940. + }
  46941. +
  46942. + /* check if address is aligned to the size */
  46943. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  46944. + {
  46945. + mvOsPrintf("mvSdmmcWinSet:Error setting SDMMC window %d to "\
  46946. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  46947. + winNum,
  46948. + mvCtrlTargetNameGet(pAddrDecWin->target),
  46949. + pAddrDecWin->addrWin.baseLow,
  46950. + pAddrDecWin->addrWin.size);
  46951. + return MV_ERROR;
  46952. + }
  46953. +
  46954. + decRegs.baseReg = 0;
  46955. + decRegs.sizeReg = 0;
  46956. +
  46957. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  46958. + {
  46959. + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
  46960. + return MV_ERROR;
  46961. + }
  46962. +
  46963. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  46964. +
  46965. + /* set attributes */
  46966. + decRegs.sizeReg &= ~MV_SDMMC_WIN_ATTR_MASK;
  46967. + decRegs.sizeReg |= (targetAttribs.attrib << MV_SDMMC_WIN_ATTR_OFFSET);
  46968. +
  46969. + /* set target ID */
  46970. + decRegs.sizeReg &= ~MV_SDMMC_WIN_TARGET_MASK;
  46971. + decRegs.sizeReg |= (targetAttribs.targetId << MV_SDMMC_WIN_TARGET_OFFSET);
  46972. +
  46973. + if (pAddrDecWin->enable == MV_TRUE)
  46974. + {
  46975. + decRegs.sizeReg |= MV_SDMMC_WIN_ENABLE_MASK;
  46976. + }
  46977. + else
  46978. + {
  46979. + decRegs.sizeReg &= ~MV_SDMMC_WIN_ENABLE_MASK;
  46980. + }
  46981. +
  46982. + MV_REG_WRITE( MV_SDMMC_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);
  46983. + MV_REG_WRITE( MV_SDMMC_WIN_BASE_REG(dev, winNum), decRegs.baseReg);
  46984. +
  46985. + return MV_OK;
  46986. +}
  46987. +
  46988. +/*******************************************************************************
  46989. +* mvSdmmcWinGet - Get SDMMC peripheral target address window.
  46990. +*
  46991. +* DESCRIPTION:
  46992. +* Get SDMMC peripheral target address window.
  46993. +*
  46994. +* INPUT:
  46995. +* winNum - SDMMC target address decode window number.
  46996. +*d
  46997. +* OUTPUT:
  46998. +* pAddrDecWin - SDMMC target window data structure.
  46999. +*
  47000. +* RETURN:
  47001. +* MV_ERROR if register parameters are invalid.
  47002. +*
  47003. +*******************************************************************************/
  47004. +MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
  47005. +{
  47006. + MV_DEC_REGS decRegs;
  47007. + MV_TARGET_ATTRIB targetAttrib;
  47008. +
  47009. + /* Parameter checking */
  47010. + if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
  47011. + {
  47012. + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
  47013. + __FUNCTION__, dev, winNum);
  47014. + return MV_NOT_SUPPORTED;
  47015. + }
  47016. +
  47017. + decRegs.baseReg = MV_REG_READ( MV_SDMMC_WIN_BASE_REG(dev, winNum) );
  47018. + decRegs.sizeReg = MV_REG_READ( MV_SDMMC_WIN_CTRL_REG(dev, winNum) );
  47019. +
  47020. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
  47021. + {
  47022. + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
  47023. + return MV_ERROR;
  47024. + }
  47025. +
  47026. + /* attrib and targetId */
  47027. + targetAttrib.attrib = (decRegs.sizeReg & MV_SDMMC_WIN_ATTR_MASK) >>
  47028. + MV_SDMMC_WIN_ATTR_OFFSET;
  47029. + targetAttrib.targetId = (decRegs.sizeReg & MV_SDMMC_WIN_TARGET_MASK) >>
  47030. + MV_SDMMC_WIN_TARGET_OFFSET;
  47031. +
  47032. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  47033. +
  47034. + /* Check if window is enabled */
  47035. + if(decRegs.sizeReg & MV_SDMMC_WIN_ENABLE_MASK)
  47036. + {
  47037. + pAddrDecWin->enable = MV_TRUE;
  47038. + }
  47039. + else
  47040. + {
  47041. + pAddrDecWin->enable = MV_FALSE;
  47042. + }
  47043. + return MV_OK;
  47044. +}
  47045. +/*******************************************************************************
  47046. +* mvSdmmcAddrDecShow - Print the SDMMC address decode map.
  47047. +*
  47048. +* DESCRIPTION:
  47049. +* This function print the SDMMC address decode map.
  47050. +*
  47051. +* INPUT:
  47052. +* None.
  47053. +*
  47054. +* OUTPUT:
  47055. +* None.
  47056. +*
  47057. +* RETURN:
  47058. +* None.
  47059. +*
  47060. +*******************************************************************************/
  47061. +MV_VOID mvSdmmcAddrDecShow(MV_VOID)
  47062. +{
  47063. +
  47064. + MV_SDMMC_DEC_WIN win;
  47065. + int i,j=0;
  47066. +
  47067. +
  47068. +
  47069. + if (MV_FALSE == mvCtrlPwrClckGet(SDIO_UNIT_ID, 0))
  47070. + return;
  47071. +
  47072. + mvOsOutput( "\n" );
  47073. + mvOsOutput( "SDMMC %d:\n", j );
  47074. + mvOsOutput( "----\n" );
  47075. +
  47076. + for( i = 0; i < MV_SDMMC_MAX_ADDR_DECODE_WIN; i++ )
  47077. + {
  47078. + memset( &win, 0, sizeof(MV_SDMMC_DEC_WIN) );
  47079. +
  47080. + mvOsOutput( "win%d - ", i );
  47081. +
  47082. + if( mvSdmmcWinGet(j, i, &win ) == MV_OK )
  47083. + {
  47084. + if( win.enable )
  47085. + {
  47086. + mvOsOutput( "%s base %08x, ",
  47087. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  47088. + mvOsOutput( "...." );
  47089. +
  47090. + mvSizePrint( win.addrWin.size );
  47091. +
  47092. + mvOsOutput( "\n" );
  47093. + }
  47094. + else
  47095. + mvOsOutput( "disable\n" );
  47096. + }
  47097. + }
  47098. +}
  47099. +
  47100. +
  47101. +/*******************************************************************************
  47102. +* mvSdmmcWinInit - Initialize the integrated SDMMC target address window.
  47103. +*
  47104. +* DESCRIPTION:
  47105. +* Initialize the SDMMC peripheral target address window.
  47106. +*
  47107. +* INPUT:
  47108. +*
  47109. +*
  47110. +* OUTPUT:
  47111. +*
  47112. +*
  47113. +* RETURN:
  47114. +* MV_ERROR if register parameters are invalid.
  47115. +*
  47116. +*******************************************************************************/
  47117. +MV_STATUS mvSdmmcWinInit(MV_VOID)
  47118. +{
  47119. + int winNum;
  47120. + MV_SDMMC_DEC_WIN sdmmcWin;
  47121. + MV_CPU_DEC_WIN cpuAddrDecWin;
  47122. + MV_U32 status, winPrioIndex = 0;
  47123. +
  47124. + /* Initiate Sdmmc address decode */
  47125. +
  47126. + /* First disable all address decode windows */
  47127. + for(winNum = 0; winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN; winNum++)
  47128. + {
  47129. + MV_U32 regVal = MV_REG_READ(MV_SDMMC_WIN_CTRL_REG(0, winNum));
  47130. + regVal &= ~MV_SDMMC_WIN_ENABLE_MASK;
  47131. + MV_REG_WRITE(MV_SDMMC_WIN_CTRL_REG(0, winNum), regVal);
  47132. + }
  47133. +
  47134. + winNum = 0;
  47135. + while( (sdmmcAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
  47136. + (winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN) )
  47137. + {
  47138. + /* first get attributes from CPU If */
  47139. + status = mvCpuIfTargetWinGet(sdmmcAddrDecPrioTab[winPrioIndex],
  47140. + &cpuAddrDecWin);
  47141. +
  47142. + if(MV_NO_SUCH == status)
  47143. + {
  47144. + winPrioIndex++;
  47145. + continue;
  47146. + }
  47147. + if (MV_OK != status)
  47148. + {
  47149. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  47150. + return MV_ERROR;
  47151. + }
  47152. +
  47153. + if (cpuAddrDecWin.enable == MV_TRUE)
  47154. + {
  47155. + sdmmcWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  47156. + sdmmcWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  47157. + sdmmcWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  47158. + sdmmcWin.enable = MV_TRUE;
  47159. + sdmmcWin.target = sdmmcAddrDecPrioTab[winPrioIndex];
  47160. +
  47161. + if(MV_OK != mvSdmmcWinSet(0/*dev*/, winNum, &sdmmcWin))
  47162. + {
  47163. + return MV_ERROR;
  47164. + }
  47165. + winNum++;
  47166. + }
  47167. + winPrioIndex++;
  47168. + }
  47169. + return MV_OK;
  47170. +}
  47171. +
  47172. +
  47173. +
  47174. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h
  47175. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h 1970-01-01 01:00:00.000000000 +0100
  47176. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h 2010-11-09 20:28:08.891243103 +0100
  47177. @@ -0,0 +1,125 @@
  47178. +
  47179. +/*******************************************************************************
  47180. +Copyright (C) Marvell International Ltd. and its affiliates
  47181. +
  47182. +This software file (the "File") is owned and distributed by Marvell
  47183. +International Ltd. and/or its affiliates ("Marvell") under the following
  47184. +alternative licensing terms. Once you have made an election to distribute the
  47185. +File under one of the following license alternatives, please (i) delete this
  47186. +introductory statement regarding license alternatives, (ii) delete the two
  47187. +license alternatives that you have not elected to use and (iii) preserve the
  47188. +Marvell copyright notice above.
  47189. +
  47190. +********************************************************************************
  47191. +Marvell Commercial License Option
  47192. +
  47193. +If you received this File from Marvell and you have entered into a commercial
  47194. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47195. +to you under the terms of the applicable Commercial License.
  47196. +
  47197. +********************************************************************************
  47198. +Marvell GPL License Option
  47199. +
  47200. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47201. +modify this File in accordance with the terms and conditions of the General
  47202. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47203. +available along with the File in the license.txt file or by writing to the Free
  47204. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47205. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47206. +
  47207. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47208. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47209. +DISCLAIMED. The GPL License provides additional details about this warranty
  47210. +disclaimer.
  47211. +********************************************************************************
  47212. +Marvell BSD License Option
  47213. +
  47214. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47215. +modify this File under the following licensing terms.
  47216. +Redistribution and use in source and binary forms, with or without modification,
  47217. +are permitted provided that the following conditions are met:
  47218. +
  47219. + * Redistributions of source code must retain the above copyright notice,
  47220. + this list of conditions and the following disclaimer.
  47221. +
  47222. + * Redistributions in binary form must reproduce the above copyright
  47223. + notice, this list of conditions and the following disclaimer in the
  47224. + documentation and/or other materials provided with the distribution.
  47225. +
  47226. + * Neither the name of Marvell nor the names of its contributors may be
  47227. + used to endorse or promote products derived from this software without
  47228. + specific prior written permission.
  47229. +
  47230. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47231. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47232. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47233. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47234. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47235. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47236. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47237. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47238. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47239. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47240. +
  47241. +*******************************************************************************/
  47242. +#ifndef __INCMVSysSdmmcAddrDech
  47243. +#define __INCMVSysSdmmcAddrDech
  47244. +
  47245. +#include "mvCommon.h"
  47246. +#include "ctrlEnv/mvCtrlEnvLib.h"
  47247. +#include "ctrlEnv/sys/mvCpuIf.h"
  47248. +
  47249. +
  47250. +#ifdef __cplusplus
  47251. +extern "C" {
  47252. +#endif
  47253. +
  47254. +typedef struct _mvSdmmcDecWin
  47255. +{
  47256. + MV_TARGET target;
  47257. + MV_ADDR_WIN addrWin; /* An address window*/
  47258. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47259. +
  47260. +} MV_SDMMC_DEC_WIN;
  47261. +
  47262. +
  47263. +#define MV_SDMMC_MAX_ADDR_DECODE_WIN 4
  47264. +
  47265. +#define MV_SDMMC_WIN_CTRL_REG(dev, win) (MV_SDIO_REG_BASE + 0x108 + ((win)<<3))
  47266. +#define MV_SDMMC_WIN_BASE_REG(dev, win) (MV_SDIO_REG_BASE + 0x10c + ((win)<<3))
  47267. +
  47268. +
  47269. +/* BITs in Windows 0-3 Control and Base Registers */
  47270. +#define MV_SDMMC_WIN_ENABLE_BIT 0
  47271. +#define MV_SDMMC_WIN_ENABLE_MASK (1<<MV_SDMMC_WIN_ENABLE_BIT)
  47272. +
  47273. +#define MV_SDMMC_WIN_TARGET_OFFSET 4
  47274. +#define MV_SDMMC_WIN_TARGET_MASK (0xF<<MV_SDMMC_WIN_TARGET_OFFSET)
  47275. +
  47276. +#define MV_SDMMC_WIN_ATTR_OFFSET 8
  47277. +#define MV_SDMMC_WIN_ATTR_MASK (0xFF<<MV_SDMMC_WIN_ATTR_OFFSET)
  47278. +
  47279. +#define MV_SDMMC_WIN_SIZE_OFFSET 16
  47280. +#define MV_SDMMC_WIN_SIZE_MASK (0xFFFF<<MV_SDMMC_WIN_SIZE_OFFSET)
  47281. +
  47282. +#define MV_SDMMC_WIN_BASE_OFFSET 16
  47283. +#define MV_SDMMC_WIN_BASE_MASK (0xFFFF<<MV_SDMMC_WIN_BASE_OFFSET)
  47284. +
  47285. +MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);
  47286. +MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);
  47287. +MV_STATUS mvSdmmcWinByTargetGet(MV_TARGET target, MV_SDMMC_DEC_WIN *pAddrDecWin);
  47288. +MV_STATUS mvSdmmcWinInit(MV_VOID);
  47289. +MV_VOID mvSdmmcAddrDecShow(MV_VOID);
  47290. +
  47291. +
  47292. +#ifdef __cplusplus
  47293. +}
  47294. +#endif
  47295. +
  47296. +
  47297. +#endif
  47298. +
  47299. +
  47300. +
  47301. +
  47302. +
  47303. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c
  47304. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c 1970-01-01 01:00:00.000000000 +0100
  47305. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c 2010-11-09 20:28:09.164485759 +0100
  47306. @@ -0,0 +1,462 @@
  47307. +/*******************************************************************************
  47308. +Copyright (C) Marvell International Ltd. and its affiliates
  47309. +
  47310. +This software file (the "File") is owned and distributed by Marvell
  47311. +International Ltd. and/or its affiliates ("Marvell") under the following
  47312. +alternative licensing terms. Once you have made an election to distribute the
  47313. +File under one of the following license alternatives, please (i) delete this
  47314. +introductory statement regarding license alternatives, (ii) delete the two
  47315. +license alternatives that you have not elected to use and (iii) preserve the
  47316. +Marvell copyright notice above.
  47317. +
  47318. +********************************************************************************
  47319. +Marvell Commercial License Option
  47320. +
  47321. +If you received this File from Marvell and you have entered into a commercial
  47322. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47323. +to you under the terms of the applicable Commercial License.
  47324. +
  47325. +********************************************************************************
  47326. +Marvell GPL License Option
  47327. +
  47328. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47329. +modify this File in accordance with the terms and conditions of the General
  47330. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47331. +available along with the File in the license.txt file or by writing to the Free
  47332. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47333. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47334. +
  47335. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47336. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47337. +DISCLAIMED. The GPL License provides additional details about this warranty
  47338. +disclaimer.
  47339. +********************************************************************************
  47340. +Marvell BSD License Option
  47341. +
  47342. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47343. +modify this File under the following licensing terms.
  47344. +Redistribution and use in source and binary forms, with or without modification,
  47345. +are permitted provided that the following conditions are met:
  47346. +
  47347. + * Redistributions of source code must retain the above copyright notice,
  47348. + this list of conditions and the following disclaimer.
  47349. +
  47350. + * Redistributions in binary form must reproduce the above copyright
  47351. + notice, this list of conditions and the following disclaimer in the
  47352. + documentation and/or other materials provided with the distribution.
  47353. +
  47354. + * Neither the name of Marvell nor the names of its contributors may be
  47355. + used to endorse or promote products derived from this software without
  47356. + specific prior written permission.
  47357. +
  47358. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47359. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47360. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47361. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47362. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47363. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47364. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47365. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47366. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47367. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47368. +
  47369. +*******************************************************************************/
  47370. +
  47371. +#include "mvSysTdm.h"
  47372. +
  47373. +
  47374. +/* defines */
  47375. +#ifdef MV_DEBUG
  47376. + #define DB(x) x
  47377. +#else
  47378. + #define DB(x)
  47379. +#endif
  47380. +
  47381. +static MV_TARGET tdmAddrDecPrioTap[] =
  47382. +{
  47383. + PEX0_MEM,
  47384. + SDRAM_CS0,
  47385. + SDRAM_CS1,
  47386. + SDRAM_CS2,
  47387. + SDRAM_CS3,
  47388. + DEVICE_CS0,
  47389. + DEVICE_CS1,
  47390. + DEVICE_CS2,
  47391. + DEV_BOOCS,
  47392. + PEX0_IO,
  47393. + TBL_TERM
  47394. +};
  47395. +
  47396. +static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  47397. +
  47398. +/*******************************************************************************
  47399. +* mvTdmWinInit - Initialize TDM address decode windows
  47400. +*
  47401. +* DESCRIPTION:
  47402. +* This function initialize TDM window decode unit. It set the
  47403. +* default address decode
  47404. +* windows of the unit.
  47405. +*
  47406. +* INPUT:
  47407. +* None.
  47408. +*
  47409. +* OUTPUT:
  47410. +* None.
  47411. +*
  47412. +* RETURN:
  47413. +* MV_ERROR if setting fail.
  47414. +*******************************************************************************/
  47415. +
  47416. +MV_STATUS mvTdmWinInit(void)
  47417. +{
  47418. + MV_U32 winNum;
  47419. + MV_U32 winPrioIndex = 0;
  47420. + MV_CPU_DEC_WIN cpuAddrDecWin;
  47421. + MV_TDM_DEC_WIN tdmWin;
  47422. + MV_STATUS status;
  47423. +
  47424. + /*Disable all windows*/
  47425. + for (winNum = 0; winNum < TDM_MBUS_MAX_WIN; winNum++)
  47426. + {
  47427. + mvTdmWinEnable(winNum, MV_FALSE);
  47428. + }
  47429. +
  47430. + for (winNum = 0; ((tdmAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  47431. + (winNum < TDM_MBUS_MAX_WIN)); )
  47432. + {
  47433. + status = mvCpuIfTargetWinGet(tdmAddrDecPrioTap[winPrioIndex],
  47434. + &cpuAddrDecWin);
  47435. + if (MV_NO_SUCH == status)
  47436. + {
  47437. + winPrioIndex++;
  47438. + continue;
  47439. + }
  47440. + if (MV_OK != status)
  47441. + {
  47442. + mvOsPrintf("mvTdmInit: ERR. mvCpuIfTargetWinGet failed\n");
  47443. + return MV_ERROR;
  47444. + }
  47445. +
  47446. + if (cpuAddrDecWin.enable == MV_TRUE)
  47447. + {
  47448. + tdmWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  47449. + tdmWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  47450. + tdmWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  47451. + tdmWin.enable = MV_TRUE;
  47452. + tdmWin.target = tdmAddrDecPrioTap[winPrioIndex];
  47453. + if (MV_OK != mvTdmWinSet(winNum, &tdmWin))
  47454. + {
  47455. + return MV_ERROR;
  47456. + }
  47457. + winNum++;
  47458. + }
  47459. + winPrioIndex++;
  47460. + }
  47461. + return MV_OK;
  47462. +}
  47463. +
  47464. +/*******************************************************************************
  47465. +* mvTdmWinSet - Set TDM target address window
  47466. +*
  47467. +* DESCRIPTION:
  47468. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  47469. +* address window, also known as address decode window.
  47470. +* After setting this target window, the TDM will be able to access the
  47471. +* target within the address window.
  47472. +*
  47473. +* INPUT:
  47474. +* winNum - TDM to target address decode window number.
  47475. +* pAddrDecWin - TDM target window data structure.
  47476. +*
  47477. +* OUTPUT:
  47478. +* None.
  47479. +*
  47480. +* RETURN:
  47481. +* MV_ERROR if address window overlapps with other address decode windows.
  47482. +* MV_BAD_PARAM if base address is invalid parameter or target is
  47483. +* unknown.
  47484. +*
  47485. +*******************************************************************************/
  47486. +
  47487. +MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
  47488. +{
  47489. + MV_TARGET_ATTRIB targetAttribs;
  47490. + MV_DEC_REGS decRegs;
  47491. + MV_U32 ctrlReg = 0;
  47492. +
  47493. + /* Parameter checking */
  47494. + if (winNum >= TDM_MBUS_MAX_WIN)
  47495. + {
  47496. + mvOsPrintf("mvTdmWinSet: ERR. Invalid win num %d\n",winNum);
  47497. + return MV_BAD_PARAM;
  47498. + }
  47499. +
  47500. + /* Check if the requested window overlapps with current windows */
  47501. + if (MV_TRUE == tdmWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
  47502. + {
  47503. + mvOsPrintf("mvTdmWinSet: ERR. Window %d overlap\n", winNum);
  47504. + return MV_ERROR;
  47505. + }
  47506. +
  47507. + /* check if address is aligned to the size */
  47508. + if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  47509. + {
  47510. + mvOsPrintf("mvTdmWinSet: Error setting TDM window %d to "\
  47511. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  47512. + winNum,
  47513. + mvCtrlTargetNameGet(pAddrDecWin->target),
  47514. + pAddrDecWin->addrWin.baseLow,
  47515. + pAddrDecWin->addrWin.size);
  47516. + return MV_ERROR;
  47517. + }
  47518. +
  47519. + decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
  47520. + decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
  47521. +
  47522. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  47523. + {
  47524. + mvOsPrintf("mvTdmWinSet: mvCtrlAddrDecToReg Failed\n");
  47525. + return MV_ERROR;
  47526. + }
  47527. +
  47528. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  47529. +
  47530. + /* for the safe side we disable the window before writing the new
  47531. + values */
  47532. + mvTdmWinEnable(winNum, MV_FALSE);
  47533. +
  47534. + ctrlReg |= (targetAttribs.attrib << TDM_WIN_ATTRIB_OFFS);
  47535. + ctrlReg |= (targetAttribs.targetId << TDM_WIN_TARGET_OFFS);
  47536. + ctrlReg |= (decRegs.sizeReg & TDM_WIN_SIZE_MASK);
  47537. +
  47538. + /* Write to address base and control registers */
  47539. + MV_REG_WRITE(TDM_WIN_BASE_REG(winNum), decRegs.baseReg);
  47540. + MV_REG_WRITE(TDM_WIN_CTRL_REG(winNum), ctrlReg);
  47541. + /* Enable address decode target window */
  47542. + if (pAddrDecWin->enable == MV_TRUE)
  47543. + {
  47544. + mvTdmWinEnable(winNum, MV_TRUE);
  47545. + }
  47546. + return MV_OK;
  47547. +}
  47548. +
  47549. +/*******************************************************************************
  47550. +* mvTdmWinGet - Get peripheral target address window.
  47551. +*
  47552. +* DESCRIPTION:
  47553. +* Get TDM peripheral target address window.
  47554. +*
  47555. +* INPUT:
  47556. +* winNum - TDM to target address decode window number.
  47557. +*
  47558. +* OUTPUT:
  47559. +* pAddrDecWin - TDM target window data structure.
  47560. +*
  47561. +* RETURN:
  47562. +* MV_ERROR if register parameters are invalid.
  47563. +*
  47564. +*******************************************************************************/
  47565. +
  47566. +MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
  47567. +{
  47568. +
  47569. + MV_DEC_REGS decRegs;
  47570. + MV_TARGET_ATTRIB targetAttrib;
  47571. +
  47572. + /* Parameter checking */
  47573. + if (winNum >= TDM_MBUS_MAX_WIN)
  47574. + {
  47575. + mvOsPrintf("mvTdmWinGet: ERR. Invalid winNum %d\n", winNum);
  47576. + return MV_NOT_SUPPORTED;
  47577. + }
  47578. +
  47579. + decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
  47580. + decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
  47581. +
  47582. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  47583. + {
  47584. + mvOsPrintf("mvTdmWinGet: mvCtrlRegToAddrDec Failed \n");
  47585. + return MV_ERROR;
  47586. + }
  47587. +
  47588. + /* attrib and targetId */
  47589. + targetAttrib.attrib =
  47590. + (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ATTRIB_MASK) >> TDM_WIN_ATTRIB_OFFS;
  47591. + targetAttrib.targetId =
  47592. + (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_TARGET_MASK) >> TDM_WIN_TARGET_OFFS;
  47593. +
  47594. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  47595. +
  47596. + /* Check if window is enabled */
  47597. + if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
  47598. + {
  47599. + pAddrDecWin->enable = MV_TRUE;
  47600. + }
  47601. + else
  47602. + {
  47603. + pAddrDecWin->enable = MV_FALSE;
  47604. + }
  47605. +
  47606. + return MV_OK;
  47607. +}
  47608. +
  47609. +/*******************************************************************************
  47610. +* mvTdmWinEnable - Enable/disable a TDM to target address window
  47611. +*
  47612. +* DESCRIPTION:
  47613. +* This function enable/disable a TDM to target address window.
  47614. +* According to parameter 'enable' the routine will enable the
  47615. +* window, thus enabling TDM accesses (before enabling the window it is
  47616. +* tested for overlapping). Otherwise, the window will be disabled.
  47617. +*
  47618. +* INPUT:
  47619. +* winNum - TDM to target address decode window number.
  47620. +* enable - Enable/disable parameter.
  47621. +*
  47622. +* OUTPUT:
  47623. +* N/A
  47624. +*
  47625. +* RETURN:
  47626. +* MV_ERROR if decode window number was wrong or enabled window overlapps.
  47627. +*
  47628. +*******************************************************************************/
  47629. +MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable)
  47630. +{
  47631. + MV_TDM_DEC_WIN addrDecWin;
  47632. +
  47633. + if (MV_TRUE == enable)
  47634. + {
  47635. + if (winNum >= TDM_MBUS_MAX_WIN)
  47636. + {
  47637. + mvOsPrintf("mvTdmWinEnable:ERR. Invalid winNum%d\n",winNum);
  47638. + return MV_ERROR;
  47639. + }
  47640. +
  47641. + /* First check for overlap with other enabled windows */
  47642. + /* Get current window */
  47643. + if (MV_OK != mvTdmWinGet(winNum, &addrDecWin))
  47644. + {
  47645. + mvOsPrintf("mvTdmWinEnable:ERR. targetWinGet fail\n");
  47646. + return MV_ERROR;
  47647. + }
  47648. + /* Check for overlapping */
  47649. + if (MV_FALSE == tdmWinOverlapDetect(winNum, &(addrDecWin.addrWin)))
  47650. + {
  47651. + /* No Overlap. Enable address decode target window */
  47652. + MV_REG_BIT_SET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
  47653. + }
  47654. + else
  47655. + { /* Overlap detected */
  47656. + mvOsPrintf("mvTdmWinEnable:ERR. Overlap detected\n");
  47657. + return MV_ERROR;
  47658. + }
  47659. + }
  47660. + else
  47661. + {
  47662. + MV_REG_BIT_RESET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
  47663. + }
  47664. + return MV_OK;
  47665. +}
  47666. +
  47667. +
  47668. +/*******************************************************************************
  47669. +* tdmWinOverlapDetect - Detect TDM address windows overlapping
  47670. +*
  47671. +* DESCRIPTION:
  47672. +* An unpredicted behaviour is expected in case TDM address decode
  47673. +* windows overlapps.
  47674. +* This function detects TDM address decode windows overlapping of a
  47675. +* specified window. The function does not check the window itself for
  47676. +* overlapping. The function also skipps disabled address decode windows.
  47677. +*
  47678. +* INPUT:
  47679. +* winNum - address decode window number.
  47680. +* pAddrDecWin - An address decode window struct.
  47681. +*
  47682. +* OUTPUT:
  47683. +* None.
  47684. +*
  47685. +* RETURN:
  47686. +* MV_TRUE if the given address window overlap current address
  47687. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  47688. +* from registers.
  47689. +*
  47690. +*******************************************************************************/
  47691. +static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  47692. +{
  47693. + MV_U32 winNumIndex;
  47694. + MV_TDM_DEC_WIN addrDecWin;
  47695. +
  47696. + for (winNumIndex = 0; winNumIndex < TDM_MBUS_MAX_WIN; winNumIndex++)
  47697. + {
  47698. + /* Do not check window itself */
  47699. + if (winNumIndex == winNum)
  47700. + {
  47701. + continue;
  47702. + }
  47703. + /* Do not check disabled windows */
  47704. + if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
  47705. + {
  47706. + /* Get window parameters */
  47707. + if (MV_OK != mvTdmWinGet(winNumIndex, &addrDecWin))
  47708. + {
  47709. + DB(mvOsPrintf("dmaWinOverlapDetect: ERR. TargetWinGet failed\n"));
  47710. + return MV_ERROR;
  47711. + }
  47712. +
  47713. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  47714. + {
  47715. + return MV_TRUE;
  47716. + }
  47717. + }
  47718. + }
  47719. + return MV_FALSE;
  47720. +}
  47721. +
  47722. +/*******************************************************************************
  47723. +* mvTdmAddrDecShow - Print the TDM address decode map.
  47724. +*
  47725. +* DESCRIPTION:
  47726. +* This function print the TDM address decode map.
  47727. +*
  47728. +* INPUT:
  47729. +* None.
  47730. +*
  47731. +* OUTPUT:
  47732. +* None.
  47733. +*
  47734. +* RETURN:
  47735. +* None.
  47736. +*
  47737. +*******************************************************************************/
  47738. +MV_VOID mvTdmAddrDecShow(MV_VOID)
  47739. +{
  47740. + MV_TDM_DEC_WIN win;
  47741. + int i;
  47742. +
  47743. + mvOsOutput( "\n" );
  47744. + mvOsOutput( "TDM:\n" );
  47745. + mvOsOutput( "----\n" );
  47746. +
  47747. + for( i = 0; i < TDM_MBUS_MAX_WIN; i++ )
  47748. + {
  47749. + memset( &win, 0, sizeof(MV_TDM_DEC_WIN) );
  47750. +
  47751. + mvOsOutput( "win%d - ", i );
  47752. +
  47753. + if (mvTdmWinGet(i, &win ) == MV_OK )
  47754. + {
  47755. + if( win.enable )
  47756. + {
  47757. + mvOsOutput( "%s base %08x, ",
  47758. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow);
  47759. + mvOsOutput( "...." );
  47760. + mvSizePrint( win.addrWin.size );
  47761. + mvOsOutput( "\n" );
  47762. + }
  47763. + else
  47764. + mvOsOutput( "disable\n" );
  47765. + }
  47766. + }
  47767. +}
  47768. +
  47769. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h
  47770. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h 1970-01-01 01:00:00.000000000 +0100
  47771. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h 2010-11-09 20:28:09.471497270 +0100
  47772. @@ -0,0 +1,106 @@
  47773. +/*******************************************************************************
  47774. +Copyright (C) Marvell International Ltd. and its affiliates
  47775. +
  47776. +This software file (the "File") is owned and distributed by Marvell
  47777. +International Ltd. and/or its affiliates ("Marvell") under the following
  47778. +alternative licensing terms. Once you have made an election to distribute the
  47779. +File under one of the following license alternatives, please (i) delete this
  47780. +introductory statement regarding license alternatives, (ii) delete the two
  47781. +license alternatives that you have not elected to use and (iii) preserve the
  47782. +Marvell copyright notice above.
  47783. +
  47784. +********************************************************************************
  47785. +Marvell Commercial License Option
  47786. +
  47787. +If you received this File from Marvell and you have entered into a commercial
  47788. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47789. +to you under the terms of the applicable Commercial License.
  47790. +
  47791. +********************************************************************************
  47792. +Marvell GPL License Option
  47793. +
  47794. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47795. +modify this File in accordance with the terms and conditions of the General
  47796. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47797. +available along with the File in the license.txt file or by writing to the Free
  47798. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47799. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47800. +
  47801. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47802. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47803. +DISCLAIMED. The GPL License provides additional details about this warranty
  47804. +disclaimer.
  47805. +********************************************************************************
  47806. +Marvell BSD License Option
  47807. +
  47808. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47809. +modify this File under the following licensing terms.
  47810. +Redistribution and use in source and binary forms, with or without modification,
  47811. +are permitted provided that the following conditions are met:
  47812. +
  47813. + * Redistributions of source code must retain the above copyright notice,
  47814. + this list of conditions and the following disclaimer.
  47815. +
  47816. + * Redistributions in binary form must reproduce the above copyright
  47817. + notice, this list of conditions and the following disclaimer in the
  47818. + documentation and/or other materials provided with the distribution.
  47819. +
  47820. + * Neither the name of Marvell nor the names of its contributors may be
  47821. + used to endorse or promote products derived from this software without
  47822. + specific prior written permission.
  47823. +
  47824. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47825. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47826. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47827. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47828. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47829. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47830. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47831. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47832. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47833. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47834. +
  47835. +*******************************************************************************/
  47836. +
  47837. +#ifndef __INCmvSysTdmh
  47838. +#define __INCmvSysTdmh
  47839. +
  47840. +#include "ctrlEnv/sys/mvCpuIf.h"
  47841. +#include "ctrlEnv/mvCtrlEnvLib.h"
  47842. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  47843. +
  47844. +typedef struct _mvTdmDecWin
  47845. +{
  47846. + MV_TARGET target;
  47847. + MV_ADDR_WIN addrWin; /* An address window*/
  47848. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47849. +} MV_TDM_DEC_WIN;
  47850. +
  47851. +MV_STATUS mvTdmWinInit(MV_VOID);
  47852. +MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);
  47853. +MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);
  47854. +MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable);
  47855. +MV_VOID mvTdmAddrDecShow(MV_VOID);
  47856. +
  47857. +
  47858. +#define TDM_MBUS_MAX_WIN 4
  47859. +#define TDM_WIN_CTRL_REG(win) ((TDM_REG_BASE + 0x4030) + (win<<4))
  47860. +#define TDM_WIN_BASE_REG(win) ((TDM_REG_BASE +0x4034) + (win<<4))
  47861. +
  47862. +/* TDM_WIN_CTRL_REG bits */
  47863. +#define TDM_WIN_ENABLE_OFFS 0
  47864. +#define TDM_WIN_ENABLE_MASK (1<<TDM_WIN_ENABLE_OFFS)
  47865. +#define TDM_WIN_ENABLE 1
  47866. +#define TDM_WIN_TARGET_OFFS 4
  47867. +#define TDM_WIN_TARGET_MASK (0xf<<TDM_WIN_TARGET_OFFS)
  47868. +#define TDM_WIN_ATTRIB_OFFS 8
  47869. +#define TDM_WIN_ATTRIB_MASK (0xff<<TDM_WIN_ATTRIB_OFFS)
  47870. +#define TDM_WIN_SIZE_OFFS 16
  47871. +#define TDM_WIN_SIZE_MASK (0xffff<<TDM_WIN_SIZE_OFFS)
  47872. +
  47873. +/* TDM_WIN_BASE_REG bits */
  47874. +#define TDM_BASE_OFFS 16
  47875. +#define TDM_BASE_MASK (0xffff<<TDM_BASE_OFFS)
  47876. +
  47877. +#endif /*__INCmvSysTdmh*/
  47878. +
  47879. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c
  47880. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c 1970-01-01 01:00:00.000000000 +0100
  47881. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c 2010-11-09 20:28:09.721570932 +0100
  47882. @@ -0,0 +1,591 @@
  47883. +/*******************************************************************************
  47884. +Copyright (C) Marvell International Ltd. and its affiliates
  47885. +
  47886. +This software file (the "File") is owned and distributed by Marvell
  47887. +International Ltd. and/or its affiliates ("Marvell") under the following
  47888. +alternative licensing terms. Once you have made an election to distribute the
  47889. +File under one of the following license alternatives, please (i) delete this
  47890. +introductory statement regarding license alternatives, (ii) delete the two
  47891. +license alternatives that you have not elected to use and (iii) preserve the
  47892. +Marvell copyright notice above.
  47893. +
  47894. +********************************************************************************
  47895. +Marvell Commercial License Option
  47896. +
  47897. +If you received this File from Marvell and you have entered into a commercial
  47898. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47899. +to you under the terms of the applicable Commercial License.
  47900. +
  47901. +********************************************************************************
  47902. +Marvell GPL License Option
  47903. +
  47904. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47905. +modify this File in accordance with the terms and conditions of the General
  47906. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47907. +available along with the File in the license.txt file or by writing to the Free
  47908. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47909. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47910. +
  47911. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47912. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47913. +DISCLAIMED. The GPL License provides additional details about this warranty
  47914. +disclaimer.
  47915. +********************************************************************************
  47916. +Marvell BSD License Option
  47917. +
  47918. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47919. +modify this File under the following licensing terms.
  47920. +Redistribution and use in source and binary forms, with or without modification,
  47921. +are permitted provided that the following conditions are met:
  47922. +
  47923. + * Redistributions of source code must retain the above copyright notice,
  47924. + this list of conditions and the following disclaimer.
  47925. +
  47926. + * Redistributions in binary form must reproduce the above copyright
  47927. + notice, this list of conditions and the following disclaimer in the
  47928. + documentation and/or other materials provided with the distribution.
  47929. +
  47930. + * Neither the name of Marvell nor the names of its contributors may be
  47931. + used to endorse or promote products derived from this software without
  47932. + specific prior written permission.
  47933. +
  47934. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47935. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47936. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47937. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47938. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47939. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47940. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47941. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47942. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47943. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47944. +
  47945. +*******************************************************************************/
  47946. +
  47947. +
  47948. +#include "ctrlEnv/sys/mvSysTs.h"
  47949. +
  47950. +
  47951. +typedef struct _mvTsuDecWin
  47952. +{
  47953. + MV_TARGET target;
  47954. + MV_ADDR_WIN addrWin; /* An address window*/
  47955. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47956. +
  47957. +}MV_TSU_DEC_WIN;
  47958. +
  47959. +
  47960. +MV_TARGET tsuAddrDecPrioTap[] =
  47961. +{
  47962. +#if defined(MV_INCLUDE_PEX)
  47963. + PEX0_MEM,
  47964. +#endif
  47965. +#if defined(MV_INCLUDE_PCI)
  47966. + PCI0_MEM,
  47967. +#endif
  47968. +#if defined(MV_INCLUDE_SDRAM_CS0)
  47969. + SDRAM_CS0,
  47970. +#endif
  47971. +#if defined(MV_INCLUDE_SDRAM_CS1)
  47972. + SDRAM_CS1,
  47973. +#endif
  47974. +#if defined(MV_INCLUDE_SDRAM_CS2)
  47975. + SDRAM_CS2,
  47976. +#endif
  47977. +#if defined(MV_INCLUDE_SDRAM_CS3)
  47978. + SDRAM_CS3,
  47979. +#endif
  47980. +#if defined(MV_INCLUDE_DEVICE_CS0)
  47981. + DEVICE_CS0,
  47982. +#endif
  47983. +#if defined(MV_INCLUDE_DEVICE_CS1)
  47984. + DEVICE_CS1,
  47985. +#endif
  47986. +#if defined(MV_INCLUDE_DEVICE_CS2)
  47987. + DEVICE_CS2,
  47988. +#endif
  47989. +#if defined(MV_INCLUDE_DEVICE_CS3)
  47990. + DEVICE_CS3,
  47991. +#endif
  47992. +#if defined(MV_INCLUDE_PEX)
  47993. + PEX0_IO,
  47994. +#endif
  47995. +#if defined(MV_INCLUDE_PCI)
  47996. + PCI0_IO,
  47997. +#endif
  47998. + TBL_TERM
  47999. +};
  48000. +
  48001. +static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  48002. +static MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);
  48003. +static MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);
  48004. +MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable);
  48005. +
  48006. +/*******************************************************************************
  48007. +* mvTsuWinInit
  48008. +*
  48009. +* DESCRIPTION:
  48010. +* Initialize the TSU unit address decode windows.
  48011. +*
  48012. +* INPUT:
  48013. +* None.
  48014. +* OUTPUT:
  48015. +* None.
  48016. +* RETURN:
  48017. +* MV_OK - on success,
  48018. +*
  48019. +*******************************************************************************/
  48020. +MV_STATUS mvTsuWinInit(void)
  48021. +{
  48022. + MV_U32 winNum, status, winPrioIndex=0;
  48023. + MV_TSU_DEC_WIN tsuWin;
  48024. + MV_CPU_DEC_WIN cpuAddrDecWin;
  48025. +
  48026. + /* First disable all address decode windows */
  48027. + for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)
  48028. + {
  48029. + MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),
  48030. + TSU_WIN_CTRL_EN_MASK);
  48031. + }
  48032. +
  48033. + /* Go through all windows in user table until table terminator */
  48034. + for(winNum = 0; ((tsuAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  48035. + (winNum < TSU_MAX_DECODE_WIN));)
  48036. + {
  48037. + /* first get attributes from CPU If */
  48038. + status = mvCpuIfTargetWinGet(tsuAddrDecPrioTap[winPrioIndex],
  48039. + &cpuAddrDecWin);
  48040. +
  48041. + if(MV_NO_SUCH == status)
  48042. + {
  48043. + winPrioIndex++;
  48044. + continue;
  48045. + }
  48046. + if(MV_OK != status)
  48047. + {
  48048. + mvOsPrintf("mvTsuWinInit: ERR. mvCpuIfTargetWinGet failed\n");
  48049. + return MV_ERROR;
  48050. + }
  48051. +
  48052. + if (cpuAddrDecWin.enable == MV_TRUE)
  48053. + {
  48054. + tsuWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  48055. + tsuWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  48056. + tsuWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  48057. + tsuWin.enable = MV_TRUE;
  48058. + tsuWin.target = tsuAddrDecPrioTap[winPrioIndex];
  48059. +
  48060. + if(MV_OK != mvTsuWinSet(winNum, &tsuWin))
  48061. + {
  48062. + mvOsPrintf("mvTsuWinInit: ERR. mvTsuWinSet failed winNum=%d\n",
  48063. + winNum);
  48064. + return MV_ERROR;
  48065. + }
  48066. + winNum++;
  48067. + }
  48068. + winPrioIndex ++;
  48069. + }
  48070. +
  48071. + return MV_OK;
  48072. +}
  48073. +
  48074. +
  48075. +/*******************************************************************************
  48076. +* mvTsuWinSet
  48077. +*
  48078. +* DESCRIPTION:
  48079. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  48080. +* address window, also known as address decode window.
  48081. +* After setting this target window, the TSU will be able to access the
  48082. +* target within the address window.
  48083. +*
  48084. +* INPUT:
  48085. +* winNum - TSU to target address decode window number.
  48086. +* pAddrDecWin - TSU target window data structure.
  48087. +*
  48088. +* OUTPUT:
  48089. +* None.
  48090. +*
  48091. +* RETURN:
  48092. +* MV_ERROR - if address window overlapps with other address decode
  48093. +* windows.
  48094. +* MV_BAD_PARAM - if base address is invalid parameter or target is
  48095. +* unknown.
  48096. +*
  48097. +*******************************************************************************/
  48098. +MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)
  48099. +{
  48100. + MV_TARGET_ATTRIB targetAttribs;
  48101. + MV_DEC_REGS decRegs;
  48102. +
  48103. + /* Parameter checking */
  48104. + if(winNum >= TSU_MAX_DECODE_WIN)
  48105. + {
  48106. + mvOsPrintf("mvTsuWinSet: ERR. Invalid win num %d\n",winNum);
  48107. + return MV_BAD_PARAM;
  48108. + }
  48109. +
  48110. + /* Check if the requested window overlapps with current windows */
  48111. + if(MV_TRUE == tsuWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
  48112. + {
  48113. + mvOsPrintf("mvTsuWinSet: ERR. Window %d overlap\n", winNum);
  48114. + return MV_ERROR;
  48115. + }
  48116. +
  48117. + /* check if address is aligned to the size */
  48118. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow,pAddrDecWin->addrWin.size))
  48119. + {
  48120. + mvOsPrintf("mvTsuWinSet: Error setting TSU window %d to target "
  48121. + "%s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  48122. + winNum, mvCtrlTargetNameGet(pAddrDecWin->target),
  48123. + pAddrDecWin->addrWin.baseLow,
  48124. + pAddrDecWin->addrWin.size);
  48125. + return MV_ERROR;
  48126. + }
  48127. +
  48128. + decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));
  48129. + decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));
  48130. +
  48131. + if(MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  48132. + {
  48133. + mvOsPrintf("mvTsuWinSet: mvCtrlAddrDecToReg Failed\n");
  48134. + return MV_ERROR;
  48135. + }
  48136. +
  48137. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  48138. +
  48139. + /* set attributes */
  48140. + decRegs.sizeReg &= ~TSU_WIN_CTRL_ATTR_MASK;
  48141. + decRegs.sizeReg |= targetAttribs.attrib << TSU_WIN_CTRL_ATTR_OFFS;
  48142. + /* set target ID */
  48143. + decRegs.sizeReg &= ~TSU_WIN_CTRL_TARGET_MASK;
  48144. + decRegs.sizeReg |= targetAttribs.targetId << TSU_WIN_CTRL_TARGET_OFFS;
  48145. +
  48146. + /* for the safe side we disable the window before writing the new */
  48147. + /* values */
  48148. + mvTsuWinEnable(winNum, MV_FALSE);
  48149. + MV_REG_WRITE(MV_TSU_WIN_CTRL_REG(winNum),decRegs.sizeReg);
  48150. +
  48151. + /* Write to address decode Size Register */
  48152. + MV_REG_WRITE(MV_TSU_WIN_BASE_REG(winNum), decRegs.baseReg);
  48153. +
  48154. + /* Enable address decode target window */
  48155. + if(pAddrDecWin->enable == MV_TRUE)
  48156. + {
  48157. + mvTsuWinEnable(winNum,MV_TRUE);
  48158. + }
  48159. +
  48160. + return MV_OK;
  48161. +}
  48162. +
  48163. +
  48164. +/*******************************************************************************
  48165. +* mvTsuWinGet
  48166. +*
  48167. +* DESCRIPTION:
  48168. +* Get TSU peripheral target address window.
  48169. +*
  48170. +* INPUT:
  48171. +* winNum - TSU to target address decode window number.
  48172. +*
  48173. +* OUTPUT:
  48174. +* pAddrDecWin - TSU target window data structure.
  48175. +*
  48176. +* RETURN:
  48177. +* MV_ERROR if register parameters are invalid.
  48178. +*
  48179. +*******************************************************************************/
  48180. +MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)
  48181. +{
  48182. + MV_DEC_REGS decRegs;
  48183. + MV_TARGET_ATTRIB targetAttrib;
  48184. +
  48185. + /* Parameter checking */
  48186. + if(winNum >= TSU_MAX_DECODE_WIN)
  48187. + {
  48188. + mvOsPrintf("mvTsuWinGet: ERR. Invalid winNum %d\n", winNum);
  48189. + return MV_NOT_SUPPORTED;
  48190. + }
  48191. +
  48192. + decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));
  48193. + decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));
  48194. +
  48195. + if(MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  48196. + {
  48197. + mvOsPrintf("mvTsuWinGet: mvCtrlRegToAddrDec Failed \n");
  48198. + return MV_ERROR;
  48199. + }
  48200. +
  48201. + /* attrib and targetId */
  48202. + targetAttrib.attrib =
  48203. + (decRegs.sizeReg & TSU_WIN_CTRL_ATTR_MASK) >> TSU_WIN_CTRL_ATTR_OFFS;
  48204. + targetAttrib.targetId =
  48205. + (decRegs.sizeReg & TSU_WIN_CTRL_TARGET_MASK) >> TSU_WIN_CTRL_TARGET_OFFS;
  48206. +
  48207. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  48208. +
  48209. + /* Check if window is enabled */
  48210. + if((MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum)) & TSU_WIN_CTRL_EN_MASK))
  48211. + {
  48212. + pAddrDecWin->enable = MV_TRUE;
  48213. + }
  48214. + else
  48215. + {
  48216. + pAddrDecWin->enable = MV_FALSE;
  48217. + }
  48218. +
  48219. + return MV_OK;
  48220. +}
  48221. +
  48222. +
  48223. +/*******************************************************************************
  48224. +* mvTsuWinEnable
  48225. +*
  48226. +* DESCRIPTION:
  48227. +* This function enable/disable a TSU to target address window.
  48228. +* According to parameter 'enable' the routine will enable the
  48229. +* window, thus enabling TSU accesses (before enabling the window it is
  48230. +* tested for overlapping). Otherwise, the window will be disabled.
  48231. +*
  48232. +* INPUT:
  48233. +* winNum - TSU to target address decode window number.
  48234. +* enable - Enable / disable parameter.
  48235. +*
  48236. +* OUTPUT:
  48237. +* N/A
  48238. +*
  48239. +* RETURN:
  48240. +* MV_ERROR if decode window number was wrong or enabled window overlapps.
  48241. +*
  48242. +*******************************************************************************/
  48243. +MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable)
  48244. +{
  48245. + MV_TSU_DEC_WIN addrDecWin;
  48246. +
  48247. + /* Parameter checking */
  48248. + if(winNum >= TSU_MAX_DECODE_WIN)
  48249. + {
  48250. + mvOsPrintf("mvTsuWinEnable: ERR. Invalid winNum%d\n",winNum);
  48251. + return MV_ERROR;
  48252. + }
  48253. +
  48254. + if(enable == MV_TRUE)
  48255. + {
  48256. + /* First check for overlap with other enabled windows */
  48257. + /* Get current window. */
  48258. + if(MV_OK != mvTsuWinGet(winNum,&addrDecWin))
  48259. + {
  48260. + mvOsPrintf("mvTsuWinEnable: ERR. targetWinGet fail\n");
  48261. + return MV_ERROR;
  48262. + }
  48263. + /* Check for overlapping. */
  48264. + if(MV_FALSE == tsuWinOverlapDetect(winNum,&(addrDecWin.addrWin)))
  48265. + {
  48266. + /* No Overlap. Enable address decode target window */
  48267. + MV_REG_BIT_SET(MV_TSU_WIN_CTRL_REG(winNum),
  48268. + TSU_WIN_CTRL_EN_MASK);
  48269. + }
  48270. + else
  48271. + {
  48272. + /* Overlap detected */
  48273. + mvOsPrintf("mvTsuWinEnable: ERR. Overlap detected\n");
  48274. + return MV_ERROR;
  48275. + }
  48276. + }
  48277. + else
  48278. + {
  48279. + /* Disable address decode target window */
  48280. + MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),
  48281. + TSU_WIN_CTRL_EN_MASK);
  48282. + }
  48283. + return MV_OK;
  48284. +}
  48285. +
  48286. +/*******************************************************************************
  48287. +* mvTsuWinTargetGet
  48288. +*
  48289. +* DESCRIPTION:
  48290. +* Get Window number associated with target
  48291. +*
  48292. +* INPUT:
  48293. +* target - Target ID to get the window number for.
  48294. +* OUTPUT:
  48295. +*
  48296. +* RETURN:
  48297. +* window number or 0xFFFFFFFF on error.
  48298. +*
  48299. +*******************************************************************************/
  48300. +MV_U32 mvTsuWinTargetGet(MV_TARGET target)
  48301. +{
  48302. + MV_TSU_DEC_WIN decWin;
  48303. + MV_U32 winNum;
  48304. +
  48305. + /* Check parameters */
  48306. + if(target >= MAX_TARGETS)
  48307. + {
  48308. + mvOsPrintf("mvTsuWinTargetGet: target %d is Illigal\n", target);
  48309. + return 0xffffffff;
  48310. + }
  48311. +
  48312. + for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)
  48313. + {
  48314. + if(mvTsuWinGet(winNum,&decWin) != MV_OK)
  48315. + {
  48316. + mvOsPrintf("mvTsuWinGet: window returned error\n");
  48317. + return 0xffffffff;
  48318. + }
  48319. +
  48320. + if (decWin.enable == MV_TRUE)
  48321. + {
  48322. + if(decWin.target == target)
  48323. + {
  48324. + return winNum;
  48325. + }
  48326. + }
  48327. + }
  48328. + return 0xFFFFFFFF;
  48329. +}
  48330. +
  48331. +
  48332. +/*******************************************************************************
  48333. +* tsuWinOverlapDetect
  48334. +*
  48335. +* DESCRIPTION:
  48336. +* Detect TSU address windows overlapping
  48337. +* An unpredicted behaviur is expected in case TSU address decode
  48338. +* windows overlapps.
  48339. +* This function detects TSU address decode windows overlapping of a
  48340. +* specified window. The function does not check the window itself for
  48341. +* overlapping. The function also skipps disabled address decode windows.
  48342. +*
  48343. +* INPUT:
  48344. +* winNum - address decode window number.
  48345. +* pAddrDecWin - An address decode window struct.
  48346. +*
  48347. +* OUTPUT:
  48348. +* None.
  48349. +*
  48350. +* RETURN:
  48351. +* MV_TRUE if the given address window overlap current address
  48352. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  48353. +* from registers.
  48354. +*
  48355. +*******************************************************************************/
  48356. +static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  48357. +{
  48358. + MV_U32 ctrlReg;
  48359. + MV_U32 winNumIndex;
  48360. + MV_TSU_DEC_WIN addrDecWin;
  48361. +
  48362. + for(winNumIndex = 0; winNumIndex < TSU_MAX_DECODE_WIN; winNumIndex++)
  48363. + {
  48364. + /* Do not check window itself */
  48365. + if(winNumIndex == winNum)
  48366. + {
  48367. + continue;
  48368. + }
  48369. +
  48370. + /* Do not check disabled windows */
  48371. + ctrlReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNumIndex));
  48372. + if((ctrlReg & TSU_WIN_CTRL_EN_MASK) == 0)
  48373. + {
  48374. + continue;
  48375. + }
  48376. +
  48377. + /* Get window parameters */
  48378. + if (MV_OK != mvTsuWinGet(winNumIndex, &addrDecWin))
  48379. + {
  48380. + mvOsPrintf("tsuWinOverlapDetect: ERR. mvTsuWinGet failed\n");
  48381. + return MV_ERROR;
  48382. + }
  48383. +
  48384. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  48385. + {
  48386. + return MV_TRUE;
  48387. + }
  48388. + }
  48389. + return MV_FALSE;
  48390. +}
  48391. +
  48392. +
  48393. +/*******************************************************************************
  48394. +* mvTsuAddrDecShow
  48395. +*
  48396. +* DESCRIPTION:
  48397. +* Print the TSU address decode map.
  48398. +*
  48399. +* INPUT:
  48400. +* None.
  48401. +*
  48402. +* OUTPUT:
  48403. +* None.
  48404. +*
  48405. +* RETURN:
  48406. +* None.
  48407. +*
  48408. +*******************************************************************************/
  48409. +void mvTsuAddrDecShow(void)
  48410. +{
  48411. + MV_TSU_DEC_WIN win;
  48412. + int i;
  48413. +
  48414. + if (MV_FALSE == mvCtrlPwrClckGet(TS_UNIT_ID, 0))
  48415. + return;
  48416. +
  48417. + mvOsOutput( "\n" );
  48418. + mvOsOutput( "TSU:\n");
  48419. + mvOsOutput( "----\n" );
  48420. +
  48421. + for(i = 0; i < TSU_MAX_DECODE_WIN; i++)
  48422. + {
  48423. + memset(&win, 0, sizeof(TSU_MAX_DECODE_WIN));
  48424. + mvOsOutput( "win%d - ", i );
  48425. +
  48426. + if(mvTsuWinGet(i, &win ) == MV_OK )
  48427. + {
  48428. + if(win.enable == MV_TRUE)
  48429. + {
  48430. + mvOsOutput("%s base %08x, ",
  48431. + mvCtrlTargetNameGet(win.target),
  48432. + win.addrWin.baseLow);
  48433. + mvOsOutput( "...." );
  48434. + mvSizePrint(win.addrWin.size );
  48435. + mvOsOutput( "\n" );
  48436. + }
  48437. + else
  48438. + {
  48439. + mvOsOutput( "disable\n" );
  48440. + }
  48441. + }
  48442. + }
  48443. + return;
  48444. +}
  48445. +
  48446. +
  48447. +/*******************************************************************************
  48448. +* mvTsuInit
  48449. +*
  48450. +* DESCRIPTION:
  48451. +* Initialize the TSU unit, and get unit out of reset.
  48452. +*
  48453. +* INPUT:
  48454. +* coreClock - The core clock at which the TSU should operate.
  48455. +* mode - The mode on configure the unit into (serial/parallel).
  48456. +* memHandle - Memory handle used for memory allocations.
  48457. +* OUTPUT:
  48458. +* None.
  48459. +* RETURN:
  48460. +* MV_OK - on success,
  48461. +*
  48462. +*******************************************************************************/
  48463. +MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,
  48464. + void *osHandle)
  48465. +{
  48466. + MV_STATUS status;
  48467. +
  48468. + status = mvTsuWinInit();
  48469. + if(status == MV_OK)
  48470. + status = mvTsuHalInit(coreClock,mode,osHandle);
  48471. +
  48472. + return status;
  48473. +}
  48474. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h
  48475. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h 1970-01-01 01:00:00.000000000 +0100
  48476. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h 2010-11-09 20:28:09.894776606 +0100
  48477. @@ -0,0 +1,110 @@
  48478. +/*******************************************************************************
  48479. +Copyright (C) Marvell International Ltd. and its affiliates
  48480. +
  48481. +This software file (the "File") is owned and distributed by Marvell
  48482. +International Ltd. and/or its affiliates ("Marvell") under the following
  48483. +alternative licensing terms. Once you have made an election to distribute the
  48484. +File under one of the following license alternatives, please (i) delete this
  48485. +introductory statement regarding license alternatives, (ii) delete the two
  48486. +license alternatives that you have not elected to use and (iii) preserve the
  48487. +Marvell copyright notice above.
  48488. +
  48489. +********************************************************************************
  48490. +Marvell Commercial License Option
  48491. +
  48492. +If you received this File from Marvell and you have entered into a commercial
  48493. +license agreement (a "Commercial License") with Marvell, the File is licensed
  48494. +to you under the terms of the applicable Commercial License.
  48495. +
  48496. +********************************************************************************
  48497. +Marvell GPL License Option
  48498. +
  48499. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48500. +modify this File in accordance with the terms and conditions of the General
  48501. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  48502. +available along with the File in the license.txt file or by writing to the Free
  48503. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  48504. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  48505. +
  48506. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  48507. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  48508. +DISCLAIMED. The GPL License provides additional details about this warranty
  48509. +disclaimer.
  48510. +********************************************************************************
  48511. +Marvell BSD License Option
  48512. +
  48513. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48514. +modify this File under the following licensing terms.
  48515. +Redistribution and use in source and binary forms, with or without modification,
  48516. +are permitted provided that the following conditions are met:
  48517. +
  48518. + * Redistributions of source code must retain the above copyright notice,
  48519. + this list of conditions and the following disclaimer.
  48520. +
  48521. + * Redistributions in binary form must reproduce the above copyright
  48522. + notice, this list of conditions and the following disclaimer in the
  48523. + documentation and/or other materials provided with the distribution.
  48524. +
  48525. + * Neither the name of Marvell nor the names of its contributors may be
  48526. + used to endorse or promote products derived from this software without
  48527. + specific prior written permission.
  48528. +
  48529. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  48530. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  48531. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  48532. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  48533. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  48534. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  48535. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  48536. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  48537. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  48538. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48539. +
  48540. +*******************************************************************************/
  48541. +
  48542. +#ifndef __INCmvSysTsh
  48543. +#define __INCmvSysTsh
  48544. +
  48545. +#ifdef __cplusplus
  48546. +extern "C" {
  48547. +#endif /* __cplusplus */
  48548. +
  48549. +/* includes */
  48550. +#include "ts/mvTsu.h"
  48551. +#include "ctrlEnv/sys/mvCpuIf.h"
  48552. +#include "ctrlEnv/mvCtrlEnvLib.h"
  48553. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  48554. +
  48555. +#define TSU_MAX_DECODE_WIN 4
  48556. +
  48557. +
  48558. +/*******************************************/
  48559. +/* TSU Windows Registers */
  48560. +/*******************************************/
  48561. +#define MV_TSU_WIN_CTRL_REG(win) (TSU_GLOBAL_REG_BASE +0x30 + 0x10 * win)
  48562. +#define MV_TSU_WIN_BASE_REG(win) (TSU_GLOBAL_REG_BASE +0x34 + 0x10 * win)
  48563. +
  48564. +/* TSU windows control register. */
  48565. +#define TSU_WIN_CTRL_EN_MASK (0x1 << 0)
  48566. +#define TSU_WIN_CTRL_TARGET_OFFS 4
  48567. +#define TSU_WIN_CTRL_TARGET_MASK (0xF << TSU_WIN_CTRL_TARGET_OFFS)
  48568. +#define TSU_WIN_CTRL_ATTR_OFFS 8
  48569. +#define TSU_WIN_CTRL_ATTR_MASK (0xFF << TSU_WIN_CTRL_ATTR_OFFS)
  48570. +#define TSU_WIN_CTRL_SIZE_OFFS 16
  48571. +#define TSU_WIN_CTRL_SIZE_MASK (0xFFFF << TSU_WIN_CTRL_SIZE_OFFS)
  48572. +
  48573. +/* TSU windows base register. */
  48574. +#define TSU_WIN_BASE_OFFS 16
  48575. +#define TSU_WIN_BASE_MASK (0xFFFF << TSU_WIN_BASE_OFFS)
  48576. +
  48577. +MV_STATUS mvTsuWinInit(void);
  48578. +
  48579. +void mvTsuAddrDecShow(void);
  48580. +MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,
  48581. + void *osHandle);
  48582. +
  48583. +#ifdef __cplusplus
  48584. +}
  48585. +#endif /* __cplusplus */
  48586. +
  48587. +#endif /* __INCmvTsh */
  48588. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c
  48589. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c 1970-01-01 01:00:00.000000000 +0100
  48590. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c 2010-11-09 20:28:09.932495382 +0100
  48591. @@ -0,0 +1,497 @@
  48592. +/*******************************************************************************
  48593. +Copyright (C) Marvell International Ltd. and its affiliates
  48594. +
  48595. +This software file (the "File") is owned and distributed by Marvell
  48596. +International Ltd. and/or its affiliates ("Marvell") under the following
  48597. +alternative licensing terms. Once you have made an election to distribute the
  48598. +File under one of the following license alternatives, please (i) delete this
  48599. +introductory statement regarding license alternatives, (ii) delete the two
  48600. +license alternatives that you have not elected to use and (iii) preserve the
  48601. +Marvell copyright notice above.
  48602. +
  48603. +********************************************************************************
  48604. +Marvell Commercial License Option
  48605. +
  48606. +If you received this File from Marvell and you have entered into a commercial
  48607. +license agreement (a "Commercial License") with Marvell, the File is licensed
  48608. +to you under the terms of the applicable Commercial License.
  48609. +
  48610. +********************************************************************************
  48611. +Marvell GPL License Option
  48612. +
  48613. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48614. +modify this File in accordance with the terms and conditions of the General
  48615. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  48616. +available along with the File in the license.txt file or by writing to the Free
  48617. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  48618. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  48619. +
  48620. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  48621. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  48622. +DISCLAIMED. The GPL License provides additional details about this warranty
  48623. +disclaimer.
  48624. +********************************************************************************
  48625. +Marvell BSD License Option
  48626. +
  48627. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48628. +modify this File under the following licensing terms.
  48629. +Redistribution and use in source and binary forms, with or without modification,
  48630. +are permitted provided that the following conditions are met:
  48631. +
  48632. + * Redistributions of source code must retain the above copyright notice,
  48633. + this list of conditions and the following disclaimer.
  48634. +
  48635. + * Redistributions in binary form must reproduce the above copyright
  48636. + notice, this list of conditions and the following disclaimer in the
  48637. + documentation and/or other materials provided with the distribution.
  48638. +
  48639. + * Neither the name of Marvell nor the names of its contributors may be
  48640. + used to endorse or promote products derived from this software without
  48641. + specific prior written permission.
  48642. +
  48643. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  48644. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  48645. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  48646. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  48647. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  48648. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  48649. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  48650. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  48651. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  48652. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48653. +
  48654. +*******************************************************************************/
  48655. +
  48656. +#include "ctrlEnv/sys/mvSysUsb.h"
  48657. +
  48658. +MV_TARGET usbAddrDecPrioTab[] =
  48659. +{
  48660. +#if defined(MV_INCLUDE_SDRAM_CS0)
  48661. + SDRAM_CS0,
  48662. +#endif
  48663. +#if defined(MV_INCLUDE_SDRAM_CS1)
  48664. + SDRAM_CS1,
  48665. +#endif
  48666. +#if defined(MV_INCLUDE_SDRAM_CS2)
  48667. + SDRAM_CS2,
  48668. +#endif
  48669. +#if defined(MV_INCLUDE_SDRAM_CS3)
  48670. + SDRAM_CS3,
  48671. +#endif
  48672. +#if defined(MV_INCLUDE_CESA) && defined(USB_UNDERRUN_WA)
  48673. + CRYPT_ENG,
  48674. +#endif
  48675. +#if defined(MV_INCLUDE_PEX)
  48676. + PEX0_MEM,
  48677. +#endif
  48678. + TBL_TERM
  48679. +};
  48680. +
  48681. +
  48682. +
  48683. +MV_STATUS mvUsbInit(int dev, MV_BOOL isHost)
  48684. +{
  48685. + MV_STATUS status;
  48686. +
  48687. + status = mvUsbWinInit(dev);
  48688. + if(status != MV_OK)
  48689. + return status;
  48690. +
  48691. + return mvUsbHalInit(dev, isHost);
  48692. +}
  48693. +
  48694. +
  48695. +/*******************************************************************************
  48696. +* usbWinOverlapDetect - Detect USB address windows overlapping
  48697. +*
  48698. +* DESCRIPTION:
  48699. +* An unpredicted behaviur is expected in case USB address decode
  48700. +* windows overlapps.
  48701. +* This function detects USB address decode windows overlapping of a
  48702. +* specified window. The function does not check the window itself for
  48703. +* overlapping. The function also skipps disabled address decode windows.
  48704. +*
  48705. +* INPUT:
  48706. +* winNum - address decode window number.
  48707. +* pAddrDecWin - An address decode window struct.
  48708. +*
  48709. +* OUTPUT:
  48710. +* None.
  48711. +*
  48712. +* RETURN:
  48713. +* MV_TRUE if the given address window overlap current address
  48714. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  48715. +* from registers.
  48716. +*
  48717. +*******************************************************************************/
  48718. +static MV_STATUS usbWinOverlapDetect(int dev, MV_U32 winNum,
  48719. + MV_ADDR_WIN *pAddrWin)
  48720. +{
  48721. + MV_U32 winNumIndex;
  48722. + MV_DEC_WIN addrDecWin;
  48723. +
  48724. + for(winNumIndex=0; winNumIndex<MV_USB_MAX_ADDR_DECODE_WIN; winNumIndex++)
  48725. + {
  48726. + /* Do not check window itself */
  48727. + if (winNumIndex == winNum)
  48728. + {
  48729. + continue;
  48730. + }
  48731. +
  48732. + /* Get window parameters */
  48733. + if (MV_OK != mvUsbWinGet(dev, winNumIndex, &addrDecWin))
  48734. + {
  48735. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  48736. + return MV_ERROR;
  48737. + }
  48738. +
  48739. + /* Do not check disabled windows */
  48740. + if(addrDecWin.enable == MV_FALSE)
  48741. + {
  48742. + continue;
  48743. + }
  48744. +
  48745. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  48746. + {
  48747. + return MV_TRUE;
  48748. + }
  48749. + }
  48750. + return MV_FALSE;
  48751. +}
  48752. +
  48753. +/*******************************************************************************
  48754. +* mvUsbWinSet - Set USB target address window
  48755. +*
  48756. +* DESCRIPTION:
  48757. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  48758. +* address window, also known as address decode window.
  48759. +* After setting this target window, the USB will be able to access the
  48760. +* target within the address window.
  48761. +*
  48762. +* INPUT:
  48763. +* winNum - USB target address decode window number.
  48764. +* pAddrDecWin - USB target window data structure.
  48765. +*
  48766. +* OUTPUT:
  48767. +* None.
  48768. +*
  48769. +* RETURN:
  48770. +* MV_ERROR if address window overlapps with other address decode windows.
  48771. +* MV_BAD_PARAM if base address is invalid parameter or target is
  48772. +* unknown.
  48773. +*
  48774. +*******************************************************************************/
  48775. +MV_STATUS mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)
  48776. +{
  48777. + MV_DEC_WIN_PARAMS winParams;
  48778. + MV_U32 sizeReg, baseReg;
  48779. +
  48780. + /* Parameter checking */
  48781. + if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)
  48782. + {
  48783. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  48784. + return MV_BAD_PARAM;
  48785. + }
  48786. +
  48787. + /* Check if the requested window overlapps with current windows */
  48788. + if (MV_TRUE == usbWinOverlapDetect(dev, winNum, &pDecWin->addrWin))
  48789. + {
  48790. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  48791. + return MV_ERROR;
  48792. + }
  48793. +
  48794. + /* check if address is aligned to the size */
  48795. + if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))
  48796. + {
  48797. + mvOsPrintf("mvUsbWinSet:Error setting USB window %d to "\
  48798. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  48799. + winNum,
  48800. + mvCtrlTargetNameGet(pDecWin->target),
  48801. + pDecWin->addrWin.baseLow,
  48802. + pDecWin->addrWin.size);
  48803. + return MV_ERROR;
  48804. + }
  48805. +
  48806. + if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))
  48807. + {
  48808. + mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);
  48809. + return MV_ERROR;
  48810. + }
  48811. +
  48812. + /* set Size, Attributes and TargetID */
  48813. + sizeReg = (((winParams.targetId << MV_USB_WIN_TARGET_OFFSET) & MV_USB_WIN_TARGET_MASK) |
  48814. + ((winParams.attrib << MV_USB_WIN_ATTR_OFFSET) & MV_USB_WIN_ATTR_MASK) |
  48815. + ((winParams.size << MV_USB_WIN_SIZE_OFFSET) & MV_USB_WIN_SIZE_MASK));
  48816. +
  48817. +#if defined(MV645xx) || defined(MV646xx)
  48818. + /* If window is DRAM with HW cache coherency, make sure bit2 is set */
  48819. + sizeReg &= ~MV_USB_WIN_BURST_WR_LIMIT_MASK;
  48820. +
  48821. + if((MV_TARGET_IS_DRAM(pDecWin->target)) &&
  48822. + (pDecWin->addrWinAttr.cachePolicy != NO_COHERENCY))
  48823. + {
  48824. + sizeReg |= MV_USB_WIN_BURST_WR_32BIT_LIMIT;
  48825. + }
  48826. + else
  48827. + {
  48828. + sizeReg |= MV_USB_WIN_BURST_WR_NO_LIMIT;
  48829. + }
  48830. +#endif /* MV645xx || MV646xx */
  48831. +
  48832. + if (pDecWin->enable == MV_TRUE)
  48833. + {
  48834. + sizeReg |= MV_USB_WIN_ENABLE_MASK;
  48835. + }
  48836. + else
  48837. + {
  48838. + sizeReg &= ~MV_USB_WIN_ENABLE_MASK;
  48839. + }
  48840. +
  48841. + /* Update Base value */
  48842. + baseReg = (winParams.baseAddr & MV_USB_WIN_BASE_MASK);
  48843. +
  48844. + MV_REG_WRITE( MV_USB_WIN_CTRL_REG(dev, winNum), sizeReg);
  48845. + MV_REG_WRITE( MV_USB_WIN_BASE_REG(dev, winNum), baseReg);
  48846. +
  48847. + return MV_OK;
  48848. +}
  48849. +
  48850. +/*******************************************************************************
  48851. +* mvUsbWinGet - Get USB peripheral target address window.
  48852. +*
  48853. +* DESCRIPTION:
  48854. +* Get USB peripheral target address window.
  48855. +*
  48856. +* INPUT:
  48857. +* winNum - USB target address decode window number.
  48858. +*
  48859. +* OUTPUT:
  48860. +* pDecWin - USB target window data structure.
  48861. +*
  48862. +* RETURN:
  48863. +* MV_ERROR if register parameters are invalid.
  48864. +*
  48865. +*******************************************************************************/
  48866. +MV_STATUS mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)
  48867. +{
  48868. + MV_DEC_WIN_PARAMS winParam;
  48869. + MV_U32 sizeReg, baseReg;
  48870. +
  48871. + /* Parameter checking */
  48872. + if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)
  48873. + {
  48874. + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
  48875. + __FUNCTION__, dev, winNum);
  48876. + return MV_NOT_SUPPORTED;
  48877. + }
  48878. +
  48879. + baseReg = MV_REG_READ( MV_USB_WIN_BASE_REG(dev, winNum) );
  48880. + sizeReg = MV_REG_READ( MV_USB_WIN_CTRL_REG(dev, winNum) );
  48881. +
  48882. + /* Check if window is enabled */
  48883. + if(sizeReg & MV_USB_WIN_ENABLE_MASK)
  48884. + {
  48885. + pDecWin->enable = MV_TRUE;
  48886. +
  48887. + /* Extract window parameters from registers */
  48888. + winParam.targetId = (sizeReg & MV_USB_WIN_TARGET_MASK) >> MV_USB_WIN_TARGET_OFFSET;
  48889. + winParam.attrib = (sizeReg & MV_USB_WIN_ATTR_MASK) >> MV_USB_WIN_ATTR_OFFSET;
  48890. + winParam.size = (sizeReg & MV_USB_WIN_SIZE_MASK) >> MV_USB_WIN_SIZE_OFFSET;
  48891. + winParam.baseAddr = (baseReg & MV_USB_WIN_BASE_MASK);
  48892. +
  48893. + /* Translate the decode window parameters to address decode struct */
  48894. + if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))
  48895. + {
  48896. + mvOsPrintf("Failed to translate register parameters to USB address" \
  48897. + " decode window structure\n");
  48898. + return MV_ERROR;
  48899. + }
  48900. + }
  48901. + else
  48902. + {
  48903. + pDecWin->enable = MV_FALSE;
  48904. + }
  48905. + return MV_OK;
  48906. +}
  48907. +
  48908. +/*******************************************************************************
  48909. +* mvUsbWinInit -
  48910. +*
  48911. +* INPUT:
  48912. +*
  48913. +* OUTPUT:
  48914. +*
  48915. +* RETURN:
  48916. +* MV_ERROR if register parameters are invalid.
  48917. +*
  48918. +*******************************************************************************/
  48919. +MV_STATUS mvUsbWinInit(int dev)
  48920. +{
  48921. + MV_STATUS status;
  48922. + MV_DEC_WIN usbWin;
  48923. + MV_CPU_DEC_WIN cpuAddrDecWin;
  48924. + int winNum;
  48925. + MV_U32 winPrioIndex = 0;
  48926. +
  48927. + /* First disable all address decode windows */
  48928. + for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)
  48929. + {
  48930. + MV_REG_BIT_RESET(MV_USB_WIN_CTRL_REG(dev, winNum), MV_USB_WIN_ENABLE_MASK);
  48931. + }
  48932. +
  48933. + /* Go through all windows in user table until table terminator */
  48934. + winNum = 0;
  48935. + while( (usbAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
  48936. + (winNum < MV_USB_MAX_ADDR_DECODE_WIN) )
  48937. + {
  48938. + /* first get attributes from CPU If */
  48939. + status = mvCpuIfTargetWinGet(usbAddrDecPrioTab[winPrioIndex],
  48940. + &cpuAddrDecWin);
  48941. +
  48942. + if(MV_NO_SUCH == status)
  48943. + {
  48944. + winPrioIndex++;
  48945. + continue;
  48946. + }
  48947. + if (MV_OK != status)
  48948. + {
  48949. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  48950. + return MV_ERROR;
  48951. + }
  48952. +
  48953. + if (cpuAddrDecWin.enable == MV_TRUE)
  48954. + {
  48955. + usbWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  48956. + usbWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  48957. + usbWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  48958. + usbWin.enable = MV_TRUE;
  48959. + usbWin.target = usbAddrDecPrioTab[winPrioIndex];
  48960. +
  48961. +#if defined(MV645xx) || defined(MV646xx)
  48962. + /* Get the default attributes for that target window */
  48963. + mvCtrlDefAttribGet(usbWin.target, &usbWin.addrWinAttr);
  48964. +#endif /* MV645xx || MV646xx */
  48965. +
  48966. + if(MV_OK != mvUsbWinSet(dev, winNum, &usbWin))
  48967. + {
  48968. + return MV_ERROR;
  48969. + }
  48970. + winNum++;
  48971. + }
  48972. + winPrioIndex++;
  48973. + }
  48974. + return MV_OK;
  48975. +}
  48976. +
  48977. +/*******************************************************************************
  48978. +* mvUsbAddrDecShow - Print the USB address decode map.
  48979. +*
  48980. +* DESCRIPTION:
  48981. +* This function print the USB address decode map.
  48982. +*
  48983. +* INPUT:
  48984. +* None.
  48985. +*
  48986. +* OUTPUT:
  48987. +* None.
  48988. +*
  48989. +* RETURN:
  48990. +* None.
  48991. +*
  48992. +*******************************************************************************/
  48993. +MV_VOID mvUsbAddrDecShow(MV_VOID)
  48994. +{
  48995. + MV_DEC_WIN addrDecWin;
  48996. + int i, winNum;
  48997. +
  48998. + mvOsOutput( "\n" );
  48999. + mvOsOutput( "USB:\n" );
  49000. + mvOsOutput( "----\n" );
  49001. +
  49002. + for(i=0; i<mvCtrlUsbMaxGet(); i++)
  49003. + {
  49004. + mvOsOutput( "Device %d:\n", i);
  49005. +
  49006. + for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)
  49007. + {
  49008. + memset(&addrDecWin, 0, sizeof(MV_DEC_WIN) );
  49009. +
  49010. + mvOsOutput( "win%d - ", winNum );
  49011. +
  49012. + if( mvUsbWinGet(i, winNum, &addrDecWin ) == MV_OK )
  49013. + {
  49014. + if( addrDecWin.enable )
  49015. + {
  49016. + mvOsOutput( "%s base %08x, ",
  49017. + mvCtrlTargetNameGet(addrDecWin.target), addrDecWin.addrWin.baseLow );
  49018. +
  49019. + mvSizePrint( addrDecWin.addrWin.size );
  49020. +
  49021. +#if defined(MV645xx) || defined(MV646xx)
  49022. + switch( addrDecWin.addrWinAttr.swapType)
  49023. + {
  49024. + case MV_BYTE_SWAP:
  49025. + mvOsOutput( "BYTE_SWAP, " );
  49026. + break;
  49027. + case MV_NO_SWAP:
  49028. + mvOsOutput( "NO_SWAP , " );
  49029. + break;
  49030. + case MV_BYTE_WORD_SWAP:
  49031. + mvOsOutput( "BYTE_WORD_SWAP, " );
  49032. + break;
  49033. + case MV_WORD_SWAP:
  49034. + mvOsOutput( "WORD_SWAP, " );
  49035. + break;
  49036. + default:
  49037. + mvOsOutput( "SWAP N/A , " );
  49038. + }
  49039. +
  49040. + switch( addrDecWin.addrWinAttr.cachePolicy )
  49041. + {
  49042. + case NO_COHERENCY:
  49043. + mvOsOutput( "NO_COHERENCY , " );
  49044. + break;
  49045. + case WT_COHERENCY:
  49046. + mvOsOutput( "WT_COHERENCY , " );
  49047. + break;
  49048. + case WB_COHERENCY:
  49049. + mvOsOutput( "WB_COHERENCY , " );
  49050. + break;
  49051. + default:
  49052. + mvOsOutput( "COHERENCY N/A, " );
  49053. + }
  49054. +
  49055. + switch( addrDecWin.addrWinAttr.pcixNoSnoop )
  49056. + {
  49057. + case 0:
  49058. + mvOsOutput( "PCI-X NS inactive, " );
  49059. + break;
  49060. + case 1:
  49061. + mvOsOutput( "PCI-X NS active , " );
  49062. + break;
  49063. + default:
  49064. + mvOsOutput( "PCI-X NS N/A , " );
  49065. + }
  49066. +
  49067. + switch( addrDecWin.addrWinAttr.p2pReq64 )
  49068. + {
  49069. + case 0:
  49070. + mvOsOutput( "REQ64 force" );
  49071. + break;
  49072. + case 1:
  49073. + mvOsOutput( "REQ64 detect" );
  49074. + break;
  49075. + default:
  49076. + mvOsOutput( "REQ64 N/A" );
  49077. + }
  49078. +#endif /* MV645xx || MV646xx */
  49079. + mvOsOutput( "\n" );
  49080. + }
  49081. + else
  49082. + mvOsOutput( "disable\n" );
  49083. + }
  49084. + }
  49085. + }
  49086. +}
  49087. +
  49088. +
  49089. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h
  49090. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h 1970-01-01 01:00:00.000000000 +0100
  49091. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h 2010-11-09 20:28:09.972495420 +0100
  49092. @@ -0,0 +1,125 @@
  49093. +/*******************************************************************************
  49094. +Copyright (C) Marvell International Ltd. and its affiliates
  49095. +
  49096. +This software file (the "File") is owned and distributed by Marvell
  49097. +International Ltd. and/or its affiliates ("Marvell") under the following
  49098. +alternative licensing terms. Once you have made an election to distribute the
  49099. +File under one of the following license alternatives, please (i) delete this
  49100. +introductory statement regarding license alternatives, (ii) delete the two
  49101. +license alternatives that you have not elected to use and (iii) preserve the
  49102. +Marvell copyright notice above.
  49103. +
  49104. +********************************************************************************
  49105. +Marvell Commercial License Option
  49106. +
  49107. +If you received this File from Marvell and you have entered into a commercial
  49108. +license agreement (a "Commercial License") with Marvell, the File is licensed
  49109. +to you under the terms of the applicable Commercial License.
  49110. +
  49111. +********************************************************************************
  49112. +Marvell GPL License Option
  49113. +
  49114. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49115. +modify this File in accordance with the terms and conditions of the General
  49116. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  49117. +available along with the File in the license.txt file or by writing to the Free
  49118. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  49119. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  49120. +
  49121. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  49122. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  49123. +DISCLAIMED. The GPL License provides additional details about this warranty
  49124. +disclaimer.
  49125. +********************************************************************************
  49126. +Marvell BSD License Option
  49127. +
  49128. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49129. +modify this File under the following licensing terms.
  49130. +Redistribution and use in source and binary forms, with or without modification,
  49131. +are permitted provided that the following conditions are met:
  49132. +
  49133. + * Redistributions of source code must retain the above copyright notice,
  49134. + this list of conditions and the following disclaimer.
  49135. +
  49136. + * Redistributions in binary form must reproduce the above copyright
  49137. + notice, this list of conditions and the following disclaimer in the
  49138. + documentation and/or other materials provided with the distribution.
  49139. +
  49140. + * Neither the name of Marvell nor the names of its contributors may be
  49141. + used to endorse or promote products derived from this software without
  49142. + specific prior written permission.
  49143. +
  49144. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  49145. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49146. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  49147. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  49148. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  49149. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  49150. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  49151. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  49152. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  49153. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49154. +
  49155. +*******************************************************************************/
  49156. +
  49157. +#ifndef __INCmvSysUsbh
  49158. +#define __INCmvSysUsbh
  49159. +
  49160. +#ifdef __cplusplus
  49161. +extern "C" {
  49162. +#endif /* __cplusplus */
  49163. +
  49164. +/* includes */
  49165. +#include "usb/mvUsb.h"
  49166. +#include "ctrlEnv/sys/mvCpuIf.h"
  49167. +#include "ctrlEnv/mvCtrlEnvLib.h"
  49168. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  49169. +
  49170. +#define MV_USB_MAX_ADDR_DECODE_WIN 4
  49171. +
  49172. +/*******************************************/
  49173. +/* USB Bridge Registers */
  49174. +/*******************************************/
  49175. +#define MV_USB_BRIDGE_CTRL_REG(dev) (USB_REG_BASE(dev) + 0x300)
  49176. +
  49177. +#define MV_USB_WIN_CTRL_REG(dev, win) (USB_REG_BASE(dev) + 0x320 + ((win)<<4))
  49178. +#define MV_USB_WIN_BASE_REG(dev, win) (USB_REG_BASE(dev) + 0x324 + ((win)<<4))
  49179. +
  49180. +/* BITs in Windows 0-3 Control and Base Registers */
  49181. +#define MV_USB_WIN_ENABLE_BIT 0
  49182. +#define MV_USB_WIN_ENABLE_MASK (1 << MV_USB_WIN_ENABLE_BIT)
  49183. +
  49184. +#define MV_USB_WIN_BURST_WR_LIMIT_BIT 1
  49185. +#define MV_USB_WIN_BURST_WR_LIMIT_MASK (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
  49186. +#define MV_USB_WIN_BURST_WR_NO_LIMIT (0 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
  49187. +#define MV_USB_WIN_BURST_WR_32BIT_LIMIT (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
  49188. +
  49189. +#define MV_USB_WIN_TARGET_OFFSET 4
  49190. +#define MV_USB_WIN_TARGET_MASK (0xF << MV_USB_WIN_TARGET_OFFSET)
  49191. +
  49192. +#define MV_USB_WIN_ATTR_OFFSET 8
  49193. +#define MV_USB_WIN_ATTR_MASK (0xFF << MV_USB_WIN_ATTR_OFFSET)
  49194. +
  49195. +#define MV_USB_WIN_SIZE_OFFSET 16
  49196. +#define MV_USB_WIN_SIZE_MASK (0xFFFF << MV_USB_WIN_SIZE_OFFSET)
  49197. +
  49198. +#define MV_USB_WIN_BASE_OFFSET 16
  49199. +#define MV_USB_WIN_BASE_MASK (0xFFFF << MV_USB_WIN_BASE_OFFSET)
  49200. +
  49201. +
  49202. +#define MV_USB_BRIDGE_IPG_REG(dev) (USB_REG_BASE(dev) + 0x360)
  49203. +
  49204. +
  49205. +MV_STATUS mvUsbInit(int dev, MV_BOOL isHost);
  49206. +
  49207. +MV_STATUS mvUsbWinInit(int dev);
  49208. +MV_STATUS mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);
  49209. +MV_STATUS mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);
  49210. +
  49211. +void mvUsbAddrDecShow(void);
  49212. +
  49213. +#ifdef __cplusplus
  49214. +}
  49215. +#endif /* __cplusplus */
  49216. +
  49217. +#endif /* __INCmvUsbh */
  49218. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c
  49219. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c 1970-01-01 01:00:00.000000000 +0100
  49220. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c 2010-11-09 20:28:10.022500031 +0100
  49221. @@ -0,0 +1,662 @@
  49222. +/*******************************************************************************
  49223. +Copyright (C) Marvell International Ltd. and its affiliates
  49224. +
  49225. +This software file (the "File") is owned and distributed by Marvell
  49226. +International Ltd. and/or its affiliates ("Marvell") under the following
  49227. +alternative licensing terms. Once you have made an election to distribute the
  49228. +File under one of the following license alternatives, please (i) delete this
  49229. +introductory statement regarding license alternatives, (ii) delete the two
  49230. +license alternatives that you have not elected to use and (iii) preserve the
  49231. +Marvell copyright notice above.
  49232. +
  49233. +********************************************************************************
  49234. +Marvell Commercial License Option
  49235. +
  49236. +If you received this File from Marvell and you have entered into a commercial
  49237. +license agreement (a "Commercial License") with Marvell, the File is licensed
  49238. +to you under the terms of the applicable Commercial License.
  49239. +
  49240. +********************************************************************************
  49241. +Marvell GPL License Option
  49242. +
  49243. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49244. +modify this File in accordance with the terms and conditions of the General
  49245. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  49246. +available along with the File in the license.txt file or by writing to the Free
  49247. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  49248. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  49249. +
  49250. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  49251. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  49252. +DISCLAIMED. The GPL License provides additional details about this warranty
  49253. +disclaimer.
  49254. +********************************************************************************
  49255. +Marvell BSD License Option
  49256. +
  49257. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49258. +modify this File under the following licensing terms.
  49259. +Redistribution and use in source and binary forms, with or without modification,
  49260. +are permitted provided that the following conditions are met:
  49261. +
  49262. + * Redistributions of source code must retain the above copyright notice,
  49263. + this list of conditions and the following disclaimer.
  49264. +
  49265. + * Redistributions in binary form must reproduce the above copyright
  49266. + notice, this list of conditions and the following disclaimer in the
  49267. + documentation and/or other materials provided with the distribution.
  49268. +
  49269. + * Neither the name of Marvell nor the names of its contributors may be
  49270. + used to endorse or promote products derived from this software without
  49271. + specific prior written permission.
  49272. +
  49273. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  49274. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49275. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  49276. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  49277. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  49278. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  49279. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  49280. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  49281. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  49282. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49283. +
  49284. +*******************************************************************************/
  49285. +
  49286. +#include "xor/mvXor.h"
  49287. +#include "mvSysXor.h"
  49288. +
  49289. +/* defines */
  49290. +#ifdef MV_DEBUG
  49291. + #define DB(x) x
  49292. +#else
  49293. + #define DB(x)
  49294. +#endif
  49295. +
  49296. +
  49297. +static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  49298. +
  49299. +MV_TARGET xorAddrDecPrioTap[] =
  49300. +{
  49301. +#if defined(MV_INCLUDE_DEVICE_CS0)
  49302. + DEVICE_CS0,
  49303. +#endif
  49304. +#if defined(MV_INCLUDE_PEX)
  49305. + PEX0_MEM,
  49306. +#endif
  49307. +#if defined(MV_INCLUDE_SDRAM_CS0)
  49308. + SDRAM_CS0,
  49309. +#endif
  49310. +#if defined(MV_INCLUDE_SDRAM_CS1)
  49311. + SDRAM_CS1,
  49312. +#endif
  49313. +#if defined(MV_INCLUDE_SDRAM_CS2)
  49314. + SDRAM_CS2,
  49315. +#endif
  49316. +#if defined(MV_INCLUDE_SDRAM_CS3)
  49317. + SDRAM_CS3,
  49318. +#endif
  49319. +#if defined(MV_INCLUDE_DEVICE_CS1)
  49320. + DEVICE_CS1,
  49321. +#endif
  49322. +#if defined(MV_INCLUDE_CESA)
  49323. + CRYPT_ENG,
  49324. +#endif
  49325. + TBL_TERM
  49326. +};
  49327. +static MV_STATUS mvXorInitWinsUnit (MV_U32 unit)
  49328. +{
  49329. + MV_U32 winNum;
  49330. + MV_XOR_DEC_WIN addrDecWin;
  49331. + MV_CPU_DEC_WIN cpuAddrDecWin;
  49332. + MV_U32 status;
  49333. + MV_U32 winPrioIndex=0;
  49334. +
  49335. + /* Initiate XOR address decode */
  49336. +
  49337. + /* First disable all address decode windows */
  49338. + for(winNum = 0; winNum < XOR_MAX_ADDR_DEC_WIN; winNum++)
  49339. + {
  49340. + mvXorTargetWinEnable(unit,winNum, MV_FALSE);
  49341. + }
  49342. +
  49343. + /* Go through all windows in user table until table terminator */
  49344. + for (winNum = 0; ((xorAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  49345. + (winNum < XOR_MAX_ADDR_DEC_WIN));)
  49346. + {
  49347. + /* first get attributes from CPU If */
  49348. + status = mvCpuIfTargetWinGet(xorAddrDecPrioTap[winPrioIndex],
  49349. + &cpuAddrDecWin);
  49350. +
  49351. + if(MV_NO_SUCH == status)
  49352. + {
  49353. + winPrioIndex++;
  49354. + continue;
  49355. + }
  49356. + if (MV_OK != status)
  49357. + {
  49358. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  49359. + return MV_ERROR;
  49360. + }
  49361. +
  49362. +
  49363. + if (cpuAddrDecWin.enable == MV_TRUE)
  49364. + {
  49365. +
  49366. + addrDecWin.target = xorAddrDecPrioTap[winPrioIndex];
  49367. + addrDecWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  49368. + addrDecWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  49369. + addrDecWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  49370. + addrDecWin.enable = MV_TRUE;
  49371. +
  49372. + if (MV_OK != mvXorTargetWinSet(unit,winNum, &addrDecWin))
  49373. + {
  49374. + DB(mvOsPrintf("mvXorInit: ERR. mvDmaTargetWinSet failed\n"));
  49375. + return MV_ERROR;
  49376. + }
  49377. + winNum++;
  49378. + }
  49379. + winPrioIndex++;
  49380. +
  49381. + }
  49382. +
  49383. + return MV_OK;
  49384. +}
  49385. +
  49386. +
  49387. +/*******************************************************************************
  49388. +* mvXorInit - Initialize XOR engine
  49389. +*
  49390. +* DESCRIPTION:
  49391. +* This function initialize XOR unit. It set the default address decode
  49392. +* windows of the unit.
  49393. +* Note that if the address window is disabled in xorAddrDecMap, the
  49394. +* window parameters will be set but the window will remain disabled.
  49395. +*
  49396. +* INPUT:
  49397. +* None.
  49398. +*
  49399. +* OUTPUT:
  49400. +* None.
  49401. +*
  49402. +* RETURN:
  49403. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  49404. +*******************************************************************************/
  49405. +MV_STATUS mvXorInit (MV_VOID)
  49406. +{
  49407. + MV_U32 i;
  49408. +
  49409. + /* Initiate XOR address decode */
  49410. + for(i = 0; i < MV_XOR_MAX_UNIT; i++)
  49411. + mvXorInitWinsUnit(i);
  49412. +
  49413. + mvXorHalInit(MV_XOR_MAX_CHAN);
  49414. +
  49415. + return MV_OK;
  49416. +}
  49417. +
  49418. +/*******************************************************************************
  49419. +* mvXorTargetWinSet - Set XOR target address window
  49420. +*
  49421. +* DESCRIPTION:
  49422. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  49423. +* address window. After setting this target window, the XOR will be
  49424. +* able to access the target within the address window.
  49425. +*
  49426. +* INPUT:
  49427. +* winNum - One of the possible XOR memory decode windows.
  49428. +* target - Peripheral target enumerator.
  49429. +* base - Window base address.
  49430. +* size - Window size.
  49431. +* enable - Window enable/disable.
  49432. +*
  49433. +* OUTPUT:
  49434. +* None.
  49435. +*
  49436. +* RETURN:
  49437. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  49438. +*
  49439. +*******************************************************************************/
  49440. +MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)
  49441. +{
  49442. + MV_DEC_REGS xorDecRegs;
  49443. + MV_TARGET_ATTRIB targetAttribs;
  49444. + MV_U32 chan;
  49445. +
  49446. + /* Parameter checking */
  49447. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  49448. + {
  49449. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum));
  49450. + return MV_BAD_PARAM;
  49451. + }
  49452. + if (pAddrDecWin == NULL)
  49453. + {
  49454. + DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));
  49455. + return MV_BAD_PTR;
  49456. + }
  49457. + /* Check if the requested window overlaps with current windows */
  49458. + if (MV_TRUE == xorWinOverlapDetect(unit, winNum, &pAddrDecWin->addrWin))
  49459. + {
  49460. + DB(mvOsPrintf("%s: ERR. Window %d overlap\n",__FUNCTION__,winNum));
  49461. + return MV_ERROR;
  49462. + }
  49463. +
  49464. + xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));
  49465. + xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));
  49466. +
  49467. + /* Get Base Address and size registers values */
  49468. + if(MV_OK != mvCtrlAddrDecToReg(&pAddrDecWin->addrWin, &xorDecRegs))
  49469. + {
  49470. + DB(mvOsPrintf("%s: ERR. Invalid addr dec window\n",__FUNCTION__));
  49471. + return MV_BAD_PARAM;
  49472. + }
  49473. +
  49474. +
  49475. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  49476. +
  49477. + /* set attributes */
  49478. + xorDecRegs.baseReg &= ~XEBARX_ATTR_MASK;
  49479. + xorDecRegs.baseReg |= targetAttribs.attrib << XEBARX_ATTR_OFFS;
  49480. + /* set target ID */
  49481. + xorDecRegs.baseReg &= ~XEBARX_TARGET_MASK;
  49482. + xorDecRegs.baseReg |= targetAttribs.targetId << XEBARX_TARGET_OFFS;
  49483. +
  49484. +
  49485. + /* Write to address decode Base Address Register */
  49486. + MV_REG_WRITE(XOR_BASE_ADDR_REG(unit,winNum), xorDecRegs.baseReg);
  49487. +
  49488. + /* Write to Size Register */
  49489. + MV_REG_WRITE(XOR_SIZE_MASK_REG(unit,winNum), xorDecRegs.sizeReg);
  49490. +
  49491. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  49492. + {
  49493. + if (pAddrDecWin->enable)
  49494. + {
  49495. + MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
  49496. + XEXWCR_WIN_EN_MASK(winNum));
  49497. + }
  49498. + else
  49499. + {
  49500. + MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
  49501. + XEXWCR_WIN_EN_MASK(winNum));
  49502. + }
  49503. + }
  49504. + return MV_OK;
  49505. +}
  49506. +
  49507. +/*******************************************************************************
  49508. +* mvXorTargetWinGet - Get xor peripheral target address window.
  49509. +*
  49510. +* DESCRIPTION:
  49511. +* Get xor peripheral target address window.
  49512. +*
  49513. +* INPUT:
  49514. +* winNum - One of the possible XOR memory decode windows.
  49515. +*
  49516. +* OUTPUT:
  49517. +* base - Window base address.
  49518. +* size - Window size.
  49519. +* enable - window enable/disable.
  49520. +*
  49521. +* RETURN:
  49522. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  49523. +*
  49524. +*******************************************************************************/
  49525. +MV_STATUS mvXorTargetWinGet(MV_U32 unit,MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)
  49526. +{
  49527. + MV_DEC_REGS xorDecRegs;
  49528. + MV_TARGET_ATTRIB targetAttrib;
  49529. + MV_U32 chan=0,chanWinEn;
  49530. +
  49531. + /* Parameter checking */
  49532. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  49533. + {
  49534. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__ , winNum));
  49535. + return MV_ERROR;
  49536. + }
  49537. +
  49538. + if (NULL == pAddrDecWin)
  49539. + {
  49540. + DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));
  49541. + return MV_BAD_PTR;
  49542. + }
  49543. +
  49544. + chanWinEn = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,0)) & XEXWCR_WIN_EN_MASK(winNum);
  49545. +
  49546. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++) /* we should scan here all channels per unit */
  49547. + {
  49548. + /* Check if enable bit is equal for all channels */
  49549. + if ((MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) &
  49550. + XEXWCR_WIN_EN_MASK(winNum)) != chanWinEn)
  49551. + {
  49552. + mvOsPrintf("%s: ERR. Window enable field must be equal in "
  49553. + "all channels(chan=%d)\n",__FUNCTION__, chan);
  49554. + return MV_ERROR;
  49555. + }
  49556. + }
  49557. +
  49558. +
  49559. +
  49560. + xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));
  49561. + xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));
  49562. +
  49563. + if (MV_OK != mvCtrlRegToAddrDec(&xorDecRegs, &pAddrDecWin->addrWin))
  49564. + {
  49565. + mvOsPrintf("%s: ERR. mvCtrlRegToAddrDec failed\n", __FUNCTION__);
  49566. + return MV_ERROR;
  49567. + }
  49568. +
  49569. + /* attrib and targetId */
  49570. + targetAttrib.attrib =
  49571. + (xorDecRegs.baseReg & XEBARX_ATTR_MASK) >> XEBARX_ATTR_OFFS;
  49572. + targetAttrib.targetId =
  49573. + (xorDecRegs.baseReg & XEBARX_TARGET_MASK) >> XEBARX_TARGET_OFFS;
  49574. +
  49575. +
  49576. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  49577. +
  49578. + if(chanWinEn)
  49579. + {
  49580. + pAddrDecWin->enable = MV_TRUE;
  49581. + }
  49582. + else pAddrDecWin->enable = MV_FALSE;
  49583. +
  49584. + return MV_OK;
  49585. +}
  49586. +
  49587. +/*******************************************************************************
  49588. +* mvXorTargetWinEnable - Enable/disable a Xor address decode window
  49589. +*
  49590. +* DESCRIPTION:
  49591. +* This function enable/disable a XOR address decode window.
  49592. +* if parameter 'enable' == MV_TRUE the routine will enable the
  49593. +* window, thus enabling XOR accesses (before enabling the window it is
  49594. +* tested for overlapping). Otherwise, the window will be disabled.
  49595. +*
  49596. +* INPUT:
  49597. +* winNum - Decode window number.
  49598. +* enable - Enable/disable parameter.
  49599. +*
  49600. +* OUTPUT:
  49601. +* None.
  49602. +*
  49603. +* RETURN:
  49604. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  49605. +*
  49606. +*******************************************************************************/
  49607. +MV_STATUS mvXorTargetWinEnable(MV_U32 unit,MV_U32 winNum, MV_BOOL enable)
  49608. +{
  49609. + MV_XOR_DEC_WIN addrDecWin;
  49610. + MV_U32 chan;
  49611. +
  49612. + /* Parameter checking */
  49613. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  49614. + {
  49615. + DB(mvOsPrintf("%s: ERR. Invalid winNum%d\n", __FUNCTION__, winNum));
  49616. + return MV_ERROR;
  49617. + }
  49618. +
  49619. + if (enable == MV_TRUE)
  49620. + {
  49621. + /* Get current window */
  49622. + if (MV_OK != mvXorTargetWinGet(unit,winNum, &addrDecWin))
  49623. + {
  49624. + DB(mvOsPrintf("%s: ERR. targetWinGet fail\n", __FUNCTION__));
  49625. + return MV_ERROR;
  49626. + }
  49627. +
  49628. + /* Check for overlapping */
  49629. + if (MV_TRUE == xorWinOverlapDetect(unit,winNum, &(addrDecWin.addrWin)))
  49630. + {
  49631. + /* Overlap detected */
  49632. + DB(mvOsPrintf("%s: ERR. Overlap detected\n", __FUNCTION__));
  49633. + return MV_ERROR;
  49634. + }
  49635. +
  49636. + /* No Overlap. Enable address decode target window */
  49637. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  49638. + {
  49639. + MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
  49640. + XEXWCR_WIN_EN_MASK(winNum));
  49641. + }
  49642. +
  49643. + }
  49644. + else
  49645. + {
  49646. + /* Disable address decode target window */
  49647. +
  49648. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  49649. + {
  49650. + MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
  49651. + XEXWCR_WIN_EN_MASK(winNum));
  49652. + }
  49653. +
  49654. + }
  49655. +
  49656. + return MV_OK;
  49657. +}
  49658. +
  49659. +/*******************************************************************************
  49660. +* mvXorSetProtWinSet - Configure access attributes of a XOR engine
  49661. +* to one of the XOR memory windows.
  49662. +*
  49663. +* DESCRIPTION:
  49664. +* Each engine can be configured with access attributes for each of the
  49665. +* memory spaces. This function sets access attributes
  49666. +* to a given window for the given engine
  49667. +*
  49668. +* INPUTS:
  49669. +* chan - One of the possible engines.
  49670. +* winNum - One of the possible XOR memory spaces.
  49671. +* access - Protection access rights.
  49672. +* write - Write rights.
  49673. +*
  49674. +* OUTPUT:
  49675. +* None.
  49676. +*
  49677. +* RETURN:
  49678. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  49679. +*
  49680. +*******************************************************************************/
  49681. +MV_STATUS mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access,
  49682. + MV_BOOL write)
  49683. +{
  49684. + MV_U32 temp;
  49685. +
  49686. + /* Parameter checking */
  49687. + if (chan >= MV_XOR_MAX_CHAN_PER_UNIT)
  49688. + {
  49689. + DB(mvOsPrintf("%s: ERR. Invalid chan num %d\n", __FUNCTION__ , chan));
  49690. + return MV_BAD_PARAM;
  49691. + }
  49692. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  49693. + {
  49694. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));
  49695. + return MV_BAD_PARAM;
  49696. + }
  49697. +
  49698. + temp = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) &
  49699. + (~XEXWCR_WIN_ACC_MASK(winNum));
  49700. +
  49701. + /* if access is disable */
  49702. + if (!access)
  49703. + {
  49704. + /* disable access */
  49705. + temp |= XEXWCR_WIN_ACC_NO_ACC(winNum);
  49706. + }
  49707. + /* if access is enable */
  49708. + else
  49709. + {
  49710. + /* if write is enable */
  49711. + if (write)
  49712. + {
  49713. + /* enable write */
  49714. + temp |= XEXWCR_WIN_ACC_RW(winNum);
  49715. + }
  49716. + /* if write is disable */
  49717. + else
  49718. + {
  49719. + /* disable write */
  49720. + temp |= XEXWCR_WIN_ACC_RO(winNum);
  49721. + }
  49722. + }
  49723. + MV_REG_WRITE(XOR_WINDOW_CTRL_REG(unit,chan),temp);
  49724. + return MV_OK;
  49725. +}
  49726. +
  49727. +/*******************************************************************************
  49728. +* mvXorPciRemap - Set XOR remap register for PCI address windows.
  49729. +*
  49730. +* DESCRIPTION:
  49731. +* only Windows 0-3 can be remapped.
  49732. +*
  49733. +* INPUT:
  49734. +* winNum - window number
  49735. +* pAddrDecWin - pointer to address space window structure
  49736. +* OUTPUT:
  49737. +* None.
  49738. +*
  49739. +* RETURN:
  49740. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  49741. +*
  49742. +*******************************************************************************/
  49743. +MV_STATUS mvXorPciRemap(MV_U32 unit,MV_U32 winNum, MV_U32 addrHigh)
  49744. +{
  49745. + /* Parameter checking */
  49746. + if (winNum >= XOR_MAX_REMAP_WIN)
  49747. + {
  49748. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));
  49749. + return MV_BAD_PARAM;
  49750. + }
  49751. +
  49752. + MV_REG_WRITE(XOR_HIGH_ADDR_REMAP_REG(unit,winNum), addrHigh);
  49753. +
  49754. + return MV_OK;
  49755. +}
  49756. +
  49757. +/*******************************************************************************
  49758. +* xorWinOverlapDetect - Detect XOR address windows overlaping
  49759. +*
  49760. +* DESCRIPTION:
  49761. +* An unpredicted behaviour is expected in case XOR address decode
  49762. +* windows overlaps.
  49763. +* This function detects XOR address decode windows overlaping of a
  49764. +* specified window. The function does not check the window itself for
  49765. +* overlaping. The function also skipps disabled address decode windows.
  49766. +*
  49767. +* INPUT:
  49768. +* winNum - address decode window number.
  49769. +* pAddrDecWin - An address decode window struct.
  49770. +*
  49771. +* OUTPUT:
  49772. +* None.
  49773. +*
  49774. +* RETURN:
  49775. +* MV_TRUE if the given address window overlap current address
  49776. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  49777. +* from registers.
  49778. +*
  49779. +*******************************************************************************/
  49780. +static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  49781. +{
  49782. + MV_U32 baseAddrEnableReg;
  49783. + MV_U32 winNumIndex,chan;
  49784. + MV_XOR_DEC_WIN addrDecWin;
  49785. +
  49786. + if (pAddrWin == NULL)
  49787. + {
  49788. + DB(mvOsPrintf("%s: ERR. pAddrWin is NULL pointer\n", __FUNCTION__ ));
  49789. + return MV_BAD_PTR;
  49790. + }
  49791. +
  49792. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  49793. + {
  49794. + /* Read base address enable register. Do not check disabled windows */
  49795. + baseAddrEnableReg = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan));
  49796. +
  49797. + for (winNumIndex = 0; winNumIndex < XOR_MAX_ADDR_DEC_WIN; winNumIndex++)
  49798. + {
  49799. + /* Do not check window itself */
  49800. + if (winNumIndex == winNum)
  49801. + {
  49802. + continue;
  49803. + }
  49804. +
  49805. + /* Do not check disabled windows */
  49806. + if ((baseAddrEnableReg & XEXWCR_WIN_EN_MASK(winNumIndex)) == 0)
  49807. + {
  49808. + continue;
  49809. + }
  49810. +
  49811. + /* Get window parameters */
  49812. + if (MV_OK != mvXorTargetWinGet(unit,winNumIndex, &addrDecWin))
  49813. + {
  49814. + DB(mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__ ));
  49815. + return MV_ERROR;
  49816. + }
  49817. +
  49818. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  49819. + {
  49820. + return MV_TRUE;
  49821. + }
  49822. + }
  49823. + }
  49824. +
  49825. + return MV_FALSE;
  49826. +}
  49827. +
  49828. +static MV_VOID mvXorAddrDecShowUnit(MV_U32 unit)
  49829. +{
  49830. + MV_XOR_DEC_WIN win;
  49831. + int i;
  49832. +
  49833. + mvOsOutput( "\n" );
  49834. + mvOsOutput( "XOR %d:\n", unit );
  49835. + mvOsOutput( "----\n" );
  49836. +
  49837. + for( i = 0; i < XOR_MAX_ADDR_DEC_WIN; i++ )
  49838. + {
  49839. + memset( &win, 0, sizeof(MV_XOR_DEC_WIN) );
  49840. +
  49841. + mvOsOutput( "win%d - ", i );
  49842. +
  49843. + if( mvXorTargetWinGet(unit, i, &win ) == MV_OK )
  49844. + {
  49845. + if( win.enable )
  49846. + {
  49847. + mvOsOutput( "%s base %x, ",
  49848. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  49849. +
  49850. + mvSizePrint( win.addrWin.size );
  49851. +
  49852. + mvOsOutput( "\n" );
  49853. + }
  49854. + else
  49855. + mvOsOutput( "disable\n" );
  49856. + }
  49857. + }
  49858. +}
  49859. +
  49860. +/*******************************************************************************
  49861. +* mvXorAddrDecShow - Print the XOR address decode map.
  49862. +*
  49863. +* DESCRIPTION:
  49864. +* This function print the XOR address decode map.
  49865. +*
  49866. +* INPUT:
  49867. +* None.
  49868. +*
  49869. +* OUTPUT:
  49870. +* None.
  49871. +*
  49872. +* RETURN:
  49873. +* None.
  49874. +*
  49875. +*******************************************************************************/
  49876. +MV_VOID mvXorAddrDecShow(MV_VOID)
  49877. +{
  49878. + int i;
  49879. +
  49880. + for( i = 0; i < MV_XOR_MAX_UNIT; i++ )
  49881. + mvXorAddrDecShowUnit(i);
  49882. +
  49883. +}
  49884. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h
  49885. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h 1970-01-01 01:00:00.000000000 +0100
  49886. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h 2010-11-09 20:28:10.062495382 +0100
  49887. @@ -0,0 +1,140 @@
  49888. +/*******************************************************************************
  49889. +Copyright (C) Marvell International Ltd. and its affiliates
  49890. +
  49891. +This software file (the "File") is owned and distributed by Marvell
  49892. +International Ltd. and/or its affiliates ("Marvell") under the following
  49893. +alternative licensing terms. Once you have made an election to distribute the
  49894. +File under one of the following license alternatives, please (i) delete this
  49895. +introductory statement regarding license alternatives, (ii) delete the two
  49896. +license alternatives that you have not elected to use and (iii) preserve the
  49897. +Marvell copyright notice above.
  49898. +
  49899. +********************************************************************************
  49900. +Marvell Commercial License Option
  49901. +
  49902. +If you received this File from Marvell and you have entered into a commercial
  49903. +license agreement (a "Commercial License") with Marvell, the File is licensed
  49904. +to you under the terms of the applicable Commercial License.
  49905. +
  49906. +********************************************************************************
  49907. +Marvell GPL License Option
  49908. +
  49909. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49910. +modify this File in accordance with the terms and conditions of the General
  49911. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  49912. +available along with the File in the license.txt file or by writing to the Free
  49913. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  49914. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  49915. +
  49916. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  49917. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  49918. +DISCLAIMED. The GPL License provides additional details about this warranty
  49919. +disclaimer.
  49920. +********************************************************************************
  49921. +Marvell BSD License Option
  49922. +
  49923. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49924. +modify this File under the following licensing terms.
  49925. +Redistribution and use in source and binary forms, with or without modification,
  49926. +are permitted provided that the following conditions are met:
  49927. +
  49928. + * Redistributions of source code must retain the above copyright notice,
  49929. + this list of conditions and the following disclaimer.
  49930. +
  49931. + * Redistributions in binary form must reproduce the above copyright
  49932. + notice, this list of conditions and the following disclaimer in the
  49933. + documentation and/or other materials provided with the distribution.
  49934. +
  49935. + * Neither the name of Marvell nor the names of its contributors may be
  49936. + used to endorse or promote products derived from this software without
  49937. + specific prior written permission.
  49938. +
  49939. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  49940. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49941. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  49942. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  49943. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  49944. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  49945. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  49946. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  49947. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  49948. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49949. +
  49950. +*******************************************************************************/
  49951. +
  49952. +#ifndef __INCMVSysXorh
  49953. +#define __INCMVSysXorh
  49954. +
  49955. +
  49956. +#ifdef __cplusplus
  49957. +extern "C" {
  49958. +#endif
  49959. +
  49960. +#include "ctrlEnv/sys/mvCpuIf.h"
  49961. +
  49962. +#include "ctrlEnv/mvCtrlEnvLib.h"
  49963. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  49964. +
  49965. +#define XOR_MAX_ADDR_DEC_WIN 8 /* Maximum address decode windows */
  49966. +#define XOR_MAX_REMAP_WIN 4 /* Maximum address arbiter windows */
  49967. +
  49968. +/* XOR Engine Address Decoding Register Map */
  49969. +#define XOR_WINDOW_CTRL_REG(unit,chan) (XOR_UNIT_BASE(unit)+(0x240 + ((chan) * 4)))
  49970. +#define XOR_BASE_ADDR_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x250 + ((winNum) * 4)))
  49971. +#define XOR_SIZE_MASK_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x270 + ((winNum) * 4)))
  49972. +#define XOR_HIGH_ADDR_REMAP_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x290 + ((winNum) * 4)))
  49973. +
  49974. +/* XOR Engine [0..1] Window Control Registers (XExWCR) */
  49975. +#define XEXWCR_WIN_EN_OFFS(winNum) (winNum)
  49976. +#define XEXWCR_WIN_EN_MASK(winNum) (1 << (XEXWCR_WIN_EN_OFFS(winNum)))
  49977. +#define XEXWCR_WIN_EN_ENABLE(winNum) (1 << (XEXWCR_WIN_EN_OFFS(winNum)))
  49978. +#define XEXWCR_WIN_EN_DISABLE(winNum) (0 << (XEXWCR_WIN_EN_OFFS(winNum)))
  49979. +
  49980. +#define XEXWCR_WIN_ACC_OFFS(winNum) ((2 * winNum) + 16)
  49981. +#define XEXWCR_WIN_ACC_MASK(winNum) (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  49982. +#define XEXWCR_WIN_ACC_NO_ACC(winNum) (0 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  49983. +#define XEXWCR_WIN_ACC_RO(winNum) (1 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  49984. +#define XEXWCR_WIN_ACC_RW(winNum) (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  49985. +
  49986. +/* XOR Engine Base Address Registers (XEBARx) */
  49987. +#define XEBARX_TARGET_OFFS (0)
  49988. +#define XEBARX_TARGET_MASK (0xF << XEBARX_TARGET_OFFS)
  49989. +#define XEBARX_ATTR_OFFS (8)
  49990. +#define XEBARX_ATTR_MASK (0xFF << XEBARX_ATTR_OFFS)
  49991. +#define XEBARX_BASE_OFFS (16)
  49992. +#define XEBARX_BASE_MASK (0xFFFF << XEBARX_BASE_OFFS)
  49993. +
  49994. +/* XOR Engine Size Mask Registers (XESMRx) */
  49995. +#define XESMRX_SIZE_MASK_OFFS (16)
  49996. +#define XESMRX_SIZE_MASK_MASK (0xFFFF << XESMRX_SIZE_MASK_OFFS)
  49997. +
  49998. +/* XOR Engine High Address Remap Register (XEHARRx1) */
  49999. +#define XEHARRX_REMAP_OFFS (0)
  50000. +#define XEHARRX_REMAP_MASK (0xFFFFFFFF << XEHARRX_REMAP_OFFS)
  50001. +
  50002. +typedef struct _mvXorDecWin
  50003. +{
  50004. + MV_TARGET target;
  50005. + MV_ADDR_WIN addrWin; /* An address window*/
  50006. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  50007. +
  50008. +}MV_XOR_DEC_WIN;
  50009. +
  50010. +MV_STATUS mvXorInit (MV_VOID);
  50011. +MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum,
  50012. + MV_XOR_DEC_WIN *pAddrDecWin);
  50013. +MV_STATUS mvXorTargetWinGet(MV_U32 unit, MV_U32 winNum,
  50014. + MV_XOR_DEC_WIN *pAddrDecWin);
  50015. +MV_STATUS mvXorTargetWinEnable(MV_U32 unit,
  50016. + MV_U32 winNum, MV_BOOL enable);
  50017. +MV_STATUS mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access,
  50018. + MV_BOOL write);
  50019. +MV_STATUS mvXorPciRemap(MV_U32 unit, MV_U32 winNum, MV_U32 addrHigh);
  50020. +
  50021. +MV_VOID mvXorAddrDecShow(MV_VOID);
  50022. +
  50023. +#ifdef __cplusplus
  50024. +}
  50025. +#endif
  50026. +
  50027. +#endif
  50028. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c
  50029. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c 1970-01-01 01:00:00.000000000 +0100
  50030. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c 2010-11-09 20:28:10.101392611 +0100
  50031. @@ -0,0 +1,75 @@
  50032. +/*******************************************************************************
  50033. +Copyright (C) Marvell International Ltd. and its affiliates
  50034. +
  50035. +This software file (the "File") is owned and distributed by Marvell
  50036. +International Ltd. and/or its affiliates ("Marvell") under the following
  50037. +alternative licensing terms. Once you have made an election to distribute the
  50038. +File under one of the following license alternatives, please (i) delete this
  50039. +introductory statement regarding license alternatives, (ii) delete the two
  50040. +license alternatives that you have not elected to use and (iii) preserve the
  50041. +Marvell copyright notice above.
  50042. +
  50043. +********************************************************************************
  50044. +Marvell Commercial License Option
  50045. +
  50046. +If you received this File from Marvell and you have entered into a commercial
  50047. +license agreement (a "Commercial License") with Marvell, the File is licensed
  50048. +to you under the terms of the applicable Commercial License.
  50049. +
  50050. +********************************************************************************
  50051. +Marvell GPL License Option
  50052. +
  50053. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50054. +modify this File in accordance with the terms and conditions of the General
  50055. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50056. +available along with the File in the license.txt file or by writing to the Free
  50057. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50058. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50059. +
  50060. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50061. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50062. +DISCLAIMED. The GPL License provides additional details about this warranty
  50063. +disclaimer.
  50064. +********************************************************************************
  50065. +Marvell BSD License Option
  50066. +
  50067. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50068. +modify this File under the following licensing terms.
  50069. +Redistribution and use in source and binary forms, with or without modification,
  50070. +are permitted provided that the following conditions are met:
  50071. +
  50072. + * Redistributions of source code must retain the above copyright notice,
  50073. + this list of conditions and the following disclaimer.
  50074. +
  50075. + * Redistributions in binary form must reproduce the above copyright
  50076. + notice, this list of conditions and the following disclaimer in the
  50077. + documentation and/or other materials provided with the distribution.
  50078. +
  50079. + * Neither the name of Marvell nor the names of its contributors may be
  50080. + used to endorse or promote products derived from this software without
  50081. + specific prior written permission.
  50082. +
  50083. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  50084. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  50085. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  50086. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  50087. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  50088. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  50089. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  50090. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50091. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  50092. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50093. +
  50094. +*******************************************************************************/
  50095. +
  50096. +#include "device/mvDevice.h"
  50097. +
  50098. +/* defines */
  50099. +#ifdef MV_DEBUG
  50100. + #define DB(x) x
  50101. +#else
  50102. + #define DB(x)
  50103. +#endif
  50104. +
  50105. +
  50106. +
  50107. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h
  50108. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h 1970-01-01 01:00:00.000000000 +0100
  50109. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h 2010-11-09 20:28:10.141918633 +0100
  50110. @@ -0,0 +1,74 @@
  50111. +/*******************************************************************************
  50112. +Copyright (C) Marvell International Ltd. and its affiliates
  50113. +
  50114. +This software file (the "File") is owned and distributed by Marvell
  50115. +International Ltd. and/or its affiliates ("Marvell") under the following
  50116. +alternative licensing terms. Once you have made an election to distribute the
  50117. +File under one of the following license alternatives, please (i) delete this
  50118. +introductory statement regarding license alternatives, (ii) delete the two
  50119. +license alternatives that you have not elected to use and (iii) preserve the
  50120. +Marvell copyright notice above.
  50121. +
  50122. +********************************************************************************
  50123. +Marvell Commercial License Option
  50124. +
  50125. +If you received this File from Marvell and you have entered into a commercial
  50126. +license agreement (a "Commercial License") with Marvell, the File is licensed
  50127. +to you under the terms of the applicable Commercial License.
  50128. +
  50129. +********************************************************************************
  50130. +Marvell GPL License Option
  50131. +
  50132. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50133. +modify this File in accordance with the terms and conditions of the General
  50134. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50135. +available along with the File in the license.txt file or by writing to the Free
  50136. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50137. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50138. +
  50139. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50140. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50141. +DISCLAIMED. The GPL License provides additional details about this warranty
  50142. +disclaimer.
  50143. +********************************************************************************
  50144. +Marvell BSD License Option
  50145. +
  50146. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50147. +modify this File under the following licensing terms.
  50148. +Redistribution and use in source and binary forms, with or without modification,
  50149. +are permitted provided that the following conditions are met:
  50150. +
  50151. + * Redistributions of source code must retain the above copyright notice,
  50152. + this list of conditions and the following disclaimer.
  50153. +
  50154. + * Redistributions in binary form must reproduce the above copyright
  50155. + notice, this list of conditions and the following disclaimer in the
  50156. + documentation and/or other materials provided with the distribution.
  50157. +
  50158. + * Neither the name of Marvell nor the names of its contributors may be
  50159. + used to endorse or promote products derived from this software without
  50160. + specific prior written permission.
  50161. +
  50162. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  50163. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  50164. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  50165. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  50166. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  50167. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  50168. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  50169. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50170. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  50171. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50172. +
  50173. +*******************************************************************************/
  50174. +
  50175. +#ifndef __INCmvDeviceH
  50176. +#define __INCmvDeviceH
  50177. +
  50178. +#include "mvCommon.h"
  50179. +#include "mvOs.h"
  50180. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  50181. +#include "device/mvDeviceRegs.h"
  50182. +
  50183. +
  50184. +#endif /* #ifndef __INCmvDeviceH */
  50185. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h
  50186. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h 1970-01-01 01:00:00.000000000 +0100
  50187. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h 2010-11-09 20:28:10.181250318 +0100
  50188. @@ -0,0 +1,101 @@
  50189. +/*******************************************************************************
  50190. +Copyright (C) Marvell International Ltd. and its affiliates
  50191. +
  50192. +This software file (the "File") is owned and distributed by Marvell
  50193. +International Ltd. and/or its affiliates ("Marvell") under the following
  50194. +alternative licensing terms. Once you have made an election to distribute the
  50195. +File under one of the following license alternatives, please (i) delete this
  50196. +introductory statement regarding license alternatives, (ii) delete the two
  50197. +license alternatives that you have not elected to use and (iii) preserve the
  50198. +Marvell copyright notice above.
  50199. +
  50200. +********************************************************************************
  50201. +Marvell Commercial License Option
  50202. +
  50203. +If you received this File from Marvell and you have entered into a commercial
  50204. +license agreement (a "Commercial License") with Marvell, the File is licensed
  50205. +to you under the terms of the applicable Commercial License.
  50206. +
  50207. +********************************************************************************
  50208. +Marvell GPL License Option
  50209. +
  50210. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50211. +modify this File in accordance with the terms and conditions of the General
  50212. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50213. +available along with the File in the license.txt file or by writing to the Free
  50214. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50215. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50216. +
  50217. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50218. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50219. +DISCLAIMED. The GPL License provides additional details about this warranty
  50220. +disclaimer.
  50221. +********************************************************************************
  50222. +Marvell BSD License Option
  50223. +
  50224. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50225. +modify this File under the following licensing terms.
  50226. +Redistribution and use in source and binary forms, with or without modification,
  50227. +are permitted provided that the following conditions are met:
  50228. +
  50229. + * Redistributions of source code must retain the above copyright notice,
  50230. + this list of conditions and the following disclaimer.
  50231. +
  50232. + * Redistributions in binary form must reproduce the above copyright
  50233. + notice, this list of conditions and the following disclaimer in the
  50234. + documentation and/or other materials provided with the distribution.
  50235. +
  50236. + * Neither the name of Marvell nor the names of its contributors may be
  50237. + used to endorse or promote products derived from this software without
  50238. + specific prior written permission.
  50239. +
  50240. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  50241. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  50242. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  50243. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  50244. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  50245. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  50246. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  50247. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50248. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  50249. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50250. +
  50251. +*******************************************************************************/
  50252. +
  50253. +#ifndef __INCmvDeviceRegsH
  50254. +#define __INCmvDeviceRegsH
  50255. +
  50256. +#ifndef MV_ASMLANGUAGE
  50257. +#include "ctrlEnv/mvCtrlEnvLib.h"
  50258. +/* This enumerator describes the Marvell controller possible devices that */
  50259. +/* can be connected to its device interface. */
  50260. +typedef enum _mvDevice
  50261. +{
  50262. +#if defined(MV_INCLUDE_DEVICE_CS0)
  50263. + DEV_CS0 = 0, /* Device connected to dev CS[0] */
  50264. +#endif
  50265. +#if defined(MV_INCLUDE_DEVICE_CS1)
  50266. + DEV_CS1 = 1, /* Device connected to dev CS[1] */
  50267. +#endif
  50268. +#if defined(MV_INCLUDE_DEVICE_CS2)
  50269. + DEV_CS2 = 2, /* Device connected to dev CS[2] */
  50270. +#endif
  50271. +#if defined(MV_INCLUDE_DEVICE_CS3)
  50272. + DEV_CS3 = 3, /* Device connected to dev CS[2] */
  50273. +#endif
  50274. +#if defined(MV_INCLUDE_DEVICE_CS4)
  50275. + DEV_CS4 = 4, /* Device connected to BOOT dev */
  50276. +#endif
  50277. + MV_DEV_MAX_CS = MV_DEVICE_MAX_CS
  50278. +}MV_DEVICE;
  50279. +
  50280. +
  50281. +#endif /* MV_ASMLANGUAGE */
  50282. +
  50283. +
  50284. +#define NAND_CTRL_REG 0x10470
  50285. +
  50286. +#define NAND_ACTCEBOOT_BIT BIT1
  50287. +
  50288. +
  50289. +#endif /* #ifndef __INCmvDeviceRegsH */
  50290. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c
  50291. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c 1970-01-01 01:00:00.000000000 +0100
  50292. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c 2010-11-09 20:28:10.222495542 +0100
  50293. @@ -0,0 +1,211 @@
  50294. +/*******************************************************************************
  50295. +Copyright (C) Marvell International Ltd. and its affiliates
  50296. +
  50297. +This software file (the "File") is owned and distributed by Marvell
  50298. +International Ltd. and/or its affiliates ("Marvell") under the following
  50299. +alternative licensing terms. Once you have made an election to distribute the
  50300. +File under one of the following license alternatives, please (i) delete this
  50301. +introductory statement regarding license alternatives, (ii) delete the two
  50302. +license alternatives that you have not elected to use and (iii) preserve the
  50303. +Marvell copyright notice above.
  50304. +
  50305. +
  50306. +********************************************************************************
  50307. +Marvell GPL License Option
  50308. +
  50309. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50310. +modify this File in accordance with the terms and conditions of the General
  50311. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50312. +available along with the File in the license.txt file or by writing to the Free
  50313. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50314. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50315. +
  50316. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50317. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50318. +DISCLAIMED. The GPL License provides additional details about this warranty
  50319. +disclaimer.
  50320. +*******************************************************************************/
  50321. +/*******************************************************************************
  50322. +* mvOsCpuArchLib.c - Marvell CPU architecture library
  50323. +*
  50324. +* DESCRIPTION:
  50325. +* This library introduce Marvell API for OS dependent CPU architecture
  50326. +* APIs. This library introduce single CPU architecture services APKI
  50327. +* cross OS.
  50328. +*
  50329. +* DEPENDENCIES:
  50330. +* None.
  50331. +*
  50332. +*******************************************************************************/
  50333. +
  50334. +/* includes */
  50335. +#include <asm/processor.h>
  50336. +#include "mvOs.h"
  50337. +
  50338. +static MV_U32 read_p15_c0 (void);
  50339. +
  50340. +/* defines */
  50341. +#define ARM_ID_REVISION_OFFS 0
  50342. +#define ARM_ID_REVISION_MASK (0xf << ARM_ID_REVISION_OFFS)
  50343. +
  50344. +#define ARM_ID_PART_NUM_OFFS 4
  50345. +#define ARM_ID_PART_NUM_MASK (0xfff << ARM_ID_PART_NUM_OFFS)
  50346. +
  50347. +#define ARM_ID_ARCH_OFFS 16
  50348. +#define ARM_ID_ARCH_MASK (0xf << ARM_ID_ARCH_OFFS)
  50349. +
  50350. +#define ARM_ID_VAR_OFFS 20
  50351. +#define ARM_ID_VAR_MASK (0xf << ARM_ID_VAR_OFFS)
  50352. +
  50353. +#define ARM_ID_ASCII_OFFS 24
  50354. +#define ARM_ID_ASCII_MASK (0xff << ARM_ID_ASCII_OFFS)
  50355. +
  50356. +
  50357. +
  50358. +void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,
  50359. + MV_U32 *memHandle)
  50360. +{
  50361. + void *p = kmalloc( size, GFP_KERNEL );
  50362. + *pPhyAddr = pci_map_single( osHandle, p, 0, PCI_DMA_BIDIRECTIONAL );
  50363. + return p;
  50364. +}
  50365. +void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,
  50366. + MV_U32 *memHandle)
  50367. +{
  50368. + return pci_alloc_consistent( osHandle, size, (dma_addr_t *)pPhyAddr );
  50369. +}
  50370. +
  50371. +void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,
  50372. + MV_U32 memHandle)
  50373. +{
  50374. + return pci_free_consistent( osHandle, size, pVirtAddr, (dma_addr_t)phyAddr );
  50375. +}
  50376. +
  50377. +void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,
  50378. + MV_U32 memHandle )
  50379. +{
  50380. + return kfree( pVirtAddr );
  50381. +}
  50382. +
  50383. +int mvOsRand(void)
  50384. +{
  50385. + int rand;
  50386. + get_random_bytes(&rand, sizeof(rand) );
  50387. + return rand;
  50388. +}
  50389. +
  50390. +/*******************************************************************************
  50391. +* mvOsCpuVerGet() -
  50392. +*
  50393. +* DESCRIPTION:
  50394. +*
  50395. +* INPUT:
  50396. +* None.
  50397. +*
  50398. +* OUTPUT:
  50399. +* None.
  50400. +*
  50401. +* RETURN:
  50402. +* 32bit CPU Revision
  50403. +*
  50404. +*******************************************************************************/
  50405. +MV_U32 mvOsCpuRevGet( MV_VOID )
  50406. +{
  50407. + return ((read_p15_c0() & ARM_ID_REVISION_MASK ) >> ARM_ID_REVISION_OFFS);
  50408. +}
  50409. +/*******************************************************************************
  50410. +* mvOsCpuPartGet() -
  50411. +*
  50412. +* DESCRIPTION:
  50413. +*
  50414. +* INPUT:
  50415. +* None.
  50416. +*
  50417. +* OUTPUT:
  50418. +* None.
  50419. +*
  50420. +* RETURN:
  50421. +* 32bit CPU Part number
  50422. +*
  50423. +*******************************************************************************/
  50424. +MV_U32 mvOsCpuPartGet( MV_VOID )
  50425. +{
  50426. + return ((read_p15_c0() & ARM_ID_PART_NUM_MASK ) >> ARM_ID_PART_NUM_OFFS);
  50427. +}
  50428. +/*******************************************************************************
  50429. +* mvOsCpuArchGet() -
  50430. +*
  50431. +* DESCRIPTION:
  50432. +*
  50433. +* INPUT:
  50434. +* None.
  50435. +*
  50436. +* OUTPUT:
  50437. +* None.
  50438. +*
  50439. +* RETURN:
  50440. +* 32bit CPU Architicture number
  50441. +*
  50442. +*******************************************************************************/
  50443. +MV_U32 mvOsCpuArchGet( MV_VOID )
  50444. +{
  50445. + return ((read_p15_c0() & ARM_ID_ARCH_MASK ) >> ARM_ID_ARCH_OFFS);
  50446. +}
  50447. +/*******************************************************************************
  50448. +* mvOsCpuVarGet() -
  50449. +*
  50450. +* DESCRIPTION:
  50451. +*
  50452. +* INPUT:
  50453. +* None.
  50454. +*
  50455. +* OUTPUT:
  50456. +* None.
  50457. +*
  50458. +* RETURN:
  50459. +* 32bit CPU Variant number
  50460. +*
  50461. +*******************************************************************************/
  50462. +MV_U32 mvOsCpuVarGet( MV_VOID )
  50463. +{
  50464. + return ((read_p15_c0() & ARM_ID_VAR_MASK ) >> ARM_ID_VAR_OFFS);
  50465. +}
  50466. +/*******************************************************************************
  50467. +* mvOsCpuAsciiGet() -
  50468. +*
  50469. +* DESCRIPTION:
  50470. +*
  50471. +* INPUT:
  50472. +* None.
  50473. +*
  50474. +* OUTPUT:
  50475. +* None.
  50476. +*
  50477. +* RETURN:
  50478. +* 32bit CPU Variant number
  50479. +*
  50480. +*******************************************************************************/
  50481. +MV_U32 mvOsCpuAsciiGet( MV_VOID )
  50482. +{
  50483. + return ((read_p15_c0() & ARM_ID_ASCII_MASK ) >> ARM_ID_ASCII_OFFS);
  50484. +}
  50485. +
  50486. +
  50487. +
  50488. +/*
  50489. +static unsigned long read_p15_c0 (void)
  50490. +*/
  50491. +/* read co-processor 15, register #0 (ID register) */
  50492. +static MV_U32 read_p15_c0 (void)
  50493. +{
  50494. + MV_U32 value;
  50495. +
  50496. + __asm__ __volatile__(
  50497. + "mrc p15, 0, %0, c0, c0, 0 @ read control reg\n"
  50498. + : "=r" (value)
  50499. + :
  50500. + : "memory");
  50501. +
  50502. + return value;
  50503. +}
  50504. +
  50505. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h
  50506. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h 1970-01-01 01:00:00.000000000 +0100
  50507. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h 2010-11-09 20:28:10.262495482 +0100
  50508. @@ -0,0 +1,423 @@
  50509. +/*******************************************************************************
  50510. +Copyright (C) Marvell International Ltd. and its affiliates
  50511. +
  50512. +This software file (the "File") is owned and distributed by Marvell
  50513. +International Ltd. and/or its affiliates ("Marvell") under the following
  50514. +alternative licensing terms. Once you have made an election to distribute the
  50515. +File under one of the following license alternatives, please (i) delete this
  50516. +introductory statement regarding license alternatives, (ii) delete the two
  50517. +license alternatives that you have not elected to use and (iii) preserve the
  50518. +Marvell copyright notice above.
  50519. +
  50520. +
  50521. +********************************************************************************
  50522. +Marvell GPL License Option
  50523. +
  50524. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50525. +modify this File in accordance with the terms and conditions of the General
  50526. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50527. +available along with the File in the license.txt file or by writing to the Free
  50528. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50529. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50530. +
  50531. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50532. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50533. +DISCLAIMED. The GPL License provides additional details about this warranty
  50534. +disclaimer.
  50535. +*******************************************************************************/
  50536. +#ifndef _MV_OS_LNX_H_
  50537. +#define _MV_OS_LNX_H_
  50538. +
  50539. +
  50540. +#ifdef __KERNEL__
  50541. +/* for kernel space */
  50542. +#include <linux/autoconf.h>
  50543. +#include <linux/interrupt.h>
  50544. +#include <linux/stddef.h>
  50545. +#include <linux/kernel.h>
  50546. +#include <linux/init.h>
  50547. +#include <linux/errno.h>
  50548. +#include <linux/reboot.h>
  50549. +#include <linux/pci.h>
  50550. +#include <linux/kdev_t.h>
  50551. +#include <linux/major.h>
  50552. +#include <linux/blkdev.h>
  50553. +#include <linux/console.h>
  50554. +#include <linux/delay.h>
  50555. +#include <linux/seq_file.h>
  50556. +#include <linux/string.h>
  50557. +#include <linux/slab.h>
  50558. +#include <linux/kernel.h>
  50559. +#include <linux/string.h>
  50560. +#include <linux/slab.h>
  50561. +#include <linux/mm.h>
  50562. +
  50563. +#include <asm/system.h>
  50564. +#include <asm/pgtable.h>
  50565. +#include <asm/page.h>
  50566. +#include <asm/hardirq.h>
  50567. +#include <asm/dma.h>
  50568. +#include <asm/io.h>
  50569. +
  50570. +#include <linux/random.h>
  50571. +
  50572. +#include "dbg-trace.h"
  50573. +
  50574. +extern void mv_early_printk(char *fmt,...);
  50575. +
  50576. +#define MV_ASM __asm__ __volatile__
  50577. +#define INLINE inline
  50578. +#define MV_TRC_REC TRC_REC
  50579. +#define mvOsPrintf printk
  50580. +#define mvOsEarlyPrintf mv_early_printk
  50581. +#define mvOsOutput printk
  50582. +#define mvOsSPrintf sprintf
  50583. +#define mvOsMalloc(_size_) kmalloc(_size_,GFP_ATOMIC)
  50584. +#define mvOsFree kfree
  50585. +#define mvOsMemcpy memcpy
  50586. +#define mvOsSleep(_mils_) mdelay(_mils_)
  50587. +#define mvOsTaskLock()
  50588. +#define mvOsTaskUnlock()
  50589. +#define strtol simple_strtoul
  50590. +#define mvOsDelay(x) mdelay(x)
  50591. +#define mvOsUDelay(x) udelay(x)
  50592. +#define mvCopyFromOs copy_from_user
  50593. +#define mvCopyToOs copy_to_user
  50594. +
  50595. +
  50596. +#include "mvTypes.h"
  50597. +#include "mvCommon.h"
  50598. +
  50599. +#ifdef MV_NDEBUG
  50600. +#define mvOsAssert(cond)
  50601. +#else
  50602. +#define mvOsAssert(cond) { do { if(!(cond)) { BUG(); } }while(0); }
  50603. +#endif /* MV_NDEBUG */
  50604. +
  50605. +#else /* __KERNEL__ */
  50606. +
  50607. +/* for user space applications */
  50608. +#include <stdlib.h>
  50609. +#include <stdio.h>
  50610. +#include <assert.h>
  50611. +#include <string.h>
  50612. +
  50613. +#define INLINE inline
  50614. +#define mvOsPrintf printf
  50615. +#define mvOsOutput printf
  50616. +#define mvOsMalloc(_size_) malloc(_size_)
  50617. +#define mvOsFree free
  50618. +#define mvOsAssert(cond) assert(cond)
  50619. +
  50620. +#endif /* __KERNEL__ */
  50621. +#define mvOsIoVirtToPhy(pDev, pVirtAddr) \
  50622. + pci_map_single( (pDev), (pVirtAddr), 0, PCI_DMA_BIDIRECTIONAL )
  50623. +
  50624. +#define mvOsCacheClear(pDev, p, size ) \
  50625. + pci_map_single( (pDev), (p), (size), PCI_DMA_BIDIRECTIONAL)
  50626. +
  50627. +#define mvOsCacheFlush(pDev, p, size ) \
  50628. + pci_map_single( (pDev), (p), (size), PCI_DMA_TODEVICE)
  50629. +
  50630. +#define mvOsCacheInvalidate(pDev, p, size) \
  50631. + pci_map_single( (pDev), (p), (size), PCI_DMA_FROMDEVICE )
  50632. +
  50633. +#define mvOsCacheUnmap(pDev, phys, size) \
  50634. + pci_unmap_single( (pDev), (dma_addr_t)(phys), (size), PCI_DMA_FROMDEVICE )
  50635. +
  50636. +
  50637. +#define CPU_PHY_MEM(x) (MV_U32)x
  50638. +#define CPU_MEMIO_CACHED_ADDR(x) (void*)x
  50639. +#define CPU_MEMIO_UNCACHED_ADDR(x) (void*)x
  50640. +
  50641. +
  50642. +/* CPU architecture dependent 32, 16, 8 bit read/write IO addresses */
  50643. +#define MV_MEMIO32_WRITE(addr, data) \
  50644. + ((*((volatile unsigned int*)(addr))) = ((unsigned int)(data)))
  50645. +
  50646. +#define MV_MEMIO32_READ(addr) \
  50647. + ((*((volatile unsigned int*)(addr))))
  50648. +
  50649. +#define MV_MEMIO16_WRITE(addr, data) \
  50650. + ((*((volatile unsigned short*)(addr))) = ((unsigned short)(data)))
  50651. +
  50652. +#define MV_MEMIO16_READ(addr) \
  50653. + ((*((volatile unsigned short*)(addr))))
  50654. +
  50655. +#define MV_MEMIO8_WRITE(addr, data) \
  50656. + ((*((volatile unsigned char*)(addr))) = ((unsigned char)(data)))
  50657. +
  50658. +#define MV_MEMIO8_READ(addr) \
  50659. + ((*((volatile unsigned char*)(addr))))
  50660. +
  50661. +
  50662. +/* No Fast Swap implementation (in assembler) for ARM */
  50663. +#define MV_32BIT_LE_FAST(val) MV_32BIT_LE(val)
  50664. +#define MV_16BIT_LE_FAST(val) MV_16BIT_LE(val)
  50665. +#define MV_32BIT_BE_FAST(val) MV_32BIT_BE(val)
  50666. +#define MV_16BIT_BE_FAST(val) MV_16BIT_BE(val)
  50667. +
  50668. +/* 32 and 16 bit read/write in big/little endian mode */
  50669. +
  50670. +/* 16bit write in little endian mode */
  50671. +#define MV_MEMIO_LE16_WRITE(addr, data) \
  50672. + MV_MEMIO16_WRITE(addr, MV_16BIT_LE_FAST(data))
  50673. +
  50674. +/* 16bit read in little endian mode */
  50675. +static __inline MV_U16 MV_MEMIO_LE16_READ(MV_U32 addr)
  50676. +{
  50677. + MV_U16 data;
  50678. +
  50679. + data= (MV_U16)MV_MEMIO16_READ(addr);
  50680. +
  50681. + return (MV_U16)MV_16BIT_LE_FAST(data);
  50682. +}
  50683. +
  50684. +/* 32bit write in little endian mode */
  50685. +#define MV_MEMIO_LE32_WRITE(addr, data) \
  50686. + MV_MEMIO32_WRITE(addr, MV_32BIT_LE_FAST(data))
  50687. +
  50688. +/* 32bit read in little endian mode */
  50689. +static __inline MV_U32 MV_MEMIO_LE32_READ(MV_U32 addr)
  50690. +{
  50691. + MV_U32 data;
  50692. +
  50693. + data= (MV_U32)MV_MEMIO32_READ(addr);
  50694. +
  50695. + return (MV_U32)MV_32BIT_LE_FAST(data);
  50696. +}
  50697. +
  50698. +static __inline void mvOsBCopy(char* srcAddr, char* dstAddr, int byteCount)
  50699. +{
  50700. + while(byteCount != 0)
  50701. + {
  50702. + *dstAddr = *srcAddr;
  50703. + dstAddr++;
  50704. + srcAddr++;
  50705. + byteCount--;
  50706. + }
  50707. +}
  50708. +
  50709. +static INLINE MV_U64 mvOsDivMod64(MV_U64 divided, MV_U64 divisor, MV_U64* modulu)
  50710. +{
  50711. + MV_U64 division = 0;
  50712. +
  50713. + if(divisor == 1)
  50714. + return divided;
  50715. +
  50716. + while(divided >= divisor)
  50717. + {
  50718. + division++;
  50719. + divided -= divisor;
  50720. + }
  50721. + if (modulu != NULL)
  50722. + *modulu = divided;
  50723. +
  50724. + return division;
  50725. +}
  50726. +
  50727. +#if defined(MV_BRIDGE_SYNC_REORDER)
  50728. +extern MV_U32 *mvUncachedParam;
  50729. +
  50730. +static __inline void mvOsBridgeReorderWA(void)
  50731. +{
  50732. + volatile MV_U32 val = 0;
  50733. +
  50734. + val = mvUncachedParam[0];
  50735. +}
  50736. +#endif
  50737. +
  50738. +
  50739. +/* Flash APIs */
  50740. +#define MV_FL_8_READ MV_MEMIO8_READ
  50741. +#define MV_FL_16_READ MV_MEMIO_LE16_READ
  50742. +#define MV_FL_32_READ MV_MEMIO_LE32_READ
  50743. +#define MV_FL_8_DATA_READ MV_MEMIO8_READ
  50744. +#define MV_FL_16_DATA_READ MV_MEMIO16_READ
  50745. +#define MV_FL_32_DATA_READ MV_MEMIO32_READ
  50746. +#define MV_FL_8_WRITE MV_MEMIO8_WRITE
  50747. +#define MV_FL_16_WRITE MV_MEMIO_LE16_WRITE
  50748. +#define MV_FL_32_WRITE MV_MEMIO_LE32_WRITE
  50749. +#define MV_FL_8_DATA_WRITE MV_MEMIO8_WRITE
  50750. +#define MV_FL_16_DATA_WRITE MV_MEMIO16_WRITE
  50751. +#define MV_FL_32_DATA_WRITE MV_MEMIO32_WRITE
  50752. +
  50753. +
  50754. +/* CPU cache information */
  50755. +#define CPU_I_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
  50756. +#define CPU_D_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
  50757. +
  50758. +#ifdef CONFIG_L2_CACHE_ENABLE
  50759. +/* Data cache flush one line */
  50760. +#define mvOsCacheLineFlushInv(handle, addr) \
  50761. +{ \
  50762. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\
  50763. + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c10, 1" : : "r" (addr));\
  50764. + __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4"); \
  50765. +}
  50766. +
  50767. +#else
  50768. +
  50769. +/* Data cache flush one line */
  50770. +#define mvOsCacheLineFlushInv(handle, addr) \
  50771. +{ \
  50772. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\
  50773. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \
  50774. +}
  50775. +#endif
  50776. +
  50777. +#ifdef CONFIG_L2_CACHE_ENABLE
  50778. +#define mvOsCacheLineInv(handle,addr) \
  50779. +{ \
  50780. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \
  50781. + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c11, 1" : : "r" (addr)); \
  50782. +}
  50783. +#else
  50784. +#define mvOsCacheLineInv(handle,addr) \
  50785. +{ \
  50786. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \
  50787. +}
  50788. +#endif
  50789. +
  50790. +#ifdef CONFIG_L2_CACHE_ENABLE
  50791. +/* Data cache flush one line */
  50792. +#define mvOsCacheLineFlush(handle, addr) \
  50793. +{ \
  50794. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\
  50795. + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c9, 1" : : "r" (addr));\
  50796. + __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4"); \
  50797. +}
  50798. +
  50799. +#else
  50800. +/* Data cache flush one line */
  50801. +#define mvOsCacheLineFlush(handle, addr) \
  50802. +{ \
  50803. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\
  50804. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \
  50805. +}
  50806. +#endif
  50807. +
  50808. +static __inline void mvOsPrefetch(const void *ptr)
  50809. +{
  50810. +#ifdef CONFIG_USE_DSP
  50811. + __asm__ __volatile__(
  50812. + "pld\t%0"
  50813. + :
  50814. + : "o" (*(char *)ptr)
  50815. + : "cc");
  50816. +#else
  50817. + return;
  50818. +#endif
  50819. +}
  50820. +
  50821. +
  50822. +/* Flush CPU pipe */
  50823. +#define CPU_PIPE_FLUSH
  50824. +
  50825. +
  50826. +
  50827. +
  50828. +
  50829. +/* register manipulations */
  50830. +
  50831. +/******************************************************************************
  50832. +* This debug function enable the write of each register that u-boot access to
  50833. +* to an array in the DRAM, the function record only MV_REG_WRITE access.
  50834. +* The function could not be operate when booting from flash.
  50835. +* In order to print the array we use the printreg command.
  50836. +******************************************************************************/
  50837. +/* #define REG_DEBUG */
  50838. +#if defined(REG_DEBUG)
  50839. +extern int reg_arry[2048][2];
  50840. +extern int reg_arry_index;
  50841. +#endif
  50842. +
  50843. +/* Marvell controller register read/write macros */
  50844. +#define MV_REG_VALUE(offset) \
  50845. + (MV_MEMIO32_READ((INTER_REGS_BASE | (offset))))
  50846. +
  50847. +#define MV_REG_READ(offset) \
  50848. + (MV_MEMIO_LE32_READ(INTER_REGS_BASE | (offset)))
  50849. +
  50850. +#if defined(REG_DEBUG)
  50851. +#define MV_REG_WRITE(offset, val) \
  50852. + MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val)); \
  50853. + { \
  50854. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  50855. + reg_arry[reg_arry_index][1] = (val);\
  50856. + reg_arry_index++;\
  50857. + }
  50858. +#else
  50859. +#define MV_REG_WRITE(offset, val) \
  50860. + MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val));
  50861. +#endif
  50862. +
  50863. +#define MV_REG_BYTE_READ(offset) \
  50864. + (MV_MEMIO8_READ((INTER_REGS_BASE | (offset))))
  50865. +
  50866. +#if defined(REG_DEBUG)
  50867. +#define MV_REG_BYTE_WRITE(offset, val) \
  50868. + MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val)); \
  50869. + { \
  50870. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  50871. + reg_arry[reg_arry_index][1] = (val);\
  50872. + reg_arry_index++;\
  50873. + }
  50874. +#else
  50875. +#define MV_REG_BYTE_WRITE(offset, val) \
  50876. + MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val))
  50877. +#endif
  50878. +
  50879. +#if defined(REG_DEBUG)
  50880. +#define MV_REG_BIT_SET(offset, bitMask) \
  50881. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  50882. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \
  50883. + MV_32BIT_LE_FAST(bitMask)))); \
  50884. + { \
  50885. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  50886. + reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\
  50887. + reg_arry_index++;\
  50888. + }
  50889. +#else
  50890. +#define MV_REG_BIT_SET(offset, bitMask) \
  50891. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  50892. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \
  50893. + MV_32BIT_LE_FAST(bitMask))))
  50894. +#endif
  50895. +
  50896. +#if defined(REG_DEBUG)
  50897. +#define MV_REG_BIT_RESET(offset,bitMask) \
  50898. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  50899. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \
  50900. + MV_32BIT_LE_FAST(~bitMask)))); \
  50901. + { \
  50902. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  50903. + reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\
  50904. + reg_arry_index++;\
  50905. + }
  50906. +#else
  50907. +#define MV_REG_BIT_RESET(offset,bitMask) \
  50908. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  50909. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \
  50910. + MV_32BIT_LE_FAST(~bitMask))))
  50911. +#endif
  50912. +
  50913. +
  50914. +
  50915. +/* ARM architecture APIs */
  50916. +MV_U32 mvOsCpuRevGet (MV_VOID);
  50917. +MV_U32 mvOsCpuPartGet (MV_VOID);
  50918. +MV_U32 mvOsCpuArchGet (MV_VOID);
  50919. +MV_U32 mvOsCpuVarGet (MV_VOID);
  50920. +MV_U32 mvOsCpuAsciiGet (MV_VOID);
  50921. +
  50922. +/* Other APIs */
  50923. +void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle);
  50924. +void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle );
  50925. +void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );
  50926. +void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );
  50927. +int mvOsRand(void);
  50928. +
  50929. +#endif /* _MV_OS_LNX_H_ */
  50930. +
  50931. +
  50932. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h
  50933. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h 1970-01-01 01:00:00.000000000 +0100
  50934. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h 2010-11-09 20:28:10.302495426 +0100
  50935. @@ -0,0 +1,158 @@
  50936. +/*******************************************************************************
  50937. +Copyright (C) Marvell International Ltd. and its affiliates
  50938. +
  50939. +This software file (the "File") is owned and distributed by Marvell
  50940. +International Ltd. and/or its affiliates ("Marvell") under the following
  50941. +alternative licensing terms. Once you have made an election to distribute the
  50942. +File under one of the following license alternatives, please (i) delete this
  50943. +introductory statement regarding license alternatives, (ii) delete the two
  50944. +license alternatives that you have not elected to use and (iii) preserve the
  50945. +Marvell copyright notice above.
  50946. +
  50947. +
  50948. +********************************************************************************
  50949. +Marvell GPL License Option
  50950. +
  50951. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50952. +modify this File in accordance with the terms and conditions of the General
  50953. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50954. +available along with the File in the license.txt file or by writing to the Free
  50955. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50956. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50957. +
  50958. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50959. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50960. +DISCLAIMED. The GPL License provides additional details about this warranty
  50961. +disclaimer.
  50962. +*******************************************************************************/
  50963. +/*******************************************************************************
  50964. +* mvOsLinux.h - O.S. interface header file for Linux
  50965. +*
  50966. +* DESCRIPTION:
  50967. +* This header file contains OS dependent definition under Linux
  50968. +*
  50969. +* DEPENDENCIES:
  50970. +* Linux kernel header files.
  50971. +*
  50972. +* FILE REVISION NUMBER:
  50973. +* $Revision: 1.1 $
  50974. +*******************************************************************************/
  50975. +
  50976. +#ifndef __INCmvOsLinuxh
  50977. +#define __INCmvOsLinuxh
  50978. +
  50979. +/* Includes */
  50980. +#include <linux/autoconf.h>
  50981. +#include <linux/module.h>
  50982. +#include <linux/types.h>
  50983. +#include <linux/string.h>
  50984. +#include <linux/kernel.h>
  50985. +#include <linux/timer.h>
  50986. +#include <linux/mm.h>
  50987. +#include <linux/interrupt.h>
  50988. +#include <linux/major.h>
  50989. +#include <linux/errno.h>
  50990. +#include <linux/genhd.h>
  50991. +#include <linux/slab.h>
  50992. +#include <linux/delay.h>
  50993. +#include <linux/ide.h>
  50994. +#include <linux/pci.h>
  50995. +
  50996. +#include <asm/byteorder.h>
  50997. +#include <asm/irq.h>
  50998. +#include <asm/uaccess.h>
  50999. +#include <asm/io.h>
  51000. +#include "mvOs.h"
  51001. +
  51002. +
  51003. +/* Definitions */
  51004. +#define MV_DEFAULT_QUEUE_DEPTH 2
  51005. +#define MV_SATA_SUPPORT_EDMA_SINGLE_DATA_REGION
  51006. +#define MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN
  51007. +
  51008. +#ifdef CONFIG_MV88F6082
  51009. + #define MV_SATA_OVERRIDE_SW_QUEUE_SIZE
  51010. + #define MV_SATA_REQUESTED_SW_QUEUE_SIZE 2
  51011. + #undef MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN
  51012. +#endif
  51013. +
  51014. +/* System dependent macro for flushing CPU write cache */
  51015. +#if defined (MV_BRIDGE_SYNC_REORDER)
  51016. +#define MV_CPU_WRITE_BUFFER_FLUSH() do { \
  51017. + wmb(); \
  51018. + mvOsBridgeReorderWA(); \
  51019. + } while (0)
  51020. +#else
  51021. +#define MV_CPU_WRITE_BUFFER_FLUSH() wmb()
  51022. +#endif /* CONFIG_MV78XX0 */
  51023. +
  51024. +/* System dependent little endian from / to CPU conversions */
  51025. +#define MV_CPU_TO_LE16(x) cpu_to_le16(x)
  51026. +#define MV_CPU_TO_LE32(x) cpu_to_le32(x)
  51027. +
  51028. +#define MV_LE16_TO_CPU(x) le16_to_cpu(x)
  51029. +#define MV_LE32_TO_CPU(x) le32_to_cpu(x)
  51030. +
  51031. +#ifdef __BIG_ENDIAN_BITFIELD
  51032. +#define MV_BIG_ENDIAN_BITFIELD
  51033. +#endif
  51034. +
  51035. +/* System dependent register read / write in byte/word/dword variants */
  51036. +#define MV_REG_WRITE_BYTE(base, offset, val) writeb(val, base + offset)
  51037. +#define MV_REG_WRITE_WORD(base, offset, val) writew(val, base + offset)
  51038. +#define MV_REG_WRITE_DWORD(base, offset, val) writel(val, base + offset)
  51039. +#define MV_REG_READ_BYTE(base, offset) readb(base + offset)
  51040. +#define MV_REG_READ_WORD(base, offset) readw(base + offset)
  51041. +#define MV_REG_READ_DWORD(base, offset) readl(base + offset)
  51042. +
  51043. +
  51044. +/* Typedefs */
  51045. +
  51046. +/* System dependant typedefs */
  51047. +typedef void *MV_VOID_PTR;
  51048. +typedef u32 *MV_U32_PTR;
  51049. +typedef u16 *MV_U16_PTR;
  51050. +typedef u8 *MV_U8_PTR;
  51051. +typedef char *MV_CHAR_PTR;
  51052. +typedef void *MV_BUS_ADDR_T;
  51053. +typedef unsigned long MV_CPU_FLAGS;
  51054. +
  51055. +
  51056. +/* Structures */
  51057. +/* System dependent structure */
  51058. +typedef struct mvOsSemaphore
  51059. +{
  51060. + int notUsed;
  51061. +} MV_OS_SEMAPHORE;
  51062. +
  51063. +
  51064. +/* Functions (User implemented)*/
  51065. +
  51066. +/* Semaphore init, take and release */
  51067. +#define mvOsSemInit(x) MV_TRUE
  51068. +#define mvOsSemTake(x)
  51069. +#define mvOsSemRelease(x)
  51070. +
  51071. +/* Interrupt masking and unmasking functions */
  51072. +MV_CPU_FLAGS mvOsSaveFlagsAndMaskCPUInterrupts(MV_VOID);
  51073. +MV_VOID mvOsRestoreFlags(MV_CPU_FLAGS);
  51074. +
  51075. +/* Delay function in micro seconds resolution */
  51076. +void mvMicroSecondsDelay(MV_VOID_PTR, MV_U32);
  51077. +
  51078. +/* Typedefs */
  51079. +typedef enum mvBoolean
  51080. +{
  51081. + MV_SFALSE, MV_STRUE
  51082. +} MV_BOOLEAN;
  51083. +
  51084. +/* System logging function */
  51085. +#include "mvLog.h"
  51086. +/* Enable READ/WRITE Long SCSI command only when driver is compiled for debugging */
  51087. +#ifdef MV_LOGGER
  51088. +#define MV_SATA_SUPPORT_READ_WRITE_LONG
  51089. +#endif
  51090. +
  51091. +#define MV_IAL_LOG_ID 3
  51092. +
  51093. +#endif /* __INCmvOsLinuxh */
  51094. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c
  51095. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c 1970-01-01 01:00:00.000000000 +0100
  51096. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c 2010-11-09 20:28:10.342495568 +0100
  51097. @@ -0,0 +1,376 @@
  51098. +/*******************************************************************************
  51099. +Copyright (C) Marvell International Ltd. and its affiliates
  51100. +
  51101. +This software file (the "File") is owned and distributed by Marvell
  51102. +International Ltd. and/or its affiliates ("Marvell") under the following
  51103. +alternative licensing terms. Once you have made an election to distribute the
  51104. +File under one of the following license alternatives, please (i) delete this
  51105. +introductory statement regarding license alternatives, (ii) delete the two
  51106. +license alternatives that you have not elected to use and (iii) preserve the
  51107. +Marvell copyright notice above.
  51108. +
  51109. +********************************************************************************
  51110. +Marvell Commercial License Option
  51111. +
  51112. +If you received this File from Marvell and you have entered into a commercial
  51113. +license agreement (a "Commercial License") with Marvell, the File is licensed
  51114. +to you under the terms of the applicable Commercial License.
  51115. +
  51116. +********************************************************************************
  51117. +Marvell GPL License Option
  51118. +
  51119. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51120. +modify this File in accordance with the terms and conditions of the General
  51121. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51122. +available along with the File in the license.txt file or by writing to the Free
  51123. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51124. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51125. +
  51126. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51127. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51128. +DISCLAIMED. The GPL License provides additional details about this warranty
  51129. +disclaimer.
  51130. +********************************************************************************
  51131. +Marvell BSD License Option
  51132. +
  51133. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51134. +modify this File under the following licensing terms.
  51135. +Redistribution and use in source and binary forms, with or without modification,
  51136. +are permitted provided that the following conditions are met:
  51137. +
  51138. + * Redistributions of source code must retain the above copyright notice,
  51139. + this list of conditions and the following disclaimer.
  51140. +
  51141. + * Redistributions in binary form must reproduce the above copyright
  51142. + notice, this list of conditions and the following disclaimer in the
  51143. + documentation and/or other materials provided with the distribution.
  51144. +
  51145. + * Neither the name of Marvell nor the names of its contributors may be
  51146. + used to endorse or promote products derived from this software without
  51147. + specific prior written permission.
  51148. +
  51149. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  51150. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  51151. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  51152. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  51153. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  51154. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  51155. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  51156. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51157. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  51158. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51159. +
  51160. +*******************************************************************************/
  51161. +
  51162. +#include "mvCntmr.h"
  51163. +#include "cpu/mvCpu.h"
  51164. +
  51165. +/* defines */
  51166. +#ifdef MV_DEBUG
  51167. + #define DB(x) x
  51168. +#else
  51169. + #define DB(x)
  51170. +#endif
  51171. +
  51172. +extern unsigned int whoAmI(void);
  51173. +
  51174. +/*******************************************************************************
  51175. +* mvCntmrLoad -
  51176. +*
  51177. +* DESCRIPTION:
  51178. +* Load an init Value to a given counter/timer
  51179. +*
  51180. +* INPUT:
  51181. +* countNum - counter number
  51182. +* value - value to be loaded
  51183. +*
  51184. +* OUTPUT:
  51185. +* None.
  51186. +*
  51187. +* RETURN:
  51188. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  51189. +*******************************************************************************/
  51190. +MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value)
  51191. +{
  51192. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  51193. + {
  51194. +
  51195. + mvOsPrintf(("mvCntmrLoad: Err. Illigal counter number \n"));
  51196. + return MV_BAD_PARAM;;
  51197. +
  51198. + }
  51199. +
  51200. + MV_REG_WRITE(CNTMR_RELOAD_REG(countNum),value);
  51201. + MV_REG_WRITE(CNTMR_VAL_REG(countNum),value);
  51202. +
  51203. + return MV_OK;
  51204. +}
  51205. +
  51206. +/*******************************************************************************
  51207. +* mvCntmrRead -
  51208. +*
  51209. +* DESCRIPTION:
  51210. +* Returns the value of the given Counter/Timer
  51211. +*
  51212. +* INPUT:
  51213. +* countNum - counter number
  51214. +*
  51215. +* OUTPUT:
  51216. +* None.
  51217. +*
  51218. +* RETURN:
  51219. +* MV_U32 counter value
  51220. +*******************************************************************************/
  51221. +MV_U32 mvCntmrRead(MV_U32 countNum)
  51222. +{
  51223. + return MV_REG_READ(CNTMR_VAL_REG(countNum));
  51224. +}
  51225. +
  51226. +/*******************************************************************************
  51227. +* mvCntmrWrite -
  51228. +*
  51229. +* DESCRIPTION:
  51230. +* Returns the value of the given Counter/Timer
  51231. +*
  51232. +* INPUT:
  51233. +* countNum - counter number
  51234. +* countVal - value to write
  51235. +*
  51236. +* OUTPUT:
  51237. +* None.
  51238. +*
  51239. +* RETURN:
  51240. +* None
  51241. +*******************************************************************************/
  51242. +void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal)
  51243. +{
  51244. + MV_REG_WRITE(CNTMR_VAL_REG(countNum),countVal);
  51245. +}
  51246. +
  51247. +/*******************************************************************************
  51248. +* mvCntmrCtrlSet -
  51249. +*
  51250. +* DESCRIPTION:
  51251. +* Set the Control to a given counter/timer
  51252. +*
  51253. +* INPUT:
  51254. +* countNum - counter number
  51255. +* pCtrl - pointer to MV_CNTMR_CTRL structure
  51256. +*
  51257. +* OUTPUT:
  51258. +* None.
  51259. +*
  51260. +* RETURN:
  51261. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  51262. +*******************************************************************************/
  51263. +MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)
  51264. +{
  51265. + MV_U32 cntmrCtrl;
  51266. +
  51267. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  51268. + {
  51269. +
  51270. + DB(mvOsPrintf(("mvCntmrCtrlSet: Err. Illigal counter number \n")));
  51271. + return MV_BAD_PARAM;;
  51272. +
  51273. + }
  51274. +
  51275. + /* read control register */
  51276. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  51277. +
  51278. +
  51279. + if (pCtrl->enable) /* enable counter\timer */
  51280. + {
  51281. + cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);
  51282. + }
  51283. + else /* disable counter\timer */
  51284. + {
  51285. + cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);
  51286. + }
  51287. +
  51288. + if ( pCtrl->autoEnable ) /* Auto mode */
  51289. + {
  51290. + cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(countNum);
  51291. +
  51292. + }
  51293. + else /* no auto mode */
  51294. + {
  51295. + cntmrCtrl &= ~CTCR_ARM_TIMER_AUTO_EN(countNum);
  51296. + }
  51297. +
  51298. + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
  51299. +
  51300. + return MV_OK;
  51301. +
  51302. +}
  51303. +
  51304. +/*******************************************************************************
  51305. +* mvCntmrCtrlGet -
  51306. +*
  51307. +* DESCRIPTION:
  51308. +* Get the Control value of a given counter/timer
  51309. +*
  51310. +* INPUT:
  51311. +* countNum - counter number
  51312. +* pCtrl - pointer to MV_CNTMR_CTRL structure
  51313. +*
  51314. +* OUTPUT:
  51315. +* Counter\Timer control value
  51316. +*
  51317. +* RETURN:
  51318. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  51319. +*******************************************************************************/
  51320. +MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)
  51321. +{
  51322. + MV_U32 cntmrCtrl;
  51323. +
  51324. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  51325. + {
  51326. + DB(mvOsPrintf(("mvCntmrCtrlGet: Err. Illigal counter number \n")));
  51327. + return MV_BAD_PARAM;;
  51328. + }
  51329. +
  51330. + /* read control register */
  51331. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  51332. +
  51333. + /* enable counter\timer */
  51334. + if (cntmrCtrl & CTCR_ARM_TIMER_EN(countNum))
  51335. + {
  51336. + pCtrl->enable = MV_TRUE;
  51337. + }
  51338. + else
  51339. + {
  51340. + pCtrl->enable = MV_FALSE;
  51341. + }
  51342. +
  51343. + /* counter mode */
  51344. + if (cntmrCtrl & CTCR_ARM_TIMER_AUTO_EN(countNum))
  51345. + {
  51346. + pCtrl->autoEnable = MV_TRUE;
  51347. + }
  51348. + else
  51349. + {
  51350. + pCtrl->autoEnable = MV_FALSE;
  51351. + }
  51352. +
  51353. + return MV_OK;
  51354. +}
  51355. +
  51356. +/*******************************************************************************
  51357. +* mvCntmrEnable -
  51358. +*
  51359. +* DESCRIPTION:
  51360. +* Set the Enable-Bit to logic '1' ==> starting the counter
  51361. +*
  51362. +* INPUT:
  51363. +* countNum - counter number
  51364. +*
  51365. +* OUTPUT:
  51366. +* None.
  51367. +*
  51368. +* RETURN:
  51369. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  51370. +*******************************************************************************/
  51371. +MV_STATUS mvCntmrEnable(MV_U32 countNum)
  51372. +{
  51373. + MV_U32 cntmrCtrl;
  51374. +
  51375. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  51376. + {
  51377. +
  51378. + DB(mvOsPrintf(("mvCntmrEnable: Err. Illigal counter number \n")));
  51379. + return MV_BAD_PARAM;;
  51380. +
  51381. + }
  51382. +
  51383. + /* read control register */
  51384. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  51385. +
  51386. + /* enable counter\timer */
  51387. + cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);
  51388. +
  51389. +
  51390. + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
  51391. +
  51392. + return MV_OK;
  51393. +}
  51394. +
  51395. +/*******************************************************************************
  51396. +* mvCntmrDisable -
  51397. +*
  51398. +* DESCRIPTION:
  51399. +* Stop the counter/timer running, and returns its Value
  51400. +*
  51401. +* INPUT:
  51402. +* countNum - counter number
  51403. +*
  51404. +* OUTPUT:
  51405. +* None.
  51406. +*
  51407. +* RETURN:
  51408. +* MV_U32 counter\timer value
  51409. +*******************************************************************************/
  51410. +MV_STATUS mvCntmrDisable(MV_U32 countNum)
  51411. +{
  51412. + MV_U32 cntmrCtrl;
  51413. +
  51414. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  51415. + {
  51416. +
  51417. + DB(mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n")));
  51418. + return MV_BAD_PARAM;;
  51419. +
  51420. + }
  51421. +
  51422. + /* read control register */
  51423. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  51424. +
  51425. + /* disable counter\timer */
  51426. + cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);
  51427. +
  51428. + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
  51429. +
  51430. + return MV_OK;
  51431. +}
  51432. +
  51433. +/*******************************************************************************
  51434. +* mvCntmrStart -
  51435. +*
  51436. +* DESCRIPTION:
  51437. +* Combined all the sub-operations above to one function: Load,setMode,Enable
  51438. +*
  51439. +* INPUT:
  51440. +* countNum - counter number
  51441. +* value - value of the counter\timer to be set
  51442. +* pCtrl - pointer to MV_CNTMR_CTRL structure
  51443. +*
  51444. +* OUTPUT:
  51445. +* None.
  51446. +*
  51447. +* RETURN:
  51448. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  51449. +*******************************************************************************/
  51450. +MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,
  51451. + MV_CNTMR_CTRL *pCtrl)
  51452. +{
  51453. +
  51454. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  51455. + {
  51456. +
  51457. + mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n"));
  51458. + return MV_BAD_PARAM;;
  51459. +
  51460. + }
  51461. +
  51462. + /* load value onto counter\timer */
  51463. + mvCntmrLoad(countNum,value);
  51464. +
  51465. + /* set the counter to load in the first time */
  51466. + mvCntmrWrite(countNum,value);
  51467. +
  51468. + /* set control for timer \ cunter and enable */
  51469. + mvCntmrCtrlSet(countNum,pCtrl);
  51470. +
  51471. + return MV_OK;
  51472. +}
  51473. +
  51474. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h
  51475. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h 1970-01-01 01:00:00.000000000 +0100
  51476. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h 2010-11-09 20:28:10.381238003 +0100
  51477. @@ -0,0 +1,121 @@
  51478. +/*******************************************************************************
  51479. +Copyright (C) Marvell International Ltd. and its affiliates
  51480. +
  51481. +This software file (the "File") is owned and distributed by Marvell
  51482. +International Ltd. and/or its affiliates ("Marvell") under the following
  51483. +alternative licensing terms. Once you have made an election to distribute the
  51484. +File under one of the following license alternatives, please (i) delete this
  51485. +introductory statement regarding license alternatives, (ii) delete the two
  51486. +license alternatives that you have not elected to use and (iii) preserve the
  51487. +Marvell copyright notice above.
  51488. +
  51489. +********************************************************************************
  51490. +Marvell Commercial License Option
  51491. +
  51492. +If you received this File from Marvell and you have entered into a commercial
  51493. +license agreement (a "Commercial License") with Marvell, the File is licensed
  51494. +to you under the terms of the applicable Commercial License.
  51495. +
  51496. +********************************************************************************
  51497. +Marvell GPL License Option
  51498. +
  51499. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51500. +modify this File in accordance with the terms and conditions of the General
  51501. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51502. +available along with the File in the license.txt file or by writing to the Free
  51503. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51504. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51505. +
  51506. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51507. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51508. +DISCLAIMED. The GPL License provides additional details about this warranty
  51509. +disclaimer.
  51510. +********************************************************************************
  51511. +Marvell BSD License Option
  51512. +
  51513. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51514. +modify this File under the following licensing terms.
  51515. +Redistribution and use in source and binary forms, with or without modification,
  51516. +are permitted provided that the following conditions are met:
  51517. +
  51518. + * Redistributions of source code must retain the above copyright notice,
  51519. + this list of conditions and the following disclaimer.
  51520. +
  51521. + * Redistributions in binary form must reproduce the above copyright
  51522. + notice, this list of conditions and the following disclaimer in the
  51523. + documentation and/or other materials provided with the distribution.
  51524. +
  51525. + * Neither the name of Marvell nor the names of its contributors may be
  51526. + used to endorse or promote products derived from this software without
  51527. + specific prior written permission.
  51528. +
  51529. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  51530. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  51531. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  51532. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  51533. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  51534. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  51535. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  51536. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51537. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  51538. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51539. +
  51540. +*******************************************************************************/
  51541. +
  51542. +#ifndef __INCmvTmrWtdgh
  51543. +#define __INCmvTmrWtdgh
  51544. +
  51545. +/* includes */
  51546. +#include "mvCommon.h"
  51547. +#include "mvOs.h"
  51548. +#include "cntmr/mvCntmrRegs.h"
  51549. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  51550. +
  51551. +
  51552. +/* This enumerator describe counters\watchdog numbers */
  51553. +typedef enum _mvCntmrID
  51554. +{
  51555. + TIMER0 = 0,
  51556. + TIMER1,
  51557. + WATCHDOG,
  51558. + TIMER2,
  51559. + TIMER3,
  51560. +}MV_CNTMR_ID;
  51561. +
  51562. +
  51563. +/* Counter / Timer control structure */
  51564. +typedef struct _mvCntmrCtrl
  51565. +{
  51566. + MV_BOOL enable; /* enable */
  51567. + MV_BOOL autoEnable; /* counter/Timer */
  51568. +}MV_CNTMR_CTRL;
  51569. +
  51570. +
  51571. +/* Functions */
  51572. +
  51573. +/* Load an init Value to a given counter/timer */
  51574. +MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value);
  51575. +
  51576. +/* Returns the value of the given Counter/Timer */
  51577. +MV_U32 mvCntmrRead(MV_U32 countNum);
  51578. +
  51579. +/* Write a value of the given Counter/Timer */
  51580. +void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal);
  51581. +
  51582. +/* Set the Control to a given counter/timer */
  51583. +MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);
  51584. +
  51585. +/* Get the value of a given counter/timer */
  51586. +MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);
  51587. +
  51588. +/* Set the Enable-Bit to logic '1' ==> starting the counter. */
  51589. +MV_STATUS mvCntmrEnable(MV_U32 countNum);
  51590. +
  51591. +/* Stop the counter/timer running, and returns its Value. */
  51592. +MV_STATUS mvCntmrDisable(MV_U32 countNum);
  51593. +
  51594. +/* Combined all the sub-operations above to one function: Load,setMode,Enable */
  51595. +MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,
  51596. + MV_CNTMR_CTRL *pCtrl);
  51597. +
  51598. +#endif /* __INCmvTmrWtdgh */
  51599. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h
  51600. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h 1970-01-01 01:00:00.000000000 +0100
  51601. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h 2010-11-09 20:28:10.422495568 +0100
  51602. @@ -0,0 +1,121 @@
  51603. +/*******************************************************************************
  51604. +Copyright (C) Marvell International Ltd. and its affiliates
  51605. +
  51606. +This software file (the "File") is owned and distributed by Marvell
  51607. +International Ltd. and/or its affiliates ("Marvell") under the following
  51608. +alternative licensing terms. Once you have made an election to distribute the
  51609. +File under one of the following license alternatives, please (i) delete this
  51610. +introductory statement regarding license alternatives, (ii) delete the two
  51611. +license alternatives that you have not elected to use and (iii) preserve the
  51612. +Marvell copyright notice above.
  51613. +
  51614. +********************************************************************************
  51615. +Marvell Commercial License Option
  51616. +
  51617. +If you received this File from Marvell and you have entered into a commercial
  51618. +license agreement (a "Commercial License") with Marvell, the File is licensed
  51619. +to you under the terms of the applicable Commercial License.
  51620. +
  51621. +********************************************************************************
  51622. +Marvell GPL License Option
  51623. +
  51624. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51625. +modify this File in accordance with the terms and conditions of the General
  51626. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51627. +available along with the File in the license.txt file or by writing to the Free
  51628. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51629. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51630. +
  51631. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51632. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51633. +DISCLAIMED. The GPL License provides additional details about this warranty
  51634. +disclaimer.
  51635. +********************************************************************************
  51636. +Marvell BSD License Option
  51637. +
  51638. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51639. +modify this File under the following licensing terms.
  51640. +Redistribution and use in source and binary forms, with or without modification,
  51641. +are permitted provided that the following conditions are met:
  51642. +
  51643. + * Redistributions of source code must retain the above copyright notice,
  51644. + this list of conditions and the following disclaimer.
  51645. +
  51646. + * Redistributions in binary form must reproduce the above copyright
  51647. + notice, this list of conditions and the following disclaimer in the
  51648. + documentation and/or other materials provided with the distribution.
  51649. +
  51650. + * Neither the name of Marvell nor the names of its contributors may be
  51651. + used to endorse or promote products derived from this software without
  51652. + specific prior written permission.
  51653. +
  51654. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  51655. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  51656. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  51657. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  51658. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  51659. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  51660. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  51661. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51662. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  51663. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51664. +
  51665. +*******************************************************************************/
  51666. +
  51667. +#ifndef __INCmvTmrwtdgRegsh
  51668. +#define __INCmvTmrwtdgRegsh
  51669. +
  51670. +/*******************************************/
  51671. +/* ARM Timers Registers Map */
  51672. +/*******************************************/
  51673. +
  51674. +#define CNTMR_RELOAD_REG(tmrNum) (CNTMR_BASE + 0x10 + (tmrNum)*8 + \
  51675. + (((tmrNum) <= 3)?0:8))
  51676. +#define CNTMR_VAL_REG(tmrNum) (CNTMR_BASE + 0x14 + (tmrNum)*8 + \
  51677. + (((tmrNum) <= 3)?0:8))
  51678. +#define CNTMR_CTRL_REG (CNTMR_BASE)
  51679. +
  51680. +/*For MV78XX0*/
  51681. +#define CNTMR_CAUSE_REG (CPU_AHB_MBUS_CAUSE_INT_REG(whoAmI()))
  51682. +#define CNTMR_MASK_REG (CPU_AHB_MBUS_MASK_INT_REG(whoAmI()))
  51683. +
  51684. +/* ARM Timers Registers Map */
  51685. +/*******************************************/
  51686. +
  51687. +
  51688. +/* ARM Timers Control Register */
  51689. +/* CPU_TIMERS_CTRL_REG (CTCR) */
  51690. +
  51691. +#define TIMER0_NUM 0
  51692. +#define TIMER1_NUM 1
  51693. +#define WATCHDOG_NUM 2
  51694. +#define TIMER2_NUM 3
  51695. +#define TIMER3_NUM 4
  51696. +
  51697. +#define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2)
  51698. +#define CTCR_ARM_TIMER_EN_MASK(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS)
  51699. +#define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr))
  51700. +#define CTCR_ARM_TIMER_DIS(cntr) (0 << CTCR_ARM_TIMER_EN_OFFS(cntr))
  51701. +
  51702. +#define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1)
  51703. +#define CTCR_ARM_TIMER_AUTO_MASK(cntr) BIT1
  51704. +#define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
  51705. +#define CTCR_ARM_TIMER_AUTO_DIS(cntr) (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
  51706. +
  51707. +
  51708. +/* ARM Timer\Watchdog Reload Register */
  51709. +/* CNTMR_RELOAD_REG (TRR) */
  51710. +
  51711. +#define TRG_ARM_TIMER_REL_OFFS 0
  51712. +#define TRG_ARM_TIMER_REL_MASK 0xffffffff
  51713. +
  51714. +/* ARM Timer\Watchdog Register */
  51715. +/* CNTMR_VAL_REG (TVRG) */
  51716. +
  51717. +#define TVR_ARM_TIMER_OFFS 0
  51718. +#define TVR_ARM_TIMER_MASK 0xffffffff
  51719. +#define TVR_ARM_TIMER_MAX 0xffffffff
  51720. +
  51721. +
  51722. +
  51723. +#endif /* __INCmvTmrwtdgRegsh */
  51724. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c
  51725. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c 1970-01-01 01:00:00.000000000 +0100
  51726. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c 2010-11-09 20:28:10.462495409 +0100
  51727. @@ -0,0 +1,207 @@
  51728. +/*
  51729. + * This program is free software; you can redistribute it and/or modify
  51730. + * it under the terms of the GNU General Public License as published by
  51731. + * the Free Software Foundation; either version 2 of the License, or
  51732. + * (at your option) any later version.
  51733. + *
  51734. + * This program is distributed in the hope that it will be useful,
  51735. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  51736. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  51737. + * GNU General Public License for more details.
  51738. + *
  51739. + * You should have received a copy of the GNU General Public License
  51740. + * along with this program; if not, write to the Free Software
  51741. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  51742. + */
  51743. +
  51744. +#include "mvOs.h"
  51745. +#include "mvCpuCntrs.h"
  51746. +
  51747. +
  51748. +const static MV_CPU_CNTRS_OPS mvCpuCntrsOpsTbl[MV_CPU_CNTRS_NUM][MV_CPU_CNTRS_OPS_NUM] =
  51749. +{
  51750. + /*0*/
  51751. + {
  51752. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_DCACHE_READ_HIT, MV_CPU_CNTRS_DCACHE_READ_MISS,
  51753. + MV_CPU_CNTRS_DCACHE_WRITE_HIT, MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_INSTRUCTIONS,
  51754. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  51755. + MV_CPU_CNTRS_MMU_READ_LATENCY, MV_CPU_CNTRS_ICACHE_READ_LATENCY, MV_CPU_CNTRS_WB_WRITE_LATENCY,
  51756. + MV_CPU_CNTRS_LDM_STM_HOLD, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  51757. + MV_CPU_CNTRS_DATA_WRITE_ACCESS, MV_CPU_CNTRS_DATA_READ_ACCESS, MV_CPU_CNTRS_INVALID,
  51758. + MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,
  51759. + },
  51760. + /*1*/
  51761. + {
  51762. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_ICACHE_READ_MISS, MV_CPU_CNTRS_DCACHE_READ_MISS,
  51763. + MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_ITLB_MISS, MV_CPU_CNTRS_SINGLE_ISSUE,
  51764. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_RETIRED, MV_CPU_CNTRS_INVALID,
  51765. + MV_CPU_CNTRS_MMU_READ_BEAT, MV_CPU_CNTRS_ICACHE_READ_LATENCY, MV_CPU_CNTRS_WB_WRITE_BEAT,
  51766. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_IS_HOLD, MV_CPU_CNTRS_DATA_READ_ACCESS,
  51767. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  51768. + MV_CPU_CNTRS_INVALID,
  51769. + },
  51770. + /*2*/
  51771. + {
  51772. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_ACCESS,
  51773. + MV_CPU_CNTRS_DTLB_MISS, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  51774. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_PREDICT_MISS, MV_CPU_CNTRS_WB_WRITE_BEAT,
  51775. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_READ_LATENCY, MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,
  51776. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BIU_SIMULT_ACCESS,
  51777. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  51778. + MV_CPU_CNTRS_INVALID,
  51779. + },
  51780. + /*3*/
  51781. + {
  51782. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_DCACHE_READ_MISS, MV_CPU_CNTRS_DCACHE_WRITE_MISS,
  51783. + MV_CPU_CNTRS_TLB_MISS, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  51784. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_TAKEN, MV_CPU_CNTRS_WB_FULL_CYCLES,
  51785. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_READ_BEAT, MV_CPU_CNTRS_DCACHE_WRITE_BEAT,
  51786. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BIU_ANY_ACCESS,
  51787. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DATA_WRITE_ACCESS,
  51788. + MV_CPU_CNTRS_INVALID,
  51789. + }
  51790. +};
  51791. +
  51792. +MV_CPU_CNTRS_ENTRY mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];
  51793. +
  51794. +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventTbl[128];
  51795. +
  51796. +void mvCpuCntrsReset(void)
  51797. +{
  51798. + MV_U32 reg = 0;
  51799. +
  51800. + MV_ASM ("mcr p15, 0, %0, c15, c13, 0" : : "r" (reg));
  51801. + MV_ASM ("mcr p15, 0, %0, c15, c13, 1" : : "r" (reg));
  51802. + MV_ASM ("mcr p15, 0, %0, c15, c13, 2" : : "r" (reg));
  51803. + MV_ASM ("mcr p15, 0, %0, c15, c13, 3" : : "r" (reg));
  51804. + MV_ASM ("mcr p15, 0, %0, c15, c13, 4" : : "r" (reg));
  51805. + MV_ASM ("mcr p15, 0, %0, c15, c13, 5" : : "r" (reg));
  51806. + MV_ASM ("mcr p15, 0, %0, c15, c13, 6" : : "r" (reg));
  51807. + MV_ASM ("mcr p15, 0, %0, c15, c13, 7" : : "r" (reg));
  51808. +}
  51809. +
  51810. +void program_counter(int counter, int op)
  51811. +{
  51812. + MV_U32 reg = (1 << op) | 0x1; /*enable*/
  51813. +
  51814. + switch(counter)
  51815. + {
  51816. + case 0:
  51817. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 0" : : "r" (reg));
  51818. + return;
  51819. +
  51820. + case 1:
  51821. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 1" : : "r" (reg));
  51822. + return;
  51823. +
  51824. + case 2:
  51825. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 2" : : "r" (reg));
  51826. + return;
  51827. +
  51828. + case 3:
  51829. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 3" : : "r" (reg));
  51830. + return;
  51831. +
  51832. + default:
  51833. + mvOsPrintf("error in program_counter: bad counter number (%d)\n", counter);
  51834. + }
  51835. + return;
  51836. +}
  51837. +
  51838. +void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent)
  51839. +{
  51840. + int i;
  51841. +
  51842. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  51843. + {
  51844. + pEvent->counters_sum[i] = 0;
  51845. + }
  51846. + pEvent->num_of_measurements = 0;
  51847. +}
  51848. +
  51849. +
  51850. +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold)
  51851. +{
  51852. + int i;
  51853. + MV_CPU_CNTRS_EVENT* event = mvOsMalloc(sizeof(MV_CPU_CNTRS_EVENT));
  51854. +
  51855. + if(event)
  51856. + {
  51857. + strncpy(event->name, name, sizeof(event->name));
  51858. + event->num_of_measurements = 0;
  51859. + event->avg_sample_count = print_threshold;
  51860. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  51861. + {
  51862. + event->counters_before[i] = 0;
  51863. + event->counters_after[i] = 0;
  51864. + event->counters_sum[i] = 0;
  51865. + }
  51866. + }
  51867. + return event;
  51868. +}
  51869. +
  51870. +void mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event)
  51871. +{
  51872. + if(event != NULL)
  51873. + mvOsFree(event);
  51874. +}
  51875. +
  51876. +
  51877. +MV_STATUS mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op,
  51878. + char* name, MV_U32 overhead)
  51879. +{
  51880. + int i;
  51881. +
  51882. + /* Find required operations */
  51883. + for(i=0; i<MV_CPU_CNTRS_OPS_NUM; i++)
  51884. + {
  51885. + if( mvCpuCntrsOpsTbl[counter][i] == op)
  51886. + {
  51887. + strncpy(mvCpuCntrsTbl[counter].name, name, sizeof(mvCpuCntrsTbl[counter].name));
  51888. + mvCpuCntrsTbl[counter].operation = op;
  51889. + mvCpuCntrsTbl[counter].opIdx = i+1;
  51890. + mvCpuCntrsTbl[counter].overhead = overhead;
  51891. + program_counter(counter, mvCpuCntrsTbl[counter].opIdx);
  51892. + mvOsPrintf("Counter=%d, opIdx=%d, overhead=%d\n",
  51893. + counter, mvCpuCntrsTbl[counter].opIdx, mvCpuCntrsTbl[counter].overhead);
  51894. + return MV_OK;
  51895. + }
  51896. + }
  51897. + return MV_NOT_FOUND;
  51898. +}
  51899. +
  51900. +void mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent)
  51901. +{
  51902. + int i;
  51903. + MV_U64 counters_avg;
  51904. +
  51905. + if(pEvent->num_of_measurements < pEvent->avg_sample_count)
  51906. + return;
  51907. +
  51908. + mvOsPrintf("%16s: ", pEvent->name);
  51909. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  51910. + {
  51911. + counters_avg = mvOsDivMod64(pEvent->counters_sum[i],
  51912. + pEvent->num_of_measurements, NULL);
  51913. + if(counters_avg >= mvCpuCntrsTbl[i].overhead)
  51914. + counters_avg -= mvCpuCntrsTbl[i].overhead;
  51915. + else
  51916. + counters_avg = 0;
  51917. +
  51918. + mvOsPrintf("%s=%5llu, ", mvCpuCntrsTbl[i].name, counters_avg);
  51919. + }
  51920. + mvOsPrintf("\n");
  51921. + mvCpuCntrsEventClear(pEvent);
  51922. + mvCpuCntrsReset();
  51923. +}
  51924. +
  51925. +void mvCpuCntrsStatus(void)
  51926. +{
  51927. + int i;
  51928. +
  51929. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  51930. + {
  51931. + mvOsPrintf("#%d: %s, overhead=%d\n",
  51932. + i, mvCpuCntrsTbl[i].name, mvCpuCntrsTbl[i].overhead);
  51933. + }
  51934. +}
  51935. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h
  51936. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h 1970-01-01 01:00:00.000000000 +0100
  51937. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h 2010-11-09 20:28:10.492495484 +0100
  51938. @@ -0,0 +1,213 @@
  51939. +/*******************************************************************************
  51940. +Copyright (C) Marvell International Ltd. and its affiliates
  51941. +
  51942. +This software file (the "File") is owned and distributed by Marvell
  51943. +International Ltd. and/or its affiliates ("Marvell") under the following
  51944. +alternative licensing terms. Once you have made an election to distribute the
  51945. +File under one of the following license alternatives, please (i) delete this
  51946. +introductory statement regarding license alternatives, (ii) delete the two
  51947. +license alternatives that you have not elected to use and (iii) preserve the
  51948. +Marvell copyright notice above.
  51949. +
  51950. +
  51951. +********************************************************************************
  51952. +Marvell GPL License Option
  51953. +
  51954. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51955. +modify this File in accordance with the terms and conditions of the General
  51956. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51957. +available along with the File in the license.txt file or by writing to the Free
  51958. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51959. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51960. +
  51961. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51962. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51963. +DISCLAIMED. The GPL License provides additional details about this warranty
  51964. +disclaimer.
  51965. +*******************************************************************************/
  51966. +#ifndef __mvCpuCntrs_h__
  51967. +#define __mvCpuCntrs_h__
  51968. +
  51969. +#include "mvTypes.h"
  51970. +#include "mvOs.h"
  51971. +
  51972. +
  51973. +#define MV_CPU_CNTRS_NUM 4
  51974. +#define MV_CPU_CNTRS_OPS_NUM 32
  51975. +
  51976. +typedef enum
  51977. +{
  51978. + MV_CPU_CNTRS_INVALID = 0,
  51979. + MV_CPU_CNTRS_CYCLES,
  51980. + MV_CPU_CNTRS_ICACHE_READ_MISS,
  51981. + MV_CPU_CNTRS_DCACHE_ACCESS,
  51982. + MV_CPU_CNTRS_DCACHE_READ_MISS,
  51983. + MV_CPU_CNTRS_DCACHE_READ_HIT,
  51984. + MV_CPU_CNTRS_DCACHE_WRITE_MISS,
  51985. + MV_CPU_CNTRS_DCACHE_WRITE_HIT,
  51986. + MV_CPU_CNTRS_DTLB_MISS,
  51987. + MV_CPU_CNTRS_TLB_MISS,
  51988. + MV_CPU_CNTRS_ITLB_MISS,
  51989. + MV_CPU_CNTRS_INSTRUCTIONS,
  51990. + MV_CPU_CNTRS_SINGLE_ISSUE,
  51991. + MV_CPU_CNTRS_MMU_READ_LATENCY,
  51992. + MV_CPU_CNTRS_MMU_READ_BEAT,
  51993. + MV_CPU_CNTRS_BRANCH_RETIRED,
  51994. + MV_CPU_CNTRS_BRANCH_TAKEN,
  51995. + MV_CPU_CNTRS_BRANCH_PREDICT_MISS,
  51996. + MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,
  51997. + MV_CPU_CNTRS_WB_FULL_CYCLES,
  51998. + MV_CPU_CNTRS_WB_WRITE_LATENCY,
  51999. + MV_CPU_CNTRS_WB_WRITE_BEAT,
  52000. + MV_CPU_CNTRS_ICACHE_READ_LATENCY,
  52001. + MV_CPU_CNTRS_ICACHE_READ_BEAT,
  52002. + MV_CPU_CNTRS_DCACHE_READ_LATENCY,
  52003. + MV_CPU_CNTRS_DCACHE_READ_BEAT,
  52004. + MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,
  52005. + MV_CPU_CNTRS_DCACHE_WRITE_BEAT,
  52006. + MV_CPU_CNTRS_LDM_STM_HOLD,
  52007. + MV_CPU_CNTRS_IS_HOLD,
  52008. + MV_CPU_CNTRS_DATA_WRITE_ACCESS,
  52009. + MV_CPU_CNTRS_DATA_READ_ACCESS,
  52010. + MV_CPU_CNTRS_BIU_SIMULT_ACCESS,
  52011. + MV_CPU_CNTRS_BIU_ANY_ACCESS,
  52012. +
  52013. +} MV_CPU_CNTRS_OPS;
  52014. +
  52015. +typedef struct
  52016. +{
  52017. + char name[16];
  52018. + MV_CPU_CNTRS_OPS operation;
  52019. + int opIdx;
  52020. + MV_U32 overhead;
  52021. +
  52022. +} MV_CPU_CNTRS_ENTRY;
  52023. +
  52024. +
  52025. +typedef struct
  52026. +{
  52027. + char name[16];
  52028. + MV_U32 num_of_measurements;
  52029. + MV_U32 avg_sample_count;
  52030. + MV_U64 counters_before[MV_CPU_CNTRS_NUM];
  52031. + MV_U64 counters_after[MV_CPU_CNTRS_NUM];
  52032. + MV_U64 counters_sum[MV_CPU_CNTRS_NUM];
  52033. +
  52034. +} MV_CPU_CNTRS_EVENT;
  52035. +
  52036. +extern MV_CPU_CNTRS_ENTRY mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];
  52037. +
  52038. +
  52039. +MV_STATUS mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op,
  52040. + char* name, MV_U32 overhead);
  52041. +void mvCpuCntrsInit(void);
  52042. +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold);
  52043. +void mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event);
  52044. +void mvCpuCntrsReset(void);
  52045. +void mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent);
  52046. +void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent);
  52047. +
  52048. +/* internal */
  52049. +void program_counter(int counter, int op);
  52050. +
  52051. +static INLINE MV_U64 mvCpuCntrsRead(const int counter)
  52052. +{
  52053. + MV_U32 low = 0, high = 0;
  52054. + MV_U32 ll = 0;
  52055. +
  52056. + switch(counter)
  52057. + {
  52058. + case 0:
  52059. + MV_ASM ("mcr p15, 0, %0, c15, c12, 0" : : "r" (ll));
  52060. + MV_ASM ("mrc p15, 0, %0, c15, c13, 0" : "=r" (low));
  52061. + MV_ASM ("mrc p15, 0, %0, c15, c13, 1" : "=r" (high));
  52062. + break;
  52063. +
  52064. + case 1:
  52065. + MV_ASM ("mcr p15, 0, %0, c15, c12, 1" : : "r" (ll));
  52066. + MV_ASM ("mrc p15, 0, %0, c15, c13, 2" : "=r" (low));
  52067. + MV_ASM ("mrc p15, 0, %0, c15, c13, 3" : "=r" (high));
  52068. + break;
  52069. +
  52070. + case 2:
  52071. + MV_ASM ("mcr p15, 0, %0, c15, c12, 2" : : "r" (ll));
  52072. + MV_ASM ("mrc p15, 0, %0, c15, c13, 4" : "=r" (low));
  52073. + MV_ASM ("mrc p15, 0, %0, c15, c13, 5" : "=r" (high));
  52074. + break;
  52075. +
  52076. + case 3:
  52077. + MV_ASM ("mcr p15, 0, %0, c15, c12, 3" : : "r" (ll));
  52078. + MV_ASM ("mrc p15, 0, %0, c15, c13, 6" : "=r" (low));
  52079. + MV_ASM ("mrc p15, 0, %0, c15, c13, 7" : "=r" (high));
  52080. + break;
  52081. +
  52082. + default:
  52083. + mvOsPrintf("mv_cpu_cntrs_read: bad counter number (%d)\n", counter);
  52084. + }
  52085. + program_counter(counter, mvCpuCntrsTbl[counter].opIdx);
  52086. + return (((MV_U64)high << 32 ) | low);
  52087. +
  52088. +}
  52089. +
  52090. +
  52091. +static INLINE void mvCpuCntrsReadBefore(MV_CPU_CNTRS_EVENT* pEvent)
  52092. +{
  52093. +#if 0
  52094. + int i;
  52095. +
  52096. + /* order is important - we want to measure the cycle count last here! */
  52097. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  52098. + pEvent->counters_before[i] = mvCpuCntrsRead(i);
  52099. +#else
  52100. + pEvent->counters_before[1] = mvCpuCntrsRead(1);
  52101. + pEvent->counters_before[3] = mvCpuCntrsRead(3);
  52102. + pEvent->counters_before[0] = mvCpuCntrsRead(0);
  52103. + pEvent->counters_before[2] = mvCpuCntrsRead(2);
  52104. +#endif
  52105. +}
  52106. +
  52107. +static INLINE void mvCpuCntrsReadAfter(MV_CPU_CNTRS_EVENT* pEvent)
  52108. +{
  52109. + int i;
  52110. +
  52111. +#if 0
  52112. + /* order is important - we want to measure the cycle count first here! */
  52113. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  52114. + pEvent->counters_after[i] = mvCpuCntrsRead(i);
  52115. +#else
  52116. + pEvent->counters_after[2] = mvCpuCntrsRead(2);
  52117. + pEvent->counters_after[0] = mvCpuCntrsRead(0);
  52118. + pEvent->counters_after[3] = mvCpuCntrsRead(3);
  52119. + pEvent->counters_after[1] = mvCpuCntrsRead(1);
  52120. +#endif
  52121. +
  52122. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  52123. + {
  52124. + pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);
  52125. + }
  52126. + pEvent->num_of_measurements++;
  52127. +}
  52128. +
  52129. +
  52130. +#ifdef CONFIG_MV_CPU_PERF_CNTRS
  52131. +
  52132. +#define MV_CPU_CNTRS_READ(counter) mvCpuCntrsRead(counter)
  52133. +
  52134. +#define MV_CPU_CNTRS_START(event) mvCpuCntrsReadBefore(event)
  52135. +
  52136. +#define MV_CPU_CNTRS_STOP(event) mvCpuCntrsReadAfter(event)
  52137. +
  52138. +#define MV_CPU_CNTRS_SHOW(event) mvCpuCntrsShow(event)
  52139. +
  52140. +#else
  52141. +
  52142. +#define MV_CPU_CNTRS_READ(counter)
  52143. +#define MV_CPU_CNTRS_START(event)
  52144. +#define MV_CPU_CNTRS_STOP(event)
  52145. +#define MV_CPU_CNTRS_SHOW(event)
  52146. +
  52147. +#endif /* CONFIG_MV_CPU_PERF_CNTRS */
  52148. +
  52149. +
  52150. +#endif /* __mvCpuCntrs_h__ */
  52151. +
  52152. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c
  52153. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c 1970-01-01 01:00:00.000000000 +0100
  52154. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c 2010-11-09 20:28:10.522495411 +0100
  52155. @@ -0,0 +1,143 @@
  52156. +/*
  52157. + * This program is free software; you can redistribute it and/or modify
  52158. + * it under the terms of the GNU General Public License as published by
  52159. + * the Free Software Foundation; either version 2 of the License, or
  52160. + * (at your option) any later version.
  52161. + *
  52162. + * This program is distributed in the hope that it will be useful,
  52163. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  52164. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  52165. + * GNU General Public License for more details.
  52166. + *
  52167. + * You should have received a copy of the GNU General Public License
  52168. + * along with this program; if not, write to the Free Software
  52169. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  52170. + */
  52171. +
  52172. +#include "mvOs.h"
  52173. +#include "mvCpuL2Cntrs.h"
  52174. +
  52175. +
  52176. +
  52177. +MV_CPU_L2_CNTRS_ENTRY mvCpuL2CntrsTbl[MV_CPU_L2_CNTRS_NUM];
  52178. +
  52179. +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventTbl[128];
  52180. +
  52181. +void mvCpuL2CntrsReset(void)
  52182. +{
  52183. + MV_U32 reg = 0;
  52184. +
  52185. + MV_ASM ("mcr p15, 6, %0, c15, c13, 0" : : "r" (reg));
  52186. + MV_ASM ("mcr p15, 6, %0, c15, c13, 1" : : "r" (reg));
  52187. + MV_ASM ("mcr p15, 6, %0, c15, c13, 2" : : "r" (reg));
  52188. + MV_ASM ("mcr p15, 6, %0, c15, c13, 3" : : "r" (reg));
  52189. +}
  52190. +
  52191. +static void mvCpuL2CntrConfig(int counter, int op)
  52192. +{
  52193. + MV_U32 reg = (1 << op) | 0x1; /*enable*/
  52194. +
  52195. + switch(counter)
  52196. + {
  52197. + case 0:
  52198. + MV_ASM ("mcr p15, 6, %0, c15, c12, 0" : : "r" (reg));
  52199. + return;
  52200. +
  52201. + case 1:
  52202. + MV_ASM ("mcr p15, 6, %0, c15, c12, 1" : : "r" (reg));
  52203. + return;
  52204. +
  52205. + default:
  52206. + mvOsPrintf("mvCpuL2CntrConfig: bad counter number (%d)\n", counter);
  52207. + }
  52208. + return;
  52209. +}
  52210. +
  52211. +void mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent)
  52212. +{
  52213. + int i;
  52214. +
  52215. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  52216. + {
  52217. + pEvent->counters_sum[i] = 0;
  52218. + }
  52219. + pEvent->num_of_measurements = 0;
  52220. +}
  52221. +
  52222. +
  52223. +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold)
  52224. +{
  52225. + int i;
  52226. + MV_CPU_L2_CNTRS_EVENT* event = mvOsMalloc(sizeof(MV_CPU_L2_CNTRS_EVENT));
  52227. +
  52228. + if(event)
  52229. + {
  52230. + strncpy(event->name, name, sizeof(event->name));
  52231. + event->num_of_measurements = 0;
  52232. + event->avg_sample_count = print_threshold;
  52233. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  52234. + {
  52235. + event->counters_before[i] = 0;
  52236. + event->counters_after[i] = 0;
  52237. + event->counters_sum[i] = 0;
  52238. + }
  52239. + }
  52240. + return event;
  52241. +}
  52242. +
  52243. +void mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event)
  52244. +{
  52245. + if(event != NULL)
  52246. + mvOsFree(event);
  52247. +}
  52248. +
  52249. +
  52250. +MV_STATUS mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op,
  52251. + char* name, MV_U32 overhead)
  52252. +{
  52253. + strncpy(mvCpuL2CntrsTbl[counter].name, name, sizeof(mvCpuL2CntrsTbl[counter].name));
  52254. + mvCpuL2CntrsTbl[counter].operation = op;
  52255. + mvCpuL2CntrsTbl[counter].opIdx = op;
  52256. + mvCpuL2CntrsTbl[counter].overhead = overhead;
  52257. + mvCpuL2CntrConfig(counter, op);
  52258. + mvOsPrintf("CPU L2 Counter %d: operation=%d, overhead=%d\n",
  52259. + counter, op, overhead);
  52260. + return MV_OK;
  52261. +}
  52262. +
  52263. +void mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent)
  52264. +{
  52265. + int i;
  52266. + MV_U64 counters_avg;
  52267. +
  52268. + if(pEvent->num_of_measurements < pEvent->avg_sample_count)
  52269. + return;
  52270. +
  52271. + mvOsPrintf("%16s: ", pEvent->name);
  52272. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  52273. + {
  52274. + counters_avg = mvOsDivMod64(pEvent->counters_sum[i],
  52275. + pEvent->num_of_measurements, NULL);
  52276. +
  52277. + if(counters_avg >= mvCpuL2CntrsTbl[i].overhead)
  52278. + counters_avg -= mvCpuL2CntrsTbl[i].overhead;
  52279. + else
  52280. + counters_avg = 0;
  52281. +
  52282. + mvOsPrintf("%s=%5llu, ", mvCpuL2CntrsTbl[i].name, counters_avg);
  52283. + }
  52284. + mvOsPrintf("\n");
  52285. + mvCpuL2CntrsEventClear(pEvent);
  52286. + mvCpuL2CntrsReset();
  52287. +}
  52288. +
  52289. +void mvCpuL2CntrsStatus(void)
  52290. +{
  52291. + int i;
  52292. +
  52293. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  52294. + {
  52295. + mvOsPrintf("#%d: %s, overhead=%d\n",
  52296. + i, mvCpuL2CntrsTbl[i].name, mvCpuL2CntrsTbl[i].overhead);
  52297. + }
  52298. +}
  52299. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h
  52300. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h 1970-01-01 01:00:00.000000000 +0100
  52301. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h 2010-11-09 20:28:10.562495466 +0100
  52302. @@ -0,0 +1,151 @@
  52303. +/*******************************************************************************
  52304. +Copyright (C) Marvell International Ltd. and its affiliates
  52305. +
  52306. +This software file (the "File") is owned and distributed by Marvell
  52307. +International Ltd. and/or its affiliates ("Marvell") under the following
  52308. +alternative licensing terms. Once you have made an election to distribute the
  52309. +File under one of the following license alternatives, please (i) delete this
  52310. +introductory statement regarding license alternatives, (ii) delete the two
  52311. +license alternatives that you have not elected to use and (iii) preserve the
  52312. +Marvell copyright notice above.
  52313. +
  52314. +
  52315. +********************************************************************************
  52316. +Marvell GPL License Option
  52317. +
  52318. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52319. +modify this File in accordance with the terms and conditions of the General
  52320. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  52321. +available along with the File in the license.txt file or by writing to the Free
  52322. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  52323. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  52324. +
  52325. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  52326. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  52327. +DISCLAIMED. The GPL License provides additional details about this warranty
  52328. +disclaimer.
  52329. +*******************************************************************************/
  52330. +#ifndef __mvCpuL2Cntrs_h__
  52331. +#define __mvCpuL2Cntrs_h__
  52332. +
  52333. +#include "mvTypes.h"
  52334. +#include "mvOs.h"
  52335. +
  52336. +
  52337. +#define MV_CPU_L2_CNTRS_NUM 2
  52338. +
  52339. +typedef enum
  52340. +{
  52341. + MV_CPU_L2_CNTRS_ENABLE = 0,
  52342. + MV_CPU_L2_CNTRS_DATA_REQ,
  52343. + MV_CPU_L2_CNTRS_DATA_MISS_REQ,
  52344. + MV_CPU_L2_CNTRS_INST_REQ,
  52345. + MV_CPU_L2_CNTRS_INST_MISS_REQ,
  52346. + MV_CPU_L2_CNTRS_DATA_READ_REQ,
  52347. + MV_CPU_L2_CNTRS_DATA_READ_MISS_REQ,
  52348. + MV_CPU_L2_CNTRS_DATA_WRITE_REQ,
  52349. + MV_CPU_L2_CNTRS_DATA_WRITE_MISS_REQ,
  52350. + MV_CPU_L2_CNTRS_RESERVED,
  52351. + MV_CPU_L2_CNTRS_DIRTY_EVICT_REQ,
  52352. + MV_CPU_L2_CNTRS_EVICT_BUFF_STALL,
  52353. + MV_CPU_L2_CNTRS_ACTIVE_CYCLES,
  52354. +
  52355. +} MV_CPU_L2_CNTRS_OPS;
  52356. +
  52357. +typedef struct
  52358. +{
  52359. + char name[16];
  52360. + MV_CPU_L2_CNTRS_OPS operation;
  52361. + int opIdx;
  52362. + MV_U32 overhead;
  52363. +
  52364. +} MV_CPU_L2_CNTRS_ENTRY;
  52365. +
  52366. +
  52367. +typedef struct
  52368. +{
  52369. + char name[16];
  52370. + MV_U32 num_of_measurements;
  52371. + MV_U32 avg_sample_count;
  52372. + MV_U64 counters_before[MV_CPU_L2_CNTRS_NUM];
  52373. + MV_U64 counters_after[MV_CPU_L2_CNTRS_NUM];
  52374. + MV_U64 counters_sum[MV_CPU_L2_CNTRS_NUM];
  52375. +
  52376. +} MV_CPU_L2_CNTRS_EVENT;
  52377. +
  52378. +
  52379. +MV_STATUS mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op,
  52380. + char* name, MV_U32 overhead);
  52381. +void mvCpuL2CntrsInit(void);
  52382. +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold);
  52383. +void mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event);
  52384. +void mvCpuL2CntrsReset(void);
  52385. +void mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent);
  52386. +void mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent);
  52387. +
  52388. +static INLINE MV_U64 mvCpuL2CntrsRead(const int counter)
  52389. +{
  52390. + MV_U32 low = 0, high = 0;
  52391. +
  52392. + switch(counter)
  52393. + {
  52394. + case 0:
  52395. + MV_ASM ("mrc p15, 6, %0, c15, c13, 0" : "=r" (low));
  52396. + MV_ASM ("mrc p15, 6, %0, c15, c13, 1" : "=r" (high));
  52397. + break;
  52398. +
  52399. + case 1:
  52400. + MV_ASM ("mrc p15, 6, %0, c15, c13, 2" : "=r" (low));
  52401. + MV_ASM ("mrc p15, 6, %0, c15, c13, 3" : "=r" (high));
  52402. + break;
  52403. +
  52404. + default:
  52405. + mvOsPrintf("mvCpuL2CntrsRead: bad counter number (%d)\n", counter);
  52406. + }
  52407. + return (((MV_U64)high << 32 ) | low);
  52408. +
  52409. +}
  52410. +
  52411. +static INLINE void mvCpuL2CntrsReadBefore(MV_CPU_L2_CNTRS_EVENT* pEvent)
  52412. +{
  52413. + int i;
  52414. +
  52415. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  52416. + pEvent->counters_before[i] = mvCpuL2CntrsRead(i);
  52417. +}
  52418. +
  52419. +static INLINE void mvCpuL2CntrsReadAfter(MV_CPU_L2_CNTRS_EVENT* pEvent)
  52420. +{
  52421. + int i;
  52422. +
  52423. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  52424. + {
  52425. + pEvent->counters_after[i] = mvCpuL2CntrsRead(i);
  52426. + pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);
  52427. + }
  52428. + pEvent->num_of_measurements++;
  52429. +}
  52430. +
  52431. +
  52432. +#ifdef CONFIG_MV_CPU_L2_PERF_CNTRS
  52433. +
  52434. +#define MV_CPU_L2_CNTRS_READ(counter) mvCpuL2CntrsRead(counter)
  52435. +
  52436. +#define MV_CPU_L2_CNTRS_START(event) mvCpuL2CntrsReadBefore(event)
  52437. +
  52438. +#define MV_CPU_L2_CNTRS_STOP(event) mvCpuL2CntrsReadAfter(event)
  52439. +
  52440. +#define MV_CPU_L2_CNTRS_SHOW(event) mvCpuL2CntrsShow(event)
  52441. +
  52442. +#else
  52443. +
  52444. +#define MV_CPU_L2_CNTRS_READ(counter)
  52445. +#define MV_CPU_L2_CNTRS_START(event)
  52446. +#define MV_CPU_L2_CNTRS_STOP(event)
  52447. +#define MV_CPU_L2_CNTRS_SHOW(event)
  52448. +
  52449. +#endif /* CONFIG_MV_CPU_L2_PERF_CNTRS */
  52450. +
  52451. +
  52452. +#endif /* __mvCpuL2Cntrs_h__ */
  52453. +
  52454. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c
  52455. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c 1970-01-01 01:00:00.000000000 +0100
  52456. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c 2010-11-09 20:28:10.592495381 +0100
  52457. @@ -0,0 +1,1479 @@
  52458. +/*******************************************************************************
  52459. +Copyright (C) Marvell International Ltd. and its affiliates
  52460. +
  52461. +This software file (the "File") is owned and distributed by Marvell
  52462. +International Ltd. and/or its affiliates ("Marvell") under the following
  52463. +alternative licensing terms. Once you have made an election to distribute the
  52464. +File under one of the following license alternatives, please (i) delete this
  52465. +introductory statement regarding license alternatives, (ii) delete the two
  52466. +license alternatives that you have not elected to use and (iii) preserve the
  52467. +Marvell copyright notice above.
  52468. +
  52469. +********************************************************************************
  52470. +Marvell Commercial License Option
  52471. +
  52472. +If you received this File from Marvell and you have entered into a commercial
  52473. +license agreement (a "Commercial License") with Marvell, the File is licensed
  52474. +to you under the terms of the applicable Commercial License.
  52475. +
  52476. +********************************************************************************
  52477. +Marvell GPL License Option
  52478. +
  52479. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52480. +modify this File in accordance with the terms and conditions of the General
  52481. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  52482. +available along with the File in the license.txt file or by writing to the Free
  52483. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  52484. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  52485. +
  52486. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  52487. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  52488. +DISCLAIMED. The GPL License provides additional details about this warranty
  52489. +disclaimer.
  52490. +********************************************************************************
  52491. +Marvell BSD License Option
  52492. +
  52493. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52494. +modify this File under the following licensing terms.
  52495. +Redistribution and use in source and binary forms, with or without modification,
  52496. +are permitted provided that the following conditions are met:
  52497. +
  52498. + * Redistributions of source code must retain the above copyright notice,
  52499. + this list of conditions and the following disclaimer.
  52500. +
  52501. + * Redistributions in binary form must reproduce the above copyright
  52502. + notice, this list of conditions and the following disclaimer in the
  52503. + documentation and/or other materials provided with the distribution.
  52504. +
  52505. + * Neither the name of Marvell nor the names of its contributors may be
  52506. + used to endorse or promote products derived from this software without
  52507. + specific prior written permission.
  52508. +
  52509. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  52510. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  52511. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  52512. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  52513. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  52514. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  52515. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  52516. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  52517. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  52518. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52519. +
  52520. +*******************************************************************************/
  52521. +
  52522. +#include "ddr1_2/mvDram.h"
  52523. +#include "boardEnv/mvBoardEnvLib.h"
  52524. +
  52525. +#undef MV_DEBUG
  52526. +#ifdef MV_DEBUG
  52527. +#define DB(x) x
  52528. +#else
  52529. +#define DB(x)
  52530. +#endif
  52531. +
  52532. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  52533. + MV_DRAM_BANK_INFO *pBankInfo);
  52534. +static MV_U32 cas2ps(MV_U8 spd_byte);
  52535. +/*******************************************************************************
  52536. +* mvDramBankGet - Get the DRAM bank paramters.
  52537. +*
  52538. +* DESCRIPTION:
  52539. +* This function retrieves DRAM bank parameters as described in
  52540. +* DRAM_BANK_INFO struct to the controller DRAM unit. In case the board
  52541. +* has its DRAM on DIMMs it will use its EEPROM to extract SPD data
  52542. +* from it. Otherwise, if the DRAM is soldered on board, the function
  52543. +* should insert its bank information into MV_DRAM_BANK_INFO struct.
  52544. +*
  52545. +* INPUT:
  52546. +* bankNum - Board DRAM bank number.
  52547. +*
  52548. +* OUTPUT:
  52549. +* pBankInfo - DRAM bank information struct.
  52550. +*
  52551. +* RETURN:
  52552. +* MV_FAIL - Bank parameters could not be read.
  52553. +*
  52554. +*******************************************************************************/
  52555. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
  52556. +{
  52557. + MV_DIMM_INFO dimmInfo;
  52558. +
  52559. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
  52560. + /* zero pBankInfo structure */
  52561. + memset(pBankInfo, 0, sizeof(*pBankInfo));
  52562. +
  52563. + if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
  52564. + {
  52565. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  52566. + return MV_BAD_PARAM;
  52567. + }
  52568. + if( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
  52569. + {
  52570. + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
  52571. + return MV_FAIL;
  52572. + }
  52573. + if((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
  52574. + {
  52575. + DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
  52576. + return MV_FAIL;
  52577. + }
  52578. +
  52579. + /* convert Dimm info to Bank info */
  52580. + cpyDimm2BankInfo(&dimmInfo, pBankInfo);
  52581. +
  52582. + return MV_OK;
  52583. +}
  52584. +
  52585. +/*******************************************************************************
  52586. +* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
  52587. +*
  52588. +* DESCRIPTION:
  52589. +* Convert a Dimm info struct into a bank info struct.
  52590. +*
  52591. +* INPUT:
  52592. +* pDimmInfo - DIMM information structure.
  52593. +*
  52594. +* OUTPUT:
  52595. +* pBankInfo - DRAM bank information struct.
  52596. +*
  52597. +* RETURN:
  52598. +* None.
  52599. +*
  52600. +*******************************************************************************/
  52601. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  52602. + MV_DRAM_BANK_INFO *pBankInfo)
  52603. +{
  52604. + pBankInfo->memoryType = pDimmInfo->memoryType;
  52605. +
  52606. + /* DIMM dimensions */
  52607. + pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
  52608. + pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
  52609. + pBankInfo->dataWidth = pDimmInfo->dataWidth;
  52610. + pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
  52611. + pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
  52612. + pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
  52613. + pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
  52614. + pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
  52615. + pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
  52616. +
  52617. + /* DIMM timing parameters */
  52618. + pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
  52619. + pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  52620. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
  52621. + pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  52622. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
  52623. +
  52624. + pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
  52625. + pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
  52626. + pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
  52627. + pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
  52628. + pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
  52629. + pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
  52630. + pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
  52631. + pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
  52632. +
  52633. + /* Parameters calculated from the extracted DIMM information */
  52634. + pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
  52635. + pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
  52636. + pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
  52637. + pDimmInfo->numOfModuleBanks;
  52638. +
  52639. + /* DIMM attributes (MV_TRUE for yes) */
  52640. +
  52641. + if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
  52642. + (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
  52643. + {
  52644. + if (pDimmInfo->dimmAttributes & BIT1)
  52645. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  52646. + else
  52647. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  52648. + }
  52649. + else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
  52650. + {
  52651. + if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
  52652. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  52653. + else
  52654. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  52655. + }
  52656. +
  52657. + return;
  52658. +}
  52659. +
  52660. +/*******************************************************************************
  52661. +* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
  52662. +*
  52663. +* DESCRIPTION:
  52664. +* Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
  52665. +*
  52666. +* INPUT:
  52667. +* None.
  52668. +*
  52669. +* OUTPUT:
  52670. +* None.
  52671. +*
  52672. +* RETURN:
  52673. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  52674. +*
  52675. +*******************************************************************************/
  52676. +MV_STATUS dimmSpdCpy(MV_VOID)
  52677. +{
  52678. + MV_U32 i;
  52679. + MV_U32 spdChecksum;
  52680. +
  52681. + MV_TWSI_SLAVE twsiSlave;
  52682. + MV_U8 data[SPD_SIZE];
  52683. +
  52684. + /* zero dimmInfo structure */
  52685. + memset(data, 0, SPD_SIZE);
  52686. +
  52687. + /* read the dimm eeprom */
  52688. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  52689. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
  52690. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  52691. + twsiSlave.validOffset = MV_TRUE;
  52692. + twsiSlave.offset = 0;
  52693. + twsiSlave.moreThen256 = MV_FALSE;
  52694. +
  52695. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
  52696. + &twsiSlave, data, SPD_SIZE) )
  52697. + {
  52698. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
  52699. + return MV_FAIL;
  52700. + }
  52701. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  52702. +
  52703. + /* calculate SPD checksum */
  52704. + spdChecksum = 0;
  52705. +
  52706. + for(i = 0 ; i <= 62 ; i++)
  52707. + {
  52708. + spdChecksum += data[i];
  52709. + }
  52710. +
  52711. + if ((spdChecksum & 0xff) != data[63])
  52712. + {
  52713. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  52714. + (MV_U32)(spdChecksum & 0xff), data[63]));
  52715. + }
  52716. + else
  52717. + {
  52718. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  52719. + }
  52720. +
  52721. + /* copy the SPD content 1:1 into the DIMM 1 SPD */
  52722. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
  52723. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  52724. + twsiSlave.validOffset = MV_TRUE;
  52725. + twsiSlave.offset = 0;
  52726. + twsiSlave.moreThen256 = MV_FALSE;
  52727. +
  52728. + for(i = 0 ; i < SPD_SIZE ; i++)
  52729. + {
  52730. + twsiSlave.offset = i;
  52731. + if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL,
  52732. + &twsiSlave, &data[i], 1) )
  52733. + {
  52734. + mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
  52735. + return MV_FAIL;
  52736. + }
  52737. + mvOsDelay(5);
  52738. + }
  52739. +
  52740. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  52741. + return MV_OK;
  52742. +}
  52743. +
  52744. +/*******************************************************************************
  52745. +* dimmSpdGet - Get the SPD parameters.
  52746. +*
  52747. +* DESCRIPTION:
  52748. +* Read the DIMM SPD parameters into given struct parameter.
  52749. +*
  52750. +* INPUT:
  52751. +* dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
  52752. +*
  52753. +* OUTPUT:
  52754. +* pDimmInfo - DIMM information structure.
  52755. +*
  52756. +* RETURN:
  52757. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  52758. +*
  52759. +*******************************************************************************/
  52760. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
  52761. +{
  52762. + MV_U32 i;
  52763. + MV_U32 density = 1;
  52764. + MV_U32 spdChecksum;
  52765. +
  52766. + MV_TWSI_SLAVE twsiSlave;
  52767. + MV_U8 data[SPD_SIZE];
  52768. +
  52769. + if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
  52770. + {
  52771. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  52772. + return MV_BAD_PARAM;
  52773. + }
  52774. +
  52775. + /* zero dimmInfo structure */
  52776. + memset(data, 0, SPD_SIZE);
  52777. +
  52778. + /* read the dimm eeprom */
  52779. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  52780. + twsiSlave.slaveAddr.address = (dimmNum == 0) ?
  52781. + MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
  52782. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  52783. + twsiSlave.validOffset = MV_TRUE;
  52784. + twsiSlave.offset = 0;
  52785. + twsiSlave.moreThen256 = MV_FALSE;
  52786. +
  52787. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
  52788. + &twsiSlave, data, SPD_SIZE) )
  52789. + {
  52790. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
  52791. + return MV_FAIL;
  52792. + }
  52793. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  52794. +
  52795. + /* calculate SPD checksum */
  52796. + spdChecksum = 0;
  52797. +
  52798. + for(i = 0 ; i <= 62 ; i++)
  52799. + {
  52800. + spdChecksum += data[i];
  52801. + }
  52802. +
  52803. + if ((spdChecksum & 0xff) != data[63])
  52804. + {
  52805. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  52806. + (MV_U32)(spdChecksum & 0xff), data[63]));
  52807. + }
  52808. + else
  52809. + {
  52810. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  52811. + }
  52812. +
  52813. + /* copy the SPD content 1:1 into the dimmInfo structure*/
  52814. + for(i = 0 ; i < SPD_SIZE ; i++)
  52815. + {
  52816. + pDimmInfo->spdRawData[i] = data[i];
  52817. + DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
  52818. + }
  52819. +
  52820. + DB(mvOsPrintf("DRAM SPD Information:\n"));
  52821. +
  52822. + /* Memory type (DDR / SDRAM) */
  52823. + switch (data[DIMM_MEM_TYPE])
  52824. + {
  52825. + case (DIMM_MEM_TYPE_SDRAM):
  52826. + pDimmInfo->memoryType = MEM_TYPE_SDRAM;
  52827. + DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
  52828. + break;
  52829. + case (DIMM_MEM_TYPE_DDR1):
  52830. + pDimmInfo->memoryType = MEM_TYPE_DDR1;
  52831. + DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
  52832. + break;
  52833. + case (DIMM_MEM_TYPE_DDR2):
  52834. + pDimmInfo->memoryType = MEM_TYPE_DDR2;
  52835. + DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
  52836. + break;
  52837. + default:
  52838. + mvOsPrintf("ERROR: Undefined memory type!\n");
  52839. + return MV_ERROR;
  52840. + }
  52841. +
  52842. +
  52843. + /* Number Of Row Addresses */
  52844. + pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
  52845. + DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
  52846. +
  52847. + /* Number Of Column Addresses */
  52848. + pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
  52849. + DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
  52850. +
  52851. + /* Number Of Module Banks */
  52852. + pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
  52853. + DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
  52854. + pDimmInfo->numOfModuleBanks));
  52855. +
  52856. + /* Number of module banks encoded differently for DDR2 */
  52857. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  52858. + pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
  52859. +
  52860. + /* Data Width */
  52861. + pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
  52862. + DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
  52863. +
  52864. + /* Minimum Cycle Time At Max CasLatancy */
  52865. + pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
  52866. +
  52867. + /* Error Check Type */
  52868. + pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
  52869. + DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
  52870. + pDimmInfo->errorCheckType));
  52871. +
  52872. + /* Refresh Interval */
  52873. + pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
  52874. + DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
  52875. + pDimmInfo->refreshInterval));
  52876. +
  52877. + /* Sdram Width */
  52878. + pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
  52879. + DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
  52880. +
  52881. + /* Error Check Data Width */
  52882. + pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
  52883. + DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
  52884. + pDimmInfo->errorCheckDataWidth));
  52885. +
  52886. + /* Burst Length Supported */
  52887. + /* SDRAM/DDR1:
  52888. + *******-******-******-******-******-******-******-*******
  52889. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  52890. + *******-******-******-******-******-******-******-*******
  52891. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  52892. + *********************************************************/
  52893. + /* DDR2:
  52894. + *******-******-******-******-******-******-******-*******
  52895. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  52896. + *******-******-******-******-******-******-******-*******
  52897. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  52898. + *********************************************************/
  52899. +
  52900. + pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
  52901. + DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
  52902. + pDimmInfo->burstLengthSupported));
  52903. +
  52904. + /* Number Of Banks On Each Device */
  52905. + pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
  52906. + DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
  52907. + pDimmInfo->numOfBanksOnEachDevice));
  52908. +
  52909. + /* Suported Cas Latencies */
  52910. +
  52911. + /* SDRAM:
  52912. + *******-******-******-******-******-******-******-*******
  52913. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  52914. + *******-******-******-******-******-******-******-*******
  52915. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  52916. + ********************************************************/
  52917. +
  52918. + /* DDR 1:
  52919. + *******-******-******-******-******-******-******-*******
  52920. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  52921. + *******-******-******-******-******-******-******-*******
  52922. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  52923. + *********************************************************/
  52924. +
  52925. + /* DDR 2:
  52926. + *******-******-******-******-******-******-******-*******
  52927. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  52928. + *******-******-******-******-******-******-******-*******
  52929. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  52930. + *********************************************************/
  52931. +
  52932. + pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
  52933. + DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
  52934. + pDimmInfo->suportedCasLatencies));
  52935. +
  52936. + /* For DDR2 only, get the DIMM type information */
  52937. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  52938. + {
  52939. + pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
  52940. + DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
  52941. + pDimmInfo->dimmTypeInfo));
  52942. + }
  52943. +
  52944. + /* SDRAM Modules Attributes */
  52945. + pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
  52946. + DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
  52947. + pDimmInfo->dimmAttributes));
  52948. +
  52949. + /* Minimum Cycle Time At Max CasLatancy Minus 1*/
  52950. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  52951. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
  52952. +
  52953. + /* Minimum Cycle Time At Max CasLatancy Minus 2*/
  52954. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  52955. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
  52956. +
  52957. + pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
  52958. + DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
  52959. + pDimmInfo->minRowPrechargeTime));
  52960. + pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
  52961. + DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
  52962. + pDimmInfo->minRowActiveToRowActive));
  52963. + pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
  52964. + DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
  52965. + pDimmInfo->minRasToCasDelay));
  52966. + pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
  52967. + DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
  52968. + pDimmInfo->minRasPulseWidth));
  52969. +
  52970. + /* DIMM Bank Density */
  52971. + pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
  52972. + DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
  52973. + pDimmInfo->dimmBankDensity));
  52974. +
  52975. + /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
  52976. + pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
  52977. + DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
  52978. + pDimmInfo->minWriteRecoveryTime));
  52979. +
  52980. + /* Only DDR2 includes Internal Write To Read Command Delay field. */
  52981. + pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
  52982. + DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
  52983. + pDimmInfo->minWriteToReadCmdDelay));
  52984. +
  52985. + /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
  52986. + pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
  52987. + DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
  52988. + pDimmInfo->minReadToPrechCmdDelay));
  52989. +
  52990. + /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
  52991. + pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
  52992. + DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
  52993. + pDimmInfo->minRefreshToActiveCmd));
  52994. +
  52995. + /* calculating the sdram density. Representing device density from */
  52996. + /* bit 20 to allow representation of 4GB and above. */
  52997. + /* For example, if density is 512Mbit 0x20000000, will be represent in */
  52998. + /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
  52999. + /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
  53000. + density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
  53001. + pDimmInfo->deviceDensity = density *
  53002. + pDimmInfo->numOfBanksOnEachDevice *
  53003. + pDimmInfo->sdramWidth;
  53004. + DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
  53005. +
  53006. + /* Number of devices includeing Error correction */
  53007. + pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
  53008. + pDimmInfo->numOfModuleBanks;
  53009. + DB(mvOsPrintf("DRAM numberOfDevices %d\n",
  53010. + pDimmInfo->numberOfDevices));
  53011. +
  53012. + pDimmInfo->size = 0;
  53013. +
  53014. + /* Note that pDimmInfo->size is in MB units */
  53015. + if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
  53016. + {
  53017. + if (pDimmInfo->dimmBankDensity & BIT0)
  53018. + pDimmInfo->size += 1024; /* Equal to 1GB */
  53019. + else if (pDimmInfo->dimmBankDensity & BIT1)
  53020. + pDimmInfo->size += 8; /* Equal to 8MB */
  53021. + else if (pDimmInfo->dimmBankDensity & BIT2)
  53022. + pDimmInfo->size += 16; /* Equal to 16MB */
  53023. + else if (pDimmInfo->dimmBankDensity & BIT3)
  53024. + pDimmInfo->size += 32; /* Equal to 32MB */
  53025. + else if (pDimmInfo->dimmBankDensity & BIT4)
  53026. + pDimmInfo->size += 64; /* Equal to 64MB */
  53027. + else if (pDimmInfo->dimmBankDensity & BIT5)
  53028. + pDimmInfo->size += 128; /* Equal to 128MB */
  53029. + else if (pDimmInfo->dimmBankDensity & BIT6)
  53030. + pDimmInfo->size += 256; /* Equal to 256MB */
  53031. + else if (pDimmInfo->dimmBankDensity & BIT7)
  53032. + pDimmInfo->size += 512; /* Equal to 512MB */
  53033. + }
  53034. + else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
  53035. + {
  53036. + if (pDimmInfo->dimmBankDensity & BIT0)
  53037. + pDimmInfo->size += 1024; /* Equal to 1GB */
  53038. + else if (pDimmInfo->dimmBankDensity & BIT1)
  53039. + pDimmInfo->size += 2048; /* Equal to 2GB */
  53040. + else if (pDimmInfo->dimmBankDensity & BIT2)
  53041. + pDimmInfo->size += 16; /* Equal to 16MB */
  53042. + else if (pDimmInfo->dimmBankDensity & BIT3)
  53043. + pDimmInfo->size += 32; /* Equal to 32MB */
  53044. + else if (pDimmInfo->dimmBankDensity & BIT4)
  53045. + pDimmInfo->size += 64; /* Equal to 64MB */
  53046. + else if (pDimmInfo->dimmBankDensity & BIT5)
  53047. + pDimmInfo->size += 128; /* Equal to 128MB */
  53048. + else if (pDimmInfo->dimmBankDensity & BIT6)
  53049. + pDimmInfo->size += 256; /* Equal to 256MB */
  53050. + else if (pDimmInfo->dimmBankDensity & BIT7)
  53051. + pDimmInfo->size += 512; /* Equal to 512MB */
  53052. + }
  53053. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  53054. + {
  53055. + if (pDimmInfo->dimmBankDensity & BIT0)
  53056. + pDimmInfo->size += 1024; /* Equal to 1GB */
  53057. + else if (pDimmInfo->dimmBankDensity & BIT1)
  53058. + pDimmInfo->size += 2048; /* Equal to 2GB */
  53059. + else if (pDimmInfo->dimmBankDensity & BIT2)
  53060. + pDimmInfo->size += 4096; /* Equal to 4GB */
  53061. + else if (pDimmInfo->dimmBankDensity & BIT3)
  53062. + pDimmInfo->size += 8192; /* Equal to 8GB */
  53063. + else if (pDimmInfo->dimmBankDensity & BIT4)
  53064. + pDimmInfo->size += 16384; /* Equal to 16GB */
  53065. + else if (pDimmInfo->dimmBankDensity & BIT5)
  53066. + pDimmInfo->size += 128; /* Equal to 128MB */
  53067. + else if (pDimmInfo->dimmBankDensity & BIT6)
  53068. + pDimmInfo->size += 256; /* Equal to 256MB */
  53069. + else if (pDimmInfo->dimmBankDensity & BIT7)
  53070. + pDimmInfo->size += 512; /* Equal to 512MB */
  53071. + }
  53072. +
  53073. + pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
  53074. +
  53075. + DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
  53076. +
  53077. + return MV_OK;
  53078. +}
  53079. +
  53080. +/*******************************************************************************
  53081. +* dimmSpdPrint - Print the SPD parameters.
  53082. +*
  53083. +* DESCRIPTION:
  53084. +* Print the Dimm SPD parameters.
  53085. +*
  53086. +* INPUT:
  53087. +* pDimmInfo - DIMM information structure.
  53088. +*
  53089. +* OUTPUT:
  53090. +* None.
  53091. +*
  53092. +* RETURN:
  53093. +* None.
  53094. +*
  53095. +*******************************************************************************/
  53096. +MV_VOID dimmSpdPrint(MV_U32 dimmNum)
  53097. +{
  53098. + MV_DIMM_INFO dimmInfo;
  53099. + MV_U32 i, temp = 0;
  53100. + MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
  53101. + MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
  53102. + MV_U32 busClkPs;
  53103. + MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
  53104. + temp_buf[40], *spdRawData;
  53105. +
  53106. + busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
  53107. +
  53108. + spdRawData = dimmInfo.spdRawData;
  53109. +
  53110. + if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
  53111. + {
  53112. + mvOsOutput("ERROR: Could not read SPD information!\n");
  53113. + return;
  53114. + }
  53115. +
  53116. + /* find Manufactura of Dimm Module */
  53117. + mvOsOutput("\nManufacturer's JEDEC ID Code: ");
  53118. + for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
  53119. + {
  53120. + mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
  53121. + }
  53122. + mvOsOutput("\n");
  53123. +
  53124. + /* Manufacturer's Specific Data */
  53125. + for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
  53126. + {
  53127. + temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
  53128. + }
  53129. + mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
  53130. +
  53131. + /* Module Part Number */
  53132. + for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
  53133. + {
  53134. + temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
  53135. + }
  53136. + mvOsOutput("Module Part Number: %s\n", temp_buf);
  53137. +
  53138. + /* Module Serial Number */
  53139. + for(i = 0; i < sizeof(MV_U32); i++)
  53140. + {
  53141. + temp |= spdRawData[95+i] << 8*i;
  53142. + }
  53143. + mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
  53144. + (long)temp);
  53145. +
  53146. + /* find Manufac-Data of Dimm Module */
  53147. + mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
  53148. + ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
  53149. + ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
  53150. + /* find modul_revision of Dimm Module */
  53151. + mvOsOutput("Module Revision: %d.%d\n",
  53152. + spdRawData[91], spdRawData[92]);
  53153. +
  53154. + /* find manufac_place of Dimm Module */
  53155. + mvOsOutput("manufac_place: %d\n", spdRawData[72]);
  53156. +
  53157. + /* go over the first 35 I2C data bytes */
  53158. + for(i = 2 ; i <= 35 ; i++)
  53159. + switch(i)
  53160. + {
  53161. + case 2: /* Memory type (DDR1/2 / SDRAM) */
  53162. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53163. + mvOsOutput("Dram Type is: SDRAM\n");
  53164. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  53165. + mvOsOutput("Dram Type is: SDRAM DDR1\n");
  53166. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  53167. + mvOsOutput("Dram Type is: SDRAM DDR2\n");
  53168. + else
  53169. + mvOsOutput("Dram Type unknown\n");
  53170. + break;
  53171. +/*----------------------------------------------------------------------------*/
  53172. +
  53173. + case 3: /* Number Of Row Addresses */
  53174. + mvOsOutput("Module Number of row addresses: %d\n",
  53175. + dimmInfo.numOfRowAddr);
  53176. + break;
  53177. +/*----------------------------------------------------------------------------*/
  53178. +
  53179. + case 4: /* Number Of Column Addresses */
  53180. + mvOsOutput("Module Number of col addresses: %d\n",
  53181. + dimmInfo.numOfColAddr);
  53182. + break;
  53183. +/*----------------------------------------------------------------------------*/
  53184. +
  53185. + case 5: /* Number Of Module Banks */
  53186. + mvOsOutput("Number of Banks on Mod.: %d\n",
  53187. + dimmInfo.numOfModuleBanks);
  53188. + break;
  53189. +/*----------------------------------------------------------------------------*/
  53190. +
  53191. + case 6: /* Data Width */
  53192. + mvOsOutput("Module Data Width: %d bit\n",
  53193. + dimmInfo.dataWidth);
  53194. + break;
  53195. +/*----------------------------------------------------------------------------*/
  53196. +
  53197. + case 8: /* Voltage Interface */
  53198. + switch(spdRawData[i])
  53199. + {
  53200. + case 0x0:
  53201. + mvOsOutput("Module is TTL_5V_TOLERANT\n");
  53202. + break;
  53203. + case 0x1:
  53204. + mvOsOutput("Module is LVTTL\n");
  53205. + break;
  53206. + case 0x2:
  53207. + mvOsOutput("Module is HSTL_1_5V\n");
  53208. + break;
  53209. + case 0x3:
  53210. + mvOsOutput("Module is SSTL_3_3V\n");
  53211. + break;
  53212. + case 0x4:
  53213. + mvOsOutput("Module is SSTL_2_5V\n");
  53214. + break;
  53215. + case 0x5:
  53216. + if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
  53217. + {
  53218. + mvOsOutput("Module is SSTL_1_8V\n");
  53219. + break;
  53220. + }
  53221. + default:
  53222. + mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
  53223. + break;
  53224. + }
  53225. + break;
  53226. +/*----------------------------------------------------------------------------*/
  53227. +
  53228. + case 9: /* Minimum Cycle Time At Max CasLatancy */
  53229. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53230. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  53231. +
  53232. + /* DDR2 addition of right of point */
  53233. + if ((spdRawData[i] & 0x0f) == 0xA)
  53234. + {
  53235. + rightOfPoint = 25;
  53236. + }
  53237. + if ((spdRawData[i] & 0x0f) == 0xB)
  53238. + {
  53239. + rightOfPoint = 33;
  53240. + }
  53241. + if ((spdRawData[i] & 0x0f) == 0xC)
  53242. + {
  53243. + rightOfPoint = 66;
  53244. + }
  53245. + if ((spdRawData[i] & 0x0f) == 0xD)
  53246. + {
  53247. + rightOfPoint = 75;
  53248. + }
  53249. + mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
  53250. + leftOfPoint, rightOfPoint);
  53251. + break;
  53252. +/*----------------------------------------------------------------------------*/
  53253. +
  53254. + case 10: /* Clock To Data Out */
  53255. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
  53256. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53257. + ((spdRawData[i] & 0x0f));
  53258. + leftOfPoint = time_tmp / div;
  53259. + rightOfPoint = time_tmp % div;
  53260. + mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
  53261. + leftOfPoint, rightOfPoint);
  53262. + break;
  53263. +/*----------------------------------------------------------------------------*/
  53264. +
  53265. + case 11: /* Error Check Type */
  53266. + mvOsOutput("Error Check Type (0=NONE): %d\n",
  53267. + dimmInfo.errorCheckType);
  53268. + break;
  53269. +/*----------------------------------------------------------------------------*/
  53270. +
  53271. + case 12: /* Refresh Interval */
  53272. + mvOsOutput("Refresh Rate: %x\n",
  53273. + dimmInfo.refreshInterval);
  53274. + break;
  53275. +/*----------------------------------------------------------------------------*/
  53276. +
  53277. + case 13: /* Sdram Width */
  53278. + mvOsOutput("Sdram Width: %d bits\n",
  53279. + dimmInfo.sdramWidth);
  53280. + break;
  53281. +/*----------------------------------------------------------------------------*/
  53282. +
  53283. + case 14: /* Error Check Data Width */
  53284. + mvOsOutput("Error Check Data Width: %d bits\n",
  53285. + dimmInfo.errorCheckDataWidth);
  53286. + break;
  53287. +/*----------------------------------------------------------------------------*/
  53288. +
  53289. + case 15: /* Minimum Clock Delay is unsupported */
  53290. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  53291. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  53292. + {
  53293. + mvOsOutput("Minimum Clk Delay back to back: %d\n",
  53294. + spdRawData[i]);
  53295. + }
  53296. + break;
  53297. +/*----------------------------------------------------------------------------*/
  53298. +
  53299. + case 16: /* Burst Length Supported */
  53300. + /* SDRAM/DDR1:
  53301. + *******-******-******-******-******-******-******-*******
  53302. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53303. + *******-******-******-******-******-******-******-*******
  53304. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  53305. + *********************************************************/
  53306. + /* DDR2:
  53307. + *******-******-******-******-******-******-******-*******
  53308. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53309. + *******-******-******-******-******-******-******-*******
  53310. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  53311. + *********************************************************/
  53312. + mvOsOutput("Burst Length Supported: ");
  53313. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  53314. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  53315. + {
  53316. + if (dimmInfo.burstLengthSupported & BIT0)
  53317. + mvOsOutput("1, ");
  53318. + if (dimmInfo.burstLengthSupported & BIT1)
  53319. + mvOsOutput("2, ");
  53320. + }
  53321. + if (dimmInfo.burstLengthSupported & BIT2)
  53322. + mvOsOutput("4, ");
  53323. + if (dimmInfo.burstLengthSupported & BIT3)
  53324. + mvOsOutput("8, ");
  53325. +
  53326. + mvOsOutput(" Bit \n");
  53327. + break;
  53328. +/*----------------------------------------------------------------------------*/
  53329. +
  53330. + case 17: /* Number Of Banks On Each Device */
  53331. + mvOsOutput("Number Of Banks On Each Chip: %d\n",
  53332. + dimmInfo.numOfBanksOnEachDevice);
  53333. + break;
  53334. +/*----------------------------------------------------------------------------*/
  53335. +
  53336. + case 18: /* Suported Cas Latencies */
  53337. +
  53338. + /* SDRAM:
  53339. + *******-******-******-******-******-******-******-*******
  53340. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53341. + *******-******-******-******-******-******-******-*******
  53342. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  53343. + ********************************************************/
  53344. +
  53345. + /* DDR 1:
  53346. + *******-******-******-******-******-******-******-*******
  53347. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53348. + *******-******-******-******-******-******-******-*******
  53349. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  53350. + *********************************************************/
  53351. +
  53352. + /* DDR 2:
  53353. + *******-******-******-******-******-******-******-*******
  53354. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53355. + *******-******-******-******-******-******-******-*******
  53356. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  53357. + *********************************************************/
  53358. +
  53359. + mvOsOutput("Suported Cas Latencies: (CL) ");
  53360. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53361. + {
  53362. + for (k = 0; k <=7; k++)
  53363. + {
  53364. + if (dimmInfo.suportedCasLatencies & (1 << k))
  53365. + mvOsOutput("%d, ", k+1);
  53366. + }
  53367. + }
  53368. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  53369. + {
  53370. + if (dimmInfo.suportedCasLatencies & BIT0)
  53371. + mvOsOutput("1, ");
  53372. + if (dimmInfo.suportedCasLatencies & BIT1)
  53373. + mvOsOutput("1.5, ");
  53374. + if (dimmInfo.suportedCasLatencies & BIT2)
  53375. + mvOsOutput("2, ");
  53376. + if (dimmInfo.suportedCasLatencies & BIT3)
  53377. + mvOsOutput("2.5, ");
  53378. + if (dimmInfo.suportedCasLatencies & BIT4)
  53379. + mvOsOutput("3, ");
  53380. + if (dimmInfo.suportedCasLatencies & BIT5)
  53381. + mvOsOutput("3.5, ");
  53382. + }
  53383. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  53384. + {
  53385. + if (dimmInfo.suportedCasLatencies & BIT2)
  53386. + mvOsOutput("2, ");
  53387. + if (dimmInfo.suportedCasLatencies & BIT3)
  53388. + mvOsOutput("3, ");
  53389. + if (dimmInfo.suportedCasLatencies & BIT4)
  53390. + mvOsOutput("4, ");
  53391. + if (dimmInfo.suportedCasLatencies & BIT5)
  53392. + mvOsOutput("5, ");
  53393. + }
  53394. + else
  53395. + mvOsOutput("?.?, ");
  53396. + mvOsOutput("\n");
  53397. + break;
  53398. +/*----------------------------------------------------------------------------*/
  53399. +
  53400. + case 20: /* DDR2 DIMM type info */
  53401. + if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  53402. + {
  53403. + if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
  53404. + mvOsOutput("Registered DIMM (RDIMM)\n");
  53405. + else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
  53406. + mvOsOutput("Unbuffered DIMM (UDIMM)\n");
  53407. + else
  53408. + mvOsOutput("Unknown DIMM type.\n");
  53409. + }
  53410. +
  53411. + break;
  53412. +/*----------------------------------------------------------------------------*/
  53413. +
  53414. + case 21: /* SDRAM Modules Attributes */
  53415. + mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
  53416. +
  53417. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53418. + {
  53419. + if (dimmInfo.dimmAttributes & BIT0)
  53420. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  53421. + else
  53422. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  53423. +
  53424. + if (dimmInfo.dimmAttributes & BIT1)
  53425. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  53426. + else
  53427. + mvOsOutput(" Registered Addr/Control Input: No\n");
  53428. +
  53429. + if (dimmInfo.dimmAttributes & BIT2)
  53430. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  53431. + else
  53432. + mvOsOutput(" On-Card PLL (clock): No \n");
  53433. +
  53434. + if (dimmInfo.dimmAttributes & BIT3)
  53435. + mvOsOutput(" Bufferd DQMB Input: Yes \n");
  53436. + else
  53437. + mvOsOutput(" Bufferd DQMB Inputs: No \n");
  53438. +
  53439. + if (dimmInfo.dimmAttributes & BIT4)
  53440. + mvOsOutput(" Registered DQMB Inputs: Yes \n");
  53441. + else
  53442. + mvOsOutput(" Registered DQMB Inputs: No \n");
  53443. +
  53444. + if (dimmInfo.dimmAttributes & BIT5)
  53445. + mvOsOutput(" Differential Clock Input: Yes \n");
  53446. + else
  53447. + mvOsOutput(" Differential Clock Input: No \n");
  53448. +
  53449. + if (dimmInfo.dimmAttributes & BIT6)
  53450. + mvOsOutput(" redundant Row Addressing: Yes \n");
  53451. + else
  53452. + mvOsOutput(" redundant Row Addressing: No \n");
  53453. + }
  53454. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  53455. + {
  53456. + if (dimmInfo.dimmAttributes & BIT0)
  53457. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  53458. + else
  53459. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  53460. +
  53461. + if (dimmInfo.dimmAttributes & BIT1)
  53462. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  53463. + else
  53464. + mvOsOutput(" Registered Addr/Control Input: No\n");
  53465. +
  53466. + if (dimmInfo.dimmAttributes & BIT2)
  53467. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  53468. + else
  53469. + mvOsOutput(" On-Card PLL (clock): No \n");
  53470. +
  53471. + if (dimmInfo.dimmAttributes & BIT3)
  53472. + mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
  53473. + else
  53474. + mvOsOutput(" FET Switch On-Card Enabled: No \n");
  53475. +
  53476. + if (dimmInfo.dimmAttributes & BIT4)
  53477. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  53478. + else
  53479. + mvOsOutput(" FET Switch External Enabled: No \n");
  53480. +
  53481. + if (dimmInfo.dimmAttributes & BIT5)
  53482. + mvOsOutput(" Differential Clock Input: Yes \n");
  53483. + else
  53484. + mvOsOutput(" Differential Clock Input: No \n");
  53485. + }
  53486. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  53487. + {
  53488. + mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
  53489. + (dimmInfo.dimmAttributes & 0x3) + 1);
  53490. +
  53491. + mvOsOutput(" Number of PLLs on the DIMM: %d\n",
  53492. + ((dimmInfo.dimmAttributes) >> 2) & 0x3);
  53493. +
  53494. + if (dimmInfo.dimmAttributes & BIT4)
  53495. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  53496. + else
  53497. + mvOsOutput(" FET Switch External Enabled: No \n");
  53498. +
  53499. + if (dimmInfo.dimmAttributes & BIT6)
  53500. + mvOsOutput(" Analysis probe installed: Yes \n");
  53501. + else
  53502. + mvOsOutput(" Analysis probe installed: No \n");
  53503. + }
  53504. +
  53505. + break;
  53506. +/*----------------------------------------------------------------------------*/
  53507. +
  53508. + case 22: /* Suported AutoPreCharge */
  53509. + mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
  53510. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53511. + {
  53512. + if ( spdRawData[i] & BIT0 )
  53513. + mvOsOutput(" Early Ras Precharge: Yes \n");
  53514. + else
  53515. + mvOsOutput(" Early Ras Precharge: No \n");
  53516. +
  53517. + if ( spdRawData[i] & BIT1 )
  53518. + mvOsOutput(" AutoPreCharge: Yes \n");
  53519. + else
  53520. + mvOsOutput(" AutoPreCharge: No \n");
  53521. +
  53522. + if ( spdRawData[i] & BIT2 )
  53523. + mvOsOutput(" Precharge All: Yes \n");
  53524. + else
  53525. + mvOsOutput(" Precharge All: No \n");
  53526. +
  53527. + if ( spdRawData[i] & BIT3 )
  53528. + mvOsOutput(" Write 1/ReadBurst: Yes \n");
  53529. + else
  53530. + mvOsOutput(" Write 1/ReadBurst: No \n");
  53531. +
  53532. + if ( spdRawData[i] & BIT4 )
  53533. + mvOsOutput(" lower VCC tolerance: 5%%\n");
  53534. + else
  53535. + mvOsOutput(" lower VCC tolerance: 10%%\n");
  53536. +
  53537. + if ( spdRawData[i] & BIT5 )
  53538. + mvOsOutput(" upper VCC tolerance: 5%%\n");
  53539. + else
  53540. + mvOsOutput(" upper VCC tolerance: 10%%\n");
  53541. + }
  53542. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  53543. + {
  53544. + if ( spdRawData[i] & BIT0 )
  53545. + mvOsOutput(" Supports Weak Driver: Yes \n");
  53546. + else
  53547. + mvOsOutput(" Supports Weak Driver: No \n");
  53548. +
  53549. + if ( !(spdRawData[i] & BIT4) )
  53550. + mvOsOutput(" lower VCC tolerance: 0.2V\n");
  53551. +
  53552. + if ( !(spdRawData[i] & BIT5) )
  53553. + mvOsOutput(" upper VCC tolerance: 0.2V\n");
  53554. +
  53555. + if ( spdRawData[i] & BIT6 )
  53556. + mvOsOutput(" Concurrent Auto Preharge: Yes \n");
  53557. + else
  53558. + mvOsOutput(" Concurrent Auto Preharge: No \n");
  53559. +
  53560. + if ( spdRawData[i] & BIT7 )
  53561. + mvOsOutput(" Supports Fast AP: Yes \n");
  53562. + else
  53563. + mvOsOutput(" Supports Fast AP: No \n");
  53564. + }
  53565. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  53566. + {
  53567. + if ( spdRawData[i] & BIT0 )
  53568. + mvOsOutput(" Supports Weak Driver: Yes \n");
  53569. + else
  53570. + mvOsOutput(" Supports Weak Driver: No \n");
  53571. + }
  53572. + break;
  53573. +/*----------------------------------------------------------------------------*/
  53574. +
  53575. + case 23:
  53576. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
  53577. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53578. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  53579. +
  53580. + /* DDR2 addition of right of point */
  53581. + if ((spdRawData[i] & 0x0f) == 0xA)
  53582. + {
  53583. + rightOfPoint = 25;
  53584. + }
  53585. + if ((spdRawData[i] & 0x0f) == 0xB)
  53586. + {
  53587. + rightOfPoint = 33;
  53588. + }
  53589. + if ((spdRawData[i] & 0x0f) == 0xC)
  53590. + {
  53591. + rightOfPoint = 66;
  53592. + }
  53593. + if ((spdRawData[i] & 0x0f) == 0xD)
  53594. + {
  53595. + rightOfPoint = 75;
  53596. + }
  53597. +
  53598. + mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
  53599. + "(0 = Not supported): %d.%d [ns]\n",
  53600. + leftOfPoint, rightOfPoint );
  53601. + break;
  53602. +/*----------------------------------------------------------------------------*/
  53603. +
  53604. + case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
  53605. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
  53606. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53607. + ((spdRawData[i] & 0x0f));
  53608. + leftOfPoint = time_tmp / div;
  53609. + rightOfPoint = time_tmp % div;
  53610. + mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
  53611. + leftOfPoint, rightOfPoint);
  53612. + break;
  53613. +/*----------------------------------------------------------------------------*/
  53614. +
  53615. + case 25:
  53616. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
  53617. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53618. + {
  53619. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  53620. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  53621. + }
  53622. + else /* DDR1 or DDR2 */
  53623. + {
  53624. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53625. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  53626. +
  53627. + /* DDR2 addition of right of point */
  53628. + if ((spdRawData[i] & 0x0f) == 0xA)
  53629. + {
  53630. + rightOfPoint = 25;
  53631. + }
  53632. + if ((spdRawData[i] & 0x0f) == 0xB)
  53633. + {
  53634. + rightOfPoint = 33;
  53635. + }
  53636. + if ((spdRawData[i] & 0x0f) == 0xC)
  53637. + {
  53638. + rightOfPoint = 66;
  53639. + }
  53640. + if ((spdRawData[i] & 0x0f) == 0xD)
  53641. + {
  53642. + rightOfPoint = 75;
  53643. + }
  53644. + }
  53645. + mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
  53646. + "(0 = Not supported): %d.%d [ns]\n",
  53647. + leftOfPoint, rightOfPoint );
  53648. + break;
  53649. +/*----------------------------------------------------------------------------*/
  53650. +
  53651. + case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
  53652. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53653. + {
  53654. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  53655. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  53656. + }
  53657. + else /* DDR1 or DDR2 */
  53658. + {
  53659. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53660. + ((spdRawData[i] & 0x0f));
  53661. + leftOfPoint = 0;
  53662. + rightOfPoint = time_tmp;
  53663. + }
  53664. + mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
  53665. + leftOfPoint, rightOfPoint );
  53666. + break;
  53667. +/*----------------------------------------------------------------------------*/
  53668. +
  53669. + case 27: /* Minimum Row Precharge Time */
  53670. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  53671. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  53672. + 0xff : 0xfc;
  53673. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  53674. + 0x00 : 0x03;
  53675. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  53676. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  53677. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
  53678. + trp_clocks = (temp + (busClkPs-1)) / busClkPs;
  53679. + mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
  53680. + "in Clk cycles %d\n",
  53681. + leftOfPoint, rightOfPoint, trp_clocks);
  53682. + break;
  53683. +/*----------------------------------------------------------------------------*/
  53684. +
  53685. + case 28: /* Minimum Row Active to Row Active Time */
  53686. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  53687. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  53688. + 0xff : 0xfc;
  53689. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  53690. + 0x00 : 0x03;
  53691. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  53692. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  53693. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  53694. + trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
  53695. + mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
  53696. + "%d.%d = in Clk cycles %d\n",
  53697. + leftOfPoint, rightOfPoint, trp_clocks);
  53698. + break;
  53699. +/*----------------------------------------------------------------------------*/
  53700. +
  53701. + case 29: /* Minimum Ras-To-Cas Delay */
  53702. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  53703. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  53704. + 0xff : 0xfc;
  53705. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  53706. + 0x00 : 0x03;
  53707. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  53708. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  53709. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  53710. + trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
  53711. + mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
  53712. + "in Clk cycles %d\n",
  53713. + leftOfPoint, rightOfPoint, trp_clocks);
  53714. + break;
  53715. +/*----------------------------------------------------------------------------*/
  53716. +
  53717. + case 30: /* Minimum Ras Pulse Width */
  53718. + tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
  53719. + mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
  53720. + "in Clk cycles %d\n", spdRawData[i], tras_clocks);
  53721. + break;
  53722. +/*----------------------------------------------------------------------------*/
  53723. +
  53724. + case 31: /* Module Bank Density */
  53725. + mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
  53726. +
  53727. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53728. + {
  53729. + if (dimmInfo.dimmBankDensity & BIT0)
  53730. + mvOsOutput("1GB, ");
  53731. + if (dimmInfo.dimmBankDensity & BIT1)
  53732. + mvOsOutput("8MB, ");
  53733. + if (dimmInfo.dimmBankDensity & BIT2)
  53734. + mvOsOutput("16MB, ");
  53735. + if (dimmInfo.dimmBankDensity & BIT3)
  53736. + mvOsOutput("32MB, ");
  53737. + if (dimmInfo.dimmBankDensity & BIT4)
  53738. + mvOsOutput("64MB, ");
  53739. + if (dimmInfo.dimmBankDensity & BIT5)
  53740. + mvOsOutput("128MB, ");
  53741. + if (dimmInfo.dimmBankDensity & BIT6)
  53742. + mvOsOutput("256MB, ");
  53743. + if (dimmInfo.dimmBankDensity & BIT7)
  53744. + mvOsOutput("512MB, ");
  53745. + }
  53746. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  53747. + {
  53748. + if (dimmInfo.dimmBankDensity & BIT0)
  53749. + mvOsOutput("1GB, ");
  53750. + if (dimmInfo.dimmBankDensity & BIT1)
  53751. + mvOsOutput("2GB, ");
  53752. + if (dimmInfo.dimmBankDensity & BIT2)
  53753. + mvOsOutput("16MB, ");
  53754. + if (dimmInfo.dimmBankDensity & BIT3)
  53755. + mvOsOutput("32MB, ");
  53756. + if (dimmInfo.dimmBankDensity & BIT4)
  53757. + mvOsOutput("64MB, ");
  53758. + if (dimmInfo.dimmBankDensity & BIT5)
  53759. + mvOsOutput("128MB, ");
  53760. + if (dimmInfo.dimmBankDensity & BIT6)
  53761. + mvOsOutput("256MB, ");
  53762. + if (dimmInfo.dimmBankDensity & BIT7)
  53763. + mvOsOutput("512MB, ");
  53764. + }
  53765. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  53766. + {
  53767. + if (dimmInfo.dimmBankDensity & BIT0)
  53768. + mvOsOutput("1GB, ");
  53769. + if (dimmInfo.dimmBankDensity & BIT1)
  53770. + mvOsOutput("2GB, ");
  53771. + if (dimmInfo.dimmBankDensity & BIT2)
  53772. + mvOsOutput("4GB, ");
  53773. + if (dimmInfo.dimmBankDensity & BIT3)
  53774. + mvOsOutput("8GB, ");
  53775. + if (dimmInfo.dimmBankDensity & BIT4)
  53776. + mvOsOutput("16GB, ");
  53777. + if (dimmInfo.dimmBankDensity & BIT5)
  53778. + mvOsOutput("128MB, ");
  53779. + if (dimmInfo.dimmBankDensity & BIT6)
  53780. + mvOsOutput("256MB, ");
  53781. + if (dimmInfo.dimmBankDensity & BIT7)
  53782. + mvOsOutput("512MB, ");
  53783. + }
  53784. + mvOsOutput("\n");
  53785. + break;
  53786. +/*----------------------------------------------------------------------------*/
  53787. +
  53788. + case 32: /* Address And Command Setup Time (measured in ns/1000) */
  53789. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53790. + {
  53791. + rightOfPoint = (spdRawData[i] & 0x0f);
  53792. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53793. + if(leftOfPoint > 7)
  53794. + {
  53795. + leftOfPoint *= -1;
  53796. + }
  53797. + }
  53798. + else /* DDR1 or DDR2 */
  53799. + {
  53800. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53801. + ((spdRawData[i] & 0x0f));
  53802. + leftOfPoint = time_tmp / 100;
  53803. + rightOfPoint = time_tmp % 100;
  53804. + }
  53805. + mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
  53806. + leftOfPoint, rightOfPoint);
  53807. + break;
  53808. +/*----------------------------------------------------------------------------*/
  53809. +
  53810. + case 33: /* Address And Command Hold Time */
  53811. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53812. + {
  53813. + rightOfPoint = (spdRawData[i] & 0x0f);
  53814. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53815. + if(leftOfPoint > 7)
  53816. + {
  53817. + leftOfPoint *= -1;
  53818. + }
  53819. + }
  53820. + else /* DDR1 or DDR2 */
  53821. + {
  53822. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53823. + ((spdRawData[i] & 0x0f));
  53824. + leftOfPoint = time_tmp / 100;
  53825. + rightOfPoint = time_tmp % 100;
  53826. + }
  53827. + mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
  53828. + leftOfPoint, rightOfPoint);
  53829. + break;
  53830. +/*----------------------------------------------------------------------------*/
  53831. +
  53832. + case 34: /* Data Input Setup Time */
  53833. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53834. + {
  53835. + rightOfPoint = (spdRawData[i] & 0x0f);
  53836. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53837. + if(leftOfPoint > 7)
  53838. + {
  53839. + leftOfPoint *= -1;
  53840. + }
  53841. + }
  53842. + else /* DDR1 or DDR2 */
  53843. + {
  53844. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53845. + ((spdRawData[i] & 0x0f));
  53846. + leftOfPoint = time_tmp / 100;
  53847. + rightOfPoint = time_tmp % 100;
  53848. + }
  53849. + mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
  53850. + leftOfPoint, rightOfPoint);
  53851. + break;
  53852. +/*----------------------------------------------------------------------------*/
  53853. +
  53854. + case 35: /* Data Input Hold Time */
  53855. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53856. + {
  53857. + rightOfPoint = (spdRawData[i] & 0x0f);
  53858. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53859. + if(leftOfPoint > 7)
  53860. + {
  53861. + leftOfPoint *= -1;
  53862. + }
  53863. + }
  53864. + else /* DDR1 or DDR2 */
  53865. + {
  53866. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53867. + ((spdRawData[i] & 0x0f));
  53868. + leftOfPoint = time_tmp / 100;
  53869. + rightOfPoint = time_tmp % 100;
  53870. + }
  53871. + mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
  53872. + leftOfPoint, rightOfPoint);
  53873. + break;
  53874. +/*----------------------------------------------------------------------------*/
  53875. +
  53876. + case 36: /* Relevant for DDR2 only: Write Recovery Time */
  53877. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
  53878. + rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
  53879. + mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
  53880. + leftOfPoint, rightOfPoint);
  53881. + break;
  53882. +/*----------------------------------------------------------------------------*/
  53883. + }
  53884. +
  53885. +}
  53886. +
  53887. +
  53888. +/*
  53889. + * translate ns.ns/10 coding of SPD timing values
  53890. + * into ps unit values
  53891. + */
  53892. +/*******************************************************************************
  53893. +* cas2ps - Translate x.y ns parameter to pico-seconds values
  53894. +*
  53895. +* DESCRIPTION:
  53896. +* This function translates x.y nano seconds to its value in pico seconds.
  53897. +* For example 3.75ns will return 3750.
  53898. +*
  53899. +* INPUT:
  53900. +* spd_byte - DIMM SPD byte.
  53901. +*
  53902. +* OUTPUT:
  53903. +* None.
  53904. +*
  53905. +* RETURN:
  53906. +* value in pico seconds.
  53907. +*
  53908. +*******************************************************************************/
  53909. +static MV_U32 cas2ps(MV_U8 spd_byte)
  53910. +{
  53911. + MV_U32 ns, ns10;
  53912. +
  53913. + /* isolate upper nibble */
  53914. + ns = (spd_byte >> 4) & 0x0F;
  53915. + /* isolate lower nibble */
  53916. + ns10 = (spd_byte & 0x0F);
  53917. +
  53918. + if( ns10 < 10 ) {
  53919. + ns10 *= 10;
  53920. + }
  53921. + else if( ns10 == 10 )
  53922. + ns10 = 25;
  53923. + else if( ns10 == 11 )
  53924. + ns10 = 33;
  53925. + else if( ns10 == 12 )
  53926. + ns10 = 66;
  53927. + else if( ns10 == 13 )
  53928. + ns10 = 75;
  53929. + else
  53930. + {
  53931. + mvOsOutput("cas2ps Err. unsupported cycle time.\n");
  53932. + }
  53933. +
  53934. + return (ns*1000 + ns10*10);
  53935. +}
  53936. +
  53937. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h
  53938. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h 1970-01-01 01:00:00.000000000 +0100
  53939. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h 2010-11-09 20:28:10.622495522 +0100
  53940. @@ -0,0 +1,191 @@
  53941. +/*******************************************************************************
  53942. +Copyright (C) Marvell International Ltd. and its affiliates
  53943. +
  53944. +This software file (the "File") is owned and distributed by Marvell
  53945. +International Ltd. and/or its affiliates ("Marvell") under the following
  53946. +alternative licensing terms. Once you have made an election to distribute the
  53947. +File under one of the following license alternatives, please (i) delete this
  53948. +introductory statement regarding license alternatives, (ii) delete the two
  53949. +license alternatives that you have not elected to use and (iii) preserve the
  53950. +Marvell copyright notice above.
  53951. +
  53952. +********************************************************************************
  53953. +Marvell Commercial License Option
  53954. +
  53955. +If you received this File from Marvell and you have entered into a commercial
  53956. +license agreement (a "Commercial License") with Marvell, the File is licensed
  53957. +to you under the terms of the applicable Commercial License.
  53958. +
  53959. +********************************************************************************
  53960. +Marvell GPL License Option
  53961. +
  53962. +If you received this File from Marvell, you may opt to use, redistribute and/or
  53963. +modify this File in accordance with the terms and conditions of the General
  53964. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  53965. +available along with the File in the license.txt file or by writing to the Free
  53966. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  53967. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  53968. +
  53969. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  53970. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  53971. +DISCLAIMED. The GPL License provides additional details about this warranty
  53972. +disclaimer.
  53973. +********************************************************************************
  53974. +Marvell BSD License Option
  53975. +
  53976. +If you received this File from Marvell, you may opt to use, redistribute and/or
  53977. +modify this File under the following licensing terms.
  53978. +Redistribution and use in source and binary forms, with or without modification,
  53979. +are permitted provided that the following conditions are met:
  53980. +
  53981. + * Redistributions of source code must retain the above copyright notice,
  53982. + this list of conditions and the following disclaimer.
  53983. +
  53984. + * Redistributions in binary form must reproduce the above copyright
  53985. + notice, this list of conditions and the following disclaimer in the
  53986. + documentation and/or other materials provided with the distribution.
  53987. +
  53988. + * Neither the name of Marvell nor the names of its contributors may be
  53989. + used to endorse or promote products derived from this software without
  53990. + specific prior written permission.
  53991. +
  53992. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  53993. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  53994. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  53995. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  53996. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  53997. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  53998. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  53999. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  54000. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  54001. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  54002. +
  54003. +*******************************************************************************/
  54004. +
  54005. +#ifndef __INCmvDram
  54006. +#define __INCmvDram
  54007. +
  54008. +#include "ddr1_2/mvDramIf.h"
  54009. +#include "twsi/mvTwsi.h"
  54010. +
  54011. +#define MAX_DIMM_NUM 2
  54012. +#define SPD_SIZE 128
  54013. +
  54014. +/* Dimm spd offsets */
  54015. +#define DIMM_MEM_TYPE 2
  54016. +#define DIMM_ROW_NUM 3
  54017. +#define DIMM_COL_NUM 4
  54018. +#define DIMM_MODULE_BANK_NUM 5
  54019. +#define DIMM_DATA_WIDTH 6
  54020. +#define DIMM_VOLT_IF 8
  54021. +#define DIMM_MIN_CC_AT_MAX_CAS 9
  54022. +#define DIMM_ERR_CHECK_TYPE 11
  54023. +#define DIMM_REFRESH_INTERVAL 12
  54024. +#define DIMM_SDRAM_WIDTH 13
  54025. +#define DIMM_ERR_CHECK_DATA_WIDTH 14
  54026. +#define DIMM_MIN_CLK_DEL 15
  54027. +#define DIMM_BURST_LEN_SUP 16
  54028. +#define DIMM_DEV_BANK_NUM 17
  54029. +#define DIMM_SUP_CAL 18
  54030. +#define DIMM_DDR2_TYPE_INFORMATION 20 /* DDR2 only */
  54031. +#define DIMM_BUF_ADDR_CONT_IN 21
  54032. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1 23
  54033. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2 25
  54034. +#define DIMM_MIN_ROW_PRECHARGE_TIME 27
  54035. +#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE 28
  54036. +#define DIMM_MIN_RAS_TO_CAS_DELAY 29
  54037. +#define DIMM_MIN_RAS_PULSE_WIDTH 30
  54038. +#define DIMM_BANK_DENSITY 31
  54039. +#define DIMM_MIN_WRITE_RECOVERY_TIME 36
  54040. +#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY 37
  54041. +#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY 38
  54042. +#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD 42
  54043. +
  54044. +/* Dimm Memory Type values */
  54045. +#define DIMM_MEM_TYPE_SDRAM 0x4
  54046. +#define DIMM_MEM_TYPE_DDR1 0x7
  54047. +#define DIMM_MEM_TYPE_DDR2 0x8
  54048. +
  54049. +#define DIMM_MODULE_MANU_OFFS 64
  54050. +#define DIMM_MODULE_MANU_SIZE 8
  54051. +#define DIMM_MODULE_VEN_OFFS 73
  54052. +#define DIMM_MODULE_VEN_SIZE 25
  54053. +#define DIMM_MODULE_ID_OFFS 99
  54054. +#define DIMM_MODULE_ID_SIZE 18
  54055. +
  54056. +/* enumeration for voltage levels. */
  54057. +typedef enum _mvDimmVoltageIf
  54058. +{
  54059. + TTL_5V_TOLERANT,
  54060. + LVTTL,
  54061. + HSTL_1_5V,
  54062. + SSTL_3_3V,
  54063. + SSTL_2_5V,
  54064. + VOLTAGE_UNKNOWN,
  54065. +} MV_DIMM_VOLTAGE_IF;
  54066. +
  54067. +
  54068. +/* enumaration for SDRAM CAS Latencies. */
  54069. +typedef enum _mvDimmSdramCas
  54070. +{
  54071. + SD_CL_1 =1,
  54072. + SD_CL_2,
  54073. + SD_CL_3,
  54074. + SD_CL_4,
  54075. + SD_CL_5,
  54076. + SD_CL_6,
  54077. + SD_CL_7,
  54078. + SD_FAULT
  54079. +}MV_DIMM_SDRAM_CAS;
  54080. +
  54081. +
  54082. +/* DIMM information structure */
  54083. +typedef struct _mvDimmInfo
  54084. +{
  54085. + MV_MEMORY_TYPE memoryType; /* DDR or SDRAM */
  54086. +
  54087. + MV_U8 spdRawData[SPD_SIZE]; /* Content of SPD-EEPROM copied 1:1 */
  54088. +
  54089. + /* DIMM dimensions */
  54090. + MV_U32 numOfRowAddr;
  54091. + MV_U32 numOfColAddr;
  54092. + MV_U32 numOfModuleBanks;
  54093. + MV_U32 dataWidth;
  54094. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  54095. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  54096. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  54097. + MV_U32 burstLengthSupported;
  54098. + MV_U32 numOfBanksOnEachDevice;
  54099. + MV_U32 suportedCasLatencies;
  54100. + MV_U32 refreshInterval;
  54101. + MV_U32 dimmBankDensity;
  54102. + MV_U32 dimmTypeInfo; /* DDR2 only */
  54103. + MV_U32 dimmAttributes;
  54104. +
  54105. + /* DIMM timing parameters */
  54106. + MV_U32 minCycleTimeAtMaxCasLatPs;
  54107. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  54108. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  54109. + MV_U32 minRowPrechargeTime;
  54110. + MV_U32 minRowActiveToRowActive;
  54111. + MV_U32 minRasToCasDelay;
  54112. + MV_U32 minRasPulseWidth;
  54113. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  54114. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  54115. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  54116. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  54117. +
  54118. + /* Parameters calculated from the extracted DIMM information */
  54119. + MV_U32 size; /* 16,64,128,256 or 512 MByte in MB units */
  54120. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit in MB units */
  54121. + MV_U32 numberOfDevices;
  54122. +
  54123. +} MV_DIMM_INFO;
  54124. +
  54125. +
  54126. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);
  54127. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);
  54128. +MV_VOID dimmSpdPrint(MV_U32 dimmNum);
  54129. +MV_STATUS dimmSpdCpy(MV_VOID);
  54130. +
  54131. +#endif /* __INCmvDram */
  54132. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c
  54133. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c 1970-01-01 01:00:00.000000000 +0100
  54134. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c 2010-11-09 20:28:10.662495471 +0100
  54135. @@ -0,0 +1,1599 @@
  54136. +/*******************************************************************************
  54137. +Copyright (C) Marvell International Ltd. and its affiliates
  54138. +
  54139. +This software file (the "File") is owned and distributed by Marvell
  54140. +International Ltd. and/or its affiliates ("Marvell") under the following
  54141. +alternative licensing terms. Once you have made an election to distribute the
  54142. +File under one of the following license alternatives, please (i) delete this
  54143. +introductory statement regarding license alternatives, (ii) delete the two
  54144. +license alternatives that you have not elected to use and (iii) preserve the
  54145. +Marvell copyright notice above.
  54146. +
  54147. +********************************************************************************
  54148. +Marvell Commercial License Option
  54149. +
  54150. +If you received this File from Marvell and you have entered into a commercial
  54151. +license agreement (a "Commercial License") with Marvell, the File is licensed
  54152. +to you under the terms of the applicable Commercial License.
  54153. +
  54154. +********************************************************************************
  54155. +Marvell GPL License Option
  54156. +
  54157. +If you received this File from Marvell, you may opt to use, redistribute and/or
  54158. +modify this File in accordance with the terms and conditions of the General
  54159. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  54160. +available along with the File in the license.txt file or by writing to the Free
  54161. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  54162. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  54163. +
  54164. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  54165. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  54166. +DISCLAIMED. The GPL License provides additional details about this warranty
  54167. +disclaimer.
  54168. +********************************************************************************
  54169. +Marvell BSD License Option
  54170. +
  54171. +If you received this File from Marvell, you may opt to use, redistribute and/or
  54172. +modify this File under the following licensing terms.
  54173. +Redistribution and use in source and binary forms, with or without modification,
  54174. +are permitted provided that the following conditions are met:
  54175. +
  54176. + * Redistributions of source code must retain the above copyright notice,
  54177. + this list of conditions and the following disclaimer.
  54178. +
  54179. + * Redistributions in binary form must reproduce the above copyright
  54180. + notice, this list of conditions and the following disclaimer in the
  54181. + documentation and/or other materials provided with the distribution.
  54182. +
  54183. + * Neither the name of Marvell nor the names of its contributors may be
  54184. + used to endorse or promote products derived from this software without
  54185. + specific prior written permission.
  54186. +
  54187. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  54188. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  54189. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  54190. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  54191. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  54192. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  54193. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  54194. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  54195. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  54196. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  54197. +
  54198. +*******************************************************************************/
  54199. +
  54200. +
  54201. +/* includes */
  54202. +#include "ddr1_2/mvDramIf.h"
  54203. +#include "ctrlEnv/sys/mvCpuIf.h"
  54204. +
  54205. +
  54206. +
  54207. +#ifdef MV_DEBUG
  54208. +#define DB(x) x
  54209. +#else
  54210. +#define DB(x)
  54211. +#endif
  54212. +
  54213. +/* DRAM bank presence encoding */
  54214. +#define BANK_PRESENT_CS0 0x1
  54215. +#define BANK_PRESENT_CS0_CS1 0x3
  54216. +#define BANK_PRESENT_CS0_CS2 0x5
  54217. +#define BANK_PRESENT_CS0_CS1_CS2 0x7
  54218. +#define BANK_PRESENT_CS0_CS2_CS3 0xd
  54219. +#define BANK_PRESENT_CS0_CS2_CS3_CS4 0xf
  54220. +
  54221. +/* locals */
  54222. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
  54223. +#if defined(MV_INC_BOARD_DDIM)
  54224. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
  54225. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas);
  54226. +static MV_U32 sdramModeRegCalc(MV_U32 minCas);
  54227. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
  54228. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
  54229. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  54230. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk,
  54231. + MV_U32 forcedCl);
  54232. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  54233. + MV_U32 minCas, MV_U32 busClk);
  54234. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  54235. + MV_U32 busClk);
  54236. +
  54237. +/*******************************************************************************
  54238. +* mvDramIfDetect - Prepare DRAM interface configuration values.
  54239. +*
  54240. +* DESCRIPTION:
  54241. +* This function implements the full DRAM detection and timing
  54242. +* configuration for best system performance.
  54243. +* Since this routine runs from a ROM device (Boot Flash), its stack
  54244. +* resides on RAM, that might be the system DRAM. Changing DRAM
  54245. +* configuration values while keeping vital data in DRAM is risky. That
  54246. +* is why the function does not preform the configuration setting but
  54247. +* prepare those in predefined 32bit registers (in this case IDMA
  54248. +* registers are used) for other routine to perform the settings.
  54249. +* The function will call for board DRAM SPD information for each DRAM
  54250. +* chip select. The function will then analyze those SPD parameters of
  54251. +* all DRAM banks in order to decide on DRAM configuration compatible
  54252. +* for all DRAM banks.
  54253. +* The function will set the CPU DRAM address decode registers.
  54254. +* Note: This routine prepares values that will overide configuration of
  54255. +* mvDramBasicAsmInit().
  54256. +*
  54257. +* INPUT:
  54258. +* forcedCl - Forced CAL Latency. If equal to zero, do not force.
  54259. +*
  54260. +* OUTPUT:
  54261. +* None.
  54262. +*
  54263. +* RETURN:
  54264. +* None.
  54265. +*
  54266. +*******************************************************************************/
  54267. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl)
  54268. +{
  54269. + MV_U32 retVal = MV_OK; /* return value */
  54270. + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
  54271. + MV_U32 busClk, size, base = 0, i, temp, deviceW, dimmW;
  54272. + MV_U8 minCas;
  54273. + MV_DRAM_DEC_WIN dramDecWin;
  54274. +
  54275. + dramDecWin.addrWin.baseHigh = 0;
  54276. +
  54277. + busClk = mvBoardSysClkGet();
  54278. +
  54279. + if (0 == busClk)
  54280. + {
  54281. + mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
  54282. + return MV_ERROR;
  54283. + }
  54284. +
  54285. + /* Close DRAM banks except bank 0 (in case code is excecuting from it...) */
  54286. +#if defined(MV_INCLUDE_SDRAM_CS1)
  54287. + for(i= SDRAM_CS1; i < MV_DRAM_MAX_CS; i++)
  54288. + mvCpuIfTargetWinEnable(i, MV_FALSE);
  54289. +#endif
  54290. +
  54291. + /* we will use bank 0 as the representative of the all the DRAM banks, */
  54292. + /* since bank 0 must exist. */
  54293. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  54294. + {
  54295. + /* if Bank exist */
  54296. + if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
  54297. + {
  54298. + /* check it isn't SDRAM */
  54299. + if(bankInfo[i].memoryType == MEM_TYPE_SDRAM)
  54300. + {
  54301. + mvOsPrintf("Dram: ERR. SDRAM type not supported !!!\n");
  54302. + return MV_ERROR;
  54303. + }
  54304. + /* All banks must support registry in order to activate it */
  54305. + if(bankInfo[i].registeredAddrAndControlInputs !=
  54306. + bankInfo[0].registeredAddrAndControlInputs)
  54307. + {
  54308. + mvOsPrintf("Dram: ERR. different Registered settings !!!\n");
  54309. + return MV_ERROR;
  54310. + }
  54311. +
  54312. + /* Init the CPU window decode */
  54313. + /* Note that the size in Bank info is in MB units */
  54314. + /* Note that the Dimm width might be different then the device DRAM width */
  54315. + temp = MV_REG_READ(SDRAM_CONFIG_REG);
  54316. +
  54317. + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_16BIT )? 16 : 32;
  54318. + dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
  54319. + size = ((bankInfo[i].size << 20) / (dimmW/deviceW));
  54320. +
  54321. + /* We can not change DRAM window settings while excecuting */
  54322. + /* code from it. That is why we skip the DRAM CS[0], saving */
  54323. + /* it to the ROM configuration routine */
  54324. + if(i == SDRAM_CS0)
  54325. + {
  54326. + MV_U32 sizeToReg;
  54327. +
  54328. + /* Translate the given window size to register format */
  54329. + sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
  54330. +
  54331. + /* Size parameter validity check. */
  54332. + if (-1 == sizeToReg)
  54333. + {
  54334. + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
  54335. + ,i);
  54336. + return MV_BAD_PARAM;
  54337. + }
  54338. +
  54339. + /* Size is located at upper 16 bits */
  54340. + sizeToReg <<= SCSR_SIZE_OFFS;
  54341. +
  54342. + /* enable it */
  54343. + sizeToReg |= SCSR_WIN_EN;
  54344. +
  54345. + MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
  54346. + }
  54347. + else
  54348. + {
  54349. + dramDecWin.addrWin.baseLow = base;
  54350. + dramDecWin.addrWin.size = size;
  54351. + dramDecWin.enable = MV_TRUE;
  54352. +
  54353. + if (MV_OK != mvDramIfWinSet(SDRAM_CS0 + i, &dramDecWin))
  54354. + {
  54355. + mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n",
  54356. + SDRAM_CS0 + i);
  54357. + return MV_ERROR;
  54358. + }
  54359. + }
  54360. +
  54361. + base += size;
  54362. +
  54363. + /* update the suportedCasLatencies mask */
  54364. + bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
  54365. +
  54366. + }
  54367. + else
  54368. + {
  54369. + if( i == 0 ) /* bank 0 doesn't exist */
  54370. + {
  54371. + mvOsPrintf("Dram: ERR. Fail to detect bank 0 !!!\n");
  54372. + return MV_ERROR;
  54373. + }
  54374. + else
  54375. + {
  54376. + DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
  54377. + bankInfo[i].size = 0; /* Mark this bank as non exist */
  54378. + }
  54379. + }
  54380. + }
  54381. +
  54382. + /* calculate minimum CAS */
  54383. + minCas = minCasCalc(&bankInfo[0], busClk, forcedCl);
  54384. + if (0 == minCas)
  54385. + {
  54386. + mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
  54387. + (busClk / 1000000));
  54388. +
  54389. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54390. + {
  54391. + minCas = DDR2_CL_4; /* Continue with this CAS */
  54392. + mvOsPrintf("Set default CAS latency 4\n");
  54393. + }
  54394. + else
  54395. + {
  54396. + minCas = DDR1_CL_3; /* Continue with this CAS */
  54397. + mvOsPrintf("Set default CAS latency 3\n");
  54398. + }
  54399. + }
  54400. +
  54401. + /* calc SDRAM_CONFIG_REG and save it to temp register */
  54402. + temp = sdramConfigRegCalc(&bankInfo[0], busClk);
  54403. + if(-1 == temp)
  54404. + {
  54405. + mvOsPrintf("Dram: ERR. sdramConfigRegCalc failed !!!\n");
  54406. + return MV_ERROR;
  54407. + }
  54408. + MV_REG_WRITE(DRAM_BUF_REG1, temp);
  54409. +
  54410. + /* calc SDRAM_MODE_REG and save it to temp register */
  54411. + temp = sdramModeRegCalc(minCas);
  54412. + if(-1 == temp)
  54413. + {
  54414. + mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
  54415. + return MV_ERROR;
  54416. + }
  54417. + MV_REG_WRITE(DRAM_BUF_REG2, temp);
  54418. +
  54419. + /* calc SDRAM_EXTENDED_MODE_REG and save it to temp register */
  54420. + temp = sdramExtModeRegCalc(&bankInfo[0]);
  54421. + if(-1 == temp)
  54422. + {
  54423. + mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
  54424. + return MV_ERROR;
  54425. + }
  54426. + MV_REG_WRITE(DRAM_BUF_REG10, temp);
  54427. +
  54428. + /* calc D_UNIT_CONTROL_LOW and save it to temp register */
  54429. + temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas);
  54430. + if(-1 == temp)
  54431. + {
  54432. + mvOsPrintf("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
  54433. + return MV_ERROR;
  54434. + }
  54435. + MV_REG_WRITE(DRAM_BUF_REG3, temp);
  54436. +
  54437. + /* calc SDRAM_ADDR_CTRL_REG and save it to temp register */
  54438. + temp = sdramAddrCtrlRegCalc(&bankInfo[0]);
  54439. + if(-1 == temp)
  54440. + {
  54441. + mvOsPrintf("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
  54442. + return MV_ERROR;
  54443. + }
  54444. + MV_REG_WRITE(DRAM_BUF_REG4, temp);
  54445. +
  54446. + /* calc SDRAM_TIMING_CTRL_LOW_REG and save it to temp register */
  54447. + temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
  54448. + if(-1 == temp)
  54449. + {
  54450. + mvOsPrintf("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
  54451. + return MV_ERROR;
  54452. + }
  54453. + MV_REG_WRITE(DRAM_BUF_REG5, temp);
  54454. +
  54455. + /* calc SDRAM_TIMING_CTRL_HIGH_REG and save it to temp register */
  54456. + temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
  54457. + if(-1 == temp)
  54458. + {
  54459. + mvOsPrintf("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
  54460. + return MV_ERROR;
  54461. + }
  54462. + MV_REG_WRITE(DRAM_BUF_REG6, temp);
  54463. +
  54464. + /* Config DDR2 On Die Termination (ODT) registers */
  54465. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54466. + {
  54467. + sdramDDr2OdtConfig(bankInfo);
  54468. + }
  54469. +
  54470. + /* Note that DDR SDRAM Address/Control and Data pad calibration */
  54471. + /* settings is done in mvSdramIfConfig.s */
  54472. +
  54473. + return retVal;
  54474. +}
  54475. +
  54476. +/*******************************************************************************
  54477. +* minCasCalc - Calculate the Minimum CAS latency which can be used.
  54478. +*
  54479. +* DESCRIPTION:
  54480. +* Calculate the minimum CAS latency that can be used, base on the DRAM
  54481. +* parameters and the SDRAM bus Clock freq.
  54482. +*
  54483. +* INPUT:
  54484. +* busClk - the DRAM bus Clock.
  54485. +* pBankInfo - bank info parameters.
  54486. +*
  54487. +* OUTPUT:
  54488. +* None
  54489. +*
  54490. +* RETURN:
  54491. +* The minimum CAS Latency. The function returns 0 if max CAS latency
  54492. +* supported by banks is incompatible with system bus clock frequancy.
  54493. +*
  54494. +*******************************************************************************/
  54495. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk,
  54496. + MV_U32 forcedCl)
  54497. +{
  54498. + MV_U32 count = 1, j;
  54499. + MV_U32 busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
  54500. + MV_U32 startBit, stopBit;
  54501. +
  54502. + /* DDR 1:
  54503. + *******-******-******-******-******-******-******-*******
  54504. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54505. + *******-******-******-******-******-******-******-*******
  54506. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  54507. + *********************************************************/
  54508. +
  54509. + /* DDR 2:
  54510. + *******-******-******-******-******-******-******-*******
  54511. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54512. + *******-******-******-******-******-******-******-*******
  54513. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  54514. + *********************************************************/
  54515. +
  54516. +
  54517. + /* If we are asked to use the forced CAL */
  54518. + if (forcedCl)
  54519. + {
  54520. + mvOsPrintf("DRAM: Using forced CL %d.%d\n", (forcedCl / 10),
  54521. + (forcedCl % 10));
  54522. +
  54523. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54524. + {
  54525. + if (forcedCl == 30)
  54526. + pBankInfo->suportedCasLatencies = 0x08;
  54527. + else if (forcedCl == 40)
  54528. + pBankInfo->suportedCasLatencies = 0x10;
  54529. + else
  54530. + {
  54531. + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n",
  54532. + (forcedCl / 10), (forcedCl % 10));
  54533. + pBankInfo->suportedCasLatencies = 0x10;
  54534. + }
  54535. + }
  54536. + else
  54537. + {
  54538. + if (forcedCl == 15)
  54539. + pBankInfo->suportedCasLatencies = 0x02;
  54540. + else if (forcedCl == 20)
  54541. + pBankInfo->suportedCasLatencies = 0x04;
  54542. + else if (forcedCl == 25)
  54543. + pBankInfo->suportedCasLatencies = 0x08;
  54544. + else if (forcedCl == 30)
  54545. + pBankInfo->suportedCasLatencies = 0x10;
  54546. + else if (forcedCl == 40)
  54547. + pBankInfo->suportedCasLatencies = 0x40;
  54548. + else
  54549. + {
  54550. + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 3\n",
  54551. + (forcedCl / 10), (forcedCl % 10));
  54552. + pBankInfo->suportedCasLatencies = 0x10;
  54553. + }
  54554. + }
  54555. +
  54556. + return pBankInfo->suportedCasLatencies;
  54557. + }
  54558. +
  54559. + /* go over the supported cas mask from Max Cas down and check if the */
  54560. + /* SysClk stands in its time requirments. */
  54561. +
  54562. +
  54563. + DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
  54564. + pBankInfo->suportedCasLatencies,busClkPs ));
  54565. + for(j = 7; j > 0; j--)
  54566. + {
  54567. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  54568. + {
  54569. + /* Reset the bits for CL incompatible for the sysClk */
  54570. + switch (count)
  54571. + {
  54572. + case 1:
  54573. + if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs)
  54574. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  54575. + count++;
  54576. + break;
  54577. + case 2:
  54578. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
  54579. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  54580. + count++;
  54581. + break;
  54582. + case 3:
  54583. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
  54584. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  54585. + count++;
  54586. + break;
  54587. + default:
  54588. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  54589. + break;
  54590. + }
  54591. + }
  54592. + }
  54593. +
  54594. + DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
  54595. + pBankInfo->suportedCasLatencies ));
  54596. +
  54597. + /* SDRAM DDR1 controller supports CL 1.5 to 3.5 */
  54598. + /* SDRAM DDR2 controller supports CL 3 to 5 */
  54599. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54600. + {
  54601. + startBit = 3; /* DDR2 support CL start with CL3 (bit 3) */
  54602. + stopBit = 5; /* DDR2 support CL stops with CL5 (bit 5) */
  54603. + }
  54604. + else
  54605. + {
  54606. + startBit = 1; /* DDR1 support CL start with CL1.5 (bit 3) */
  54607. + stopBit = 4; /* DDR1 support CL stops with CL3 (bit 4) */
  54608. + }
  54609. +
  54610. + for(j = startBit; j <= stopBit ; j++)
  54611. + {
  54612. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  54613. + {
  54614. + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
  54615. + return (BIT0 << j);
  54616. + }
  54617. + }
  54618. +
  54619. + return 0;
  54620. +}
  54621. +
  54622. +/*******************************************************************************
  54623. +* sdramConfigRegCalc - Calculate sdram config register
  54624. +*
  54625. +* DESCRIPTION: Calculate sdram config register optimized value based
  54626. +* on the bank info parameters.
  54627. +*
  54628. +* INPUT:
  54629. +* pBankInfo - sdram bank parameters
  54630. +*
  54631. +* OUTPUT:
  54632. +* None
  54633. +*
  54634. +* RETURN:
  54635. +* sdram config reg value.
  54636. +*
  54637. +*******************************************************************************/
  54638. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  54639. +{
  54640. + MV_U32 sdramConfig = 0;
  54641. + MV_U32 refreshPeriod;
  54642. +
  54643. + busClk /= 1000000; /* we work with busClk in MHz */
  54644. +
  54645. + sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
  54646. +
  54647. + /* figure out the memory refresh internal */
  54648. + switch (pBankInfo->refreshInterval & 0xf)
  54649. + {
  54650. + case 0x0: /* refresh period is 15.625 usec */
  54651. + refreshPeriod = 15625;
  54652. + break;
  54653. + case 0x1: /* refresh period is 3.9 usec */
  54654. + refreshPeriod = 3900;
  54655. + break;
  54656. + case 0x2: /* refresh period is 7.8 usec */
  54657. + refreshPeriod = 7800;
  54658. + break;
  54659. + case 0x3: /* refresh period is 31.3 usec */
  54660. + refreshPeriod = 31300;
  54661. + break;
  54662. + case 0x4: /* refresh period is 62.5 usec */
  54663. + refreshPeriod = 62500;
  54664. + break;
  54665. + case 0x5: /* refresh period is 125 usec */
  54666. + refreshPeriod = 125000;
  54667. + break;
  54668. + default: /* refresh period undefined */
  54669. + mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
  54670. + return -1;
  54671. + }
  54672. +
  54673. + /* Now the refreshPeriod is in register format value */
  54674. + refreshPeriod = (busClk * refreshPeriod) / 1000;
  54675. +
  54676. + DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n",
  54677. + refreshPeriod));
  54678. +
  54679. + /* make sure the refresh value is only 14 bits */
  54680. + if(refreshPeriod > SDRAM_REFRESH_MAX)
  54681. + {
  54682. + refreshPeriod = SDRAM_REFRESH_MAX;
  54683. + DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n",
  54684. + refreshPeriod));
  54685. + }
  54686. +
  54687. + /* Clear the refresh field */
  54688. + sdramConfig &= ~SDRAM_REFRESH_MASK;
  54689. +
  54690. + /* Set new value to refresh field */
  54691. + sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
  54692. +
  54693. + /* registered DRAM ? */
  54694. + if ( pBankInfo->registeredAddrAndControlInputs )
  54695. + {
  54696. + /* it's registered DRAM, so set the reg. DRAM bit */
  54697. + sdramConfig |= SDRAM_REGISTERED;
  54698. + mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");
  54699. + }
  54700. +
  54701. + /* set DDR SDRAM devices configuration */
  54702. + sdramConfig &= ~SDRAM_DCFG_MASK; /* Clear Dcfg field */
  54703. +
  54704. + switch (pBankInfo->sdramWidth)
  54705. + {
  54706. + case 8: /* memory is x8 */
  54707. + sdramConfig |= SDRAM_DCFG_X8_DEV;
  54708. + DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x8\n"));
  54709. + break;
  54710. + case 16:
  54711. + sdramConfig |= SDRAM_DCFG_X16_DEV;
  54712. + DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x16\n"));
  54713. + break;
  54714. + default: /* memory width unsupported */
  54715. + mvOsPrintf("Dram: ERR. DRAM chip width is unknown!\n");
  54716. + return -1;
  54717. + }
  54718. +
  54719. + /* Set static default settings */
  54720. + sdramConfig |= SDRAM_CONFIG_DV;
  54721. +
  54722. + DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
  54723. + sdramConfig));
  54724. +
  54725. + return sdramConfig;
  54726. +}
  54727. +
  54728. +/*******************************************************************************
  54729. +* sdramModeRegCalc - Calculate sdram mode register
  54730. +*
  54731. +* DESCRIPTION: Calculate sdram mode register optimized value based
  54732. +* on the bank info parameters and the minCas.
  54733. +*
  54734. +* INPUT:
  54735. +* minCas - minimum CAS supported.
  54736. +*
  54737. +* OUTPUT:
  54738. +* None
  54739. +*
  54740. +* RETURN:
  54741. +* sdram mode reg value.
  54742. +*
  54743. +*******************************************************************************/
  54744. +static MV_U32 sdramModeRegCalc(MV_U32 minCas)
  54745. +{
  54746. + MV_U32 sdramMode;
  54747. +
  54748. + sdramMode = MV_REG_READ(SDRAM_MODE_REG);
  54749. +
  54750. + /* Clear CAS Latency field */
  54751. + sdramMode &= ~SDRAM_CL_MASK;
  54752. +
  54753. + mvOsPrintf("DRAM CAS Latency ");
  54754. +
  54755. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54756. + {
  54757. + switch (minCas)
  54758. + {
  54759. + case DDR2_CL_3:
  54760. + sdramMode |= SDRAM_DDR2_CL_3;
  54761. + mvOsPrintf("3.\n");
  54762. + break;
  54763. + case DDR2_CL_4:
  54764. + sdramMode |= SDRAM_DDR2_CL_4;
  54765. + mvOsPrintf("4.\n");
  54766. + break;
  54767. + case DDR2_CL_5:
  54768. + sdramMode |= SDRAM_DDR2_CL_5;
  54769. + mvOsPrintf("5.\n");
  54770. + break;
  54771. + default:
  54772. + mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
  54773. + return -1;
  54774. + }
  54775. + sdramMode |= DDR2_MODE_REG_DV;
  54776. + }
  54777. + else /* DDR1 */
  54778. + {
  54779. + switch (minCas)
  54780. + {
  54781. + case DDR1_CL_1_5:
  54782. + sdramMode |= SDRAM_DDR1_CL_1_5;
  54783. + mvOsPrintf("1.5\n");
  54784. + break;
  54785. + case DDR1_CL_2:
  54786. + sdramMode |= SDRAM_DDR1_CL_2;
  54787. + mvOsPrintf("2\n");
  54788. + break;
  54789. + case DDR1_CL_2_5:
  54790. + sdramMode |= SDRAM_DDR1_CL_2_5;
  54791. + mvOsPrintf("2.5\n");
  54792. + break;
  54793. + case DDR1_CL_3:
  54794. + sdramMode |= SDRAM_DDR1_CL_3;
  54795. + mvOsPrintf("3\n");
  54796. + break;
  54797. + case DDR1_CL_4:
  54798. + sdramMode |= SDRAM_DDR1_CL_4;
  54799. + mvOsPrintf("4\n");
  54800. + break;
  54801. + default:
  54802. + mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
  54803. + return -1;
  54804. + }
  54805. + sdramMode |= DDR1_MODE_REG_DV;
  54806. + }
  54807. +
  54808. + DB(mvOsPrintf("nsdramModeRegCalc register 0x%x\n", sdramMode ));
  54809. +
  54810. + return sdramMode;
  54811. +}
  54812. +
  54813. +/*******************************************************************************
  54814. +* sdramExtModeRegCalc - Calculate sdram Extended mode register
  54815. +*
  54816. +* DESCRIPTION:
  54817. +* Return sdram Extended mode register value based
  54818. +* on the bank info parameters and bank presence.
  54819. +*
  54820. +* INPUT:
  54821. +* pBankInfo - sdram bank parameters
  54822. +*
  54823. +* OUTPUT:
  54824. +* None
  54825. +*
  54826. +* RETURN:
  54827. +* sdram Extended mode reg value.
  54828. +*
  54829. +*******************************************************************************/
  54830. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
  54831. +{
  54832. + MV_U32 populateBanks = 0;
  54833. + int bankNum;
  54834. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54835. + {
  54836. + /* Represent the populate banks in binary form */
  54837. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  54838. + {
  54839. + if (0 != pBankInfo[bankNum].size)
  54840. + {
  54841. + populateBanks |= (1 << bankNum);
  54842. + }
  54843. + }
  54844. +
  54845. + switch(populateBanks)
  54846. + {
  54847. + case(BANK_PRESENT_CS0):
  54848. + return DDR_SDRAM_EXT_MODE_CS0_DV;
  54849. +
  54850. + case(BANK_PRESENT_CS0_CS1):
  54851. + return DDR_SDRAM_EXT_MODE_CS0_DV;
  54852. +
  54853. + case(BANK_PRESENT_CS0_CS2):
  54854. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  54855. +
  54856. + case(BANK_PRESENT_CS0_CS1_CS2):
  54857. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  54858. +
  54859. + case(BANK_PRESENT_CS0_CS2_CS3):
  54860. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  54861. +
  54862. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  54863. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  54864. +
  54865. + default:
  54866. + mvOsPrintf("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
  54867. + return -1;
  54868. + }
  54869. + }
  54870. + return 0;
  54871. +}
  54872. +
  54873. +/*******************************************************************************
  54874. +* dunitCtrlLowRegCalc - Calculate sdram dunit control low register
  54875. +*
  54876. +* DESCRIPTION: Calculate sdram dunit control low register optimized value based
  54877. +* on the bank info parameters and the minCas.
  54878. +*
  54879. +* INPUT:
  54880. +* pBankInfo - sdram bank parameters
  54881. +* minCas - minimum CAS supported.
  54882. +*
  54883. +* OUTPUT:
  54884. +* None
  54885. +*
  54886. +* RETURN:
  54887. +* sdram dunit control low reg value.
  54888. +*
  54889. +*******************************************************************************/
  54890. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas)
  54891. +{
  54892. + MV_U32 dunitCtrlLow;
  54893. +
  54894. + dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
  54895. +
  54896. + /* Clear StBurstDel field */
  54897. + dunitCtrlLow &= ~SDRAM_ST_BURST_DEL_MASK;
  54898. +
  54899. +#ifdef MV_88W8660
  54900. + /* Clear address/control output timing field */
  54901. + dunitCtrlLow &= ~SDRAM_CTRL_POS_RISE;
  54902. +#endif /* MV_88W8660 */
  54903. +
  54904. + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
  54905. +
  54906. + /* For proper sample of read data set the Dunit Control register's */
  54907. + /* stBurstDel bits [27:24] */
  54908. + /********-********-********-********-********-*********
  54909. + * CL=1.5 | CL=2 | CL=2.5 | CL=3 | CL=4 | CL=5 *
  54910. + *********-********-********-********-********-*********
  54911. +Not Reg. * 0011 | 0011 | 0100 | 0100 | 0101 | TBD *
  54912. + *********-********-********-********-********-*********
  54913. +Registered * 0100 | 0100 | 0101 | 0101 | 0110 | TBD *
  54914. + *********-********-********-********-********-*********/
  54915. +
  54916. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54917. + {
  54918. + switch (minCas)
  54919. + {
  54920. + case DDR2_CL_3:
  54921. + /* registerd DDR SDRAM? */
  54922. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54923. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  54924. + else
  54925. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  54926. + break;
  54927. + case DDR2_CL_4:
  54928. + /* registerd DDR SDRAM? */
  54929. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54930. + dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
  54931. + else
  54932. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  54933. + break;
  54934. + default:
  54935. + mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n",
  54936. + minCas);
  54937. + return -1;
  54938. + }
  54939. + }
  54940. + else /* DDR1 */
  54941. + {
  54942. + switch (minCas)
  54943. + {
  54944. + case DDR1_CL_1_5:
  54945. + /* registerd DDR SDRAM? */
  54946. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54947. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  54948. + else
  54949. + dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
  54950. + break;
  54951. + case DDR1_CL_2:
  54952. + /* registerd DDR SDRAM? */
  54953. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54954. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  54955. + else
  54956. + dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
  54957. + break;
  54958. + case DDR1_CL_2_5:
  54959. + /* registerd DDR SDRAM? */
  54960. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54961. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  54962. + else
  54963. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  54964. + break;
  54965. + case DDR1_CL_3:
  54966. + /* registerd DDR SDRAM? */
  54967. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54968. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  54969. + else
  54970. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  54971. + break;
  54972. + case DDR1_CL_4:
  54973. + /* registerd DDR SDRAM? */
  54974. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54975. + dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
  54976. + else
  54977. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  54978. + break;
  54979. + default:
  54980. + mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n",
  54981. + minCas);
  54982. + return -1;
  54983. + }
  54984. +
  54985. + }
  54986. + DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
  54987. +
  54988. + return dunitCtrlLow;
  54989. +}
  54990. +
  54991. +/*******************************************************************************
  54992. +* sdramAddrCtrlRegCalc - Calculate sdram address control register
  54993. +*
  54994. +* DESCRIPTION: Calculate sdram address control register optimized value based
  54995. +* on the bank info parameters and the minCas.
  54996. +*
  54997. +* INPUT:
  54998. +* pBankInfo - sdram bank parameters
  54999. +*
  55000. +* OUTPUT:
  55001. +* None
  55002. +*
  55003. +* RETURN:
  55004. +* sdram address control reg value.
  55005. +*
  55006. +*******************************************************************************/
  55007. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
  55008. +{
  55009. + MV_U32 addrCtrl = 0;
  55010. +
  55011. + /* Set Address Control register static configuration bits */
  55012. + addrCtrl = MV_REG_READ(SDRAM_ADDR_CTRL_REG);
  55013. +
  55014. + /* Set address control default value */
  55015. + addrCtrl |= SDRAM_ADDR_CTRL_DV;
  55016. +
  55017. + /* Clear DSize field */
  55018. + addrCtrl &= ~SDRAM_DSIZE_MASK;
  55019. +
  55020. + /* Note that density is in MB units */
  55021. + switch (pBankInfo->deviceDensity)
  55022. + {
  55023. + case 128: /* 128 Mbit */
  55024. + DB(mvOsPrintf("DRAM Device Density 128Mbit\n"));
  55025. + addrCtrl |= SDRAM_DSIZE_128Mb;
  55026. + break;
  55027. + case 256: /* 256 Mbit */
  55028. + DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
  55029. + addrCtrl |= SDRAM_DSIZE_256Mb;
  55030. + break;
  55031. + case 512: /* 512 Mbit */
  55032. + DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
  55033. + addrCtrl |= SDRAM_DSIZE_512Mb;
  55034. + break;
  55035. + default:
  55036. + mvOsPrintf("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
  55037. + pBankInfo->deviceDensity);
  55038. + return -1;
  55039. + }
  55040. +
  55041. + /* SDRAM address control */
  55042. + DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
  55043. +
  55044. + return addrCtrl;
  55045. +}
  55046. +
  55047. +/*******************************************************************************
  55048. +* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
  55049. +*
  55050. +* DESCRIPTION:
  55051. +* This function calculates sdram timing control low register
  55052. +* optimized value based on the bank info parameters and the minCas.
  55053. +*
  55054. +* INPUT:
  55055. +* pBankInfo - sdram bank parameters
  55056. +* busClk - Bus clock
  55057. +*
  55058. +* OUTPUT:
  55059. +* None
  55060. +*
  55061. +* RETURN:
  55062. +* sdram timinf control low reg value.
  55063. +*
  55064. +*******************************************************************************/
  55065. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  55066. + MV_U32 minCas, MV_U32 busClk)
  55067. +{
  55068. + MV_U32 tRp = 0;
  55069. + MV_U32 tRrd = 0;
  55070. + MV_U32 tRcd = 0;
  55071. + MV_U32 tRas = 0;
  55072. + MV_U32 tWr = 0;
  55073. + MV_U32 tWtr = 0;
  55074. + MV_U32 tRtp = 0;
  55075. +
  55076. + MV_U32 bankNum;
  55077. +
  55078. + busClk = busClk / 1000000; /* In MHz */
  55079. +
  55080. + /* Scan all DRAM banks to find maximum timing values */
  55081. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  55082. + {
  55083. + tRp = MV_MAX(tRp, pBankInfo[bankNum].minRowPrechargeTime);
  55084. + tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
  55085. + tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
  55086. + tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
  55087. + }
  55088. +
  55089. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns part. */
  55090. + /* by shifting the data two bits right. */
  55091. + tRp = tRp >> 2; /* For example 0x50 -> 20ns */
  55092. + tRrd = tRrd >> 2;
  55093. + tRcd = tRcd >> 2;
  55094. +
  55095. + /* Extract clock cycles from time parameter. We need to round up */
  55096. + tRp = ((busClk * tRp) / 1000) + (((busClk * tRp) % 1000) ? 1 : 0);
  55097. + /* Micron work around for 133MHz */
  55098. + if (busClk == 133)
  55099. + tRp += 1;
  55100. + DB(mvOsPrintf("Dram Timing Low: tRp = %d ", tRp));
  55101. + tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
  55102. + /* JEDEC min reqeirments tRrd = 2 */
  55103. + if (tRrd < 2)
  55104. + tRrd = 2;
  55105. + DB(mvOsPrintf("tRrd = %d ", tRrd));
  55106. + tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
  55107. + DB(mvOsPrintf("tRcd = %d ", tRcd));
  55108. + tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
  55109. + DB(mvOsPrintf("tRas = %d ", tRas));
  55110. +
  55111. + /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2 */
  55112. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  55113. + {
  55114. + /* Scan all DRAM banks to find maximum timing values */
  55115. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  55116. + {
  55117. + tWr = MV_MAX(tWr, pBankInfo[bankNum].minWriteRecoveryTime);
  55118. + tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
  55119. + tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
  55120. + }
  55121. +
  55122. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns */
  55123. + /* part by shifting the data two bits right. */
  55124. + tWr = tWr >> 2; /* For example 0x50 -> 20ns */
  55125. + tWtr = tWtr >> 2;
  55126. + tRtp = tRtp >> 2;
  55127. +
  55128. + /* Extract clock cycles from time parameter. We need to round up */
  55129. + tWr = ((busClk * tWr) / 1000) + (((busClk * tWr) % 1000) ? 1 : 0);
  55130. + DB(mvOsPrintf("tWr = %d ", tWr));
  55131. + tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
  55132. + /* JEDEC min reqeirments tWtr = 2 */
  55133. + if (tWtr < 2)
  55134. + tWtr = 2;
  55135. + DB(mvOsPrintf("tWtr = %d ", tWtr));
  55136. + tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
  55137. + /* JEDEC min reqeirments tRtp = 2 */
  55138. + if (tRtp < 2)
  55139. + tRtp = 2;
  55140. + DB(mvOsPrintf("tRtp = %d ", tRtp));
  55141. + }
  55142. + else
  55143. + {
  55144. + tWr = ((busClk*SDRAM_TWR) / 1000) + (((busClk*SDRAM_TWR) % 1000)?1:0);
  55145. +
  55146. + if ((200 == busClk) || ((100 == busClk) && (DDR1_CL_1_5 == minCas)))
  55147. + {
  55148. + tWtr = 2;
  55149. + }
  55150. + else
  55151. + {
  55152. + tWtr = 1;
  55153. + }
  55154. +
  55155. + tRtp = 2; /* Must be set to 0x1 (two cycles) when using DDR1 */
  55156. + }
  55157. +
  55158. + DB(mvOsPrintf("tWtr = %d\n", tWtr));
  55159. +
  55160. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  55161. + return (((tRp - 1) << SDRAM_TRP_OFFS) |
  55162. + ((tRrd - 1) << SDRAM_TRRD_OFFS) |
  55163. + ((tRcd - 1) << SDRAM_TRCD_OFFS) |
  55164. + ((tRas - 1) << SDRAM_TRAS_OFFS) |
  55165. + ((tWr - 1) << SDRAM_TWR_OFFS) |
  55166. + ((tWtr - 1) << SDRAM_TWTR_OFFS) |
  55167. + ((tRtp - 1) << SDRAM_TRTP_OFFS));
  55168. +}
  55169. +
  55170. +/*******************************************************************************
  55171. +* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
  55172. +*
  55173. +* DESCRIPTION:
  55174. +* This function calculates sdram timing control high register
  55175. +* optimized value based on the bank info parameters and the bus clock.
  55176. +*
  55177. +* INPUT:
  55178. +* pBankInfo - sdram bank parameters
  55179. +* busClk - Bus clock
  55180. +*
  55181. +* OUTPUT:
  55182. +* None
  55183. +*
  55184. +* RETURN:
  55185. +* sdram timinf control high reg value.
  55186. +*
  55187. +*******************************************************************************/
  55188. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  55189. + MV_U32 busClk)
  55190. +{
  55191. + MV_U32 tRfc;
  55192. + MV_U32 timeNs = 0;
  55193. + int bankNum;
  55194. + MV_U32 sdramTw2wCyc = 0;
  55195. +
  55196. + busClk = busClk / 1000000; /* In MHz */
  55197. +
  55198. + /* tRfc is different for DDR1 and DDR2. */
  55199. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  55200. + {
  55201. + MV_U32 bankNum;
  55202. +
  55203. + /* Scan all DRAM banks to find maximum timing values */
  55204. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  55205. + timeNs = MV_MAX(timeNs, pBankInfo[bankNum].minRefreshToActiveCmd);
  55206. + }
  55207. + else
  55208. + {
  55209. + if (pBankInfo[0].deviceDensity == _1G)
  55210. + {
  55211. + timeNs = SDRAM_TRFC_1G;
  55212. + }
  55213. + else
  55214. + {
  55215. + if (200 == busClk)
  55216. + {
  55217. + timeNs = SDRAM_TRFC_64_512M_AT_200MHZ;
  55218. + }
  55219. + else
  55220. + {
  55221. + timeNs = SDRAM_TRFC_64_512M;
  55222. + }
  55223. + }
  55224. + }
  55225. +
  55226. + tRfc = ((busClk * timeNs) / 1000) + (((busClk * timeNs) % 1000) ? 1 : 0);
  55227. +
  55228. + DB(mvOsPrintf("Dram Timing High: tRfc = %d\n", tRfc));
  55229. +
  55230. +
  55231. + /* Represent the populate banks in binary form */
  55232. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  55233. + {
  55234. + if (0 != pBankInfo[bankNum].size)
  55235. + sdramTw2wCyc++;
  55236. + }
  55237. +
  55238. + /* If we have more the 1 bank then we need the TW2W in 1 for ODT switch */
  55239. + if (sdramTw2wCyc > 1)
  55240. + sdramTw2wCyc = 1;
  55241. + else
  55242. + sdramTw2wCyc = 0;
  55243. +
  55244. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  55245. + return ((((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS) |
  55246. + ((SDRAM_TR2R_CYC - 1) << SDRAM_TR2R_OFFS) |
  55247. + ((SDRAM_TR2WW2R_CYC - 1) << SDRAM_TR2W_W2R_OFFS) |
  55248. + (((tRfc - 1) >> 4) << SDRAM_TRFC_EXT_OFFS) |
  55249. + (sdramTw2wCyc << SDRAM_TW2W_OFFS));
  55250. +
  55251. +}
  55252. +
  55253. +/*******************************************************************************
  55254. +* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
  55255. +*
  55256. +* DESCRIPTION:
  55257. +* This function config DDR2 On Die Termination (ODT) registers.
  55258. +* ODT configuration is done according to DIMM presence:
  55259. +*
  55260. +* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode
  55261. +* CS0 0x84210000 0x00000000 0x0000780F 0x00000440
  55262. +* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440
  55263. +* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404
  55264. +* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404
  55265. +* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404
  55266. +* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404
  55267. +*
  55268. +* INPUT:
  55269. +* pBankInfo - bank info parameters.
  55270. +*
  55271. +* OUTPUT:
  55272. +* None
  55273. +*
  55274. +* RETURN:
  55275. +* None
  55276. +*******************************************************************************/
  55277. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
  55278. +{
  55279. + MV_U32 populateBanks = 0;
  55280. + MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
  55281. + int bankNum;
  55282. +
  55283. + /* Represent the populate banks in binary form */
  55284. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  55285. + {
  55286. + if (0 != pBankInfo[bankNum].size)
  55287. + {
  55288. + populateBanks |= (1 << bankNum);
  55289. + }
  55290. + }
  55291. +
  55292. + switch(populateBanks)
  55293. + {
  55294. + case(BANK_PRESENT_CS0):
  55295. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_DV;
  55296. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_DV;
  55297. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
  55298. + break;
  55299. + case(BANK_PRESENT_CS0_CS1):
  55300. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_DV;
  55301. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_DV;
  55302. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
  55303. + break;
  55304. + case(BANK_PRESENT_CS0_CS2):
  55305. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  55306. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  55307. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  55308. + break;
  55309. + case(BANK_PRESENT_CS0_CS1_CS2):
  55310. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  55311. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  55312. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  55313. + break;
  55314. + case(BANK_PRESENT_CS0_CS2_CS3):
  55315. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  55316. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  55317. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  55318. + break;
  55319. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  55320. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  55321. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  55322. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  55323. + break;
  55324. + default:
  55325. + mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n");
  55326. + return;
  55327. + }
  55328. + MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
  55329. + MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
  55330. + MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
  55331. + return;
  55332. +}
  55333. +#endif /* defined(MV_INC_BOARD_DDIM) */
  55334. +
  55335. +/*******************************************************************************
  55336. +* mvDramIfWinSet - Set DRAM interface address decode window
  55337. +*
  55338. +* DESCRIPTION:
  55339. +* This function sets DRAM interface address decode window.
  55340. +*
  55341. +* INPUT:
  55342. +* target - System target. Use only SDRAM targets.
  55343. +* pAddrDecWin - SDRAM address window structure.
  55344. +*
  55345. +* OUTPUT:
  55346. +* None
  55347. +*
  55348. +* RETURN:
  55349. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  55350. +* otherwise.
  55351. +*******************************************************************************/
  55352. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  55353. +{
  55354. + MV_U32 baseReg=0,sizeReg=0;
  55355. + MV_U32 baseToReg=0 , sizeToReg=0;
  55356. +
  55357. + /* Check parameters */
  55358. + if (!MV_TARGET_IS_DRAM(target))
  55359. + {
  55360. + mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
  55361. + return MV_BAD_PARAM;
  55362. + }
  55363. +
  55364. + /* Check if the requested window overlaps with current enabled windows */
  55365. + if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
  55366. + {
  55367. + mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
  55368. + return MV_BAD_PARAM;
  55369. + }
  55370. +
  55371. + /* check if address is aligned to the size */
  55372. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  55373. + {
  55374. + mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
  55375. + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
  55376. + target,
  55377. + pAddrDecWin->addrWin.baseLow,
  55378. + pAddrDecWin->addrWin.size);
  55379. + return MV_ERROR;
  55380. + }
  55381. +
  55382. + /* read base register*/
  55383. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
  55384. +
  55385. + /* read size register */
  55386. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
  55387. +
  55388. + /* BaseLow[31:16] => base register [31:16] */
  55389. + baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;
  55390. +
  55391. + /* Write to address decode Base Address Register */
  55392. + baseReg &= ~SCBAR_BASE_MASK;
  55393. + baseReg |= baseToReg;
  55394. +
  55395. + /* Translate the given window size to register format */
  55396. + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);
  55397. +
  55398. + /* Size parameter validity check. */
  55399. + if (-1 == sizeToReg)
  55400. + {
  55401. + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
  55402. + return MV_BAD_PARAM;
  55403. + }
  55404. +
  55405. + /* set size */
  55406. + sizeReg &= ~SCSR_SIZE_MASK;
  55407. + /* Size is located at upper 16 bits */
  55408. + sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);
  55409. +
  55410. + /* enable/Disable */
  55411. + if (MV_TRUE == pAddrDecWin->enable)
  55412. + {
  55413. + sizeReg |= SCSR_WIN_EN;
  55414. + }
  55415. + else
  55416. + {
  55417. + sizeReg &= ~SCSR_WIN_EN;
  55418. + }
  55419. +
  55420. + /* 3) Write to address decode Base Address Register */
  55421. + MV_REG_WRITE(SDRAM_BASE_ADDR_REG(target), baseReg);
  55422. +
  55423. + /* Write to address decode Size Register */
  55424. + MV_REG_WRITE(SDRAM_SIZE_REG(target), sizeReg);
  55425. +
  55426. + return MV_OK;
  55427. +}
  55428. +/*******************************************************************************
  55429. +* mvDramIfWinGet - Get DRAM interface address decode window
  55430. +*
  55431. +* DESCRIPTION:
  55432. +* This function gets DRAM interface address decode window.
  55433. +*
  55434. +* INPUT:
  55435. +* target - System target. Use only SDRAM targets.
  55436. +*
  55437. +* OUTPUT:
  55438. +* pAddrDecWin - SDRAM address window structure.
  55439. +*
  55440. +* RETURN:
  55441. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  55442. +* otherwise.
  55443. +*******************************************************************************/
  55444. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  55445. +{
  55446. + MV_U32 baseReg,sizeReg;
  55447. + MV_U32 sizeRegVal;
  55448. +
  55449. + /* Check parameters */
  55450. + if (!MV_TARGET_IS_DRAM(target))
  55451. + {
  55452. + mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);
  55453. + return MV_ERROR;
  55454. + }
  55455. +
  55456. + /* Read base and size registers */
  55457. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
  55458. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
  55459. +
  55460. + sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;
  55461. +
  55462. + pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,
  55463. + SCSR_SIZE_ALIGNMENT);
  55464. +
  55465. + /* Check if ctrlRegToSize returned OK */
  55466. + if (-1 == pAddrDecWin->addrWin.size)
  55467. + {
  55468. + mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);
  55469. + return MV_ERROR;
  55470. + }
  55471. +
  55472. + /* Extract base address */
  55473. + /* Base register [31:16] ==> baseLow[31:16] */
  55474. + pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;
  55475. +
  55476. + pAddrDecWin->addrWin.baseHigh = 0;
  55477. +
  55478. +
  55479. + if (sizeReg & SCSR_WIN_EN)
  55480. + {
  55481. + pAddrDecWin->enable = MV_TRUE;
  55482. + }
  55483. + else
  55484. + {
  55485. + pAddrDecWin->enable = MV_FALSE;
  55486. + }
  55487. +
  55488. + return MV_OK;
  55489. +}
  55490. +/*******************************************************************************
  55491. +* mvDramIfWinEnable - Enable/Disable SDRAM address decode window
  55492. +*
  55493. +* DESCRIPTION:
  55494. +* This function enable/Disable SDRAM address decode window.
  55495. +*
  55496. +* INPUT:
  55497. +* target - System target. Use only SDRAM targets.
  55498. +*
  55499. +* OUTPUT:
  55500. +* None.
  55501. +*
  55502. +* RETURN:
  55503. +* MV_ERROR in case function parameter are invalid, MV_OK otherewise.
  55504. +*
  55505. +*******************************************************************************/
  55506. +MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable)
  55507. +{
  55508. + MV_DRAM_DEC_WIN addrDecWin;
  55509. +
  55510. + /* Check parameters */
  55511. + if (!MV_TARGET_IS_DRAM(target))
  55512. + {
  55513. + mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
  55514. + return MV_ERROR;
  55515. + }
  55516. +
  55517. + if (enable == MV_TRUE)
  55518. + { /* First check for overlap with other enabled windows */
  55519. + if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
  55520. + {
  55521. + mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n",
  55522. + target);
  55523. + return MV_ERROR;
  55524. + }
  55525. + /* Check for overlapping */
  55526. + if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
  55527. + {
  55528. + /* No Overlap. Enable address decode winNum window */
  55529. + MV_REG_BIT_SET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
  55530. + }
  55531. + else
  55532. + { /* Overlap detected */
  55533. + mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
  55534. + target);
  55535. + return MV_ERROR;
  55536. + }
  55537. + }
  55538. + else
  55539. + { /* Disable address decode winNum window */
  55540. + MV_REG_BIT_RESET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
  55541. + }
  55542. +
  55543. + return MV_OK;
  55544. +}
  55545. +
  55546. +/*******************************************************************************
  55547. +* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window
  55548. +*
  55549. +* DESCRIPTION:
  55550. +* This function scan each SDRAM address decode window to test if it
  55551. +* overlapps the given address windoow
  55552. +*
  55553. +* INPUT:
  55554. +* target - SDRAM target where the function skips checking.
  55555. +* pAddrDecWin - The tested address window for overlapping with
  55556. +* SDRAM windows.
  55557. +*
  55558. +* OUTPUT:
  55559. +* None.
  55560. +*
  55561. +* RETURN:
  55562. +* MV_TRUE if the given address window overlaps any enabled address
  55563. +* decode map, MV_FALSE otherwise.
  55564. +*
  55565. +*******************************************************************************/
  55566. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
  55567. +{
  55568. + MV_TARGET targetNum;
  55569. + MV_DRAM_DEC_WIN addrDecWin;
  55570. +
  55571. + for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)
  55572. + {
  55573. + /* don't check our winNum or illegal targets */
  55574. + if (targetNum == target)
  55575. + {
  55576. + continue;
  55577. + }
  55578. +
  55579. + /* Get window parameters */
  55580. + if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))
  55581. + {
  55582. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  55583. + return MV_ERROR;
  55584. + }
  55585. +
  55586. + /* Do not check disabled windows */
  55587. + if (MV_FALSE == addrDecWin.enable)
  55588. + {
  55589. + continue;
  55590. + }
  55591. +
  55592. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  55593. + {
  55594. + mvOsPrintf(
  55595. + "sdramIfWinOverlap: Required target %d overlap winNum %d\n",
  55596. + target, targetNum);
  55597. + return MV_TRUE;
  55598. + }
  55599. + }
  55600. +
  55601. + return MV_FALSE;
  55602. +}
  55603. +
  55604. +/*******************************************************************************
  55605. +* mvDramIfBankSizeGet - Get DRAM interface bank size.
  55606. +*
  55607. +* DESCRIPTION:
  55608. +* This function returns the size of a given DRAM bank.
  55609. +*
  55610. +* INPUT:
  55611. +* bankNum - Bank number.
  55612. +*
  55613. +* OUTPUT:
  55614. +* None.
  55615. +*
  55616. +* RETURN:
  55617. +* DRAM bank size. If bank is disabled the function return '0'. In case
  55618. +* or paramter is invalid, the function returns -1.
  55619. +*
  55620. +*******************************************************************************/
  55621. +MV_32 mvDramIfBankSizeGet(MV_U32 bankNum)
  55622. +{
  55623. + MV_DRAM_DEC_WIN addrDecWin;
  55624. +
  55625. + /* Check parameters */
  55626. + if (!MV_TARGET_IS_DRAM(bankNum))
  55627. + {
  55628. + mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
  55629. + return -1;
  55630. + }
  55631. + /* Get window parameters */
  55632. + if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
  55633. + {
  55634. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  55635. + return -1;
  55636. + }
  55637. +
  55638. + if (MV_TRUE == addrDecWin.enable)
  55639. + {
  55640. + return addrDecWin.addrWin.size;
  55641. + }
  55642. + else
  55643. + {
  55644. + return 0;
  55645. + }
  55646. +}
  55647. +
  55648. +
  55649. +/*******************************************************************************
  55650. +* mvDramIfSizeGet - Get DRAM interface total size.
  55651. +*
  55652. +* DESCRIPTION:
  55653. +* This function get the DRAM total size.
  55654. +*
  55655. +* INPUT:
  55656. +* None.
  55657. +*
  55658. +* OUTPUT:
  55659. +* None.
  55660. +*
  55661. +* RETURN:
  55662. +* DRAM total size. In case or paramter is invalid, the function
  55663. +* returns -1.
  55664. +*
  55665. +*******************************************************************************/
  55666. +MV_32 mvDramIfSizeGet(MV_VOID)
  55667. +{
  55668. + MV_U32 totalSize = 0, bankSize = 0, bankNum;
  55669. +
  55670. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  55671. + {
  55672. + bankSize = mvDramIfBankSizeGet(bankNum);
  55673. +
  55674. + if (-1 == bankSize)
  55675. + {
  55676. + mvOsPrintf("Dram: mvDramIfSizeGet error with bank %d \n",bankNum);
  55677. + return -1;
  55678. + }
  55679. + else
  55680. + {
  55681. + totalSize += bankSize;
  55682. + }
  55683. + }
  55684. +
  55685. + DB(mvOsPrintf("Dram: Total DRAM size is 0x%x \n",totalSize));
  55686. +
  55687. + return totalSize;
  55688. +}
  55689. +
  55690. +/*******************************************************************************
  55691. +* mvDramIfBankBaseGet - Get DRAM interface bank base.
  55692. +*
  55693. +* DESCRIPTION:
  55694. +* This function returns the 32 bit base address of a given DRAM bank.
  55695. +*
  55696. +* INPUT:
  55697. +* bankNum - Bank number.
  55698. +*
  55699. +* OUTPUT:
  55700. +* None.
  55701. +*
  55702. +* RETURN:
  55703. +* DRAM bank size. If bank is disabled or paramter is invalid, the
  55704. +* function returns -1.
  55705. +*
  55706. +*******************************************************************************/
  55707. +MV_32 mvDramIfBankBaseGet(MV_U32 bankNum)
  55708. +{
  55709. + MV_DRAM_DEC_WIN addrDecWin;
  55710. +
  55711. + /* Check parameters */
  55712. + if (!MV_TARGET_IS_DRAM(bankNum))
  55713. + {
  55714. + mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
  55715. + return -1;
  55716. + }
  55717. + /* Get window parameters */
  55718. + if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
  55719. + {
  55720. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  55721. + return -1;
  55722. + }
  55723. +
  55724. + if (MV_TRUE == addrDecWin.enable)
  55725. + {
  55726. + return addrDecWin.addrWin.baseLow;
  55727. + }
  55728. + else
  55729. + {
  55730. + return -1;
  55731. + }
  55732. +}
  55733. +
  55734. +
  55735. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h
  55736. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h 1970-01-01 01:00:00.000000000 +0100
  55737. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h 2010-11-09 20:28:10.692495407 +0100
  55738. @@ -0,0 +1,192 @@
  55739. +/*******************************************************************************
  55740. +Copyright (C) Marvell International Ltd. and its affiliates
  55741. +
  55742. +This software file (the "File") is owned and distributed by Marvell
  55743. +International Ltd. and/or its affiliates ("Marvell") under the following
  55744. +alternative licensing terms. Once you have made an election to distribute the
  55745. +File under one of the following license alternatives, please (i) delete this
  55746. +introductory statement regarding license alternatives, (ii) delete the two
  55747. +license alternatives that you have not elected to use and (iii) preserve the
  55748. +Marvell copyright notice above.
  55749. +
  55750. +********************************************************************************
  55751. +Marvell Commercial License Option
  55752. +
  55753. +If you received this File from Marvell and you have entered into a commercial
  55754. +license agreement (a "Commercial License") with Marvell, the File is licensed
  55755. +to you under the terms of the applicable Commercial License.
  55756. +
  55757. +********************************************************************************
  55758. +Marvell GPL License Option
  55759. +
  55760. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55761. +modify this File in accordance with the terms and conditions of the General
  55762. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  55763. +available along with the File in the license.txt file or by writing to the Free
  55764. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  55765. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  55766. +
  55767. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  55768. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  55769. +DISCLAIMED. The GPL License provides additional details about this warranty
  55770. +disclaimer.
  55771. +********************************************************************************
  55772. +Marvell BSD License Option
  55773. +
  55774. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55775. +modify this File under the following licensing terms.
  55776. +Redistribution and use in source and binary forms, with or without modification,
  55777. +are permitted provided that the following conditions are met:
  55778. +
  55779. + * Redistributions of source code must retain the above copyright notice,
  55780. + this list of conditions and the following disclaimer.
  55781. +
  55782. + * Redistributions in binary form must reproduce the above copyright
  55783. + notice, this list of conditions and the following disclaimer in the
  55784. + documentation and/or other materials provided with the distribution.
  55785. +
  55786. + * Neither the name of Marvell nor the names of its contributors may be
  55787. + used to endorse or promote products derived from this software without
  55788. + specific prior written permission.
  55789. +
  55790. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  55791. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  55792. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  55793. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  55794. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  55795. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  55796. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  55797. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  55798. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  55799. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  55800. +
  55801. +*******************************************************************************/
  55802. +
  55803. +
  55804. +#ifndef __INCmvDramIfConfigh
  55805. +#define __INCmvDramIfConfigh
  55806. +
  55807. +/* includes */
  55808. +
  55809. +/* defines */
  55810. +
  55811. +/* registers defaults values */
  55812. +
  55813. +#define SDRAM_CONFIG_DV \
  55814. + (SDRAM_PERR_WRITE | \
  55815. + SDRAM_SRMODE | \
  55816. + SDRAM_SRCLK_GATED)
  55817. +
  55818. +#define SDRAM_DUNIT_CTRL_LOW_DV \
  55819. + (SDRAM_CTRL_POS_RISE | \
  55820. + SDRAM_CLK1DRV_NORMAL | \
  55821. + SDRAM_LOCKEN_ENABLE)
  55822. +
  55823. +#define SDRAM_ADDR_CTRL_DV 0
  55824. +
  55825. +#define SDRAM_TIMING_CTRL_LOW_REG_DV \
  55826. + ((0x2 << SDRAM_TRCD_OFFS) | \
  55827. + (0x2 << SDRAM_TRP_OFFS) | \
  55828. + (0x1 << SDRAM_TWR_OFFS) | \
  55829. + (0x0 << SDRAM_TWTR_OFFS) | \
  55830. + (0x5 << SDRAM_TRAS_OFFS) | \
  55831. + (0x1 << SDRAM_TRRD_OFFS))
  55832. +/* TRFC 0x27, TW2W 0x1 */
  55833. +#define SDRAM_TIMING_CTRL_HIGH_REG_DV (( 0x7 << SDRAM_TRFC_OFFS ) |\
  55834. + ( 0x2 << SDRAM_TRFC_EXT_OFFS) |\
  55835. + ( 0x1 << SDRAM_TW2W_OFFS))
  55836. +
  55837. +#define SDRAM_OPEN_PAGES_CTRL_REG_DV SDRAM_OPEN_PAGE_EN
  55838. +
  55839. +/* DDR2 ODT default register values */
  55840. +
  55841. +/* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode */
  55842. +/* CS0 0x84210000 0x00000000 0x0000780F 0x00000440 */
  55843. +/* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440 */
  55844. +/* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  55845. +/* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  55846. +/* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  55847. +/* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  55848. +
  55849. +#define DDR2_ODT_CTRL_LOW_CS0_DV 0x84210000
  55850. +#define DDR2_ODT_CTRL_HIGH_CS0_DV 0x00000000
  55851. +#define DDR2_DUNIT_ODT_CTRL_CS0_DV 0x0000780F
  55852. +#define DDR_SDRAM_EXT_MODE_CS0_DV 0x00000440
  55853. +
  55854. +#define DDR2_ODT_CTRL_LOW_CS0_CS2_DV 0x030C030C
  55855. +#define DDR2_ODT_CTRL_HIGH_CS0_CS2_DV 0x00000000
  55856. +#define DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV 0x0000740F
  55857. +#define DDR_SDRAM_EXT_MODE_CS0_CS2_DV 0x00000404
  55858. +
  55859. +
  55860. +/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */
  55861. +#define DDR1_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
  55862. + (1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  55863. +#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
  55864. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  55865. +
  55866. +
  55867. +#define DDR1_DATA_PAD_STRENGTH_TYPICAL_DV \
  55868. + (1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  55869. +#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV \
  55870. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  55871. +
  55872. +/* DDR SDRAM Mode Register default value */
  55873. +#define DDR1_MODE_REG_DV 0x00000000
  55874. +#define DDR2_MODE_REG_DV 0x00000400
  55875. +
  55876. +/* DDR SDRAM Timing parameter default values */
  55877. +#define DDR1_TIMING_LOW_DV 0x11602220
  55878. +#define DDR1_TIMING_HIGH_DV 0x0000000d
  55879. +
  55880. +#define DDR2_TIMING_LOW_DV 0x11812220
  55881. +#define DDR2_TIMING_HIGH_DV 0x0000030f
  55882. +
  55883. +/* For Guideline (GL# MEM-4) DQS Reference Delay Tuning */
  55884. +#define FTDLL_DDR1_166MHZ ((0x1 << 0) | \
  55885. + (0x7F<< 12) | \
  55886. + (0x1 << 22))
  55887. +
  55888. +#define FTDLL_DDR1_133MHZ FTDLL_DDR1_166MHZ
  55889. +
  55890. +#define FTDLL_DDR1_200MHZ ((0x1 << 0) | \
  55891. + (0x1 << 12) | \
  55892. + (0x3 << 14) | \
  55893. + (0x1 << 18) | \
  55894. + (0x1 << 22))
  55895. +
  55896. +
  55897. +#define FTDLL_DDR2_166MHZ ((0x1 << 0) | \
  55898. + (0x1 << 12) | \
  55899. + (0x1 << 14) | \
  55900. + (0x1 << 16) | \
  55901. + (0x1 << 19) | \
  55902. + (0xF << 20))
  55903. +
  55904. +#define FTDLL_DDR2_133MHZ FTDLL_DDR2_166MHZ
  55905. +
  55906. +#define FTDLL_DDR2_200MHZ ((0x1 << 0) | \
  55907. + (0x1 << 12) | \
  55908. + (0x1 << 14) | \
  55909. + (0x1 << 16) | \
  55910. + (0x1 << 19) | \
  55911. + (0xF << 20))
  55912. +
  55913. +#define FTDLL_DDR2_250MHZ 0x445001
  55914. +
  55915. +/* Orion 1 B1 and above */
  55916. +#define FTDLL_DDR1_166MHZ_5181_B1 0x45D001
  55917. +
  55918. +/* Orion nas */
  55919. +#define FTDLL_DDR2_166MHZ_5182 0x597001
  55920. +
  55921. +/* Orion 2 D0 and above */
  55922. +#define FTDLL_DDR1_166MHZ_5281_D0 0x8D0001
  55923. +#define FTDLL_DDR1_200MHZ_5281_D0 0x8D0001
  55924. +#define FTDLL_DDR2_166MHZ_5281_D0 0x485001
  55925. +#define FTDLL_DDR2_200MHZ_5281_D0 0x485001
  55926. +#define FTDLL_DDR2_250MHZ_5281_D0 0x445001
  55927. +#define FTDLL_DDR2_200MHZ_5281_D1 0x995001
  55928. +#define FTDLL_DDR2_250MHZ_5281_D1 0x984801
  55929. +
  55930. +#endif /* __INCmvDramIfh */
  55931. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h
  55932. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h 1970-01-01 01:00:00.000000000 +0100
  55933. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h 2010-11-09 20:28:10.747105889 +0100
  55934. @@ -0,0 +1,179 @@
  55935. +/*******************************************************************************
  55936. +Copyright (C) Marvell International Ltd. and its affiliates
  55937. +
  55938. +This software file (the "File") is owned and distributed by Marvell
  55939. +International Ltd. and/or its affiliates ("Marvell") under the following
  55940. +alternative licensing terms. Once you have made an election to distribute the
  55941. +File under one of the following license alternatives, please (i) delete this
  55942. +introductory statement regarding license alternatives, (ii) delete the two
  55943. +license alternatives that you have not elected to use and (iii) preserve the
  55944. +Marvell copyright notice above.
  55945. +
  55946. +********************************************************************************
  55947. +Marvell Commercial License Option
  55948. +
  55949. +If you received this File from Marvell and you have entered into a commercial
  55950. +license agreement (a "Commercial License") with Marvell, the File is licensed
  55951. +to you under the terms of the applicable Commercial License.
  55952. +
  55953. +********************************************************************************
  55954. +Marvell GPL License Option
  55955. +
  55956. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55957. +modify this File in accordance with the terms and conditions of the General
  55958. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  55959. +available along with the File in the license.txt file or by writing to the Free
  55960. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  55961. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  55962. +
  55963. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  55964. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  55965. +DISCLAIMED. The GPL License provides additional details about this warranty
  55966. +disclaimer.
  55967. +********************************************************************************
  55968. +Marvell BSD License Option
  55969. +
  55970. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55971. +modify this File under the following licensing terms.
  55972. +Redistribution and use in source and binary forms, with or without modification,
  55973. +are permitted provided that the following conditions are met:
  55974. +
  55975. + * Redistributions of source code must retain the above copyright notice,
  55976. + this list of conditions and the following disclaimer.
  55977. +
  55978. + * Redistributions in binary form must reproduce the above copyright
  55979. + notice, this list of conditions and the following disclaimer in the
  55980. + documentation and/or other materials provided with the distribution.
  55981. +
  55982. + * Neither the name of Marvell nor the names of its contributors may be
  55983. + used to endorse or promote products derived from this software without
  55984. + specific prior written permission.
  55985. +
  55986. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  55987. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  55988. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  55989. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  55990. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  55991. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  55992. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  55993. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  55994. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  55995. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  55996. +
  55997. +*******************************************************************************/
  55998. +
  55999. +
  56000. +#ifndef __INCmvDramIfh
  56001. +#define __INCmvDramIfh
  56002. +
  56003. +/* includes */
  56004. +#include "ddr1_2/mvDramIfRegs.h"
  56005. +#include "ddr1_2/mvDramIfConfig.h"
  56006. +#include "ctrlEnv/mvCtrlEnvLib.h"
  56007. +
  56008. +/* defines */
  56009. +/* DRAM Timing parameters */
  56010. +#define SDRAM_TWR 15 /* ns tWr */
  56011. +#define SDRAM_TRFC_64_512M_AT_200MHZ 70 /* ns tRfc for dens 64-512 @ 200MHz */
  56012. +#define SDRAM_TRFC_64_512M 75 /* ns tRfc for dens 64-512 */
  56013. +#define SDRAM_TRFC_1G 120 /* ns tRfc for dens 1GB */
  56014. +#define SDRAM_TR2R_CYC 1 /* cycle for tR2r */
  56015. +#define SDRAM_TR2WW2R_CYC 1 /* cycle for tR2wW2r */
  56016. +
  56017. +/* typedefs */
  56018. +
  56019. +/* enumeration for memory types */
  56020. +typedef enum _mvMemoryType
  56021. +{
  56022. + MEM_TYPE_SDRAM,
  56023. + MEM_TYPE_DDR1,
  56024. + MEM_TYPE_DDR2
  56025. +}MV_MEMORY_TYPE;
  56026. +
  56027. +/* enumeration for DDR1 supported CAS Latencies */
  56028. +typedef enum _mvDimmDdr1Cas
  56029. +{
  56030. + DDR1_CL_1_5 = 0x02,
  56031. + DDR1_CL_2 = 0x04,
  56032. + DDR1_CL_2_5 = 0x08,
  56033. + DDR1_CL_3 = 0x10,
  56034. + DDR1_CL_4 = 0x40,
  56035. + DDR1_CL_FAULT
  56036. +} MV_DIMM_DDR1_CAS;
  56037. +
  56038. +/* enumeration for DDR2 supported CAS Latencies */
  56039. +typedef enum _mvDimmDdr2Cas
  56040. +{
  56041. + DDR2_CL_3 = 0x08,
  56042. + DDR2_CL_4 = 0x10,
  56043. + DDR2_CL_5 = 0x20,
  56044. + DDR2_CL_FAULT
  56045. +} MV_DIMM_DDR2_CAS;
  56046. +
  56047. +
  56048. +typedef struct _mvDramBankInfo
  56049. +{
  56050. + MV_MEMORY_TYPE memoryType; /* DDR1, DDR2 or SDRAM */
  56051. +
  56052. + /* DIMM dimensions */
  56053. + MV_U32 numOfRowAddr;
  56054. + MV_U32 numOfColAddr;
  56055. + MV_U32 dataWidth;
  56056. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  56057. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  56058. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  56059. + MV_U32 burstLengthSupported;
  56060. + MV_U32 numOfBanksOnEachDevice;
  56061. + MV_U32 suportedCasLatencies;
  56062. + MV_U32 refreshInterval;
  56063. +
  56064. + /* DIMM timing parameters */
  56065. + MV_U32 minCycleTimeAtMaxCasLatPs;
  56066. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  56067. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  56068. + MV_U32 minRowPrechargeTime;
  56069. + MV_U32 minRowActiveToRowActive;
  56070. + MV_U32 minRasToCasDelay;
  56071. + MV_U32 minRasPulseWidth;
  56072. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  56073. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  56074. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  56075. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  56076. +
  56077. + /* Parameters calculated from the extracted DIMM information */
  56078. + MV_U32 size;
  56079. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit */
  56080. + MV_U32 numberOfDevices;
  56081. +
  56082. + /* DIMM attributes (MV_TRUE for yes) */
  56083. + MV_BOOL registeredAddrAndControlInputs;
  56084. +
  56085. +}MV_DRAM_BANK_INFO;
  56086. +
  56087. +/* This structure describes CPU interface address decode window */
  56088. +typedef struct _mvDramIfDecWin
  56089. +{
  56090. + MV_ADDR_WIN addrWin; /* An address window*/
  56091. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  56092. +}MV_DRAM_DEC_WIN;
  56093. +
  56094. +#include "ddr1_2/mvDram.h"
  56095. +
  56096. +/* mvDramIf.h API list */
  56097. +MV_VOID mvDramIfBasicAsmInit(MV_VOID);
  56098. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl);
  56099. +MV_VOID _mvDramIfConfig(MV_VOID);
  56100. +
  56101. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  56102. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  56103. +MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable);
  56104. +MV_32 mvDramIfBankSizeGet(MV_U32 bankNum);
  56105. +MV_32 mvDramIfBankBaseGet(MV_U32 bankNum);
  56106. +MV_32 mvDramIfSizeGet(MV_VOID);
  56107. +
  56108. +#if 0
  56109. +MV_STATUS mvDramIfMbusCtrlSet(MV_XBAR_TARGET *pPizzaArbArray);
  56110. +MV_STATUS mvDramIfMbusToutSet(MV_U32 timeout, MV_BOOL enable);
  56111. +#endif
  56112. +
  56113. +#endif /* __INCmvDramIfh */
  56114. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h
  56115. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  56116. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h 2010-11-09 20:28:10.772495655 +0100
  56117. @@ -0,0 +1,306 @@
  56118. +/*******************************************************************************
  56119. +Copyright (C) Marvell International Ltd. and its affiliates
  56120. +
  56121. +This software file (the "File") is owned and distributed by Marvell
  56122. +International Ltd. and/or its affiliates ("Marvell") under the following
  56123. +alternative licensing terms. Once you have made an election to distribute the
  56124. +File under one of the following license alternatives, please (i) delete this
  56125. +introductory statement regarding license alternatives, (ii) delete the two
  56126. +license alternatives that you have not elected to use and (iii) preserve the
  56127. +Marvell copyright notice above.
  56128. +
  56129. +********************************************************************************
  56130. +Marvell Commercial License Option
  56131. +
  56132. +If you received this File from Marvell and you have entered into a commercial
  56133. +license agreement (a "Commercial License") with Marvell, the File is licensed
  56134. +to you under the terms of the applicable Commercial License.
  56135. +
  56136. +********************************************************************************
  56137. +Marvell GPL License Option
  56138. +
  56139. +If you received this File from Marvell, you may opt to use, redistribute and/or
  56140. +modify this File in accordance with the terms and conditions of the General
  56141. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  56142. +available along with the File in the license.txt file or by writing to the Free
  56143. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  56144. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  56145. +
  56146. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  56147. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  56148. +DISCLAIMED. The GPL License provides additional details about this warranty
  56149. +disclaimer.
  56150. +********************************************************************************
  56151. +Marvell BSD License Option
  56152. +
  56153. +If you received this File from Marvell, you may opt to use, redistribute and/or
  56154. +modify this File under the following licensing terms.
  56155. +Redistribution and use in source and binary forms, with or without modification,
  56156. +are permitted provided that the following conditions are met:
  56157. +
  56158. + * Redistributions of source code must retain the above copyright notice,
  56159. + this list of conditions and the following disclaimer.
  56160. +
  56161. + * Redistributions in binary form must reproduce the above copyright
  56162. + notice, this list of conditions and the following disclaimer in the
  56163. + documentation and/or other materials provided with the distribution.
  56164. +
  56165. + * Neither the name of Marvell nor the names of its contributors may be
  56166. + used to endorse or promote products derived from this software without
  56167. + specific prior written permission.
  56168. +
  56169. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  56170. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  56171. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  56172. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  56173. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  56174. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  56175. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  56176. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  56177. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  56178. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  56179. +
  56180. +*******************************************************************************/
  56181. +
  56182. +#ifndef __INCmvDramIfRegsh
  56183. +#define __INCmvDramIfRegsh
  56184. +
  56185. +
  56186. +/* DDR SDRAM Controller Address Decode Registers */
  56187. +/* SDRAM CSn Base Address Register (SCBAR) */
  56188. +#define SDRAM_BASE_ADDR_REG(csNum) (0x1500 + (csNum * 8))
  56189. +#define SCBAR_BASE_OFFS 16
  56190. +#define SCBAR_BASE_MASK (0xffff << SCBAR_BASE_OFFS)
  56191. +#define SCBAR_BASE_ALIGNMENT 0x10000
  56192. +
  56193. +/* SDRAM CSn Size Register (SCSR) */
  56194. +#define SDRAM_SIZE_REG(csNum) (0x1504 + (csNum * 8))
  56195. +#define SCSR_WIN_EN BIT0
  56196. +#define SCSR_SIZE_OFFS 16
  56197. +#define SCSR_SIZE_MASK (0xffff << SCSR_SIZE_OFFS)
  56198. +#define SCSR_SIZE_ALIGNMENT 0x10000
  56199. +
  56200. +/* configuration register */
  56201. +#define SDRAM_CONFIG_REG 0x1400
  56202. +#define SDRAM_REFRESH_OFFS 0
  56203. +#define SDRAM_REFRESH_MAX 0x3000
  56204. +#define SDRAM_REFRESH_MASK (SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)
  56205. +#define SDRAM_DWIDTH_OFFS 14
  56206. +#define SDRAM_DWIDTH_MASK (3 << SDRAM_DWIDTH_OFFS)
  56207. +#define SDRAM_DWIDTH_16BIT (1 << SDRAM_DWIDTH_OFFS)
  56208. +#define SDRAM_DWIDTH_32BIT (2 << SDRAM_DWIDTH_OFFS)
  56209. +#define SDRAM_DTYPE_OFFS 16
  56210. +#define SDRAM_DTYPE_MASK (1 << SDRAM_DTYPE_OFFS)
  56211. +#define SDRAM_DTYPE_DDR1 (0 << SDRAM_DTYPE_OFFS)
  56212. +#define SDRAM_DTYPE_DDR2 (1 << SDRAM_DTYPE_OFFS)
  56213. +#define SDRAM_REGISTERED (1 << 17)
  56214. +#define SDRAM_PERR_OFFS 18
  56215. +#define SDRAM_PERR_MASK (1 << SDRAM_PERR_OFFS)
  56216. +#define SDRAM_PERR_NO_WRITE (0 << SDRAM_PERR_OFFS)
  56217. +#define SDRAM_PERR_WRITE (1 << SDRAM_PERR_OFFS)
  56218. +#define SDRAM_DCFG_OFFS 20
  56219. +#define SDRAM_DCFG_MASK (0x3 << SDRAM_DCFG_OFFS)
  56220. +#define SDRAM_DCFG_X16_DEV (1 << SDRAM_DCFG_OFFS)
  56221. +#define SDRAM_DCFG_X8_DEV (2 << SDRAM_DCFG_OFFS)
  56222. +#define SDRAM_SRMODE (1 << 24)
  56223. +#define SDRAM_SRCLK_OFFS 25
  56224. +#define SDRAM_SRCLK_MASK (1 << SDRAM_SRCLK_OFFS)
  56225. +#define SDRAM_SRCLK_KEPT (0 << SDRAM_SRCLK_OFFS)
  56226. +#define SDRAM_SRCLK_GATED (1 << SDRAM_SRCLK_OFFS)
  56227. +#define SDRAM_CATTH_OFFS 26
  56228. +#define SDRAM_CATTHR_EN (1 << SDRAM_CATTH_OFFS)
  56229. +
  56230. +
  56231. +/* dunit control register */
  56232. +#define SDRAM_DUNIT_CTRL_REG 0x1404
  56233. +#define SDRAM_CTRL_POS_OFFS 6
  56234. +#define SDRAM_CTRL_POS_FALL (0 << SDRAM_CTRL_POS_OFFS)
  56235. +#define SDRAM_CTRL_POS_RISE (1 << SDRAM_CTRL_POS_OFFS)
  56236. +#define SDRAM_CLK1DRV_OFFS 12
  56237. +#define SDRAM_CLK1DRV_MASK (1 << SDRAM_CLK1DRV_OFFS)
  56238. +#define SDRAM_CLK1DRV_HIGH_Z (0 << SDRAM_CLK1DRV_OFFS)
  56239. +#define SDRAM_CLK1DRV_NORMAL (1 << SDRAM_CLK1DRV_OFFS)
  56240. +#define SDRAM_LOCKEN_OFFS 18
  56241. +#define SDRAM_LOCKEN_MASK (1 << SDRAM_LOCKEN_OFFS)
  56242. +#define SDRAM_LOCKEN_DISABLE (0 << SDRAM_LOCKEN_OFFS)
  56243. +#define SDRAM_LOCKEN_ENABLE (1 << SDRAM_LOCKEN_OFFS)
  56244. +#define SDRAM_ST_BURST_DEL_OFFS 24
  56245. +#define SDRAM_ST_BURST_DEL_MAX 0xf
  56246. +#define SDRAM_ST_BURST_DEL_MASK (SDRAM_ST_BURST_DEL_MAX<<SDRAM_ST_BURST_DEL_OFFS)
  56247. +
  56248. +/* sdram timing control low register */
  56249. +#define SDRAM_TIMING_CTRL_LOW_REG 0x1408
  56250. +#define SDRAM_TRCD_OFFS 4
  56251. +#define SDRAM_TRCD_MASK (0xF << SDRAM_TRCD_OFFS)
  56252. +#define SDRAM_TRP_OFFS 8
  56253. +#define SDRAM_TRP_MASK (0xF << SDRAM_TRP_OFFS)
  56254. +#define SDRAM_TWR_OFFS 12
  56255. +#define SDRAM_TWR_MASK (0xF << SDRAM_TWR_OFFS)
  56256. +#define SDRAM_TWTR_OFFS 16
  56257. +#define SDRAM_TWTR_MASK (0xF << SDRAM_TWTR_OFFS)
  56258. +#define SDRAM_TRAS_OFFS 20
  56259. +#define SDRAM_TRAS_MASK (0xF << SDRAM_TRAS_OFFS)
  56260. +#define SDRAM_TRRD_OFFS 24
  56261. +#define SDRAM_TRRD_MASK (0xF << SDRAM_TRRD_OFFS)
  56262. +#define SDRAM_TRTP_OFFS 28
  56263. +#define SDRAM_TRTP_MASK (0xF << SDRAM_TRTP_OFFS)
  56264. +
  56265. +/* sdram timing control high register */
  56266. +#define SDRAM_TIMING_CTRL_HIGH_REG 0x140c
  56267. +#define SDRAM_TRFC_OFFS 0
  56268. +#define SDRAM_TRFC_MASK (0xF << SDRAM_TRFC_OFFS)
  56269. +#define SDRAM_TR2R_OFFS 4
  56270. +#define SDRAM_TR2R_MASK (0x3 << SDRAM_TR2R_OFFS)
  56271. +#define SDRAM_TR2W_W2R_OFFS 6
  56272. +#define SDRAM_TR2W_W2R_MASK (0x3 << SDRAM_TR2W_W2R_OFFS)
  56273. +#define SDRAM_TRFC_EXT_OFFS 8
  56274. +#define SDRAM_TRFC_EXT_MASK (0x1 << SDRAM_TRFC_EXT_OFFS)
  56275. +#define SDRAM_TW2W_OFFS 10
  56276. +#define SDRAM_TW2W_MASK (0x1 << SDRAM_TW2W_OFFS)
  56277. +
  56278. +/* address control register */
  56279. +#define SDRAM_ADDR_CTRL_REG 0x1410
  56280. +#define SDRAM_DSIZE_OFFS 4
  56281. +#define SDRAM_DSIZE_MASK (0x3 << SDRAM_DSIZE_OFFS)
  56282. +#define SDRAM_DSIZE_128Mb (0x0 << SDRAM_DSIZE_OFFS)
  56283. +#define SDRAM_DSIZE_256Mb (0x1 << SDRAM_DSIZE_OFFS)
  56284. +#define SDRAM_DSIZE_512Mb (0x2 << SDRAM_DSIZE_OFFS)
  56285. +
  56286. +/* SDRAM Open Pages Control registers */
  56287. +#define SDRAM_OPEN_PAGE_CTRL_REG 0x1414
  56288. +#define SDRAM_OPEN_PAGE_EN (0 << 0)
  56289. +#define SDRAM_OPEN_PAGE_DIS (1 << 0)
  56290. +
  56291. +/* sdram opertion register */
  56292. +#define SDRAM_OPERATION_REG 0x1418
  56293. +#define SDRAM_CMD_OFFS 0
  56294. +#define SDRAM_CMD_MASK (0x7 << SDRAM_CMD_OFFS)
  56295. +#define SDRAM_CMD_NORMAL (0x0 << SDRAM_CMD_OFFS)
  56296. +#define SDRAM_CMD_PRECHARGE_ALL (0x1 << SDRAM_CMD_OFFS)
  56297. +#define SDRAM_CMD_REFRESH_ALL (0x2 << SDRAM_CMD_OFFS)
  56298. +#define SDRAM_CMD_REG_SET_CMD (0x3 << SDRAM_CMD_OFFS)
  56299. +#define SDRAM_CMD_EXT_MODE_SET (0x4 << SDRAM_CMD_OFFS)
  56300. +#define SDRAM_CMD_NOP (0x5 << SDRAM_CMD_OFFS)
  56301. +#define SDRAM_CMD_SLF_RFRSH (0x7 << SDRAM_CMD_OFFS)
  56302. +#define SDRAM_CMD_EMRS2_CMD (0x8 << SDRAM_CMD_OFFS)
  56303. +#define SDRAM_CMD_EMRS3_CMD (0x9 << SDRAM_CMD_OFFS)
  56304. +
  56305. +/* sdram mode register */
  56306. +#define SDRAM_MODE_REG 0x141c
  56307. +#define SDRAM_BURST_LEN_OFFS 0
  56308. +#define SDRAM_BURST_LEN_MASK (0x7 << SDRAM_BURST_LEN_OFFS)
  56309. +#define SDRAM_BURST_LEN_4 (0x2 << SDRAM_BURST_LEN_OFFS)
  56310. +#define SDRAM_CL_OFFS 4
  56311. +#define SDRAM_CL_MASK (0x7 << SDRAM_CL_OFFS)
  56312. +#define SDRAM_DDR1_CL_2 (0x2 << SDRAM_CL_OFFS)
  56313. +#define SDRAM_DDR1_CL_3 (0x3 << SDRAM_CL_OFFS)
  56314. +#define SDRAM_DDR1_CL_4 (0x4 << SDRAM_CL_OFFS)
  56315. +#define SDRAM_DDR1_CL_1_5 (0x5 << SDRAM_CL_OFFS)
  56316. +#define SDRAM_DDR1_CL_2_5 (0x6 << SDRAM_CL_OFFS)
  56317. +#define SDRAM_DDR2_CL_3 (0x3 << SDRAM_CL_OFFS)
  56318. +#define SDRAM_DDR2_CL_4 (0x4 << SDRAM_CL_OFFS)
  56319. +#define SDRAM_DDR2_CL_5 (0x5 << SDRAM_CL_OFFS)
  56320. +#define SDRAM_TM_OFFS 7
  56321. +#define SDRAM_TM_MASK (1 << SDRAM_TM_OFFS)
  56322. +#define SDRAM_TM_NORMAL (0 << SDRAM_TM_OFFS)
  56323. +#define SDRAM_TM_TEST_MODE (1 << SDRAM_TM_OFFS)
  56324. +#define SDRAM_DLL_OFFS 8
  56325. +#define SDRAM_DLL_MASK (1 << SDRAM_DLL_OFFS)
  56326. +#define SDRAM_DLL_NORMAL (0 << SDRAM_DLL_OFFS)
  56327. +#define SDRAM_DLL_RESET (1 << SDRAM_DLL_OFFS)
  56328. +#define SDRAM_WR_OFFS 11
  56329. +#define SDRAM_WR_MAX 7
  56330. +#define SDRAM_WR_MASK (SDRAM_WR_MAX << SDRAM_WR_OFFS)
  56331. +#define SDRAM_PD_OFFS 12
  56332. +#define SDRAM_PD_MASK (1 << SDRAM_PD_OFFS)
  56333. +#define SDRAM_PD_FAST_EXIT (0 << SDRAM_PD_OFFS)
  56334. +#define SDRAM_PD_SLOW_EXIT (1 << SDRAM_PD_OFFS)
  56335. +
  56336. +/* DDR SDRAM Extended Mode register (DSEMR) */
  56337. +#define SDRAM_EXTENDED_MODE_REG 0x1420
  56338. +#define DSEMR_DLL_ENABLE (1 << 0)
  56339. +#define DSEMR_DS_OFFS 1
  56340. +#define DSEMR_DS_MASK (1 << DSEMR_DS_OFFS)
  56341. +#define DSEMR_DS_NORMAL (0 << DSEMR_DS_OFFS)
  56342. +#define DSEMR_DS_REDUCED (1 << DSEMR_DS_OFFS)
  56343. +#define DSEMR_RTT0_OFFS 2
  56344. +#define DSEMR_RTT1_OFFS 6
  56345. +#define DSEMR_RTT_ODT_DISABLE ((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  56346. +#define DSEMR_RTT_ODT_75_OHM ((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  56347. +#define DSEMR_RTT_ODT_150_OHM ((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
  56348. +#define DSEMR_OCD_OFFS 7
  56349. +#define DSEMR_OCD_MASK (0x7 << DSEMR_OCD_OFFS)
  56350. +#define DSEMR_OCD_EXIT_CALIB (0 << DSEMR_OCD_OFFS)
  56351. +#define DSEMR_OCD_DRIVE1 (1 << DSEMR_OCD_OFFS)
  56352. +#define DSEMR_OCD_DRIVE0 (2 << DSEMR_OCD_OFFS)
  56353. +#define DSEMR_OCD_ADJUST_MODE (4 << DSEMR_OCD_OFFS)
  56354. +#define DSEMR_OCD_CALIB_DEFAULT (7 << DSEMR_OCD_OFFS)
  56355. +#define DSEMR_DQS_OFFS 10
  56356. +#define DSEMR_DQS_MASK (1 << DSEMR_DQS_OFFS)
  56357. +#define DSEMR_DQS_DIFFERENTIAL (0 << DSEMR_DQS_OFFS)
  56358. +#define DSEMR_DQS_SINGLE_ENDED (0 << DSEMR_DQS_OFFS)
  56359. +#define DSEMR_RDQS_ENABLE (1 << 11)
  56360. +#define DSEMR_QOFF_OUTPUT_BUFF_EN (1 << 12)
  56361. +
  56362. +/* DDR SDRAM Operation Control Register */
  56363. +#define SDRAM_OPERATION_CTRL_REG 0x142c
  56364. +
  56365. +/* Dunit FTDLL Configuration Register */
  56366. +#define SDRAM_FTDLL_CONFIG_REG 0x1484
  56367. +
  56368. +/* Pads Calibration register */
  56369. +#define SDRAM_ADDR_CTRL_PADS_CAL_REG 0x14c0
  56370. +#define SDRAM_DATA_PADS_CAL_REG 0x14c4
  56371. +#define SDRAM_DRVN_OFFS 0
  56372. +#define SDRAM_DRVN_MASK (0x3F << SDRAM_DRVN_OFFS)
  56373. +#define SDRAM_DRVP_OFFS 6
  56374. +#define SDRAM_DRVP_MASK (0x3F << SDRAM_DRVP_OFFS)
  56375. +#define SDRAM_PRE_DRIVER_STRENGTH_OFFS 12
  56376. +#define SDRAM_PRE_DRIVER_STRENGTH_MASK (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  56377. +#define SDRAM_TUNE_EN BIT16
  56378. +#define SDRAM_LOCK_OFFS 17
  56379. +#define SDRAM_LOCK_MAKS (0x1F << SDRAM_LOCK_OFFS)
  56380. +#define SDRAM_LOCKN_OFFS 17
  56381. +#define SDRAM_LOCKN_MAKS (0x3F << SDRAM_LOCKN_OFFS)
  56382. +#define SDRAM_LOCKP_OFFS 23
  56383. +#define SDRAM_LOCKP_MAKS (0x3F << SDRAM_LOCKP_OFFS)
  56384. +#define SDRAM_WR_EN (1 << 31)
  56385. +
  56386. +/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */
  56387. +#define DDR2_SDRAM_ODT_CTRL_LOW_REG 0x1494
  56388. +#define DSOCLR_ODT_RD_OFFS(odtNum) (odtNum * 4)
  56389. +#define DSOCLR_ODT_RD_MASK(odtNum) (0xf << DSOCLR_ODT_RD_OFFS(odtNum))
  56390. +#define DSOCLR_ODT_RD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))
  56391. +#define DSOCLR_ODT_WR_OFFS(odtNum) (16 + (odtNum * 4))
  56392. +#define DSOCLR_ODT_WR_MASK(odtNum) (0xf << DSOCLR_ODT_WR_OFFS(odtNum))
  56393. +#define DSOCLR_ODT_WD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))
  56394. +
  56395. +/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */
  56396. +#define DDR2_SDRAM_ODT_CTRL_HIGH_REG 0x1498
  56397. +/* Optional control values to DSOCHR_ODT_EN macro */
  56398. +#define DDR2_ODT_CTRL_DUNIT 0
  56399. +#define DDR2_ODT_CTRL_NEVER 1
  56400. +#define DDR2_ODT_CTRL_ALWAYS 3
  56401. +#define DSOCHR_ODT_EN_OFFS(odtNum) (odtNum * 2)
  56402. +#define DSOCHR_ODT_EN_MASK(odtNum) (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))
  56403. +#define DSOCHR_ODT_EN(odtNum, ctrl) ((1 << ctrl) << DSOCHR_ODT_RD_OFFS(odtNum))
  56404. +
  56405. +/* DDR2 Dunit ODT Control Register (DDOCR)*/
  56406. +#define DDR2_DUNIT_ODT_CONTROL_REG 0x149c
  56407. +#define DDOCR_ODT_RD_OFFS 0
  56408. +#define DDOCR_ODT_RD_MASK (0xf << DDOCR_ODT_RD_OFFS)
  56409. +#define DDOCR_ODT_RD(bank) ((1 << bank) << DDOCR_ODT_RD_OFFS)
  56410. +#define DDOCR_ODT_WR_OFFS 4
  56411. +#define DDOCR_ODT_WR_MASK (0xf << DDOCR_ODT_WR_OFFS)
  56412. +#define DDOCR_ODT_WR(bank) ((1 << bank) << DDOCR_ODT_WR_OFFS)
  56413. +#define DSOCR_ODT_EN_OFFS 8
  56414. +#define DSOCR_ODT_EN_MASK (0x3 << DSOCR_ODT_EN_OFFS)
  56415. +#define DSOCR_ODT_EN(ctrl) ((1 << ctrl) << DSOCR_ODT_EN_OFFS)
  56416. +#define DSOCR_ODT_SEL_OFFS 10
  56417. +#define DSOCR_ODT_SEL_MASK (0x3 << DSOCR_ODT_SEL_OFFS)
  56418. +
  56419. +/* DDR SDRAM Initialization Control Register (DSICR) */
  56420. +#define DDR_SDRAM_INIT_CTRL_REG 0x1480
  56421. +#define DSICR_INIT_EN (1 << 0)
  56422. +
  56423. +#endif /* __INCmvDramIfRegsh */
  56424. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c
  56425. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c 1970-01-01 01:00:00.000000000 +0100
  56426. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c 2010-11-09 20:28:10.812495401 +0100
  56427. @@ -0,0 +1,1855 @@
  56428. +/*******************************************************************************
  56429. +Copyright (C) Marvell International Ltd. and its affiliates
  56430. +
  56431. +This software file (the "File") is owned and distributed by Marvell
  56432. +International Ltd. and/or its affiliates ("Marvell") under the following
  56433. +alternative licensing terms. Once you have made an election to distribute the
  56434. +File under one of the following license alternatives, please (i) delete this
  56435. +introductory statement regarding license alternatives, (ii) delete the two
  56436. +license alternatives that you have not elected to use and (iii) preserve the
  56437. +Marvell copyright notice above.
  56438. +
  56439. +********************************************************************************
  56440. +Marvell Commercial License Option
  56441. +
  56442. +If you received this File from Marvell and you have entered into a commercial
  56443. +license agreement (a "Commercial License") with Marvell, the File is licensed
  56444. +to you under the terms of the applicable Commercial License.
  56445. +
  56446. +********************************************************************************
  56447. +Marvell GPL License Option
  56448. +
  56449. +If you received this File from Marvell, you may opt to use, redistribute and/or
  56450. +modify this File in accordance with the terms and conditions of the General
  56451. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  56452. +available along with the File in the license.txt file or by writing to the Free
  56453. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  56454. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  56455. +
  56456. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  56457. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  56458. +DISCLAIMED. The GPL License provides additional details about this warranty
  56459. +disclaimer.
  56460. +********************************************************************************
  56461. +Marvell BSD License Option
  56462. +
  56463. +If you received this File from Marvell, you may opt to use, redistribute and/or
  56464. +modify this File under the following licensing terms.
  56465. +Redistribution and use in source and binary forms, with or without modification,
  56466. +are permitted provided that the following conditions are met:
  56467. +
  56468. + * Redistributions of source code must retain the above copyright notice,
  56469. + this list of conditions and the following disclaimer.
  56470. +
  56471. + * Redistributions in binary form must reproduce the above copyright
  56472. + notice, this list of conditions and the following disclaimer in the
  56473. + documentation and/or other materials provided with the distribution.
  56474. +
  56475. + * Neither the name of Marvell nor the names of its contributors may be
  56476. + used to endorse or promote products derived from this software without
  56477. + specific prior written permission.
  56478. +
  56479. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  56480. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  56481. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  56482. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  56483. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  56484. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  56485. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  56486. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  56487. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  56488. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  56489. +
  56490. +*******************************************************************************/
  56491. +
  56492. +
  56493. +/* includes */
  56494. +#include "ddr2/mvDramIf.h"
  56495. +#include "ctrlEnv/sys/mvCpuIf.h"
  56496. +
  56497. +#include "ddr2/mvDramIfStaticInit.h"
  56498. +
  56499. +/* #define MV_DEBUG */
  56500. +#ifdef MV_DEBUG
  56501. +#define DB(x) x
  56502. +#else
  56503. +#define DB(x)
  56504. +#endif
  56505. +
  56506. +/* DRAM bank presence encoding */
  56507. +#define BANK_PRESENT_CS0 0x1
  56508. +#define BANK_PRESENT_CS0_CS1 0x3
  56509. +#define BANK_PRESENT_CS0_CS2 0x5
  56510. +#define BANK_PRESENT_CS0_CS1_CS2 0x7
  56511. +#define BANK_PRESENT_CS0_CS2_CS3 0xd
  56512. +#define BANK_PRESENT_CS0_CS2_CS3_CS4 0xf
  56513. +
  56514. +/* locals */
  56515. +#ifndef MV_STATIC_DRAM_ON_BOARD
  56516. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
  56517. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk, MV_STATUS TTmode );
  56518. +static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  56519. +static MV_U32 sdramModeRegCalc(MV_U32 minCas);
  56520. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  56521. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1);
  56522. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk);
  56523. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl);
  56524. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk);
  56525. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  56526. +static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas);
  56527. +static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas);
  56528. +#endif
  56529. +MV_32 DRAM_CS_Order[MV_DRAM_MAX_CS] = {N_A
  56530. +
  56531. +#ifdef MV_INCLUDE_SDRAM_CS1
  56532. + ,N_A
  56533. +#endif
  56534. +#ifdef MV_INCLUDE_SDRAM_CS2
  56535. + ,N_A
  56536. +#endif
  56537. +#ifdef MV_INCLUDE_SDRAM_CS3
  56538. + ,N_A
  56539. +#endif
  56540. + };
  56541. +/* Get DRAM size of CS num */
  56542. +MV_U32 mvDramCsSizeGet(MV_U32 csNum)
  56543. +{
  56544. + MV_DRAM_BANK_INFO bankInfo;
  56545. + MV_U32 size, deviceW, dimmW;
  56546. +#ifdef MV78XX0
  56547. + MV_U32 temp;
  56548. +#endif
  56549. +
  56550. + if(MV_OK == mvDramBankInfoGet(csNum, &bankInfo))
  56551. + {
  56552. + if (0 == bankInfo.size)
  56553. + return 0;
  56554. +
  56555. + /* Note that the Dimm width might be different then the device DRAM width */
  56556. +#ifdef MV78XX0
  56557. + temp = MV_REG_READ(SDRAM_CONFIG_REG);
  56558. + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
  56559. +#else
  56560. + deviceW = 16 /* KW family */;
  56561. +#endif
  56562. + dimmW = bankInfo.dataWidth - (bankInfo.dataWidth % 16);
  56563. + size = ((bankInfo.size << 20) / (dimmW/deviceW));
  56564. + return size;
  56565. + }
  56566. + else
  56567. + return 0;
  56568. +}
  56569. +/*******************************************************************************
  56570. +* mvDramIfDetect - Prepare DRAM interface configuration values.
  56571. +*
  56572. +* DESCRIPTION:
  56573. +* This function implements the full DRAM detection and timing
  56574. +* configuration for best system performance.
  56575. +* Since this routine runs from a ROM device (Boot Flash), its stack
  56576. +* resides on RAM, that might be the system DRAM. Changing DRAM
  56577. +* configuration values while keeping vital data in DRAM is risky. That
  56578. +* is why the function does not preform the configuration setting but
  56579. +* prepare those in predefined 32bit registers (in this case IDMA
  56580. +* registers are used) for other routine to perform the settings.
  56581. +* The function will call for board DRAM SPD information for each DRAM
  56582. +* chip select. The function will then analyze those SPD parameters of
  56583. +* all DRAM banks in order to decide on DRAM configuration compatible
  56584. +* for all DRAM banks.
  56585. +* The function will set the CPU DRAM address decode registers.
  56586. +* Note: This routine prepares values that will overide configuration of
  56587. +* mvDramBasicAsmInit().
  56588. +*
  56589. +* INPUT:
  56590. +* forcedCl - Forced CAL Latency. If equal to zero, do not force.
  56591. +* eccDisable - Force down the ECC.
  56592. +*
  56593. +* OUTPUT:
  56594. +* None.
  56595. +*
  56596. +* RETURN:
  56597. +* None.
  56598. +*
  56599. +*******************************************************************************/
  56600. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable)
  56601. +{
  56602. + MV_32 MV_DRAM_CS_order[MV_DRAM_MAX_CS] = {
  56603. + SDRAM_CS0
  56604. +#ifdef MV_INCLUDE_SDRAM_CS1
  56605. + ,SDRAM_CS1
  56606. +#endif
  56607. +#ifdef MV_INCLUDE_SDRAM_CS2
  56608. + ,SDRAM_CS2
  56609. +#endif
  56610. +#ifdef MV_INCLUDE_SDRAM_CS3
  56611. + ,SDRAM_CS3
  56612. +#endif
  56613. + };
  56614. + MV_U32 busClk, deviceW, dimmW;
  56615. + MV_U32 numOfAllDevices = 0;
  56616. + MV_STATUS TTMode;
  56617. +#ifndef MV_STATIC_DRAM_ON_BOARD
  56618. + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
  56619. + MV_U32 size, base = 0, i, j, temp, busClkPs;
  56620. + MV_U8 minCas;
  56621. + MV_CPU_DEC_WIN dramDecWin;
  56622. + dramDecWin.addrWin.baseHigh = 0;
  56623. +#endif
  56624. +
  56625. + busClk = mvBoardSysClkGet();
  56626. +
  56627. + if (0 == busClk)
  56628. + {
  56629. + mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
  56630. + return MV_ERROR;
  56631. + }
  56632. +
  56633. +#ifndef MV_STATIC_DRAM_ON_BOARD
  56634. +
  56635. + busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
  56636. + /* we will use bank 0 as the representative of the all the DRAM banks, */
  56637. + /* since bank 0 must exist. */
  56638. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  56639. + {
  56640. + /* if Bank exist */
  56641. + if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
  56642. + {
  56643. + DB(mvOsPrintf("Dram: Find bank %d\n", i));
  56644. + /* check it isn't SDRAM */
  56645. + if(bankInfo[i].memoryType != MEM_TYPE_DDR2)
  56646. + {
  56647. + mvOsOutput("Dram: ERR. SDRAM type not supported !!!\n");
  56648. + return MV_ERROR;
  56649. + }
  56650. +
  56651. + /* All banks must support the Mclk freqency */
  56652. + if(bankInfo[i].minCycleTimeAtMaxCasLatPs > busClkPs)
  56653. + {
  56654. + mvOsOutput("Dram: ERR. Bank %d doesn't support memory clock!!!\n", i);
  56655. + return MV_ERROR;
  56656. + }
  56657. +
  56658. + /* All banks must support registry in order to activate it */
  56659. + if(bankInfo[i].registeredAddrAndControlInputs !=
  56660. + bankInfo[0].registeredAddrAndControlInputs)
  56661. + {
  56662. + mvOsOutput("Dram: ERR. different Registered settings !!!\n");
  56663. + return MV_ERROR;
  56664. + }
  56665. +
  56666. + /* All banks must support same ECC mode */
  56667. + if(bankInfo[i].errorCheckType !=
  56668. + bankInfo[0].errorCheckType)
  56669. + {
  56670. + mvOsOutput("Dram: ERR. different ECC settings !!!\n");
  56671. + return MV_ERROR;
  56672. + }
  56673. +
  56674. + }
  56675. + else
  56676. + {
  56677. + if( i == 0 ) /* bank 0 doesn't exist */
  56678. + {
  56679. + mvOsOutput("Dram: ERR. Fail to detect bank 0 !!!\n");
  56680. + return MV_ERROR;
  56681. + }
  56682. + else
  56683. + {
  56684. + DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
  56685. + bankInfo[i].size = 0; /* Mark this bank as non exist */
  56686. + }
  56687. + }
  56688. + }
  56689. +
  56690. +#ifdef MV_INCLUDE_SDRAM_CS2
  56691. + if (bankInfo[SDRAM_CS0].size < bankInfo[SDRAM_CS2].size)
  56692. + {
  56693. + MV_DRAM_CS_order[0] = SDRAM_CS2;
  56694. + MV_DRAM_CS_order[1] = SDRAM_CS3;
  56695. + MV_DRAM_CS_order[2] = SDRAM_CS0;
  56696. + MV_DRAM_CS_order[3] = SDRAM_CS1;
  56697. + DRAM_CS_Order[0] = SDRAM_CS2;
  56698. + DRAM_CS_Order[1] = SDRAM_CS3;
  56699. + DRAM_CS_Order[2] = SDRAM_CS0;
  56700. + DRAM_CS_Order[3] = SDRAM_CS1;
  56701. +
  56702. + }
  56703. + else
  56704. +#endif
  56705. + {
  56706. + MV_DRAM_CS_order[0] = SDRAM_CS0;
  56707. + MV_DRAM_CS_order[1] = SDRAM_CS1;
  56708. + DRAM_CS_Order[0] = SDRAM_CS0;
  56709. + DRAM_CS_Order[1] = SDRAM_CS1;
  56710. +#ifdef MV_INCLUDE_SDRAM_CS2
  56711. + MV_DRAM_CS_order[2] = SDRAM_CS2;
  56712. + MV_DRAM_CS_order[3] = SDRAM_CS3;
  56713. + DRAM_CS_Order[2] = SDRAM_CS2;
  56714. + DRAM_CS_Order[3] = SDRAM_CS3;
  56715. +#endif
  56716. + }
  56717. +
  56718. + for(j = 0; j < MV_DRAM_MAX_CS; j++)
  56719. + {
  56720. + i = MV_DRAM_CS_order[j];
  56721. +
  56722. + if (0 == bankInfo[i].size)
  56723. + continue;
  56724. +
  56725. + /* Init the CPU window decode */
  56726. + /* Note that the Dimm width might be different then the device DRAM width */
  56727. +#ifdef MV78XX0
  56728. + temp = MV_REG_READ(SDRAM_CONFIG_REG);
  56729. + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
  56730. +#else
  56731. + deviceW = 16 /* KW family */;
  56732. +#endif
  56733. + dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
  56734. + size = ((bankInfo[i].size << 20) / (dimmW/deviceW));
  56735. +
  56736. + /* We can not change DRAM window settings while excecuting */
  56737. + /* code from it. That is why we skip the DRAM CS[0], saving */
  56738. + /* it to the ROM configuration routine */
  56739. +
  56740. + numOfAllDevices += bankInfo[i].numberOfDevices;
  56741. + if (i == MV_DRAM_CS_order[0])
  56742. + {
  56743. + MV_U32 sizeToReg;
  56744. + /* Translate the given window size to register format */
  56745. + sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
  56746. + /* Size parameter validity check. */
  56747. + if (-1 == sizeToReg)
  56748. + {
  56749. + mvOsOutput("DRAM: mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
  56750. + ,i);
  56751. + return MV_BAD_PARAM;
  56752. + }
  56753. +
  56754. + DB(mvOsPrintf("Dram: Bank 0 Size - %x\n",sizeToReg);)
  56755. + sizeToReg = (sizeToReg << SCSR_SIZE_OFFS);
  56756. + sizeToReg |= SCSR_WIN_EN;
  56757. + MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
  56758. + }
  56759. + else
  56760. + {
  56761. + dramDecWin.addrWin.baseLow = base;
  56762. + dramDecWin.addrWin.size = size;
  56763. + dramDecWin.enable = MV_TRUE;
  56764. + DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
  56765. +
  56766. + /* Check if the DRAM size is more then 3GByte */
  56767. + if (base < 0xC0000000)
  56768. + {
  56769. + DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
  56770. + if (MV_OK != mvCpuIfTargetWinSet(i, &dramDecWin))
  56771. + {
  56772. + mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n", SDRAM_CS0 + i);
  56773. + return MV_ERROR;
  56774. + }
  56775. + }
  56776. + }
  56777. +
  56778. + base += size;
  56779. +
  56780. + /* update the suportedCasLatencies mask */
  56781. + bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
  56782. + }
  56783. +
  56784. + /* calculate minimum CAS */
  56785. + minCas = minCasCalc(&bankInfo[0], &bankInfo[2], busClk, forcedCl);
  56786. + if (0 == minCas)
  56787. + {
  56788. + mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
  56789. + (busClk / 1000000));
  56790. +
  56791. + minCas = DDR2_CL_4; /* Continue with this CAS */
  56792. + mvOsOutput("Set default CAS latency 4\n");
  56793. + }
  56794. +
  56795. + /* calc SDRAM_CONFIG_REG and save it to temp register */
  56796. + temp = sdramConfigRegCalc(&bankInfo[0],&bankInfo[2], busClk);
  56797. + if(-1 == temp)
  56798. + {
  56799. + mvOsOutput("Dram: ERR. sdramConfigRegCalc failed !!!\n");
  56800. + return MV_ERROR;
  56801. + }
  56802. +
  56803. + /* check if ECC is enabled by the user */
  56804. + if(eccDisable)
  56805. + {
  56806. + /* turn off ECC*/
  56807. + temp &= ~BIT18;
  56808. + }
  56809. + DB(mvOsPrintf("Dram: sdramConfigRegCalc - %x\n",temp);)
  56810. + MV_REG_WRITE(DRAM_BUF_REG1, temp);
  56811. +
  56812. + /* calc SDRAM_MODE_REG and save it to temp register */
  56813. + temp = sdramModeRegCalc(minCas);
  56814. + if(-1 == temp)
  56815. + {
  56816. + mvOsOutput("Dram: ERR. sdramModeRegCalc failed !!!\n");
  56817. + return MV_ERROR;
  56818. + }
  56819. + DB(mvOsPrintf("Dram: sdramModeRegCalc - %x\n",temp);)
  56820. + MV_REG_WRITE(DRAM_BUF_REG2, temp);
  56821. +
  56822. + /* calc SDRAM_EXTENDED_MODE_REG and save it to temp register */
  56823. + temp = sdramExtModeRegCalc(&bankInfo[0], busClk);
  56824. + if(-1 == temp)
  56825. + {
  56826. + mvOsOutput("Dram: ERR. sdramExtModeRegCalc failed !!!\n");
  56827. + return MV_ERROR;
  56828. + }
  56829. + DB(mvOsPrintf("Dram: sdramExtModeRegCalc - %x\n",temp);)
  56830. + MV_REG_WRITE(DRAM_BUF_REG10, temp);
  56831. +
  56832. + /* calc D_UNIT_CONTROL_LOW and save it to temp register */
  56833. + TTMode = MV_FALSE;
  56834. + DB(mvOsPrintf("Dram: numOfAllDevices = %x\n",numOfAllDevices);)
  56835. + if( (numOfAllDevices > 9) && (bankInfo[0].registeredAddrAndControlInputs == MV_FALSE) )
  56836. + {
  56837. + if ( ( (numOfAllDevices > 9) && (busClk > MV_BOARD_SYSCLK_200MHZ) ) ||
  56838. + (numOfAllDevices > 18) )
  56839. + {
  56840. + mvOsOutput("Enable 2T ");
  56841. + TTMode = MV_TRUE;
  56842. + }
  56843. + }
  56844. +
  56845. + temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas, busClk, TTMode );
  56846. + if(-1 == temp)
  56847. + {
  56848. + mvOsOutput("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
  56849. + return MV_ERROR;
  56850. + }
  56851. + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc - %x\n",temp);)
  56852. + MV_REG_WRITE(DRAM_BUF_REG3, temp);
  56853. +
  56854. + /* calc D_UNIT_CONTROL_HIGH and save it to temp register */
  56855. + temp = dunitCtrlHighRegCalc(&bankInfo[0], busClk);
  56856. + if(-1 == temp)
  56857. + {
  56858. + mvOsOutput("Dram: ERR. dunitCtrlHighRegCalc failed !!!\n");
  56859. + return MV_ERROR;
  56860. + }
  56861. + DB(mvOsPrintf("Dram: dunitCtrlHighRegCalc - %x\n",temp);)
  56862. + /* check if ECC is enabled by the user */
  56863. + if(eccDisable)
  56864. + {
  56865. + /* turn off sample stage if no ecc */
  56866. + temp &= ~SDRAM__D2P_EN;;
  56867. + }
  56868. + MV_REG_WRITE(DRAM_BUF_REG13, temp);
  56869. +
  56870. + /* calc SDRAM_ADDR_CTRL_REG and save it to temp register */
  56871. + temp = sdramAddrCtrlRegCalc(&bankInfo[0],&bankInfo[2]);
  56872. + if(-1 == temp)
  56873. + {
  56874. + mvOsOutput("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
  56875. + return MV_ERROR;
  56876. + }
  56877. + DB(mvOsPrintf("Dram: sdramAddrCtrlRegCalc - %x\n",temp);)
  56878. + MV_REG_WRITE(DRAM_BUF_REG4, temp);
  56879. +
  56880. + /* calc SDRAM_TIMING_CTRL_LOW_REG and save it to temp register */
  56881. + temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
  56882. + if(-1 == temp)
  56883. + {
  56884. + mvOsOutput("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
  56885. + return MV_ERROR;
  56886. + }
  56887. + DB(mvOsPrintf("Dram: sdramTimeCtrlLowRegCalc - %x\n",temp);)
  56888. + MV_REG_WRITE(DRAM_BUF_REG5, temp);
  56889. +
  56890. + /* calc SDRAM_TIMING_CTRL_HIGH_REG and save it to temp register */
  56891. + temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
  56892. + if(-1 == temp)
  56893. + {
  56894. + mvOsOutput("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
  56895. + return MV_ERROR;
  56896. + }
  56897. + DB(mvOsPrintf("Dram: sdramTimeCtrlHighRegCalc - %x\n",temp);)
  56898. + MV_REG_WRITE(DRAM_BUF_REG6, temp);
  56899. +
  56900. + sdramDDr2OdtConfig(bankInfo);
  56901. +
  56902. + /* calc DDR2_SDRAM_TIMING_LOW_REG and save it to temp register */
  56903. + temp = sdramDdr2TimeLoRegCalc(minCas);
  56904. + if(-1 == temp)
  56905. + {
  56906. + mvOsOutput("Dram: ERR. sdramDdr2TimeLoRegCalc failed !!!\n");
  56907. + return MV_ERROR;
  56908. + }
  56909. + DB(mvOsPrintf("Dram: sdramDdr2TimeLoRegCalc - %x\n",temp);)
  56910. + MV_REG_WRITE(DRAM_BUF_REG11, temp);
  56911. +
  56912. + /* calc DDR2_SDRAM_TIMING_HIGH_REG and save it to temp register */
  56913. + temp = sdramDdr2TimeHiRegCalc(minCas);
  56914. + if(-1 == temp)
  56915. + {
  56916. + mvOsOutput("Dram: ERR. sdramDdr2TimeHiRegCalc failed !!!\n");
  56917. + return MV_ERROR;
  56918. + }
  56919. + DB(mvOsPrintf("Dram: sdramDdr2TimeHiRegCalc - %x\n",temp);)
  56920. + MV_REG_WRITE(DRAM_BUF_REG12, temp);
  56921. +#endif
  56922. +
  56923. + /* Note that DDR SDRAM Address/Control and Data pad calibration */
  56924. + /* settings is done in mvSdramIfConfig.s */
  56925. +
  56926. + return MV_OK;
  56927. +}
  56928. +
  56929. +
  56930. +/*******************************************************************************
  56931. +* mvDramIfBankBaseGet - Get DRAM interface bank base.
  56932. +*
  56933. +* DESCRIPTION:
  56934. +* This function returns the 32 bit base address of a given DRAM bank.
  56935. +*
  56936. +* INPUT:
  56937. +* bankNum - Bank number.
  56938. +*
  56939. +* OUTPUT:
  56940. +* None.
  56941. +*
  56942. +* RETURN:
  56943. +* DRAM bank size. If bank is disabled or paramter is invalid, the
  56944. +* function returns -1.
  56945. +*
  56946. +*******************************************************************************/
  56947. +MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum)
  56948. +{
  56949. + DB(mvOsPrintf("Dram: mvDramIfBankBaseGet Bank %d base addr is %x \n",
  56950. + bankNum, mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum)));
  56951. + return mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum);
  56952. +}
  56953. +
  56954. +/*******************************************************************************
  56955. +* mvDramIfBankSizeGet - Get DRAM interface bank size.
  56956. +*
  56957. +* DESCRIPTION:
  56958. +* This function returns the size of a given DRAM bank.
  56959. +*
  56960. +* INPUT:
  56961. +* bankNum - Bank number.
  56962. +*
  56963. +* OUTPUT:
  56964. +* None.
  56965. +*
  56966. +* RETURN:
  56967. +* DRAM bank size. If bank is disabled the function return '0'. In case
  56968. +* or paramter is invalid, the function returns -1.
  56969. +*
  56970. +*******************************************************************************/
  56971. +MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum)
  56972. +{
  56973. + DB(mvOsPrintf("Dram: mvDramIfBankSizeGet Bank %d size is %x \n",
  56974. + bankNum, mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum)));
  56975. + return mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum);
  56976. +}
  56977. +
  56978. +
  56979. +/*******************************************************************************
  56980. +* mvDramIfSizeGet - Get DRAM interface total size.
  56981. +*
  56982. +* DESCRIPTION:
  56983. +* This function get the DRAM total size.
  56984. +*
  56985. +* INPUT:
  56986. +* None.
  56987. +*
  56988. +* OUTPUT:
  56989. +* None.
  56990. +*
  56991. +* RETURN:
  56992. +* DRAM total size. In case or paramter is invalid, the function
  56993. +* returns -1.
  56994. +*
  56995. +*******************************************************************************/
  56996. +MV_U32 mvDramIfSizeGet(MV_VOID)
  56997. +{
  56998. + MV_U32 size = 0, i;
  56999. +
  57000. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  57001. + size += mvDramIfBankSizeGet(i);
  57002. +
  57003. + DB(mvOsPrintf("Dram: mvDramIfSizeGet size is %x \n",size));
  57004. + return size;
  57005. +}
  57006. +
  57007. +/*******************************************************************************
  57008. +* mvDramIfSingleBitErrThresholdSet - Set single bit ECC threshold.
  57009. +*
  57010. +* DESCRIPTION:
  57011. +* The ECC single bit error threshold is the number of single bit
  57012. +* errors to happen before the Dunit generates an interrupt.
  57013. +* This function set single bit ECC threshold.
  57014. +*
  57015. +* INPUT:
  57016. +* threshold - threshold.
  57017. +*
  57018. +* OUTPUT:
  57019. +* None.
  57020. +*
  57021. +* RETURN:
  57022. +* MV_BAD_PARAM if threshold is to big, MV_OK otherwise.
  57023. +*
  57024. +*******************************************************************************/
  57025. +MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold)
  57026. +{
  57027. + MV_U32 regVal;
  57028. +
  57029. + if (threshold > SECR_THRECC_MAX)
  57030. + {
  57031. + return MV_BAD_PARAM;
  57032. + }
  57033. +
  57034. + regVal = MV_REG_READ(SDRAM_ECC_CONTROL_REG);
  57035. + regVal &= ~SECR_THRECC_MASK;
  57036. + regVal |= ((SECR_THRECC(threshold) & SECR_THRECC_MASK));
  57037. + MV_REG_WRITE(SDRAM_ECC_CONTROL_REG, regVal);
  57038. +
  57039. + return MV_OK;
  57040. +}
  57041. +
  57042. +#ifndef MV_STATIC_DRAM_ON_BOARD
  57043. +/*******************************************************************************
  57044. +* minCasCalc - Calculate the Minimum CAS latency which can be used.
  57045. +*
  57046. +* DESCRIPTION:
  57047. +* Calculate the minimum CAS latency that can be used, base on the DRAM
  57048. +* parameters and the SDRAM bus Clock freq.
  57049. +*
  57050. +* INPUT:
  57051. +* busClk - the DRAM bus Clock.
  57052. +* pBankInfo - bank info parameters.
  57053. +* forcedCl - Forced CAS Latency multiplied by 10. If equal to zero, do not force.
  57054. +*
  57055. +* OUTPUT:
  57056. +* None
  57057. +*
  57058. +* RETURN:
  57059. +* The minimum CAS Latency. The function returns 0 if max CAS latency
  57060. +* supported by banks is incompatible with system bus clock frequancy.
  57061. +*
  57062. +*******************************************************************************/
  57063. +
  57064. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl)
  57065. +{
  57066. + MV_U32 count = 1, j;
  57067. + MV_U32 busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
  57068. + MV_U32 startBit, stopBit;
  57069. + MV_U32 minCas0 = 0, minCas2 = 0;
  57070. +
  57071. +
  57072. + /* DDR 2:
  57073. + *******-******-******-******-******-******-******-*******
  57074. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  57075. + *******-******-******-******-******-******-******-*******
  57076. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  57077. + Disco VI= * TBD | TBD | 5 | 4 | 3 | TBD | TBD | TBD *
  57078. + Disco Duo= * TBD | 6 | 5 | 4 | 3 | TBD | TBD | TBD *
  57079. + *********************************************************/
  57080. +
  57081. +
  57082. + /* If we are asked to use the forced CAL we change the suported CAL to be forcedCl only */
  57083. + if (forcedCl)
  57084. + {
  57085. + mvOsOutput("DRAM: Using forced CL %d.%d\n", (forcedCl / 10), (forcedCl % 10));
  57086. +
  57087. + if (forcedCl == 30)
  57088. + pBankInfo->suportedCasLatencies = 0x08;
  57089. + else if (forcedCl == 40)
  57090. + pBankInfo->suportedCasLatencies = 0x10;
  57091. + else if (forcedCl == 50)
  57092. + pBankInfo->suportedCasLatencies = 0x20;
  57093. + else if (forcedCl == 60)
  57094. + pBankInfo->suportedCasLatencies = 0x40;
  57095. + else
  57096. + {
  57097. + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n",
  57098. + (forcedCl / 10), (forcedCl % 10));
  57099. + pBankInfo->suportedCasLatencies = 0x10;
  57100. + }
  57101. +
  57102. + return pBankInfo->suportedCasLatencies;
  57103. + }
  57104. +
  57105. + /* go over the supported cas mask from Max Cas down and check if the */
  57106. + /* SysClk stands in its time requirments. */
  57107. +
  57108. + DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
  57109. + pBankInfo->suportedCasLatencies,busClkPs ));
  57110. + count = 1;
  57111. + for(j = 7; j > 0; j--)
  57112. + {
  57113. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  57114. + {
  57115. + /* Reset the bits for CL incompatible for the sysClk */
  57116. + switch (count)
  57117. + {
  57118. + case 1:
  57119. + if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs)
  57120. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  57121. + count++;
  57122. + break;
  57123. + case 2:
  57124. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
  57125. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  57126. + count++;
  57127. + break;
  57128. + case 3:
  57129. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
  57130. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  57131. + count++;
  57132. + break;
  57133. + default:
  57134. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  57135. + break;
  57136. + }
  57137. + }
  57138. + }
  57139. +
  57140. + DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
  57141. + pBankInfo->suportedCasLatencies ));
  57142. +
  57143. + count = 1;
  57144. + DB(mvOsPrintf("Dram2: minCasCalc supported mask = %x busClkPs = %x \n",
  57145. + pBankInfo2->suportedCasLatencies,busClkPs ));
  57146. + for(j = 7; j > 0; j--)
  57147. + {
  57148. + if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
  57149. + {
  57150. + /* Reset the bits for CL incompatible for the sysClk */
  57151. + switch (count)
  57152. + {
  57153. + case 1:
  57154. + if (pBankInfo2->minCycleTimeAtMaxCasLatPs > busClkPs)
  57155. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  57156. + count++;
  57157. + break;
  57158. + case 2:
  57159. + if (pBankInfo2->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
  57160. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  57161. + count++;
  57162. + break;
  57163. + case 3:
  57164. + if (pBankInfo2->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
  57165. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  57166. + count++;
  57167. + break;
  57168. + default:
  57169. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  57170. + break;
  57171. + }
  57172. + }
  57173. + }
  57174. +
  57175. + DB(mvOsPrintf("Dram2: minCasCalc support = %x (after SysCC calc)\n",
  57176. + pBankInfo2->suportedCasLatencies ));
  57177. +
  57178. + startBit = 3; /* DDR2 support CL start with CL3 (bit 3) */
  57179. + stopBit = 6; /* DDR2 support CL stops with CL6 (bit 6) */
  57180. +
  57181. + for(j = startBit; j <= stopBit ; j++)
  57182. + {
  57183. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  57184. + {
  57185. + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
  57186. + minCas0 = (BIT0 << j);
  57187. + break;
  57188. + }
  57189. + }
  57190. +
  57191. + for(j = startBit; j <= stopBit ; j++)
  57192. + {
  57193. + if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
  57194. + {
  57195. + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
  57196. + minCas2 = (BIT0 << j);
  57197. + break;
  57198. + }
  57199. + }
  57200. +
  57201. + if (minCas2 > minCas0)
  57202. + return minCas2;
  57203. + else
  57204. + return minCas0;
  57205. +
  57206. + return 0;
  57207. +}
  57208. +
  57209. +/*******************************************************************************
  57210. +* sdramConfigRegCalc - Calculate sdram config register
  57211. +*
  57212. +* DESCRIPTION: Calculate sdram config register optimized value based
  57213. +* on the bank info parameters.
  57214. +*
  57215. +* INPUT:
  57216. +* busClk - the DRAM bus Clock.
  57217. +* pBankInfo - sdram bank parameters
  57218. +*
  57219. +* OUTPUT:
  57220. +* None
  57221. +*
  57222. +* RETURN:
  57223. +* sdram config reg value.
  57224. +*
  57225. +*******************************************************************************/
  57226. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk)
  57227. +{
  57228. + MV_U32 sdramConfig = 0;
  57229. + MV_U32 refreshPeriod;
  57230. +
  57231. + busClk /= 1000000; /* we work with busClk in MHz */
  57232. +
  57233. + sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
  57234. +
  57235. + /* figure out the memory refresh internal */
  57236. + switch (pBankInfo->refreshInterval & 0xf)
  57237. + {
  57238. + case 0x0: /* refresh period is 15.625 usec */
  57239. + refreshPeriod = 15625;
  57240. + break;
  57241. + case 0x1: /* refresh period is 3.9 usec */
  57242. + refreshPeriod = 3900;
  57243. + break;
  57244. + case 0x2: /* refresh period is 7.8 usec */
  57245. + refreshPeriod = 7800;
  57246. + break;
  57247. + case 0x3: /* refresh period is 31.3 usec */
  57248. + refreshPeriod = 31300;
  57249. + break;
  57250. + case 0x4: /* refresh period is 62.5 usec */
  57251. + refreshPeriod = 62500;
  57252. + break;
  57253. + case 0x5: /* refresh period is 125 usec */
  57254. + refreshPeriod = 125000;
  57255. + break;
  57256. + default: /* refresh period undefined */
  57257. + mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
  57258. + return -1;
  57259. + }
  57260. +
  57261. + /* Now the refreshPeriod is in register format value */
  57262. + refreshPeriod = (busClk * refreshPeriod) / 1000;
  57263. +
  57264. + DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n",
  57265. + refreshPeriod));
  57266. +
  57267. + /* make sure the refresh value is only 14 bits */
  57268. + if(refreshPeriod > SDRAM_REFRESH_MAX)
  57269. + {
  57270. + refreshPeriod = SDRAM_REFRESH_MAX;
  57271. + DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n",
  57272. + refreshPeriod));
  57273. + }
  57274. +
  57275. + /* Clear the refresh field */
  57276. + sdramConfig &= ~SDRAM_REFRESH_MASK;
  57277. +
  57278. + /* Set new value to refresh field */
  57279. + sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
  57280. +
  57281. + /* registered DRAM ? */
  57282. + if ( pBankInfo->registeredAddrAndControlInputs )
  57283. + {
  57284. + /* it's registered DRAM, so set the reg. DRAM bit */
  57285. + sdramConfig |= SDRAM_REGISTERED;
  57286. + DB(mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");)
  57287. + }
  57288. +
  57289. + /* ECC and IERR support */
  57290. + sdramConfig &= ~SDRAM_ECC_MASK; /* Clear ECC field */
  57291. + sdramConfig &= ~SDRAM_IERR_MASK; /* Clear IErr field */
  57292. +
  57293. + if ( pBankInfo->errorCheckType )
  57294. + {
  57295. + sdramConfig |= SDRAM_ECC_EN;
  57296. + sdramConfig |= SDRAM_IERR_REPORTE;
  57297. + DB(mvOsPrintf("Dram: mvDramIfDetect Enabling ECC\n"));
  57298. + }
  57299. + else
  57300. + {
  57301. + sdramConfig |= SDRAM_ECC_DIS;
  57302. + sdramConfig |= SDRAM_IERR_IGNORE;
  57303. + DB(mvOsPrintf("Dram: mvDramIfDetect Disabling ECC!\n"));
  57304. + }
  57305. + /* Set static default settings */
  57306. + sdramConfig |= SDRAM_CONFIG_DV;
  57307. +
  57308. + DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
  57309. + sdramConfig));
  57310. +
  57311. + return sdramConfig;
  57312. +}
  57313. +
  57314. +/*******************************************************************************
  57315. +* sdramModeRegCalc - Calculate sdram mode register
  57316. +*
  57317. +* DESCRIPTION: Calculate sdram mode register optimized value based
  57318. +* on the bank info parameters and the minCas.
  57319. +*
  57320. +* INPUT:
  57321. +* minCas - minimum CAS supported.
  57322. +*
  57323. +* OUTPUT:
  57324. +* None
  57325. +*
  57326. +* RETURN:
  57327. +* sdram mode reg value.
  57328. +*
  57329. +*******************************************************************************/
  57330. +static MV_U32 sdramModeRegCalc(MV_U32 minCas)
  57331. +{
  57332. + MV_U32 sdramMode;
  57333. +
  57334. + sdramMode = MV_REG_READ(SDRAM_MODE_REG);
  57335. +
  57336. + /* Clear CAS Latency field */
  57337. + sdramMode &= ~SDRAM_CL_MASK;
  57338. +
  57339. + DB(mvOsPrintf("DRAM CAS Latency ");)
  57340. +
  57341. + switch (minCas)
  57342. + {
  57343. + case DDR2_CL_3:
  57344. + sdramMode |= SDRAM_DDR2_CL_3;
  57345. + DB(mvOsPrintf("3.\n");)
  57346. + break;
  57347. + case DDR2_CL_4:
  57348. + sdramMode |= SDRAM_DDR2_CL_4;
  57349. + DB(mvOsPrintf("4.\n");)
  57350. + break;
  57351. + case DDR2_CL_5:
  57352. + sdramMode |= SDRAM_DDR2_CL_5;
  57353. + DB(mvOsPrintf("5.\n");)
  57354. + break;
  57355. + case DDR2_CL_6:
  57356. + sdramMode |= SDRAM_DDR2_CL_6;
  57357. + DB(mvOsPrintf("6.\n");)
  57358. + break;
  57359. + default:
  57360. + mvOsOutput("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
  57361. + return -1;
  57362. + }
  57363. +
  57364. + DB(mvOsPrintf("\nsdramModeRegCalc register 0x%x\n", sdramMode ));
  57365. +
  57366. + return sdramMode;
  57367. +}
  57368. +/*******************************************************************************
  57369. +* sdramExtModeRegCalc - Calculate sdram Extended mode register
  57370. +*
  57371. +* DESCRIPTION:
  57372. +* Return sdram Extended mode register value based
  57373. +* on the bank info parameters and bank presence.
  57374. +*
  57375. +* INPUT:
  57376. +* pBankInfo - sdram bank parameters
  57377. +* busClk - DRAM frequency
  57378. +*
  57379. +* OUTPUT:
  57380. +* None
  57381. +*
  57382. +* RETURN:
  57383. +* sdram Extended mode reg value.
  57384. +*
  57385. +*******************************************************************************/
  57386. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  57387. +{
  57388. + MV_U32 populateBanks = 0;
  57389. + int bankNum;
  57390. +
  57391. + /* Represent the populate banks in binary form */
  57392. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  57393. + {
  57394. + if (0 != pBankInfo[bankNum].size)
  57395. + {
  57396. + populateBanks |= (1 << bankNum);
  57397. + }
  57398. + }
  57399. +
  57400. + switch(populateBanks)
  57401. + {
  57402. + case(BANK_PRESENT_CS0):
  57403. + case(BANK_PRESENT_CS0_CS1):
  57404. + return DDR_SDRAM_EXT_MODE_CS0_CS1_DV;
  57405. +
  57406. + case(BANK_PRESENT_CS0_CS2):
  57407. + case(BANK_PRESENT_CS0_CS1_CS2):
  57408. + case(BANK_PRESENT_CS0_CS2_CS3):
  57409. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  57410. + if (busClk >= MV_BOARD_SYSCLK_267MHZ)
  57411. + return DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV;
  57412. + else
  57413. + return DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV;
  57414. +
  57415. + default:
  57416. + mvOsOutput("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
  57417. + return -1;
  57418. + }
  57419. + return 0;
  57420. +}
  57421. +
  57422. +/*******************************************************************************
  57423. +* dunitCtrlLowRegCalc - Calculate sdram dunit control low register
  57424. +*
  57425. +* DESCRIPTION: Calculate sdram dunit control low register optimized value based
  57426. +* on the bank info parameters and the minCas.
  57427. +*
  57428. +* INPUT:
  57429. +* pBankInfo - sdram bank parameters
  57430. +* minCas - minimum CAS supported.
  57431. +*
  57432. +* OUTPUT:
  57433. +* None
  57434. +*
  57435. +* RETURN:
  57436. +* sdram dunit control low reg value.
  57437. +*
  57438. +*******************************************************************************/
  57439. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk, MV_STATUS TTMode)
  57440. +{
  57441. + MV_U32 dunitCtrlLow, cl;
  57442. + MV_U32 sbOutR[4]={3,5,7,9} ;
  57443. + MV_U32 sbOutU[4]={1,3,5,7} ;
  57444. +
  57445. + dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
  57446. +
  57447. + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
  57448. +
  57449. + /* Clear StBurstOutDel field */
  57450. + dunitCtrlLow &= ~SDRAM_SB_OUT_MASK;
  57451. +
  57452. + /* Clear StBurstInDel field */
  57453. + dunitCtrlLow &= ~SDRAM_SB_IN_MASK;
  57454. +
  57455. + /* Clear CtrlPos field */
  57456. + dunitCtrlLow &= ~SDRAM_CTRL_POS_MASK;
  57457. +
  57458. + /* Clear 2T field */
  57459. + dunitCtrlLow &= ~SDRAM_2T_MASK;
  57460. + if (TTMode == MV_TRUE)
  57461. + {
  57462. + dunitCtrlLow |= SDRAM_2T_MODE;
  57463. + }
  57464. +
  57465. + /* For proper sample of read data set the Dunit Control register's */
  57466. + /* stBurstInDel bits [27:24] */
  57467. + /* 200MHz - 267MHz None reg = CL + 1 */
  57468. + /* 200MHz - 267MHz reg = CL + 2 */
  57469. + /* > 267MHz None reg = CL + 2 */
  57470. + /* > 267MHz reg = CL + 3 */
  57471. +
  57472. + /* For proper sample of read data set the Dunit Control register's */
  57473. + /* stBurstOutDel bits [23:20] */
  57474. + /********-********-********-********-
  57475. + * CL=3 | CL=4 | CL=5 | CL=6 |
  57476. + *********-********-********-********-
  57477. + Not Reg. * 0001 | 0011 | 0101 | 0111 |
  57478. + *********-********-********-********-
  57479. + Registered * 0011 | 0101 | 0111 | 1001 |
  57480. + *********-********-********-********/
  57481. +
  57482. + /* Set Dunit Control low default value */
  57483. + dunitCtrlLow |= SDRAM_DUNIT_CTRL_LOW_DDR2_DV;
  57484. +
  57485. + switch (minCas)
  57486. + {
  57487. + case DDR2_CL_3: cl = 3; break;
  57488. + case DDR2_CL_4: cl = 4; break;
  57489. + case DDR2_CL_5: cl = 5; break;
  57490. + case DDR2_CL_6: cl = 6; break;
  57491. + default:
  57492. + mvOsOutput("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n", minCas);
  57493. + return -1;
  57494. + }
  57495. +
  57496. + /* registerd DDR SDRAM? */
  57497. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  57498. + {
  57499. + dunitCtrlLow |= (sbOutR[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
  57500. + }
  57501. + else
  57502. + {
  57503. + dunitCtrlLow |= (sbOutU[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
  57504. + }
  57505. +
  57506. + DB(mvOsPrintf("\n\ndunitCtrlLowRegCalc: CL = %d, frequencies=%d\n", cl, busClk));
  57507. +
  57508. + if (busClk <= MV_BOARD_SYSCLK_267MHZ)
  57509. + {
  57510. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  57511. + cl = cl + 2;
  57512. + else
  57513. + cl = cl + 1;
  57514. + }
  57515. + else
  57516. + {
  57517. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  57518. + cl = cl + 3;
  57519. + else
  57520. + cl = cl + 2;
  57521. + }
  57522. +
  57523. + DB(mvOsPrintf("dunitCtrlLowRegCalc: SDRAM_SB_IN_DEL_OFFS = %d \n", cl));
  57524. + dunitCtrlLow |= cl << SDRAM_SB_IN_DEL_OFFS;
  57525. +
  57526. + DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
  57527. +
  57528. + return dunitCtrlLow;
  57529. +}
  57530. +
  57531. +/*******************************************************************************
  57532. +* dunitCtrlHighRegCalc - Calculate sdram dunit control high register
  57533. +*
  57534. +* DESCRIPTION: Calculate sdram dunit control high register optimized value based
  57535. +* on the bus clock.
  57536. +*
  57537. +* INPUT:
  57538. +* busClk - DRAM frequency.
  57539. +*
  57540. +* OUTPUT:
  57541. +* None
  57542. +*
  57543. +* RETURN:
  57544. +* sdram dunit control high reg value.
  57545. +*
  57546. +*******************************************************************************/
  57547. +static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  57548. +{
  57549. + MV_U32 dunitCtrlHigh;
  57550. + dunitCtrlHigh = MV_REG_READ(SDRAM_DUNIT_CTRL_HI_REG);
  57551. + if(busClk > MV_BOARD_SYSCLK_300MHZ)
  57552. + dunitCtrlHigh |= SDRAM__P2D_EN;
  57553. + else
  57554. + dunitCtrlHigh &= ~SDRAM__P2D_EN;
  57555. +
  57556. + if(busClk > MV_BOARD_SYSCLK_267MHZ)
  57557. + dunitCtrlHigh |= (SDRAM__WR_MESH_DELAY_EN | SDRAM__PUP_ZERO_SKEW_EN | SDRAM__ADD_HALF_FCC_EN);
  57558. +
  57559. + /* If ECC support we turn on D2P sample */
  57560. + dunitCtrlHigh &= ~SDRAM__D2P_EN; /* Clear D2P bit */
  57561. + if (( pBankInfo->errorCheckType ) && (busClk > MV_BOARD_SYSCLK_267MHZ))
  57562. + dunitCtrlHigh |= SDRAM__D2P_EN;
  57563. +
  57564. + return dunitCtrlHigh;
  57565. +}
  57566. +
  57567. +/*******************************************************************************
  57568. +* sdramAddrCtrlRegCalc - Calculate sdram address control register
  57569. +*
  57570. +* DESCRIPTION: Calculate sdram address control register optimized value based
  57571. +* on the bank info parameters and the minCas.
  57572. +*
  57573. +* INPUT:
  57574. +* pBankInfo - sdram bank parameters
  57575. +*
  57576. +* OUTPUT:
  57577. +* None
  57578. +*
  57579. +* RETURN:
  57580. +* sdram address control reg value.
  57581. +*
  57582. +*******************************************************************************/
  57583. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1)
  57584. +{
  57585. + MV_U32 addrCtrl = 0;
  57586. +
  57587. + if (pBankInfoDIMM1->size)
  57588. + {
  57589. + switch (pBankInfoDIMM1->sdramWidth)
  57590. + {
  57591. + case 4: /* memory is x4 */
  57592. + mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
  57593. + return -1;
  57594. + break;
  57595. + case 8: /* memory is x8 */
  57596. + addrCtrl |= SDRAM_ADDRSEL_X8(2) | SDRAM_ADDRSEL_X8(3);
  57597. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x8\n"));
  57598. + break;
  57599. + case 16:
  57600. + addrCtrl |= SDRAM_ADDRSEL_X16(2) | SDRAM_ADDRSEL_X16(3);
  57601. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x16\n"));
  57602. + break;
  57603. + default: /* memory width unsupported */
  57604. + mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
  57605. + return -1;
  57606. + }
  57607. + }
  57608. +
  57609. + switch (pBankInfo->sdramWidth)
  57610. + {
  57611. + case 4: /* memory is x4 */
  57612. + mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
  57613. + return -1;
  57614. + break;
  57615. + case 8: /* memory is x8 */
  57616. + addrCtrl |= SDRAM_ADDRSEL_X8(0) | SDRAM_ADDRSEL_X8(1);
  57617. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x8\n"));
  57618. + break;
  57619. + case 16:
  57620. + addrCtrl |= SDRAM_ADDRSEL_X16(0) | SDRAM_ADDRSEL_X16(1);
  57621. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x16\n"));
  57622. + break;
  57623. + default: /* memory width unsupported */
  57624. + mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
  57625. + return -1;
  57626. + }
  57627. +
  57628. + /* Note that density is in MB units */
  57629. + switch (pBankInfo->deviceDensity)
  57630. + {
  57631. + case 256: /* 256 Mbit */
  57632. + DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
  57633. + addrCtrl |= SDRAM_DSIZE_256Mb(0) | SDRAM_DSIZE_256Mb(1);
  57634. + break;
  57635. + case 512: /* 512 Mbit */
  57636. + DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
  57637. + addrCtrl |= SDRAM_DSIZE_512Mb(0) | SDRAM_DSIZE_512Mb(1);
  57638. + break;
  57639. + case 1024: /* 1 Gbit */
  57640. + DB(mvOsPrintf("DRAM Device Density 1Gbit\n"));
  57641. + addrCtrl |= SDRAM_DSIZE_1Gb(0) | SDRAM_DSIZE_1Gb(1);
  57642. + break;
  57643. + case 2048: /* 2 Gbit */
  57644. + DB(mvOsPrintf("DRAM Device Density 2Gbit\n"));
  57645. + addrCtrl |= SDRAM_DSIZE_2Gb(0) | SDRAM_DSIZE_2Gb(1);
  57646. + break;
  57647. + default:
  57648. + mvOsOutput("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
  57649. + pBankInfo->deviceDensity);
  57650. + return -1;
  57651. + }
  57652. +
  57653. + if (pBankInfoDIMM1->size)
  57654. + {
  57655. + switch (pBankInfoDIMM1->deviceDensity)
  57656. + {
  57657. + case 256: /* 256 Mbit */
  57658. + DB(mvOsPrintf("DIMM2: DRAM Device Density 256Mbit\n"));
  57659. + addrCtrl |= SDRAM_DSIZE_256Mb(2) | SDRAM_DSIZE_256Mb(3);
  57660. + break;
  57661. + case 512: /* 512 Mbit */
  57662. + DB(mvOsPrintf("DIMM2: DRAM Device Density 512Mbit\n"));
  57663. + addrCtrl |= SDRAM_DSIZE_512Mb(2) | SDRAM_DSIZE_512Mb(3);
  57664. + break;
  57665. + case 1024: /* 1 Gbit */
  57666. + DB(mvOsPrintf("DIMM2: DRAM Device Density 1Gbit\n"));
  57667. + addrCtrl |= SDRAM_DSIZE_1Gb(2) | SDRAM_DSIZE_1Gb(3);
  57668. + break;
  57669. + case 2048: /* 2 Gbit */
  57670. + DB(mvOsPrintf("DIMM2: DRAM Device Density 2Gbit\n"));
  57671. + addrCtrl |= SDRAM_DSIZE_2Gb(2) | SDRAM_DSIZE_2Gb(3);
  57672. + break;
  57673. + default:
  57674. + mvOsOutput("DIMM2: Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
  57675. + pBankInfoDIMM1->deviceDensity);
  57676. + return -1;
  57677. + }
  57678. + }
  57679. + /* SDRAM address control */
  57680. + DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
  57681. +
  57682. + return addrCtrl;
  57683. +}
  57684. +
  57685. +/*******************************************************************************
  57686. +* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
  57687. +*
  57688. +* DESCRIPTION:
  57689. +* This function calculates sdram timing control low register
  57690. +* optimized value based on the bank info parameters and the minCas.
  57691. +*
  57692. +* INPUT:
  57693. +* pBankInfo - sdram bank parameters
  57694. +* minCas - minimum CAS supported.
  57695. +* busClk - Bus clock
  57696. +*
  57697. +* OUTPUT:
  57698. +* None
  57699. +*
  57700. +* RETURN:
  57701. +* sdram timing control low reg value.
  57702. +*
  57703. +*******************************************************************************/
  57704. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk)
  57705. +{
  57706. + MV_U32 tRp = 0;
  57707. + MV_U32 tRrd = 0;
  57708. + MV_U32 tRcd = 0;
  57709. + MV_U32 tRas = 0;
  57710. + MV_U32 tWr = 0;
  57711. + MV_U32 tWtr = 0;
  57712. + MV_U32 tRtp = 0;
  57713. + MV_U32 timeCtrlLow = 0;
  57714. +
  57715. + MV_U32 bankNum;
  57716. +
  57717. + busClk = busClk / 1000000; /* In MHz */
  57718. +
  57719. + /* Scan all DRAM banks to find maximum timing values */
  57720. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  57721. + {
  57722. + tRp = MV_MAX(tRp, pBankInfo[bankNum].minRowPrechargeTime);
  57723. + tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
  57724. + tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
  57725. + tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
  57726. + }
  57727. +
  57728. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns part. */
  57729. + /* by shifting the data two bits right. */
  57730. + tRp = tRp >> 2; /* For example 0x50 -> 20ns */
  57731. + tRrd = tRrd >> 2;
  57732. + tRcd = tRcd >> 2;
  57733. +
  57734. + /* Extract clock cycles from time parameter. We need to round up */
  57735. + tRp = ((busClk * tRp) / 1000) + (((busClk * tRp) % 1000) ? 1 : 0);
  57736. + DB(mvOsPrintf("Dram Timing Low: tRp = %d ", tRp));
  57737. + tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
  57738. + /* JEDEC min reqeirments tRrd = 2 */
  57739. + if (tRrd < 2)
  57740. + tRrd = 2;
  57741. + DB(mvOsPrintf("tRrd = %d ", tRrd));
  57742. + tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
  57743. + DB(mvOsPrintf("tRcd = %d ", tRcd));
  57744. + tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
  57745. + DB(mvOsPrintf("tRas = %d ", tRas));
  57746. +
  57747. + /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2 */
  57748. + /* Scan all DRAM banks to find maximum timing values */
  57749. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  57750. + {
  57751. + tWr = MV_MAX(tWr, pBankInfo[bankNum].minWriteRecoveryTime);
  57752. + tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
  57753. + tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
  57754. + }
  57755. +
  57756. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns */
  57757. + /* part by shifting the data two bits right. */
  57758. + tWr = tWr >> 2; /* For example 0x50 -> 20ns */
  57759. + tWtr = tWtr >> 2;
  57760. + tRtp = tRtp >> 2;
  57761. + /* Extract clock cycles from time parameter. We need to round up */
  57762. + tWr = ((busClk * tWr) / 1000) + (((busClk * tWr) % 1000) ? 1 : 0);
  57763. + DB(mvOsPrintf("tWr = %d ", tWr));
  57764. + tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
  57765. + /* JEDEC min reqeirments tWtr = 2 */
  57766. + if (tWtr < 2)
  57767. + tWtr = 2;
  57768. + DB(mvOsPrintf("tWtr = %d ", tWtr));
  57769. + tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
  57770. + /* JEDEC min reqeirments tRtp = 2 */
  57771. + if (tRtp < 2)
  57772. + tRtp = 2;
  57773. + DB(mvOsPrintf("tRtp = %d ", tRtp));
  57774. +
  57775. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  57776. + timeCtrlLow = (((tRp - 1) << SDRAM_TRP_OFFS) |
  57777. + ((tRrd - 1) << SDRAM_TRRD_OFFS) |
  57778. + ((tRcd - 1) << SDRAM_TRCD_OFFS) |
  57779. + (((tRas - 1) << SDRAM_TRAS_OFFS) & SDRAM_TRAS_MASK)|
  57780. + ((tWr - 1) << SDRAM_TWR_OFFS) |
  57781. + ((tWtr - 1) << SDRAM_TWTR_OFFS) |
  57782. + ((tRtp - 1) << SDRAM_TRTP_OFFS));
  57783. +
  57784. + /* Check extended tRas bit */
  57785. + if ((tRas - 1) & BIT4)
  57786. + timeCtrlLow |= (1 << SDRAM_EXT_TRAS_OFFS);
  57787. +
  57788. + return timeCtrlLow;
  57789. +}
  57790. +
  57791. +/*******************************************************************************
  57792. +* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
  57793. +*
  57794. +* DESCRIPTION:
  57795. +* This function calculates sdram timing control high register
  57796. +* optimized value based on the bank info parameters and the bus clock.
  57797. +*
  57798. +* INPUT:
  57799. +* pBankInfo - sdram bank parameters
  57800. +* busClk - Bus clock
  57801. +*
  57802. +* OUTPUT:
  57803. +* None
  57804. +*
  57805. +* RETURN:
  57806. +* sdram timing control high reg value.
  57807. +*
  57808. +*******************************************************************************/
  57809. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  57810. +{
  57811. + MV_U32 tRfc;
  57812. + MV_U32 timingHigh;
  57813. + MV_U32 timeNs = 0;
  57814. + MV_U32 bankNum;
  57815. +
  57816. + busClk = busClk / 1000000; /* In MHz */
  57817. +
  57818. + /* Set DDR timing high register static configuration bits */
  57819. + timingHigh = MV_REG_READ(SDRAM_TIMING_CTRL_HIGH_REG);
  57820. +
  57821. + /* Set DDR timing high register default value */
  57822. + timingHigh |= SDRAM_TIMING_CTRL_HIGH_REG_DV;
  57823. +
  57824. + /* Clear tRfc field */
  57825. + timingHigh &= ~SDRAM_TRFC_MASK;
  57826. +
  57827. + /* Scan all DRAM banks to find maximum timing values */
  57828. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  57829. + {
  57830. + timeNs = MV_MAX(timeNs, pBankInfo[bankNum].minRefreshToActiveCmd);
  57831. + DB(mvOsPrintf("Dram: Timing High: minRefreshToActiveCmd = %d\n",
  57832. + pBankInfo[bankNum].minRefreshToActiveCmd));
  57833. + }
  57834. + if(busClk >= 333 && mvCtrlModelGet() == MV_78XX0_A1_REV)
  57835. + {
  57836. + timingHigh |= 0x1 << SDRAM_TR2W_W2R_OFFS;
  57837. + }
  57838. +
  57839. + tRfc = ((busClk * timeNs) / 1000) + (((busClk * timeNs) % 1000) ? 1 : 0);
  57840. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  57841. + DB(mvOsPrintf("Dram: Timing High: tRfc = %d\n", tRfc));
  57842. + timingHigh |= (((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS);
  57843. + DB(mvOsPrintf("Dram: Timing High: tRfc = %d\n", tRfc));
  57844. +
  57845. + /* SDRAM timing high */
  57846. + DB(mvOsPrintf("Dram: setting timing high with: %x \n", timingHigh));
  57847. +
  57848. + return timingHigh;
  57849. +}
  57850. +/*******************************************************************************
  57851. +* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
  57852. +*
  57853. +* DESCRIPTION:
  57854. +* This function config DDR2 On Die Termination (ODT) registers.
  57855. +*
  57856. +* INPUT:
  57857. +* pBankInfo - bank info parameters.
  57858. +*
  57859. +* OUTPUT:
  57860. +* None
  57861. +*
  57862. +* RETURN:
  57863. +* None
  57864. +*******************************************************************************/
  57865. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
  57866. +{
  57867. + MV_U32 populateBanks = 0;
  57868. + MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
  57869. + int bankNum;
  57870. +
  57871. + /* Represent the populate banks in binary form */
  57872. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  57873. + {
  57874. + if (0 != pBankInfo[bankNum].size)
  57875. + {
  57876. + populateBanks |= (1 << bankNum);
  57877. + }
  57878. + }
  57879. +
  57880. + switch(populateBanks)
  57881. + {
  57882. + case(BANK_PRESENT_CS0):
  57883. + case(BANK_PRESENT_CS0_CS1):
  57884. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS1_DV;
  57885. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS1_DV;
  57886. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV;
  57887. + break;
  57888. + case(BANK_PRESENT_CS0_CS2):
  57889. + case(BANK_PRESENT_CS0_CS1_CS2):
  57890. + case(BANK_PRESENT_CS0_CS2_CS3):
  57891. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  57892. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV;
  57893. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV;
  57894. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV;
  57895. + break;
  57896. + default:
  57897. + DB(mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n"));
  57898. + return;
  57899. + }
  57900. + /* DDR2 SDRAM ODT ctrl low */
  57901. + DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl low with: %x \n", odtCtrlLow));
  57902. + MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
  57903. +
  57904. + /* DDR2 SDRAM ODT ctrl high */
  57905. + DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl high with: %x \n", odtCtrlHigh));
  57906. + MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
  57907. +
  57908. + /* DDR2 DUNIT ODT ctrl */
  57909. + if ( ((mvCtrlModelGet() == MV_78XX0_DEV_ID) && (mvCtrlRevGet() == MV_78XX0_Y0_REV)) ||
  57910. + (mvCtrlModelGet() == MV_76100_DEV_ID) ||
  57911. + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
  57912. + (mvCtrlModelGet() == MV_78200_DEV_ID) )
  57913. + dunitOdtCtrl &= ~(BIT9|BIT8); /* Clear ODT always on */
  57914. +
  57915. + DB(mvOsPrintf("DUNIT: DDR2 setting ODT ctrl with: %x \n", dunitOdtCtrl));
  57916. + MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
  57917. + return;
  57918. +}
  57919. +/*******************************************************************************
  57920. +* sdramDdr2TimeLoRegCalc - Set DDR2 DRAM Timing Low registers.
  57921. +*
  57922. +* DESCRIPTION:
  57923. +* This function config DDR2 DRAM Timing low registers.
  57924. +*
  57925. +* INPUT:
  57926. +* minCas - minimum CAS supported.
  57927. +*
  57928. +* OUTPUT:
  57929. +* None
  57930. +*
  57931. +* RETURN:
  57932. +* DDR2 sdram timing low reg value.
  57933. +*******************************************************************************/
  57934. +static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas)
  57935. +{
  57936. + MV_U8 cl = -1;
  57937. + MV_U32 ddr2TimeLoReg;
  57938. +
  57939. + /* read and clear the feilds we are going to set */
  57940. + ddr2TimeLoReg = MV_REG_READ(SDRAM_DDR2_TIMING_LO_REG);
  57941. + ddr2TimeLoReg &= ~(SD2TLR_TODT_ON_RD_MASK |
  57942. + SD2TLR_TODT_OFF_RD_MASK |
  57943. + SD2TLR_TODT_ON_CTRL_RD_MASK |
  57944. + SD2TLR_TODT_OFF_CTRL_RD_MASK);
  57945. +
  57946. + if( minCas == DDR2_CL_3 )
  57947. + {
  57948. + cl = 3;
  57949. + }
  57950. + else if( minCas == DDR2_CL_4 )
  57951. + {
  57952. + cl = 4;
  57953. + }
  57954. + else if( minCas == DDR2_CL_5 )
  57955. + {
  57956. + cl = 5;
  57957. + }
  57958. + else if( minCas == DDR2_CL_6 )
  57959. + {
  57960. + cl = 6;
  57961. + }
  57962. + else
  57963. + {
  57964. + DB(mvOsPrintf("sdramDdr2TimeLoRegCalc: CAS latency %d unsupported. using CAS latency 4\n",
  57965. + minCas));
  57966. + cl = 4;
  57967. + }
  57968. +
  57969. + ddr2TimeLoReg |= ((cl-3) << SD2TLR_TODT_ON_RD_OFFS);
  57970. + ddr2TimeLoReg |= ( cl << SD2TLR_TODT_OFF_RD_OFFS);
  57971. + ddr2TimeLoReg |= ( cl << SD2TLR_TODT_ON_CTRL_RD_OFFS);
  57972. + ddr2TimeLoReg |= ((cl+3) << SD2TLR_TODT_OFF_CTRL_RD_OFFS);
  57973. +
  57974. + /* DDR2 SDRAM timing low */
  57975. + DB(mvOsPrintf("Dram: DDR2 setting timing low with: %x \n", ddr2TimeLoReg));
  57976. +
  57977. + return ddr2TimeLoReg;
  57978. +}
  57979. +
  57980. +/*******************************************************************************
  57981. +* sdramDdr2TimeHiRegCalc - Set DDR2 DRAM Timing High registers.
  57982. +*
  57983. +* DESCRIPTION:
  57984. +* This function config DDR2 DRAM Timing high registers.
  57985. +*
  57986. +* INPUT:
  57987. +* minCas - minimum CAS supported.
  57988. +*
  57989. +* OUTPUT:
  57990. +* None
  57991. +*
  57992. +* RETURN:
  57993. +* DDR2 sdram timing high reg value.
  57994. +*******************************************************************************/
  57995. +static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas)
  57996. +{
  57997. + MV_U8 cl = -1;
  57998. + MV_U32 ddr2TimeHiReg;
  57999. +
  58000. + /* read and clear the feilds we are going to set */
  58001. + ddr2TimeHiReg = MV_REG_READ(SDRAM_DDR2_TIMING_HI_REG);
  58002. + ddr2TimeHiReg &= ~(SD2THR_TODT_ON_WR_MASK |
  58003. + SD2THR_TODT_OFF_WR_MASK |
  58004. + SD2THR_TODT_ON_CTRL_WR_MASK |
  58005. + SD2THR_TODT_OFF_CTRL_WR_MASK);
  58006. +
  58007. + if( minCas == DDR2_CL_3 )
  58008. + {
  58009. + cl = 3;
  58010. + }
  58011. + else if( minCas == DDR2_CL_4 )
  58012. + {
  58013. + cl = 4;
  58014. + }
  58015. + else if( minCas == DDR2_CL_5 )
  58016. + {
  58017. + cl = 5;
  58018. + }
  58019. + else if( minCas == DDR2_CL_6 )
  58020. + {
  58021. + cl = 6;
  58022. + }
  58023. + else
  58024. + {
  58025. + mvOsOutput("sdramDdr2TimeHiRegCalc: CAS latency %d unsupported. using CAS latency 4\n",
  58026. + minCas);
  58027. + cl = 4;
  58028. + }
  58029. +
  58030. + ddr2TimeHiReg |= ((cl-3) << SD2THR_TODT_ON_WR_OFFS);
  58031. + ddr2TimeHiReg |= ( cl << SD2THR_TODT_OFF_WR_OFFS);
  58032. + ddr2TimeHiReg |= ( cl << SD2THR_TODT_ON_CTRL_WR_OFFS);
  58033. + ddr2TimeHiReg |= ((cl+3) << SD2THR_TODT_OFF_CTRL_WR_OFFS);
  58034. +
  58035. + /* DDR2 SDRAM timin high */
  58036. + DB(mvOsPrintf("Dram: DDR2 setting timing high with: %x \n", ddr2TimeHiReg));
  58037. +
  58038. + return ddr2TimeHiReg;
  58039. +}
  58040. +#endif
  58041. +
  58042. +/*******************************************************************************
  58043. +* mvDramIfCalGet - Get CAS Latency
  58044. +*
  58045. +* DESCRIPTION:
  58046. +* This function get the CAS Latency.
  58047. +*
  58048. +* INPUT:
  58049. +* None
  58050. +*
  58051. +* OUTPUT:
  58052. +* None
  58053. +*
  58054. +* RETURN:
  58055. +* CAS latency times 10 (to avoid using floating point).
  58056. +*
  58057. +*******************************************************************************/
  58058. +MV_U32 mvDramIfCalGet(void)
  58059. +{
  58060. + MV_U32 sdramCasLat, casLatMask;
  58061. +
  58062. + casLatMask = (MV_REG_READ(SDRAM_MODE_REG) & SDRAM_CL_MASK);
  58063. +
  58064. + switch (casLatMask)
  58065. + {
  58066. + case SDRAM_DDR2_CL_3:
  58067. + sdramCasLat = 30;
  58068. + break;
  58069. + case SDRAM_DDR2_CL_4:
  58070. + sdramCasLat = 40;
  58071. + break;
  58072. + case SDRAM_DDR2_CL_5:
  58073. + sdramCasLat = 50;
  58074. + break;
  58075. + case SDRAM_DDR2_CL_6:
  58076. + sdramCasLat = 60;
  58077. + break;
  58078. + default:
  58079. + mvOsOutput("mvDramIfCalGet: Err, unknown DDR2 CAL\n");
  58080. + return -1;
  58081. + }
  58082. +
  58083. + return sdramCasLat;
  58084. +}
  58085. +
  58086. +
  58087. +/*******************************************************************************
  58088. +* mvDramIfSelfRefreshSet - Put the dram in self refresh mode -
  58089. +*
  58090. +* DESCRIPTION:
  58091. +* add support in power management.
  58092. +*
  58093. +*
  58094. +* INPUT:
  58095. +* None
  58096. +*
  58097. +* OUTPUT:
  58098. +* None
  58099. +*
  58100. +* RETURN:
  58101. +* None
  58102. +*
  58103. +*******************************************************************************/
  58104. +
  58105. +MV_VOID mvDramIfSelfRefreshSet()
  58106. +{
  58107. + MV_U32 operReg;
  58108. +
  58109. + operReg = MV_REG_READ(SDRAM_OPERATION_REG);
  58110. + MV_REG_WRITE(SDRAM_OPERATION_REG ,operReg |SDRAM_CMD_SLF_RFRSH);
  58111. + /* Read until register is reset to 0 */
  58112. + while(MV_REG_READ(SDRAM_OPERATION_REG));
  58113. +}
  58114. +/*******************************************************************************
  58115. +* mvDramIfDimGetSPDversion - return DIMM SPD version.
  58116. +*
  58117. +* DESCRIPTION:
  58118. +* This function prints the DRAM controller information.
  58119. +*
  58120. +* INPUT:
  58121. +* None.
  58122. +*
  58123. +* OUTPUT:
  58124. +* None.
  58125. +*
  58126. +* RETURN:
  58127. +* None.
  58128. +*
  58129. +*******************************************************************************/
  58130. +static void mvDramIfDimGetSPDversion(MV_U32 *pMajor, MV_U32 *pMinor, MV_U32 bankNum)
  58131. +{
  58132. + MV_DIMM_INFO dimmInfo;
  58133. + if (bankNum >= MV_DRAM_MAX_CS )
  58134. + {
  58135. + DB(mvOsPrintf("Dram: mvDramIfDimGetSPDversion bad params \n"));
  58136. + return ;
  58137. + }
  58138. + memset(&dimmInfo,0,sizeof(dimmInfo));
  58139. + if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
  58140. + {
  58141. + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
  58142. + return ;
  58143. + }
  58144. + *pMajor = dimmInfo.spdRawData[DIMM_SPD_VERSION]/10;
  58145. + *pMinor = dimmInfo.spdRawData[DIMM_SPD_VERSION]%10;
  58146. +}
  58147. +/*******************************************************************************
  58148. +* mvDramIfShow - Show DRAM controller information.
  58149. +*
  58150. +* DESCRIPTION:
  58151. +* This function prints the DRAM controller information.
  58152. +*
  58153. +* INPUT:
  58154. +* None.
  58155. +*
  58156. +* OUTPUT:
  58157. +* None.
  58158. +*
  58159. +* RETURN:
  58160. +* None.
  58161. +*
  58162. +*******************************************************************************/
  58163. +void mvDramIfShow(void)
  58164. +{
  58165. + int i, sdramCasLat, sdramCsSize;
  58166. + MV_U32 Major=0, Minor=0;
  58167. +
  58168. + mvOsOutput("DRAM Controller info:\n");
  58169. +
  58170. + mvOsOutput("Total DRAM ");
  58171. + mvSizePrint(mvDramIfSizeGet());
  58172. + mvOsOutput("\n");
  58173. +
  58174. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  58175. + {
  58176. + sdramCsSize = mvDramIfBankSizeGet(i);
  58177. + if (sdramCsSize)
  58178. + {
  58179. + if (0 == (i & 1))
  58180. + {
  58181. + mvDramIfDimGetSPDversion(&Major, &Minor,i);
  58182. + mvOsOutput("DIMM %d version %d.%d\n", i/2, Major, Minor);
  58183. + }
  58184. + mvOsOutput("\tDRAM CS[%d] ", i);
  58185. + mvSizePrint(sdramCsSize);
  58186. + mvOsOutput("\n");
  58187. + }
  58188. + }
  58189. + sdramCasLat = mvDramIfCalGet();
  58190. +
  58191. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_ECC_EN)
  58192. + {
  58193. + mvOsOutput("ECC enabled, ");
  58194. + }
  58195. + else
  58196. + {
  58197. + mvOsOutput("ECC Disabled, ");
  58198. + }
  58199. +
  58200. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_REGISTERED)
  58201. + {
  58202. + mvOsOutput("Registered DIMM\n");
  58203. + }
  58204. + else
  58205. + {
  58206. + mvOsOutput("Non registered DIMM\n");
  58207. + }
  58208. +
  58209. + mvOsOutput("Configured CAS Latency %d.%d\n", sdramCasLat/10, sdramCasLat%10);
  58210. +}
  58211. +/*******************************************************************************
  58212. +* mvDramIfGetFirstCS - find the DRAM bank on the lower address
  58213. +*
  58214. +*
  58215. +* DESCRIPTION:
  58216. +* This function return the fisrt CS on address 0
  58217. +*
  58218. +* INPUT:
  58219. +* None.
  58220. +*
  58221. +* OUTPUT:
  58222. +* None.
  58223. +*
  58224. +* RETURN:
  58225. +* SDRAM_CS0 or SDRAM_CS2
  58226. +*
  58227. +*******************************************************************************/
  58228. +MV_U32 mvDramIfGetFirstCS(void)
  58229. +{
  58230. + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
  58231. +
  58232. + if (DRAM_CS_Order[0] == N_A)
  58233. + {
  58234. + mvDramBankInfoGet(SDRAM_CS0, &bankInfo[SDRAM_CS0]);
  58235. +#ifdef MV_INCLUDE_SDRAM_CS2
  58236. + mvDramBankInfoGet(SDRAM_CS2, &bankInfo[SDRAM_CS2]);
  58237. +#endif
  58238. +
  58239. +#ifdef MV_INCLUDE_SDRAM_CS2
  58240. + if (bankInfo[SDRAM_CS0].size < bankInfo[SDRAM_CS2].size)
  58241. + {
  58242. + DRAM_CS_Order[0] = SDRAM_CS2;
  58243. + DRAM_CS_Order[1] = SDRAM_CS3;
  58244. + DRAM_CS_Order[2] = SDRAM_CS0;
  58245. + DRAM_CS_Order[3] = SDRAM_CS1;
  58246. +
  58247. + return SDRAM_CS2;
  58248. + }
  58249. +#endif
  58250. + DRAM_CS_Order[0] = SDRAM_CS0;
  58251. + DRAM_CS_Order[1] = SDRAM_CS1;
  58252. +#ifdef MV_INCLUDE_SDRAM_CS2
  58253. + DRAM_CS_Order[2] = SDRAM_CS2;
  58254. + DRAM_CS_Order[3] = SDRAM_CS3;
  58255. +#endif
  58256. + return SDRAM_CS0;
  58257. + }
  58258. + return DRAM_CS_Order[0];
  58259. +}
  58260. +/*******************************************************************************
  58261. +* mvDramIfGetCSorder -
  58262. +*
  58263. +*
  58264. +* DESCRIPTION:
  58265. +* This function return the fisrt CS on address 0
  58266. +*
  58267. +* INPUT:
  58268. +* CS number.
  58269. +*
  58270. +* OUTPUT:
  58271. +* CS order.
  58272. +*
  58273. +* RETURN:
  58274. +* SDRAM_CS0 or SDRAM_CS2
  58275. +*
  58276. +* NOTE: mvDramIfGetFirstCS must be caled before this subroutine
  58277. +*******************************************************************************/
  58278. +MV_U32 mvDramIfGetCSorder(MV_U32 csOrder )
  58279. +{
  58280. + return DRAM_CS_Order[csOrder];
  58281. +}
  58282. +
  58283. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h
  58284. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h 1970-01-01 01:00:00.000000000 +0100
  58285. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h 2010-11-09 20:28:10.852495382 +0100
  58286. @@ -0,0 +1,157 @@
  58287. +/*******************************************************************************
  58288. +Copyright (C) Marvell International Ltd. and its affiliates
  58289. +
  58290. +This software file (the "File") is owned and distributed by Marvell
  58291. +International Ltd. and/or its affiliates ("Marvell") under the following
  58292. +alternative licensing terms. Once you have made an election to distribute the
  58293. +File under one of the following license alternatives, please (i) delete this
  58294. +introductory statement regarding license alternatives, (ii) delete the two
  58295. +license alternatives that you have not elected to use and (iii) preserve the
  58296. +Marvell copyright notice above.
  58297. +
  58298. +********************************************************************************
  58299. +Marvell Commercial License Option
  58300. +
  58301. +If you received this File from Marvell and you have entered into a commercial
  58302. +license agreement (a "Commercial License") with Marvell, the File is licensed
  58303. +to you under the terms of the applicable Commercial License.
  58304. +
  58305. +********************************************************************************
  58306. +Marvell GPL License Option
  58307. +
  58308. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58309. +modify this File in accordance with the terms and conditions of the General
  58310. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  58311. +available along with the File in the license.txt file or by writing to the Free
  58312. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  58313. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  58314. +
  58315. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  58316. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  58317. +DISCLAIMED. The GPL License provides additional details about this warranty
  58318. +disclaimer.
  58319. +********************************************************************************
  58320. +Marvell BSD License Option
  58321. +
  58322. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58323. +modify this File under the following licensing terms.
  58324. +Redistribution and use in source and binary forms, with or without modification,
  58325. +are permitted provided that the following conditions are met:
  58326. +
  58327. + * Redistributions of source code must retain the above copyright notice,
  58328. + this list of conditions and the following disclaimer.
  58329. +
  58330. + * Redistributions in binary form must reproduce the above copyright
  58331. + notice, this list of conditions and the following disclaimer in the
  58332. + documentation and/or other materials provided with the distribution.
  58333. +
  58334. + * Neither the name of Marvell nor the names of its contributors may be
  58335. + used to endorse or promote products derived from this software without
  58336. + specific prior written permission.
  58337. +
  58338. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  58339. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  58340. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  58341. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  58342. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  58343. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  58344. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  58345. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  58346. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58347. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  58348. +
  58349. +*******************************************************************************/
  58350. +
  58351. +
  58352. +#ifndef __INCmvDramIfConfigh
  58353. +#define __INCmvDramIfConfigh
  58354. +
  58355. +#ifdef __cplusplus
  58356. +extern "C" {
  58357. +#endif /* __cplusplus */
  58358. +
  58359. +/* includes */
  58360. +
  58361. +/* defines */
  58362. +
  58363. +/* registers defaults values */
  58364. +
  58365. +#define SDRAM_CONFIG_DV (SDRAM_SRMODE_DRAM | BIT25 | BIT30)
  58366. +
  58367. +#define SDRAM_DUNIT_CTRL_LOW_DDR2_DV \
  58368. + (SDRAM_SRCLK_KEPT | \
  58369. + SDRAM_CLK1DRV_NORMAL | \
  58370. + (BIT28 | BIT29))
  58371. +
  58372. +#define SDRAM_ADDR_CTRL_DV 2
  58373. +
  58374. +#define SDRAM_TIMING_CTRL_LOW_REG_DV \
  58375. + ((0x2 << SDRAM_TRCD_OFFS) | \
  58376. + (0x2 << SDRAM_TRP_OFFS) | \
  58377. + (0x1 << SDRAM_TWR_OFFS) | \
  58378. + (0x0 << SDRAM_TWTR_OFFS) | \
  58379. + (0x5 << SDRAM_TRAS_OFFS) | \
  58380. + (0x1 << SDRAM_TRRD_OFFS))
  58381. +
  58382. +/* Note: value of 0 in register means one cycle, 1 means two and so on */
  58383. +#define SDRAM_TIMING_CTRL_HIGH_REG_DV \
  58384. + ((0x0 << SDRAM_TR2R_OFFS) | \
  58385. + (0x0 << SDRAM_TR2W_W2R_OFFS) | \
  58386. + (0x1 << SDRAM_TW2W_OFFS))
  58387. +
  58388. +#define SDRAM_OPEN_PAGES_CTRL_REG_DV SDRAM_OPEN_PAGE_EN
  58389. +
  58390. +/* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode */
  58391. +/* CS0 0x84210000 0x00000000 0x0000780F 0x00000440 */
  58392. +/* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440 */
  58393. +/* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  58394. +/* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  58395. +/* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  58396. +/* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  58397. +
  58398. +#define DDR2_ODT_CTRL_LOW_CS0_CS1_DV 0x84210000
  58399. +#define DDR2_ODT_CTRL_HIGH_CS0_CS1_DV 0x00000000
  58400. +#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV 0x0000E80F
  58401. +#ifdef MV78XX0
  58402. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV 0x00000040
  58403. +#else
  58404. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV 0x00000440
  58405. +#endif
  58406. +
  58407. +#define DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV 0x030C030C
  58408. +#define DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV 0x00000000
  58409. +#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV 0x0000F40F
  58410. +#ifdef MV78XX0
  58411. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV 0x00000004
  58412. +#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV 0x00000044
  58413. +#else
  58414. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV 0x00000404
  58415. +#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV 0x00000444
  58416. +#endif
  58417. +
  58418. +/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */
  58419. +#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
  58420. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  58421. +
  58422. +#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV \
  58423. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  58424. +
  58425. +/* DDR SDRAM Mode Register default value */
  58426. +#define DDR2_MODE_REG_DV (SDRAM_BURST_LEN_4 | SDRAM_WR_3_CYC)
  58427. +/* DDR SDRAM Timing parameter default values */
  58428. +#define SDRAM_TIMING_CTRL_LOW_REG_DEFAULT 0x33136552
  58429. +#define SDRAM_TRFC_DEFAULT_VALUE 0x34
  58430. +#define SDRAM_TRFC_DEFAULT SDRAM_TRFC_DEFAULT_VALUE
  58431. +#define SDRAM_TW2W_DEFALT (0x1 << SDRAM_TW2W_OFFS)
  58432. +
  58433. +#define SDRAM_TIMING_CTRL_HIGH_REG_DEFAULT (SDRAM_TRFC_DEFAULT | SDRAM_TW2W_DEFALT)
  58434. +
  58435. +#define SDRAM_FTDLL_REG_DEFAULT_LEFT 0x88C800
  58436. +#define SDRAM_FTDLL_REG_DEFAULT_RIGHT 0x88C800
  58437. +#define SDRAM_FTDLL_REG_DEFAULT_UP 0x88C800
  58438. +
  58439. +#ifdef __cplusplus
  58440. +}
  58441. +#endif /* __cplusplus */
  58442. +
  58443. +#endif /* __INCmvDramIfh */
  58444. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h
  58445. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h 1970-01-01 01:00:00.000000000 +0100
  58446. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h 2010-11-09 20:28:10.882495421 +0100
  58447. @@ -0,0 +1,172 @@
  58448. +/*******************************************************************************
  58449. +Copyright (C) Marvell International Ltd. and its affiliates
  58450. +
  58451. +This software file (the "File") is owned and distributed by Marvell
  58452. +International Ltd. and/or its affiliates ("Marvell") under the following
  58453. +alternative licensing terms. Once you have made an election to distribute the
  58454. +File under one of the following license alternatives, please (i) delete this
  58455. +introductory statement regarding license alternatives, (ii) delete the two
  58456. +license alternatives that you have not elected to use and (iii) preserve the
  58457. +Marvell copyright notice above.
  58458. +
  58459. +********************************************************************************
  58460. +Marvell Commercial License Option
  58461. +
  58462. +If you received this File from Marvell and you have entered into a commercial
  58463. +license agreement (a "Commercial License") with Marvell, the File is licensed
  58464. +to you under the terms of the applicable Commercial License.
  58465. +
  58466. +********************************************************************************
  58467. +Marvell GPL License Option
  58468. +
  58469. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58470. +modify this File in accordance with the terms and conditions of the General
  58471. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  58472. +available along with the File in the license.txt file or by writing to the Free
  58473. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  58474. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  58475. +
  58476. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  58477. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  58478. +DISCLAIMED. The GPL License provides additional details about this warranty
  58479. +disclaimer.
  58480. +********************************************************************************
  58481. +Marvell BSD License Option
  58482. +
  58483. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58484. +modify this File under the following licensing terms.
  58485. +Redistribution and use in source and binary forms, with or without modification,
  58486. +are permitted provided that the following conditions are met:
  58487. +
  58488. + * Redistributions of source code must retain the above copyright notice,
  58489. + this list of conditions and the following disclaimer.
  58490. +
  58491. + * Redistributions in binary form must reproduce the above copyright
  58492. + notice, this list of conditions and the following disclaimer in the
  58493. + documentation and/or other materials provided with the distribution.
  58494. +
  58495. + * Neither the name of Marvell nor the names of its contributors may be
  58496. + used to endorse or promote products derived from this software without
  58497. + specific prior written permission.
  58498. +
  58499. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  58500. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  58501. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  58502. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  58503. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  58504. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  58505. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  58506. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  58507. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58508. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  58509. +
  58510. +*******************************************************************************/
  58511. +
  58512. +
  58513. +#ifndef __INCmvDramIfh
  58514. +#define __INCmvDramIfh
  58515. +
  58516. +#ifdef __cplusplus
  58517. +extern "C" {
  58518. +#endif /* __cplusplus */
  58519. +
  58520. +/* includes */
  58521. +#include "ddr2/mvDramIfRegs.h"
  58522. +#include "ddr2/mvDramIfConfig.h"
  58523. +#include "ctrlEnv/mvCtrlEnvLib.h"
  58524. +
  58525. +/* defines */
  58526. +/* DRAM Timing parameters */
  58527. +#define SDRAM_TWR 15 /* ns tWr */
  58528. +#define SDRAM_TRFC_64_512M_AT_200MHZ 70 /* ns tRfc for dens 64-512 @ 200MHz */
  58529. +#define SDRAM_TRFC_64_512M 75 /* ns tRfc for dens 64-512 */
  58530. +#define SDRAM_TRFC_1G 120 /* ns tRfc for dens 1GB */
  58531. +#define SDRAM_TR2R_CYC 1 /* cycle for tR2r */
  58532. +
  58533. +#define CAL_AUTO_DETECT 0 /* Do not force CAS latancy (mvDramIfDetect) */
  58534. +#define ECC_DISABLE 1 /* Force ECC to Disable */
  58535. +#define ECC_ENABLE 0 /* Force ECC to ENABLE */
  58536. +/* typedefs */
  58537. +
  58538. +/* enumeration for memory types */
  58539. +typedef enum _mvMemoryType
  58540. +{
  58541. + MEM_TYPE_SDRAM,
  58542. + MEM_TYPE_DDR1,
  58543. + MEM_TYPE_DDR2
  58544. +}MV_MEMORY_TYPE;
  58545. +
  58546. +/* enumeration for DDR2 supported CAS Latencies */
  58547. +typedef enum _mvDimmDdr2Cas
  58548. +{
  58549. + DDR2_CL_3 = 0x08,
  58550. + DDR2_CL_4 = 0x10,
  58551. + DDR2_CL_5 = 0x20,
  58552. + DDR2_CL_6 = 0x40,
  58553. + DDR2_CL_FAULT
  58554. +} MV_DIMM_DDR2_CAS;
  58555. +
  58556. +
  58557. +typedef struct _mvDramBankInfo
  58558. +{
  58559. + MV_MEMORY_TYPE memoryType; /* DDR1, DDR2 or SDRAM */
  58560. +
  58561. + /* DIMM dimensions */
  58562. + MV_U32 numOfRowAddr;
  58563. + MV_U32 numOfColAddr;
  58564. + MV_U32 dataWidth;
  58565. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  58566. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  58567. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  58568. + MV_U32 burstLengthSupported;
  58569. + MV_U32 numOfBanksOnEachDevice;
  58570. + MV_U32 suportedCasLatencies;
  58571. + MV_U32 refreshInterval;
  58572. +
  58573. + /* DIMM timing parameters */
  58574. + MV_U32 minCycleTimeAtMaxCasLatPs;
  58575. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  58576. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  58577. + MV_U32 minRowPrechargeTime;
  58578. + MV_U32 minRowActiveToRowActive;
  58579. + MV_U32 minRasToCasDelay;
  58580. + MV_U32 minRasPulseWidth;
  58581. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  58582. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  58583. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  58584. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  58585. +
  58586. + /* Parameters calculated from the extracted DIMM information */
  58587. + MV_U32 size;
  58588. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit */
  58589. + MV_U32 numberOfDevices;
  58590. +
  58591. + /* DIMM attributes (MV_TRUE for yes) */
  58592. + MV_BOOL registeredAddrAndControlInputs;
  58593. + MV_BOOL registeredDQMBinputs;
  58594. +
  58595. +}MV_DRAM_BANK_INFO;
  58596. +
  58597. +#include "ddr2/spd/mvSpd.h"
  58598. +
  58599. +/* mvDramIf.h API list */
  58600. +MV_VOID mvDramIfBasicAsmInit(MV_VOID);
  58601. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable);
  58602. +MV_VOID _mvDramIfConfig(int entryNum);
  58603. +
  58604. +MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum);
  58605. +MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum);
  58606. +MV_U32 mvDramIfSizeGet(MV_VOID);
  58607. +MV_U32 mvDramIfCalGet(void);
  58608. +MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold);
  58609. +MV_VOID mvDramIfSelfRefreshSet(void);
  58610. +void mvDramIfShow(void);
  58611. +MV_U32 mvDramIfGetFirstCS(void);
  58612. +MV_U32 mvDramIfGetCSorder(MV_U32 csOrder );
  58613. +MV_U32 mvDramCsSizeGet(MV_U32 csNum);
  58614. +
  58615. +#ifdef __cplusplus
  58616. +}
  58617. +#endif /* __cplusplus */
  58618. +
  58619. +#endif /* __INCmvDramIfh */
  58620. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h
  58621. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  58622. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h 2010-11-09 20:28:10.921244571 +0100
  58623. @@ -0,0 +1,423 @@
  58624. +/*******************************************************************************
  58625. +Copyright (C) Marvell International Ltd. and its affiliates
  58626. +
  58627. +This software file (the "File") is owned and distributed by Marvell
  58628. +International Ltd. and/or its affiliates ("Marvell") under the following
  58629. +alternative licensing terms. Once you have made an election to distribute the
  58630. +File under one of the following license alternatives, please (i) delete this
  58631. +introductory statement regarding license alternatives, (ii) delete the two
  58632. +license alternatives that you have not elected to use and (iii) preserve the
  58633. +Marvell copyright notice above.
  58634. +
  58635. +********************************************************************************
  58636. +Marvell Commercial License Option
  58637. +
  58638. +If you received this File from Marvell and you have entered into a commercial
  58639. +license agreement (a "Commercial License") with Marvell, the File is licensed
  58640. +to you under the terms of the applicable Commercial License.
  58641. +
  58642. +********************************************************************************
  58643. +Marvell GPL License Option
  58644. +
  58645. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58646. +modify this File in accordance with the terms and conditions of the General
  58647. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  58648. +available along with the File in the license.txt file or by writing to the Free
  58649. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  58650. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  58651. +
  58652. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  58653. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  58654. +DISCLAIMED. The GPL License provides additional details about this warranty
  58655. +disclaimer.
  58656. +********************************************************************************
  58657. +Marvell BSD License Option
  58658. +
  58659. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58660. +modify this File under the following licensing terms.
  58661. +Redistribution and use in source and binary forms, with or without modification,
  58662. +are permitted provided that the following conditions are met:
  58663. +
  58664. + * Redistributions of source code must retain the above copyright notice,
  58665. + this list of conditions and the following disclaimer.
  58666. +
  58667. + * Redistributions in binary form must reproduce the above copyright
  58668. + notice, this list of conditions and the following disclaimer in the
  58669. + documentation and/or other materials provided with the distribution.
  58670. +
  58671. + * Neither the name of Marvell nor the names of its contributors may be
  58672. + used to endorse or promote products derived from this software without
  58673. + specific prior written permission.
  58674. +
  58675. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  58676. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  58677. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  58678. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  58679. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  58680. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  58681. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  58682. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  58683. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58684. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  58685. +
  58686. +*******************************************************************************/
  58687. +
  58688. +#ifndef __INCmvDramIfRegsh
  58689. +#define __INCmvDramIfRegsh
  58690. +
  58691. +#ifdef __cplusplus
  58692. +extern "C" {
  58693. +#endif /* __cplusplus */
  58694. +
  58695. +/* DDR SDRAM Controller Address Decode Registers */
  58696. + /* SDRAM CSn Base Address Register (SCBAR) */
  58697. +#define SDRAM_BASE_ADDR_REG(cpu,csNum) (0x1500 + ((csNum) * 8) + ((cpu) * 0x70))
  58698. +#define SCBAR_BASE_OFFS 16
  58699. +#define SCBAR_BASE_MASK (0xffff << SCBAR_BASE_OFFS)
  58700. +#define SCBAR_BASE_ALIGNMENT 0x10000
  58701. +
  58702. +/* SDRAM CSn Size Register (SCSR) */
  58703. +#define SDRAM_SIZE_REG(cpu,csNum) (0x1504 + ((csNum) * 8) + ((cpu) * 0x70))
  58704. +#define SCSR_SIZE_OFFS 24
  58705. +#define SCSR_SIZE_MASK (0xff << SCSR_SIZE_OFFS)
  58706. +#define SCSR_SIZE_ALIGNMENT 0x1000000
  58707. +#define SCSR_WIN_EN BIT0
  58708. +
  58709. +/* configuration register */
  58710. +#define SDRAM_CONFIG_REG (DRAM_BASE + 0x1400)
  58711. +#define SDRAM_REFRESH_OFFS 0
  58712. +#define SDRAM_REFRESH_MAX 0x3FFF
  58713. +#define SDRAM_REFRESH_MASK (SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)
  58714. +#define SDRAM_DWIDTH_OFFS 15
  58715. +#define SDRAM_DWIDTH_MASK (1 << SDRAM_DWIDTH_OFFS)
  58716. +#define SDRAM_DWIDTH_32BIT (0 << SDRAM_DWIDTH_OFFS)
  58717. +#define SDRAM_DWIDTH_64BIT (1 << SDRAM_DWIDTH_OFFS)
  58718. +#define SDRAM_REGISTERED (1 << 17)
  58719. +#define SDRAM_ECC_OFFS 18
  58720. +#define SDRAM_ECC_MASK (1 << SDRAM_ECC_OFFS)
  58721. +#define SDRAM_ECC_DIS (0 << SDRAM_ECC_OFFS)
  58722. +#define SDRAM_ECC_EN (1 << SDRAM_ECC_OFFS)
  58723. +#define SDRAM_IERR_OFFS 19
  58724. +#define SDRAM_IERR_MASK (1 << SDRAM_IERR_OFFS)
  58725. +#define SDRAM_IERR_REPORTE (0 << SDRAM_IERR_OFFS)
  58726. +#define SDRAM_IERR_IGNORE (1 << SDRAM_IERR_OFFS)
  58727. +#define SDRAM_SRMODE_OFFS 24
  58728. +#define SDRAM_SRMODE_MASK (1 << SDRAM_SRMODE_OFFS)
  58729. +#define SDRAM_SRMODE_POWER (0 << SDRAM_SRMODE_OFFS)
  58730. +#define SDRAM_SRMODE_DRAM (1 << SDRAM_SRMODE_OFFS)
  58731. +
  58732. +/* dunit control low register */
  58733. +#define SDRAM_DUNIT_CTRL_REG (DRAM_BASE + 0x1404)
  58734. +#define SDRAM_2T_OFFS 4
  58735. +#define SDRAM_2T_MASK (1 << SDRAM_2T_OFFS)
  58736. +#define SDRAM_2T_MODE (1 << SDRAM_2T_OFFS)
  58737. +
  58738. +#define SDRAM_SRCLK_OFFS 5
  58739. +#define SDRAM_SRCLK_MASK (1 << SDRAM_SRCLK_OFFS)
  58740. +#define SDRAM_SRCLK_KEPT (0 << SDRAM_SRCLK_OFFS)
  58741. +#define SDRAM_SRCLK_GATED (1 << SDRAM_SRCLK_OFFS)
  58742. +#define SDRAM_CTRL_POS_OFFS 6
  58743. +#define SDRAM_CTRL_POS_MASK (1 << SDRAM_CTRL_POS_OFFS)
  58744. +#define SDRAM_CTRL_POS_FALL (0 << SDRAM_CTRL_POS_OFFS)
  58745. +#define SDRAM_CTRL_POS_RISE (1 << SDRAM_CTRL_POS_OFFS)
  58746. +#define SDRAM_CLK1DRV_OFFS 12
  58747. +#define SDRAM_CLK1DRV_MASK (1 << SDRAM_CLK1DRV_OFFS)
  58748. +#define SDRAM_CLK1DRV_HIGH_Z (0 << SDRAM_CLK1DRV_OFFS)
  58749. +#define SDRAM_CLK1DRV_NORMAL (1 << SDRAM_CLK1DRV_OFFS)
  58750. +#define SDRAM_CLK2DRV_OFFS 13
  58751. +#define SDRAM_CLK2DRV_MASK (1 << SDRAM_CLK2DRV_OFFS)
  58752. +#define SDRAM_CLK2DRV_HIGH_Z (0 << SDRAM_CLK2DRV_OFFS)
  58753. +#define SDRAM_CLK2DRV_NORMAL (1 << SDRAM_CLK2DRV_OFFS)
  58754. +#define SDRAM_SB_OUT_DEL_OFFS 20
  58755. +#define SDRAM_SB_OUT_DEL_MAX 0xf
  58756. +#define SDRAM_SB_OUT_MASK (SDRAM_SB_OUT_DEL_MAX<<SDRAM_SB_OUT_DEL_OFFS)
  58757. +#define SDRAM_SB_IN_DEL_OFFS 24
  58758. +#define SDRAM_SB_IN_DEL_MAX 0xf
  58759. +#define SDRAM_SB_IN_MASK (SDRAM_SB_IN_DEL_MAX<<SDRAM_SB_IN_DEL_OFFS)
  58760. +
  58761. +/* dunit control hight register */
  58762. +#define SDRAM_DUNIT_CTRL_HI_REG (DRAM_BASE + 0x1424)
  58763. +#define SDRAM__D2P_OFFS 7
  58764. +#define SDRAM__D2P_EN (1 << SDRAM__D2P_OFFS)
  58765. +#define SDRAM__P2D_OFFS 8
  58766. +#define SDRAM__P2D_EN (1 << SDRAM__P2D_OFFS)
  58767. +#define SDRAM__ADD_HALF_FCC_OFFS 9
  58768. +#define SDRAM__ADD_HALF_FCC_EN (1 << SDRAM__ADD_HALF_FCC_OFFS)
  58769. +#define SDRAM__PUP_ZERO_SKEW_OFFS 10
  58770. +#define SDRAM__PUP_ZERO_SKEW_EN (1 << SDRAM__PUP_ZERO_SKEW_OFFS)
  58771. +#define SDRAM__WR_MESH_DELAY_OFFS 11
  58772. +#define SDRAM__WR_MESH_DELAY_EN (1 << SDRAM__WR_MESH_DELAY_OFFS)
  58773. +
  58774. +/* sdram timing control low register */
  58775. +#define SDRAM_TIMING_CTRL_LOW_REG (DRAM_BASE + 0x1408)
  58776. +#define SDRAM_TRCD_OFFS 4
  58777. +#define SDRAM_TRCD_MASK (0xF << SDRAM_TRCD_OFFS)
  58778. +#define SDRAM_TRP_OFFS 8
  58779. +#define SDRAM_TRP_MASK (0xF << SDRAM_TRP_OFFS)
  58780. +#define SDRAM_TWR_OFFS 12
  58781. +#define SDRAM_TWR_MASK (0xF << SDRAM_TWR_OFFS)
  58782. +#define SDRAM_TWTR_OFFS 16
  58783. +#define SDRAM_TWTR_MASK (0xF << SDRAM_TWTR_OFFS)
  58784. +#define SDRAM_TRAS_OFFS 0
  58785. +#define SDRAM_TRAS_MASK (0xF << SDRAM_TRAS_OFFS)
  58786. +#define SDRAM_EXT_TRAS_OFFS 20
  58787. +#define SDRAM_EXT_TRAS_MASK (0x1 << SDRAM_EXT_TRAS_OFFS)
  58788. +#define SDRAM_TRRD_OFFS 24
  58789. +#define SDRAM_TRRD_MASK (0xF << SDRAM_TRRD_OFFS)
  58790. +#define SDRAM_TRTP_OFFS 28
  58791. +#define SDRAM_TRTP_MASK (0xF << SDRAM_TRTP_OFFS)
  58792. +#define SDRAM_TRTP_DDR1 (0x1 << SDRAM_TRTP_OFFS)
  58793. +
  58794. +/* sdram timing control high register */
  58795. +#define SDRAM_TIMING_CTRL_HIGH_REG (DRAM_BASE + 0x140c)
  58796. +#define SDRAM_TRFC_OFFS 0
  58797. +#define SDRAM_TRFC_MASK (0x3F << SDRAM_TRFC_OFFS)
  58798. +#define SDRAM_TR2R_OFFS 7
  58799. +#define SDRAM_TR2R_MASK (0x3 << SDRAM_TR2R_OFFS)
  58800. +#define SDRAM_TR2W_W2R_OFFS 9
  58801. +#define SDRAM_TR2W_W2R_MASK (0x3 << SDRAM_TR2W_W2R_OFFS)
  58802. +#define SDRAM_TW2W_OFFS 11
  58803. +#define SDRAM_TW2W_MASK (0x3 << SDRAM_TW2W_OFFS)
  58804. +
  58805. +/* sdram DDR2 timing low register (SD2TLR) */
  58806. +#define SDRAM_DDR2_TIMING_LO_REG (DRAM_BASE + 0x1428)
  58807. +#define SD2TLR_TODT_ON_RD_OFFS 4
  58808. +#define SD2TLR_TODT_ON_RD_MASK (0xF << SD2TLR_TODT_ON_RD_OFFS)
  58809. +#define SD2TLR_TODT_OFF_RD_OFFS 8
  58810. +#define SD2TLR_TODT_OFF_RD_MASK (0xF << SD2TLR_TODT_OFF_RD_OFFS)
  58811. +#define SD2TLR_TODT_ON_CTRL_RD_OFFS 12
  58812. +#define SD2TLR_TODT_ON_CTRL_RD_MASK (0xF << SD2TLR_TODT_ON_CTRL_RD_OFFS)
  58813. +#define SD2TLR_TODT_OFF_CTRL_RD_OFFS 16
  58814. +#define SD2TLR_TODT_OFF_CTRL_RD_MASK (0xF << SD2TLR_TODT_OFF_CTRL_RD_OFFS)
  58815. +
  58816. +/* sdram DDR2 timing high register (SD2TLR) */
  58817. +#define SDRAM_DDR2_TIMING_HI_REG (DRAM_BASE + 0x147C)
  58818. +#define SD2THR_TODT_ON_WR_OFFS 0
  58819. +#define SD2THR_TODT_ON_WR_MASK (0xF << SD2THR_TODT_ON_WR_OFFS)
  58820. +#define SD2THR_TODT_OFF_WR_OFFS 4
  58821. +#define SD2THR_TODT_OFF_WR_MASK (0xF << SD2THR_TODT_OFF_WR_OFFS)
  58822. +#define SD2THR_TODT_ON_CTRL_WR_OFFS 8
  58823. +#define SD2THR_TODT_ON_CTRL_WR_MASK (0xF << SD2THR_TODT_ON_CTRL_WR_OFFS)
  58824. +#define SD2THR_TODT_OFF_CTRL_WR_OFFS 12
  58825. +#define SD2THR_TODT_OFF_CTRL_WR_MASK (0xF << SD2THR_TODT_OFF_CTRL_WR_OFFS)
  58826. +
  58827. +/* address control register */
  58828. +#define SDRAM_ADDR_CTRL_REG (DRAM_BASE + 0x1410)
  58829. +#define SDRAM_ADDRSEL_OFFS(cs) (4 * (cs))
  58830. +#define SDRAM_ADDRSEL_MASK(cs) (0x3 << SDRAM_ADDRSEL_OFFS(cs))
  58831. +#define SDRAM_ADDRSEL_X8(cs) (0x0 << SDRAM_ADDRSEL_OFFS(cs))
  58832. +#define SDRAM_ADDRSEL_X16(cs) (0x1 << SDRAM_ADDRSEL_OFFS(cs))
  58833. +#define SDRAM_DSIZE_OFFS(cs) (2 + 4 * (cs))
  58834. +#define SDRAM_DSIZE_MASK(cs) (0x3 << SDRAM_DSIZE_OFFS(cs))
  58835. +#define SDRAM_DSIZE_256Mb(cs) (0x1 << SDRAM_DSIZE_OFFS(cs))
  58836. +#define SDRAM_DSIZE_512Mb(cs) (0x2 << SDRAM_DSIZE_OFFS(cs))
  58837. +#define SDRAM_DSIZE_1Gb(cs) (0x3 << SDRAM_DSIZE_OFFS(cs))
  58838. +#define SDRAM_DSIZE_2Gb(cs) (0x0 << SDRAM_DSIZE_OFFS(cs))
  58839. +
  58840. +/* SDRAM Open Pages Control registers */
  58841. +#define SDRAM_OPEN_PAGE_CTRL_REG (DRAM_BASE + 0x1414)
  58842. +#define SDRAM_OPEN_PAGE_EN (0 << 0)
  58843. +#define SDRAM_OPEN_PAGE_DIS (1 << 0)
  58844. +
  58845. +/* sdram opertion register */
  58846. +#define SDRAM_OPERATION_REG (DRAM_BASE + 0x1418)
  58847. +#define SDRAM_CMD_OFFS 0
  58848. +#define SDRAM_CMD_MASK (0xF << SDRAM_CMD_OFFS)
  58849. +#define SDRAM_CMD_NORMAL (0x0 << SDRAM_CMD_OFFS)
  58850. +#define SDRAM_CMD_PRECHARGE_ALL (0x1 << SDRAM_CMD_OFFS)
  58851. +#define SDRAM_CMD_REFRESH_ALL (0x2 << SDRAM_CMD_OFFS)
  58852. +#define SDRAM_CMD_REG_SET_CMD (0x3 << SDRAM_CMD_OFFS)
  58853. +#define SDRAM_CMD_EXT_MODE_SET (0x4 << SDRAM_CMD_OFFS)
  58854. +#define SDRAM_CMD_NOP (0x5 << SDRAM_CMD_OFFS)
  58855. +#define SDRAM_CMD_SLF_RFRSH (0x7 << SDRAM_CMD_OFFS)
  58856. +#define SDRAM_CMD_EMRS2_CMD (0x8 << SDRAM_CMD_OFFS)
  58857. +#define SDRAM_CMD_EMRS3_CMD (0x9 << SDRAM_CMD_OFFS)
  58858. +
  58859. +/* sdram mode register */
  58860. +#define SDRAM_MODE_REG (DRAM_BASE + 0x141c)
  58861. +#define SDRAM_BURST_LEN_OFFS 0
  58862. +#define SDRAM_BURST_LEN_MASK (0x7 << SDRAM_BURST_LEN_OFFS)
  58863. +#define SDRAM_BURST_LEN_4 (0x2 << SDRAM_BURST_LEN_OFFS)
  58864. +#define SDRAM_CL_OFFS 4
  58865. +#define SDRAM_CL_MASK (0x7 << SDRAM_CL_OFFS)
  58866. +#define SDRAM_DDR2_CL_3 (0x3 << SDRAM_CL_OFFS)
  58867. +#define SDRAM_DDR2_CL_4 (0x4 << SDRAM_CL_OFFS)
  58868. +#define SDRAM_DDR2_CL_5 (0x5 << SDRAM_CL_OFFS)
  58869. +#define SDRAM_DDR2_CL_6 (0x6 << SDRAM_CL_OFFS)
  58870. +
  58871. +#define SDRAM_TM_OFFS 7
  58872. +#define SDRAM_TM_MASK (1 << SDRAM_TM_OFFS)
  58873. +#define SDRAM_TM_NORMAL (0 << SDRAM_TM_OFFS)
  58874. +#define SDRAM_TM_TEST_MODE (1 << SDRAM_TM_OFFS)
  58875. +#define SDRAM_DLL_OFFS 8
  58876. +#define SDRAM_DLL_MASK (1 << SDRAM_DLL_OFFS)
  58877. +#define SDRAM_DLL_NORMAL (0 << SDRAM_DLL_OFFS)
  58878. +#define SDRAM_DLL_RESET (1 << SDRAM_DLL_OFFS)
  58879. +#define SDRAM_WR_OFFS 9
  58880. +#define SDRAM_WR_MAX 7
  58881. +#define SDRAM_WR_MASK (SDRAM_WR_MAX << SDRAM_WR_OFFS)
  58882. +#define SDRAM_WR_2_CYC (1 << SDRAM_WR_OFFS)
  58883. +#define SDRAM_WR_3_CYC (2 << SDRAM_WR_OFFS)
  58884. +#define SDRAM_WR_4_CYC (3 << SDRAM_WR_OFFS)
  58885. +#define SDRAM_WR_5_CYC (4 << SDRAM_WR_OFFS)
  58886. +#define SDRAM_WR_6_CYC (5 << SDRAM_WR_OFFS)
  58887. +#define SDRAM_PD_OFFS 12
  58888. +#define SDRAM_PD_MASK (1 << SDRAM_PD_OFFS)
  58889. +#define SDRAM_PD_FAST_EXIT (0 << SDRAM_PD_OFFS)
  58890. +#define SDRAM_PD_SLOW_EXIT (1 << SDRAM_PD_OFFS)
  58891. +
  58892. +/* DDR SDRAM Extended Mode register (DSEMR) */
  58893. +#define SDRAM_EXTENDED_MODE_REG (DRAM_BASE + 0x1420)
  58894. +#define DSEMR_DLL_ENABLE 0
  58895. +#define DSEMR_DLL_DISABLE 1
  58896. +#define DSEMR_DS_OFFS 1
  58897. +#define DSEMR_DS_MASK (1 << DSEMR_DS_OFFS)
  58898. +#define DSEMR_DS_NORMAL (0 << DSEMR_DS_OFFS)
  58899. +#define DSEMR_DS_REDUCED (1 << DSEMR_DS_OFFS)
  58900. +#define DSEMR_QOFF_OUTPUT_BUFF_EN (0 << 12)
  58901. +#define DSEMR_RTT0_OFFS 2
  58902. +#define DSEMR_RTT1_OFFS 6
  58903. +#define DSEMR_RTT_ODT_DISABLE ((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  58904. +#define DSEMR_RTT_ODT_75_OHM ((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  58905. +#define DSEMR_RTT_ODT_150_OHM ((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
  58906. +#define DSEMR_RTT_ODT_50_OHM ((1 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
  58907. +#define DSEMR_DQS_OFFS 10
  58908. +#define DSEMR_DQS_MASK (1 << DSEMR_DQS_OFFS)
  58909. +#define DSEMR_DQS_DIFFERENTIAL (0 << DSEMR_DQS_OFFS)
  58910. +#define DSEMR_DQS_SINGLE_ENDED (1 << DSEMR_DQS_OFFS)
  58911. +#define DSEMR_RDQS_ENABLE (1 << 11)
  58912. +#define DSEMR_QOFF_OUTPUT_BUFF_EN (0 << 12)
  58913. +#define DSEMR_QOFF_OUTPUT_BUFF_DIS (1 << 12)
  58914. +
  58915. +/* DDR SDRAM Operation Control Register */
  58916. +#define SDRAM_OPERATION_CTRL_REG (DRAM_BASE + 0x142c)
  58917. +
  58918. +/* Dunit FTDLL Configuration Register */
  58919. +#define SDRAM_FTDLL_CONFIG_LEFT_REG (DRAM_BASE + 0x1484)
  58920. +#define SDRAM_FTDLL_CONFIG_RIGHT_REG (DRAM_BASE + 0x161C)
  58921. +#define SDRAM_FTDLL_CONFIG_UP_REG (DRAM_BASE + 0x1620)
  58922. +
  58923. +/* Pads Calibration register */
  58924. +#define SDRAM_ADDR_CTRL_PADS_CAL_REG (DRAM_BASE + 0x14c0)
  58925. +#define SDRAM_DATA_PADS_CAL_REG (DRAM_BASE + 0x14c4)
  58926. +#define SDRAM_DRVN_OFFS 0
  58927. +#define SDRAM_DRVN_MASK (0x3F << SDRAM_DRVN_OFFS)
  58928. +#define SDRAM_DRVP_OFFS 6
  58929. +#define SDRAM_DRVP_MASK (0x3F << SDRAM_DRVP_OFFS)
  58930. +#define SDRAM_PRE_DRIVER_STRENGTH_OFFS 12
  58931. +#define SDRAM_PRE_DRIVER_STRENGTH_MASK (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  58932. +#define SDRAM_TUNE_EN BIT16
  58933. +#define SDRAM_LOCKN_OFFS 17
  58934. +#define SDRAM_LOCKN_MAKS (0x3F << SDRAM_LOCKN_OFFS)
  58935. +#define SDRAM_LOCKP_OFFS 23
  58936. +#define SDRAM_LOCKP_MAKS (0x3F << SDRAM_LOCKP_OFFS)
  58937. +#define SDRAM_WR_EN (1 << 31)
  58938. +
  58939. +/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */
  58940. +#define DDR2_SDRAM_ODT_CTRL_LOW_REG (DRAM_BASE + 0x1494)
  58941. +#define DSOCLR_ODT_RD_OFFS(odtNum) (odtNum * 4)
  58942. +#define DSOCLR_ODT_RD_MASK(odtNum) (0xf << DSOCLR_ODT_RD_OFFS(odtNum))
  58943. +#define DSOCLR_ODT_RD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))
  58944. +#define DSOCLR_ODT_WR_OFFS(odtNum) (16 + (odtNum * 4))
  58945. +#define DSOCLR_ODT_WR_MASK(odtNum) (0xf << DSOCLR_ODT_WR_OFFS(odtNum))
  58946. +#define DSOCLR_ODT_WR(odtNum, bank) ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))
  58947. +
  58948. +/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */
  58949. +#define DDR2_SDRAM_ODT_CTRL_HIGH_REG (DRAM_BASE + 0x1498)
  58950. +/* Optional control values to DSOCHR_ODT_EN macro */
  58951. +#define DDR2_ODT_CTRL_DUNIT 0
  58952. +#define DDR2_ODT_CTRL_NEVER 1
  58953. +#define DDR2_ODT_CTRL_ALWAYS 3
  58954. +#define DSOCHR_ODT_EN_OFFS(odtNum) (odtNum * 2)
  58955. +#define DSOCHR_ODT_EN_MASK(odtNum) (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))
  58956. +#define DSOCHR_ODT_EN(odtNum, ctrl) (ctrl << DSOCHR_ODT_EN_OFFS(odtNum))
  58957. +
  58958. +/* DDR2 Dunit ODT Control Register (DDOCR)*/
  58959. +#define DDR2_DUNIT_ODT_CONTROL_REG (DRAM_BASE + 0x149c)
  58960. +#define DDOCR_ODT_RD_OFFS 0
  58961. +#define DDOCR_ODT_RD_MASK (0xf << DDOCR_ODT_RD_OFFS)
  58962. +#define DDOCR_ODT_RD(bank) ((1 << bank) << DDOCR_ODT_RD_OFFS)
  58963. +#define DDOCR_ODT_WR_OFFS 4
  58964. +#define DDOCR_ODT_WR_MASK (0xf << DDOCR_ODT_WR_OFFS)
  58965. +#define DDOCR_ODT_WR(bank) ((1 << bank) << DDOCR_ODT_WR_OFFS)
  58966. +#define DSOCR_ODT_EN_OFFS 8
  58967. +#define DSOCR_ODT_EN_MASK (0x3 << DSOCR_ODT_EN_OFFS)
  58968. +/* For ctrl parameters see DDR2 SDRAM ODT Control (High) Register (0x1498) above. */
  58969. +#define DSOCR_ODT_EN(ctrl) (ctrl << DSOCR_ODT_EN_OFFS)
  58970. +#define DSOCR_ODT_SEL_DISABLE 0
  58971. +#define DSOCR_ODT_SEL_75_OHM 2
  58972. +#define DSOCR_ODT_SEL_150_OHM 1
  58973. +#define DSOCR_ODT_SEL_50_OHM 3
  58974. +#define DSOCR_DQ_ODT_SEL_OFFS 10
  58975. +#define DSOCR_DQ_ODT_SEL_MASK (0x3 << DSOCR_DQ_ODT_SEL_OFFS)
  58976. +#define DSOCR_DQ_ODT_SEL(odtSel) (odtSel << DSOCR_DQ_ODT_SEL_OFFS)
  58977. +#define DSOCR_ST_ODT_SEL_OFFS 12
  58978. +#define DSOCR_ST_ODT_SEL_MASK (0x3 << DSOCR_ST_ODT_SEL_OFFS)
  58979. +#define DSOCR_ST_ODT_SEL(odtSel) (odtSel << DSOCR_ST_ODT_SEL_OFFS)
  58980. +#define DSOCR_ST_ODT_EN (1 << 14)
  58981. +
  58982. +/* DDR SDRAM Initialization Control Register (DSICR) */
  58983. +#define DDR_SDRAM_INIT_CTRL_REG (DRAM_BASE + 0x1480)
  58984. +#define DSICR_INIT_EN (1 << 0)
  58985. +#define DSICR_T200_SET (1 << 8)
  58986. +
  58987. +/* sdram extended mode2 register (SEM2R) */
  58988. +#define SDRAM_EXTENDED_MODE2_REG (DRAM_BASE + 0x148C)
  58989. +#define SEM2R_EMRS2_DDR2_OFFS 0
  58990. +#define SEM2R_EMRS2_DDR2_MASK (0x7FFF << SEM2R_EMRS2_DDR2_OFFS)
  58991. +
  58992. +/* sdram extended mode3 register (SEM3R) */
  58993. +#define SDRAM_EXTENDED_MODE3_REG (DRAM_BASE + 0x1490)
  58994. +#define SEM3R_EMRS3_DDR2_OFFS 0
  58995. +#define SEM3R_EMRS3_DDR2_MASK (0x7FFF << SEM3R_EMRS3_DDR2_OFFS)
  58996. +
  58997. +/* sdram error registers */
  58998. +#define SDRAM_ERROR_CAUSE_REG (DRAM_BASE + 0x14d0)
  58999. +#define SDRAM_ERROR_MASK_REG (DRAM_BASE + 0x14d4)
  59000. +#define SDRAM_ERROR_DATA_LOW_REG (DRAM_BASE + 0x1444)
  59001. +#define SDRAM_ERROR_DATA_HIGH_REG (DRAM_BASE + 0x1440)
  59002. +#define SDRAM_ERROR_ADDR_REG (DRAM_BASE + 0x1450)
  59003. +#define SDRAM_ERROR_ECC_REG (DRAM_BASE + 0x1448)
  59004. +#define SDRAM_CALC_ECC_REG (DRAM_BASE + 0x144c)
  59005. +#define SDRAM_ECC_CONTROL_REG (DRAM_BASE + 0x1454)
  59006. +#define SDRAM_SINGLE_BIT_ERR_CNTR_REG (DRAM_BASE + 0x1458)
  59007. +#define SDRAM_DOUBLE_BIT_ERR_CNTR_REG (DRAM_BASE + 0x145c)
  59008. +
  59009. +/* SDRAM Error Cause Register (SECR) */
  59010. +#define SECR_SINGLE_BIT_ERR BIT0
  59011. +#define SECR_DOUBLE_BIT_ERR BIT1
  59012. +#define SECR_DATA_PATH_PARITY_ERR BIT2
  59013. +/* SDRAM Error Address Register (SEAR) */
  59014. +#define SEAR_ERR_TYPE_OFFS 0
  59015. +#define SEAR_ERR_TYPE_MASK (1 << SEAR_ERR_TYPE_OFFS)
  59016. +#define SEAR_ERR_TYPE_SINGLE 0
  59017. +#define SEAR_ERR_TYPE_DOUBLE (1 << SEAR_ERR_TYPE_OFFS)
  59018. +#define SEAR_ERR_CS_OFFS 1
  59019. +#define SEAR_ERR_CS_MASK (3 << SEAR_ERR_CS_OFFS)
  59020. +#define SEAR_ERR_CS(csNum) (csNum << SEAR_ERR_CS_OFFS)
  59021. +#define SEAR_ERR_ADDR_OFFS 3
  59022. +#define SEAR_ERR_ADDR_MASK (0x1FFFFFFF << SEAR_ERR_ADDR_OFFS)
  59023. +
  59024. +/* SDRAM ECC Control Register (SECR) */
  59025. +#define SECR_FORCEECC_OFFS 0
  59026. +#define SECR_FORCEECC_MASK (0xFF << SECR_FORCEECC_OFFS)
  59027. +#define SECR_FORCEEN_OFFS 8
  59028. +#define SECR_FORCEEN_MASK (1 << SECR_FORCEEN_OFFS)
  59029. +#define SECR_ECC_CALC_MASK (0 << SECR_FORCEEN_OFFS)
  59030. +#define SECR_ECC_USER_MASK (1 << SECR_FORCEEN_OFFS)
  59031. +#define SECR_PERRPROP_EN BIT9
  59032. +#define SECR_CNTMODE_OFFS 10
  59033. +#define SECR_CNTMODE_MASK (1 << SECR_CNTMODE_OFFS)
  59034. +#define SECR_ALL_IN_CS0 (0 << SECR_CNTMODE_OFFS)
  59035. +#define SECR_NORMAL_COUNTER (1 << SECR_CNTMODE_OFFS)
  59036. +#define SECR_THRECC_OFFS 16
  59037. +#define SECR_THRECC_MAX 0xFF
  59038. +#define SECR_THRECC_MASK (SECR_THRECC_MAX << SECR_THRECC_OFFS)
  59039. +#define SECR_THRECC(threshold) (threshold << SECR_THRECC_OFFS)
  59040. +
  59041. +
  59042. +#ifdef __cplusplus
  59043. +}
  59044. +#endif /* __cplusplus */
  59045. +
  59046. +#endif /* __INCmvDramIfRegsh */
  59047. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h
  59048. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h 1970-01-01 01:00:00.000000000 +0100
  59049. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h 2010-11-09 20:28:10.962495352 +0100
  59050. @@ -0,0 +1,179 @@
  59051. +/*******************************************************************************
  59052. +Copyright (C) Marvell International Ltd. and its affiliates
  59053. +
  59054. +This software file (the "File") is owned and distributed by Marvell
  59055. +International Ltd. and/or its affiliates ("Marvell") under the following
  59056. +alternative licensing terms. Once you have made an election to distribute the
  59057. +File under one of the following license alternatives, please (i) delete this
  59058. +introductory statement regarding license alternatives, (ii) delete the two
  59059. +license alternatives that you have not elected to use and (iii) preserve the
  59060. +Marvell copyright notice above.
  59061. +
  59062. +********************************************************************************
  59063. +Marvell Commercial License Option
  59064. +
  59065. +If you received this File from Marvell and you have entered into a commercial
  59066. +license agreement (a "Commercial License") with Marvell, the File is licensed
  59067. +to you under the terms of the applicable Commercial License.
  59068. +
  59069. +********************************************************************************
  59070. +Marvell GPL License Option
  59071. +
  59072. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59073. +modify this File in accordance with the terms and conditions of the General
  59074. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  59075. +available along with the File in the license.txt file or by writing to the Free
  59076. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  59077. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  59078. +
  59079. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  59080. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  59081. +DISCLAIMED. The GPL License provides additional details about this warranty
  59082. +disclaimer.
  59083. +********************************************************************************
  59084. +Marvell BSD License Option
  59085. +
  59086. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59087. +modify this File under the following licensing terms.
  59088. +Redistribution and use in source and binary forms, with or without modification,
  59089. +are permitted provided that the following conditions are met:
  59090. +
  59091. + * Redistributions of source code must retain the above copyright notice,
  59092. + this list of conditions and the following disclaimer.
  59093. +
  59094. + * Redistributions in binary form must reproduce the above copyright
  59095. + notice, this list of conditions and the following disclaimer in the
  59096. + documentation and/or other materials provided with the distribution.
  59097. +
  59098. + * Neither the name of Marvell nor the names of its contributors may be
  59099. + used to endorse or promote products derived from this software without
  59100. + specific prior written permission.
  59101. +
  59102. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  59103. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  59104. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  59105. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  59106. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  59107. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  59108. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  59109. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  59110. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  59111. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59112. +
  59113. +*******************************************************************************/
  59114. +
  59115. +
  59116. +#ifndef __INCmvDramIfStaticInith
  59117. +#define __INCmvDramIfStaticInith
  59118. +
  59119. +#ifdef MV_STATIC_DRAM_ON_BOARD
  59120. +#define STATIC_DRAM_BANK_1
  59121. +#undef STATIC_DRAM_BANK_2
  59122. +#undef STATIC_DRAM_BANK_3
  59123. +#undef STATIC_DRAM_BANK_4
  59124. +
  59125. +
  59126. +#ifdef MV_DIMM_TS256MLQ72V5U
  59127. +#define STATIC_DRAM_BANK_2
  59128. +#define STATIC_DRAM_BANK_3
  59129. +#undef STATIC_DRAM_BANK_4
  59130. +
  59131. +#define STATIC_SDRAM_CONFIG_REG 0x4724481A /* offset 0x1400 - DMA reg-0xf1000814 */
  59132. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0x37707450 /* offset 0x1404 - DMA reg-0xf100081c */
  59133. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11A13330 /* offset 0x1408 - DMA reg-0xf1000824 */
  59134. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000601 /* offset 0x140c - DMA reg-0xf1000828 */
  59135. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00001CB2 /* offset 0x1410 - DMA reg-0xf1000820 */
  59136. +#define STATIC_SDRAM_MODE_REG 0x00000642 /* offset 0x141c - DMA reg-0xf1000818 */
  59137. +#define STATIC_SDRAM_ODT_CTRL_LOW 0x030C030C /* 0x1494 */
  59138. +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000 /* 0x1498 */
  59139. +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000740F /* 0x149c */
  59140. +#define STATIC_SDRAM_EXT_MODE 0x00000404 /* 0x1420 */
  59141. +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00074410 /* 0x1428 */
  59142. +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00007441 /* 0x147C */
  59143. +
  59144. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x3FFF /* size bank0 dimm0 - DMA reg-0xf1000810 */
  59145. +#define STATIC_SDRAM_RANK1_SIZE_DIMM0 0x3FFF /* size bank1 dimm0 */
  59146. +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x3FFF /* size bank0 dimm1 */
  59147. +#define STATIC_SDRAM_RANK1_SIZE_DIMM1 0x0 /* size bank1 dimm1 */
  59148. +
  59149. +#endif /* TS256MLQ72V5U */
  59150. +
  59151. +
  59152. +#ifdef MV_MT9VDDT3272AG
  59153. +/* one DIMM 256M */
  59154. +#define STATIC_SDRAM_CONFIG_REG 0x5820040d /* offset 0x1400 - DMA reg-0xf1000814 */
  59155. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xC4000540 /* offset 0x1404 - DMA reg-0xf100081c */
  59156. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x01602220 /* offset 0x1408 - DMA reg-0xf1000824 */
  59157. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x0000000b /* offset 0x140c - DMA reg-0xf1000828 */
  59158. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000012 /* offset 0x1410 - DMA reg-0xf1000820 */
  59159. +#define STATIC_SDRAM_MODE_REG 0x00000062 /* offset 0x141c - DMA reg-0xf1000818 */
  59160. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x0fff /* size bank0 dimm0 - DMA reg-0xf1000810 */
  59161. +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x0 /* size bank0 dimm1 */
  59162. +
  59163. +#endif /* MV_MT9VDDT3272AG */
  59164. +
  59165. +
  59166. +
  59167. +#ifdef MV_D27RB12P
  59168. +/*
  59169. +Two DIMM 512M + ECC enabled, Registered DIMM CAS Latency 2.5
  59170. +*/
  59171. +
  59172. +#define STATIC_SDRAM_CONFIG_REG 0x6826081E /* offset 0x1400 - DMA reg-0xf1000814 */
  59173. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xC5000540 /* offset 0x1404 - DMA reg-0xf100081c */
  59174. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x01501220 /* offset 0x1408 - DMA reg-0xf1000824 */
  59175. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000009 /* offset 0x140c - DMA reg-0xf1000828 */
  59176. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000012 /* offset 0x1410 - DMA reg-0xf1000820 */
  59177. +#define STATIC_SDRAM_MODE_REG 0x00000062 /* offset 0x141c - DMA reg-0xf1000818 */
  59178. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x0FFF /* size bank0 dimm0 - DMA reg-0xf1000810 */
  59179. +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x0FFF /* size bank0 dimm1 */
  59180. +
  59181. +#define STATIC_DRAM_BANK_2
  59182. +
  59183. +#define STATIC_DRAM_BANK_3
  59184. +#define STATIC_DRAM_BANK_4
  59185. +
  59186. +#endif /* mv_D27RB12P */
  59187. +
  59188. +#ifdef RD_MV645XX
  59189. +
  59190. +#define STATIC_MEM_TYPE MEM_TYPE_DDR2
  59191. +#define STATIC_DIMM_INFO_BANK0_SIZE 256
  59192. +/* DDR2 boards 256 MB*/
  59193. +
  59194. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x00000fff /* size bank0 dimm0 - DMA reg-0xf1000810 */
  59195. +#define STATIC_SDRAM_CONFIG_REG 0x07190618
  59196. +#define STATIC_SDRAM_MODE_REG 0x00000432
  59197. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xf4a03440
  59198. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000022
  59199. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11712220
  59200. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000504
  59201. +#define STATIC_SDRAM_ODT_CTRL_LOW 0x84210000
  59202. +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000
  59203. +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000780f
  59204. +#define STATIC_SDRAM_EXT_MODE 0x00000440
  59205. +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00063300
  59206. +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00006330
  59207. +#endif /* RD_MV645XX */
  59208. +
  59209. +#if MV_DIMM_M3783354CZ3_CE6
  59210. +
  59211. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x00000FFF /* 0x2010 size bank0 dimm0 - DMA reg-0xf1000810 */
  59212. +#define STATIC_SDRAM_CONFIG_REG 0x07190618 /* 0x1400 */
  59213. +#define STATIC_SDRAM_MODE_REG 0x00000432 /* 0x141c */
  59214. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xf4a03440 /* 0x1404 */
  59215. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000022 /* 0x1410 */
  59216. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11712220 /* 0x1408 */
  59217. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000504 /* 0x140c */
  59218. +#define STATIC_SDRAM_ODT_CTRL_LOW 0x84210000 /* 0x1494 */
  59219. +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000 /* 0x1498 */
  59220. +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000780f /* 0x149c */
  59221. +#define STATIC_SDRAM_EXT_MODE 0x00000440 /* 0x1420 */
  59222. +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00063300 /* 0x1428 */
  59223. +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00006330 /* 0x147C */
  59224. +
  59225. +#endif /* MV_DIMM_M3783354CZ3_CE6 */
  59226. +
  59227. +#endif /* MV_STATIC_DRAM_ON_BOARD */
  59228. +#endif /* __INCmvDramIfStaticInith */
  59229. +
  59230. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c
  59231. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c 1970-01-01 01:00:00.000000000 +0100
  59232. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c 2010-11-09 20:28:11.002495540 +0100
  59233. @@ -0,0 +1,1474 @@
  59234. +/*******************************************************************************
  59235. +Copyright (C) Marvell International Ltd. and its affiliates
  59236. +
  59237. +This software file (the "File") is owned and distributed by Marvell
  59238. +International Ltd. and/or its affiliates ("Marvell") under the following
  59239. +alternative licensing terms. Once you have made an election to distribute the
  59240. +File under one of the following license alternatives, please (i) delete this
  59241. +introductory statement regarding license alternatives, (ii) delete the two
  59242. +license alternatives that you have not elected to use and (iii) preserve the
  59243. +Marvell copyright notice above.
  59244. +
  59245. +********************************************************************************
  59246. +Marvell Commercial License Option
  59247. +
  59248. +If you received this File from Marvell and you have entered into a commercial
  59249. +license agreement (a "Commercial License") with Marvell, the File is licensed
  59250. +to you under the terms of the applicable Commercial License.
  59251. +
  59252. +********************************************************************************
  59253. +Marvell GPL License Option
  59254. +
  59255. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59256. +modify this File in accordance with the terms and conditions of the General
  59257. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  59258. +available along with the File in the license.txt file or by writing to the Free
  59259. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  59260. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  59261. +
  59262. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  59263. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  59264. +DISCLAIMED. The GPL License provides additional details about this warranty
  59265. +disclaimer.
  59266. +********************************************************************************
  59267. +Marvell BSD License Option
  59268. +
  59269. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59270. +modify this File under the following licensing terms.
  59271. +Redistribution and use in source and binary forms, with or without modification,
  59272. +are permitted provided that the following conditions are met:
  59273. +
  59274. + * Redistributions of source code must retain the above copyright notice,
  59275. + this list of conditions and the following disclaimer.
  59276. +
  59277. + * Redistributions in binary form must reproduce the above copyright
  59278. + notice, this list of conditions and the following disclaimer in the
  59279. + documentation and/or other materials provided with the distribution.
  59280. +
  59281. + * Neither the name of Marvell nor the names of its contributors may be
  59282. + used to endorse or promote products derived from this software without
  59283. + specific prior written permission.
  59284. +
  59285. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  59286. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  59287. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  59288. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  59289. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  59290. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  59291. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  59292. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  59293. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  59294. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59295. +
  59296. +*******************************************************************************/
  59297. +
  59298. +#include "ddr2/spd/mvSpd.h"
  59299. +#include "boardEnv/mvBoardEnvLib.h"
  59300. +
  59301. +/* #define MV_DEBUG */
  59302. +#ifdef MV_DEBUG
  59303. +#define DB(x) x
  59304. +#else
  59305. +#define DB(x)
  59306. +#endif
  59307. +
  59308. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  59309. + MV_DRAM_BANK_INFO *pBankInfo);
  59310. +static MV_U32 cas2ps(MV_U8 spd_byte);
  59311. +/*******************************************************************************
  59312. +* mvDramBankGet - Get the DRAM bank paramters.
  59313. +*
  59314. +* DESCRIPTION:
  59315. +* This function retrieves DRAM bank parameters as described in
  59316. +* DRAM_BANK_INFO struct to the controller DRAM unit. In case the board
  59317. +* has its DRAM on DIMMs it will use its EEPROM to extract SPD data
  59318. +* from it. Otherwise, if the DRAM is soldered on board, the function
  59319. +* should insert its bank information into MV_DRAM_BANK_INFO struct.
  59320. +*
  59321. +* INPUT:
  59322. +* bankNum - Board DRAM bank number.
  59323. +*
  59324. +* OUTPUT:
  59325. +* pBankInfo - DRAM bank information struct.
  59326. +*
  59327. +* RETURN:
  59328. +* MV_FAIL - Bank parameters could not be read.
  59329. +*
  59330. +*******************************************************************************/
  59331. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
  59332. +{
  59333. + MV_DIMM_INFO dimmInfo;
  59334. +
  59335. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
  59336. + /* zero pBankInfo structure */
  59337. +
  59338. + if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
  59339. + {
  59340. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  59341. + return MV_BAD_PARAM;
  59342. + }
  59343. + memset(pBankInfo, 0, sizeof(*pBankInfo));
  59344. +
  59345. + if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
  59346. + {
  59347. + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
  59348. + return MV_FAIL;
  59349. + }
  59350. + if ((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
  59351. + {
  59352. + DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
  59353. + return MV_FAIL;
  59354. + }
  59355. + /* convert Dimm info to Bank info */
  59356. + cpyDimm2BankInfo(&dimmInfo, pBankInfo);
  59357. + return MV_OK;
  59358. +}
  59359. +
  59360. +/*******************************************************************************
  59361. +* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
  59362. +*
  59363. +* DESCRIPTION:
  59364. +* Convert a Dimm info struct into a bank info struct.
  59365. +*
  59366. +* INPUT:
  59367. +* pDimmInfo - DIMM information structure.
  59368. +*
  59369. +* OUTPUT:
  59370. +* pBankInfo - DRAM bank information struct.
  59371. +*
  59372. +* RETURN:
  59373. +* None.
  59374. +*
  59375. +*******************************************************************************/
  59376. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  59377. + MV_DRAM_BANK_INFO *pBankInfo)
  59378. +{
  59379. + pBankInfo->memoryType = pDimmInfo->memoryType;
  59380. +
  59381. + /* DIMM dimensions */
  59382. + pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
  59383. + pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
  59384. + pBankInfo->dataWidth = pDimmInfo->dataWidth;
  59385. + pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
  59386. + pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
  59387. + pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
  59388. + pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
  59389. + pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
  59390. + pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
  59391. +
  59392. + /* DIMM timing parameters */
  59393. + pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
  59394. + pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  59395. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
  59396. + pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  59397. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
  59398. +
  59399. + pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
  59400. + pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
  59401. + pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
  59402. + pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
  59403. + pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
  59404. + pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
  59405. + pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
  59406. + pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
  59407. +
  59408. + /* Parameters calculated from the extracted DIMM information */
  59409. + pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
  59410. + pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
  59411. + pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
  59412. + pDimmInfo->numOfModuleBanks;
  59413. +
  59414. + /* DIMM attributes (MV_TRUE for yes) */
  59415. +
  59416. + if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
  59417. + (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
  59418. + {
  59419. + if (pDimmInfo->dimmAttributes & BIT1)
  59420. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  59421. + else
  59422. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  59423. + }
  59424. + else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
  59425. + {
  59426. + if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
  59427. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  59428. + else
  59429. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  59430. + }
  59431. +
  59432. + return;
  59433. +}
  59434. +/*******************************************************************************
  59435. +* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
  59436. +*
  59437. +* DESCRIPTION:
  59438. +* Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
  59439. +*
  59440. +* INPUT:
  59441. +* None.
  59442. +*
  59443. +* OUTPUT:
  59444. +* None.
  59445. +*
  59446. +* RETURN:
  59447. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  59448. +*
  59449. +*******************************************************************************/
  59450. +MV_STATUS dimmSpdCpy(MV_VOID)
  59451. +{
  59452. + MV_U32 i;
  59453. + MV_U32 spdChecksum;
  59454. +
  59455. + MV_TWSI_SLAVE twsiSlave;
  59456. + MV_U8 data[SPD_SIZE];
  59457. +
  59458. + /* zero dimmInfo structure */
  59459. + memset(data, 0, SPD_SIZE);
  59460. +
  59461. + /* read the dimm eeprom */
  59462. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  59463. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
  59464. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  59465. + twsiSlave.validOffset = MV_TRUE;
  59466. + twsiSlave.offset = 0;
  59467. + twsiSlave.moreThen256 = MV_FALSE;
  59468. +
  59469. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
  59470. + {
  59471. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
  59472. + return MV_FAIL;
  59473. + }
  59474. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  59475. +
  59476. + /* calculate SPD checksum */
  59477. + spdChecksum = 0;
  59478. +
  59479. + for(i = 0 ; i <= 62 ; i++)
  59480. + {
  59481. + spdChecksum += data[i];
  59482. + }
  59483. +
  59484. + if ((spdChecksum & 0xff) != data[63])
  59485. + {
  59486. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  59487. + (MV_U32)(spdChecksum & 0xff), data[63]));
  59488. + }
  59489. + else
  59490. + {
  59491. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  59492. + }
  59493. +
  59494. + /* copy the SPD content 1:1 into the DIMM 1 SPD */
  59495. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
  59496. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  59497. + twsiSlave.validOffset = MV_TRUE;
  59498. + twsiSlave.offset = 0;
  59499. + twsiSlave.moreThen256 = MV_FALSE;
  59500. +
  59501. + for(i = 0 ; i < SPD_SIZE ; i++)
  59502. + {
  59503. + twsiSlave.offset = i;
  59504. + if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, &data[i], 1) )
  59505. + {
  59506. + mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
  59507. + return MV_FAIL;
  59508. + }
  59509. + mvOsDelay(5);
  59510. + }
  59511. +
  59512. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  59513. + return MV_OK;
  59514. +}
  59515. +
  59516. +/*******************************************************************************
  59517. +* dimmSpdGet - Get the SPD parameters.
  59518. +*
  59519. +* DESCRIPTION:
  59520. +* Read the DIMM SPD parameters into given struct parameter.
  59521. +*
  59522. +* INPUT:
  59523. +* dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
  59524. +*
  59525. +* OUTPUT:
  59526. +* pDimmInfo - DIMM information structure.
  59527. +*
  59528. +* RETURN:
  59529. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  59530. +*
  59531. +*******************************************************************************/
  59532. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
  59533. +{
  59534. + MV_U32 i;
  59535. + MV_U32 density = 1;
  59536. + MV_U32 spdChecksum;
  59537. +
  59538. + MV_TWSI_SLAVE twsiSlave;
  59539. + MV_U8 data[SPD_SIZE];
  59540. +
  59541. + if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
  59542. + {
  59543. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  59544. + return MV_BAD_PARAM;
  59545. + }
  59546. +
  59547. + /* zero dimmInfo structure */
  59548. + memset(data, 0, SPD_SIZE);
  59549. +
  59550. + /* read the dimm eeprom */
  59551. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  59552. + twsiSlave.slaveAddr.address = (dimmNum == 0) ?
  59553. + MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
  59554. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  59555. + twsiSlave.validOffset = MV_TRUE;
  59556. + twsiSlave.offset = 0;
  59557. + twsiSlave.moreThen256 = MV_FALSE;
  59558. +
  59559. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
  59560. + {
  59561. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
  59562. + return MV_FAIL;
  59563. + }
  59564. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  59565. +
  59566. + /* calculate SPD checksum */
  59567. + spdChecksum = 0;
  59568. +
  59569. + for(i = 0 ; i <= 62 ; i++)
  59570. + {
  59571. + spdChecksum += data[i];
  59572. + }
  59573. +
  59574. + if ((spdChecksum & 0xff) != data[63])
  59575. + {
  59576. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  59577. + (MV_U32)(spdChecksum & 0xff), data[63]));
  59578. + }
  59579. + else
  59580. + {
  59581. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  59582. + }
  59583. +
  59584. + /* copy the SPD content 1:1 into the dimmInfo structure*/
  59585. + for(i = 0 ; i < SPD_SIZE ; i++)
  59586. + {
  59587. + pDimmInfo->spdRawData[i] = data[i];
  59588. + DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
  59589. + }
  59590. +
  59591. + DB(mvOsPrintf("DRAM SPD Information:\n"));
  59592. +
  59593. + /* Memory type (DDR / SDRAM) */
  59594. + switch (data[DIMM_MEM_TYPE])
  59595. + {
  59596. + case (DIMM_MEM_TYPE_SDRAM):
  59597. + pDimmInfo->memoryType = MEM_TYPE_SDRAM;
  59598. + DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
  59599. + break;
  59600. + case (DIMM_MEM_TYPE_DDR1):
  59601. + pDimmInfo->memoryType = MEM_TYPE_DDR1;
  59602. + DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
  59603. + break;
  59604. + case (DIMM_MEM_TYPE_DDR2):
  59605. + pDimmInfo->memoryType = MEM_TYPE_DDR2;
  59606. + DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
  59607. + break;
  59608. + default:
  59609. + mvOsPrintf("ERROR: Undefined memory type!\n");
  59610. + return MV_ERROR;
  59611. + }
  59612. +
  59613. +
  59614. + /* Number Of Row Addresses */
  59615. + pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
  59616. + DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
  59617. +
  59618. + /* Number Of Column Addresses */
  59619. + pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
  59620. + DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
  59621. +
  59622. + /* Number Of Module Banks */
  59623. + pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
  59624. + DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
  59625. + pDimmInfo->numOfModuleBanks));
  59626. +
  59627. + /* Number of module banks encoded differently for DDR2 */
  59628. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  59629. + pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
  59630. +
  59631. + /* Data Width */
  59632. + pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
  59633. + DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
  59634. +
  59635. + /* Minimum Cycle Time At Max CasLatancy */
  59636. + pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
  59637. +
  59638. + /* Error Check Type */
  59639. + pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
  59640. + DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
  59641. + pDimmInfo->errorCheckType));
  59642. +
  59643. + /* Refresh Interval */
  59644. + pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
  59645. + DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
  59646. + pDimmInfo->refreshInterval));
  59647. +
  59648. + /* Sdram Width */
  59649. + pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
  59650. + DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
  59651. +
  59652. + /* Error Check Data Width */
  59653. + pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
  59654. + DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
  59655. + pDimmInfo->errorCheckDataWidth));
  59656. +
  59657. + /* Burst Length Supported */
  59658. + /* SDRAM/DDR1:
  59659. + *******-******-******-******-******-******-******-*******
  59660. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  59661. + *******-******-******-******-******-******-******-*******
  59662. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  59663. + *********************************************************/
  59664. + /* DDR2:
  59665. + *******-******-******-******-******-******-******-*******
  59666. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  59667. + *******-******-******-******-******-******-******-*******
  59668. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  59669. + *********************************************************/
  59670. +
  59671. + pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
  59672. + DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
  59673. + pDimmInfo->burstLengthSupported));
  59674. +
  59675. + /* Number Of Banks On Each Device */
  59676. + pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
  59677. + DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
  59678. + pDimmInfo->numOfBanksOnEachDevice));
  59679. +
  59680. + /* Suported Cas Latencies */
  59681. +
  59682. + /* SDRAM:
  59683. + *******-******-******-******-******-******-******-*******
  59684. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  59685. + *******-******-******-******-******-******-******-*******
  59686. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  59687. + ********************************************************/
  59688. +
  59689. + /* DDR 1:
  59690. + *******-******-******-******-******-******-******-*******
  59691. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  59692. + *******-******-******-******-******-******-******-*******
  59693. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  59694. + *********************************************************/
  59695. +
  59696. + /* DDR 2:
  59697. + *******-******-******-******-******-******-******-*******
  59698. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  59699. + *******-******-******-******-******-******-******-*******
  59700. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  59701. + *********************************************************/
  59702. +
  59703. + pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
  59704. + DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
  59705. + pDimmInfo->suportedCasLatencies));
  59706. +
  59707. + /* For DDR2 only, get the DIMM type information */
  59708. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  59709. + {
  59710. + pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
  59711. + DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
  59712. + pDimmInfo->dimmTypeInfo));
  59713. + }
  59714. +
  59715. + /* SDRAM Modules Attributes */
  59716. + pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
  59717. + DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
  59718. + pDimmInfo->dimmAttributes));
  59719. +
  59720. + /* Minimum Cycle Time At Max CasLatancy Minus 1*/
  59721. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  59722. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
  59723. +
  59724. + /* Minimum Cycle Time At Max CasLatancy Minus 2*/
  59725. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  59726. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
  59727. +
  59728. + pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
  59729. + DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
  59730. + pDimmInfo->minRowPrechargeTime));
  59731. + pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
  59732. + DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
  59733. + pDimmInfo->minRowActiveToRowActive));
  59734. + pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
  59735. + DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
  59736. + pDimmInfo->minRasToCasDelay));
  59737. + pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
  59738. + DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
  59739. + pDimmInfo->minRasPulseWidth));
  59740. +
  59741. + /* DIMM Bank Density */
  59742. + pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
  59743. + DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
  59744. + pDimmInfo->dimmBankDensity));
  59745. +
  59746. + /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
  59747. + pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
  59748. + DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
  59749. + pDimmInfo->minWriteRecoveryTime));
  59750. +
  59751. + /* Only DDR2 includes Internal Write To Read Command Delay field. */
  59752. + pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
  59753. + DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
  59754. + pDimmInfo->minWriteToReadCmdDelay));
  59755. +
  59756. + /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
  59757. + pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
  59758. + DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
  59759. + pDimmInfo->minReadToPrechCmdDelay));
  59760. +
  59761. + /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
  59762. + pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
  59763. + DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
  59764. + pDimmInfo->minRefreshToActiveCmd));
  59765. +
  59766. + /* calculating the sdram density. Representing device density from */
  59767. + /* bit 20 to allow representation of 4GB and above. */
  59768. + /* For example, if density is 512Mbit 0x20000000, will be represent in */
  59769. + /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
  59770. + /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
  59771. + density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
  59772. + pDimmInfo->deviceDensity = density *
  59773. + pDimmInfo->numOfBanksOnEachDevice *
  59774. + pDimmInfo->sdramWidth;
  59775. + DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
  59776. +
  59777. + /* Number of devices includeing Error correction */
  59778. + pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
  59779. + pDimmInfo->numOfModuleBanks;
  59780. + DB(mvOsPrintf("DRAM numberOfDevices %d\n",
  59781. + pDimmInfo->numberOfDevices));
  59782. +
  59783. + pDimmInfo->size = 0;
  59784. +
  59785. + /* Note that pDimmInfo->size is in MB units */
  59786. + if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
  59787. + {
  59788. + if (pDimmInfo->dimmBankDensity & BIT0)
  59789. + pDimmInfo->size += 1024; /* Equal to 1GB */
  59790. + else if (pDimmInfo->dimmBankDensity & BIT1)
  59791. + pDimmInfo->size += 8; /* Equal to 8MB */
  59792. + else if (pDimmInfo->dimmBankDensity & BIT2)
  59793. + pDimmInfo->size += 16; /* Equal to 16MB */
  59794. + else if (pDimmInfo->dimmBankDensity & BIT3)
  59795. + pDimmInfo->size += 32; /* Equal to 32MB */
  59796. + else if (pDimmInfo->dimmBankDensity & BIT4)
  59797. + pDimmInfo->size += 64; /* Equal to 64MB */
  59798. + else if (pDimmInfo->dimmBankDensity & BIT5)
  59799. + pDimmInfo->size += 128; /* Equal to 128MB */
  59800. + else if (pDimmInfo->dimmBankDensity & BIT6)
  59801. + pDimmInfo->size += 256; /* Equal to 256MB */
  59802. + else if (pDimmInfo->dimmBankDensity & BIT7)
  59803. + pDimmInfo->size += 512; /* Equal to 512MB */
  59804. + }
  59805. + else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
  59806. + {
  59807. + if (pDimmInfo->dimmBankDensity & BIT0)
  59808. + pDimmInfo->size += 1024; /* Equal to 1GB */
  59809. + else if (pDimmInfo->dimmBankDensity & BIT1)
  59810. + pDimmInfo->size += 2048; /* Equal to 2GB */
  59811. + else if (pDimmInfo->dimmBankDensity & BIT2)
  59812. + pDimmInfo->size += 16; /* Equal to 16MB */
  59813. + else if (pDimmInfo->dimmBankDensity & BIT3)
  59814. + pDimmInfo->size += 32; /* Equal to 32MB */
  59815. + else if (pDimmInfo->dimmBankDensity & BIT4)
  59816. + pDimmInfo->size += 64; /* Equal to 64MB */
  59817. + else if (pDimmInfo->dimmBankDensity & BIT5)
  59818. + pDimmInfo->size += 128; /* Equal to 128MB */
  59819. + else if (pDimmInfo->dimmBankDensity & BIT6)
  59820. + pDimmInfo->size += 256; /* Equal to 256MB */
  59821. + else if (pDimmInfo->dimmBankDensity & BIT7)
  59822. + pDimmInfo->size += 512; /* Equal to 512MB */
  59823. + }
  59824. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  59825. + {
  59826. + if (pDimmInfo->dimmBankDensity & BIT0)
  59827. + pDimmInfo->size += 1024; /* Equal to 1GB */
  59828. + else if (pDimmInfo->dimmBankDensity & BIT1)
  59829. + pDimmInfo->size += 2048; /* Equal to 2GB */
  59830. + else if (pDimmInfo->dimmBankDensity & BIT2)
  59831. + pDimmInfo->size += 4096; /* Equal to 4GB */
  59832. + else if (pDimmInfo->dimmBankDensity & BIT3)
  59833. + pDimmInfo->size += 8192; /* Equal to 8GB */
  59834. + else if (pDimmInfo->dimmBankDensity & BIT4)
  59835. + pDimmInfo->size += 16384; /* Equal to 16GB */
  59836. + else if (pDimmInfo->dimmBankDensity & BIT5)
  59837. + pDimmInfo->size += 128; /* Equal to 128MB */
  59838. + else if (pDimmInfo->dimmBankDensity & BIT6)
  59839. + pDimmInfo->size += 256; /* Equal to 256MB */
  59840. + else if (pDimmInfo->dimmBankDensity & BIT7)
  59841. + pDimmInfo->size += 512; /* Equal to 512MB */
  59842. + }
  59843. +
  59844. + pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
  59845. +
  59846. + DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
  59847. +
  59848. + return MV_OK;
  59849. +}
  59850. +
  59851. +/*******************************************************************************
  59852. +* dimmSpdPrint - Print the SPD parameters.
  59853. +*
  59854. +* DESCRIPTION:
  59855. +* Print the Dimm SPD parameters.
  59856. +*
  59857. +* INPUT:
  59858. +* pDimmInfo - DIMM information structure.
  59859. +*
  59860. +* OUTPUT:
  59861. +* None.
  59862. +*
  59863. +* RETURN:
  59864. +* None.
  59865. +*
  59866. +*******************************************************************************/
  59867. +MV_VOID dimmSpdPrint(MV_U32 dimmNum)
  59868. +{
  59869. + MV_DIMM_INFO dimmInfo;
  59870. + MV_U32 i, temp = 0;
  59871. + MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
  59872. + MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
  59873. + MV_U32 busClkPs;
  59874. + MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
  59875. + temp_buf[40], *spdRawData;
  59876. +
  59877. + busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
  59878. +
  59879. + spdRawData = dimmInfo.spdRawData;
  59880. +
  59881. + if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
  59882. + {
  59883. + mvOsOutput("ERROR: Could not read SPD information!\n");
  59884. + return;
  59885. + }
  59886. +
  59887. + /* find Manufactura of Dimm Module */
  59888. + mvOsOutput("\nManufacturer's JEDEC ID Code: ");
  59889. + for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
  59890. + {
  59891. + mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
  59892. + }
  59893. + mvOsOutput("\n");
  59894. +
  59895. + /* Manufacturer's Specific Data */
  59896. + for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
  59897. + {
  59898. + temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
  59899. + }
  59900. + mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
  59901. +
  59902. + /* Module Part Number */
  59903. + for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
  59904. + {
  59905. + temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
  59906. + }
  59907. + mvOsOutput("Module Part Number: %s\n", temp_buf);
  59908. +
  59909. + /* Module Serial Number */
  59910. + for(i = 0; i < sizeof(MV_U32); i++)
  59911. + {
  59912. + temp |= spdRawData[95+i] << 8*i;
  59913. + }
  59914. + mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
  59915. + (long)temp);
  59916. +
  59917. + /* find Manufac-Data of Dimm Module */
  59918. + mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
  59919. + ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
  59920. + ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
  59921. + /* find modul_revision of Dimm Module */
  59922. + mvOsOutput("Module Revision: %d.%d\n",
  59923. + spdRawData[62]/10, spdRawData[62]%10);
  59924. +
  59925. + /* find manufac_place of Dimm Module */
  59926. + mvOsOutput("manufac_place: %d\n", spdRawData[72]);
  59927. +
  59928. + /* go over the first 35 I2C data bytes */
  59929. + for(i = 2 ; i <= 35 ; i++)
  59930. + switch(i)
  59931. + {
  59932. + case 2: /* Memory type (DDR1/2 / SDRAM) */
  59933. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  59934. + mvOsOutput("Dram Type is: SDRAM\n");
  59935. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  59936. + mvOsOutput("Dram Type is: SDRAM DDR1\n");
  59937. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  59938. + mvOsOutput("Dram Type is: SDRAM DDR2\n");
  59939. + else
  59940. + mvOsOutput("Dram Type unknown\n");
  59941. + break;
  59942. +/*----------------------------------------------------------------------------*/
  59943. +
  59944. + case 3: /* Number Of Row Addresses */
  59945. + mvOsOutput("Module Number of row addresses: %d\n",
  59946. + dimmInfo.numOfRowAddr);
  59947. + break;
  59948. +/*----------------------------------------------------------------------------*/
  59949. +
  59950. + case 4: /* Number Of Column Addresses */
  59951. + mvOsOutput("Module Number of col addresses: %d\n",
  59952. + dimmInfo.numOfColAddr);
  59953. + break;
  59954. +/*----------------------------------------------------------------------------*/
  59955. +
  59956. + case 5: /* Number Of Module Banks */
  59957. + mvOsOutput("Number of Banks on Mod.: %d\n",
  59958. + dimmInfo.numOfModuleBanks);
  59959. + break;
  59960. +/*----------------------------------------------------------------------------*/
  59961. +
  59962. + case 6: /* Data Width */
  59963. + mvOsOutput("Module Data Width: %d bit\n",
  59964. + dimmInfo.dataWidth);
  59965. + break;
  59966. +/*----------------------------------------------------------------------------*/
  59967. +
  59968. + case 8: /* Voltage Interface */
  59969. + switch(spdRawData[i])
  59970. + {
  59971. + case 0x0:
  59972. + mvOsOutput("Module is TTL_5V_TOLERANT\n");
  59973. + break;
  59974. + case 0x1:
  59975. + mvOsOutput("Module is LVTTL\n");
  59976. + break;
  59977. + case 0x2:
  59978. + mvOsOutput("Module is HSTL_1_5V\n");
  59979. + break;
  59980. + case 0x3:
  59981. + mvOsOutput("Module is SSTL_3_3V\n");
  59982. + break;
  59983. + case 0x4:
  59984. + mvOsOutput("Module is SSTL_2_5V\n");
  59985. + break;
  59986. + case 0x5:
  59987. + if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
  59988. + {
  59989. + mvOsOutput("Module is SSTL_1_8V\n");
  59990. + break;
  59991. + }
  59992. + default:
  59993. + mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
  59994. + break;
  59995. + }
  59996. + break;
  59997. +/*----------------------------------------------------------------------------*/
  59998. +
  59999. + case 9: /* Minimum Cycle Time At Max CasLatancy */
  60000. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60001. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  60002. +
  60003. + /* DDR2 addition of right of point */
  60004. + if ((spdRawData[i] & 0x0f) == 0xA)
  60005. + {
  60006. + rightOfPoint = 25;
  60007. + }
  60008. + if ((spdRawData[i] & 0x0f) == 0xB)
  60009. + {
  60010. + rightOfPoint = 33;
  60011. + }
  60012. + if ((spdRawData[i] & 0x0f) == 0xC)
  60013. + {
  60014. + rightOfPoint = 66;
  60015. + }
  60016. + if ((spdRawData[i] & 0x0f) == 0xD)
  60017. + {
  60018. + rightOfPoint = 75;
  60019. + }
  60020. + mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
  60021. + leftOfPoint, rightOfPoint);
  60022. + break;
  60023. +/*----------------------------------------------------------------------------*/
  60024. +
  60025. + case 10: /* Clock To Data Out */
  60026. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
  60027. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60028. + ((spdRawData[i] & 0x0f));
  60029. + leftOfPoint = time_tmp / div;
  60030. + rightOfPoint = time_tmp % div;
  60031. + mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
  60032. + leftOfPoint, rightOfPoint);
  60033. + break;
  60034. +/*----------------------------------------------------------------------------*/
  60035. +
  60036. + case 11: /* Error Check Type */
  60037. + mvOsOutput("Error Check Type (0=NONE): %d\n",
  60038. + dimmInfo.errorCheckType);
  60039. + break;
  60040. +/*----------------------------------------------------------------------------*/
  60041. +
  60042. + case 12: /* Refresh Interval */
  60043. + mvOsOutput("Refresh Rate: %x\n",
  60044. + dimmInfo.refreshInterval);
  60045. + break;
  60046. +/*----------------------------------------------------------------------------*/
  60047. +
  60048. + case 13: /* Sdram Width */
  60049. + mvOsOutput("Sdram Width: %d bits\n",
  60050. + dimmInfo.sdramWidth);
  60051. + break;
  60052. +/*----------------------------------------------------------------------------*/
  60053. +
  60054. + case 14: /* Error Check Data Width */
  60055. + mvOsOutput("Error Check Data Width: %d bits\n",
  60056. + dimmInfo.errorCheckDataWidth);
  60057. + break;
  60058. +/*----------------------------------------------------------------------------*/
  60059. +
  60060. + case 15: /* Minimum Clock Delay is unsupported */
  60061. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  60062. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  60063. + {
  60064. + mvOsOutput("Minimum Clk Delay back to back: %d\n",
  60065. + spdRawData[i]);
  60066. + }
  60067. + break;
  60068. +/*----------------------------------------------------------------------------*/
  60069. +
  60070. + case 16: /* Burst Length Supported */
  60071. + /* SDRAM/DDR1:
  60072. + *******-******-******-******-******-******-******-*******
  60073. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60074. + *******-******-******-******-******-******-******-*******
  60075. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  60076. + *********************************************************/
  60077. + /* DDR2:
  60078. + *******-******-******-******-******-******-******-*******
  60079. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60080. + *******-******-******-******-******-******-******-*******
  60081. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  60082. + *********************************************************/
  60083. + mvOsOutput("Burst Length Supported: ");
  60084. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  60085. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  60086. + {
  60087. + if (dimmInfo.burstLengthSupported & BIT0)
  60088. + mvOsOutput("1, ");
  60089. + if (dimmInfo.burstLengthSupported & BIT1)
  60090. + mvOsOutput("2, ");
  60091. + }
  60092. + if (dimmInfo.burstLengthSupported & BIT2)
  60093. + mvOsOutput("4, ");
  60094. + if (dimmInfo.burstLengthSupported & BIT3)
  60095. + mvOsOutput("8, ");
  60096. +
  60097. + mvOsOutput(" Bit \n");
  60098. + break;
  60099. +/*----------------------------------------------------------------------------*/
  60100. +
  60101. + case 17: /* Number Of Banks On Each Device */
  60102. + mvOsOutput("Number Of Banks On Each Chip: %d\n",
  60103. + dimmInfo.numOfBanksOnEachDevice);
  60104. + break;
  60105. +/*----------------------------------------------------------------------------*/
  60106. +
  60107. + case 18: /* Suported Cas Latencies */
  60108. +
  60109. + /* SDRAM:
  60110. + *******-******-******-******-******-******-******-*******
  60111. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60112. + *******-******-******-******-******-******-******-*******
  60113. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  60114. + ********************************************************/
  60115. +
  60116. + /* DDR 1:
  60117. + *******-******-******-******-******-******-******-*******
  60118. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60119. + *******-******-******-******-******-******-******-*******
  60120. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  60121. + *********************************************************/
  60122. +
  60123. + /* DDR 2:
  60124. + *******-******-******-******-******-******-******-*******
  60125. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60126. + *******-******-******-******-******-******-******-*******
  60127. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  60128. + *********************************************************/
  60129. +
  60130. + mvOsOutput("Suported Cas Latencies: (CL) ");
  60131. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60132. + {
  60133. + for (k = 0; k <=7; k++)
  60134. + {
  60135. + if (dimmInfo.suportedCasLatencies & (1 << k))
  60136. + mvOsOutput("%d, ", k+1);
  60137. + }
  60138. + }
  60139. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  60140. + {
  60141. + if (dimmInfo.suportedCasLatencies & BIT0)
  60142. + mvOsOutput("1, ");
  60143. + if (dimmInfo.suportedCasLatencies & BIT1)
  60144. + mvOsOutput("1.5, ");
  60145. + if (dimmInfo.suportedCasLatencies & BIT2)
  60146. + mvOsOutput("2, ");
  60147. + if (dimmInfo.suportedCasLatencies & BIT3)
  60148. + mvOsOutput("2.5, ");
  60149. + if (dimmInfo.suportedCasLatencies & BIT4)
  60150. + mvOsOutput("3, ");
  60151. + if (dimmInfo.suportedCasLatencies & BIT5)
  60152. + mvOsOutput("3.5, ");
  60153. + }
  60154. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  60155. + {
  60156. + if (dimmInfo.suportedCasLatencies & BIT2)
  60157. + mvOsOutput("2, ");
  60158. + if (dimmInfo.suportedCasLatencies & BIT3)
  60159. + mvOsOutput("3, ");
  60160. + if (dimmInfo.suportedCasLatencies & BIT4)
  60161. + mvOsOutput("4, ");
  60162. + if (dimmInfo.suportedCasLatencies & BIT5)
  60163. + mvOsOutput("5, ");
  60164. + }
  60165. + else
  60166. + mvOsOutput("?.?, ");
  60167. + mvOsOutput("\n");
  60168. + break;
  60169. +/*----------------------------------------------------------------------------*/
  60170. +
  60171. + case 20: /* DDR2 DIMM type info */
  60172. + if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  60173. + {
  60174. + if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
  60175. + mvOsOutput("Registered DIMM (RDIMM)\n");
  60176. + else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
  60177. + mvOsOutput("Unbuffered DIMM (UDIMM)\n");
  60178. + else
  60179. + mvOsOutput("Unknown DIMM type.\n");
  60180. + }
  60181. +
  60182. + break;
  60183. +/*----------------------------------------------------------------------------*/
  60184. +
  60185. + case 21: /* SDRAM Modules Attributes */
  60186. + mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
  60187. +
  60188. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60189. + {
  60190. + if (dimmInfo.dimmAttributes & BIT0)
  60191. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  60192. + else
  60193. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  60194. +
  60195. + if (dimmInfo.dimmAttributes & BIT1)
  60196. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  60197. + else
  60198. + mvOsOutput(" Registered Addr/Control Input: No\n");
  60199. +
  60200. + if (dimmInfo.dimmAttributes & BIT2)
  60201. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  60202. + else
  60203. + mvOsOutput(" On-Card PLL (clock): No \n");
  60204. +
  60205. + if (dimmInfo.dimmAttributes & BIT3)
  60206. + mvOsOutput(" Bufferd DQMB Input: Yes \n");
  60207. + else
  60208. + mvOsOutput(" Bufferd DQMB Inputs: No \n");
  60209. +
  60210. + if (dimmInfo.dimmAttributes & BIT4)
  60211. + mvOsOutput(" Registered DQMB Inputs: Yes \n");
  60212. + else
  60213. + mvOsOutput(" Registered DQMB Inputs: No \n");
  60214. +
  60215. + if (dimmInfo.dimmAttributes & BIT5)
  60216. + mvOsOutput(" Differential Clock Input: Yes \n");
  60217. + else
  60218. + mvOsOutput(" Differential Clock Input: No \n");
  60219. +
  60220. + if (dimmInfo.dimmAttributes & BIT6)
  60221. + mvOsOutput(" redundant Row Addressing: Yes \n");
  60222. + else
  60223. + mvOsOutput(" redundant Row Addressing: No \n");
  60224. + }
  60225. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  60226. + {
  60227. + if (dimmInfo.dimmAttributes & BIT0)
  60228. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  60229. + else
  60230. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  60231. +
  60232. + if (dimmInfo.dimmAttributes & BIT1)
  60233. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  60234. + else
  60235. + mvOsOutput(" Registered Addr/Control Input: No\n");
  60236. +
  60237. + if (dimmInfo.dimmAttributes & BIT2)
  60238. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  60239. + else
  60240. + mvOsOutput(" On-Card PLL (clock): No \n");
  60241. +
  60242. + if (dimmInfo.dimmAttributes & BIT3)
  60243. + mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
  60244. + else
  60245. + mvOsOutput(" FET Switch On-Card Enabled: No \n");
  60246. +
  60247. + if (dimmInfo.dimmAttributes & BIT4)
  60248. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  60249. + else
  60250. + mvOsOutput(" FET Switch External Enabled: No \n");
  60251. +
  60252. + if (dimmInfo.dimmAttributes & BIT5)
  60253. + mvOsOutput(" Differential Clock Input: Yes \n");
  60254. + else
  60255. + mvOsOutput(" Differential Clock Input: No \n");
  60256. + }
  60257. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  60258. + {
  60259. + mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
  60260. + (dimmInfo.dimmAttributes & 0x3) + 1);
  60261. +
  60262. + mvOsOutput(" Number of PLLs on the DIMM: %d\n",
  60263. + ((dimmInfo.dimmAttributes) >> 2) & 0x3);
  60264. +
  60265. + if (dimmInfo.dimmAttributes & BIT4)
  60266. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  60267. + else
  60268. + mvOsOutput(" FET Switch External Enabled: No \n");
  60269. +
  60270. + if (dimmInfo.dimmAttributes & BIT6)
  60271. + mvOsOutput(" Analysis probe installed: Yes \n");
  60272. + else
  60273. + mvOsOutput(" Analysis probe installed: No \n");
  60274. + }
  60275. +
  60276. + break;
  60277. +/*----------------------------------------------------------------------------*/
  60278. +
  60279. + case 22: /* Suported AutoPreCharge */
  60280. + mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
  60281. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60282. + {
  60283. + if ( spdRawData[i] & BIT0 )
  60284. + mvOsOutput(" Early Ras Precharge: Yes \n");
  60285. + else
  60286. + mvOsOutput(" Early Ras Precharge: No \n");
  60287. +
  60288. + if ( spdRawData[i] & BIT1 )
  60289. + mvOsOutput(" AutoPreCharge: Yes \n");
  60290. + else
  60291. + mvOsOutput(" AutoPreCharge: No \n");
  60292. +
  60293. + if ( spdRawData[i] & BIT2 )
  60294. + mvOsOutput(" Precharge All: Yes \n");
  60295. + else
  60296. + mvOsOutput(" Precharge All: No \n");
  60297. +
  60298. + if ( spdRawData[i] & BIT3 )
  60299. + mvOsOutput(" Write 1/ReadBurst: Yes \n");
  60300. + else
  60301. + mvOsOutput(" Write 1/ReadBurst: No \n");
  60302. +
  60303. + if ( spdRawData[i] & BIT4 )
  60304. + mvOsOutput(" lower VCC tolerance: 5%%\n");
  60305. + else
  60306. + mvOsOutput(" lower VCC tolerance: 10%%\n");
  60307. +
  60308. + if ( spdRawData[i] & BIT5 )
  60309. + mvOsOutput(" upper VCC tolerance: 5%%\n");
  60310. + else
  60311. + mvOsOutput(" upper VCC tolerance: 10%%\n");
  60312. + }
  60313. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  60314. + {
  60315. + if ( spdRawData[i] & BIT0 )
  60316. + mvOsOutput(" Supports Weak Driver: Yes \n");
  60317. + else
  60318. + mvOsOutput(" Supports Weak Driver: No \n");
  60319. +
  60320. + if ( !(spdRawData[i] & BIT4) )
  60321. + mvOsOutput(" lower VCC tolerance: 0.2V\n");
  60322. +
  60323. + if ( !(spdRawData[i] & BIT5) )
  60324. + mvOsOutput(" upper VCC tolerance: 0.2V\n");
  60325. +
  60326. + if ( spdRawData[i] & BIT6 )
  60327. + mvOsOutput(" Concurrent Auto Preharge: Yes \n");
  60328. + else
  60329. + mvOsOutput(" Concurrent Auto Preharge: No \n");
  60330. +
  60331. + if ( spdRawData[i] & BIT7 )
  60332. + mvOsOutput(" Supports Fast AP: Yes \n");
  60333. + else
  60334. + mvOsOutput(" Supports Fast AP: No \n");
  60335. + }
  60336. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  60337. + {
  60338. + if ( spdRawData[i] & BIT0 )
  60339. + mvOsOutput(" Supports Weak Driver: Yes \n");
  60340. + else
  60341. + mvOsOutput(" Supports Weak Driver: No \n");
  60342. + }
  60343. + break;
  60344. +/*----------------------------------------------------------------------------*/
  60345. +
  60346. + case 23:
  60347. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
  60348. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60349. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  60350. +
  60351. + /* DDR2 addition of right of point */
  60352. + if ((spdRawData[i] & 0x0f) == 0xA)
  60353. + {
  60354. + rightOfPoint = 25;
  60355. + }
  60356. + if ((spdRawData[i] & 0x0f) == 0xB)
  60357. + {
  60358. + rightOfPoint = 33;
  60359. + }
  60360. + if ((spdRawData[i] & 0x0f) == 0xC)
  60361. + {
  60362. + rightOfPoint = 66;
  60363. + }
  60364. + if ((spdRawData[i] & 0x0f) == 0xD)
  60365. + {
  60366. + rightOfPoint = 75;
  60367. + }
  60368. +
  60369. + mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
  60370. + "(0 = Not supported): %d.%d [ns]\n",
  60371. + leftOfPoint, rightOfPoint );
  60372. + break;
  60373. +/*----------------------------------------------------------------------------*/
  60374. +
  60375. + case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
  60376. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
  60377. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60378. + ((spdRawData[i] & 0x0f));
  60379. + leftOfPoint = time_tmp / div;
  60380. + rightOfPoint = time_tmp % div;
  60381. + mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
  60382. + leftOfPoint, rightOfPoint);
  60383. + break;
  60384. +/*----------------------------------------------------------------------------*/
  60385. +
  60386. + case 25:
  60387. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
  60388. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60389. + {
  60390. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  60391. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  60392. + }
  60393. + else /* DDR1 or DDR2 */
  60394. + {
  60395. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60396. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  60397. +
  60398. + /* DDR2 addition of right of point */
  60399. + if ((spdRawData[i] & 0x0f) == 0xA)
  60400. + {
  60401. + rightOfPoint = 25;
  60402. + }
  60403. + if ((spdRawData[i] & 0x0f) == 0xB)
  60404. + {
  60405. + rightOfPoint = 33;
  60406. + }
  60407. + if ((spdRawData[i] & 0x0f) == 0xC)
  60408. + {
  60409. + rightOfPoint = 66;
  60410. + }
  60411. + if ((spdRawData[i] & 0x0f) == 0xD)
  60412. + {
  60413. + rightOfPoint = 75;
  60414. + }
  60415. + }
  60416. + mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
  60417. + "(0 = Not supported): %d.%d [ns]\n",
  60418. + leftOfPoint, rightOfPoint );
  60419. + break;
  60420. +/*----------------------------------------------------------------------------*/
  60421. +
  60422. + case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
  60423. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60424. + {
  60425. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  60426. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  60427. + }
  60428. + else /* DDR1 or DDR2 */
  60429. + {
  60430. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60431. + ((spdRawData[i] & 0x0f));
  60432. + leftOfPoint = 0;
  60433. + rightOfPoint = time_tmp;
  60434. + }
  60435. + mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
  60436. + leftOfPoint, rightOfPoint );
  60437. + break;
  60438. +/*----------------------------------------------------------------------------*/
  60439. +
  60440. + case 27: /* Minimum Row Precharge Time */
  60441. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  60442. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  60443. + 0xff : 0xfc;
  60444. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  60445. + 0x00 : 0x03;
  60446. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  60447. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  60448. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
  60449. + trp_clocks = (temp + (busClkPs-1)) / busClkPs;
  60450. + mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
  60451. + "in Clk cycles %d\n",
  60452. + leftOfPoint, rightOfPoint, trp_clocks);
  60453. + break;
  60454. +/*----------------------------------------------------------------------------*/
  60455. +
  60456. + case 28: /* Minimum Row Active to Row Active Time */
  60457. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  60458. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  60459. + 0xff : 0xfc;
  60460. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  60461. + 0x00 : 0x03;
  60462. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  60463. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  60464. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  60465. + trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
  60466. + mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
  60467. + "%d.%d = in Clk cycles %d\n",
  60468. + leftOfPoint, rightOfPoint, trp_clocks);
  60469. + break;
  60470. +/*----------------------------------------------------------------------------*/
  60471. +
  60472. + case 29: /* Minimum Ras-To-Cas Delay */
  60473. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  60474. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  60475. + 0xff : 0xfc;
  60476. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  60477. + 0x00 : 0x03;
  60478. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  60479. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  60480. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  60481. + trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
  60482. + mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
  60483. + "in Clk cycles %d\n",
  60484. + leftOfPoint, rightOfPoint, trp_clocks);
  60485. + break;
  60486. +/*----------------------------------------------------------------------------*/
  60487. +
  60488. + case 30: /* Minimum Ras Pulse Width */
  60489. + tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
  60490. + mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
  60491. + "in Clk cycles %d\n", spdRawData[i], tras_clocks);
  60492. + break;
  60493. +/*----------------------------------------------------------------------------*/
  60494. +
  60495. + case 31: /* Module Bank Density */
  60496. + mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
  60497. +
  60498. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60499. + {
  60500. + if (dimmInfo.dimmBankDensity & BIT0)
  60501. + mvOsOutput("1GB, ");
  60502. + if (dimmInfo.dimmBankDensity & BIT1)
  60503. + mvOsOutput("8MB, ");
  60504. + if (dimmInfo.dimmBankDensity & BIT2)
  60505. + mvOsOutput("16MB, ");
  60506. + if (dimmInfo.dimmBankDensity & BIT3)
  60507. + mvOsOutput("32MB, ");
  60508. + if (dimmInfo.dimmBankDensity & BIT4)
  60509. + mvOsOutput("64MB, ");
  60510. + if (dimmInfo.dimmBankDensity & BIT5)
  60511. + mvOsOutput("128MB, ");
  60512. + if (dimmInfo.dimmBankDensity & BIT6)
  60513. + mvOsOutput("256MB, ");
  60514. + if (dimmInfo.dimmBankDensity & BIT7)
  60515. + mvOsOutput("512MB, ");
  60516. + }
  60517. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  60518. + {
  60519. + if (dimmInfo.dimmBankDensity & BIT0)
  60520. + mvOsOutput("1GB, ");
  60521. + if (dimmInfo.dimmBankDensity & BIT1)
  60522. + mvOsOutput("2GB, ");
  60523. + if (dimmInfo.dimmBankDensity & BIT2)
  60524. + mvOsOutput("16MB, ");
  60525. + if (dimmInfo.dimmBankDensity & BIT3)
  60526. + mvOsOutput("32MB, ");
  60527. + if (dimmInfo.dimmBankDensity & BIT4)
  60528. + mvOsOutput("64MB, ");
  60529. + if (dimmInfo.dimmBankDensity & BIT5)
  60530. + mvOsOutput("128MB, ");
  60531. + if (dimmInfo.dimmBankDensity & BIT6)
  60532. + mvOsOutput("256MB, ");
  60533. + if (dimmInfo.dimmBankDensity & BIT7)
  60534. + mvOsOutput("512MB, ");
  60535. + }
  60536. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  60537. + {
  60538. + if (dimmInfo.dimmBankDensity & BIT0)
  60539. + mvOsOutput("1GB, ");
  60540. + if (dimmInfo.dimmBankDensity & BIT1)
  60541. + mvOsOutput("2GB, ");
  60542. + if (dimmInfo.dimmBankDensity & BIT2)
  60543. + mvOsOutput("4GB, ");
  60544. + if (dimmInfo.dimmBankDensity & BIT3)
  60545. + mvOsOutput("8GB, ");
  60546. + if (dimmInfo.dimmBankDensity & BIT4)
  60547. + mvOsOutput("16GB, ");
  60548. + if (dimmInfo.dimmBankDensity & BIT5)
  60549. + mvOsOutput("128MB, ");
  60550. + if (dimmInfo.dimmBankDensity & BIT6)
  60551. + mvOsOutput("256MB, ");
  60552. + if (dimmInfo.dimmBankDensity & BIT7)
  60553. + mvOsOutput("512MB, ");
  60554. + }
  60555. + mvOsOutput("\n");
  60556. + break;
  60557. +/*----------------------------------------------------------------------------*/
  60558. +
  60559. + case 32: /* Address And Command Setup Time (measured in ns/1000) */
  60560. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60561. + {
  60562. + rightOfPoint = (spdRawData[i] & 0x0f);
  60563. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60564. + if(leftOfPoint > 7)
  60565. + {
  60566. + leftOfPoint *= -1;
  60567. + }
  60568. + }
  60569. + else /* DDR1 or DDR2 */
  60570. + {
  60571. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60572. + ((spdRawData[i] & 0x0f));
  60573. + leftOfPoint = time_tmp / 100;
  60574. + rightOfPoint = time_tmp % 100;
  60575. + }
  60576. + mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
  60577. + leftOfPoint, rightOfPoint);
  60578. + break;
  60579. +/*----------------------------------------------------------------------------*/
  60580. +
  60581. + case 33: /* Address And Command Hold Time */
  60582. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60583. + {
  60584. + rightOfPoint = (spdRawData[i] & 0x0f);
  60585. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60586. + if(leftOfPoint > 7)
  60587. + {
  60588. + leftOfPoint *= -1;
  60589. + }
  60590. + }
  60591. + else /* DDR1 or DDR2 */
  60592. + {
  60593. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60594. + ((spdRawData[i] & 0x0f));
  60595. + leftOfPoint = time_tmp / 100;
  60596. + rightOfPoint = time_tmp % 100;
  60597. + }
  60598. + mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
  60599. + leftOfPoint, rightOfPoint);
  60600. + break;
  60601. +/*----------------------------------------------------------------------------*/
  60602. +
  60603. + case 34: /* Data Input Setup Time */
  60604. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60605. + {
  60606. + rightOfPoint = (spdRawData[i] & 0x0f);
  60607. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60608. + if(leftOfPoint > 7)
  60609. + {
  60610. + leftOfPoint *= -1;
  60611. + }
  60612. + }
  60613. + else /* DDR1 or DDR2 */
  60614. + {
  60615. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60616. + ((spdRawData[i] & 0x0f));
  60617. + leftOfPoint = time_tmp / 100;
  60618. + rightOfPoint = time_tmp % 100;
  60619. + }
  60620. + mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
  60621. + leftOfPoint, rightOfPoint);
  60622. + break;
  60623. +/*----------------------------------------------------------------------------*/
  60624. +
  60625. + case 35: /* Data Input Hold Time */
  60626. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60627. + {
  60628. + rightOfPoint = (spdRawData[i] & 0x0f);
  60629. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60630. + if(leftOfPoint > 7)
  60631. + {
  60632. + leftOfPoint *= -1;
  60633. + }
  60634. + }
  60635. + else /* DDR1 or DDR2 */
  60636. + {
  60637. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60638. + ((spdRawData[i] & 0x0f));
  60639. + leftOfPoint = time_tmp / 100;
  60640. + rightOfPoint = time_tmp % 100;
  60641. + }
  60642. + mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
  60643. + leftOfPoint, rightOfPoint);
  60644. + break;
  60645. +/*----------------------------------------------------------------------------*/
  60646. +
  60647. + case 36: /* Relevant for DDR2 only: Write Recovery Time */
  60648. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
  60649. + rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
  60650. + mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
  60651. + leftOfPoint, rightOfPoint);
  60652. + break;
  60653. +/*----------------------------------------------------------------------------*/
  60654. + }
  60655. +
  60656. +}
  60657. +
  60658. +
  60659. +/*
  60660. + * translate ns.ns/10 coding of SPD timing values
  60661. + * into ps unit values
  60662. + */
  60663. +/*******************************************************************************
  60664. +* cas2ps - Translate x.y ns parameter to pico-seconds values
  60665. +*
  60666. +* DESCRIPTION:
  60667. +* This function translates x.y nano seconds to its value in pico seconds.
  60668. +* For example 3.75ns will return 3750.
  60669. +*
  60670. +* INPUT:
  60671. +* spd_byte - DIMM SPD byte.
  60672. +*
  60673. +* OUTPUT:
  60674. +* None.
  60675. +*
  60676. +* RETURN:
  60677. +* value in pico seconds.
  60678. +*
  60679. +*******************************************************************************/
  60680. +static MV_U32 cas2ps(MV_U8 spd_byte)
  60681. +{
  60682. + MV_U32 ns, ns10;
  60683. +
  60684. + /* isolate upper nibble */
  60685. + ns = (spd_byte >> 4) & 0x0F;
  60686. + /* isolate lower nibble */
  60687. + ns10 = (spd_byte & 0x0F);
  60688. +
  60689. + if( ns10 < 10 ) {
  60690. + ns10 *= 10;
  60691. + }
  60692. + else if( ns10 == 10 )
  60693. + ns10 = 25;
  60694. + else if( ns10 == 11 )
  60695. + ns10 = 33;
  60696. + else if( ns10 == 12 )
  60697. + ns10 = 66;
  60698. + else if( ns10 == 13 )
  60699. + ns10 = 75;
  60700. + else
  60701. + {
  60702. + mvOsOutput("cas2ps Err. unsupported cycle time.\n");
  60703. + }
  60704. +
  60705. + return (ns*1000 + ns10*10);
  60706. +}
  60707. +
  60708. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h
  60709. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h 1970-01-01 01:00:00.000000000 +0100
  60710. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h 2010-11-09 20:28:11.032495447 +0100
  60711. @@ -0,0 +1,192 @@
  60712. +/*******************************************************************************
  60713. +Copyright (C) Marvell International Ltd. and its affiliates
  60714. +
  60715. +This software file (the "File") is owned and distributed by Marvell
  60716. +International Ltd. and/or its affiliates ("Marvell") under the following
  60717. +alternative licensing terms. Once you have made an election to distribute the
  60718. +File under one of the following license alternatives, please (i) delete this
  60719. +introductory statement regarding license alternatives, (ii) delete the two
  60720. +license alternatives that you have not elected to use and (iii) preserve the
  60721. +Marvell copyright notice above.
  60722. +
  60723. +********************************************************************************
  60724. +Marvell Commercial License Option
  60725. +
  60726. +If you received this File from Marvell and you have entered into a commercial
  60727. +license agreement (a "Commercial License") with Marvell, the File is licensed
  60728. +to you under the terms of the applicable Commercial License.
  60729. +
  60730. +********************************************************************************
  60731. +Marvell GPL License Option
  60732. +
  60733. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60734. +modify this File in accordance with the terms and conditions of the General
  60735. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  60736. +available along with the File in the license.txt file or by writing to the Free
  60737. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  60738. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  60739. +
  60740. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  60741. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  60742. +DISCLAIMED. The GPL License provides additional details about this warranty
  60743. +disclaimer.
  60744. +********************************************************************************
  60745. +Marvell BSD License Option
  60746. +
  60747. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60748. +modify this File under the following licensing terms.
  60749. +Redistribution and use in source and binary forms, with or without modification,
  60750. +are permitted provided that the following conditions are met:
  60751. +
  60752. + * Redistributions of source code must retain the above copyright notice,
  60753. + this list of conditions and the following disclaimer.
  60754. +
  60755. + * Redistributions in binary form must reproduce the above copyright
  60756. + notice, this list of conditions and the following disclaimer in the
  60757. + documentation and/or other materials provided with the distribution.
  60758. +
  60759. + * Neither the name of Marvell nor the names of its contributors may be
  60760. + used to endorse or promote products derived from this software without
  60761. + specific prior written permission.
  60762. +
  60763. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  60764. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  60765. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  60766. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  60767. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  60768. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  60769. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  60770. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  60771. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  60772. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60773. +
  60774. +*******************************************************************************/
  60775. +
  60776. +#ifndef __INCmvDram
  60777. +#define __INCmvDram
  60778. +
  60779. +#include "ddr2/mvDramIf.h"
  60780. +#include "twsi/mvTwsi.h"
  60781. +
  60782. +#define MAX_DIMM_NUM 2
  60783. +#define SPD_SIZE 128
  60784. +
  60785. +/* Dimm spd offsets */
  60786. +#define DIMM_MEM_TYPE 2
  60787. +#define DIMM_ROW_NUM 3
  60788. +#define DIMM_COL_NUM 4
  60789. +#define DIMM_MODULE_BANK_NUM 5
  60790. +#define DIMM_DATA_WIDTH 6
  60791. +#define DIMM_VOLT_IF 8
  60792. +#define DIMM_MIN_CC_AT_MAX_CAS 9
  60793. +#define DIMM_ERR_CHECK_TYPE 11
  60794. +#define DIMM_REFRESH_INTERVAL 12
  60795. +#define DIMM_SDRAM_WIDTH 13
  60796. +#define DIMM_ERR_CHECK_DATA_WIDTH 14
  60797. +#define DIMM_MIN_CLK_DEL 15
  60798. +#define DIMM_BURST_LEN_SUP 16
  60799. +#define DIMM_DEV_BANK_NUM 17
  60800. +#define DIMM_SUP_CAL 18
  60801. +#define DIMM_DDR2_TYPE_INFORMATION 20 /* DDR2 only */
  60802. +#define DIMM_BUF_ADDR_CONT_IN 21
  60803. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1 23
  60804. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2 25
  60805. +#define DIMM_MIN_ROW_PRECHARGE_TIME 27
  60806. +#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE 28
  60807. +#define DIMM_MIN_RAS_TO_CAS_DELAY 29
  60808. +#define DIMM_MIN_RAS_PULSE_WIDTH 30
  60809. +#define DIMM_BANK_DENSITY 31
  60810. +#define DIMM_MIN_WRITE_RECOVERY_TIME 36
  60811. +#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY 37
  60812. +#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY 38
  60813. +#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD 42
  60814. +#define DIMM_SPD_VERSION 62
  60815. +
  60816. +/* Dimm Memory Type values */
  60817. +#define DIMM_MEM_TYPE_SDRAM 0x4
  60818. +#define DIMM_MEM_TYPE_DDR1 0x7
  60819. +#define DIMM_MEM_TYPE_DDR2 0x8
  60820. +
  60821. +#define DIMM_MODULE_MANU_OFFS 64
  60822. +#define DIMM_MODULE_MANU_SIZE 8
  60823. +#define DIMM_MODULE_VEN_OFFS 73
  60824. +#define DIMM_MODULE_VEN_SIZE 25
  60825. +#define DIMM_MODULE_ID_OFFS 99
  60826. +#define DIMM_MODULE_ID_SIZE 18
  60827. +
  60828. +/* enumeration for voltage levels. */
  60829. +typedef enum _mvDimmVoltageIf
  60830. +{
  60831. + TTL_5V_TOLERANT,
  60832. + LVTTL,
  60833. + HSTL_1_5V,
  60834. + SSTL_3_3V,
  60835. + SSTL_2_5V,
  60836. + VOLTAGE_UNKNOWN,
  60837. +} MV_DIMM_VOLTAGE_IF;
  60838. +
  60839. +
  60840. +/* enumaration for SDRAM CAS Latencies. */
  60841. +typedef enum _mvDimmSdramCas
  60842. +{
  60843. + SD_CL_1 =1,
  60844. + SD_CL_2,
  60845. + SD_CL_3,
  60846. + SD_CL_4,
  60847. + SD_CL_5,
  60848. + SD_CL_6,
  60849. + SD_CL_7,
  60850. + SD_FAULT
  60851. +}MV_DIMM_SDRAM_CAS;
  60852. +
  60853. +
  60854. +/* DIMM information structure */
  60855. +typedef struct _mvDimmInfo
  60856. +{
  60857. + MV_MEMORY_TYPE memoryType; /* DDR or SDRAM */
  60858. +
  60859. + MV_U8 spdRawData[SPD_SIZE]; /* Content of SPD-EEPROM copied 1:1 */
  60860. +
  60861. + /* DIMM dimensions */
  60862. + MV_U32 numOfRowAddr;
  60863. + MV_U32 numOfColAddr;
  60864. + MV_U32 numOfModuleBanks;
  60865. + MV_U32 dataWidth;
  60866. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  60867. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  60868. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  60869. + MV_U32 burstLengthSupported;
  60870. + MV_U32 numOfBanksOnEachDevice;
  60871. + MV_U32 suportedCasLatencies;
  60872. + MV_U32 refreshInterval;
  60873. + MV_U32 dimmBankDensity;
  60874. + MV_U32 dimmTypeInfo; /* DDR2 only */
  60875. + MV_U32 dimmAttributes;
  60876. +
  60877. + /* DIMM timing parameters */
  60878. + MV_U32 minCycleTimeAtMaxCasLatPs;
  60879. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  60880. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  60881. + MV_U32 minRowPrechargeTime;
  60882. + MV_U32 minRowActiveToRowActive;
  60883. + MV_U32 minRasToCasDelay;
  60884. + MV_U32 minRasPulseWidth;
  60885. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  60886. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  60887. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  60888. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  60889. +
  60890. + /* Parameters calculated from the extracted DIMM information */
  60891. + MV_U32 size; /* 16,64,128,256 or 512 MByte in MB units */
  60892. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit in MB units */
  60893. + MV_U32 numberOfDevices;
  60894. +
  60895. +} MV_DIMM_INFO;
  60896. +
  60897. +
  60898. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);
  60899. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);
  60900. +MV_VOID dimmSpdPrint(MV_U32 dimmNum);
  60901. +MV_STATUS dimmSpdCpy(MV_VOID);
  60902. +
  60903. +#endif /* __INCmvDram */
  60904. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c
  60905. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c 1970-01-01 01:00:00.000000000 +0100
  60906. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c 2010-11-09 20:28:11.042495489 +0100
  60907. @@ -0,0 +1,2952 @@
  60908. +/*******************************************************************************
  60909. +Copyright (C) Marvell International Ltd. and its affiliates
  60910. +
  60911. +This software file (the "File") is owned and distributed by Marvell
  60912. +International Ltd. and/or its affiliates ("Marvell") under the following
  60913. +alternative licensing terms. Once you have made an election to distribute the
  60914. +File under one of the following license alternatives, please (i) delete this
  60915. +introductory statement regarding license alternatives, (ii) delete the two
  60916. +license alternatives that you have not elected to use and (iii) preserve the
  60917. +Marvell copyright notice above.
  60918. +
  60919. +********************************************************************************
  60920. +Marvell Commercial License Option
  60921. +
  60922. +If you received this File from Marvell and you have entered into a commercial
  60923. +license agreement (a "Commercial License") with Marvell, the File is licensed
  60924. +to you under the terms of the applicable Commercial License.
  60925. +
  60926. +********************************************************************************
  60927. +Marvell GPL License Option
  60928. +
  60929. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60930. +modify this File in accordance with the terms and conditions of the General
  60931. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  60932. +available along with the File in the license.txt file or by writing to the Free
  60933. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  60934. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  60935. +
  60936. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  60937. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  60938. +DISCLAIMED. The GPL License provides additional details about this warranty
  60939. +disclaimer.
  60940. +********************************************************************************
  60941. +Marvell BSD License Option
  60942. +
  60943. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60944. +modify this File under the following licensing terms.
  60945. +Redistribution and use in source and binary forms, with or without modification,
  60946. +are permitted provided that the following conditions are met:
  60947. +
  60948. + * Redistributions of source code must retain the above copyright notice,
  60949. + this list of conditions and the following disclaimer.
  60950. +
  60951. + * Redistributions in binary form must reproduce the above copyright
  60952. + notice, this list of conditions and the following disclaimer in the
  60953. + documentation and/or other materials provided with the distribution.
  60954. +
  60955. + * Neither the name of Marvell nor the names of its contributors may be
  60956. + used to endorse or promote products derived from this software without
  60957. + specific prior written permission.
  60958. +
  60959. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  60960. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  60961. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  60962. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  60963. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  60964. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  60965. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  60966. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  60967. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  60968. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60969. +
  60970. +*******************************************************************************/
  60971. +
  60972. +/*******************************************************************************
  60973. +* mvEth.c - Marvell's Gigabit Ethernet controller low level driver
  60974. +*
  60975. +* DESCRIPTION:
  60976. +* This file introduce OS independent APIs to Marvell's Gigabit Ethernet
  60977. +* controller. This Gigabit Ethernet Controller driver API controls
  60978. +* 1) Operations (i.e. port Init, Finish, Up, Down, PhyReset etc').
  60979. +* 2) Data flow (i.e. port Send, Receive etc').
  60980. +* 3) MAC Filtering functions (ethSetMcastAddr, ethSetRxFilterMode, etc.)
  60981. +* 4) MIB counters support (ethReadMibCounter)
  60982. +* 5) Debug functions (ethPortRegs, ethPortCounters, ethPortQueues, etc.)
  60983. +* Each Gigabit Ethernet port is controlled via ETH_PORT_CTRL struct.
  60984. +* This struct includes configuration information as well as driver
  60985. +* internal data needed for its operations.
  60986. +*
  60987. +* Supported Features:
  60988. +* - OS independent. All required OS services are implemented via external
  60989. +* OS dependent components (like osLayer or ethOsg)
  60990. +* - The user is free from Rx/Tx queue managing.
  60991. +* - Simple Gigabit Ethernet port operation API.
  60992. +* - Simple Gigabit Ethernet port data flow API.
  60993. +* - Data flow and operation API support per queue functionality.
  60994. +* - Support cached descriptors for better performance.
  60995. +* - PHY access and control API.
  60996. +* - Port Configuration API.
  60997. +* - Full control over Special and Other Multicast MAC tables.
  60998. +*
  60999. +*******************************************************************************/
  61000. +/* includes */
  61001. +#include "mvTypes.h"
  61002. +#include "mv802_3.h"
  61003. +#include "mvDebug.h"
  61004. +#include "mvCommon.h"
  61005. +#include "mvOs.h"
  61006. +#include "ctrlEnv/mvCtrlEnvLib.h"
  61007. +#include "eth-phy/mvEthPhy.h"
  61008. +#include "eth/mvEth.h"
  61009. +#include "eth/gbe/mvEthGbe.h"
  61010. +#include "cpu/mvCpu.h"
  61011. +
  61012. +#ifdef INCLUDE_SYNC_BARR
  61013. +#include "sys/mvCpuIf.h"
  61014. +#endif
  61015. +
  61016. +#ifdef MV_RT_DEBUG
  61017. +# define ETH_DEBUG
  61018. +#endif
  61019. +
  61020. +
  61021. +/* locals */
  61022. +MV_BOOL ethDescInSram;
  61023. +MV_BOOL ethDescSwCoher;
  61024. +
  61025. +/* This array holds the control structure of each port */
  61026. +ETH_PORT_CTRL* ethPortCtrl[MV_ETH_MAX_PORTS];
  61027. +
  61028. +/* Ethernet Port Local routines */
  61029. +
  61030. +static void ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);
  61031. +
  61032. +static void ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);
  61033. +
  61034. +static void ethSetUcastTable(int portNo, int queue);
  61035. +
  61036. +static MV_BOOL ethSetUcastAddr (int ethPortNum, MV_U8 lastNibble, int queue);
  61037. +static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue);
  61038. +static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue);
  61039. +
  61040. +static void ethFreeDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, MV_BUF_INFO* pDescBuf);
  61041. +static MV_U8* ethAllocDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, int size,
  61042. + MV_ULONG* pPhysAddr, MV_U32 *memHandle);
  61043. +
  61044. +static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize);
  61045. +
  61046. +static void mvEthPortSgmiiConfig(int port);
  61047. +
  61048. +
  61049. +
  61050. +/******************************************************************************/
  61051. +/* EthDrv Initialization functions */
  61052. +/******************************************************************************/
  61053. +
  61054. +/*******************************************************************************
  61055. +* mvEthHalInit - Initialize the Giga Ethernet unit
  61056. +*
  61057. +* DESCRIPTION:
  61058. +* This function initialize the Giga Ethernet unit.
  61059. +* 1) Configure Address decode windows of the unit
  61060. +* 2) Set registers to HW default values.
  61061. +* 3) Clear and Disable interrupts
  61062. +*
  61063. +* INPUT: NONE
  61064. +*
  61065. +* RETURN: NONE
  61066. +*
  61067. +* NOTE: this function is called once in the boot process.
  61068. +*******************************************************************************/
  61069. +void mvEthHalInit(void)
  61070. +{
  61071. + int port;
  61072. +
  61073. + /* Init static data structures */
  61074. + for (port=0; port<MV_ETH_MAX_PORTS; port++)
  61075. + {
  61076. + ethPortCtrl[port] = NULL;
  61077. + }
  61078. + /* Power down all existing ports */
  61079. + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
  61080. + {
  61081. +
  61082. +#if defined (MV78200)
  61083. + /* Skip ports mapped to another CPU*/
  61084. + if (MV_FALSE == mvSocUnitIsMappedToThisCpu(GIGA0+port))
  61085. + {
  61086. + continue;
  61087. + }
  61088. +#endif
  61089. +
  61090. + /* Skip power down ports */
  61091. + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;
  61092. +
  61093. + /* Disable Giga Ethernet Unit interrupts */
  61094. + MV_REG_WRITE(ETH_UNIT_INTR_MASK_REG(port), 0);
  61095. +
  61096. + /* Clear ETH_UNIT_INTR_CAUSE_REG register */
  61097. + MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);
  61098. +
  61099. + }
  61100. +
  61101. + mvEthMemAttrGet(&ethDescInSram, &ethDescSwCoher);
  61102. +
  61103. +#if defined(ETH_DESCR_IN_SRAM)
  61104. + if(ethDescInSram == MV_FALSE)
  61105. + {
  61106. + mvOsPrintf("ethDrv: WARNING! Descriptors will be allocated in DRAM instead of SRAM.\n");
  61107. + }
  61108. +#endif /* ETH_DESCR_IN_SRAM */
  61109. +}
  61110. +
  61111. +/*******************************************************************************
  61112. +* mvEthMemAttrGet - Define properties (SRAM/DRAM, SW_COHER / HW_COHER / UNCACHED)
  61113. +* of of memory location for RX and TX descriptors.
  61114. +*
  61115. +* DESCRIPTION:
  61116. +* This function allocates memory for RX and TX descriptors.
  61117. +* - If ETH_DESCR_IN_SRAM defined, allocate from SRAM memory.
  61118. +* - If ETH_DESCR_IN_SDRAM defined, allocate from SDRAM memory.
  61119. +*
  61120. +* INPUT:
  61121. +* MV_BOOL* pIsSram - place of descriptors:
  61122. +* MV_TRUE - in SRAM
  61123. +* MV_FALSE - in DRAM
  61124. +* MV_BOOL* pIsSwCoher - cache coherency of descriptors:
  61125. +* MV_TRUE - driver is responsible for cache coherency
  61126. +* MV_FALSE - driver is not responsible for cache coherency
  61127. +*
  61128. +* RETURN:
  61129. +*
  61130. +*******************************************************************************/
  61131. +void mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher)
  61132. +{
  61133. + MV_BOOL isSram, isSwCoher;
  61134. +
  61135. + isSram = MV_FALSE;
  61136. +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW)
  61137. + isSwCoher = MV_TRUE;
  61138. +#else
  61139. + isSwCoher = MV_FALSE;
  61140. +#endif
  61141. +
  61142. +#if defined(ETH_DESCR_IN_SRAM)
  61143. + if( mvCtrlSramSizeGet() > 0)
  61144. + {
  61145. + isSram = MV_TRUE;
  61146. + #if (INTEG_SRAM_COHER == MV_CACHE_COHER_SW)
  61147. + isSwCoher = MV_TRUE;
  61148. + #else
  61149. + isSwCoher = MV_FALSE;
  61150. + #endif
  61151. + }
  61152. +#endif /* ETH_DESCR_IN_SRAM */
  61153. +
  61154. + if(pIsSram != NULL)
  61155. + *pIsSram = isSram;
  61156. +
  61157. + if(pIsSwCoher != NULL)
  61158. + *pIsSwCoher = isSwCoher;
  61159. +}
  61160. +
  61161. +
  61162. +
  61163. +/******************************************************************************/
  61164. +/* Port Initialization functions */
  61165. +/******************************************************************************/
  61166. +
  61167. +/*******************************************************************************
  61168. +* mvEthPortInit - Initialize the Ethernet port driver
  61169. +*
  61170. +* DESCRIPTION:
  61171. +* This function initialize the ethernet port.
  61172. +* 1) Allocate and initialize internal port Control structure.
  61173. +* 2) Create RX and TX descriptor rings for default RX and TX queues
  61174. +* 3) Disable RX and TX operations, clear cause registers and
  61175. +* mask all interrupts.
  61176. +* 4) Set all registers to default values and clean all MAC tables.
  61177. +*
  61178. +* INPUT:
  61179. +* int portNo - Ethernet port number
  61180. +* ETH_PORT_INIT *pEthPortInit - Ethernet port init structure
  61181. +*
  61182. +* RETURN:
  61183. +* void* - ethernet port handler, that should be passed to the most other
  61184. +* functions dealing with this port.
  61185. +*
  61186. +* NOTE: This function is called once per port when loading the eth module.
  61187. +*******************************************************************************/
  61188. +void* mvEthPortInit(int portNo, MV_ETH_PORT_INIT *pEthPortInit)
  61189. +{
  61190. + int queue, descSize;
  61191. + ETH_PORT_CTRL* pPortCtrl;
  61192. +
  61193. + /* Check validity of parameters */
  61194. + if( (portNo >= (int)mvCtrlEthMaxPortGet()) ||
  61195. + (pEthPortInit->rxDefQ >= MV_ETH_RX_Q_NUM) ||
  61196. + (pEthPortInit->maxRxPktSize < 1518) )
  61197. + {
  61198. + mvOsPrintf("EthPort #%d: Bad initialization parameters\n", portNo);
  61199. + return NULL;
  61200. + }
  61201. + if( (pEthPortInit->rxDescrNum[pEthPortInit->rxDefQ]) == 0)
  61202. + {
  61203. + mvOsPrintf("EthPort #%d: rxDefQ (%d) must be created\n",
  61204. + portNo, pEthPortInit->rxDefQ);
  61205. + return NULL;
  61206. + }
  61207. +
  61208. + pPortCtrl = (ETH_PORT_CTRL*)mvOsMalloc( sizeof(ETH_PORT_CTRL) );
  61209. + if(pPortCtrl == NULL)
  61210. + {
  61211. + mvOsPrintf("EthDrv: Can't allocate %dB for port #%d control structure!\n",
  61212. + (int)sizeof(ETH_PORT_CTRL), portNo);
  61213. + return NULL;
  61214. + }
  61215. +
  61216. + memset(pPortCtrl, 0, sizeof(ETH_PORT_CTRL) );
  61217. + ethPortCtrl[portNo] = pPortCtrl;
  61218. +
  61219. + pPortCtrl->portState = MV_UNDEFINED_STATE;
  61220. +
  61221. + pPortCtrl->portNo = portNo;
  61222. +
  61223. + pPortCtrl->osHandle = pEthPortInit->osHandle;
  61224. +
  61225. + /* Copy Configuration parameters */
  61226. + pPortCtrl->portConfig.maxRxPktSize = pEthPortInit->maxRxPktSize;
  61227. + pPortCtrl->portConfig.rxDefQ = pEthPortInit->rxDefQ;
  61228. + pPortCtrl->portConfig.ejpMode = 0;
  61229. +
  61230. + for( queue=0; queue<MV_ETH_RX_Q_NUM; queue++ )
  61231. + {
  61232. + pPortCtrl->rxQueueConfig[queue].descrNum = pEthPortInit->rxDescrNum[queue];
  61233. + }
  61234. + for( queue=0; queue<MV_ETH_TX_Q_NUM; queue++ )
  61235. + {
  61236. + pPortCtrl->txQueueConfig[queue].descrNum = pEthPortInit->txDescrNum[queue];
  61237. + }
  61238. +
  61239. + mvEthPortDisable(pPortCtrl);
  61240. +
  61241. + /* Set the board information regarding PHY address */
  61242. + mvEthPhyAddrSet(pPortCtrl, mvBoardPhyAddrGet(portNo) );
  61243. +
  61244. + /* Create all requested RX queues */
  61245. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  61246. + {
  61247. + if(pPortCtrl->rxQueueConfig[queue].descrNum == 0)
  61248. + continue;
  61249. +
  61250. + /* Allocate memory for RX descriptors */
  61251. + descSize = ((pPortCtrl->rxQueueConfig[queue].descrNum * ETH_RX_DESC_ALIGNED_SIZE) +
  61252. + CPU_D_CACHE_LINE_SIZE);
  61253. +
  61254. + pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr =
  61255. + ethAllocDescrMemory(pPortCtrl, descSize,
  61256. + &pPortCtrl->rxQueue[queue].descBuf.bufPhysAddr,
  61257. + &pPortCtrl->rxQueue[queue].descBuf.memHandle);
  61258. + pPortCtrl->rxQueue[queue].descBuf.bufSize = descSize;
  61259. + if(pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr == NULL)
  61260. + {
  61261. + mvOsPrintf("EthPort #%d, rxQ=%d: Can't allocate %d bytes in %s for %d RX descr\n",
  61262. + pPortCtrl->portNo, queue, descSize,
  61263. + ethDescInSram ? "SRAM" : "DRAM",
  61264. + pPortCtrl->rxQueueConfig[queue].descrNum);
  61265. + return NULL;
  61266. + }
  61267. +
  61268. + ethInitRxDescRing(pPortCtrl, queue);
  61269. + }
  61270. + /* Create TX queues */
  61271. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  61272. + {
  61273. + if(pPortCtrl->txQueueConfig[queue].descrNum == 0)
  61274. + continue;
  61275. +
  61276. + /* Allocate memory for TX descriptors */
  61277. + descSize = ((pPortCtrl->txQueueConfig[queue].descrNum * ETH_TX_DESC_ALIGNED_SIZE) +
  61278. + CPU_D_CACHE_LINE_SIZE);
  61279. +
  61280. + pPortCtrl->txQueue[queue].descBuf.bufVirtPtr =
  61281. + ethAllocDescrMemory(pPortCtrl, descSize,
  61282. + &pPortCtrl->txQueue[queue].descBuf.bufPhysAddr,
  61283. + &pPortCtrl->txQueue[queue].descBuf.memHandle);
  61284. + pPortCtrl->txQueue[queue].descBuf.bufSize = descSize;
  61285. + if(pPortCtrl->txQueue[queue].descBuf.bufVirtPtr == NULL)
  61286. + {
  61287. + mvOsPrintf("EthPort #%d, txQ=%d: Can't allocate %d bytes in %s for %d TX descr\n",
  61288. + pPortCtrl->portNo, queue, descSize, ethDescInSram ? "SRAM" : "DRAM",
  61289. + pPortCtrl->txQueueConfig[queue].descrNum);
  61290. + return NULL;
  61291. + }
  61292. +
  61293. + ethInitTxDescRing(pPortCtrl, queue);
  61294. + }
  61295. + mvEthDefaultsSet(pPortCtrl);
  61296. +
  61297. + pPortCtrl->portState = MV_IDLE;
  61298. + return pPortCtrl;
  61299. +}
  61300. +
  61301. +/*******************************************************************************
  61302. +* ethPortFinish - Finish the Ethernet port driver
  61303. +*
  61304. +* DESCRIPTION:
  61305. +* This function finish the ethernet port.
  61306. +* 1) Down ethernet port if needed.
  61307. +* 2) Delete RX and TX descriptor rings for all created RX and TX queues
  61308. +* 3) Free internal port Control structure.
  61309. +*
  61310. +* INPUT:
  61311. +* void* pEthPortHndl - Ethernet port handler
  61312. +*
  61313. +* RETURN: NONE.
  61314. +*
  61315. +*******************************************************************************/
  61316. +void mvEthPortFinish(void* pPortHndl)
  61317. +{
  61318. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  61319. + int queue, portNo = pPortCtrl->portNo;
  61320. +
  61321. + if(pPortCtrl->portState == MV_ACTIVE)
  61322. + {
  61323. + mvOsPrintf("ethPort #%d: Warning !!! Finish port in Active state\n",
  61324. + portNo);
  61325. + mvEthPortDisable(pPortHndl);
  61326. + }
  61327. +
  61328. + /* Free all allocated RX queues */
  61329. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  61330. + {
  61331. + ethFreeDescrMemory(pPortCtrl, &pPortCtrl->rxQueue[queue].descBuf);
  61332. + }
  61333. +
  61334. + /* Free all allocated TX queues */
  61335. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  61336. + {
  61337. + ethFreeDescrMemory(pPortCtrl, &pPortCtrl->txQueue[queue].descBuf);
  61338. + }
  61339. +
  61340. + /* Free port control structure */
  61341. + mvOsFree(pPortCtrl);
  61342. +
  61343. + ethPortCtrl[portNo] = NULL;
  61344. +}
  61345. +
  61346. +/*******************************************************************************
  61347. +* mvEthDefaultsSet - Set defaults to the ethernet port
  61348. +*
  61349. +* DESCRIPTION:
  61350. +* This function set default values to the ethernet port.
  61351. +* 1) Clear Cause registers and Mask all interrupts
  61352. +* 2) Clear all MAC tables
  61353. +* 3) Set defaults to all registers
  61354. +* 4) Reset all created RX and TX descriptors ring
  61355. +* 5) Reset PHY
  61356. +*
  61357. +* INPUT:
  61358. +* void* pEthPortHndl - Ethernet port handler
  61359. +*
  61360. +* RETURN: MV_STATUS
  61361. +* MV_OK - Success, Others - Failure
  61362. +* NOTE:
  61363. +* This function update all the port configuration except those set
  61364. +* Initialy by the OsGlue by MV_ETH_PORT_INIT.
  61365. +* This function can be called after portDown to return the port setting
  61366. +* to defaults.
  61367. +*******************************************************************************/
  61368. +MV_STATUS mvEthDefaultsSet(void* pPortHndl)
  61369. +{
  61370. + int ethPortNo, queue;
  61371. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  61372. + ETH_QUEUE_CTRL* pQueueCtrl;
  61373. + MV_U32 txPrio;
  61374. + MV_U32 portCfgReg, portCfgExtReg, portSerialCtrlReg, portSerialCtrl1Reg, portSdmaCfgReg;
  61375. + MV_BOARD_MAC_SPEED boardMacCfg;
  61376. +
  61377. + ethPortNo = pPortCtrl->portNo;
  61378. +
  61379. + /* Clear Cause registers */
  61380. + MV_REG_WRITE(ETH_INTR_CAUSE_REG(ethPortNo),0);
  61381. + MV_REG_WRITE(ETH_INTR_CAUSE_EXT_REG(ethPortNo),0);
  61382. +
  61383. + /* Mask all interrupts */
  61384. + MV_REG_WRITE(ETH_INTR_MASK_REG(ethPortNo),0);
  61385. + MV_REG_WRITE(ETH_INTR_MASK_EXT_REG(ethPortNo),0);
  61386. +
  61387. + portCfgReg = PORT_CONFIG_VALUE;
  61388. + portCfgExtReg = PORT_CONFIG_EXTEND_VALUE;
  61389. +
  61390. + boardMacCfg = mvBoardMacSpeedGet(ethPortNo);
  61391. +
  61392. + if(boardMacCfg == BOARD_MAC_SPEED_100M)
  61393. + {
  61394. + portSerialCtrlReg = PORT_SERIAL_CONTROL_100MB_FORCE_VALUE;
  61395. + }
  61396. + else if(boardMacCfg == BOARD_MAC_SPEED_1000M)
  61397. + {
  61398. + portSerialCtrlReg = PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE;
  61399. + }
  61400. + else
  61401. + {
  61402. + portSerialCtrlReg = PORT_SERIAL_CONTROL_VALUE;
  61403. + }
  61404. +
  61405. + /* build PORT_SDMA_CONFIG_REG */
  61406. + portSdmaCfgReg = ETH_TX_INTR_COAL_MASK(0);
  61407. + portSdmaCfgReg |= ETH_TX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);
  61408. +
  61409. +#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB) || \
  61410. + (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT) )
  61411. + /* some devices have restricted RX burst size when using HW coherency */
  61412. + portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_4_64BIT_VALUE);
  61413. +#else
  61414. + portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);
  61415. +#endif
  61416. +
  61417. +#if defined(MV_CPU_BE)
  61418. + /* big endian */
  61419. +# if defined(MV_ARM)
  61420. + portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK |
  61421. + ETH_TX_NO_DATA_SWAP_MASK |
  61422. + ETH_DESC_SWAP_MASK);
  61423. +# elif defined(MV_PPC)
  61424. + portSdmaCfgReg |= (ETH_RX_DATA_SWAP_MASK |
  61425. + ETH_TX_DATA_SWAP_MASK |
  61426. + ETH_NO_DESC_SWAP_MASK);
  61427. +# else
  61428. +# error "Giga Ethernet Swap policy is not defined for the CPU_ARCH"
  61429. +# endif /* MV_ARM / MV_PPC */
  61430. +
  61431. +#else /* MV_CPU_LE */
  61432. + /* little endian */
  61433. + portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK |
  61434. + ETH_TX_NO_DATA_SWAP_MASK |
  61435. + ETH_NO_DESC_SWAP_MASK);
  61436. +#endif /* MV_CPU_BE / MV_CPU_LE */
  61437. +
  61438. + pPortCtrl->portRxQueueCmdReg = 0;
  61439. + pPortCtrl->portTxQueueCmdReg = 0;
  61440. +
  61441. +#if (MV_ETH_VERSION >= 4)
  61442. + if(pPortCtrl->portConfig.ejpMode == MV_TRUE)
  61443. + {
  61444. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), ETH_TX_EJP_ENABLE_MASK);
  61445. + }
  61446. + else
  61447. + {
  61448. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), 0)
  61449. + }
  61450. +#endif /* (MV_ETH_VERSION >= 4) */
  61451. +
  61452. + ethSetUcastTable(ethPortNo, -1);
  61453. + mvEthSetSpecialMcastTable(ethPortNo, -1);
  61454. + mvEthSetOtherMcastTable(ethPortNo, -1);
  61455. +
  61456. + portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;
  61457. +
  61458. + portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);
  61459. +
  61460. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);
  61461. +
  61462. + /* Update value of PortConfig register accordingly with all RxQueue types */
  61463. + pPortCtrl->portConfig.rxArpQ = pPortCtrl->portConfig.rxDefQ;
  61464. + pPortCtrl->portConfig.rxBpduQ = pPortCtrl->portConfig.rxDefQ;
  61465. + pPortCtrl->portConfig.rxTcpQ = pPortCtrl->portConfig.rxDefQ;
  61466. + pPortCtrl->portConfig.rxUdpQ = pPortCtrl->portConfig.rxDefQ;
  61467. +
  61468. + portCfgReg &= ~ETH_DEF_RX_QUEUE_ALL_MASK;
  61469. + portCfgReg |= ETH_DEF_RX_QUEUE_MASK(pPortCtrl->portConfig.rxDefQ);
  61470. +
  61471. + portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;
  61472. + portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ);
  61473. +
  61474. + portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;
  61475. + portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);
  61476. +
  61477. + portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;
  61478. + portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);
  61479. +
  61480. + portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;
  61481. + portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);
  61482. +
  61483. + /* Assignment of Tx CTRP of given queue */
  61484. + txPrio = 0;
  61485. +
  61486. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  61487. + {
  61488. + pQueueCtrl = &pPortCtrl->txQueue[queue];
  61489. +
  61490. + if(pQueueCtrl->pFirstDescr != NULL)
  61491. + {
  61492. + ethResetTxDescRing(pPortCtrl, queue);
  61493. +
  61494. + MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue),
  61495. + 0x3fffffff);
  61496. + MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue),
  61497. + 0x03ffffff);
  61498. + }
  61499. + else
  61500. + {
  61501. + MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue), 0x0);
  61502. + MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue), 0x0);
  61503. + }
  61504. + }
  61505. +
  61506. + /* Assignment of Rx CRDP of given queue */
  61507. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  61508. + {
  61509. + ethResetRxDescRing(pPortCtrl, queue);
  61510. + }
  61511. +
  61512. + /* Allow receiving packes with odd number of preamble nibbles */
  61513. + portSerialCtrl1Reg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo));
  61514. + portSerialCtrl1Reg |= ETH_EN_MII_ODD_PRE_MASK;
  61515. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo), portSerialCtrl1Reg);
  61516. +
  61517. + /* Assign port configuration and command. */
  61518. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(ethPortNo), portCfgReg);
  61519. +
  61520. + MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(ethPortNo), portCfgExtReg);
  61521. +
  61522. + /* Assign port SDMA configuration */
  61523. + MV_REG_WRITE(ETH_SDMA_CONFIG_REG(ethPortNo), portSdmaCfgReg);
  61524. +
  61525. + /* Turn off the port/queue bandwidth limitation */
  61526. + MV_REG_WRITE(ETH_MAX_TRANSMIT_UNIT_REG(ethPortNo), 0x0);
  61527. +
  61528. + return MV_OK;
  61529. +}
  61530. +
  61531. +/*******************************************************************************
  61532. +* ethPortUp - Start the Ethernet port RX and TX activity.
  61533. +*
  61534. +* DESCRIPTION:
  61535. +* This routine start Rx and Tx activity:
  61536. +*
  61537. +* Note: Each Rx and Tx queue descriptor's list must be initialized prior
  61538. +* to calling this function (use etherInitTxDescRing for Tx queues and
  61539. +* etherInitRxDescRing for Rx queues).
  61540. +*
  61541. +* INPUT:
  61542. +* void* pEthPortHndl - Ethernet port handler
  61543. +*
  61544. +* RETURN: MV_STATUS
  61545. +* MV_OK - Success, Others - Failure.
  61546. +*
  61547. +* NOTE : used for port link up.
  61548. +*******************************************************************************/
  61549. +MV_STATUS mvEthPortUp(void* pEthPortHndl)
  61550. +{
  61551. + int ethPortNo;
  61552. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  61553. +
  61554. + ethPortNo = pPortCtrl->portNo;
  61555. +
  61556. + if( (pPortCtrl->portState != MV_ACTIVE) &&
  61557. + (pPortCtrl->portState != MV_PAUSED) )
  61558. + {
  61559. + mvOsPrintf("ethDrv port%d: Unexpected port state %d\n",
  61560. + ethPortNo, pPortCtrl->portState);
  61561. + return MV_BAD_STATE;
  61562. + }
  61563. +
  61564. + ethPortNo = pPortCtrl->portNo;
  61565. +
  61566. + /* Enable port RX. */
  61567. + MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNo), pPortCtrl->portRxQueueCmdReg);
  61568. +
  61569. + /* Enable port TX. */
  61570. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(ethPortNo)) = pPortCtrl->portTxQueueCmdReg;
  61571. +
  61572. + pPortCtrl->portState = MV_ACTIVE;
  61573. +
  61574. + return MV_OK;
  61575. +}
  61576. +
  61577. +/*******************************************************************************
  61578. +* ethPortDown - Stop the Ethernet port activity.
  61579. +*
  61580. +* DESCRIPTION:
  61581. +*
  61582. +* INPUT:
  61583. +* void* pEthPortHndl - Ethernet port handler
  61584. +*
  61585. +* RETURN: MV_STATUS
  61586. +* MV_OK - Success, Others - Failure.
  61587. +*
  61588. +* NOTE : used for port link down.
  61589. +*******************************************************************************/
  61590. +MV_STATUS mvEthPortDown(void* pEthPortHndl)
  61591. +{
  61592. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  61593. + int ethPortNum = pPortCtrl->portNo;
  61594. + unsigned int regData;
  61595. + volatile int uDelay, mDelay;
  61596. +
  61597. + /* Stop Rx port activity. Check port Rx activity. */
  61598. + regData = (MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_RXQ_ENABLE_MASK;
  61599. + if(regData != 0)
  61600. + {
  61601. + /* Issue stop command for active channels only */
  61602. + MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNum), (regData << ETH_RXQ_DISABLE_OFFSET));
  61603. + }
  61604. +
  61605. + /* Stop Tx port activity. Check port Tx activity. */
  61606. + regData = (MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_TXQ_ENABLE_MASK;
  61607. + if(regData != 0)
  61608. + {
  61609. + /* Issue stop command for active channels only */
  61610. + MV_REG_WRITE(ETH_TX_QUEUE_COMMAND_REG(ethPortNum),
  61611. + (regData << ETH_TXQ_DISABLE_OFFSET) );
  61612. + }
  61613. +
  61614. + /* Force link down */
  61615. +/*
  61616. + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
  61617. + regData &= ~(ETH_DO_NOT_FORCE_LINK_FAIL_MASK);
  61618. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
  61619. +*/
  61620. + /* Wait for all Rx activity to terminate. */
  61621. + mDelay = 0;
  61622. + do
  61623. + {
  61624. + if(mDelay >= RX_DISABLE_TIMEOUT_MSEC)
  61625. + {
  61626. + mvOsPrintf("ethPort_%d: TIMEOUT for RX stopped !!! rxQueueCmd - 0x08%x\n",
  61627. + ethPortNum, regData);
  61628. + break;
  61629. + }
  61630. + mvOsDelay(1);
  61631. + mDelay++;
  61632. +
  61633. + /* Check port RX Command register that all Rx queues are stopped */
  61634. + regData = MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum));
  61635. + }
  61636. + while(regData & 0xFF);
  61637. +
  61638. + /* Wait for all Tx activity to terminate. */
  61639. + mDelay = 0;
  61640. + do
  61641. + {
  61642. + if(mDelay >= TX_DISABLE_TIMEOUT_MSEC)
  61643. + {
  61644. + mvOsPrintf("ethPort_%d: TIMEOUT for TX stoped !!! txQueueCmd - 0x08%x\n",
  61645. + ethPortNum, regData);
  61646. + break;
  61647. + }
  61648. + mvOsDelay(1);
  61649. + mDelay++;
  61650. +
  61651. + /* Check port TX Command register that all Tx queues are stopped */
  61652. + regData = MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum));
  61653. + }
  61654. + while(regData & 0xFF);
  61655. +
  61656. + /* Double check to Verify that TX FIFO is Empty */
  61657. + mDelay = 0;
  61658. + while(MV_TRUE)
  61659. + {
  61660. + do
  61661. + {
  61662. + if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)
  61663. + {
  61664. + mvOsPrintf("\n ethPort_%d: TIMEOUT for TX FIFO empty !!! portStatus - 0x08%x\n",
  61665. + ethPortNum, regData);
  61666. + break;
  61667. + }
  61668. + mvOsDelay(1);
  61669. + mDelay++;
  61670. +
  61671. + regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));
  61672. + }
  61673. + while( ((regData & ETH_TX_FIFO_EMPTY_MASK) == 0) ||
  61674. + ((regData & ETH_TX_IN_PROGRESS_MASK) != 0) );
  61675. +
  61676. + if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)
  61677. + break;
  61678. +
  61679. + /* Double check */
  61680. + regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));
  61681. + if( ((regData & ETH_TX_FIFO_EMPTY_MASK) != 0) &&
  61682. + ((regData & ETH_TX_IN_PROGRESS_MASK) == 0) )
  61683. + {
  61684. + break;
  61685. + }
  61686. + else
  61687. + mvOsPrintf("ethPort_%d: TX FIFO Empty double check failed. %d msec, portStatus=0x%x\n",
  61688. + ethPortNum, mDelay, regData);
  61689. + }
  61690. +
  61691. + /* Do NOT force link down */
  61692. +/*
  61693. + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
  61694. + regData |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK);
  61695. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
  61696. +*/
  61697. + /* Wait about 2500 tclk cycles */
  61698. + uDelay = (PORT_DISABLE_WAIT_TCLOCKS/(mvBoardTclkGet()/1000000));
  61699. + mvOsUDelay(uDelay);
  61700. +
  61701. + pPortCtrl->portState = MV_PAUSED;
  61702. +
  61703. + return MV_OK;
  61704. +}
  61705. +
  61706. +
  61707. +/*******************************************************************************
  61708. +* ethPortEnable - Enable the Ethernet port and Start RX and TX.
  61709. +*
  61710. +* DESCRIPTION:
  61711. +* This routine enable the Ethernet port and Rx and Tx activity:
  61712. +*
  61713. +* Note: Each Rx and Tx queue descriptor's list must be initialized prior
  61714. +* to calling this function (use etherInitTxDescRing for Tx queues and
  61715. +* etherInitRxDescRing for Rx queues).
  61716. +*
  61717. +* INPUT:
  61718. +* void* pEthPortHndl - Ethernet port handler
  61719. +*
  61720. +* RETURN: MV_STATUS
  61721. +* MV_OK - Success, Others - Failure.
  61722. +*
  61723. +* NOTE: main usage is to enable the port after ifconfig up.
  61724. +*******************************************************************************/
  61725. +MV_STATUS mvEthPortEnable(void* pEthPortHndl)
  61726. +{
  61727. + int ethPortNo;
  61728. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  61729. + MV_U32 portSerialCtrlReg;
  61730. +
  61731. + ethPortNo = pPortCtrl->portNo;
  61732. +
  61733. + /* Enable port */
  61734. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNo));
  61735. + portSerialCtrlReg |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK | ETH_PORT_ENABLE_MASK);
  61736. +
  61737. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);
  61738. +
  61739. + mvEthMibCountersClear(pEthPortHndl);
  61740. +
  61741. + pPortCtrl->portState = MV_PAUSED;
  61742. +
  61743. + /* If Link is UP, Start RX and TX traffic */
  61744. + if( MV_REG_READ( ETH_PORT_STATUS_REG(ethPortNo) ) & ETH_LINK_UP_MASK)
  61745. + return( mvEthPortUp(pEthPortHndl) );
  61746. +
  61747. + return MV_NOT_READY;
  61748. +}
  61749. +
  61750. +
  61751. +/*******************************************************************************
  61752. +* mvEthPortDisable - Stop RX and TX activities and Disable the Ethernet port.
  61753. +*
  61754. +* DESCRIPTION:
  61755. +*
  61756. +* INPUT:
  61757. +* void* pEthPortHndl - Ethernet port handler
  61758. +*
  61759. +* RETURN: MV_STATUS
  61760. +* MV_OK - Success, Others - Failure.
  61761. +*
  61762. +* NOTE: main usage is to disable the port after ifconfig down.
  61763. +*******************************************************************************/
  61764. +MV_STATUS mvEthPortDisable(void* pEthPortHndl)
  61765. +{
  61766. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  61767. + int ethPortNum = pPortCtrl->portNo;
  61768. + unsigned int regData;
  61769. + volatile int mvDelay;
  61770. +
  61771. + if(pPortCtrl->portState == MV_ACTIVE)
  61772. + {
  61773. + /* Stop RX and TX activities */
  61774. + mvEthPortDown(pEthPortHndl);
  61775. + }
  61776. +
  61777. + /* Reset the Enable bit in the Serial Control Register */
  61778. + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
  61779. + regData &= ~(ETH_PORT_ENABLE_MASK);
  61780. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
  61781. +
  61782. + /* Wait about 2500 tclk cycles */
  61783. + mvDelay = (PORT_DISABLE_WAIT_TCLOCKS*(mvCpuPclkGet()/mvBoardTclkGet()));
  61784. + for(mvDelay; mvDelay>0; mvDelay--);
  61785. +
  61786. + pPortCtrl->portState = MV_IDLE;
  61787. + return MV_OK;
  61788. +}
  61789. +
  61790. +/*******************************************************************************
  61791. +* mvEthPortForceTxDone - Get next buffer from TX queue in spite of buffer ownership.
  61792. +*
  61793. +* DESCRIPTION:
  61794. +* This routine used to free buffers attached to the Tx ring and should
  61795. +* be called only when Giga Ethernet port is Down
  61796. +*
  61797. +* INPUT:
  61798. +* void* pEthPortHndl - Ethernet Port handler.
  61799. +* int txQueue - Number of TX queue.
  61800. +*
  61801. +* OUTPUT:
  61802. +* MV_PKT_INFO *pPktInfo - Pointer to packet was sent.
  61803. +*
  61804. +* RETURN:
  61805. +* MV_EMPTY - There is no more buffers in this queue.
  61806. +* MV_OK - Buffer detached from the queue and pPktInfo structure
  61807. +* filled with relevant information.
  61808. +*
  61809. +*******************************************************************************/
  61810. +MV_PKT_INFO* mvEthPortForceTxDone(void* pEthPortHndl, int txQueue)
  61811. +{
  61812. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  61813. + ETH_QUEUE_CTRL* pQueueCtrl;
  61814. + MV_PKT_INFO* pPktInfo;
  61815. + ETH_TX_DESC* pTxDesc;
  61816. + int port = pPortCtrl->portNo;
  61817. +
  61818. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  61819. +
  61820. + while( (pQueueCtrl->pUsedDescr != pQueueCtrl->pCurrentDescr) ||
  61821. + (pQueueCtrl->resource == 0) )
  61822. + {
  61823. + /* Free next descriptor */
  61824. + pQueueCtrl->resource++;
  61825. + pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pUsedDescr;
  61826. +
  61827. + /* pPktInfo is available only in descriptors which are last descriptors */
  61828. + pPktInfo = (MV_PKT_INFO*)pTxDesc->returnInfo;
  61829. + if (pPktInfo)
  61830. + pPktInfo->status = pTxDesc->cmdSts;
  61831. +
  61832. + pTxDesc->cmdSts = 0x0;
  61833. + pTxDesc->returnInfo = 0x0;
  61834. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);
  61835. +
  61836. + pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);
  61837. +
  61838. + if (pPktInfo)
  61839. + if (pPktInfo->status & ETH_TX_LAST_DESC_MASK)
  61840. + return pPktInfo;
  61841. + }
  61842. + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(port, txQueue),
  61843. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  61844. + return NULL;
  61845. +}
  61846. +
  61847. +
  61848. +
  61849. +/*******************************************************************************
  61850. +* mvEthPortForceRx - Get next buffer from RX queue in spite of buffer ownership.
  61851. +*
  61852. +* DESCRIPTION:
  61853. +* This routine used to free buffers attached to the Rx ring and should
  61854. +* be called only when Giga Ethernet port is Down
  61855. +*
  61856. +* INPUT:
  61857. +* void* pEthPortHndl - Ethernet Port handler.
  61858. +* int rxQueue - Number of Rx queue.
  61859. +*
  61860. +* OUTPUT:
  61861. +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
  61862. +*
  61863. +* RETURN:
  61864. +* MV_EMPTY - There is no more buffers in this queue.
  61865. +* MV_OK - Buffer detached from the queue and pBufInfo structure
  61866. +* filled with relevant information.
  61867. +*
  61868. +*******************************************************************************/
  61869. +MV_PKT_INFO* mvEthPortForceRx(void* pEthPortHndl, int rxQueue)
  61870. +{
  61871. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  61872. + ETH_QUEUE_CTRL* pQueueCtrl;
  61873. + ETH_RX_DESC* pRxDesc;
  61874. + MV_PKT_INFO* pPktInfo;
  61875. + int port = pPortCtrl->portNo;
  61876. +
  61877. + pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
  61878. +
  61879. + if(pQueueCtrl->resource == 0)
  61880. + {
  61881. + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue),
  61882. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  61883. +
  61884. + return NULL;
  61885. + }
  61886. + /* Free next descriptor */
  61887. + pQueueCtrl->resource--;
  61888. + pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pCurrentDescr;
  61889. + pPktInfo = (MV_PKT_INFO*)pRxDesc->returnInfo;
  61890. +
  61891. + pPktInfo->status = pRxDesc->cmdSts;
  61892. + pRxDesc->cmdSts = 0x0;
  61893. + pRxDesc->returnInfo = 0x0;
  61894. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);
  61895. +
  61896. + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);
  61897. + return pPktInfo;
  61898. +}
  61899. +
  61900. +
  61901. +/******************************************************************************/
  61902. +/* Port Configuration functions */
  61903. +/******************************************************************************/
  61904. +/*******************************************************************************
  61905. +* mvEthMruGet - Get MRU configuration for Max Rx packet size.
  61906. +*
  61907. +* INPUT:
  61908. +* MV_U32 maxRxPktSize - max packet size.
  61909. +*
  61910. +* RETURN: MV_U32 - MRU configuration.
  61911. +*
  61912. +*******************************************************************************/
  61913. +static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize)
  61914. +{
  61915. + MV_U32 portSerialCtrlReg = 0;
  61916. +
  61917. + if(maxRxPktSize > 9192)
  61918. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9700BYTE;
  61919. + else if(maxRxPktSize > 9022)
  61920. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9192BYTE;
  61921. + else if(maxRxPktSize > 1552)
  61922. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9022BYTE;
  61923. + else if(maxRxPktSize > 1522)
  61924. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1552BYTE;
  61925. + else if(maxRxPktSize > 1518)
  61926. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1522BYTE;
  61927. + else
  61928. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1518BYTE;
  61929. +
  61930. + return portSerialCtrlReg;
  61931. +}
  61932. +
  61933. +/*******************************************************************************
  61934. +* mvEthRxCoalSet - Sets coalescing interrupt mechanism on RX path
  61935. +*
  61936. +* DESCRIPTION:
  61937. +* This routine sets the RX coalescing interrupt mechanism parameter.
  61938. +* This parameter is a timeout counter, that counts in 64 tClk
  61939. +* chunks, that when timeout event occurs a maskable interrupt occurs.
  61940. +* The parameter is calculated using the tCLK frequency of the
  61941. +* MV-64xxx chip, and the required number is in micro seconds.
  61942. +*
  61943. +* INPUT:
  61944. +* void* pPortHndl - Ethernet Port handler.
  61945. +* MV_U32 uSec - Number of micro seconds between
  61946. +* RX interrupts
  61947. +*
  61948. +* RETURN:
  61949. +* None.
  61950. +*
  61951. +* COMMENT:
  61952. +* 1 sec - TCLK_RATE clocks
  61953. +* 1 uSec - TCLK_RATE / 1,000,000 clocks
  61954. +*
  61955. +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
  61956. +*
  61957. +* RETURN:
  61958. +* None.
  61959. +*
  61960. +*******************************************************************************/
  61961. +MV_U32 mvEthRxCoalSet (void* pPortHndl, MV_U32 uSec)
  61962. +{
  61963. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  61964. + MV_U32 coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);
  61965. + MV_U32 portSdmaCfgReg;
  61966. +
  61967. + portSdmaCfgReg = MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));
  61968. + portSdmaCfgReg &= ~ETH_RX_INTR_COAL_ALL_MASK;
  61969. +
  61970. + portSdmaCfgReg |= ETH_RX_INTR_COAL_MASK(coal);
  61971. +
  61972. +#if (MV_ETH_VERSION >= 2)
  61973. + /* Set additional bit if needed ETH_RX_INTR_COAL_MSB_BIT (25) */
  61974. + if(ETH_RX_INTR_COAL_MASK(coal) > ETH_RX_INTR_COAL_ALL_MASK)
  61975. + portSdmaCfgReg |= ETH_RX_INTR_COAL_MSB_MASK;
  61976. +#endif /* MV_ETH_VERSION >= 2 */
  61977. +
  61978. + MV_REG_WRITE (ETH_SDMA_CONFIG_REG(pPortCtrl->portNo), portSdmaCfgReg);
  61979. + return coal;
  61980. +}
  61981. +
  61982. +/*******************************************************************************
  61983. +* mvEthTxCoalSet - Sets coalescing interrupt mechanism on TX path
  61984. +*
  61985. +* DESCRIPTION:
  61986. +* This routine sets the TX coalescing interrupt mechanism parameter.
  61987. +* This parameter is a timeout counter, that counts in 64 tClk
  61988. +* chunks, that when timeout event occurs a maskable interrupt
  61989. +* occurs.
  61990. +* The parameter is calculated using the tCLK frequency of the
  61991. +* MV-64xxx chip, and the required number is in micro seconds.
  61992. +*
  61993. +* INPUT:
  61994. +* void* pPortHndl - Ethernet Port handler.
  61995. +* MV_U32 uSec - Number of micro seconds between
  61996. +* RX interrupts
  61997. +*
  61998. +* RETURN:
  61999. +* None.
  62000. +*
  62001. +* COMMENT:
  62002. +* 1 sec - TCLK_RATE clocks
  62003. +* 1 uSec - TCLK_RATE / 1,000,000 clocks
  62004. +*
  62005. +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
  62006. +*
  62007. +*******************************************************************************/
  62008. +MV_U32 mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec)
  62009. +{
  62010. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62011. + MV_U32 coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);
  62012. + MV_U32 regVal;
  62013. +
  62014. + regVal = MV_REG_READ(ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));
  62015. + regVal &= ~ETH_TX_INTR_COAL_ALL_MASK;
  62016. + regVal |= ETH_TX_INTR_COAL_MASK(coal);
  62017. +
  62018. + /* Set TX Coalescing mechanism */
  62019. + MV_REG_WRITE (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo), regVal);
  62020. + return coal;
  62021. +}
  62022. +
  62023. +/*******************************************************************************
  62024. +* mvEthCoalGet - Gets RX and TX coalescing values in micro seconds
  62025. +*
  62026. +* DESCRIPTION:
  62027. +* This routine gets the RX and TX coalescing interrupt values.
  62028. +* The parameter is calculated using the tCLK frequency of the
  62029. +* MV-64xxx chip, and the returned numbers are in micro seconds.
  62030. +*
  62031. +* INPUTs:
  62032. +* void* pPortHndl - Ethernet Port handler.
  62033. +*
  62034. +* OUTPUTs:
  62035. +* MV_U32* pRxCoal - Number of micro seconds between RX interrupts
  62036. +* MV_U32* pTxCoal - Number of micro seconds between TX interrupts
  62037. +*
  62038. +* RETURN:
  62039. +* MV_STATUS MV_OK - success
  62040. +* Others - failure.
  62041. +*
  62042. +* COMMENT:
  62043. +* 1 sec - TCLK_RATE clocks
  62044. +* 1 uSec - TCLK_RATE / 1,000,000 clocks
  62045. +*
  62046. +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
  62047. +*
  62048. +*******************************************************************************/
  62049. +MV_STATUS mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal)
  62050. +{
  62051. + MV_U32 regVal, coal, usec;
  62052. +
  62053. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62054. +
  62055. + /* get TX Coalescing */
  62056. + regVal = MV_REG_READ (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));
  62057. + coal = ((regVal & ETH_TX_INTR_COAL_ALL_MASK) >> ETH_TX_INTR_COAL_OFFSET);
  62058. +
  62059. + usec = (coal * 64) / (mvBoardTclkGet() / 1000000);
  62060. + if(pTxCoal != NULL)
  62061. + *pTxCoal = usec;
  62062. +
  62063. + /* Get RX Coalescing */
  62064. + regVal = MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));
  62065. + coal = ((regVal & ETH_RX_INTR_COAL_ALL_MASK) >> ETH_RX_INTR_COAL_OFFSET);
  62066. +
  62067. +#if (MV_ETH_VERSION >= 2)
  62068. + if(regVal & ETH_RX_INTR_COAL_MSB_MASK)
  62069. + {
  62070. + /* Add MSB */
  62071. + coal |= (ETH_RX_INTR_COAL_ALL_MASK + 1);
  62072. + }
  62073. +#endif /* MV_ETH_VERSION >= 2 */
  62074. +
  62075. + usec = (coal * 64) / (mvBoardTclkGet() / 1000000);
  62076. + if(pRxCoal != NULL)
  62077. + *pRxCoal = usec;
  62078. +
  62079. + return MV_OK;
  62080. +}
  62081. +
  62082. +/*******************************************************************************
  62083. +* mvEthMaxRxSizeSet -
  62084. +*
  62085. +* DESCRIPTION:
  62086. +* Change maximum receive size of the port. This configuration will take place
  62087. +* after next call of ethPortSetDefaults() function.
  62088. +*
  62089. +* INPUT:
  62090. +*
  62091. +* RETURN:
  62092. +*******************************************************************************/
  62093. +MV_STATUS mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize)
  62094. +{
  62095. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62096. + MV_U32 portSerialCtrlReg;
  62097. +
  62098. + if((maxRxSize < 1518) || (maxRxSize & ~ETH_RX_BUFFER_MASK))
  62099. + return MV_BAD_PARAM;
  62100. +
  62101. + pPortCtrl->portConfig.maxRxPktSize = maxRxSize;
  62102. +
  62103. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo));
  62104. + portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;
  62105. + portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);
  62106. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo), portSerialCtrlReg);
  62107. +
  62108. + return MV_OK;
  62109. +}
  62110. +
  62111. +
  62112. +/******************************************************************************/
  62113. +/* MAC Filtering functions */
  62114. +/******************************************************************************/
  62115. +
  62116. +/*******************************************************************************
  62117. +* mvEthRxFilterModeSet - Configure Fitering mode of Ethernet port
  62118. +*
  62119. +* DESCRIPTION:
  62120. +* This routine used to free buffers attached to the Rx ring and should
  62121. +* be called only when Giga Ethernet port is Down
  62122. +*
  62123. +* INPUT:
  62124. +* void* pEthPortHndl - Ethernet Port handler.
  62125. +* MV_BOOL isPromisc - Promiscous mode
  62126. +* MV_TRUE - accept all Broadcast, Multicast
  62127. +* and Unicast packets
  62128. +* MV_FALSE - accept all Broadcast,
  62129. +* specially added Multicast and
  62130. +* single Unicast packets
  62131. +*
  62132. +* RETURN: MV_STATUS MV_OK - Success, Other - Failure
  62133. +*
  62134. +*******************************************************************************/
  62135. +MV_STATUS mvEthRxFilterModeSet(void* pEthPortHndl, MV_BOOL isPromisc)
  62136. +{
  62137. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  62138. + int queue;
  62139. + MV_U32 portCfgReg;
  62140. +
  62141. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  62142. + /* Set / Clear UPM bit in port configuration register */
  62143. + if(isPromisc)
  62144. + {
  62145. + /* Accept all multicast packets to RX default queue */
  62146. + queue = pPortCtrl->portConfig.rxDefQ;
  62147. + portCfgReg |= ETH_UNICAST_PROMISCUOUS_MODE_MASK;
  62148. + memset(pPortCtrl->mcastCount, 1, sizeof(pPortCtrl->mcastCount));
  62149. + MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo),0xFFFF);
  62150. + MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo),0xFFFFFFFF);
  62151. + }
  62152. + else
  62153. + {
  62154. + /* Reject all Multicast addresses */
  62155. + queue = -1;
  62156. + portCfgReg &= ~ETH_UNICAST_PROMISCUOUS_MODE_MASK;
  62157. + /* Clear all mcastCount */
  62158. + memset(pPortCtrl->mcastCount, 0, sizeof(pPortCtrl->mcastCount));
  62159. + }
  62160. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  62161. +
  62162. + /* Set Special Multicast and Other Multicast tables */
  62163. + mvEthSetSpecialMcastTable(pPortCtrl->portNo, queue);
  62164. + mvEthSetOtherMcastTable(pPortCtrl->portNo, queue);
  62165. + ethSetUcastTable(pPortCtrl->portNo, queue);
  62166. +
  62167. + return MV_OK;
  62168. +}
  62169. +
  62170. +/*******************************************************************************
  62171. +* mvEthMacAddrSet - This function Set the port Unicast address.
  62172. +*
  62173. +* DESCRIPTION:
  62174. +* This function Set the port Ethernet MAC address. This address
  62175. +* will be used to send Pause frames if enabled. Packets with this
  62176. +* address will be accepted and dispatched to default RX queue
  62177. +*
  62178. +* INPUT:
  62179. +* void* pEthPortHndl - Ethernet port handler.
  62180. +* char* pAddr - Address to be set
  62181. +*
  62182. +* RETURN: MV_STATUS
  62183. +* MV_OK - Success, Other - Faulure
  62184. +*
  62185. +*******************************************************************************/
  62186. +MV_STATUS mvEthMacAddrSet(void* pPortHndl, unsigned char *pAddr, int queue)
  62187. +{
  62188. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62189. + unsigned int macH;
  62190. + unsigned int macL;
  62191. +
  62192. + if(queue >= MV_ETH_RX_Q_NUM)
  62193. + {
  62194. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", queue);
  62195. + return MV_BAD_PARAM;
  62196. + }
  62197. +
  62198. + if(queue != -1)
  62199. + {
  62200. + macL = (pAddr[4] << 8) | (pAddr[5]);
  62201. + macH = (pAddr[0] << 24)| (pAddr[1] << 16) |
  62202. + (pAddr[2] << 8) | (pAddr[3] << 0);
  62203. +
  62204. + MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo), macL);
  62205. + MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo), macH);
  62206. + }
  62207. +
  62208. + /* Accept frames of this address */
  62209. + ethSetUcastAddr(pPortCtrl->portNo, pAddr[5], queue);
  62210. +
  62211. + return MV_OK;
  62212. +}
  62213. +
  62214. +/*******************************************************************************
  62215. +* mvEthMacAddrGet - This function returns the port Unicast address.
  62216. +*
  62217. +* DESCRIPTION:
  62218. +* This function returns the port Ethernet MAC address.
  62219. +*
  62220. +* INPUT:
  62221. +* int portNo - Ethernet port number.
  62222. +* char* pAddr - Pointer where address will be written to
  62223. +*
  62224. +* RETURN: MV_STATUS
  62225. +* MV_OK - Success, Other - Faulure
  62226. +*
  62227. +*******************************************************************************/
  62228. +MV_STATUS mvEthMacAddrGet(int portNo, unsigned char *pAddr)
  62229. +{
  62230. + unsigned int macH;
  62231. + unsigned int macL;
  62232. +
  62233. + if(pAddr == NULL)
  62234. + {
  62235. + mvOsPrintf("mvEthMacAddrGet: NULL pointer.\n");
  62236. + return MV_BAD_PARAM;
  62237. + }
  62238. +
  62239. + macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(portNo));
  62240. + macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(portNo));
  62241. + pAddr[0] = (macH >> 24) & 0xff;
  62242. + pAddr[1] = (macH >> 16) & 0xff;
  62243. + pAddr[2] = (macH >> 8) & 0xff;
  62244. + pAddr[3] = macH & 0xff;
  62245. + pAddr[4] = (macL >> 8) & 0xff;
  62246. + pAddr[5] = macL & 0xff;
  62247. +
  62248. + return MV_OK;
  62249. +}
  62250. +
  62251. +/*******************************************************************************
  62252. +* mvEthMcastCrc8Get - Calculate CRC8 of MAC address.
  62253. +*
  62254. +* DESCRIPTION:
  62255. +*
  62256. +* INPUT:
  62257. +* MV_U8* pAddr - Address to calculate CRC-8
  62258. +*
  62259. +* RETURN: MV_U8 - CRC-8 of this MAC address
  62260. +*
  62261. +*******************************************************************************/
  62262. +MV_U8 mvEthMcastCrc8Get(MV_U8* pAddr)
  62263. +{
  62264. + unsigned int macH;
  62265. + unsigned int macL;
  62266. + int macArray[48];
  62267. + int crc[8];
  62268. + int i;
  62269. + unsigned char crcResult = 0;
  62270. +
  62271. + /* Calculate CRC-8 out of the given address */
  62272. + macH = (pAddr[0] << 8) | (pAddr[1]);
  62273. + macL = (pAddr[2] << 24)| (pAddr[3] << 16) |
  62274. + (pAddr[4] << 8) | (pAddr[5] << 0);
  62275. +
  62276. + for(i=0; i<32; i++)
  62277. + macArray[i] = (macL >> i) & 0x1;
  62278. +
  62279. + for(i=32; i<48; i++)
  62280. + macArray[i] = (macH >> (i - 32)) & 0x1;
  62281. +
  62282. + crc[0] = macArray[45] ^ macArray[43] ^ macArray[40] ^ macArray[39] ^
  62283. + macArray[35] ^ macArray[34] ^ macArray[31] ^ macArray[30] ^
  62284. + macArray[28] ^ macArray[23] ^ macArray[21] ^ macArray[19] ^
  62285. + macArray[18] ^ macArray[16] ^ macArray[14] ^ macArray[12] ^
  62286. + macArray[8] ^ macArray[7] ^ macArray[6] ^ macArray[0];
  62287. +
  62288. + crc[1] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^
  62289. + macArray[41] ^ macArray[39] ^ macArray[36] ^ macArray[34] ^
  62290. + macArray[32] ^ macArray[30] ^ macArray[29] ^ macArray[28] ^
  62291. + macArray[24] ^ macArray[23] ^ macArray[22] ^ macArray[21] ^
  62292. + macArray[20] ^ macArray[18] ^ macArray[17] ^ macArray[16] ^
  62293. + macArray[15] ^ macArray[14] ^ macArray[13] ^ macArray[12] ^
  62294. + macArray[9] ^ macArray[6] ^ macArray[1] ^ macArray[0];
  62295. +
  62296. + crc[2] = macArray[47] ^ macArray[46] ^ macArray[44] ^ macArray[43] ^
  62297. + macArray[42] ^ macArray[39] ^ macArray[37] ^ macArray[34] ^
  62298. + macArray[33] ^ macArray[29] ^ macArray[28] ^ macArray[25] ^
  62299. + macArray[24] ^ macArray[22] ^ macArray[17] ^ macArray[15] ^
  62300. + macArray[13] ^ macArray[12] ^ macArray[10] ^ macArray[8] ^
  62301. + macArray[6] ^ macArray[2] ^ macArray[1] ^ macArray[0];
  62302. +
  62303. + crc[3] = macArray[47] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^
  62304. + macArray[40] ^ macArray[38] ^ macArray[35] ^ macArray[34] ^
  62305. + macArray[30] ^ macArray[29] ^ macArray[26] ^ macArray[25] ^
  62306. + macArray[23] ^ macArray[18] ^ macArray[16] ^ macArray[14] ^
  62307. + macArray[13] ^ macArray[11] ^ macArray[9] ^ macArray[7] ^
  62308. + macArray[3] ^ macArray[2] ^ macArray[1];
  62309. +
  62310. + crc[4] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[41] ^
  62311. + macArray[39] ^ macArray[36] ^ macArray[35] ^ macArray[31] ^
  62312. + macArray[30] ^ macArray[27] ^ macArray[26] ^ macArray[24] ^
  62313. + macArray[19] ^ macArray[17] ^ macArray[15] ^ macArray[14] ^
  62314. + macArray[12] ^ macArray[10] ^ macArray[8] ^ macArray[4] ^
  62315. + macArray[3] ^ macArray[2];
  62316. +
  62317. + crc[5] = macArray[47] ^ macArray[46] ^ macArray[45] ^ macArray[42] ^
  62318. + macArray[40] ^ macArray[37] ^ macArray[36] ^ macArray[32] ^
  62319. + macArray[31] ^ macArray[28] ^ macArray[27] ^ macArray[25] ^
  62320. + macArray[20] ^ macArray[18] ^ macArray[16] ^ macArray[15] ^
  62321. + macArray[13] ^ macArray[11] ^ macArray[9] ^ macArray[5] ^
  62322. + macArray[4] ^ macArray[3];
  62323. +
  62324. + crc[6] = macArray[47] ^ macArray[46] ^ macArray[43] ^ macArray[41] ^
  62325. + macArray[38] ^ macArray[37] ^ macArray[33] ^ macArray[32] ^
  62326. + macArray[29] ^ macArray[28] ^ macArray[26] ^ macArray[21] ^
  62327. + macArray[19] ^ macArray[17] ^ macArray[16] ^ macArray[14] ^
  62328. + macArray[12] ^ macArray[10] ^ macArray[6] ^ macArray[5] ^
  62329. + macArray[4];
  62330. +
  62331. + crc[7] = macArray[47] ^ macArray[44] ^ macArray[42] ^ macArray[39] ^
  62332. + macArray[38] ^ macArray[34] ^ macArray[33] ^ macArray[30] ^
  62333. + macArray[29] ^ macArray[27] ^ macArray[22] ^ macArray[20] ^
  62334. + macArray[18] ^ macArray[17] ^ macArray[15] ^ macArray[13] ^
  62335. + macArray[11] ^ macArray[7] ^ macArray[6] ^ macArray[5];
  62336. +
  62337. + for(i=0; i<8; i++)
  62338. + crcResult = crcResult | (crc[i] << i);
  62339. +
  62340. + return crcResult;
  62341. +}
  62342. +/*******************************************************************************
  62343. +* mvEthMcastAddrSet - Multicast address settings.
  62344. +*
  62345. +* DESCRIPTION:
  62346. +* This API controls the MV device MAC multicast support.
  62347. +* The MV device supports multicast using two tables:
  62348. +* 1) Special Multicast Table for MAC addresses of the form
  62349. +* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
  62350. +* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
  62351. +* Table entries in the DA-Filter table.
  62352. +* In this case, the function calls ethPortSmcAddr() routine to set the
  62353. +* Special Multicast Table.
  62354. +* 2) Other Multicast Table for multicast of another type. A CRC-8bit
  62355. +* is used as an index to the Other Multicast Table entries in the
  62356. +* DA-Filter table.
  62357. +* In this case, the function calculates the CRC-8bit value and calls
  62358. +* ethPortOmcAddr() routine to set the Other Multicast Table.
  62359. +*
  62360. +* INPUT:
  62361. +* void* pEthPortHndl - Ethernet port handler.
  62362. +* MV_U8* pAddr - Address to be set
  62363. +* int queue - RX queue to capture all packets with this
  62364. +* Multicast MAC address.
  62365. +* -1 means delete this Multicast address.
  62366. +*
  62367. +* RETURN: MV_STATUS
  62368. +* MV_TRUE - Success, Other - Failure
  62369. +*
  62370. +*******************************************************************************/
  62371. +MV_STATUS mvEthMcastAddrSet(void* pPortHndl, MV_U8 *pAddr, int queue)
  62372. +{
  62373. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62374. + unsigned char crcResult = 0;
  62375. +
  62376. + if(queue >= MV_ETH_RX_Q_NUM)
  62377. + {
  62378. + mvOsPrintf("ethPort %d: RX queue #%d is out of range\n",
  62379. + pPortCtrl->portNo, queue);
  62380. + return MV_BAD_PARAM;
  62381. + }
  62382. +
  62383. + if((pAddr[0] == 0x01) &&
  62384. + (pAddr[1] == 0x00) &&
  62385. + (pAddr[2] == 0x5E) &&
  62386. + (pAddr[3] == 0x00) &&
  62387. + (pAddr[4] == 0x00))
  62388. + {
  62389. + ethSetSpecialMcastAddr(pPortCtrl->portNo, pAddr[5], queue);
  62390. + }
  62391. + else
  62392. + {
  62393. + crcResult = mvEthMcastCrc8Get(pAddr);
  62394. +
  62395. + /* Check Add counter for this CRC value */
  62396. + if(queue == -1)
  62397. + {
  62398. + if(pPortCtrl->mcastCount[crcResult] == 0)
  62399. + {
  62400. + mvOsPrintf("ethPort #%d: No valid Mcast for crc8=0x%02x\n",
  62401. + pPortCtrl->portNo, (unsigned)crcResult);
  62402. + return MV_NO_SUCH;
  62403. + }
  62404. +
  62405. + pPortCtrl->mcastCount[crcResult]--;
  62406. + if(pPortCtrl->mcastCount[crcResult] != 0)
  62407. + {
  62408. + mvOsPrintf("ethPort #%d: After delete there are %d valid Mcast for crc8=0x%02x\n",
  62409. + pPortCtrl->portNo, pPortCtrl->mcastCount[crcResult],
  62410. + (unsigned)crcResult);
  62411. + return MV_NO_CHANGE;
  62412. + }
  62413. + }
  62414. + else
  62415. + {
  62416. + pPortCtrl->mcastCount[crcResult]++;
  62417. + if(pPortCtrl->mcastCount[crcResult] > 1)
  62418. + {
  62419. + mvOsPrintf("ethPort #%d: Valid Mcast for crc8=0x%02x already exists\n",
  62420. + pPortCtrl->portNo, (unsigned)crcResult);
  62421. + return MV_NO_CHANGE;
  62422. + }
  62423. + }
  62424. + ethSetOtherMcastAddr(pPortCtrl->portNo, crcResult, queue);
  62425. + }
  62426. + return MV_OK;
  62427. +}
  62428. +
  62429. +/*******************************************************************************
  62430. +* ethSetUcastTable - Unicast address settings.
  62431. +*
  62432. +* DESCRIPTION:
  62433. +* Set all entries in the Unicast MAC Table queue==-1 means reject all
  62434. +* INPUT:
  62435. +*
  62436. +* RETURN:
  62437. +*
  62438. +*******************************************************************************/
  62439. +static void ethSetUcastTable(int portNo, int queue)
  62440. +{
  62441. + int offset;
  62442. + MV_U32 regValue;
  62443. +
  62444. + if(queue == -1)
  62445. + {
  62446. + regValue = 0;
  62447. + }
  62448. + else
  62449. + {
  62450. + regValue = (((0x01 | (queue<<1)) << 0) |
  62451. + ((0x01 | (queue<<1)) << 8) |
  62452. + ((0x01 | (queue<<1)) << 16) |
  62453. + ((0x01 | (queue<<1)) << 24));
  62454. + }
  62455. +
  62456. + for (offset=0; offset<=0xC; offset+=4)
  62457. + MV_REG_WRITE((ETH_DA_FILTER_UCAST_BASE(portNo) + offset), regValue);
  62458. +}
  62459. +
  62460. +/*******************************************************************************
  62461. +* mvEthSetSpecialMcastTable - Special Multicast address settings.
  62462. +*
  62463. +* DESCRIPTION:
  62464. +* Set all entries to the Special Multicast MAC Table. queue==-1 means reject all
  62465. +* INPUT:
  62466. +*
  62467. +* RETURN:
  62468. +*
  62469. +*******************************************************************************/
  62470. +MV_VOID mvEthSetSpecialMcastTable(int portNo, int queue)
  62471. +{
  62472. + int offset;
  62473. + MV_U32 regValue;
  62474. +
  62475. + if(queue == -1)
  62476. + {
  62477. + regValue = 0;
  62478. + }
  62479. + else
  62480. + {
  62481. + regValue = (((0x01 | (queue<<1)) << 0) |
  62482. + ((0x01 | (queue<<1)) << 8) |
  62483. + ((0x01 | (queue<<1)) << 16) |
  62484. + ((0x01 | (queue<<1)) << 24));
  62485. + }
  62486. +
  62487. + for (offset=0; offset<=0xFC; offset+=4)
  62488. + {
  62489. + MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(portNo) +
  62490. + offset), regValue);
  62491. + }
  62492. +}
  62493. +
  62494. +/*******************************************************************************
  62495. +* mvEthSetOtherMcastTable - Other Multicast address settings.
  62496. +*
  62497. +* DESCRIPTION:
  62498. +* Set all entries to the Other Multicast MAC Table. queue==-1 means reject all
  62499. +* INPUT:
  62500. +*
  62501. +* RETURN:
  62502. +*
  62503. +*******************************************************************************/
  62504. +MV_VOID mvEthSetOtherMcastTable(int portNo, int queue)
  62505. +{
  62506. + int offset;
  62507. + MV_U32 regValue;
  62508. +
  62509. + if(queue == -1)
  62510. + {
  62511. + regValue = 0;
  62512. + }
  62513. + else
  62514. + {
  62515. + regValue = (((0x01 | (queue<<1)) << 0) |
  62516. + ((0x01 | (queue<<1)) << 8) |
  62517. + ((0x01 | (queue<<1)) << 16) |
  62518. + ((0x01 | (queue<<1)) << 24));
  62519. + }
  62520. +
  62521. + for (offset=0; offset<=0xFC; offset+=4)
  62522. + {
  62523. + MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(portNo) +
  62524. + offset), regValue);
  62525. + }
  62526. +}
  62527. +
  62528. +/*******************************************************************************
  62529. +* ethSetUcastAddr - This function Set the port unicast address table
  62530. +*
  62531. +* DESCRIPTION:
  62532. +* This function locates the proper entry in the Unicast table for the
  62533. +* specified MAC nibble and sets its properties according to function
  62534. +* parameters.
  62535. +*
  62536. +* INPUT:
  62537. +* int ethPortNum - Port number.
  62538. +* MV_U8 lastNibble - Unicast MAC Address last nibble.
  62539. +* int queue - Rx queue number for this MAC address.
  62540. +* value "-1" means remove address
  62541. +*
  62542. +* OUTPUT:
  62543. +* This function add/removes MAC addresses from the port unicast address
  62544. +* table.
  62545. +*
  62546. +* RETURN:
  62547. +* MV_TRUE is output succeeded.
  62548. +* MV_FALSE if option parameter is invalid.
  62549. +*
  62550. +*******************************************************************************/
  62551. +static MV_BOOL ethSetUcastAddr(int portNo, MV_U8 lastNibble, int queue)
  62552. +{
  62553. + unsigned int unicastReg;
  62554. + unsigned int tblOffset;
  62555. + unsigned int regOffset;
  62556. +
  62557. + /* Locate the Unicast table entry */
  62558. + lastNibble = (0xf & lastNibble);
  62559. + tblOffset = (lastNibble / 4) * 4; /* Register offset from unicast table base*/
  62560. + regOffset = lastNibble % 4; /* Entry offset within the above register */
  62561. +
  62562. +
  62563. + unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(portNo) +
  62564. + tblOffset));
  62565. +
  62566. +
  62567. + if(queue == -1)
  62568. + {
  62569. + /* Clear accepts frame bit at specified unicast DA table entry */
  62570. + unicastReg &= ~(0xFF << (8*regOffset));
  62571. + }
  62572. + else
  62573. + {
  62574. + unicastReg &= ~(0xFF << (8*regOffset));
  62575. + unicastReg |= ((0x01 | (queue<<1)) << (8*regOffset));
  62576. + }
  62577. + MV_REG_WRITE( (ETH_DA_FILTER_UCAST_BASE(portNo) + tblOffset),
  62578. + unicastReg);
  62579. +
  62580. + return MV_TRUE;
  62581. +}
  62582. +
  62583. +/*******************************************************************************
  62584. +* ethSetSpecialMcastAddr - Special Multicast address settings.
  62585. +*
  62586. +* DESCRIPTION:
  62587. +* This routine controls the MV device special MAC multicast support.
  62588. +* The Special Multicast Table for MAC addresses supports MAC of the form
  62589. +* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
  62590. +* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
  62591. +* Table entries in the DA-Filter table.
  62592. +* This function set the Special Multicast Table appropriate entry
  62593. +* according to the argument given.
  62594. +*
  62595. +* INPUT:
  62596. +* int ethPortNum Port number.
  62597. +* unsigned char mcByte Multicast addr last byte (MAC DA[7:0] bits).
  62598. +* int queue Rx queue number for this MAC address.
  62599. +* int option 0 = Add, 1 = remove address.
  62600. +*
  62601. +* OUTPUT:
  62602. +* See description.
  62603. +*
  62604. +* RETURN:
  62605. +* MV_TRUE is output succeeded.
  62606. +* MV_FALSE if option parameter is invalid.
  62607. +*
  62608. +*******************************************************************************/
  62609. +static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue)
  62610. +{
  62611. + unsigned int smcTableReg;
  62612. + unsigned int tblOffset;
  62613. + unsigned int regOffset;
  62614. +
  62615. + /* Locate the SMC table entry */
  62616. + tblOffset = (lastByte / 4); /* Register offset from SMC table base */
  62617. + regOffset = lastByte % 4; /* Entry offset within the above register */
  62618. +
  62619. + smcTableReg = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) + tblOffset*4));
  62620. +
  62621. + if(queue == -1)
  62622. + {
  62623. + /* Clear accepts frame bit at specified Special DA table entry */
  62624. + smcTableReg &= ~(0xFF << (8 * regOffset));
  62625. + }
  62626. + else
  62627. + {
  62628. + smcTableReg &= ~(0xFF << (8 * regOffset));
  62629. + smcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));
  62630. + }
  62631. + MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) +
  62632. + tblOffset*4), smcTableReg);
  62633. +
  62634. + return MV_TRUE;
  62635. +}
  62636. +
  62637. +/*******************************************************************************
  62638. +* ethSetOtherMcastAddr - Multicast address settings.
  62639. +*
  62640. +* DESCRIPTION:
  62641. +* This routine controls the MV device Other MAC multicast support.
  62642. +* The Other Multicast Table is used for multicast of another type.
  62643. +* A CRC-8bit is used as an index to the Other Multicast Table entries
  62644. +* in the DA-Filter table.
  62645. +* The function gets the CRC-8bit value from the calling routine and
  62646. +* set the Other Multicast Table appropriate entry according to the
  62647. +* CRC-8 argument given.
  62648. +*
  62649. +* INPUT:
  62650. +* int ethPortNum Port number.
  62651. +* MV_U8 crc8 A CRC-8bit (Polynomial: x^8+x^2+x^1+1).
  62652. +* int queue Rx queue number for this MAC address.
  62653. +*
  62654. +* OUTPUT:
  62655. +* See description.
  62656. +*
  62657. +* RETURN:
  62658. +* MV_TRUE is output succeeded.
  62659. +* MV_FALSE if option parameter is invalid.
  62660. +*
  62661. +*******************************************************************************/
  62662. +static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue)
  62663. +{
  62664. + unsigned int omcTableReg;
  62665. + unsigned int tblOffset;
  62666. + unsigned int regOffset;
  62667. +
  62668. + /* Locate the OMC table entry */
  62669. + tblOffset = (crc8 / 4) * 4; /* Register offset from OMC table base */
  62670. + regOffset = crc8 % 4; /* Entry offset within the above register */
  62671. +
  62672. + omcTableReg = MV_REG_READ(
  62673. + (ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset));
  62674. +
  62675. + if(queue == -1)
  62676. + {
  62677. + /* Clear accepts frame bit at specified Other DA table entry */
  62678. + omcTableReg &= ~(0xFF << (8 * regOffset));
  62679. + }
  62680. + else
  62681. + {
  62682. + omcTableReg &= ~(0xFF << (8 * regOffset));
  62683. + omcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));
  62684. + }
  62685. +
  62686. + MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset),
  62687. + omcTableReg);
  62688. +
  62689. + return MV_TRUE;
  62690. +}
  62691. +
  62692. +
  62693. +/******************************************************************************/
  62694. +/* MIB Counters functions */
  62695. +/******************************************************************************/
  62696. +
  62697. +
  62698. +/*******************************************************************************
  62699. +* mvEthMibCounterRead - Read a MIB counter
  62700. +*
  62701. +* DESCRIPTION:
  62702. +* This function reads a MIB counter of a specific ethernet port.
  62703. +* NOTE - Read from ETH_MIB_GOOD_OCTETS_RECEIVED_LOW or
  62704. +* ETH_MIB_GOOD_OCTETS_SENT_LOW counters will return 64 bits value,
  62705. +* so pHigh32 pointer should not be NULL in this case.
  62706. +*
  62707. +* INPUT:
  62708. +* int ethPortNum - Ethernet Port number.
  62709. +* unsigned int mibOffset - MIB counter offset.
  62710. +*
  62711. +* OUTPUT:
  62712. +* MV_U32* pHigh32 - pointer to place where 32 most significant bits
  62713. +* of the counter will be stored.
  62714. +*
  62715. +* RETURN:
  62716. +* 32 low sgnificant bits of MIB counter value.
  62717. +*
  62718. +*******************************************************************************/
  62719. +MV_U32 mvEthMibCounterRead(void* pPortHandle, unsigned int mibOffset,
  62720. + MV_U32* pHigh32)
  62721. +{
  62722. + int portNo;
  62723. + MV_U32 valLow32, valHigh32;
  62724. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62725. +
  62726. + portNo = pPortCtrl->portNo;
  62727. +
  62728. + valLow32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset);
  62729. +
  62730. + /* Implement FEr ETH. Erroneous Value when Reading the Upper 32-bits */
  62731. + /* of a 64-bit MIB Counter. */
  62732. + if( (mibOffset == ETH_MIB_GOOD_OCTETS_RECEIVED_LOW) ||
  62733. + (mibOffset == ETH_MIB_GOOD_OCTETS_SENT_LOW) )
  62734. + {
  62735. + valHigh32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset + 4);
  62736. + if(pHigh32 != NULL)
  62737. + *pHigh32 = valHigh32;
  62738. + }
  62739. + return valLow32;
  62740. +}
  62741. +
  62742. +/*******************************************************************************
  62743. +* mvEthMibCountersClear - Clear all MIB counters
  62744. +*
  62745. +* DESCRIPTION:
  62746. +* This function clears all MIB counters
  62747. +*
  62748. +* INPUT:
  62749. +* int ethPortNum - Ethernet Port number.
  62750. +*
  62751. +*
  62752. +* RETURN: void
  62753. +*
  62754. +*******************************************************************************/
  62755. +void mvEthMibCountersClear(void* pPortHandle)
  62756. +{
  62757. + int i, portNo;
  62758. + unsigned int dummy;
  62759. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62760. +
  62761. + portNo = pPortCtrl->portNo;
  62762. +
  62763. + /* Perform dummy reads from MIB counters */
  62764. + for(i=ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i<ETH_MIB_LATE_COLLISION; i+=4)
  62765. + dummy = MV_REG_READ((ETH_MIB_COUNTERS_BASE(portNo) + i));
  62766. +}
  62767. +
  62768. +
  62769. +/******************************************************************************/
  62770. +/* RX Dispatching configuration routines */
  62771. +/******************************************************************************/
  62772. +
  62773. +int mvEthTosToRxqGet(void* pPortHandle, int tos)
  62774. +{
  62775. + MV_U32 regValue;
  62776. + int regIdx, regOffs, rxq;
  62777. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62778. +
  62779. + if(tos > 0xFF)
  62780. + {
  62781. + mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);
  62782. + return -1;
  62783. + }
  62784. + regIdx = mvOsDivide(tos>>2, 10);
  62785. + regOffs = mvOsReminder(tos>>2, 10);
  62786. +
  62787. + regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );
  62788. + rxq = (regValue >> (regOffs*3));
  62789. + rxq &= 0x7;
  62790. +
  62791. + return rxq;
  62792. +}
  62793. +
  62794. +/*******************************************************************************
  62795. +* mvEthTosToRxqSet - Map packets with special TOS value to special RX queue
  62796. +*
  62797. +* DESCRIPTION:
  62798. +*
  62799. +* INPUT:
  62800. +* void* pPortHandle - Pointer to port specific handler;
  62801. +* int tos - TOS value in the IP header of the packet
  62802. +* int rxq - RX Queue for packets with the configured TOS value
  62803. +* Negative value (-1) means no special processing for these packets,
  62804. +* so they will be processed as regular packets.
  62805. +*
  62806. +* RETURN: MV_STATUS
  62807. +*******************************************************************************/
  62808. +MV_STATUS mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq)
  62809. +{
  62810. + MV_U32 regValue;
  62811. + int regIdx, regOffs;
  62812. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62813. +
  62814. + if( (rxq < 0) || (rxq >= MV_ETH_RX_Q_NUM) )
  62815. + {
  62816. + mvOsPrintf("eth_%d: RX queue #%d is out of range\n", pPortCtrl->portNo, rxq);
  62817. + return MV_BAD_PARAM;
  62818. + }
  62819. + if(tos > 0xFF)
  62820. + {
  62821. + mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);
  62822. + return MV_BAD_PARAM;
  62823. + }
  62824. + regIdx = mvOsDivide(tos>>2, 10);
  62825. + regOffs = mvOsReminder(tos>>2, 10);
  62826. +
  62827. + regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );
  62828. + regValue &= ~(0x7 << (regOffs*3));
  62829. + regValue |= (rxq << (regOffs*3));
  62830. +
  62831. + MV_REG_WRITE(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx), regValue);
  62832. + return MV_OK;
  62833. +}
  62834. +
  62835. +/*******************************************************************************
  62836. +* mvEthVlanPrioRxQueue - Configure RX queue to capture VLAN tagged packets with
  62837. +* special priority bits [0-2]
  62838. +*
  62839. +* DESCRIPTION:
  62840. +*
  62841. +* INPUT:
  62842. +* void* pPortHandle - Pointer to port specific handler;
  62843. +* int bpduQueue - Special queue to capture VLAN tagged packets with special
  62844. +* priority.
  62845. +* Negative value (-1) means no special processing for these packets,
  62846. +* so they will be processed as regular packets.
  62847. +*
  62848. +* RETURN: MV_STATUS
  62849. +* MV_OK - Success
  62850. +* MV_FAIL - Failed.
  62851. +*
  62852. +*******************************************************************************/
  62853. +MV_STATUS mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue)
  62854. +{
  62855. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62856. + MV_U32 vlanPrioReg;
  62857. +
  62858. + if(vlanPrioQueue >= MV_ETH_RX_Q_NUM)
  62859. + {
  62860. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", vlanPrioQueue);
  62861. + return MV_BAD_PARAM;
  62862. + }
  62863. + if(vlanPrio >= 8)
  62864. + {
  62865. + mvOsPrintf("ethDrv: vlanPrio=%d is out of range\n", vlanPrio);
  62866. + return MV_BAD_PARAM;
  62867. + }
  62868. +
  62869. + vlanPrioReg = MV_REG_READ(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo));
  62870. + vlanPrioReg &= ~(0x7 << (vlanPrio*3));
  62871. + vlanPrioReg |= (vlanPrioQueue << (vlanPrio*3));
  62872. + MV_REG_WRITE(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo), vlanPrioReg);
  62873. +
  62874. + return MV_OK;
  62875. +}
  62876. +
  62877. +
  62878. +/*******************************************************************************
  62879. +* mvEthBpduRxQueue - Configure RX queue to capture BPDU packets.
  62880. +*
  62881. +* DESCRIPTION:
  62882. +* This function defines processing of BPDU packets.
  62883. +* BPDU packets can be accepted and captured to one of RX queues
  62884. +* or can be processing as regular Multicast packets.
  62885. +*
  62886. +* INPUT:
  62887. +* void* pPortHandle - Pointer to port specific handler;
  62888. +* int bpduQueue - Special queue to capture BPDU packets (DA is equal to
  62889. +* 01-80-C2-00-00-00 through 01-80-C2-00-00-FF,
  62890. +* except for the Flow-Control Pause packets).
  62891. +* Negative value (-1) means no special processing for BPDU,
  62892. +* packets so they will be processed as regular Multicast packets.
  62893. +*
  62894. +* RETURN: MV_STATUS
  62895. +* MV_OK - Success
  62896. +* MV_FAIL - Failed.
  62897. +*
  62898. +*******************************************************************************/
  62899. +MV_STATUS mvEthBpduRxQueue(void* pPortHandle, int bpduQueue)
  62900. +{
  62901. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62902. + MV_U32 portCfgReg;
  62903. + MV_U32 portCfgExtReg;
  62904. +
  62905. + if(bpduQueue >= MV_ETH_RX_Q_NUM)
  62906. + {
  62907. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", bpduQueue);
  62908. + return MV_BAD_PARAM;
  62909. + }
  62910. +
  62911. + portCfgExtReg = MV_REG_READ(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo));
  62912. +
  62913. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  62914. + if(bpduQueue >= 0)
  62915. + {
  62916. + pPortCtrl->portConfig.rxBpduQ = bpduQueue;
  62917. +
  62918. + portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;
  62919. + portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);
  62920. +
  62921. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  62922. +
  62923. + portCfgExtReg |= ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK;
  62924. + }
  62925. + else
  62926. + {
  62927. + pPortCtrl->portConfig.rxBpduQ = -1;
  62928. + /* no special processing for BPDU packets */
  62929. + portCfgExtReg &= (~ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK);
  62930. + }
  62931. +
  62932. + MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo), portCfgExtReg);
  62933. +
  62934. + return MV_OK;
  62935. +}
  62936. +
  62937. +
  62938. +/*******************************************************************************
  62939. +* mvEthArpRxQueue - Configure RX queue to capture ARP packets.
  62940. +*
  62941. +* DESCRIPTION:
  62942. +* This function defines processing of ARP (type=0x0806) packets.
  62943. +* ARP packets can be accepted and captured to one of RX queues
  62944. +* or can be processed as other Broadcast packets.
  62945. +*
  62946. +* INPUT:
  62947. +* void* pPortHandle - Pointer to port specific handler;
  62948. +* int arpQueue - Special queue to capture ARP packets (type=0x806).
  62949. +* Negative value (-1) means discard ARP packets
  62950. +*
  62951. +* RETURN: MV_STATUS
  62952. +* MV_OK - Success
  62953. +* MV_FAIL - Failed.
  62954. +*
  62955. +*******************************************************************************/
  62956. +MV_STATUS mvEthArpRxQueue(void* pPortHandle, int arpQueue)
  62957. +{
  62958. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62959. + MV_U32 portCfgReg;
  62960. +
  62961. + if(arpQueue >= MV_ETH_RX_Q_NUM)
  62962. + {
  62963. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", arpQueue);
  62964. + return MV_BAD_PARAM;
  62965. + }
  62966. +
  62967. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  62968. +
  62969. + if(arpQueue >= 0)
  62970. + {
  62971. + pPortCtrl->portConfig.rxArpQ = arpQueue;
  62972. + portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;
  62973. + portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ);
  62974. +
  62975. + portCfgReg &= (~ETH_REJECT_ARP_BCAST_MASK);
  62976. + }
  62977. + else
  62978. + {
  62979. + pPortCtrl->portConfig.rxArpQ = -1;
  62980. + portCfgReg |= ETH_REJECT_ARP_BCAST_MASK;
  62981. + }
  62982. +
  62983. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  62984. +
  62985. + return MV_OK;
  62986. +}
  62987. +
  62988. +
  62989. +/*******************************************************************************
  62990. +* mvEthTcpRxQueue - Configure RX queue to capture TCP packets.
  62991. +*
  62992. +* DESCRIPTION:
  62993. +* This function defines processing of TCP packets.
  62994. +* TCP packets can be accepted and captured to one of RX queues
  62995. +* or can be processed as regular Unicast packets.
  62996. +*
  62997. +* INPUT:
  62998. +* void* pPortHandle - Pointer to port specific handler;
  62999. +* int tcpQueue - Special queue to capture TCP packets. Value "-1"
  63000. +* means no special processing for TCP packets,
  63001. +* so they will be processed as regular
  63002. +*
  63003. +* RETURN: MV_STATUS
  63004. +* MV_OK - Success
  63005. +* MV_FAIL - Failed.
  63006. +*
  63007. +*******************************************************************************/
  63008. +MV_STATUS mvEthTcpRxQueue(void* pPortHandle, int tcpQueue)
  63009. +{
  63010. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63011. + MV_U32 portCfgReg;
  63012. +
  63013. + if(tcpQueue >= MV_ETH_RX_Q_NUM)
  63014. + {
  63015. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", tcpQueue);
  63016. + return MV_BAD_PARAM;
  63017. + }
  63018. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  63019. +
  63020. + if(tcpQueue >= 0)
  63021. + {
  63022. + pPortCtrl->portConfig.rxTcpQ = tcpQueue;
  63023. + portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;
  63024. + portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);
  63025. +
  63026. + portCfgReg |= ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK;
  63027. + }
  63028. + else
  63029. + {
  63030. + pPortCtrl->portConfig.rxTcpQ = -1;
  63031. + portCfgReg &= (~ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK);
  63032. + }
  63033. +
  63034. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  63035. +
  63036. + return MV_OK;
  63037. +}
  63038. +
  63039. +
  63040. +/*******************************************************************************
  63041. +* mvEthUdpRxQueue - Configure RX queue to capture UDP packets.
  63042. +*
  63043. +* DESCRIPTION:
  63044. +* This function defines processing of UDP packets.
  63045. +* TCP packets can be accepted and captured to one of RX queues
  63046. +* or can be processed as regular Unicast packets.
  63047. +*
  63048. +* INPUT:
  63049. +* void* pPortHandle - Pointer to port specific handler;
  63050. +* int udpQueue - Special queue to capture UDP packets. Value "-1"
  63051. +* means no special processing for UDP packets,
  63052. +* so they will be processed as regular
  63053. +*
  63054. +* RETURN: MV_STATUS
  63055. +* MV_OK - Success
  63056. +* MV_FAIL - Failed.
  63057. +*
  63058. +*******************************************************************************/
  63059. +MV_STATUS mvEthUdpRxQueue(void* pPortHandle, int udpQueue)
  63060. +{
  63061. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63062. + MV_U32 portCfgReg;
  63063. +
  63064. + if(udpQueue >= MV_ETH_RX_Q_NUM)
  63065. + {
  63066. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", udpQueue);
  63067. + return MV_BAD_PARAM;
  63068. + }
  63069. +
  63070. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  63071. +
  63072. + if(udpQueue >= 0)
  63073. + {
  63074. + pPortCtrl->portConfig.rxUdpQ = udpQueue;
  63075. + portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;
  63076. + portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);
  63077. +
  63078. + portCfgReg |= ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;
  63079. + }
  63080. + else
  63081. + {
  63082. + pPortCtrl->portConfig.rxUdpQ = -1;
  63083. + portCfgReg &= ~ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;
  63084. + }
  63085. +
  63086. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  63087. +
  63088. + return MV_OK;
  63089. +}
  63090. +
  63091. +
  63092. +/******************************************************************************/
  63093. +/* Speed, Duplex, FlowControl routines */
  63094. +/******************************************************************************/
  63095. +
  63096. +/*******************************************************************************
  63097. +* mvEthSpeedDuplexSet - Set Speed and Duplex of the port.
  63098. +*
  63099. +* DESCRIPTION:
  63100. +* This function configure the port to work with desirable Duplex and Speed.
  63101. +* Changing of these parameters are allowed only when port is disabled.
  63102. +* This function disable the port if was enabled, change duplex and speed
  63103. +* and, enable the port back if needed.
  63104. +*
  63105. +* INPUT:
  63106. +* void* pPortHandle - Pointer to port specific handler;
  63107. +* ETH_PORT_SPEED speed - Speed of the port.
  63108. +* ETH_PORT_SPEED duplex - Duplex of the port.
  63109. +*
  63110. +* RETURN: MV_STATUS
  63111. +* MV_OK - Success
  63112. +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
  63113. +* MV_NOT_FOUND - Failed. Port is not initialized.
  63114. +* MV_BAD_PARAM - Input parameters (speed/duplex) in conflict.
  63115. +* MV_BAD_VALUE - Value of one of input parameters (speed, duplex)
  63116. +* is not valid
  63117. +*
  63118. +*******************************************************************************/
  63119. +MV_STATUS mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed,
  63120. + MV_ETH_PORT_DUPLEX duplex)
  63121. +{
  63122. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63123. + int port = pPortCtrl->portNo;
  63124. + MV_U32 portSerialCtrlReg;
  63125. +
  63126. + if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet()) )
  63127. + return MV_OUT_OF_RANGE;
  63128. +
  63129. + pPortCtrl = ethPortCtrl[port];
  63130. + if(pPortCtrl == NULL)
  63131. + return MV_NOT_FOUND;
  63132. +
  63133. + /* Check validity */
  63134. + if( (speed == MV_ETH_SPEED_1000) && (duplex == MV_ETH_DUPLEX_HALF) )
  63135. + return MV_BAD_PARAM;
  63136. +
  63137. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
  63138. + /* Set Speed */
  63139. + switch(speed)
  63140. + {
  63141. + case MV_ETH_SPEED_AN:
  63142. + portSerialCtrlReg &= ~ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  63143. + break;
  63144. +
  63145. + case MV_ETH_SPEED_10:
  63146. + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  63147. + portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;
  63148. + portSerialCtrlReg &= ~ETH_SET_MII_SPEED_100_MASK;
  63149. + break;
  63150. +
  63151. + case MV_ETH_SPEED_100:
  63152. + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  63153. + portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;
  63154. + portSerialCtrlReg |= ETH_SET_MII_SPEED_100_MASK;
  63155. + break;
  63156. +
  63157. + case MV_ETH_SPEED_1000:
  63158. + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  63159. + portSerialCtrlReg |= ETH_SET_GMII_SPEED_1000_MASK;
  63160. + break;
  63161. +
  63162. + default:
  63163. + mvOsPrintf("ethDrv: Unexpected Speed value %d\n", speed);
  63164. + return MV_BAD_VALUE;
  63165. + }
  63166. + /* Set duplex */
  63167. + switch(duplex)
  63168. + {
  63169. + case MV_ETH_DUPLEX_AN:
  63170. + portSerialCtrlReg &= ~ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
  63171. + break;
  63172. +
  63173. + case MV_ETH_DUPLEX_HALF:
  63174. + portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
  63175. + portSerialCtrlReg &= ~ETH_SET_FULL_DUPLEX_MASK;
  63176. + break;
  63177. +
  63178. + case MV_ETH_DUPLEX_FULL:
  63179. + portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
  63180. + portSerialCtrlReg |= ETH_SET_FULL_DUPLEX_MASK;
  63181. + break;
  63182. +
  63183. + default:
  63184. + mvOsPrintf("ethDrv: Unexpected Duplex value %d\n", duplex);
  63185. + return MV_BAD_VALUE;
  63186. + }
  63187. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);
  63188. +
  63189. + return MV_OK;
  63190. +}
  63191. +
  63192. +/*******************************************************************************
  63193. +* mvEthFlowCtrlSet - Set Flow Control of the port.
  63194. +*
  63195. +* DESCRIPTION:
  63196. +* This function configure the port to work with desirable Duplex and
  63197. +* Speed. Changing of these parameters are allowed only when port is
  63198. +* disabled. This function disable the port if was enabled, change
  63199. +* duplex and speed and, enable the port back if needed.
  63200. +*
  63201. +* INPUT:
  63202. +* void* pPortHandle - Pointer to port specific handler;
  63203. +* MV_ETH_PORT_FC flowControl - Flow control of the port.
  63204. +*
  63205. +* RETURN: MV_STATUS
  63206. +* MV_OK - Success
  63207. +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
  63208. +* MV_NOT_FOUND - Failed. Port is not initialized.
  63209. +* MV_BAD_VALUE - Value flowControl parameters is not valid
  63210. +*
  63211. +*******************************************************************************/
  63212. +MV_STATUS mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl)
  63213. +{
  63214. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63215. + int port = pPortCtrl->portNo;
  63216. + MV_U32 portSerialCtrlReg;
  63217. +
  63218. + if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet() ) )
  63219. + return MV_OUT_OF_RANGE;
  63220. +
  63221. + pPortCtrl = ethPortCtrl[port];
  63222. + if(pPortCtrl == NULL)
  63223. + return MV_NOT_FOUND;
  63224. +
  63225. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
  63226. + switch(flowControl)
  63227. + {
  63228. + case MV_ETH_FC_AN_ADV_DIS:
  63229. + portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;
  63230. + portSerialCtrlReg &= ~ETH_ADVERTISE_SYM_FC_MASK;
  63231. + break;
  63232. +
  63233. + case MV_ETH_FC_AN_ADV_SYM:
  63234. + portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;
  63235. + portSerialCtrlReg |= ETH_ADVERTISE_SYM_FC_MASK;
  63236. + break;
  63237. +
  63238. + case MV_ETH_FC_DISABLE:
  63239. + portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;
  63240. + portSerialCtrlReg &= ~ETH_SET_FLOW_CTRL_MASK;
  63241. + break;
  63242. +
  63243. + case MV_ETH_FC_ENABLE:
  63244. + portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;
  63245. + portSerialCtrlReg |= ETH_SET_FLOW_CTRL_MASK;
  63246. + break;
  63247. +
  63248. + default:
  63249. + mvOsPrintf("ethDrv: Unexpected FlowControl value %d\n", flowControl);
  63250. + return MV_BAD_VALUE;
  63251. + }
  63252. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);
  63253. +
  63254. + return MV_OK;
  63255. +}
  63256. +
  63257. +/*******************************************************************************
  63258. +* mvEthHeaderModeSet - Set port header mode.
  63259. +*
  63260. +* DESCRIPTION:
  63261. +* This function configures the port to work in Marvell-Header mode.
  63262. +*
  63263. +* INPUT:
  63264. +* void* pPortHandle - Pointer to port specific handler;
  63265. +* MV_ETH_HEADER_MODE headerMode - The header mode to set the port in.
  63266. +*
  63267. +* RETURN: MV_STATUS
  63268. +* MV_OK - Success
  63269. +* MV_NOT_SUPPORTED- Feature not supported.
  63270. +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
  63271. +* MV_NOT_FOUND - Failed. Port is not initialized.
  63272. +* MV_BAD_VALUE - Value of headerMode or numRxQueue parameter is not valid.
  63273. +*
  63274. +*******************************************************************************/
  63275. +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode)
  63276. +{
  63277. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63278. + int port = pPortCtrl->portNo;
  63279. + MV_U32 mvHeaderReg;
  63280. + MV_U32 numRxQ = MV_ETH_RX_Q_NUM;
  63281. +
  63282. + if((port < 0) || (port >= mvCtrlEthMaxPortGet()))
  63283. + return MV_OUT_OF_RANGE;
  63284. +
  63285. + pPortCtrl = ethPortCtrl[port];
  63286. + if(pPortCtrl == NULL)
  63287. + return MV_NOT_FOUND;
  63288. +
  63289. + mvHeaderReg = MV_REG_READ(ETH_PORT_MARVELL_HEADER_REG(port));
  63290. + /* Disable header mode. */
  63291. + mvHeaderReg &= ~ETH_MVHDR_EN_MASK;
  63292. +
  63293. + if(headerMode != MV_ETH_DISABLE_HEADER_MODE)
  63294. + {
  63295. + /* Enable Header mode. */
  63296. + mvHeaderReg |= ETH_MVHDR_EN_MASK;
  63297. +
  63298. + /* Clear DA-Prefix & MHMask fields.*/
  63299. + mvHeaderReg &= ~(ETH_MVHDR_DAPREFIX_MASK | ETH_MVHDR_MHMASK_MASK);
  63300. +
  63301. + if(numRxQ > 1)
  63302. + {
  63303. + switch (headerMode)
  63304. + {
  63305. + case(MV_ETH_ENABLE_HEADER_MODE_PRI_2_1):
  63306. + mvHeaderReg |= ETH_MVHDR_DAPREFIX_PRI_1_2;
  63307. + break;
  63308. + case(MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM):
  63309. + mvHeaderReg |= ETH_MVHDR_DAPREFIX_DBNUM_PRI;
  63310. + break;
  63311. + case(MV_ETH_ENABLE_HEADER_MODE_PRI_SPID):
  63312. + mvHeaderReg |= ETH_MVHDR_DAPREFIX_SPID_PRI;
  63313. + break;
  63314. + default:
  63315. + break;
  63316. + }
  63317. +
  63318. + switch (numRxQ)
  63319. + {
  63320. + case (4):
  63321. + mvHeaderReg |= ETH_MVHDR_MHMASK_4_QUEUE;
  63322. + break;
  63323. + case (8):
  63324. + mvHeaderReg |= ETH_MVHDR_MHMASK_8_QUEUE;
  63325. + break;
  63326. + default:
  63327. + break;
  63328. + }
  63329. + }
  63330. + }
  63331. +
  63332. + MV_REG_WRITE(ETH_PORT_MARVELL_HEADER_REG(port), mvHeaderReg);
  63333. +
  63334. + return MV_OK;
  63335. +}
  63336. +
  63337. +#if (MV_ETH_VERSION >= 4)
  63338. +/*******************************************************************************
  63339. +* mvEthEjpModeSet - Enable / Disable EJP policy for TX.
  63340. +*
  63341. +* DESCRIPTION:
  63342. +* This function
  63343. +*
  63344. +* INPUT:
  63345. +* void* pPortHandle - Pointer to port specific handler;
  63346. +* MV_BOOL TRUE - enable EJP mode
  63347. +* FALSE - disable EJP mode
  63348. +*
  63349. +* OUTPUT: MV_STATUS
  63350. +* MV_OK - Success
  63351. +* Other - Failure
  63352. +*
  63353. +* RETURN: None.
  63354. +*
  63355. +*******************************************************************************/
  63356. +MV_STATUS mvEthEjpModeSet(void* pPortHandle, int mode)
  63357. +{
  63358. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63359. + int port = pPortCtrl->portNo;
  63360. +
  63361. + if((port < 0) || (port >= mvCtrlEthMaxPortGet()))
  63362. + return MV_OUT_OF_RANGE;
  63363. +
  63364. + pPortCtrl = ethPortCtrl[port];
  63365. + if(pPortCtrl == NULL)
  63366. + return MV_NOT_FOUND;
  63367. +
  63368. + pPortCtrl->portConfig.ejpMode = mode;
  63369. + if(mode)
  63370. + {
  63371. + /* EJP enabled */
  63372. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), ETH_TX_EJP_ENABLE_MASK);
  63373. + }
  63374. + else
  63375. + {
  63376. + /* EJP disabled */
  63377. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), 0);
  63378. + }
  63379. + mvOsPrintf("eth_%d: EJP %s - ETH_TXQ_CMD_1_REG: 0x%x = 0x%08x\n",
  63380. + port, mode ? "Enabled" : "Disabled", ETH_TXQ_CMD_1_REG(port),
  63381. + MV_REG_READ(ETH_TXQ_CMD_1_REG(port)));
  63382. +
  63383. + return MV_OK;
  63384. +}
  63385. +#endif /* MV_ETH_VERSION >= 4 */
  63386. +
  63387. +/*******************************************************************************
  63388. +* mvEthStatusGet - Get major properties of the port .
  63389. +*
  63390. +* DESCRIPTION:
  63391. +* This function get major properties of the port (link, speed, duplex,
  63392. +* flowControl, etc) and return them using the single structure.
  63393. +*
  63394. +* INPUT:
  63395. +* void* pPortHandle - Pointer to port specific handler;
  63396. +*
  63397. +* OUTPUT:
  63398. +* MV_ETH_PORT_STATUS* pStatus - Pointer to structure, were port status
  63399. +* will be placed.
  63400. +*
  63401. +* RETURN: None.
  63402. +*
  63403. +*******************************************************************************/
  63404. +void mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus)
  63405. +{
  63406. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63407. + int port = pPortCtrl->portNo;
  63408. +
  63409. + MV_U32 regValue;
  63410. +
  63411. + regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );
  63412. +
  63413. + if(regValue & ETH_GMII_SPEED_1000_MASK)
  63414. + pStatus->speed = MV_ETH_SPEED_1000;
  63415. + else if(regValue & ETH_MII_SPEED_100_MASK)
  63416. + pStatus->speed = MV_ETH_SPEED_100;
  63417. + else
  63418. + pStatus->speed = MV_ETH_SPEED_10;
  63419. +
  63420. + if(regValue & ETH_LINK_UP_MASK)
  63421. + pStatus->isLinkUp = MV_TRUE;
  63422. + else
  63423. + pStatus->isLinkUp = MV_FALSE;
  63424. +
  63425. + if(regValue & ETH_FULL_DUPLEX_MASK)
  63426. + pStatus->duplex = MV_ETH_DUPLEX_FULL;
  63427. + else
  63428. + pStatus->duplex = MV_ETH_DUPLEX_HALF;
  63429. +
  63430. +
  63431. + if(regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK)
  63432. + pStatus->flowControl = MV_ETH_FC_ENABLE;
  63433. + else
  63434. + pStatus->flowControl = MV_ETH_FC_DISABLE;
  63435. +}
  63436. +
  63437. +
  63438. +/******************************************************************************/
  63439. +/* PHY Control Functions */
  63440. +/******************************************************************************/
  63441. +
  63442. +
  63443. +/*******************************************************************************
  63444. +* mvEthPhyAddrSet - Set the ethernet port PHY address.
  63445. +*
  63446. +* DESCRIPTION:
  63447. +* This routine set the ethernet port PHY address according to given
  63448. +* parameter.
  63449. +*
  63450. +* INPUT:
  63451. +* void* pPortHandle - Pointer to port specific handler;
  63452. +* int phyAddr - PHY address
  63453. +*
  63454. +* RETURN:
  63455. +* None.
  63456. +*
  63457. +*******************************************************************************/
  63458. +void mvEthPhyAddrSet(void* pPortHandle, int phyAddr)
  63459. +{
  63460. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63461. + int port = pPortCtrl->portNo;
  63462. + unsigned int regData;
  63463. +
  63464. + regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));
  63465. +
  63466. + regData &= ~ETH_PHY_ADDR_MASK;
  63467. + regData |= phyAddr;
  63468. +
  63469. + MV_REG_WRITE(ETH_PHY_ADDR_REG(port), regData);
  63470. +
  63471. + return;
  63472. +}
  63473. +
  63474. +/*******************************************************************************
  63475. +* mvEthPhyAddrGet - Get the ethernet port PHY address.
  63476. +*
  63477. +* DESCRIPTION:
  63478. +* This routine returns the given ethernet port PHY address.
  63479. +*
  63480. +* INPUT:
  63481. +* void* pPortHandle - Pointer to port specific handler;
  63482. +*
  63483. +*
  63484. +* RETURN: int - PHY address.
  63485. +*
  63486. +*******************************************************************************/
  63487. +int mvEthPhyAddrGet(void* pPortHandle)
  63488. +{
  63489. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63490. + int port = pPortCtrl->portNo;
  63491. + unsigned int regData;
  63492. +
  63493. + regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));
  63494. +
  63495. + return ((regData >> (5 * port)) & 0x1f);
  63496. +}
  63497. +
  63498. +/******************************************************************************/
  63499. +/* Descriptor handling Functions */
  63500. +/******************************************************************************/
  63501. +
  63502. +/*******************************************************************************
  63503. +* etherInitRxDescRing - Curve a Rx chain desc list and buffer in memory.
  63504. +*
  63505. +* DESCRIPTION:
  63506. +* This function prepares a Rx chained list of descriptors and packet
  63507. +* buffers in a form of a ring. The routine must be called after port
  63508. +* initialization routine and before port start routine.
  63509. +* The Ethernet SDMA engine uses CPU bus addresses to access the various
  63510. +* devices in the system (i.e. DRAM). This function uses the ethernet
  63511. +* struct 'virtual to physical' routine (set by the user) to set the ring
  63512. +* with physical addresses.
  63513. +*
  63514. +* INPUT:
  63515. +* ETH_QUEUE_CTRL *pEthPortCtrl Ethernet Port Control srtuct.
  63516. +* int rxQueue Number of Rx queue.
  63517. +* int rxDescNum Number of Rx descriptors
  63518. +* MV_U8* rxDescBaseAddr Rx descriptors memory area base addr.
  63519. +*
  63520. +* OUTPUT:
  63521. +* The routine updates the Ethernet port control struct with information
  63522. +* regarding the Rx descriptors and buffers.
  63523. +*
  63524. +* RETURN: None
  63525. +*
  63526. +*******************************************************************************/
  63527. +static void ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)
  63528. +{
  63529. + ETH_RX_DESC *pRxDescBase, *pRxDesc, *pRxPrevDesc;
  63530. + int ix, rxDescNum = pPortCtrl->rxQueueConfig[queue].descrNum;
  63531. + ETH_QUEUE_CTRL *pQueueCtrl = &pPortCtrl->rxQueue[queue];
  63532. +
  63533. + /* Make sure descriptor address is cache line size aligned */
  63534. + pRxDescBase = (ETH_RX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr,
  63535. + CPU_D_CACHE_LINE_SIZE);
  63536. +
  63537. + pRxDesc = (ETH_RX_DESC*)pRxDescBase;
  63538. + pRxPrevDesc = pRxDesc;
  63539. +
  63540. + /* initialize the Rx descriptors ring */
  63541. + for (ix=0; ix<rxDescNum; ix++)
  63542. + {
  63543. + pRxDesc->bufSize = 0x0;
  63544. + pRxDesc->byteCnt = 0x0;
  63545. + pRxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  63546. + pRxDesc->bufPtr = 0x0;
  63547. + pRxDesc->returnInfo = 0x0;
  63548. + pRxPrevDesc = pRxDesc;
  63549. + if(ix == (rxDescNum-1))
  63550. + {
  63551. + /* Closing Rx descriptors ring */
  63552. + pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDescBase);
  63553. + }
  63554. + else
  63555. + {
  63556. + pRxDesc = (ETH_RX_DESC*)((MV_ULONG)pRxDesc + ETH_RX_DESC_ALIGNED_SIZE);
  63557. + pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDesc);
  63558. + }
  63559. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxPrevDesc);
  63560. + }
  63561. +
  63562. + pQueueCtrl->pCurrentDescr = pRxDescBase;
  63563. + pQueueCtrl->pUsedDescr = pRxDescBase;
  63564. +
  63565. + pQueueCtrl->pFirstDescr = pRxDescBase;
  63566. + pQueueCtrl->pLastDescr = pRxDesc;
  63567. + pQueueCtrl->resource = 0;
  63568. +}
  63569. +
  63570. +void ethResetRxDescRing(void* pPortHndl, int queue)
  63571. +{
  63572. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63573. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[queue];
  63574. + ETH_RX_DESC* pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;
  63575. +
  63576. + pQueueCtrl->resource = 0;
  63577. + if(pQueueCtrl->pFirstDescr != NULL)
  63578. + {
  63579. + while(MV_TRUE)
  63580. + {
  63581. + pRxDesc->bufSize = 0x0;
  63582. + pRxDesc->byteCnt = 0x0;
  63583. + pRxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  63584. + pRxDesc->bufPtr = 0x0;
  63585. + pRxDesc->returnInfo = 0x0;
  63586. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);
  63587. + if( (void*)pRxDesc == pQueueCtrl->pLastDescr)
  63588. + break;
  63589. + pRxDesc = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);
  63590. + }
  63591. + pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;
  63592. + pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;
  63593. +
  63594. + /* Update RX Command register */
  63595. + pPortCtrl->portRxQueueCmdReg |= (1 << queue);
  63596. +
  63597. + /* update HW */
  63598. + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),
  63599. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  63600. + }
  63601. + else
  63602. + {
  63603. + /* Update RX Command register */
  63604. + pPortCtrl->portRxQueueCmdReg &= ~(1 << queue);
  63605. +
  63606. + /* update HW */
  63607. + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0);
  63608. + }
  63609. +}
  63610. +
  63611. +/*******************************************************************************
  63612. +* etherInitTxDescRing - Curve a Tx chain desc list and buffer in memory.
  63613. +*
  63614. +* DESCRIPTION:
  63615. +* This function prepares a Tx chained list of descriptors and packet
  63616. +* buffers in a form of a ring. The routine must be called after port
  63617. +* initialization routine and before port start routine.
  63618. +* The Ethernet SDMA engine uses CPU bus addresses to access the various
  63619. +* devices in the system (i.e. DRAM). This function uses the ethernet
  63620. +* struct 'virtual to physical' routine (set by the user) to set the ring
  63621. +* with physical addresses.
  63622. +*
  63623. +* INPUT:
  63624. +* ETH_PORT_CTRL *pEthPortCtrl Ethernet Port Control srtuct.
  63625. +* int txQueue Number of Tx queue.
  63626. +* int txDescNum Number of Tx descriptors
  63627. +* int txBuffSize Size of Tx buffer
  63628. +* MV_U8* pTxDescBase Tx descriptors memory area base addr.
  63629. +*
  63630. +* OUTPUT:
  63631. +* The routine updates the Ethernet port control struct with information
  63632. +* regarding the Tx descriptors and buffers.
  63633. +*
  63634. +* RETURN: None.
  63635. +*
  63636. +*******************************************************************************/
  63637. +static void ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)
  63638. +{
  63639. + ETH_TX_DESC *pTxDescBase, *pTxDesc, *pTxPrevDesc;
  63640. + int ix, txDescNum = pPortCtrl->txQueueConfig[queue].descrNum;
  63641. + ETH_QUEUE_CTRL *pQueueCtrl = &pPortCtrl->txQueue[queue];
  63642. +
  63643. + /* Make sure descriptor address is cache line size aligned */
  63644. + pTxDescBase = (ETH_TX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr,
  63645. + CPU_D_CACHE_LINE_SIZE);
  63646. +
  63647. + pTxDesc = (ETH_TX_DESC*)pTxDescBase;
  63648. + pTxPrevDesc = pTxDesc;
  63649. +
  63650. + /* initialize the Tx descriptors ring */
  63651. + for (ix=0; ix<txDescNum; ix++)
  63652. + {
  63653. + pTxDesc->byteCnt = 0x0000;
  63654. + pTxDesc->L4iChk = 0x0000;
  63655. + pTxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  63656. + pTxDesc->bufPtr = 0x0;
  63657. + pTxDesc->returnInfo = 0x0;
  63658. +
  63659. + pTxPrevDesc = pTxDesc;
  63660. +
  63661. + if(ix == (txDescNum-1))
  63662. + {
  63663. + /* Closing Tx descriptors ring */
  63664. + pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDescBase);
  63665. + }
  63666. + else
  63667. + {
  63668. + pTxDesc = (ETH_TX_DESC*)((MV_ULONG)pTxDesc + ETH_TX_DESC_ALIGNED_SIZE);
  63669. + pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDesc);
  63670. + }
  63671. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxPrevDesc);
  63672. + }
  63673. +
  63674. + pQueueCtrl->pCurrentDescr = pTxDescBase;
  63675. + pQueueCtrl->pUsedDescr = pTxDescBase;
  63676. +
  63677. + pQueueCtrl->pFirstDescr = pTxDescBase;
  63678. + pQueueCtrl->pLastDescr = pTxDesc;
  63679. + /* Leave one TX descriptor out of use */
  63680. + pQueueCtrl->resource = txDescNum - 1;
  63681. +}
  63682. +
  63683. +void ethResetTxDescRing(void* pPortHndl, int queue)
  63684. +{
  63685. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63686. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[queue];
  63687. + ETH_TX_DESC* pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;
  63688. +
  63689. + pQueueCtrl->resource = 0;
  63690. + if(pQueueCtrl->pFirstDescr != NULL)
  63691. + {
  63692. + while(MV_TRUE)
  63693. + {
  63694. + pTxDesc->byteCnt = 0x0000;
  63695. + pTxDesc->L4iChk = 0x0000;
  63696. + pTxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  63697. + pTxDesc->bufPtr = 0x0;
  63698. + pTxDesc->returnInfo = 0x0;
  63699. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);
  63700. + pQueueCtrl->resource++;
  63701. + if( (void*)pTxDesc == pQueueCtrl->pLastDescr)
  63702. + break;
  63703. + pTxDesc = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);
  63704. + }
  63705. + /* Leave one TX descriptor out of use */
  63706. + pQueueCtrl->resource--;
  63707. + pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;
  63708. + pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;
  63709. +
  63710. + /* Update TX Command register */
  63711. + pPortCtrl->portTxQueueCmdReg |= MV_32BIT_LE_FAST(1 << queue);
  63712. + /* update HW */
  63713. + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),
  63714. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  63715. + }
  63716. + else
  63717. + {
  63718. + /* Update TX Command register */
  63719. + pPortCtrl->portTxQueueCmdReg &= MV_32BIT_LE_FAST(~(1 << queue));
  63720. + /* update HW */
  63721. + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0 );
  63722. + }
  63723. +}
  63724. +
  63725. +/*******************************************************************************
  63726. +* ethAllocDescrMemory - Free memory allocated for RX and TX descriptors.
  63727. +*
  63728. +* DESCRIPTION:
  63729. +* This function allocates memory for RX and TX descriptors.
  63730. +* - If ETH_DESCR_IN_SRAM defined, allocate memory from SRAM.
  63731. +* - If ETH_DESCR_IN_SDRAM defined, allocate memory in SDRAM.
  63732. +*
  63733. +* INPUT:
  63734. +* int size - size of memory should be allocated.
  63735. +*
  63736. +* RETURN: None
  63737. +*
  63738. +*******************************************************************************/
  63739. +static MV_U8* ethAllocDescrMemory(ETH_PORT_CTRL* pPortCtrl, int descSize,
  63740. + MV_ULONG* pPhysAddr, MV_U32 *memHandle)
  63741. +{
  63742. + MV_U8* pVirt;
  63743. +
  63744. +#if defined(ETH_DESCR_IN_SRAM)
  63745. + if(ethDescInSram == MV_TRUE)
  63746. + pVirt = (char*)mvSramMalloc(descSize, pPhysAddr);
  63747. + else
  63748. +#endif /* ETH_DESCR_IN_SRAM */
  63749. + {
  63750. +#ifdef ETH_DESCR_UNCACHED
  63751. + pVirt = (MV_U8*)mvOsIoUncachedMalloc(pPortCtrl->osHandle, descSize,
  63752. + pPhysAddr,memHandle);
  63753. +#else
  63754. + pVirt = (MV_U8*)mvOsIoCachedMalloc(pPortCtrl->osHandle, descSize,
  63755. + pPhysAddr, memHandle);
  63756. +#endif /* ETH_DESCR_UNCACHED */
  63757. + }
  63758. + memset(pVirt, 0, descSize);
  63759. +
  63760. + return pVirt;
  63761. +}
  63762. +
  63763. +/*******************************************************************************
  63764. +* ethFreeDescrMemory - Free memory allocated for RX and TX descriptors.
  63765. +*
  63766. +* DESCRIPTION:
  63767. +* This function frees memory allocated for RX and TX descriptors.
  63768. +* - If ETH_DESCR_IN_SRAM defined, free memory using gtSramFree() function.
  63769. +* - If ETH_DESCR_IN_SDRAM defined, free memory using mvOsFree() function.
  63770. +*
  63771. +* INPUT:
  63772. +* void* pVirtAddr - virtual pointer to memory allocated for RX and TX
  63773. +* desriptors.
  63774. +*
  63775. +* RETURN: None
  63776. +*
  63777. +*******************************************************************************/
  63778. +void ethFreeDescrMemory(ETH_PORT_CTRL* pPortCtrl, MV_BUF_INFO* pDescBuf)
  63779. +{
  63780. + if( (pDescBuf == NULL) || (pDescBuf->bufVirtPtr == NULL) )
  63781. + return;
  63782. +
  63783. +#if defined(ETH_DESCR_IN_SRAM)
  63784. + if( ethDescInSram )
  63785. + {
  63786. + mvSramFree(pDescBuf->bufSize, pDescBuf->bufPhysAddr, pDescBuf->bufVirtPtr);
  63787. + return;
  63788. + }
  63789. +#endif /* ETH_DESCR_IN_SRAM */
  63790. +
  63791. +#ifdef ETH_DESCR_UNCACHED
  63792. + mvOsIoUncachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr,
  63793. + pDescBuf->bufVirtPtr,pDescBuf->memHandle);
  63794. +#else
  63795. + mvOsIoCachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr,
  63796. + pDescBuf->bufVirtPtr,pDescBuf->memHandle);
  63797. +#endif /* ETH_DESCR_UNCACHED */
  63798. +}
  63799. +
  63800. +/******************************************************************************/
  63801. +/* Other Functions */
  63802. +/******************************************************************************/
  63803. +
  63804. +void mvEthPortPowerUp(int port)
  63805. +{
  63806. + MV_U32 regVal;
  63807. +
  63808. + /* MAC Cause register should be cleared */
  63809. + MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);
  63810. +
  63811. + if (mvBoardIsPortInSgmii(port))
  63812. + mvEthPortSgmiiConfig(port);
  63813. +
  63814. + /* Cancel Port Reset */
  63815. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
  63816. + regVal &= (~ETH_PORT_RESET_MASK);
  63817. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);
  63818. + while( (MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) != 0);
  63819. +}
  63820. +
  63821. +void mvEthPortPowerDown(int port)
  63822. +{
  63823. + MV_U32 regVal;
  63824. +
  63825. + /* Port must be DISABLED */
  63826. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
  63827. + if( (regVal & ETH_PORT_ENABLE_MASK) != 0)
  63828. + {
  63829. + mvOsPrintf("ethPort #%d: PowerDown - port must be Disabled (PSC=0x%x)\n",
  63830. + port, regVal);
  63831. + return;
  63832. + }
  63833. +
  63834. + /* Port Reset (Read after write the register as a precaution) */
  63835. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
  63836. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal | ETH_PORT_RESET_MASK);
  63837. + while((MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) == 0);
  63838. +}
  63839. +
  63840. +static void mvEthPortSgmiiConfig(int port)
  63841. +{
  63842. + MV_U32 regVal;
  63843. +
  63844. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
  63845. +
  63846. + regVal |= (ETH_SGMII_MODE_MASK /*| ETH_INBAND_AUTO_NEG_ENABLE_MASK */);
  63847. + regVal &= (~ETH_INBAND_AUTO_NEG_BYPASS_MASK);
  63848. +
  63849. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);
  63850. +}
  63851. +
  63852. +
  63853. +
  63854. +
  63855. +
  63856. +
  63857. +
  63858. +
  63859. +
  63860. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c
  63861. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c 1970-01-01 01:00:00.000000000 +0100
  63862. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c 2010-11-09 20:28:11.072495491 +0100
  63863. @@ -0,0 +1,748 @@
  63864. +/*******************************************************************************
  63865. +Copyright (C) Marvell International Ltd. and its affiliates
  63866. +
  63867. +This software file (the "File") is owned and distributed by Marvell
  63868. +International Ltd. and/or its affiliates ("Marvell") under the following
  63869. +alternative licensing terms. Once you have made an election to distribute the
  63870. +File under one of the following license alternatives, please (i) delete this
  63871. +introductory statement regarding license alternatives, (ii) delete the two
  63872. +license alternatives that you have not elected to use and (iii) preserve the
  63873. +Marvell copyright notice above.
  63874. +
  63875. +********************************************************************************
  63876. +Marvell Commercial License Option
  63877. +
  63878. +If you received this File from Marvell and you have entered into a commercial
  63879. +license agreement (a "Commercial License") with Marvell, the File is licensed
  63880. +to you under the terms of the applicable Commercial License.
  63881. +
  63882. +********************************************************************************
  63883. +Marvell GPL License Option
  63884. +
  63885. +If you received this File from Marvell, you may opt to use, redistribute and/or
  63886. +modify this File in accordance with the terms and conditions of the General
  63887. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  63888. +available along with the File in the license.txt file or by writing to the Free
  63889. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  63890. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  63891. +
  63892. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  63893. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  63894. +DISCLAIMED. The GPL License provides additional details about this warranty
  63895. +disclaimer.
  63896. +********************************************************************************
  63897. +Marvell BSD License Option
  63898. +
  63899. +If you received this File from Marvell, you may opt to use, redistribute and/or
  63900. +modify this File under the following licensing terms.
  63901. +Redistribution and use in source and binary forms, with or without modification,
  63902. +are permitted provided that the following conditions are met:
  63903. +
  63904. + * Redistributions of source code must retain the above copyright notice,
  63905. + this list of conditions and the following disclaimer.
  63906. +
  63907. + * Redistributions in binary form must reproduce the above copyright
  63908. + notice, this list of conditions and the following disclaimer in the
  63909. + documentation and/or other materials provided with the distribution.
  63910. +
  63911. + * Neither the name of Marvell nor the names of its contributors may be
  63912. + used to endorse or promote products derived from this software without
  63913. + specific prior written permission.
  63914. +
  63915. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  63916. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  63917. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  63918. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  63919. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  63920. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  63921. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  63922. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  63923. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  63924. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  63925. +
  63926. +*******************************************************************************/
  63927. +
  63928. +/*******************************************************************************
  63929. +* mvEthDebug.c - Source file for user friendly debug functions
  63930. +*
  63931. +* DESCRIPTION:
  63932. +*
  63933. +* DEPENDENCIES:
  63934. +* None.
  63935. +*
  63936. +*******************************************************************************/
  63937. +
  63938. +#include "mvOs.h"
  63939. +#include "mvCommon.h"
  63940. +#include "mvTypes.h"
  63941. +#include "mv802_3.h"
  63942. +#include "mvDebug.h"
  63943. +#include "ctrlEnv/mvCtrlEnvLib.h"
  63944. +#include "eth-phy/mvEthPhy.h"
  63945. +#include "eth/mvEth.h"
  63946. +#include "eth/gbe/mvEthDebug.h"
  63947. +
  63948. +/* #define mvOsPrintf printf */
  63949. +
  63950. +void mvEthPortShow(void* pHndl);
  63951. +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);
  63952. +
  63953. +/******************************************************************************/
  63954. +/* Debug functions */
  63955. +/******************************************************************************/
  63956. +void ethRxCoal(int port, int usec)
  63957. +{
  63958. + void* pHndl;
  63959. +
  63960. + pHndl = mvEthPortHndlGet(port);
  63961. + if(pHndl != NULL)
  63962. + {
  63963. + mvEthRxCoalSet(pHndl, usec);
  63964. + }
  63965. +}
  63966. +
  63967. +void ethTxCoal(int port, int usec)
  63968. +{
  63969. + void* pHndl;
  63970. +
  63971. + pHndl = mvEthPortHndlGet(port);
  63972. + if(pHndl != NULL)
  63973. + {
  63974. + mvEthTxCoalSet(pHndl, usec);
  63975. + }
  63976. +}
  63977. +
  63978. +#if (MV_ETH_VERSION >= 4)
  63979. +void ethEjpModeSet(int port, int mode)
  63980. +{
  63981. + void* pHndl;
  63982. +
  63983. + pHndl = mvEthPortHndlGet(port);
  63984. + if(pHndl != NULL)
  63985. + {
  63986. + mvEthEjpModeSet(pHndl, mode);
  63987. + }
  63988. +}
  63989. +#endif /* (MV_ETH_VERSION >= 4) */
  63990. +
  63991. +void ethBpduRxQ(int port, int bpduQueue)
  63992. +{
  63993. + void* pHndl;
  63994. +
  63995. + pHndl = mvEthPortHndlGet(port);
  63996. + if(pHndl != NULL)
  63997. + {
  63998. + mvEthBpduRxQueue(pHndl, bpduQueue);
  63999. + }
  64000. +}
  64001. +
  64002. +void ethArpRxQ(int port, int arpQueue)
  64003. +{
  64004. + void* pHndl;
  64005. +
  64006. + pHndl = mvEthPortHndlGet(port);
  64007. + if(pHndl != NULL)
  64008. + {
  64009. + mvEthArpRxQueue(pHndl, arpQueue);
  64010. + }
  64011. +}
  64012. +
  64013. +void ethTcpRxQ(int port, int tcpQueue)
  64014. +{
  64015. + void* pHndl;
  64016. +
  64017. + pHndl = mvEthPortHndlGet(port);
  64018. + if(pHndl != NULL)
  64019. + {
  64020. + mvEthTcpRxQueue(pHndl, tcpQueue);
  64021. + }
  64022. +}
  64023. +
  64024. +void ethUdpRxQ(int port, int udpQueue)
  64025. +{
  64026. + void* pHndl;
  64027. +
  64028. + pHndl = mvEthPortHndlGet(port);
  64029. + if(pHndl != NULL)
  64030. + {
  64031. + mvEthUdpRxQueue(pHndl, udpQueue);
  64032. + }
  64033. +}
  64034. +
  64035. +void ethTxPolicyRegs(int port)
  64036. +{
  64037. + int queue;
  64038. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)mvEthPortHndlGet(port);
  64039. +
  64040. + if(pPortCtrl == NULL)
  64041. + {
  64042. + return;
  64043. + }
  64044. + mvOsPrintf("Port #%d TX Policy: EJP=%d, TXQs: ",
  64045. + port, pPortCtrl->portConfig.ejpMode);
  64046. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  64047. + {
  64048. + if(pPortCtrl->txQueueConfig[queue].descrNum > 0)
  64049. + mvOsPrintf("%d, ", queue);
  64050. + }
  64051. + mvOsPrintf("\n");
  64052. +
  64053. + mvOsPrintf("\n\t TX policy Port #%d configuration registers\n", port);
  64054. +
  64055. + mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
  64056. + ETH_TX_QUEUE_COMMAND_REG(port),
  64057. + MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );
  64058. +
  64059. + mvOsPrintf("ETH_TX_FIXED_PRIO_CFG_REG : 0x%X = 0x%08x\n",
  64060. + ETH_TX_FIXED_PRIO_CFG_REG(port),
  64061. + MV_REG_READ( ETH_TX_FIXED_PRIO_CFG_REG(port) ) );
  64062. +
  64063. + mvOsPrintf("ETH_TX_TOKEN_RATE_CFG_REG : 0x%X = 0x%08x\n",
  64064. + ETH_TX_TOKEN_RATE_CFG_REG(port),
  64065. + MV_REG_READ( ETH_TX_TOKEN_RATE_CFG_REG(port) ) );
  64066. +
  64067. + mvOsPrintf("ETH_MAX_TRANSMIT_UNIT_REG : 0x%X = 0x%08x\n",
  64068. + ETH_MAX_TRANSMIT_UNIT_REG(port),
  64069. + MV_REG_READ( ETH_MAX_TRANSMIT_UNIT_REG(port) ) );
  64070. +
  64071. + mvOsPrintf("ETH_TX_TOKEN_BUCKET_SIZE_REG : 0x%X = 0x%08x\n",
  64072. + ETH_TX_TOKEN_BUCKET_SIZE_REG(port),
  64073. + MV_REG_READ( ETH_TX_TOKEN_BUCKET_SIZE_REG(port) ) );
  64074. +
  64075. + mvOsPrintf("ETH_TX_TOKEN_BUCKET_COUNT_REG : 0x%X = 0x%08x\n",
  64076. + ETH_TX_TOKEN_BUCKET_COUNT_REG(port),
  64077. + MV_REG_READ( ETH_TX_TOKEN_BUCKET_COUNT_REG(port) ) );
  64078. +
  64079. + for(queue=0; queue<MV_ETH_MAX_TXQ; queue++)
  64080. + {
  64081. + mvOsPrintf("\n\t TX policy Port #%d, Queue #%d configuration registers\n", port, queue);
  64082. +
  64083. + mvOsPrintf("ETH_TXQ_TOKEN_COUNT_REG : 0x%X = 0x%08x\n",
  64084. + ETH_TXQ_TOKEN_COUNT_REG(port, queue),
  64085. + MV_REG_READ( ETH_TXQ_TOKEN_COUNT_REG(port, queue) ) );
  64086. +
  64087. + mvOsPrintf("ETH_TXQ_TOKEN_CFG_REG : 0x%X = 0x%08x\n",
  64088. + ETH_TXQ_TOKEN_CFG_REG(port, queue),
  64089. + MV_REG_READ( ETH_TXQ_TOKEN_CFG_REG(port, queue) ) );
  64090. +
  64091. + mvOsPrintf("ETH_TXQ_ARBITER_CFG_REG : 0x%X = 0x%08x\n",
  64092. + ETH_TXQ_ARBITER_CFG_REG(port, queue),
  64093. + MV_REG_READ( ETH_TXQ_ARBITER_CFG_REG(port, queue) ) );
  64094. + }
  64095. + mvOsPrintf("\n");
  64096. +}
  64097. +
  64098. +/* Print important registers of Ethernet port */
  64099. +void ethPortRegs(int port)
  64100. +{
  64101. + mvOsPrintf("\n\t ethGiga #%d port Registers:\n", port);
  64102. +
  64103. + mvOsPrintf("ETH_PORT_STATUS_REG : 0x%X = 0x%08x\n",
  64104. + ETH_PORT_STATUS_REG(port),
  64105. + MV_REG_READ( ETH_PORT_STATUS_REG(port) ) );
  64106. +
  64107. + mvOsPrintf("ETH_PORT_SERIAL_CTRL_REG : 0x%X = 0x%08x\n",
  64108. + ETH_PORT_SERIAL_CTRL_REG(port),
  64109. + MV_REG_READ( ETH_PORT_SERIAL_CTRL_REG(port) ) );
  64110. +
  64111. + mvOsPrintf("ETH_PORT_CONFIG_REG : 0x%X = 0x%08x\n",
  64112. + ETH_PORT_CONFIG_REG(port),
  64113. + MV_REG_READ( ETH_PORT_CONFIG_REG(port) ) );
  64114. +
  64115. + mvOsPrintf("ETH_PORT_CONFIG_EXTEND_REG : 0x%X = 0x%08x\n",
  64116. + ETH_PORT_CONFIG_EXTEND_REG(port),
  64117. + MV_REG_READ( ETH_PORT_CONFIG_EXTEND_REG(port) ) );
  64118. +
  64119. + mvOsPrintf("ETH_SDMA_CONFIG_REG : 0x%X = 0x%08x\n",
  64120. + ETH_SDMA_CONFIG_REG(port),
  64121. + MV_REG_READ( ETH_SDMA_CONFIG_REG(port) ) );
  64122. +
  64123. + mvOsPrintf("ETH_TX_FIFO_URGENT_THRESH_REG : 0x%X = 0x%08x\n",
  64124. + ETH_TX_FIFO_URGENT_THRESH_REG(port),
  64125. + MV_REG_READ( ETH_TX_FIFO_URGENT_THRESH_REG(port) ) );
  64126. +
  64127. + mvOsPrintf("ETH_RX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
  64128. + ETH_RX_QUEUE_COMMAND_REG(port),
  64129. + MV_REG_READ( ETH_RX_QUEUE_COMMAND_REG(port) ) );
  64130. +
  64131. + mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
  64132. + ETH_TX_QUEUE_COMMAND_REG(port),
  64133. + MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );
  64134. +
  64135. + mvOsPrintf("ETH_INTR_CAUSE_REG : 0x%X = 0x%08x\n",
  64136. + ETH_INTR_CAUSE_REG(port),
  64137. + MV_REG_READ( ETH_INTR_CAUSE_REG(port) ) );
  64138. +
  64139. + mvOsPrintf("ETH_INTR_EXTEND_CAUSE_REG : 0x%X = 0x%08x\n",
  64140. + ETH_INTR_CAUSE_EXT_REG(port),
  64141. + MV_REG_READ( ETH_INTR_CAUSE_EXT_REG(port) ) );
  64142. +
  64143. + mvOsPrintf("ETH_INTR_MASK_REG : 0x%X = 0x%08x\n",
  64144. + ETH_INTR_MASK_REG(port),
  64145. + MV_REG_READ( ETH_INTR_MASK_REG(port) ) );
  64146. +
  64147. + mvOsPrintf("ETH_INTR_EXTEND_MASK_REG : 0x%X = 0x%08x\n",
  64148. + ETH_INTR_MASK_EXT_REG(port),
  64149. + MV_REG_READ( ETH_INTR_MASK_EXT_REG(port) ) );
  64150. +
  64151. + mvOsPrintf("ETH_RX_DESCR_STAT_CMD_REG : 0x%X = 0x%08x\n",
  64152. + ETH_RX_DESCR_STAT_CMD_REG(port, 0),
  64153. + MV_REG_READ( ETH_RX_DESCR_STAT_CMD_REG(port, 0) ) );
  64154. +
  64155. + mvOsPrintf("ETH_RX_BYTE_COUNT_REG : 0x%X = 0x%08x\n",
  64156. + ETH_RX_BYTE_COUNT_REG(port, 0),
  64157. + MV_REG_READ( ETH_RX_BYTE_COUNT_REG(port, 0) ) );
  64158. +
  64159. + mvOsPrintf("ETH_RX_BUF_PTR_REG : 0x%X = 0x%08x\n",
  64160. + ETH_RX_BUF_PTR_REG(port, 0),
  64161. + MV_REG_READ( ETH_RX_BUF_PTR_REG(port, 0) ) );
  64162. +
  64163. + mvOsPrintf("ETH_RX_CUR_DESC_PTR_REG : 0x%X = 0x%08x\n",
  64164. + ETH_RX_CUR_DESC_PTR_REG(port, 0),
  64165. + MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, 0) ) );
  64166. +}
  64167. +
  64168. +
  64169. +/* Print Giga Ethernet UNIT registers */
  64170. +void ethRegs(int port)
  64171. +{
  64172. + mvOsPrintf("ETH_PHY_ADDR_REG : 0x%X = 0x%08x\n",
  64173. + ETH_PHY_ADDR_REG(port),
  64174. + MV_REG_READ(ETH_PHY_ADDR_REG(port)) );
  64175. +
  64176. + mvOsPrintf("ETH_UNIT_INTR_CAUSE_REG : 0x%X = 0x%08x\n",
  64177. + ETH_UNIT_INTR_CAUSE_REG(port),
  64178. + MV_REG_READ( ETH_UNIT_INTR_CAUSE_REG(port)) );
  64179. +
  64180. + mvOsPrintf("ETH_UNIT_INTR_MASK_REG : 0x%X = 0x%08x\n",
  64181. + ETH_UNIT_INTR_MASK_REG(port),
  64182. + MV_REG_READ( ETH_UNIT_INTR_MASK_REG(port)) );
  64183. +
  64184. + mvOsPrintf("ETH_UNIT_ERROR_ADDR_REG : 0x%X = 0x%08x\n",
  64185. + ETH_UNIT_ERROR_ADDR_REG(port),
  64186. + MV_REG_READ(ETH_UNIT_ERROR_ADDR_REG(port)) );
  64187. +
  64188. + mvOsPrintf("ETH_UNIT_INT_ADDR_ERROR_REG : 0x%X = 0x%08x\n",
  64189. + ETH_UNIT_INT_ADDR_ERROR_REG(port),
  64190. + MV_REG_READ(ETH_UNIT_INT_ADDR_ERROR_REG(port)) );
  64191. +
  64192. +}
  64193. +
  64194. +/******************************************************************************/
  64195. +/* MIB Counters functions */
  64196. +/******************************************************************************/
  64197. +
  64198. +/*******************************************************************************
  64199. +* ethClearMibCounters - Clear all MIB counters
  64200. +*
  64201. +* DESCRIPTION:
  64202. +* This function clears all MIB counters of a specific ethernet port.
  64203. +* A read from the MIB counter will reset the counter.
  64204. +*
  64205. +* INPUT:
  64206. +* int port - Ethernet Port number.
  64207. +*
  64208. +* RETURN: None
  64209. +*
  64210. +*******************************************************************************/
  64211. +void ethClearCounters(int port)
  64212. +{
  64213. + void* pHndl;
  64214. +
  64215. + pHndl = mvEthPortHndlGet(port);
  64216. + if(pHndl != NULL)
  64217. + mvEthMibCountersClear(pHndl);
  64218. +
  64219. + return;
  64220. +}
  64221. +
  64222. +
  64223. +/* Print counters of the Ethernet port */
  64224. +void ethPortCounters(int port)
  64225. +{
  64226. + MV_U32 regValue, regValHigh;
  64227. + void* pHndl;
  64228. +
  64229. + pHndl = mvEthPortHndlGet(port);
  64230. + if(pHndl == NULL)
  64231. + return;
  64232. +
  64233. + mvOsPrintf("\n\t Port #%d MIB Counters\n\n", port);
  64234. +
  64235. + mvOsPrintf("GoodFramesReceived = %u\n",
  64236. + mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_RECEIVED, NULL));
  64237. + mvOsPrintf("BadFramesReceived = %u\n",
  64238. + mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FRAMES_RECEIVED, NULL));
  64239. + mvOsPrintf("BroadcastFramesReceived = %u\n",
  64240. + mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_RECEIVED, NULL));
  64241. + mvOsPrintf("MulticastFramesReceived = %u\n",
  64242. + mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_RECEIVED, NULL));
  64243. +
  64244. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW,
  64245. + &regValHigh);
  64246. + mvOsPrintf("GoodOctetsReceived = 0x%08x%08x\n",
  64247. + regValHigh, regValue);
  64248. +
  64249. + mvOsPrintf("\n");
  64250. + mvOsPrintf("GoodFramesSent = %u\n",
  64251. + mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_SENT, NULL));
  64252. + mvOsPrintf("BroadcastFramesSent = %u\n",
  64253. + mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_SENT, NULL));
  64254. + mvOsPrintf("MulticastFramesSent = %u\n",
  64255. + mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_SENT, NULL));
  64256. +
  64257. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_SENT_LOW,
  64258. + &regValHigh);
  64259. + mvOsPrintf("GoodOctetsSent = 0x%08x%08x\n", regValHigh, regValue);
  64260. +
  64261. +
  64262. + mvOsPrintf("\n\t FC Control Counters\n");
  64263. +
  64264. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNREC_MAC_CONTROL_RECEIVED, NULL);
  64265. + mvOsPrintf("UnrecogMacControlReceived = %u\n", regValue);
  64266. +
  64267. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FC_RECEIVED, NULL);
  64268. + mvOsPrintf("GoodFCFramesReceived = %u\n", regValue);
  64269. +
  64270. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FC_RECEIVED, NULL);
  64271. + mvOsPrintf("BadFCFramesReceived = %u\n", regValue);
  64272. +
  64273. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FC_SENT, NULL);
  64274. + mvOsPrintf("FCFramesSent = %u\n", regValue);
  64275. +
  64276. +
  64277. + mvOsPrintf("\n\t RX Errors\n");
  64278. +
  64279. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_OCTETS_RECEIVED, NULL);
  64280. + mvOsPrintf("BadOctetsReceived = %u\n", regValue);
  64281. +
  64282. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNDERSIZE_RECEIVED, NULL);
  64283. + mvOsPrintf("UndersizeFramesReceived = %u\n", regValue);
  64284. +
  64285. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FRAGMENTS_RECEIVED, NULL);
  64286. + mvOsPrintf("FragmentsReceived = %u\n", regValue);
  64287. +
  64288. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_OVERSIZE_RECEIVED, NULL);
  64289. + mvOsPrintf("OversizeFramesReceived = %u\n", regValue);
  64290. +
  64291. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_JABBER_RECEIVED, NULL);
  64292. + mvOsPrintf("JabbersReceived = %u\n", regValue);
  64293. +
  64294. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_MAC_RECEIVE_ERROR, NULL);
  64295. + mvOsPrintf("MacReceiveErrors = %u\n", regValue);
  64296. +
  64297. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_CRC_EVENT, NULL);
  64298. + mvOsPrintf("BadCrcReceived = %u\n", regValue);
  64299. +
  64300. + mvOsPrintf("\n\t TX Errors\n");
  64301. +
  64302. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR, NULL);
  64303. + mvOsPrintf("TxMacErrors = %u\n", regValue);
  64304. +
  64305. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_EXCESSIVE_COLLISION, NULL);
  64306. + mvOsPrintf("TxExcessiveCollisions = %u\n", regValue);
  64307. +
  64308. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_COLLISION, NULL);
  64309. + mvOsPrintf("TxCollisions = %u\n", regValue);
  64310. +
  64311. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_LATE_COLLISION, NULL);
  64312. + mvOsPrintf("TxLateCollisions = %u\n", regValue);
  64313. +
  64314. +
  64315. + mvOsPrintf("\n");
  64316. + regValue = MV_REG_READ( ETH_RX_DISCARD_PKTS_CNTR_REG(port));
  64317. + mvOsPrintf("Rx Discard packets counter = %u\n", regValue);
  64318. +
  64319. + regValue = MV_REG_READ(ETH_RX_OVERRUN_PKTS_CNTR_REG(port));
  64320. + mvOsPrintf("Rx Overrun packets counter = %u\n", regValue);
  64321. +}
  64322. +
  64323. +/* Print RMON counters of the Ethernet port */
  64324. +void ethPortRmonCounters(int port)
  64325. +{
  64326. + void* pHndl;
  64327. +
  64328. + pHndl = mvEthPortHndlGet(port);
  64329. + if(pHndl == NULL)
  64330. + return;
  64331. +
  64332. + mvOsPrintf("\n\t Port #%d RMON MIB Counters\n\n", port);
  64333. +
  64334. + mvOsPrintf("64 ByteFramesReceived = %u\n",
  64335. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_64_OCTETS, NULL));
  64336. + mvOsPrintf("65...127 ByteFramesReceived = %u\n",
  64337. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_65_TO_127_OCTETS, NULL));
  64338. + mvOsPrintf("128...255 ByteFramesReceived = %u\n",
  64339. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_128_TO_255_OCTETS, NULL));
  64340. + mvOsPrintf("256...511 ByteFramesReceived = %u\n",
  64341. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_256_TO_511_OCTETS, NULL));
  64342. + mvOsPrintf("512...1023 ByteFramesReceived = %u\n",
  64343. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_512_TO_1023_OCTETS, NULL));
  64344. + mvOsPrintf("1024...Max ByteFramesReceived = %u\n",
  64345. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_1024_TO_MAX_OCTETS, NULL));
  64346. +}
  64347. +
  64348. +/* Print port information */
  64349. +void ethPortStatus(int port)
  64350. +{
  64351. + void* pHndl;
  64352. +
  64353. + pHndl = mvEthPortHndlGet(port);
  64354. + if(pHndl != NULL)
  64355. + {
  64356. + mvEthPortShow(pHndl);
  64357. + }
  64358. +}
  64359. +
  64360. +/* Print port queues information */
  64361. +void ethPortQueues(int port, int rxQueue, int txQueue, int mode)
  64362. +{
  64363. + void* pHndl;
  64364. +
  64365. + pHndl = mvEthPortHndlGet(port);
  64366. + if(pHndl != NULL)
  64367. + {
  64368. + mvEthQueuesShow(pHndl, rxQueue, txQueue, mode);
  64369. + }
  64370. +}
  64371. +
  64372. +void ethUcastSet(int port, char* macStr, int queue)
  64373. +{
  64374. + void* pHndl;
  64375. + MV_U8 macAddr[MV_MAC_ADDR_SIZE];
  64376. +
  64377. + pHndl = mvEthPortHndlGet(port);
  64378. + if(pHndl != NULL)
  64379. + {
  64380. + mvMacStrToHex(macStr, macAddr);
  64381. + mvEthMacAddrSet(pHndl, macAddr, queue);
  64382. + }
  64383. +}
  64384. +
  64385. +
  64386. +void ethPortUcastShow(int port)
  64387. +{
  64388. + MV_U32 unicastReg, macL, macH;
  64389. + int i, j;
  64390. +
  64391. + macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(port));
  64392. + macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(port));
  64393. +
  64394. + mvOsPrintf("\n\t Port #%d Unicast MAC table: %02x:%02x:%02x:%02x:%02x:%02x\n\n",
  64395. + port, ((macH >> 24) & 0xff), ((macH >> 16) & 0xff),
  64396. + ((macH >> 8) & 0xff), (macH & 0xff),
  64397. + ((macL >> 8) & 0xff), (macL & 0xff) );
  64398. +
  64399. + for (i=0; i<4; i++)
  64400. + {
  64401. + unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(port) + i*4));
  64402. + for(j=0; j<4; j++)
  64403. + {
  64404. + MV_U8 macEntry = (unicastReg >> (8*j)) & 0xFF;
  64405. +
  64406. + mvOsPrintf("%X: %8s, Q = %d\n", i*4+j,
  64407. + (macEntry & BIT0) ? "Accept" : "Reject", (macEntry >> 1) & 0x7);
  64408. + }
  64409. + }
  64410. +}
  64411. +
  64412. +void ethMcastAdd(int port, char* macStr, int queue)
  64413. +{
  64414. + void* pHndl;
  64415. + MV_U8 macAddr[MV_MAC_ADDR_SIZE];
  64416. +
  64417. + pHndl = mvEthPortHndlGet(port);
  64418. + if(pHndl != NULL)
  64419. + {
  64420. + mvMacStrToHex(macStr, macAddr);
  64421. + mvEthMcastAddrSet(pHndl, macAddr, queue);
  64422. + }
  64423. +}
  64424. +
  64425. +void ethPortMcast(int port)
  64426. +{
  64427. + int tblIdx, regIdx;
  64428. + MV_U32 regVal;
  64429. +
  64430. + mvOsPrintf("\n\t Port #%d Special (IP) Multicast table: 01:00:5E:00:00:XX\n\n",
  64431. + port);
  64432. +
  64433. + for(tblIdx=0; tblIdx<(256/4); tblIdx++)
  64434. + {
  64435. + regVal = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(port) + tblIdx*4));
  64436. + for(regIdx=0; regIdx<4; regIdx++)
  64437. + {
  64438. + if((regVal & (0x01 << (regIdx*8))) != 0)
  64439. + {
  64440. + mvOsPrintf("0x%02X: Accepted, rxQ = %d\n",
  64441. + tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));
  64442. + }
  64443. + }
  64444. + }
  64445. + mvOsPrintf("\n\t Port #%d Other Multicast table\n\n", port);
  64446. + for(tblIdx=0; tblIdx<(256/4); tblIdx++)
  64447. + {
  64448. + regVal = MV_REG_READ((ETH_DA_FILTER_OTH_MCAST_BASE(port) + tblIdx*4));
  64449. + for(regIdx=0; regIdx<4; regIdx++)
  64450. + {
  64451. + if((regVal & (0x01 << (regIdx*8))) != 0)
  64452. + {
  64453. + mvOsPrintf("Crc8=0x%02X: Accepted, rxQ = %d\n",
  64454. + tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));
  64455. + }
  64456. + }
  64457. + }
  64458. +}
  64459. +
  64460. +
  64461. +/* Print status of Ethernet port */
  64462. +void mvEthPortShow(void* pHndl)
  64463. +{
  64464. + MV_U32 regValue, rxCoal, txCoal;
  64465. + int speed, queue, port;
  64466. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pHndl;
  64467. +
  64468. + port = pPortCtrl->portNo;
  64469. +
  64470. + regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );
  64471. +
  64472. + mvOsPrintf("\n\t ethGiga #%d port Status: 0x%04x = 0x%08x\n\n",
  64473. + port, ETH_PORT_STATUS_REG(port), regValue);
  64474. +
  64475. + mvOsPrintf("descInSram=%d, descSwCoher=%d\n",
  64476. + ethDescInSram, ethDescSwCoher);
  64477. +
  64478. + if(regValue & ETH_GMII_SPEED_1000_MASK)
  64479. + speed = 1000;
  64480. + else if(regValue & ETH_MII_SPEED_100_MASK)
  64481. + speed = 100;
  64482. + else
  64483. + speed = 10;
  64484. +
  64485. + mvEthCoalGet(pPortCtrl, &rxCoal, &txCoal);
  64486. +
  64487. + /* Link, Speed, Duplex, FlowControl */
  64488. + mvOsPrintf("Link=%s, Speed=%d, Duplex=%s, RxFlowControl=%s",
  64489. + (regValue & ETH_LINK_UP_MASK) ? "UP" : "DOWN",
  64490. + speed,
  64491. + (regValue & ETH_FULL_DUPLEX_MASK) ? "FULL" : "HALF",
  64492. + (regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK) ? "ENABLE" : "DISABLE");
  64493. +
  64494. + mvOsPrintf("\n");
  64495. +
  64496. + mvOsPrintf("RxCoal = %d usec, TxCoal = %d usec\n",
  64497. + rxCoal, txCoal);
  64498. +
  64499. + mvOsPrintf("rxDefQ=%d, arpQ=%d, bpduQ=%d, tcpQ=%d, udpQ=%d\n\n",
  64500. + pPortCtrl->portConfig.rxDefQ, pPortCtrl->portConfig.rxArpQ,
  64501. + pPortCtrl->portConfig.rxBpduQ,
  64502. + pPortCtrl->portConfig.rxTcpQ, pPortCtrl->portConfig.rxUdpQ);
  64503. +
  64504. + /* Print all RX and TX queues */
  64505. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  64506. + {
  64507. + mvOsPrintf("RX Queue #%d: base=0x%lx, free=%d\n",
  64508. + queue, (MV_ULONG)pPortCtrl->rxQueue[queue].pFirstDescr,
  64509. + mvEthRxResourceGet(pPortCtrl, queue) );
  64510. + }
  64511. + mvOsPrintf("\n");
  64512. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  64513. + {
  64514. + mvOsPrintf("TX Queue #%d: base=0x%lx, free=%d\n",
  64515. + queue, (MV_ULONG)pPortCtrl->txQueue[queue].pFirstDescr,
  64516. + mvEthTxResourceGet(pPortCtrl, queue) );
  64517. + }
  64518. +}
  64519. +
  64520. +/* Print RX and TX queue of the Ethernet port */
  64521. +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode)
  64522. +{
  64523. + ETH_PORT_CTRL *pPortCtrl = (ETH_PORT_CTRL*)pHndl;
  64524. + ETH_QUEUE_CTRL *pQueueCtrl;
  64525. + MV_U32 regValue;
  64526. + ETH_RX_DESC *pRxDescr;
  64527. + ETH_TX_DESC *pTxDescr;
  64528. + int i, port = pPortCtrl->portNo;
  64529. +
  64530. + if( (rxQueue >=0) && (rxQueue < MV_ETH_RX_Q_NUM) )
  64531. + {
  64532. + pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);
  64533. + mvOsPrintf("Port #%d, RX Queue #%d\n\n", port, rxQueue);
  64534. +
  64535. + mvOsPrintf("CURR_RX_DESC_PTR : 0x%X = 0x%08x\n",
  64536. + ETH_RX_CUR_DESC_PTR_REG(port, rxQueue),
  64537. + MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue)));
  64538. +
  64539. +
  64540. + if(pQueueCtrl->pFirstDescr != NULL)
  64541. + {
  64542. + mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",
  64543. + (MV_ULONG)pQueueCtrl->pFirstDescr, (MV_ULONG)pQueueCtrl->pLastDescr,
  64544. + pQueueCtrl->resource);
  64545. + mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",
  64546. + (MV_ULONG)pQueueCtrl->pCurrentDescr,
  64547. + (MV_ULONG)pQueueCtrl->pUsedDescr);
  64548. +
  64549. + if(mode == 1)
  64550. + {
  64551. + pRxDescr = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;
  64552. + i = 0;
  64553. + do
  64554. + {
  64555. + mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%4d, buf=%08x, pkt=%lx, os=%lx\n",
  64556. + i, (MV_U32)pRxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pRxDescr),
  64557. + pRxDescr->cmdSts, pRxDescr->byteCnt, (MV_U32)pRxDescr->bufSize,
  64558. + (unsigned int)pRxDescr->bufPtr, (MV_ULONG)pRxDescr->returnInfo,
  64559. + ((MV_PKT_INFO*)pRxDescr->returnInfo)->osInfo);
  64560. +
  64561. + ETH_DESCR_INV(pPortCtrl, pRxDescr);
  64562. + pRxDescr = RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl);
  64563. + i++;
  64564. + } while (pRxDescr != pQueueCtrl->pFirstDescr);
  64565. + }
  64566. + }
  64567. + else
  64568. + mvOsPrintf("RX Queue #%d is NOT CREATED\n", rxQueue);
  64569. + }
  64570. +
  64571. + if( (txQueue >=0) && (txQueue < MV_ETH_TX_Q_NUM) )
  64572. + {
  64573. + pQueueCtrl = &(pPortCtrl->txQueue[txQueue]);
  64574. + mvOsPrintf("Port #%d, TX Queue #%d\n\n", port, txQueue);
  64575. +
  64576. + regValue = MV_REG_READ( ETH_TX_CUR_DESC_PTR_REG(port, txQueue));
  64577. + mvOsPrintf("CURR_TX_DESC_PTR : 0x%X = 0x%08x\n",
  64578. + ETH_TX_CUR_DESC_PTR_REG(port, txQueue), regValue);
  64579. +
  64580. + if(pQueueCtrl->pFirstDescr != NULL)
  64581. + {
  64582. + mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",
  64583. + (MV_ULONG)pQueueCtrl->pFirstDescr,
  64584. + (MV_ULONG)pQueueCtrl->pLastDescr,
  64585. + pQueueCtrl->resource);
  64586. + mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",
  64587. + (MV_ULONG)pQueueCtrl->pCurrentDescr,
  64588. + (MV_ULONG)pQueueCtrl->pUsedDescr);
  64589. +
  64590. + if(mode == 1)
  64591. + {
  64592. + pTxDescr = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;
  64593. + i = 0;
  64594. + do
  64595. + {
  64596. + mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%08x, pkt=%lx, os=%lx\n",
  64597. + i, (MV_U32)pTxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxDescr),
  64598. + pTxDescr->cmdSts, pTxDescr->byteCnt,
  64599. + (MV_U32)pTxDescr->bufPtr, (MV_ULONG)pTxDescr->returnInfo,
  64600. + pTxDescr->returnInfo ? (((MV_PKT_INFO*)pTxDescr->returnInfo)->osInfo) : 0x0);
  64601. +
  64602. + ETH_DESCR_INV(pPortCtrl, pTxDescr);
  64603. + pTxDescr = TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl);
  64604. + i++;
  64605. + } while (pTxDescr != pQueueCtrl->pFirstDescr);
  64606. + }
  64607. + }
  64608. + else
  64609. + mvOsPrintf("TX Queue #%d is NOT CREATED\n", txQueue);
  64610. + }
  64611. +}
  64612. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h
  64613. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h 1970-01-01 01:00:00.000000000 +0100
  64614. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h 2010-11-09 20:28:11.112495471 +0100
  64615. @@ -0,0 +1,146 @@
  64616. +/*******************************************************************************
  64617. +Copyright (C) Marvell International Ltd. and its affiliates
  64618. +
  64619. +This software file (the "File") is owned and distributed by Marvell
  64620. +International Ltd. and/or its affiliates ("Marvell") under the following
  64621. +alternative licensing terms. Once you have made an election to distribute the
  64622. +File under one of the following license alternatives, please (i) delete this
  64623. +introductory statement regarding license alternatives, (ii) delete the two
  64624. +license alternatives that you have not elected to use and (iii) preserve the
  64625. +Marvell copyright notice above.
  64626. +
  64627. +********************************************************************************
  64628. +Marvell Commercial License Option
  64629. +
  64630. +If you received this File from Marvell and you have entered into a commercial
  64631. +license agreement (a "Commercial License") with Marvell, the File is licensed
  64632. +to you under the terms of the applicable Commercial License.
  64633. +
  64634. +********************************************************************************
  64635. +Marvell GPL License Option
  64636. +
  64637. +If you received this File from Marvell, you may opt to use, redistribute and/or
  64638. +modify this File in accordance with the terms and conditions of the General
  64639. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  64640. +available along with the File in the license.txt file or by writing to the Free
  64641. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  64642. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  64643. +
  64644. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  64645. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  64646. +DISCLAIMED. The GPL License provides additional details about this warranty
  64647. +disclaimer.
  64648. +********************************************************************************
  64649. +Marvell BSD License Option
  64650. +
  64651. +If you received this File from Marvell, you may opt to use, redistribute and/or
  64652. +modify this File under the following licensing terms.
  64653. +Redistribution and use in source and binary forms, with or without modification,
  64654. +are permitted provided that the following conditions are met:
  64655. +
  64656. + * Redistributions of source code must retain the above copyright notice,
  64657. + this list of conditions and the following disclaimer.
  64658. +
  64659. + * Redistributions in binary form must reproduce the above copyright
  64660. + notice, this list of conditions and the following disclaimer in the
  64661. + documentation and/or other materials provided with the distribution.
  64662. +
  64663. + * Neither the name of Marvell nor the names of its contributors may be
  64664. + used to endorse or promote products derived from this software without
  64665. + specific prior written permission.
  64666. +
  64667. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  64668. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  64669. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  64670. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  64671. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  64672. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  64673. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  64674. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  64675. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  64676. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  64677. +
  64678. +*******************************************************************************/
  64679. +#ifndef __MV_ETH_DEBUG_H__
  64680. +#define __MV_ETH_DEBUG_H__
  64681. +
  64682. +#if 0
  64683. +/*
  64684. + ** Externs
  64685. + */
  64686. +void ethBpduRxQ(int port, int bpduQueue);
  64687. +void ethArpRxQ(int port, int bpduQueue);
  64688. +void ethTcpRxQ(int port, int bpduQueue);
  64689. +void ethUdpRxQ(int port, int bpduQueue);
  64690. +void ethMcastAdd(int port, char* macStr, int queue);
  64691. +
  64692. +#ifdef INCLUDE_MULTI_QUEUE
  64693. +void ethRxPolicy( int port);
  64694. +void ethTxPolicy( int port);
  64695. +void ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);
  64696. +void ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);
  64697. +void ethRxPolQ(int port, int rxQueue, int rxQuota);
  64698. +#endif /* INCLUDE_MULTI_QUEUE */
  64699. +
  64700. +void print_egiga_stat(void *sc, unsigned int port);
  64701. +void ethPortStatus (int port);
  64702. +void ethPortQueues( int port, int rxQueue, int txQueue, int mode);
  64703. +void ethPortMcast(int port);
  64704. +void ethPortRegs(int port);
  64705. +void ethPortCounters(int port);
  64706. +void ethPortRmonCounters(int port);
  64707. +void ethRxCoal(int port, int usec);
  64708. +void ethTxCoal(int port, int usec);
  64709. +
  64710. +void ethRegs(int port);
  64711. +void ethClearCounters(int port);
  64712. +void ethUcastSet(int port, char* macStr, int queue);
  64713. +void ethPortUcastShow(int port);
  64714. +
  64715. +#ifdef CONFIG_MV_ETH_HEADER
  64716. +void run_com_header(const char *buffer);
  64717. +#endif
  64718. +
  64719. +#ifdef INCLUDE_MULTI_QUEUE
  64720. +void ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);
  64721. +void ethRxPolQ(int port, int queue, int quota);
  64722. +void ethRxPolicy(int port);
  64723. +void ethTxPolDef(int port, int txQ, char* headerHexStr);
  64724. +void ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);
  64725. +void ethTxPolicy(int port);
  64726. +#endif /* INCLUDE_MULTI_QUEUE */
  64727. +
  64728. +#if (MV_ETH_VERSION >= 4)
  64729. +void ethEjpModeSet(int port, int mode)
  64730. +#endif
  64731. +#endif /* 0 */
  64732. +
  64733. +
  64734. +
  64735. +
  64736. +void ethRxCoal(int port, int usec);
  64737. +void ethTxCoal(int port, int usec);
  64738. +#if (MV_ETH_VERSION >= 4)
  64739. +void ethEjpModeSet(int port, int mode);
  64740. +#endif /* (MV_ETH_VERSION >= 4) */
  64741. +
  64742. +void ethBpduRxQ(int port, int bpduQueue);
  64743. +void ethArpRxQ(int port, int arpQueue);
  64744. +void ethTcpRxQ(int port, int tcpQueue);
  64745. +void ethUdpRxQ(int port, int udpQueue);
  64746. +void ethTxPolicyRegs(int port);
  64747. +void ethPortRegs(int port);
  64748. +void ethRegs(int port);
  64749. +void ethClearCounters(int port);
  64750. +void ethPortCounters(int port);
  64751. +void ethPortRmonCounters(int port);
  64752. +void ethPortStatus(int port);
  64753. +void ethPortQueues(int port, int rxQueue, int txQueue, int mode);
  64754. +void ethUcastSet(int port, char* macStr, int queue);
  64755. +void ethPortUcastShow(int port);
  64756. +void ethMcastAdd(int port, char* macStr, int queue);
  64757. +void ethPortMcast(int port);
  64758. +void mvEthPortShow(void* pHndl);
  64759. +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);
  64760. +
  64761. +#endif
  64762. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h
  64763. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h 1970-01-01 01:00:00.000000000 +0100
  64764. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h 2010-11-09 20:28:11.152495442 +0100
  64765. @@ -0,0 +1,751 @@
  64766. +/*******************************************************************************
  64767. +Copyright (C) Marvell International Ltd. and its affiliates
  64768. +
  64769. +This software file (the "File") is owned and distributed by Marvell
  64770. +International Ltd. and/or its affiliates ("Marvell") under the following
  64771. +alternative licensing terms. Once you have made an election to distribute the
  64772. +File under one of the following license alternatives, please (i) delete this
  64773. +introductory statement regarding license alternatives, (ii) delete the two
  64774. +license alternatives that you have not elected to use and (iii) preserve the
  64775. +Marvell copyright notice above.
  64776. +
  64777. +********************************************************************************
  64778. +Marvell Commercial License Option
  64779. +
  64780. +If you received this File from Marvell and you have entered into a commercial
  64781. +license agreement (a "Commercial License") with Marvell, the File is licensed
  64782. +to you under the terms of the applicable Commercial License.
  64783. +
  64784. +********************************************************************************
  64785. +Marvell GPL License Option
  64786. +
  64787. +If you received this File from Marvell, you may opt to use, redistribute and/or
  64788. +modify this File in accordance with the terms and conditions of the General
  64789. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  64790. +available along with the File in the license.txt file or by writing to the Free
  64791. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  64792. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  64793. +
  64794. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  64795. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  64796. +DISCLAIMED. The GPL License provides additional details about this warranty
  64797. +disclaimer.
  64798. +********************************************************************************
  64799. +Marvell BSD License Option
  64800. +
  64801. +If you received this File from Marvell, you may opt to use, redistribute and/or
  64802. +modify this File under the following licensing terms.
  64803. +Redistribution and use in source and binary forms, with or without modification,
  64804. +are permitted provided that the following conditions are met:
  64805. +
  64806. + * Redistributions of source code must retain the above copyright notice,
  64807. + this list of conditions and the following disclaimer.
  64808. +
  64809. + * Redistributions in binary form must reproduce the above copyright
  64810. + notice, this list of conditions and the following disclaimer in the
  64811. + documentation and/or other materials provided with the distribution.
  64812. +
  64813. + * Neither the name of Marvell nor the names of its contributors may be
  64814. + used to endorse or promote products derived from this software without
  64815. + specific prior written permission.
  64816. +
  64817. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  64818. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  64819. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  64820. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  64821. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  64822. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  64823. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  64824. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  64825. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  64826. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  64827. +
  64828. +*******************************************************************************/
  64829. +
  64830. +/*******************************************************************************
  64831. +* mvEth.h - Header File for : Marvell Gigabit Ethernet Controller
  64832. +*
  64833. +* DESCRIPTION:
  64834. +* This header file contains macros typedefs and function declaration specific to
  64835. +* the Marvell Gigabit Ethernet Controller.
  64836. +*
  64837. +* DEPENDENCIES:
  64838. +* None.
  64839. +*
  64840. +*******************************************************************************/
  64841. +
  64842. +#ifndef __mvEthGbe_h__
  64843. +#define __mvEthGbe_h__
  64844. +
  64845. +extern MV_BOOL ethDescInSram;
  64846. +extern MV_BOOL ethDescSwCoher;
  64847. +extern ETH_PORT_CTRL* ethPortCtrl[];
  64848. +
  64849. +static INLINE MV_ULONG ethDescVirtToPhy(ETH_QUEUE_CTRL* pQueueCtrl, MV_U8* pDesc)
  64850. +{
  64851. +#if defined (ETH_DESCR_IN_SRAM)
  64852. + if( ethDescInSram )
  64853. + return mvSramVirtToPhy(pDesc);
  64854. + else
  64855. +#endif /* ETH_DESCR_IN_SRAM */
  64856. + return (pQueueCtrl->descBuf.bufPhysAddr + (pDesc - pQueueCtrl->descBuf.bufVirtPtr));
  64857. +}
  64858. +/* Return port handler */
  64859. +#define mvEthPortHndlGet(port) ethPortCtrl[port]
  64860. +
  64861. +/* Used as WA for HW/SW race on TX */
  64862. +static INLINE int mvEthPortTxEnable(void* pPortHndl, int queue, int max_deep)
  64863. +{
  64864. + int deep = 0;
  64865. + MV_U32 txCurrReg, txEnReg;
  64866. + ETH_TX_DESC* pTxLastDesc;
  64867. + ETH_QUEUE_CTRL* pQueueCtrl;
  64868. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  64869. +
  64870. + txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));
  64871. + if( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) == 0)
  64872. + {
  64873. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
  64874. + return 0;
  64875. + }
  64876. +
  64877. + pQueueCtrl = &pPortCtrl->txQueue[queue];
  64878. + pTxLastDesc = pQueueCtrl->pCurrentDescr;
  64879. + txCurrReg = MV_REG_READ(ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue));
  64880. + if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)
  64881. + {
  64882. + /* All descriptors are processed, no chance for race */
  64883. + return 0;
  64884. + }
  64885. +
  64886. + /* Check distance betwee HW and SW location: */
  64887. + /* If distance between HW and SW pointers is less than max_deep descriptors */
  64888. + /* Race condition is possible, so wait end of TX and restart TXQ */
  64889. + while(deep < max_deep)
  64890. + {
  64891. + pTxLastDesc = TX_PREV_DESC_PTR(pTxLastDesc, pQueueCtrl);
  64892. + if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)
  64893. + {
  64894. + int count = 0;
  64895. +
  64896. + while( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) != 0)
  64897. + {
  64898. + count++;
  64899. + if(count > 10000)
  64900. + {
  64901. + mvOsPrintf("mvEthPortTxEnable: timeout - TXQ_CMD=0x%08x\n",
  64902. + MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) );
  64903. + break;
  64904. + }
  64905. + txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));
  64906. + }
  64907. +
  64908. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
  64909. + return count;
  64910. + }
  64911. + deep++;
  64912. + }
  64913. + /* Distance between HW and SW pointers is more than max_deep descriptors, */
  64914. + /* So NO race condition - do nothing */
  64915. + return -1;
  64916. +}
  64917. +
  64918. +
  64919. +/* defines */
  64920. +#define ETH_CSUM_MIN_BYTE_COUNT 72
  64921. +
  64922. +/* Tailgate and Kirwood have only 2K TX FIFO */
  64923. +#if (MV_ETH_VERSION == 2) || (MV_ETH_VERSION == 4)
  64924. +#define ETH_CSUM_MAX_BYTE_COUNT 1600
  64925. +#else
  64926. +#define ETH_CSUM_MAX_BYTE_COUNT 9*1024
  64927. +#endif /* MV_ETH_VERSION */
  64928. +
  64929. +#define ETH_MV_HEADER_SIZE 2
  64930. +#define ETH_MV_TX_EN
  64931. +
  64932. +/* An offest in Tx descriptors to store data for buffers less than 8 Bytes */
  64933. +#define MIN_TX_BUFF_LOAD 8
  64934. +#define TX_BUF_OFFSET_IN_DESC (ETH_TX_DESC_ALIGNED_SIZE - MIN_TX_BUFF_LOAD)
  64935. +
  64936. +/* Default port configuration value */
  64937. +#define PORT_CONFIG_VALUE \
  64938. + ETH_DEF_RX_QUEUE_MASK(0) | \
  64939. + ETH_DEF_RX_ARP_QUEUE_MASK(0) | \
  64940. + ETH_DEF_RX_TCP_QUEUE_MASK(0) | \
  64941. + ETH_DEF_RX_UDP_QUEUE_MASK(0) | \
  64942. + ETH_DEF_RX_BPDU_QUEUE_MASK(0) | \
  64943. + ETH_RX_CHECKSUM_WITH_PSEUDO_HDR
  64944. +
  64945. +/* Default port extend configuration value */
  64946. +#define PORT_CONFIG_EXTEND_VALUE 0
  64947. +
  64948. +#define PORT_SERIAL_CONTROL_VALUE \
  64949. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  64950. + BIT9 | \
  64951. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  64952. + ETH_MAX_RX_PACKET_1552BYTE | \
  64953. + ETH_SET_FULL_DUPLEX_MASK
  64954. +
  64955. +#define PORT_SERIAL_CONTROL_100MB_FORCE_VALUE \
  64956. + ETH_FORCE_LINK_PASS_MASK | \
  64957. + ETH_DISABLE_DUPLEX_AUTO_NEG_MASK | \
  64958. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  64959. + BIT9 | \
  64960. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  64961. + ETH_DISABLE_SPEED_AUTO_NEG_MASK | \
  64962. + ETH_SET_FULL_DUPLEX_MASK | \
  64963. + ETH_SET_MII_SPEED_100_MASK | \
  64964. + ETH_MAX_RX_PACKET_1552BYTE
  64965. +
  64966. +
  64967. +#define PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE \
  64968. + ETH_FORCE_LINK_PASS_MASK | \
  64969. + ETH_DISABLE_DUPLEX_AUTO_NEG_MASK | \
  64970. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  64971. + BIT9 | \
  64972. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  64973. + ETH_DISABLE_SPEED_AUTO_NEG_MASK | \
  64974. + ETH_SET_FULL_DUPLEX_MASK | \
  64975. + ETH_SET_GMII_SPEED_1000_MASK | \
  64976. + ETH_MAX_RX_PACKET_1552BYTE
  64977. +
  64978. +#define PORT_SERIAL_CONTROL_SGMII_IBAN_VALUE \
  64979. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  64980. + BIT9 | \
  64981. + ETH_IN_BAND_AN_EN_MASK | \
  64982. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  64983. + ETH_MAX_RX_PACKET_1552BYTE
  64984. +
  64985. +/* Function headers: */
  64986. +MV_VOID mvEthSetSpecialMcastTable(int portNo, int queue);
  64987. +MV_STATUS mvEthArpRxQueue(void* pPortHandle, int arpQueue);
  64988. +MV_STATUS mvEthUdpRxQueue(void* pPortHandle, int udpQueue);
  64989. +MV_STATUS mvEthTcpRxQueue(void* pPortHandle, int tcpQueue);
  64990. +MV_STATUS mvEthMacAddrGet(int portNo, unsigned char *pAddr);
  64991. +MV_VOID mvEthSetOtherMcastTable(int portNo, int queue);
  64992. +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);
  64993. +/* Interrupt Coalesting functions */
  64994. +MV_U32 mvEthRxCoalSet(void* pPortHndl, MV_U32 uSec);
  64995. +MV_U32 mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec);
  64996. +MV_STATUS mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal);
  64997. +
  64998. +/******************************************************************************/
  64999. +/* Data Flow functions */
  65000. +/******************************************************************************/
  65001. +static INLINE void mvEthPortTxRestart(void* pPortHndl)
  65002. +{
  65003. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65004. +
  65005. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
  65006. +}
  65007. +
  65008. +/* Get number of Free resources in specific TX queue */
  65009. +static INLINE int mvEthTxResourceGet(void* pPortHndl, int txQueue)
  65010. +{
  65011. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65012. +
  65013. + return (pPortCtrl->txQueue[txQueue].resource);
  65014. +}
  65015. +
  65016. +/* Get number of Free resources in specific RX queue */
  65017. +static INLINE int mvEthRxResourceGet(void* pPortHndl, int rxQueue)
  65018. +{
  65019. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65020. +
  65021. + return (pPortCtrl->rxQueue[rxQueue].resource);
  65022. +}
  65023. +
  65024. +static INLINE int mvEthTxQueueIsFull(void* pPortHndl, int txQueue)
  65025. +{
  65026. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65027. +
  65028. + if(pPortCtrl->txQueue[txQueue].resource == 0)
  65029. + return MV_TRUE;
  65030. +
  65031. + return MV_FALSE;
  65032. +}
  65033. +
  65034. +/* Get number of Free resources in specific RX queue */
  65035. +static INLINE int mvEthRxQueueIsFull(void* pPortHndl, int rxQueue)
  65036. +{
  65037. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65038. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
  65039. +
  65040. + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
  65041. + (pQueueCtrl->resource != 0) )
  65042. + return MV_TRUE;
  65043. +
  65044. + return MV_FALSE;
  65045. +}
  65046. +
  65047. +static INLINE int mvEthTxQueueIsEmpty(void* pPortHndl, int txQueue)
  65048. +{
  65049. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65050. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  65051. +
  65052. + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
  65053. + (pQueueCtrl->resource != 0) )
  65054. + {
  65055. + return MV_TRUE;
  65056. + }
  65057. + return MV_FALSE;
  65058. +}
  65059. +
  65060. +/* Get number of Free resources in specific RX queue */
  65061. +static INLINE int mvEthRxQueueIsEmpty(void* pPortHndl, int rxQueue)
  65062. +{
  65063. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65064. +
  65065. + if(pPortCtrl->rxQueue[rxQueue].resource == 0)
  65066. + return MV_TRUE;
  65067. +
  65068. + return MV_FALSE;
  65069. +}
  65070. +
  65071. +/*******************************************************************************
  65072. +* mvEthPortTx - Send an Ethernet packet
  65073. +*
  65074. +* DESCRIPTION:
  65075. +* This routine send a given packet described by pPktInfo parameter.
  65076. +* Single buffer only.
  65077. +*
  65078. +* INPUT:
  65079. +* void* pEthPortHndl - Ethernet Port handler.
  65080. +* int txQueue - Number of Tx queue.
  65081. +* MV_PKT_INFO *pPktInfo - User packet to send.
  65082. +*
  65083. +* RETURN:
  65084. +* MV_NO_RESOURCE - No enough resources to send this packet.
  65085. +* MV_ERROR - Unexpected Fatal error.
  65086. +* MV_OK - Packet send successfully.
  65087. +*
  65088. +*******************************************************************************/
  65089. +static INLINE MV_STATUS mvEthPortTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)
  65090. +{
  65091. + ETH_TX_DESC* pTxCurrDesc;
  65092. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  65093. + ETH_QUEUE_CTRL* pQueueCtrl;
  65094. + int portNo;
  65095. + MV_BUF_INFO* pBufInfo = pPktInfo->pFrags;
  65096. +
  65097. +#ifdef ETH_DEBUG
  65098. + if(pPortCtrl->portState != MV_ACTIVE)
  65099. + return MV_BAD_STATE;
  65100. +#endif /* ETH_DEBUG */
  65101. +
  65102. + portNo = pPortCtrl->portNo;
  65103. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  65104. +
  65105. + /* Get the Tx Desc ring indexes */
  65106. + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
  65107. +
  65108. + /* Check if there is enough resources to send the packet */
  65109. + if(pQueueCtrl->resource == 0)
  65110. + return MV_NO_RESOURCE;
  65111. +
  65112. + pTxCurrDesc->byteCnt = pBufInfo->dataSize;
  65113. +
  65114. + /* Flash Buffer */
  65115. + if(pPktInfo->pktSize != 0)
  65116. + {
  65117. +#ifdef MV_NETBSD
  65118. + pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;
  65119. + ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);
  65120. +#else
  65121. + pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);
  65122. +#endif
  65123. + pPktInfo->pktSize = 0;
  65124. + }
  65125. + else
  65126. + pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;
  65127. +
  65128. + pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;
  65129. +
  65130. + /* There is only one buffer in the packet */
  65131. + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
  65132. + pTxCurrDesc->cmdSts = pPktInfo->status |
  65133. + ETH_BUFFER_OWNED_BY_DMA |
  65134. + ETH_TX_GENERATE_CRC_MASK |
  65135. + ETH_TX_ENABLE_INTERRUPT_MASK |
  65136. + ETH_TX_ZERO_PADDING_MASK |
  65137. + ETH_TX_FIRST_DESC_MASK |
  65138. + ETH_TX_LAST_DESC_MASK;
  65139. +
  65140. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  65141. +
  65142. + pQueueCtrl->resource--;
  65143. + pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
  65144. +
  65145. + /* Apply send command */
  65146. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;
  65147. +
  65148. + return MV_OK;
  65149. +}
  65150. +
  65151. +
  65152. +/*******************************************************************************
  65153. +* mvEthPortSgTx - Send an Ethernet packet
  65154. +*
  65155. +* DESCRIPTION:
  65156. +* This routine send a given packet described by pBufInfo parameter. It
  65157. +* supports transmitting of a packet spaned over multiple buffers.
  65158. +*
  65159. +* INPUT:
  65160. +* void* pEthPortHndl - Ethernet Port handler.
  65161. +* int txQueue - Number of Tx queue.
  65162. +* MV_PKT_INFO *pPktInfo - User packet to send.
  65163. +*
  65164. +* RETURN:
  65165. +* MV_NO_RESOURCE - No enough resources to send this packet.
  65166. +* MV_ERROR - Unexpected Fatal error.
  65167. +* MV_OK - Packet send successfully.
  65168. +*
  65169. +*******************************************************************************/
  65170. +static INLINE MV_STATUS mvEthPortSgTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)
  65171. +{
  65172. + ETH_TX_DESC* pTxFirstDesc;
  65173. + ETH_TX_DESC* pTxCurrDesc;
  65174. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  65175. + ETH_QUEUE_CTRL* pQueueCtrl;
  65176. + int portNo, bufCount;
  65177. + MV_BUF_INFO* pBufInfo = pPktInfo->pFrags;
  65178. + MV_U8* pTxBuf;
  65179. +
  65180. +#ifdef ETH_DEBUG
  65181. + if(pPortCtrl->portState != MV_ACTIVE)
  65182. + return MV_BAD_STATE;
  65183. +#endif /* ETH_DEBUG */
  65184. +
  65185. + portNo = pPortCtrl->portNo;
  65186. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  65187. +
  65188. + /* Get the Tx Desc ring indexes */
  65189. + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
  65190. +
  65191. + /* Check if there is enough resources to send the packet */
  65192. + if(pQueueCtrl->resource < pPktInfo->numFrags)
  65193. + return MV_NO_RESOURCE;
  65194. +
  65195. + /* Remember first desc */
  65196. + pTxFirstDesc = pTxCurrDesc;
  65197. +
  65198. + bufCount = 0;
  65199. + while(MV_TRUE)
  65200. + {
  65201. + if(pBufInfo[bufCount].dataSize <= MIN_TX_BUFF_LOAD)
  65202. + {
  65203. + /* Buffers with a payload smaller than MIN_TX_BUFF_LOAD (8 bytes) must be aligned */
  65204. + /* to 64-bit boundary. Two options here: */
  65205. + /* 1) Usually, copy the payload to the reserved 8 bytes inside descriptor. */
  65206. + /* 2) In the Half duplex workaround, the reserved 8 bytes inside descriptor are used */
  65207. + /* as a pointer to the aligned buffer, copy the small payload to this buffer. */
  65208. + pTxBuf = ((MV_U8*)pTxCurrDesc)+TX_BUF_OFFSET_IN_DESC;
  65209. + mvOsBCopy(pBufInfo[bufCount].bufVirtPtr, pTxBuf, pBufInfo[bufCount].dataSize);
  65210. + pTxCurrDesc->bufPtr = ethDescVirtToPhy(pQueueCtrl, pTxBuf);
  65211. + }
  65212. + else
  65213. + {
  65214. + /* Flash Buffer */
  65215. +#ifdef MV_NETBSD
  65216. + pTxCurrDesc->bufPtr = pBufInfo[bufCount].bufPhysAddr;
  65217. + ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);
  65218. +#else
  65219. + pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);
  65220. +#endif
  65221. + }
  65222. +
  65223. + pTxCurrDesc->byteCnt = pBufInfo[bufCount].dataSize;
  65224. + bufCount++;
  65225. +
  65226. + if(bufCount >= pPktInfo->numFrags)
  65227. + break;
  65228. +
  65229. + if(bufCount > 1)
  65230. + {
  65231. + /* There is middle buffer of the packet Not First and Not Last */
  65232. + pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA;
  65233. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  65234. + }
  65235. + /* Go to next descriptor and next buffer */
  65236. + pTxCurrDesc = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
  65237. + }
  65238. + /* Set last desc with DMA ownership and interrupt enable. */
  65239. + pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;
  65240. + if(bufCount == 1)
  65241. + {
  65242. + /* There is only one buffer in the packet */
  65243. + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
  65244. + pTxCurrDesc->cmdSts = pPktInfo->status |
  65245. + ETH_BUFFER_OWNED_BY_DMA |
  65246. + ETH_TX_GENERATE_CRC_MASK |
  65247. + ETH_TX_ENABLE_INTERRUPT_MASK |
  65248. + ETH_TX_ZERO_PADDING_MASK |
  65249. + ETH_TX_FIRST_DESC_MASK |
  65250. + ETH_TX_LAST_DESC_MASK;
  65251. +
  65252. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  65253. + }
  65254. + else
  65255. + {
  65256. + /* Last but not First */
  65257. + pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA |
  65258. + ETH_TX_ENABLE_INTERRUPT_MASK |
  65259. + ETH_TX_ZERO_PADDING_MASK |
  65260. + ETH_TX_LAST_DESC_MASK;
  65261. +
  65262. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  65263. +
  65264. + /* Update First when more than one buffer in the packet */
  65265. + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
  65266. + pTxFirstDesc->cmdSts = pPktInfo->status |
  65267. + ETH_BUFFER_OWNED_BY_DMA |
  65268. + ETH_TX_GENERATE_CRC_MASK |
  65269. + ETH_TX_FIRST_DESC_MASK;
  65270. +
  65271. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxFirstDesc);
  65272. + }
  65273. + /* Update txQueue state */
  65274. + pQueueCtrl->resource -= bufCount;
  65275. + pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
  65276. +
  65277. + /* Apply send command */
  65278. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;
  65279. +
  65280. + return MV_OK;
  65281. +}
  65282. +
  65283. +/*******************************************************************************
  65284. +* mvEthPortTxDone - Free all used Tx descriptors and mBlks.
  65285. +*
  65286. +* DESCRIPTION:
  65287. +* This routine returns the transmitted packet information to the caller.
  65288. +*
  65289. +* INPUT:
  65290. +* void* pEthPortHndl - Ethernet Port handler.
  65291. +* int txQueue - Number of Tx queue.
  65292. +*
  65293. +* OUTPUT:
  65294. +* MV_PKT_INFO *pPktInfo - Pointer to packet was sent.
  65295. +*
  65296. +* RETURN:
  65297. +* MV_NOT_FOUND - No transmitted packets to return. Transmit in progress.
  65298. +* MV_EMPTY - No transmitted packets to return. TX Queue is empty.
  65299. +* MV_ERROR - Unexpected Fatal error.
  65300. +* MV_OK - There is transmitted packet in the queue,
  65301. +* 'pPktInfo' filled with relevant information.
  65302. +*
  65303. +*******************************************************************************/
  65304. +static INLINE MV_PKT_INFO* mvEthPortTxDone(void* pEthPortHndl, int txQueue)
  65305. +{
  65306. + ETH_TX_DESC* pTxCurrDesc;
  65307. + ETH_TX_DESC* pTxUsedDesc;
  65308. + ETH_QUEUE_CTRL* pQueueCtrl;
  65309. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  65310. + MV_PKT_INFO* pPktInfo;
  65311. + MV_U32 commandStatus;
  65312. +
  65313. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  65314. +
  65315. + pTxUsedDesc = pQueueCtrl->pUsedDescr;
  65316. + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
  65317. +
  65318. + while(MV_TRUE)
  65319. + {
  65320. + /* No more used descriptors */
  65321. + commandStatus = pTxUsedDesc->cmdSts;
  65322. + if (commandStatus & (ETH_BUFFER_OWNED_BY_DMA))
  65323. + {
  65324. + ETH_DESCR_INV(pPortCtrl, pTxUsedDesc);
  65325. + return NULL;
  65326. + }
  65327. + if( (pTxUsedDesc == pTxCurrDesc) &&
  65328. + (pQueueCtrl->resource != 0) )
  65329. + {
  65330. + return NULL;
  65331. + }
  65332. + pQueueCtrl->resource++;
  65333. + pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxUsedDesc, pQueueCtrl);
  65334. + if(commandStatus & (ETH_TX_LAST_DESC_MASK))
  65335. + {
  65336. + pPktInfo = (MV_PKT_INFO*)pTxUsedDesc->returnInfo;
  65337. + pPktInfo->status = commandStatus;
  65338. + return pPktInfo;
  65339. + }
  65340. + pTxUsedDesc = pQueueCtrl->pUsedDescr;
  65341. + }
  65342. +}
  65343. +
  65344. +/*******************************************************************************
  65345. +* mvEthPortRx - Get new received packets from Rx queue.
  65346. +*
  65347. +* DESCRIPTION:
  65348. +* This routine returns the received data to the caller. There is no
  65349. +* data copying during routine operation. All information is returned
  65350. +* using pointer to packet information struct passed from the caller.
  65351. +*
  65352. +* INPUT:
  65353. +* void* pEthPortHndl - Ethernet Port handler.
  65354. +* int rxQueue - Number of Rx queue.
  65355. +*
  65356. +* OUTPUT:
  65357. +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
  65358. +*
  65359. +* RETURN:
  65360. +* MV_NO_RESOURCE - No free resources in RX queue.
  65361. +* MV_ERROR - Unexpected Fatal error.
  65362. +* MV_OK - New packet received and 'pBufInfo' structure filled
  65363. +* with relevant information.
  65364. +*
  65365. +*******************************************************************************/
  65366. +static INLINE MV_PKT_INFO* mvEthPortRx(void* pEthPortHndl, int rxQueue)
  65367. +{
  65368. + ETH_RX_DESC *pRxCurrDesc;
  65369. + MV_U32 commandStatus;
  65370. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  65371. + ETH_QUEUE_CTRL* pQueueCtrl;
  65372. + MV_PKT_INFO* pPktInfo;
  65373. +
  65374. + pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);
  65375. +
  65376. + /* Check resources */
  65377. + if(pQueueCtrl->resource == 0)
  65378. + {
  65379. + mvOsPrintf("ethPortRx: no more resources\n");
  65380. + return NULL;
  65381. + }
  65382. + while(MV_TRUE)
  65383. + {
  65384. + /* Get the Rx Desc ring 'curr and 'used' indexes */
  65385. + pRxCurrDesc = pQueueCtrl->pCurrentDescr;
  65386. +
  65387. + commandStatus = pRxCurrDesc->cmdSts;
  65388. + if (commandStatus & (ETH_BUFFER_OWNED_BY_DMA))
  65389. + {
  65390. + /* Nothing to receive... */
  65391. + ETH_DESCR_INV(pPortCtrl, pRxCurrDesc);
  65392. + return NULL;
  65393. + }
  65394. +
  65395. + /* Valid RX only if FIRST and LAST bits are set */
  65396. + if( (commandStatus & (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK)) ==
  65397. + (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK) )
  65398. + {
  65399. + pPktInfo = (MV_PKT_INFO*)pRxCurrDesc->returnInfo;
  65400. + pPktInfo->pFrags->dataSize = pRxCurrDesc->byteCnt - 4;
  65401. + pPktInfo->status = commandStatus;
  65402. + pPktInfo->fragIP = pRxCurrDesc->bufSize & ETH_RX_IP_FRAGMENTED_FRAME_MASK;
  65403. +
  65404. + pQueueCtrl->resource--;
  65405. + /* Update 'curr' in data structure */
  65406. + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);
  65407. +
  65408. +#ifdef INCLUDE_SYNC_BARR
  65409. + mvCpuIfSyncBarr(DRAM_TARGET);
  65410. +#endif
  65411. + return pPktInfo;
  65412. + }
  65413. + else
  65414. + {
  65415. + ETH_RX_DESC* pRxUsedDesc = pQueueCtrl->pUsedDescr;
  65416. +
  65417. +#ifdef ETH_DEBUG
  65418. + mvOsPrintf("ethDrv: Unexpected Jumbo frame: "
  65419. + "status=0x%08x, byteCnt=%d, pData=0x%x\n",
  65420. + commandStatus, pRxCurrDesc->byteCnt, pRxCurrDesc->bufPtr);
  65421. +#endif /* ETH_DEBUG */
  65422. +
  65423. + /* move buffer from pCurrentDescr position to pUsedDescr position */
  65424. + pRxUsedDesc->bufPtr = pRxCurrDesc->bufPtr;
  65425. + pRxUsedDesc->returnInfo = pRxCurrDesc->returnInfo;
  65426. + pRxUsedDesc->bufSize = pRxCurrDesc->bufSize & ETH_RX_BUFFER_MASK;
  65427. +
  65428. + /* Return the descriptor to DMA ownership */
  65429. + pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA |
  65430. + ETH_RX_ENABLE_INTERRUPT_MASK;
  65431. +
  65432. + /* Flush descriptor and CPU pipe */
  65433. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);
  65434. +
  65435. + /* Move the used descriptor pointer to the next descriptor */
  65436. + pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);
  65437. + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);
  65438. + }
  65439. + }
  65440. +}
  65441. +
  65442. +/*******************************************************************************
  65443. +* mvEthPortRxDone - Returns a Rx buffer back to the Rx ring.
  65444. +*
  65445. +* DESCRIPTION:
  65446. +* This routine returns a Rx buffer back to the Rx ring.
  65447. +*
  65448. +* INPUT:
  65449. +* void* pEthPortHndl - Ethernet Port handler.
  65450. +* int rxQueue - Number of Rx queue.
  65451. +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
  65452. +*
  65453. +* RETURN:
  65454. +* MV_ERROR - Unexpected Fatal error.
  65455. +* MV_OUT_OF_RANGE - RX queue is already FULL, so this buffer can't be
  65456. +* returned to this queue.
  65457. +* MV_FULL - Buffer returned successfully and RX queue became full.
  65458. +* More buffers should not be returned at the time.
  65459. +* MV_OK - Buffer returned successfully and there are more free
  65460. +* places in the queue.
  65461. +*
  65462. +*******************************************************************************/
  65463. +static INLINE MV_STATUS mvEthPortRxDone(void* pEthPortHndl, int rxQueue, MV_PKT_INFO *pPktInfo)
  65464. +{
  65465. + ETH_RX_DESC* pRxUsedDesc;
  65466. + ETH_QUEUE_CTRL* pQueueCtrl;
  65467. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  65468. +
  65469. + pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
  65470. +
  65471. + /* Get 'used' Rx descriptor */
  65472. + pRxUsedDesc = pQueueCtrl->pUsedDescr;
  65473. +
  65474. + /* Check that ring is not FULL */
  65475. + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
  65476. + (pQueueCtrl->resource != 0) )
  65477. + {
  65478. + mvOsPrintf("%s %d: out of range Error resource=%d, curr=%p, used=%p\n",
  65479. + __FUNCTION__, pPortCtrl->portNo, pQueueCtrl->resource,
  65480. + pQueueCtrl->pCurrentDescr, pQueueCtrl->pUsedDescr);
  65481. + return MV_OUT_OF_RANGE;
  65482. + }
  65483. +
  65484. + pRxUsedDesc->bufPtr = pPktInfo->pFrags->bufPhysAddr;
  65485. + pRxUsedDesc->returnInfo = (MV_ULONG)pPktInfo;
  65486. + pRxUsedDesc->bufSize = pPktInfo->pFrags->bufSize & ETH_RX_BUFFER_MASK;
  65487. +
  65488. + /* Invalidate data buffer accordingly with pktSize */
  65489. + if(pPktInfo->pktSize != 0)
  65490. + {
  65491. + ETH_PACKET_CACHE_INVALIDATE(pPktInfo->pFrags->bufVirtPtr, pPktInfo->pktSize);
  65492. + pPktInfo->pktSize = 0;
  65493. + }
  65494. +
  65495. + /* Return the descriptor to DMA ownership */
  65496. + pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT_MASK;
  65497. +
  65498. + /* Flush descriptor and CPU pipe */
  65499. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);
  65500. +
  65501. + pQueueCtrl->resource++;
  65502. +
  65503. + /* Move the used descriptor pointer to the next descriptor */
  65504. + pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);
  65505. +
  65506. + /* If ring became Full return MV_FULL */
  65507. + if(pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr)
  65508. + return MV_FULL;
  65509. +
  65510. + return MV_OK;
  65511. +}
  65512. +
  65513. +
  65514. +#endif /* __mvEthGbe_h__ */
  65515. +
  65516. +
  65517. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h
  65518. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h 1970-01-01 01:00:00.000000000 +0100
  65519. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h 2010-11-09 20:28:11.192495435 +0100
  65520. @@ -0,0 +1,700 @@
  65521. +/*******************************************************************************
  65522. +Copyright (C) Marvell International Ltd. and its affiliates
  65523. +
  65524. +This software file (the "File") is owned and distributed by Marvell
  65525. +International Ltd. and/or its affiliates ("Marvell") under the following
  65526. +alternative licensing terms. Once you have made an election to distribute the
  65527. +File under one of the following license alternatives, please (i) delete this
  65528. +introductory statement regarding license alternatives, (ii) delete the two
  65529. +license alternatives that you have not elected to use and (iii) preserve the
  65530. +Marvell copyright notice above.
  65531. +
  65532. +********************************************************************************
  65533. +Marvell Commercial License Option
  65534. +
  65535. +If you received this File from Marvell and you have entered into a commercial
  65536. +license agreement (a "Commercial License") with Marvell, the File is licensed
  65537. +to you under the terms of the applicable Commercial License.
  65538. +
  65539. +********************************************************************************
  65540. +Marvell GPL License Option
  65541. +
  65542. +If you received this File from Marvell, you may opt to use, redistribute and/or
  65543. +modify this File in accordance with the terms and conditions of the General
  65544. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  65545. +available along with the File in the license.txt file or by writing to the Free
  65546. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  65547. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  65548. +
  65549. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  65550. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  65551. +DISCLAIMED. The GPL License provides additional details about this warranty
  65552. +disclaimer.
  65553. +********************************************************************************
  65554. +Marvell BSD License Option
  65555. +
  65556. +If you received this File from Marvell, you may opt to use, redistribute and/or
  65557. +modify this File under the following licensing terms.
  65558. +Redistribution and use in source and binary forms, with or without modification,
  65559. +are permitted provided that the following conditions are met:
  65560. +
  65561. + * Redistributions of source code must retain the above copyright notice,
  65562. + this list of conditions and the following disclaimer.
  65563. +
  65564. + * Redistributions in binary form must reproduce the above copyright
  65565. + notice, this list of conditions and the following disclaimer in the
  65566. + documentation and/or other materials provided with the distribution.
  65567. +
  65568. + * Neither the name of Marvell nor the names of its contributors may be
  65569. + used to endorse or promote products derived from this software without
  65570. + specific prior written permission.
  65571. +
  65572. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  65573. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  65574. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  65575. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  65576. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  65577. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  65578. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  65579. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  65580. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  65581. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  65582. +
  65583. +*******************************************************************************/
  65584. +
  65585. +
  65586. +#ifndef __INCmvEthRegsh
  65587. +#define __INCmvEthRegsh
  65588. +
  65589. +#ifdef __cplusplus
  65590. +extern "C" {
  65591. +#endif /* __cplusplus */
  65592. +
  65593. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  65594. +
  65595. +/****************************************/
  65596. +/* Ethernet Unit Registers */
  65597. +/****************************************/
  65598. +#define ETH_REG_BASE MV_ETH_REG_BASE
  65599. +
  65600. +#define ETH_PHY_ADDR_REG(port) (ETH_REG_BASE(port) + 0x000)
  65601. +#define ETH_SMI_REG(port) (ETH_REG_BASE(port) + 0x004)
  65602. +#define ETH_UNIT_DEF_ADDR_REG(port) (ETH_REG_BASE(port) + 0x008)
  65603. +#define ETH_UNIT_DEF_ID_REG(port) (ETH_REG_BASE(port) + 0x00c)
  65604. +#define ETH_UNIT_RESERVED(port) (ETH_REG_BASE(port) + 0x014)
  65605. +#define ETH_UNIT_INTR_CAUSE_REG(port) (ETH_REG_BASE(port) + 0x080)
  65606. +#define ETH_UNIT_INTR_MASK_REG(port) (ETH_REG_BASE(port) + 0x084)
  65607. +
  65608. +
  65609. +#define ETH_UNIT_ERROR_ADDR_REG(port) (ETH_REG_BASE(port) + 0x094)
  65610. +#define ETH_UNIT_INT_ADDR_ERROR_REG(port) (ETH_REG_BASE(port) + 0x098)
  65611. +#define ETH_UNIT_CONTROL_REG(port) (ETH_REG_BASE(port) + 0x0B0)
  65612. +
  65613. +#define ETH_PORT_CONFIG_REG(port) (ETH_REG_BASE(port) + 0x400)
  65614. +#define ETH_PORT_CONFIG_EXTEND_REG(port) (ETH_REG_BASE(port) + 0x404)
  65615. +#define ETH_MII_SERIAL_PARAM_REG(port) (ETH_REG_BASE(port) + 0x408)
  65616. +#define ETH_GMII_SERIAL_PARAM_REG(port) (ETH_REG_BASE(port) + 0x40c)
  65617. +#define ETH_VLAN_ETHER_TYPE_REG(port) (ETH_REG_BASE(port) + 0x410)
  65618. +#define ETH_MAC_ADDR_LOW_REG(port) (ETH_REG_BASE(port) + 0x414)
  65619. +#define ETH_MAC_ADDR_HIGH_REG(port) (ETH_REG_BASE(port) + 0x418)
  65620. +#define ETH_SDMA_CONFIG_REG(port) (ETH_REG_BASE(port) + 0x41c)
  65621. +#define ETH_DIFF_SERV_PRIO_REG(port, code) (ETH_REG_BASE(port) + 0x420 + ((code)<<2))
  65622. +#define ETH_PORT_SERIAL_CTRL_REG(port) (ETH_REG_BASE(port) + 0x43c)
  65623. +#define ETH_VLAN_TAG_TO_PRIO_REG(port) (ETH_REG_BASE(port) + 0x440)
  65624. +#define ETH_PORT_STATUS_REG(port) (ETH_REG_BASE(port) + 0x444)
  65625. +
  65626. +#define ETH_RX_QUEUE_COMMAND_REG(port) (ETH_REG_BASE(port) + 0x680)
  65627. +#define ETH_TX_QUEUE_COMMAND_REG(port) (ETH_REG_BASE(port) + 0x448)
  65628. +
  65629. +#define ETH_PORT_SERIAL_CTRL_1_REG(port) (ETH_REG_BASE(port) + 0x44c)
  65630. +#define ETH_PORT_STATUS_1_REG(port) (ETH_REG_BASE(port) + 0x450)
  65631. +#define ETH_PORT_MARVELL_HEADER_REG(port) (ETH_REG_BASE(port) + 0x454)
  65632. +#define ETH_PORT_FIFO_PARAMS_REG(port) (ETH_REG_BASE(port) + 0x458)
  65633. +#define ETH_MAX_TOKEN_BUCKET_SIZE_REG(port) (ETH_REG_BASE(port) + 0x45c)
  65634. +#define ETH_INTR_CAUSE_REG(port) (ETH_REG_BASE(port) + 0x460)
  65635. +#define ETH_INTR_CAUSE_EXT_REG(port) (ETH_REG_BASE(port) + 0x464)
  65636. +#define ETH_INTR_MASK_REG(port) (ETH_REG_BASE(port) + 0x468)
  65637. +#define ETH_INTR_MASK_EXT_REG(port) (ETH_REG_BASE(port) + 0x46c)
  65638. +#define ETH_TX_FIFO_URGENT_THRESH_REG(port) (ETH_REG_BASE(port) + 0x474)
  65639. +#define ETH_RX_MINIMAL_FRAME_SIZE_REG(port) (ETH_REG_BASE(port) + 0x47c)
  65640. +#define ETH_RX_DISCARD_PKTS_CNTR_REG(port) (ETH_REG_BASE(port) + 0x484)
  65641. +#define ETH_RX_OVERRUN_PKTS_CNTR_REG(port) (ETH_REG_BASE(port) + 0x488)
  65642. +#define ETH_INTERNAL_ADDR_ERROR_REG(port) (ETH_REG_BASE(port) + 0x494)
  65643. +#define ETH_TX_FIXED_PRIO_CFG_REG(port) (ETH_REG_BASE(port) + 0x4dc)
  65644. +#define ETH_TX_TOKEN_RATE_CFG_REG(port) (ETH_REG_BASE(port) + 0x4e0)
  65645. +#define ETH_TX_QUEUE_COMMAND1_REG(port) (ETH_REG_BASE(port) + 0x4e4)
  65646. +#define ETH_MAX_TRANSMIT_UNIT_REG(port) (ETH_REG_BASE(port) + 0x4e8)
  65647. +#define ETH_TX_TOKEN_BUCKET_SIZE_REG(port) (ETH_REG_BASE(port) + 0x4ec)
  65648. +#define ETH_TX_TOKEN_BUCKET_COUNT_REG(port) (ETH_REG_BASE(port) + 0x780)
  65649. +#define ETH_RX_DESCR_STAT_CMD_REG(port, q) (ETH_REG_BASE(port) + 0x600 + ((q)<<4))
  65650. +#define ETH_RX_BYTE_COUNT_REG(port, q) (ETH_REG_BASE(port) + 0x604 + ((q)<<4))
  65651. +#define ETH_RX_BUF_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x608 + ((q)<<4))
  65652. +#define ETH_RX_CUR_DESC_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x60c + ((q)<<4))
  65653. +#define ETH_TX_CUR_DESC_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x6c0 + ((q)<<2))
  65654. +
  65655. +#define ETH_TXQ_TOKEN_COUNT_REG(port, q) (ETH_REG_BASE(port) + 0x700 + ((q)<<4))
  65656. +#define ETH_TXQ_TOKEN_CFG_REG(port, q) (ETH_REG_BASE(port) + 0x704 + ((q)<<4))
  65657. +#define ETH_TXQ_ARBITER_CFG_REG(port, q) (ETH_REG_BASE(port) + 0x708 + ((q)<<4))
  65658. +
  65659. +#if (MV_ETH_VERSION >= 4)
  65660. +#define ETH_TXQ_CMD_1_REG(port) (ETH_REG_BASE(port) + 0x4E4)
  65661. +#define ETH_EJP_TX_HI_IPG_REG(port) (ETH_REG_BASE(port) + 0x7A8)
  65662. +#define ETH_EJP_TX_LO_IPG_REG(port) (ETH_REG_BASE(port) + 0x7B8)
  65663. +#define ETH_EJP_HI_TKN_LO_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C0)
  65664. +#define ETH_EJP_HI_TKN_ASYNC_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C4)
  65665. +#define ETH_EJP_LO_TKN_ASYNC_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C8)
  65666. +#define ETH_EJP_TX_SPEED_REG(port) (ETH_REG_BASE(port) + 0x7D0)
  65667. +#endif /* MV_ETH_VERSION >= 4 */
  65668. +
  65669. +#define ETH_MIB_COUNTERS_BASE(port) (ETH_REG_BASE(port) + 0x1000)
  65670. +#define ETH_DA_FILTER_SPEC_MCAST_BASE(port) (ETH_REG_BASE(port) + 0x1400)
  65671. +#define ETH_DA_FILTER_OTH_MCAST_BASE(port) (ETH_REG_BASE(port) + 0x1500)
  65672. +#define ETH_DA_FILTER_UCAST_BASE(port) (ETH_REG_BASE(port) + 0x1600)
  65673. +
  65674. +/* Phy address register definitions */
  65675. +#define ETH_PHY_ADDR_OFFS 0
  65676. +#define ETH_PHY_ADDR_MASK (0x1f <<ETH_PHY_ADDR_OFFS)
  65677. +
  65678. +/* MIB Counters register definitions */
  65679. +#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW 0x0
  65680. +#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH 0x4
  65681. +#define ETH_MIB_BAD_OCTETS_RECEIVED 0x8
  65682. +#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR 0xc
  65683. +#define ETH_MIB_GOOD_FRAMES_RECEIVED 0x10
  65684. +#define ETH_MIB_BAD_FRAMES_RECEIVED 0x14
  65685. +#define ETH_MIB_BROADCAST_FRAMES_RECEIVED 0x18
  65686. +#define ETH_MIB_MULTICAST_FRAMES_RECEIVED 0x1c
  65687. +#define ETH_MIB_FRAMES_64_OCTETS 0x20
  65688. +#define ETH_MIB_FRAMES_65_TO_127_OCTETS 0x24
  65689. +#define ETH_MIB_FRAMES_128_TO_255_OCTETS 0x28
  65690. +#define ETH_MIB_FRAMES_256_TO_511_OCTETS 0x2c
  65691. +#define ETH_MIB_FRAMES_512_TO_1023_OCTETS 0x30
  65692. +#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS 0x34
  65693. +#define ETH_MIB_GOOD_OCTETS_SENT_LOW 0x38
  65694. +#define ETH_MIB_GOOD_OCTETS_SENT_HIGH 0x3c
  65695. +#define ETH_MIB_GOOD_FRAMES_SENT 0x40
  65696. +#define ETH_MIB_EXCESSIVE_COLLISION 0x44
  65697. +#define ETH_MIB_MULTICAST_FRAMES_SENT 0x48
  65698. +#define ETH_MIB_BROADCAST_FRAMES_SENT 0x4c
  65699. +#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED 0x50
  65700. +#define ETH_MIB_FC_SENT 0x54
  65701. +#define ETH_MIB_GOOD_FC_RECEIVED 0x58
  65702. +#define ETH_MIB_BAD_FC_RECEIVED 0x5c
  65703. +#define ETH_MIB_UNDERSIZE_RECEIVED 0x60
  65704. +#define ETH_MIB_FRAGMENTS_RECEIVED 0x64
  65705. +#define ETH_MIB_OVERSIZE_RECEIVED 0x68
  65706. +#define ETH_MIB_JABBER_RECEIVED 0x6c
  65707. +#define ETH_MIB_MAC_RECEIVE_ERROR 0x70
  65708. +#define ETH_MIB_BAD_CRC_EVENT 0x74
  65709. +#define ETH_MIB_COLLISION 0x78
  65710. +#define ETH_MIB_LATE_COLLISION 0x7c
  65711. +
  65712. +
  65713. +/****************************************/
  65714. +/* Ethernet Unit Register BITs */
  65715. +/****************************************/
  65716. +
  65717. +#define ETH_RXQ_ENABLE_OFFSET 0
  65718. +#define ETH_RXQ_ENABLE_MASK (0x000000FF << ETH_RXQ_ENABLE_OFFSET)
  65719. +
  65720. +#define ETH_RXQ_DISABLE_OFFSET 8
  65721. +#define ETH_RXQ_DISABLE_MASK (0x000000FF << ETH_RXQ_DISABLE_OFFSET)
  65722. +
  65723. +/***** BITs of Transmit Queue Command (TQC) register *****/
  65724. +#define ETH_TXQ_ENABLE_OFFSET 0
  65725. +#define ETH_TXQ_ENABLE_MASK (0x000000FF << ETH_TXQ_ENABLE_OFFSET)
  65726. +
  65727. +#define ETH_TXQ_DISABLE_OFFSET 8
  65728. +#define ETH_TXQ_DISABLE_MASK (0x000000FF << ETH_TXQ_DISABLE_OFFSET)
  65729. +
  65730. +#if (MV_ETH_VERSION >= 4)
  65731. +#define ETH_TX_EJP_RESET_BIT 0
  65732. +#define ETH_TX_EJP_RESET_MASK (1 << ETH_TX_EJP_RESET_BIT)
  65733. +
  65734. +#define ETH_TX_EJP_ENABLE_BIT 2
  65735. +#define ETH_TX_EJP_ENABLE_MASK (1 << ETH_TX_EJP_ENABLE_BIT)
  65736. +
  65737. +#define ETH_TX_LEGACY_WRR_BIT 3
  65738. +#define ETH_TX_LEGACY_WRR_MASK (1 << ETH_TX_LEGACY_WRR_BIT)
  65739. +#endif /* (MV_ETH_VERSION >= 4) */
  65740. +
  65741. +/***** BITs of Ethernet Port Status reg (PSR) *****/
  65742. +#define ETH_LINK_UP_BIT 1
  65743. +#define ETH_LINK_UP_MASK (1<<ETH_LINK_UP_BIT)
  65744. +
  65745. +#define ETH_FULL_DUPLEX_BIT 2
  65746. +#define ETH_FULL_DUPLEX_MASK (1<<ETH_FULL_DUPLEX_BIT)
  65747. +
  65748. +#define ETH_ENABLE_RCV_FLOW_CTRL_BIT 3
  65749. +#define ETH_ENABLE_RCV_FLOW_CTRL_MASK (1<<ETH_ENABLE_RCV_FLOW_CTRL_BIT)
  65750. +
  65751. +#define ETH_GMII_SPEED_1000_BIT 4
  65752. +#define ETH_GMII_SPEED_1000_MASK (1<<ETH_GMII_SPEED_1000_BIT)
  65753. +
  65754. +#define ETH_MII_SPEED_100_BIT 5
  65755. +#define ETH_MII_SPEED_100_MASK (1<<ETH_MII_SPEED_100_BIT)
  65756. +
  65757. +#define ETH_TX_IN_PROGRESS_BIT 7
  65758. +#define ETH_TX_IN_PROGRESS_MASK (1<<ETH_TX_IN_PROGRESS_BIT)
  65759. +
  65760. +#define ETH_TX_FIFO_EMPTY_BIT 10
  65761. +#define ETH_TX_FIFO_EMPTY_MASK (1<<ETH_TX_FIFO_EMPTY_BIT)
  65762. +
  65763. +/***** BITs of Ethernet Port Status 1 reg (PS1R) *****/
  65764. +#define ETH_AUTO_NEG_DONE_BIT 4
  65765. +#define ETH_AUTO_NEG_DONE_MASK (1<<ETH_AUTO_NEG_DONE_BIT)
  65766. +
  65767. +#define ETH_SERDES_PLL_LOCKED_BIT 6
  65768. +#define ETH_SERDES_PLL_LOCKED_MASK (1<<ETH_SERDES_PLL_LOCKED_BIT)
  65769. +
  65770. +/***** BITs of Port Configuration reg (PxCR) *****/
  65771. +#define ETH_UNICAST_PROMISCUOUS_MODE_BIT 0
  65772. +#define ETH_UNICAST_PROMISCUOUS_MODE_MASK (1<<ETH_UNICAST_PROMISCUOUS_MODE_BIT)
  65773. +
  65774. +#define ETH_DEF_RX_QUEUE_OFFSET 1
  65775. +#define ETH_DEF_RX_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_QUEUE_OFFSET)
  65776. +#define ETH_DEF_RX_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_QUEUE_OFFSET)
  65777. +
  65778. +#define ETH_DEF_RX_ARP_QUEUE_OFFSET 4
  65779. +#define ETH_DEF_RX_ARP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_ARP_QUEUE_OFFSET)
  65780. +#define ETH_DEF_RX_ARP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_ARP_QUEUE_OFFSET)
  65781. +
  65782. +#define ETH_REJECT_NOT_IP_ARP_BCAST_BIT 7
  65783. +#define ETH_REJECT_NOT_IP_ARP_BCAST_MASK (1<<ETH_REJECT_NOT_IP_ARP_BCAST_BIT)
  65784. +
  65785. +#define ETH_REJECT_IP_BCAST_BIT 8
  65786. +#define ETH_REJECT_IP_BCAST_MASK (1<<ETH_REJECT_IP_BCAST_BIT)
  65787. +
  65788. +#define ETH_REJECT_ARP_BCAST_BIT 9
  65789. +#define ETH_REJECT_ARP_BCAST_MASK (1<<ETH_REJECT_ARP_BCAST_BIT)
  65790. +
  65791. +#define ETH_TX_NO_SET_ERROR_SUMMARY_BIT 12
  65792. +#define ETH_TX_NO_SET_ERROR_SUMMARY_MASK (1<<ETH_TX_NO_SET_ERROR_SUMMARY_BIT)
  65793. +
  65794. +#define ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT 14
  65795. +#define ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK (1<<ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT)
  65796. +
  65797. +#define ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT 15
  65798. +#define ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK (1<<ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT)
  65799. +
  65800. +#define ETH_DEF_RX_TCP_QUEUE_OFFSET 16
  65801. +#define ETH_DEF_RX_TCP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_TCP_QUEUE_OFFSET)
  65802. +#define ETH_DEF_RX_TCP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_TCP_QUEUE_OFFSET)
  65803. +
  65804. +#define ETH_DEF_RX_UDP_QUEUE_OFFSET 19
  65805. +#define ETH_DEF_RX_UDP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_UDP_QUEUE_OFFSET)
  65806. +#define ETH_DEF_RX_UDP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_UDP_QUEUE_OFFSET)
  65807. +
  65808. +#define ETH_DEF_RX_BPDU_QUEUE_OFFSET 22
  65809. +#define ETH_DEF_RX_BPDU_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)
  65810. +#define ETH_DEF_RX_BPDU_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)
  65811. +
  65812. +#define ETH_RX_CHECKSUM_MODE_OFFSET 25
  65813. +#define ETH_RX_CHECKSUM_NO_PSEUDO_HDR (0<<ETH_RX_CHECKSUM_MODE_OFFSET)
  65814. +#define ETH_RX_CHECKSUM_WITH_PSEUDO_HDR (1<<ETH_RX_CHECKSUM_MODE_OFFSET)
  65815. +
  65816. +/***** BITs of Port Configuration Extend reg (PxCXR) *****/
  65817. +#define ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT 1
  65818. +#define ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK (1<<ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT)
  65819. +
  65820. +#define ETH_TX_DISABLE_GEN_CRC_BIT 3
  65821. +#define ETH_TX_DISABLE_GEN_CRC_MASK (1<<ETH_TX_DISABLE_GEN_CRC_BIT)
  65822. +
  65823. +/***** BITs of Tx/Rx queue command reg (RQCR/TQCR) *****/
  65824. +#define ETH_QUEUE_ENABLE_OFFSET 0
  65825. +#define ETH_QUEUE_ENABLE_ALL_MASK (0xFF<<ETH_QUEUE_ENABLE_OFFSET)
  65826. +#define ETH_QUEUE_ENABLE_MASK(queue) (1<<((queue)+ETH_QUEUE_ENABLE_OFFSET))
  65827. +
  65828. +#define ETH_QUEUE_DISABLE_OFFSET 8
  65829. +#define ETH_QUEUE_DISABLE_ALL_MASK (0xFF<<ETH_QUEUE_DISABLE_OFFSET)
  65830. +#define ETH_QUEUE_DISABLE_MASK(queue) (1<<((queue)+ETH_QUEUE_DISABLE_OFFSET))
  65831. +
  65832. +
  65833. +/***** BITs of Port Sdma Configuration reg (SDCR) *****/
  65834. +#define ETH_RX_FRAME_INTERRUPT_BIT 0
  65835. +#define ETH_RX_FRAME_INTERRUPT_MASK (1<<ETH_RX_FRAME_INTERRUPT_BIT)
  65836. +
  65837. +#define ETH_BURST_SIZE_1_64BIT_VALUE 0
  65838. +#define ETH_BURST_SIZE_2_64BIT_VALUE 1
  65839. +#define ETH_BURST_SIZE_4_64BIT_VALUE 2
  65840. +#define ETH_BURST_SIZE_8_64BIT_VALUE 3
  65841. +#define ETH_BURST_SIZE_16_64BIT_VALUE 4
  65842. +
  65843. +#define ETH_RX_BURST_SIZE_OFFSET 1
  65844. +#define ETH_RX_BURST_SIZE_ALL_MASK (0x7<<ETH_RX_BURST_SIZE_OFFSET)
  65845. +#define ETH_RX_BURST_SIZE_MASK(burst) ((burst)<<ETH_RX_BURST_SIZE_OFFSET)
  65846. +
  65847. +#define ETH_RX_NO_DATA_SWAP_BIT 4
  65848. +#define ETH_RX_NO_DATA_SWAP_MASK (1<<ETH_RX_NO_DATA_SWAP_BIT)
  65849. +#define ETH_RX_DATA_SWAP_MASK (0<<ETH_RX_NO_DATA_SWAP_BIT)
  65850. +
  65851. +#define ETH_TX_NO_DATA_SWAP_BIT 5
  65852. +#define ETH_TX_NO_DATA_SWAP_MASK (1<<ETH_TX_NO_DATA_SWAP_BIT)
  65853. +#define ETH_TX_DATA_SWAP_MASK (0<<ETH_TX_NO_DATA_SWAP_BIT)
  65854. +
  65855. +#define ETH_DESC_SWAP_BIT 6
  65856. +#define ETH_DESC_SWAP_MASK (1<<ETH_DESC_SWAP_BIT)
  65857. +#define ETH_NO_DESC_SWAP_MASK (0<<ETH_DESC_SWAP_BIT)
  65858. +
  65859. +#define ETH_RX_INTR_COAL_OFFSET 7
  65860. +#define ETH_RX_INTR_COAL_ALL_MASK (0x3fff<<ETH_RX_INTR_COAL_OFFSET)
  65861. +#define ETH_RX_INTR_COAL_MASK(value) (((value)<<ETH_RX_INTR_COAL_OFFSET) \
  65862. + & ETH_RX_INTR_COAL_ALL_MASK)
  65863. +
  65864. +#define ETH_TX_BURST_SIZE_OFFSET 22
  65865. +#define ETH_TX_BURST_SIZE_ALL_MASK (0x7<<ETH_TX_BURST_SIZE_OFFSET)
  65866. +#define ETH_TX_BURST_SIZE_MASK(burst) ((burst)<<ETH_TX_BURST_SIZE_OFFSET)
  65867. +
  65868. +#define ETH_RX_INTR_COAL_MSB_BIT 25
  65869. +#define ETH_RX_INTR_COAL_MSB_MASK (1<<ETH_RX_INTR_COAL_MSB_BIT)
  65870. +
  65871. +/* BITs Port #x Tx FIFO Urgent Threshold (PxTFUT) */
  65872. +#define ETH_TX_INTR_COAL_OFFSET 4
  65873. +#define ETH_TX_INTR_COAL_ALL_MASK (0x3fff << ETH_TX_INTR_COAL_OFFSET)
  65874. +#define ETH_TX_INTR_COAL_MASK(value) (((value) << ETH_TX_INTR_COAL_OFFSET) \
  65875. + & ETH_TX_INTR_COAL_ALL_MASK)
  65876. +
  65877. +/* BITs of Port Serial Control reg (PSCR) */
  65878. +#define ETH_PORT_ENABLE_BIT 0
  65879. +#define ETH_PORT_ENABLE_MASK (1<<ETH_PORT_ENABLE_BIT)
  65880. +
  65881. +#define ETH_FORCE_LINK_PASS_BIT 1
  65882. +#define ETH_FORCE_LINK_PASS_MASK (1<<ETH_FORCE_LINK_PASS_BIT)
  65883. +
  65884. +#define ETH_DISABLE_DUPLEX_AUTO_NEG_BIT 2
  65885. +#define ETH_DISABLE_DUPLEX_AUTO_NEG_MASK (1<<ETH_DISABLE_DUPLEX_AUTO_NEG_BIT)
  65886. +
  65887. +#define ETH_DISABLE_FC_AUTO_NEG_BIT 3
  65888. +#define ETH_DISABLE_FC_AUTO_NEG_MASK (1<<ETH_DISABLE_FC_AUTO_NEG_BIT)
  65889. +
  65890. +#define ETH_ADVERTISE_SYM_FC_BIT 4
  65891. +#define ETH_ADVERTISE_SYM_FC_MASK (1<<ETH_ADVERTISE_SYM_FC_BIT)
  65892. +
  65893. +#define ETH_TX_FC_MODE_OFFSET 5
  65894. +#define ETH_TX_FC_MODE_MASK (3<<ETH_TX_FC_MODE_OFFSET)
  65895. +#define ETH_TX_FC_NO_PAUSE (0<<ETH_TX_FC_MODE_OFFSET)
  65896. +#define ETH_TX_FC_SEND_PAUSE (1<<ETH_TX_FC_MODE_OFFSET)
  65897. +
  65898. +#define ETH_TX_BP_MODE_OFFSET 7
  65899. +#define ETH_TX_BP_MODE_MASK (3<<ETH_TX_BP_MODE_OFFSET)
  65900. +#define ETH_TX_BP_NO_JAM (0<<ETH_TX_BP_MODE_OFFSET)
  65901. +#define ETH_TX_BP_SEND_JAM (1<<ETH_TX_BP_MODE_OFFSET)
  65902. +
  65903. +#define ETH_DO_NOT_FORCE_LINK_FAIL_BIT 10
  65904. +#define ETH_DO_NOT_FORCE_LINK_FAIL_MASK (1<<ETH_DO_NOT_FORCE_LINK_FAIL_BIT)
  65905. +
  65906. +#define ETH_RETRANSMIT_FOREVER_BIT 11
  65907. +#define ETH_RETRANSMIT_FOREVER_MASK (1<<ETH_RETRANSMIT_FOREVER_BIT)
  65908. +
  65909. +#define ETH_DISABLE_SPEED_AUTO_NEG_BIT 13
  65910. +#define ETH_DISABLE_SPEED_AUTO_NEG_MASK (1<<ETH_DISABLE_SPEED_AUTO_NEG_BIT)
  65911. +
  65912. +#define ETH_DTE_ADVERT_BIT 14
  65913. +#define ETH_DTE_ADVERT_MASK (1<<ETH_DTE_ADVERT_BIT)
  65914. +
  65915. +#define ETH_MII_PHY_MODE_BIT 15
  65916. +#define ETH_MII_PHY_MODE_MAC (0<<ETH_MII_PHY_MODE_BIT)
  65917. +#define ETH_MII_PHY_MODE_PHY (1<<ETH_MII_PHY_MODE_BIT)
  65918. +
  65919. +#define ETH_MII_SOURCE_SYNCH_BIT 16
  65920. +#define ETH_MII_STANDARD_SYNCH (0<<ETH_MII_SOURCE_SYNCH_BIT)
  65921. +#define ETH_MII_400Mbps_SYNCH (1<<ETH_MII_SOURCE_CLK_BIT)
  65922. +
  65923. +#define ETH_MAX_RX_PACKET_SIZE_OFFSET 17
  65924. +#define ETH_MAX_RX_PACKET_SIZE_MASK (7<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65925. +#define ETH_MAX_RX_PACKET_1518BYTE (0<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65926. +#define ETH_MAX_RX_PACKET_1522BYTE (1<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65927. +#define ETH_MAX_RX_PACKET_1552BYTE (2<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65928. +#define ETH_MAX_RX_PACKET_9022BYTE (3<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65929. +#define ETH_MAX_RX_PACKET_9192BYTE (4<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65930. +#define ETH_MAX_RX_PACKET_9700BYTE (5<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65931. +
  65932. +#define ETH_SET_FULL_DUPLEX_BIT 21
  65933. +#define ETH_SET_FULL_DUPLEX_MASK (1<<ETH_SET_FULL_DUPLEX_BIT)
  65934. +
  65935. +#define ETH_SET_FLOW_CTRL_BIT 22
  65936. +#define ETH_SET_FLOW_CTRL_MASK (1<<ETH_SET_FLOW_CTRL_BIT)
  65937. +
  65938. +#define ETH_SET_GMII_SPEED_1000_BIT 23
  65939. +#define ETH_SET_GMII_SPEED_1000_MASK (1<<ETH_SET_GMII_SPEED_1000_BIT)
  65940. +
  65941. +#define ETH_SET_MII_SPEED_100_BIT 24
  65942. +#define ETH_SET_MII_SPEED_100_MASK (1<<ETH_SET_MII_SPEED_100_BIT)
  65943. +
  65944. +/* BITs of Port Serial Control 1 reg (PSC1R) */
  65945. +#define ETH_PSC_ENABLE_BIT 2
  65946. +#define ETH_PSC_ENABLE_MASK (1<<ETH_PSC_ENABLE_BIT)
  65947. +
  65948. +#define ETH_RGMII_ENABLE_BIT 3
  65949. +#define ETH_RGMII_ENABLE_MASK (1<<ETH_RGMII_ENABLE_BIT)
  65950. +
  65951. +#define ETH_PORT_RESET_BIT 4
  65952. +#define ETH_PORT_RESET_MASK (1<<ETH_PORT_RESET_BIT)
  65953. +
  65954. +#define ETH_INBAND_AUTO_NEG_ENABLE_BIT 6
  65955. +#define ETH_INBAND_AUTO_NEG_ENABLE_MASK (1<<ETH_INBAND_AUTO_NEG_ENABLE_BIT)
  65956. +
  65957. +#define ETH_INBAND_AUTO_NEG_BYPASS_BIT 7
  65958. +#define ETH_INBAND_AUTO_NEG_BYPASS_MASK (1<<ETH_INBAND_AUTO_NEG_BYPASS_BIT)
  65959. +
  65960. +#define ETH_INBAND_AUTO_NEG_START_BIT 8
  65961. +#define ETH_INBAND_AUTO_NEG_START_MASK (1<<ETH_INBAND_AUTO_NEG_START_BIT)
  65962. +
  65963. +#define ETH_PORT_TYPE_BIT 11
  65964. +#define ETH_PORT_TYPE_1000BasedX_MASK (1<<ETH_PORT_TYPE_BIT)
  65965. +
  65966. +#define ETH_SGMII_MODE_BIT 12
  65967. +#define ETH_1000BaseX_MODE_MASK (0<<ETH_SGMII_MODE_BIT)
  65968. +#define ETH_SGMII_MODE_MASK (1<<ETH_SGMII_MODE_BIT)
  65969. +
  65970. +#define ETH_MGMII_MODE_BIT 13
  65971. +
  65972. +#define ETH_EN_MII_ODD_PRE_BIT 22
  65973. +#define ETH_EN_MII_ODD_PRE_MASK (1<<ETH_EN_MII_ODD_PRE_BIT)
  65974. +
  65975. +/* BITs of SDMA Descriptor Command/Status field */
  65976. +#if defined(MV_CPU_BE)
  65977. +typedef struct _ethRxDesc
  65978. +{
  65979. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  65980. + MV_U16 bufSize ; /* Buffer size */
  65981. + MV_U32 cmdSts ; /* Descriptor command status */
  65982. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  65983. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  65984. + MV_ULONG returnInfo ; /* User resource return information */
  65985. +} ETH_RX_DESC;
  65986. +
  65987. +typedef struct _ethTxDesc
  65988. +{
  65989. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  65990. + MV_U16 L4iChk ; /* CPU provided TCP Checksum */
  65991. + MV_U32 cmdSts ; /* Descriptor command status */
  65992. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  65993. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  65994. + MV_ULONG returnInfo ; /* User resource return information */
  65995. + MV_U8* alignBufPtr; /* Pointer to 8 byte aligned buffer */
  65996. +} ETH_TX_DESC;
  65997. +
  65998. +#elif defined(MV_CPU_LE)
  65999. +
  66000. +typedef struct _ethRxDesc
  66001. +{
  66002. + MV_U32 cmdSts ; /* Descriptor command status */
  66003. + MV_U16 bufSize ; /* Buffer size */
  66004. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  66005. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  66006. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  66007. + MV_ULONG returnInfo ; /* User resource return information */
  66008. +} ETH_RX_DESC;
  66009. +
  66010. +typedef struct _ethTxDesc
  66011. +{
  66012. + MV_U32 cmdSts ; /* Descriptor command status */
  66013. + MV_U16 L4iChk ; /* CPU provided TCP Checksum */
  66014. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  66015. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  66016. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  66017. + MV_ULONG returnInfo ; /* User resource return information */
  66018. + MV_U8* alignBufPtr; /* Pointer to 32 byte aligned buffer */
  66019. +} ETH_TX_DESC;
  66020. +
  66021. +#else
  66022. +#error "MV_CPU_BE or MV_CPU_LE must be defined"
  66023. +#endif /* MV_CPU_BE || MV_CPU_LE */
  66024. +
  66025. +/* Buffer offset from buffer pointer */
  66026. +#define ETH_RX_BUF_OFFSET 0x2
  66027. +
  66028. +
  66029. +/* Tx & Rx descriptor bits */
  66030. +#define ETH_ERROR_SUMMARY_BIT 0
  66031. +#define ETH_ERROR_SUMMARY_MASK (1<<ETH_ERROR_SUMMARY_BIT)
  66032. +
  66033. +#define ETH_BUFFER_OWNER_BIT 31
  66034. +#define ETH_BUFFER_OWNED_BY_DMA (1<<ETH_BUFFER_OWNER_BIT)
  66035. +#define ETH_BUFFER_OWNED_BY_HOST (0<<ETH_BUFFER_OWNER_BIT)
  66036. +
  66037. +/* Tx descriptor bits */
  66038. +#define ETH_TX_ERROR_CODE_OFFSET 1
  66039. +#define ETH_TX_ERROR_CODE_MASK (3<<ETH_TX_ERROR_CODE_OFFSET)
  66040. +#define ETH_TX_LATE_COLLISION_ERROR (0<<ETH_TX_ERROR_CODE_OFFSET)
  66041. +#define ETH_TX_UNDERRUN_ERROR (1<<ETH_TX_ERROR_CODE_OFFSET)
  66042. +#define ETH_TX_EXCESSIVE_COLLISION_ERROR (2<<ETH_TX_ERROR_CODE_OFFSET)
  66043. +
  66044. +#define ETH_TX_LLC_SNAP_FORMAT_BIT 9
  66045. +#define ETH_TX_LLC_SNAP_FORMAT_MASK (1<<ETH_TX_LLC_SNAP_FORMAT_BIT)
  66046. +
  66047. +#define ETH_TX_IP_FRAG_BIT 10
  66048. +#define ETH_TX_IP_FRAG_MASK (1<<ETH_TX_IP_FRAG_BIT)
  66049. +#define ETH_TX_IP_FRAG (0<<ETH_TX_IP_FRAG_BIT)
  66050. +#define ETH_TX_IP_NO_FRAG (1<<ETH_TX_IP_FRAG_BIT)
  66051. +
  66052. +#define ETH_TX_IP_HEADER_LEN_OFFSET 11
  66053. +#define ETH_TX_IP_HEADER_LEN_ALL_MASK (0xF<<ETH_TX_IP_HEADER_LEN_OFFSET)
  66054. +#define ETH_TX_IP_HEADER_LEN_MASK(len) ((len)<<ETH_TX_IP_HEADER_LEN_OFFSET)
  66055. +
  66056. +#define ETH_TX_VLAN_TAGGED_FRAME_BIT 15
  66057. +#define ETH_TX_VLAN_TAGGED_FRAME_MASK (1<<ETH_TX_VLAN_TAGGED_FRAME_BIT)
  66058. +
  66059. +#define ETH_TX_L4_TYPE_BIT 16
  66060. +#define ETH_TX_L4_TCP_TYPE (0<<ETH_TX_L4_TYPE_BIT)
  66061. +#define ETH_TX_L4_UDP_TYPE (1<<ETH_TX_L4_TYPE_BIT)
  66062. +
  66063. +#define ETH_TX_GENERATE_L4_CHKSUM_BIT 17
  66064. +#define ETH_TX_GENERATE_L4_CHKSUM_MASK (1<<ETH_TX_GENERATE_L4_CHKSUM_BIT)
  66065. +
  66066. +#define ETH_TX_GENERATE_IP_CHKSUM_BIT 18
  66067. +#define ETH_TX_GENERATE_IP_CHKSUM_MASK (1<<ETH_TX_GENERATE_IP_CHKSUM_BIT)
  66068. +
  66069. +#define ETH_TX_ZERO_PADDING_BIT 19
  66070. +#define ETH_TX_ZERO_PADDING_MASK (1<<ETH_TX_ZERO_PADDING_BIT)
  66071. +
  66072. +#define ETH_TX_LAST_DESC_BIT 20
  66073. +#define ETH_TX_LAST_DESC_MASK (1<<ETH_TX_LAST_DESC_BIT)
  66074. +
  66075. +#define ETH_TX_FIRST_DESC_BIT 21
  66076. +#define ETH_TX_FIRST_DESC_MASK (1<<ETH_TX_FIRST_DESC_BIT)
  66077. +
  66078. +#define ETH_TX_GENERATE_CRC_BIT 22
  66079. +#define ETH_TX_GENERATE_CRC_MASK (1<<ETH_TX_GENERATE_CRC_BIT)
  66080. +
  66081. +#define ETH_TX_ENABLE_INTERRUPT_BIT 23
  66082. +#define ETH_TX_ENABLE_INTERRUPT_MASK (1<<ETH_TX_ENABLE_INTERRUPT_BIT)
  66083. +
  66084. +#define ETH_TX_AUTO_MODE_BIT 30
  66085. +#define ETH_TX_AUTO_MODE_MASK (1<<ETH_TX_AUTO_MODE_BIT)
  66086. +
  66087. +
  66088. +/* Rx descriptor bits */
  66089. +#define ETH_RX_ERROR_CODE_OFFSET 1
  66090. +#define ETH_RX_ERROR_CODE_MASK (3<<ETH_RX_ERROR_CODE_OFFSET)
  66091. +#define ETH_RX_CRC_ERROR (0<<ETH_RX_ERROR_CODE_OFFSET)
  66092. +#define ETH_RX_OVERRUN_ERROR (1<<ETH_RX_ERROR_CODE_OFFSET)
  66093. +#define ETH_RX_MAX_FRAME_LEN_ERROR (2<<ETH_RX_ERROR_CODE_OFFSET)
  66094. +#define ETH_RX_RESOURCE_ERROR (3<<ETH_RX_ERROR_CODE_OFFSET)
  66095. +
  66096. +#define ETH_RX_L4_CHECKSUM_OFFSET 3
  66097. +#define ETH_RX_L4_CHECKSUM_MASK (0xffff<<ETH_RX_L4_CHECKSUM_OFFSET)
  66098. +
  66099. +#define ETH_RX_VLAN_TAGGED_FRAME_BIT 19
  66100. +#define ETH_RX_VLAN_TAGGED_FRAME_MASK (1<<ETH_RX_VLAN_TAGGED_FRAME_BIT)
  66101. +
  66102. +#define ETH_RX_BPDU_FRAME_BIT 20
  66103. +#define ETH_RX_BPDU_FRAME_MASK (1<<ETH_RX_BPDU_FRAME_BIT)
  66104. +
  66105. +#define ETH_RX_L4_TYPE_OFFSET 21
  66106. +#define ETH_RX_L4_TYPE_MASK (3<<ETH_RX_L4_TYPE_OFFSET)
  66107. +#define ETH_RX_L4_TCP_TYPE (0<<ETH_RX_L4_TYPE_OFFSET)
  66108. +#define ETH_RX_L4_UDP_TYPE (1<<ETH_RX_L4_TYPE_OFFSET)
  66109. +#define ETH_RX_L4_OTHER_TYPE (2<<ETH_RX_L4_TYPE_OFFSET)
  66110. +
  66111. +#define ETH_RX_NOT_LLC_SNAP_FORMAT_BIT 23
  66112. +#define ETH_RX_NOT_LLC_SNAP_FORMAT_MASK (1<<ETH_RX_NOT_LLC_SNAP_FORMAT_BIT)
  66113. +
  66114. +#define ETH_RX_IP_FRAME_TYPE_BIT 24
  66115. +#define ETH_RX_IP_FRAME_TYPE_MASK (1<<ETH_RX_IP_FRAME_TYPE_BIT)
  66116. +
  66117. +#define ETH_RX_IP_HEADER_OK_BIT 25
  66118. +#define ETH_RX_IP_HEADER_OK_MASK (1<<ETH_RX_IP_HEADER_OK_BIT)
  66119. +
  66120. +#define ETH_RX_LAST_DESC_BIT 26
  66121. +#define ETH_RX_LAST_DESC_MASK (1<<ETH_RX_LAST_DESC_BIT)
  66122. +
  66123. +#define ETH_RX_FIRST_DESC_BIT 27
  66124. +#define ETH_RX_FIRST_DESC_MASK (1<<ETH_RX_FIRST_DESC_BIT)
  66125. +
  66126. +#define ETH_RX_UNKNOWN_DA_BIT 28
  66127. +#define ETH_RX_UNKNOWN_DA_MASK (1<<ETH_RX_UNKNOWN_DA_BIT)
  66128. +
  66129. +#define ETH_RX_ENABLE_INTERRUPT_BIT 29
  66130. +#define ETH_RX_ENABLE_INTERRUPT_MASK (1<<ETH_RX_ENABLE_INTERRUPT_BIT)
  66131. +
  66132. +#define ETH_RX_L4_CHECKSUM_OK_BIT 30
  66133. +#define ETH_RX_L4_CHECKSUM_OK_MASK (1<<ETH_RX_L4_CHECKSUM_OK_BIT)
  66134. +
  66135. +/* Rx descriptor bufSize field */
  66136. +#define ETH_RX_IP_FRAGMENTED_FRAME_BIT 2
  66137. +#define ETH_RX_IP_FRAGMENTED_FRAME_MASK (1<<ETH_RX_IP_FRAGMENTED_FRAME_BIT)
  66138. +
  66139. +#define ETH_RX_BUFFER_MASK 0xFFF8
  66140. +
  66141. +
  66142. +/* Ethernet Cause Register BITs */
  66143. +#define ETH_CAUSE_RX_READY_SUM_BIT 0
  66144. +#define ETH_CAUSE_EXTEND_BIT 1
  66145. +
  66146. +#define ETH_CAUSE_RX_READY_OFFSET 2
  66147. +#define ETH_CAUSE_RX_READY_BIT(queue) (ETH_CAUSE_RX_READY_OFFSET + (queue))
  66148. +#define ETH_CAUSE_RX_READY_MASK(queue) (1 << (ETH_CAUSE_RX_READY_BIT(queue)))
  66149. +
  66150. +#define ETH_CAUSE_RX_ERROR_SUM_BIT 10
  66151. +#define ETH_CAUSE_RX_ERROR_OFFSET 11
  66152. +#define ETH_CAUSE_RX_ERROR_BIT(queue) (ETH_CAUSE_RX_ERROR_OFFSET + (queue))
  66153. +#define ETH_CAUSE_RX_ERROR_MASK(queue) (1 << (ETH_CAUSE_RX_ERROR_BIT(queue)))
  66154. +
  66155. +#define ETH_CAUSE_TX_END_BIT 19
  66156. +#define ETH_CAUSE_SUM_BIT 31
  66157. +
  66158. +/* Ethernet Cause Extended Register BITs */
  66159. +#define ETH_CAUSE_TX_BUF_OFFSET 0
  66160. +#define ETH_CAUSE_TX_BUF_BIT(queue) (ETH_CAUSE_TX_BUF_OFFSET + (queue))
  66161. +#define ETH_CAUSE_TX_BUF_MASK(queue) (1 << (ETH_CAUSE_TX_BUF_BIT(queue)))
  66162. +
  66163. +#define ETH_CAUSE_TX_ERROR_OFFSET 8
  66164. +#define ETH_CAUSE_TX_ERROR_BIT(queue) (ETH_CAUSE_TX_ERROR_OFFSET + (queue))
  66165. +#define ETH_CAUSE_TX_ERROR_MASK(queue) (1 << (ETH_CAUSE_TX_ERROR_BIT(queue)))
  66166. +
  66167. +#define ETH_CAUSE_PHY_STATUS_CHANGE_BIT 16
  66168. +#define ETH_CAUSE_RX_OVERRUN_BIT 18
  66169. +#define ETH_CAUSE_TX_UNDERRUN_BIT 19
  66170. +#define ETH_CAUSE_LINK_STATE_CHANGE_BIT 20
  66171. +#define ETH_CAUSE_INTERNAL_ADDR_ERR_BIT 23
  66172. +#define ETH_CAUSE_EXTEND_SUM_BIT 31
  66173. +
  66174. +/* Marvell Header Register */
  66175. +/* Marvell Header register bits */
  66176. +#define ETH_MVHDR_EN_BIT 0
  66177. +#define ETH_MVHDR_EN_MASK (1 << ETH_MVHDR_EN_BIT)
  66178. +
  66179. +#define ETH_MVHDR_DAPREFIX_BIT 1
  66180. +#define ETH_MVHDR_DAPREFIX_MASK (0x3 << ETH_MVHDR_DAPREFIX_BIT)
  66181. +#define ETH_MVHDR_DAPREFIX_PRI_1_2 (0x1 << ETH_MVHDR_DAPREFIX_BIT)
  66182. +#define ETH_MVHDR_DAPREFIX_DBNUM_PRI (0x2 << ETH_MVHDR_DAPREFIX_BIT)
  66183. +#define ETH_MVHDR_DAPREFIX_SPID_PRI (0x3 << ETH_MVHDR_DAPREFIX_BIT)
  66184. +
  66185. +#define ETH_MVHDR_MHMASK_BIT 8
  66186. +#define ETH_MVHDR_MHMASK_MASK (0x3 << ETH_MVHDR_MHMASK_BIT)
  66187. +#define ETH_MVHDR_MHMASK_8_QUEUE (0x0 << ETH_MVHDR_MHMASK_BIT)
  66188. +#define ETH_MVHDR_MHMASK_4_QUEUE (0x1 << ETH_MVHDR_MHMASK_BIT)
  66189. +#define ETH_MVHDR_MHMASK_2_QUEUE (0x3 << ETH_MVHDR_MHMASK_BIT)
  66190. +
  66191. +
  66192. +/* Relevant for 6183 ONLY */
  66193. +#define ETH_UNIT_PORTS_PADS_CALIB_0_REG (MV_ETH_REG_BASE(0) + 0x0A0)
  66194. +#define ETH_UNIT_PORTS_PADS_CALIB_1_REG (MV_ETH_REG_BASE(0) + 0x0A4)
  66195. +#define ETH_UNIT_PORTS_PADS_CALIB_2_REG (MV_ETH_REG_BASE(0) + 0x0A8)
  66196. +/* Ethernet Unit Ports Pads Calibration_REG (ETH_UNIT_PORTS_PADS_CALIB_x_REG) */
  66197. +#define ETH_ETHERNET_PAD_CLIB_DRVN_OFFS 0
  66198. +#define ETH_ETHERNET_PAD_CLIB_DRVN_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_DRVN_OFFS)
  66199. +
  66200. +#define ETH_ETHERNET_PAD_CLIB_DRVP_OFFS 5
  66201. +#define ETH_ETHERNET_PAD_CLIB_DRVP_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_DRVP_OFFS)
  66202. +
  66203. +#define ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS 16
  66204. +#define ETH_ETHERNET_PAD_CLIB_TUNEEN_MASK (0x1 << ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS)
  66205. +
  66206. +#define ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS 17
  66207. +#define ETH_ETHERNET_PAD_CLIB_LOCKN_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS)
  66208. +
  66209. +#define ETH_ETHERNET_PAD_CLIB_OFFST_OFFS 24
  66210. +#define ETH_ETHERNET_PAD_CLIB_OFFST_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_OFFST_OFFS)
  66211. +
  66212. +#define ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS 31
  66213. +#define ETH_ETHERNET_PAD_CLIB_WR_EN_MASK (0x1 << ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS)
  66214. +
  66215. +
  66216. +#ifdef __cplusplus
  66217. +}
  66218. +#endif /* __cplusplus */
  66219. +
  66220. +#endif /* __INCmvEthRegsh */
  66221. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h
  66222. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h 1970-01-01 01:00:00.000000000 +0100
  66223. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h 2010-11-09 20:28:11.222495438 +0100
  66224. @@ -0,0 +1,356 @@
  66225. +/*******************************************************************************
  66226. +Copyright (C) Marvell International Ltd. and its affiliates
  66227. +
  66228. +This software file (the "File") is owned and distributed by Marvell
  66229. +International Ltd. and/or its affiliates ("Marvell") under the following
  66230. +alternative licensing terms. Once you have made an election to distribute the
  66231. +File under one of the following license alternatives, please (i) delete this
  66232. +introductory statement regarding license alternatives, (ii) delete the two
  66233. +license alternatives that you have not elected to use and (iii) preserve the
  66234. +Marvell copyright notice above.
  66235. +
  66236. +********************************************************************************
  66237. +Marvell Commercial License Option
  66238. +
  66239. +If you received this File from Marvell and you have entered into a commercial
  66240. +license agreement (a "Commercial License") with Marvell, the File is licensed
  66241. +to you under the terms of the applicable Commercial License.
  66242. +
  66243. +********************************************************************************
  66244. +Marvell GPL License Option
  66245. +
  66246. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66247. +modify this File in accordance with the terms and conditions of the General
  66248. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  66249. +available along with the File in the license.txt file or by writing to the Free
  66250. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  66251. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  66252. +
  66253. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  66254. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  66255. +DISCLAIMED. The GPL License provides additional details about this warranty
  66256. +disclaimer.
  66257. +********************************************************************************
  66258. +Marvell BSD License Option
  66259. +
  66260. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66261. +modify this File under the following licensing terms.
  66262. +Redistribution and use in source and binary forms, with or without modification,
  66263. +are permitted provided that the following conditions are met:
  66264. +
  66265. + * Redistributions of source code must retain the above copyright notice,
  66266. + this list of conditions and the following disclaimer.
  66267. +
  66268. + * Redistributions in binary form must reproduce the above copyright
  66269. + notice, this list of conditions and the following disclaimer in the
  66270. + documentation and/or other materials provided with the distribution.
  66271. +
  66272. + * Neither the name of Marvell nor the names of its contributors may be
  66273. + used to endorse or promote products derived from this software without
  66274. + specific prior written permission.
  66275. +
  66276. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  66277. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  66278. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  66279. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  66280. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  66281. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  66282. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  66283. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  66284. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  66285. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  66286. +
  66287. +*******************************************************************************/
  66288. +
  66289. +/*******************************************************************************
  66290. +* mvEth.h - Header File for : Ethernet Controller
  66291. +*
  66292. +* DESCRIPTION:
  66293. +* This header file contains macros typedefs and function declaration for
  66294. +* Marvell Gigabit Ethernet Controllers.
  66295. +*
  66296. +* DEPENDENCIES:
  66297. +* None.
  66298. +*
  66299. +*******************************************************************************/
  66300. +
  66301. +#ifndef __mvEth_h__
  66302. +#define __mvEth_h__
  66303. +
  66304. +/* includes */
  66305. +#include "mvTypes.h"
  66306. +#include "mv802_3.h"
  66307. +#include "ctrlEnv/mvCtrlEnvLib.h"
  66308. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  66309. +#include "eth/gbe/mvEthRegs.h"
  66310. +#include "mvSysHwConfig.h"
  66311. +
  66312. +/* defines */
  66313. +
  66314. +#define MV_ETH_EXTRA_FRAGS_NUM 2
  66315. +
  66316. +
  66317. +typedef enum
  66318. +{
  66319. + MV_ETH_SPEED_AN,
  66320. + MV_ETH_SPEED_10,
  66321. + MV_ETH_SPEED_100,
  66322. + MV_ETH_SPEED_1000
  66323. +
  66324. +} MV_ETH_PORT_SPEED;
  66325. +
  66326. +typedef enum
  66327. +{
  66328. + MV_ETH_DUPLEX_AN,
  66329. + MV_ETH_DUPLEX_HALF,
  66330. + MV_ETH_DUPLEX_FULL
  66331. +
  66332. +} MV_ETH_PORT_DUPLEX;
  66333. +
  66334. +typedef enum
  66335. +{
  66336. + MV_ETH_FC_AN_ADV_DIS,
  66337. + MV_ETH_FC_AN_ADV_SYM,
  66338. + MV_ETH_FC_DISABLE,
  66339. + MV_ETH_FC_ENABLE
  66340. +
  66341. +} MV_ETH_PORT_FC;
  66342. +
  66343. +typedef enum
  66344. +{
  66345. + MV_ETH_PRIO_FIXED = 0, /* Fixed priority mode */
  66346. + MV_ETH_PRIO_WRR = 1 /* Weighted round robin priority mode */
  66347. +} MV_ETH_PRIO_MODE;
  66348. +
  66349. +/* Ethernet port specific infomation */
  66350. +typedef struct
  66351. +{
  66352. + int maxRxPktSize;
  66353. + int rxDefQ;
  66354. + int rxBpduQ;
  66355. + int rxArpQ;
  66356. + int rxTcpQ;
  66357. + int rxUdpQ;
  66358. + int ejpMode;
  66359. +} MV_ETH_PORT_CFG;
  66360. +
  66361. +typedef struct
  66362. +{
  66363. + int descrNum;
  66364. +} MV_ETH_RX_Q_CFG;
  66365. +
  66366. +typedef struct
  66367. +{
  66368. + int descrNum;
  66369. + MV_ETH_PRIO_MODE prioMode;
  66370. + int quota;
  66371. +} MV_ETH_TX_Q_CFG;
  66372. +
  66373. +typedef struct
  66374. +{
  66375. + int maxRxPktSize;
  66376. + int rxDefQ;
  66377. + int txDescrNum[MV_ETH_TX_Q_NUM];
  66378. + int rxDescrNum[MV_ETH_RX_Q_NUM];
  66379. + void *osHandle;
  66380. +} MV_ETH_PORT_INIT;
  66381. +
  66382. +typedef struct
  66383. +{
  66384. + MV_BOOL isLinkUp;
  66385. + MV_ETH_PORT_SPEED speed;
  66386. + MV_ETH_PORT_DUPLEX duplex;
  66387. + MV_ETH_PORT_FC flowControl;
  66388. +
  66389. +} MV_ETH_PORT_STATUS;
  66390. +
  66391. +typedef enum
  66392. +{
  66393. + MV_ETH_DISABLE_HEADER_MODE = 0,
  66394. + MV_ETH_ENABLE_HEADER_MODE_PRI_2_1 = 1,
  66395. + MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM = 2,
  66396. + MV_ETH_ENABLE_HEADER_MODE_PRI_SPID = 3
  66397. +} MV_ETH_HEADER_MODE;
  66398. +
  66399. +
  66400. +/* ethernet.h API list */
  66401. +void mvEthHalInit(void);
  66402. +void mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher);
  66403. +
  66404. +/* Port Initalization routines */
  66405. +void* mvEthPortInit (int port, MV_ETH_PORT_INIT *pPortInit);
  66406. +void ethResetTxDescRing(void* pPortHndl, int queue);
  66407. +void ethResetRxDescRing(void* pPortHndl, int queue);
  66408. +
  66409. +void* mvEthPortHndlGet(int port);
  66410. +
  66411. +void mvEthPortFinish(void* pEthPortHndl);
  66412. +MV_STATUS mvEthPortDown(void* pEthPortHndl);
  66413. +MV_STATUS mvEthPortDisable(void* pEthPortHndl);
  66414. +MV_STATUS mvEthPortUp(void* pEthPortHndl);
  66415. +MV_STATUS mvEthPortEnable(void* pEthPortHndl);
  66416. +
  66417. +/* Port data flow routines */
  66418. +MV_PKT_INFO *mvEthPortForceTxDone(void* pEthPortHndl, int txQueue);
  66419. +MV_PKT_INFO *mvEthPortForceRx(void* pEthPortHndl, int rxQueue);
  66420. +
  66421. +/* Port Configuration routines */
  66422. +MV_STATUS mvEthDefaultsSet(void* pEthPortHndl);
  66423. +MV_STATUS mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize);
  66424. +
  66425. +/* Port RX MAC Filtering control routines */
  66426. +MV_U8 mvEthMcastCrc8Get(MV_U8* pAddr);
  66427. +MV_STATUS mvEthRxFilterModeSet(void* pPortHndl, MV_BOOL isPromisc);
  66428. +MV_STATUS mvEthMacAddrSet(void* pPortHandle, MV_U8* pMacAddr, int queue);
  66429. +MV_STATUS mvEthMcastAddrSet(void* pPortHandle, MV_U8 *pAddr, int queue);
  66430. +
  66431. +/* MIB Counters APIs */
  66432. +MV_U32 mvEthMibCounterRead(void* pPortHndl, unsigned int mibOffset,
  66433. + MV_U32* pHigh32);
  66434. +void mvEthMibCountersClear(void* pPortHandle);
  66435. +
  66436. +/* TX Scheduling configuration routines */
  66437. +MV_STATUS mvEthTxQueueConfig(void* pPortHandle, int txQueue,
  66438. + MV_ETH_PRIO_MODE txPrioMode, int txQuota);
  66439. +
  66440. +/* RX Dispatching configuration routines */
  66441. +MV_STATUS mvEthBpduRxQueue(void* pPortHandle, int bpduQueue);
  66442. +MV_STATUS mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue);
  66443. +MV_STATUS mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq);
  66444. +int mvEthTosToRxqGet(void* pPortHandle, int tos);
  66445. +
  66446. +/* Speed, Duplex, FlowControl routines */
  66447. +MV_STATUS mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed,
  66448. + MV_ETH_PORT_DUPLEX duplex);
  66449. +
  66450. +MV_STATUS mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl);
  66451. +
  66452. +#if (MV_ETH_VERSION >= 4)
  66453. +MV_STATUS mvEthEjpModeSet(void* pPortHandle, int mode);
  66454. +#endif /* (MV_ETH_VERSION >= 4) */
  66455. +
  66456. +void mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus);
  66457. +
  66458. +/* Marvell Header control */
  66459. +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);
  66460. +
  66461. +/* PHY routines */
  66462. +void mvEthPhyAddrSet(void* pPortHandle, int phyAddr);
  66463. +int mvEthPhyAddrGet(void* pPortHandle);
  66464. +
  66465. +/* Power management routines */
  66466. +void mvEthPortPowerDown(int port);
  66467. +void mvEthPortPowerUp(int port);
  66468. +
  66469. +/******************** ETH PRIVATE ************************/
  66470. +
  66471. +/*#define UNCACHED_TX_BUFFERS*/
  66472. +/*#define UNCACHED_RX_BUFFERS*/
  66473. +
  66474. +
  66475. +/* Port attributes */
  66476. +/* Size of a Tx/Rx descriptor used in chain list data structure */
  66477. +#define ETH_RX_DESC_ALIGNED_SIZE 32
  66478. +#define ETH_TX_DESC_ALIGNED_SIZE 32
  66479. +
  66480. +#define TX_DISABLE_TIMEOUT_MSEC 1000
  66481. +#define RX_DISABLE_TIMEOUT_MSEC 1000
  66482. +#define TX_FIFO_EMPTY_TIMEOUT_MSEC 10000
  66483. +#define PORT_DISABLE_WAIT_TCLOCKS 5000
  66484. +
  66485. +/* Macros that save access to desc in order to find next desc pointer */
  66486. +#define RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl) \
  66487. + ((pRxDescr) == (pQueueCtrl)->pLastDescr) ? \
  66488. + (ETH_RX_DESC*)((pQueueCtrl)->pFirstDescr) : \
  66489. + (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) + ETH_RX_DESC_ALIGNED_SIZE)
  66490. +
  66491. +#define TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl) \
  66492. + ((pTxDescr) == (pQueueCtrl)->pLastDescr) ? \
  66493. + (ETH_TX_DESC*)((pQueueCtrl)->pFirstDescr) : \
  66494. + (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) + ETH_TX_DESC_ALIGNED_SIZE)
  66495. +
  66496. +#define RX_PREV_DESC_PTR(pRxDescr, pQueueCtrl) \
  66497. + ((pRxDescr) == (pQueueCtrl)->pFirstDescr) ? \
  66498. + (ETH_RX_DESC*)((pQueueCtrl)->pLastDescr) : \
  66499. + (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) - ETH_RX_DESC_ALIGNED_SIZE)
  66500. +
  66501. +#define TX_PREV_DESC_PTR(pTxDescr, pQueueCtrl) \
  66502. + ((pTxDescr) == (pQueueCtrl)->pFirstDescr) ? \
  66503. + (ETH_TX_DESC*)((pQueueCtrl)->pLastDescr) : \
  66504. + (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) - ETH_TX_DESC_ALIGNED_SIZE)
  66505. +
  66506. +
  66507. +/* Queue specific information */
  66508. +typedef struct
  66509. +{
  66510. + void* pFirstDescr;
  66511. + void* pLastDescr;
  66512. + void* pCurrentDescr;
  66513. + void* pUsedDescr;
  66514. + int resource;
  66515. + MV_BUF_INFO descBuf;
  66516. +} ETH_QUEUE_CTRL;
  66517. +
  66518. +
  66519. +/* Ethernet port specific infomation */
  66520. +typedef struct _ethPortCtrl
  66521. +{
  66522. + int portNo;
  66523. + ETH_QUEUE_CTRL rxQueue[MV_ETH_RX_Q_NUM]; /* Rx ring resource */
  66524. + ETH_QUEUE_CTRL txQueue[MV_ETH_TX_Q_NUM]; /* Tx ring resource */
  66525. +
  66526. + MV_ETH_PORT_CFG portConfig;
  66527. + MV_ETH_RX_Q_CFG rxQueueConfig[MV_ETH_RX_Q_NUM];
  66528. + MV_ETH_TX_Q_CFG txQueueConfig[MV_ETH_TX_Q_NUM];
  66529. +
  66530. + /* Register images - For DP */
  66531. + MV_U32 portTxQueueCmdReg; /* Port active Tx queues summary */
  66532. + MV_U32 portRxQueueCmdReg; /* Port active Rx queues summary */
  66533. +
  66534. + MV_STATE portState;
  66535. +
  66536. + MV_U8 mcastCount[256];
  66537. + MV_U32* hashPtr;
  66538. + void *osHandle;
  66539. +} ETH_PORT_CTRL;
  66540. +
  66541. +/************** MACROs ****************/
  66542. +
  66543. +/* MACROs to Flush / Invalidate TX / RX Buffers */
  66544. +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_TX_BUFFERS)
  66545. +# define ETH_PACKET_CACHE_FLUSH(pAddr, size) \
  66546. + mvOsCacheClear(NULL, (pAddr), (size)); \
  66547. + /*CPU_PIPE_FLUSH;*/
  66548. +#else
  66549. +# define ETH_PACKET_CACHE_FLUSH(pAddr, size) \
  66550. + mvOsIoVirtToPhy(NULL, (pAddr));
  66551. +#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW */
  66552. +
  66553. +#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_RX_BUFFERS) )
  66554. +# define ETH_PACKET_CACHE_INVALIDATE(pAddr, size) \
  66555. + mvOsCacheInvalidate (NULL, (pAddr), (size)); \
  66556. + /*CPU_PIPE_FLUSH;*/
  66557. +#else
  66558. +# define ETH_PACKET_CACHE_INVALIDATE(pAddr, size)
  66559. +#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW && !UNCACHED_RX_BUFFERS */
  66560. +
  66561. +#ifdef ETH_DESCR_UNCACHED
  66562. +
  66563. +#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr)
  66564. +#define ETH_DESCR_INV(pPortCtrl, pDescr)
  66565. +
  66566. +#else
  66567. +
  66568. +#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr) \
  66569. + mvOsCacheLineFlushInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))
  66570. +
  66571. +#define ETH_DESCR_INV(pPortCtrl, pDescr) \
  66572. + mvOsCacheLineInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))
  66573. +
  66574. +#endif /* ETH_DESCR_UNCACHED */
  66575. +
  66576. +#include "eth/gbe/mvEthGbe.h"
  66577. +
  66578. +#endif /* __mvEth_h__ */
  66579. +
  66580. +
  66581. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c
  66582. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c 1970-01-01 01:00:00.000000000 +0100
  66583. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c 2010-11-09 20:28:11.262495582 +0100
  66584. @@ -0,0 +1,362 @@
  66585. +/*******************************************************************************
  66586. +Copyright (C) Marvell International Ltd. and its affiliates
  66587. +
  66588. +This software file (the "File") is owned and distributed by Marvell
  66589. +International Ltd. and/or its affiliates ("Marvell") under the following
  66590. +alternative licensing terms. Once you have made an election to distribute the
  66591. +File under one of the following license alternatives, please (i) delete this
  66592. +introductory statement regarding license alternatives, (ii) delete the two
  66593. +license alternatives that you have not elected to use and (iii) preserve the
  66594. +Marvell copyright notice above.
  66595. +
  66596. +********************************************************************************
  66597. +Marvell Commercial License Option
  66598. +
  66599. +If you received this File from Marvell and you have entered into a commercial
  66600. +license agreement (a "Commercial License") with Marvell, the File is licensed
  66601. +to you under the terms of the applicable Commercial License.
  66602. +
  66603. +********************************************************************************
  66604. +Marvell GPL License Option
  66605. +
  66606. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66607. +modify this File in accordance with the terms and conditions of the General
  66608. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  66609. +available along with the File in the license.txt file or by writing to the Free
  66610. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  66611. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  66612. +
  66613. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  66614. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  66615. +DISCLAIMED. The GPL License provides additional details about this warranty
  66616. +disclaimer.
  66617. +********************************************************************************
  66618. +Marvell BSD License Option
  66619. +
  66620. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66621. +modify this File under the following licensing terms.
  66622. +Redistribution and use in source and binary forms, with or without modification,
  66623. +are permitted provided that the following conditions are met:
  66624. +
  66625. + * Redistributions of source code must retain the above copyright notice,
  66626. + this list of conditions and the following disclaimer.
  66627. +
  66628. + * Redistributions in binary form must reproduce the above copyright
  66629. + notice, this list of conditions and the following disclaimer in the
  66630. + documentation and/or other materials provided with the distribution.
  66631. +
  66632. + * Neither the name of Marvell nor the names of its contributors may be
  66633. + used to endorse or promote products derived from this software without
  66634. + specific prior written permission.
  66635. +
  66636. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  66637. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  66638. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  66639. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  66640. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  66641. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  66642. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  66643. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  66644. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  66645. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  66646. +
  66647. +*******************************************************************************/
  66648. +
  66649. +#include "gpp/mvGpp.h"
  66650. +#include "ctrlEnv/mvCtrlEnvLib.h"
  66651. +/* defines */
  66652. +#ifdef MV_DEBUG
  66653. + #define DB(x) x
  66654. +#else
  66655. + #define DB(x)
  66656. +#endif
  66657. +
  66658. +static MV_VOID gppRegSet(MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value);
  66659. +
  66660. +/*******************************************************************************
  66661. +* mvGppTypeSet - Enable a GPP (OUT) pin
  66662. +*
  66663. +* DESCRIPTION:
  66664. +*
  66665. +* INPUT:
  66666. +* group - GPP group number
  66667. +* mask - 32bit mask value. Each set bit in the mask means that the type
  66668. +* of corresponding GPP will be set. Other GPPs are ignored.
  66669. +* value - 32bit value that describes GPP type per pin.
  66670. +*
  66671. +* OUTPUT:
  66672. +* None.
  66673. +*
  66674. +* EXAMPLE:
  66675. +* Set GPP8 to input and GPP15 to output.
  66676. +* mvGppTypeSet(0, (GPP8 | GPP15),
  66677. +* ((MV_GPP_IN & GPP8) | (MV_GPP_OUT & GPP15)) );
  66678. +*
  66679. +* RETURN:
  66680. +* None.
  66681. +*
  66682. +*******************************************************************************/
  66683. +MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value)
  66684. +{
  66685. + if (group >= MV_GPP_MAX_GROUP)
  66686. + {
  66687. + DB(mvOsPrintf("mvGppTypeSet: ERR. invalid group number \n"));
  66688. + return MV_BAD_PARAM;
  66689. + }
  66690. +
  66691. + gppRegSet(group, GPP_DATA_OUT_EN_REG(group), mask, value);
  66692. +
  66693. + /* Workaround for Erratum FE-MISC-70*/
  66694. + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))
  66695. + {
  66696. + mask &= 0x2;
  66697. + gppRegSet(0, GPP_DATA_OUT_EN_REG(0), mask, value);
  66698. + } /*End of WA*/
  66699. +
  66700. + return MV_OK;
  66701. +
  66702. +}
  66703. +
  66704. +/*******************************************************************************
  66705. +* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms
  66706. +*
  66707. +* DESCRIPTION:
  66708. +*
  66709. +* INPUT:
  66710. +* group - GPP group number
  66711. +* mask - 32bit mask value. Each set bit in the mask means that the type
  66712. +* of corresponding GPP will be set. Other GPPs are ignored.
  66713. +* value - 32bit value that describes GPP blink per pin.
  66714. +*
  66715. +* OUTPUT:
  66716. +* None.
  66717. +*
  66718. +* EXAMPLE:
  66719. +* Set GPP8 to be static and GPP15 to be blinking.
  66720. +* mvGppBlinkEn(0, (GPP8 | GPP15),
  66721. +* ((MV_GPP_OUT_STATIC & GPP8) | (MV_GPP_OUT_BLINK & GPP15)) );
  66722. +*
  66723. +* RETURN:
  66724. +* None.
  66725. +*
  66726. +*******************************************************************************/
  66727. +MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value)
  66728. +{
  66729. + if (group >= MV_GPP_MAX_GROUP)
  66730. + {
  66731. + DB(mvOsPrintf("mvGppBlinkEn: ERR. invalid group number \n"));
  66732. + return MV_BAD_PARAM;
  66733. + }
  66734. +
  66735. + gppRegSet(group, GPP_BLINK_EN_REG(group), mask, value);
  66736. +
  66737. + return MV_OK;
  66738. +
  66739. +}
  66740. +/*******************************************************************************
  66741. +* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode
  66742. +*
  66743. +* DESCRIPTION:
  66744. +*
  66745. +* INPUT:
  66746. +* group - GPP group number
  66747. +* mask - 32bit mask value. Each set bit in the mask means that the type
  66748. +* of corresponding GPP will be set. Other GPPs are ignored.
  66749. +* value - 32bit value that describes GPP polarity per pin.
  66750. +*
  66751. +* OUTPUT:
  66752. +* None.
  66753. +*
  66754. +* EXAMPLE:
  66755. +* Set GPP8 to the actual pin value and GPP15 to be inverted.
  66756. +* mvGppPolaritySet(0, (GPP8 | GPP15),
  66757. +* ((MV_GPP_IN_ORIGIN & GPP8) | (MV_GPP_IN_INVERT & GPP15)) );
  66758. +*
  66759. +* RETURN:
  66760. +* None.
  66761. +*
  66762. +*******************************************************************************/
  66763. +MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value)
  66764. +{
  66765. + if (group >= MV_GPP_MAX_GROUP)
  66766. + {
  66767. + DB(mvOsPrintf("mvGppPolaritySet: ERR. invalid group number \n"));
  66768. + return MV_BAD_PARAM;
  66769. + }
  66770. +
  66771. + gppRegSet(group, GPP_DATA_IN_POL_REG(group), mask, value);
  66772. +
  66773. + return MV_OK;
  66774. +
  66775. +}
  66776. +
  66777. +/*******************************************************************************
  66778. +* mvGppPolarityGet - Get a value of relevant bits from GPP Polarity register.
  66779. +*
  66780. +* DESCRIPTION:
  66781. +*
  66782. +* INPUT:
  66783. +* group - GPP group number
  66784. +* mask - 32bit mask value. Each set bit in the mask means that the
  66785. +* returned value is valid for it.
  66786. +*
  66787. +* OUTPUT:
  66788. +* None.
  66789. +*
  66790. +* EXAMPLE:
  66791. +* Get GPP8 and GPP15 value.
  66792. +* mvGppPolarityGet(0, (GPP8 | GPP15));
  66793. +*
  66794. +* RETURN:
  66795. +* 32bit value that describes GPP polatity mode per pin.
  66796. +*
  66797. +*******************************************************************************/
  66798. +MV_U32 mvGppPolarityGet(MV_U32 group, MV_U32 mask)
  66799. +{
  66800. + MV_U32 regVal;
  66801. +
  66802. + if (group >= MV_GPP_MAX_GROUP)
  66803. + {
  66804. + DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));
  66805. + return MV_ERROR;
  66806. + }
  66807. + regVal = MV_REG_READ(GPP_DATA_IN_POL_REG(group));
  66808. +
  66809. + return (regVal & mask);
  66810. +}
  66811. +
  66812. +/*******************************************************************************
  66813. +* mvGppValueGet - Get a GPP Pin list value.
  66814. +*
  66815. +* DESCRIPTION:
  66816. +* This function get GPP value.
  66817. +*
  66818. +* INPUT:
  66819. +* group - GPP group number
  66820. +* mask - 32bit mask value. Each set bit in the mask means that the
  66821. +* returned value is valid for it.
  66822. +*
  66823. +* OUTPUT:
  66824. +* None.
  66825. +*
  66826. +* EXAMPLE:
  66827. +* Get GPP8 and GPP15 value.
  66828. +* mvGppValueGet(0, (GPP8 | GPP15));
  66829. +*
  66830. +* RETURN:
  66831. +* 32bit value that describes GPP activity mode per pin.
  66832. +*
  66833. +*******************************************************************************/
  66834. +MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask)
  66835. +{
  66836. + MV_U32 gppData;
  66837. +
  66838. + gppData = MV_REG_READ(GPP_DATA_IN_REG(group));
  66839. +
  66840. + gppData &= mask;
  66841. +
  66842. + return gppData;
  66843. +
  66844. +}
  66845. +
  66846. +/*******************************************************************************
  66847. +* mvGppValueSet - Set a GPP Pin list value.
  66848. +*
  66849. +* DESCRIPTION:
  66850. +* This function set value for given GPP pin list.
  66851. +*
  66852. +* INPUT:
  66853. +* group - GPP group number
  66854. +* mask - 32bit mask value. Each set bit in the mask means that the
  66855. +* value of corresponding GPP will be set accordingly. Other GPP
  66856. +* are not affected.
  66857. +* value - 32bit value that describes GPP value per pin.
  66858. +*
  66859. +* OUTPUT:
  66860. +* None.
  66861. +*
  66862. +* EXAMPLE:
  66863. +* Set GPP8 value of '0' and GPP15 value of '1'.
  66864. +* mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (GPP15)) );
  66865. +*
  66866. +* RETURN:
  66867. +* None.
  66868. +*
  66869. +*******************************************************************************/
  66870. +MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value)
  66871. +{
  66872. + MV_U32 outEnable, tmp;
  66873. + MV_U32 i;
  66874. +
  66875. + if (group >= MV_GPP_MAX_GROUP)
  66876. + {
  66877. + DB(mvOsPrintf("mvGppValueSet: Error invalid group number \n"));
  66878. + return MV_BAD_PARAM;
  66879. + }
  66880. +
  66881. + /* verify that the gpp pin is configured as output */
  66882. + /* Note that in the register out enabled -> bit = '0'. */
  66883. + outEnable = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(group));
  66884. +
  66885. + /* Workaround for Erratum FE-MISC-70*/
  66886. + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))
  66887. + {
  66888. + tmp = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(0));
  66889. + outEnable &= 0xfffffffd;
  66890. + outEnable |= (tmp & 0x2);
  66891. + } /*End of WA*/
  66892. +
  66893. + for (i = 0 ; i < 32 ;i++)
  66894. + {
  66895. + if (((mask & (1 << i)) & (outEnable & (1 << i))) != (mask & (1 << i)))
  66896. + {
  66897. + mvOsPrintf("mvGppValueSet: Err. An attempt to set output "\
  66898. + "value to GPP %d in input mode.\n", i);
  66899. + return MV_ERROR;
  66900. + }
  66901. + }
  66902. +
  66903. + gppRegSet(group, GPP_DATA_OUT_REG(group), mask, value);
  66904. +
  66905. + return MV_OK;
  66906. +
  66907. +}
  66908. +/*******************************************************************************
  66909. +* gppRegSet - Set a specific GPP pin on a specific GPP register
  66910. +*
  66911. +* DESCRIPTION:
  66912. +* This function set a specific GPP pin on a specific GPP register
  66913. +*
  66914. +* INPUT:
  66915. +* regOffs - GPP Register offset
  66916. +* group - GPP group number
  66917. +* mask - 32bit mask value. Each set bit in the mask means that the
  66918. +* value of corresponding GPP will be set accordingly. Other GPP
  66919. +* are not affected.
  66920. +* value - 32bit value that describes GPP value per pin.
  66921. +*
  66922. +* OUTPUT:
  66923. +* None.
  66924. +*
  66925. +* EXAMPLE:
  66926. +* Set GPP8 value of '0' and GPP15 value of '1'.
  66927. +* mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (1 & GPP15)) );
  66928. +*
  66929. +* RETURN:
  66930. +* None.
  66931. +*
  66932. +*******************************************************************************/
  66933. +static MV_VOID gppRegSet (MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value)
  66934. +{
  66935. + MV_U32 gppData;
  66936. +
  66937. + gppData = MV_REG_READ(regOffs);
  66938. +
  66939. + gppData &= ~mask;
  66940. +
  66941. + gppData |= (value & mask);
  66942. +
  66943. + MV_REG_WRITE(regOffs, gppData);
  66944. +}
  66945. +
  66946. +
  66947. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h
  66948. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h 1970-01-01 01:00:00.000000000 +0100
  66949. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h 2010-11-09 20:28:11.302495429 +0100
  66950. @@ -0,0 +1,118 @@
  66951. +/*******************************************************************************
  66952. +Copyright (C) Marvell International Ltd. and its affiliates
  66953. +
  66954. +This software file (the "File") is owned and distributed by Marvell
  66955. +International Ltd. and/or its affiliates ("Marvell") under the following
  66956. +alternative licensing terms. Once you have made an election to distribute the
  66957. +File under one of the following license alternatives, please (i) delete this
  66958. +introductory statement regarding license alternatives, (ii) delete the two
  66959. +license alternatives that you have not elected to use and (iii) preserve the
  66960. +Marvell copyright notice above.
  66961. +
  66962. +********************************************************************************
  66963. +Marvell Commercial License Option
  66964. +
  66965. +If you received this File from Marvell and you have entered into a commercial
  66966. +license agreement (a "Commercial License") with Marvell, the File is licensed
  66967. +to you under the terms of the applicable Commercial License.
  66968. +
  66969. +********************************************************************************
  66970. +Marvell GPL License Option
  66971. +
  66972. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66973. +modify this File in accordance with the terms and conditions of the General
  66974. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  66975. +available along with the File in the license.txt file or by writing to the Free
  66976. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  66977. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  66978. +
  66979. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  66980. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  66981. +DISCLAIMED. The GPL License provides additional details about this warranty
  66982. +disclaimer.
  66983. +********************************************************************************
  66984. +Marvell BSD License Option
  66985. +
  66986. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66987. +modify this File under the following licensing terms.
  66988. +Redistribution and use in source and binary forms, with or without modification,
  66989. +are permitted provided that the following conditions are met:
  66990. +
  66991. + * Redistributions of source code must retain the above copyright notice,
  66992. + this list of conditions and the following disclaimer.
  66993. +
  66994. + * Redistributions in binary form must reproduce the above copyright
  66995. + notice, this list of conditions and the following disclaimer in the
  66996. + documentation and/or other materials provided with the distribution.
  66997. +
  66998. + * Neither the name of Marvell nor the names of its contributors may be
  66999. + used to endorse or promote products derived from this software without
  67000. + specific prior written permission.
  67001. +
  67002. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  67003. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  67004. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  67005. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  67006. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  67007. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  67008. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  67009. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  67010. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  67011. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  67012. +
  67013. +*******************************************************************************/
  67014. +
  67015. +#ifndef __INCmvGppH
  67016. +#define __INCmvGppH
  67017. +
  67018. +#include "mvCommon.h"
  67019. +#include "mvOs.h"
  67020. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  67021. +#include "gpp/mvGppRegs.h"
  67022. +
  67023. +/* These macros describes the GPP type. Each of the GPPs pins can */
  67024. +/* be assigned to act as a general purpose input or output pin. */
  67025. +#define MV_GPP_IN 0xFFFFFFFF /* GPP input */
  67026. +#define MV_GPP_OUT 0 /* GPP output */
  67027. +
  67028. +
  67029. +/* These macros describes the GPP Out Enable. */
  67030. +#define MV_GPP_OUT_DIS 0xFFFFFFFF /* Out pin disabled*/
  67031. +#define MV_GPP_OUT_EN 0 /* Out pin enabled*/
  67032. +
  67033. +/* These macros describes the GPP Out Blinking. */
  67034. +/* When set and the corresponding bit in GPIO Data Out Enable Control */
  67035. +/* Register is enabled, the GPIO pin blinks every ~100 ms (a period of */
  67036. +/* 2^24 TCLK clocks). */
  67037. +#define MV_GPP_OUT_BLINK 0xFFFFFFFF /* Out pin blinking*/
  67038. +#define MV_GPP_OUT_STATIC 0 /* Out pin static*/
  67039. +
  67040. +
  67041. +/* These macros describes the GPP Polarity. */
  67042. +/* When set to 1 GPIO Data In Register reflects the inverted value of the */
  67043. +/* corresponding pin. */
  67044. +
  67045. +#define MV_GPP_IN_INVERT 0xFFFFFFFF /* Inverted value is got*/
  67046. +#define MV_GPP_IN_ORIGIN 0 /* original value is got*/
  67047. +
  67048. +/* mvGppTypeSet - Set PP pin mode (IN or OUT) */
  67049. +MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value);
  67050. +
  67051. +/* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms */
  67052. +MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value);
  67053. +
  67054. +/* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode. */
  67055. +MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value);
  67056. +
  67057. +/* mvGppPolarityGet - Get the Polarity of a GPP Pin */
  67058. +MV_U32 mvGppPolarityGet(MV_U32 group, MV_U32 mask);
  67059. +
  67060. +/* mvGppValueGet - Get a GPP Pin list value.*/
  67061. +MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask);
  67062. +
  67063. +
  67064. +/* mvGppValueSet - Set a GPP Pin list value. */
  67065. +MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value);
  67066. +
  67067. +#endif /* #ifndef __INCmvGppH */
  67068. +
  67069. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h
  67070. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h 1970-01-01 01:00:00.000000000 +0100
  67071. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h 2010-11-09 20:28:11.342495467 +0100
  67072. @@ -0,0 +1,116 @@
  67073. +/*******************************************************************************
  67074. +Copyright (C) Marvell International Ltd. and its affiliates
  67075. +
  67076. +This software file (the "File") is owned and distributed by Marvell
  67077. +International Ltd. and/or its affiliates ("Marvell") under the following
  67078. +alternative licensing terms. Once you have made an election to distribute the
  67079. +File under one of the following license alternatives, please (i) delete this
  67080. +introductory statement regarding license alternatives, (ii) delete the two
  67081. +license alternatives that you have not elected to use and (iii) preserve the
  67082. +Marvell copyright notice above.
  67083. +
  67084. +********************************************************************************
  67085. +Marvell Commercial License Option
  67086. +
  67087. +If you received this File from Marvell and you have entered into a commercial
  67088. +license agreement (a "Commercial License") with Marvell, the File is licensed
  67089. +to you under the terms of the applicable Commercial License.
  67090. +
  67091. +********************************************************************************
  67092. +Marvell GPL License Option
  67093. +
  67094. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67095. +modify this File in accordance with the terms and conditions of the General
  67096. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  67097. +available along with the File in the license.txt file or by writing to the Free
  67098. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  67099. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  67100. +
  67101. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  67102. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  67103. +DISCLAIMED. The GPL License provides additional details about this warranty
  67104. +disclaimer.
  67105. +********************************************************************************
  67106. +Marvell BSD License Option
  67107. +
  67108. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67109. +modify this File under the following licensing terms.
  67110. +Redistribution and use in source and binary forms, with or without modification,
  67111. +are permitted provided that the following conditions are met:
  67112. +
  67113. + * Redistributions of source code must retain the above copyright notice,
  67114. + this list of conditions and the following disclaimer.
  67115. +
  67116. + * Redistributions in binary form must reproduce the above copyright
  67117. + notice, this list of conditions and the following disclaimer in the
  67118. + documentation and/or other materials provided with the distribution.
  67119. +
  67120. + * Neither the name of Marvell nor the names of its contributors may be
  67121. + used to endorse or promote products derived from this software without
  67122. + specific prior written permission.
  67123. +
  67124. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  67125. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  67126. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  67127. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  67128. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  67129. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  67130. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  67131. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  67132. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  67133. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  67134. +
  67135. +*******************************************************************************/
  67136. +
  67137. +#ifndef __INCmvGppRegsH
  67138. +#define __INCmvGppRegsH
  67139. +
  67140. +#define MV_GPP0 BIT0
  67141. +#define MV_GPP1 BIT1
  67142. +#define MV_GPP2 BIT2
  67143. +#define MV_GPP3 BIT3
  67144. +#define MV_GPP4 BIT4
  67145. +#define MV_GPP5 BIT5
  67146. +#define MV_GPP6 BIT6
  67147. +#define MV_GPP7 BIT7
  67148. +#define MV_GPP8 BIT8
  67149. +#define MV_GPP9 BIT9
  67150. +#define MV_GPP10 BIT10
  67151. +#define MV_GPP11 BIT11
  67152. +#define MV_GPP12 BIT12
  67153. +#define MV_GPP13 BIT13
  67154. +#define MV_GPP14 BIT14
  67155. +#define MV_GPP15 BIT15
  67156. +#define MV_GPP16 BIT16
  67157. +#define MV_GPP17 BIT17
  67158. +#define MV_GPP18 BIT18
  67159. +#define MV_GPP19 BIT19
  67160. +#define MV_GPP20 BIT20
  67161. +#define MV_GPP21 BIT21
  67162. +#define MV_GPP22 BIT22
  67163. +#define MV_GPP23 BIT23
  67164. +#define MV_GPP24 BIT24
  67165. +#define MV_GPP25 BIT25
  67166. +#define MV_GPP26 BIT26
  67167. +#define MV_GPP27 BIT27
  67168. +#define MV_GPP28 BIT28
  67169. +#define MV_GPP29 BIT29
  67170. +#define MV_GPP30 BIT30
  67171. +#define MV_GPP31 BIT31
  67172. +
  67173. +
  67174. +/* registers offsets */
  67175. +
  67176. +#define GPP_DATA_OUT_REG(grp) ((grp == 0) ? 0x10100 : 0x10140)
  67177. +#define GPP_DATA_OUT_EN_REG(grp) ((grp == 0) ? 0x10104 : 0x10144)
  67178. +#define GPP_BLINK_EN_REG(grp) ((grp == 0) ? 0x10108 : 0x10148)
  67179. +#define GPP_DATA_IN_POL_REG(grp) ((grp == 0) ? 0x1010C : 0x1014c)
  67180. +#define GPP_DATA_IN_REG(grp) ((grp == 0) ? 0x10110 : 0x10150)
  67181. +#define GPP_INT_CAUSE_REG(grp) ((grp == 0) ? 0x10114 : 0x10154)
  67182. +#define GPP_INT_MASK_REG(grp) ((grp == 0) ? 0x10118 : 0x10158)
  67183. +#define GPP_INT_LVL_REG(grp) ((grp == 0) ? 0x1011c : 0x1015c)
  67184. +
  67185. +#define GPP_DATA_OUT_SET_REG 0x10120
  67186. +#define GPP_DATA_OUT_CLEAR_REG 0x10124
  67187. +
  67188. +#endif /* #ifndef __INCmvGppRegsH */
  67189. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c
  67190. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c 1970-01-01 01:00:00.000000000 +0100
  67191. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c 2010-11-09 20:28:11.372495482 +0100
  67192. @@ -0,0 +1,1047 @@
  67193. +/*******************************************************************************
  67194. +Copyright (C) Marvell International Ltd. and its affiliates
  67195. +
  67196. +This software file (the "File") is owned and distributed by Marvell
  67197. +International Ltd. and/or its affiliates ("Marvell") under the following
  67198. +alternative licensing terms. Once you have made an election to distribute the
  67199. +File under one of the following license alternatives, please (i) delete this
  67200. +introductory statement regarding license alternatives, (ii) delete the two
  67201. +license alternatives that you have not elected to use and (iii) preserve the
  67202. +Marvell copyright notice above.
  67203. +
  67204. +********************************************************************************
  67205. +Marvell Commercial License Option
  67206. +
  67207. +If you received this File from Marvell and you have entered into a commercial
  67208. +license agreement (a "Commercial License") with Marvell, the File is licensed
  67209. +to you under the terms of the applicable Commercial License.
  67210. +
  67211. +********************************************************************************
  67212. +Marvell GPL License Option
  67213. +
  67214. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67215. +modify this File in accordance with the terms and conditions of the General
  67216. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  67217. +available along with the File in the license.txt file or by writing to the Free
  67218. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  67219. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  67220. +
  67221. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  67222. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  67223. +DISCLAIMED. The GPL License provides additional details about this warranty
  67224. +disclaimer.
  67225. +********************************************************************************
  67226. +Marvell BSD License Option
  67227. +
  67228. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67229. +modify this File under the following licensing terms.
  67230. +Redistribution and use in source and binary forms, with or without modification,
  67231. +are permitted provided that the following conditions are met:
  67232. +
  67233. + * Redistributions of source code must retain the above copyright notice,
  67234. + this list of conditions and the following disclaimer.
  67235. +
  67236. + * Redistributions in binary form must reproduce the above copyright
  67237. + notice, this list of conditions and the following disclaimer in the
  67238. + documentation and/or other materials provided with the distribution.
  67239. +
  67240. + * Neither the name of Marvell nor the names of its contributors may be
  67241. + used to endorse or promote products derived from this software without
  67242. + specific prior written permission.
  67243. +
  67244. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  67245. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  67246. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  67247. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  67248. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  67249. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  67250. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  67251. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  67252. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  67253. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  67254. +
  67255. +*******************************************************************************/
  67256. +#include "pci/mvPci.h"
  67257. +
  67258. +#include "ctrlEnv/mvCtrlEnvLib.h"
  67259. +
  67260. +/* defines */
  67261. +#ifdef MV_DEBUG
  67262. + #define DB(x) x
  67263. +#else
  67264. + #define DB(x)
  67265. +#endif
  67266. +
  67267. +
  67268. +
  67269. +MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod)
  67270. +{
  67271. + if (MV_PCI_MOD_HOST == pciIfmod)
  67272. + {
  67273. +
  67274. + mvPciLocalBusNumSet(pciIf, PCI_HOST_BUS_NUM(pciIf));
  67275. + mvPciLocalDevNumSet(pciIf, PCI_HOST_DEV_NUM(pciIf));
  67276. +
  67277. + /* Local device master Enable */
  67278. + mvPciMasterEnable(pciIf, MV_TRUE);
  67279. +
  67280. + /* Local device slave Enable */
  67281. + mvPciSlaveEnable(pciIf, mvPciLocalBusNumGet(pciIf),
  67282. + mvPciLocalDevNumGet(pciIf), MV_TRUE);
  67283. + }
  67284. + /* enable CPU-2-PCI ordering */
  67285. + MV_REG_BIT_SET(PCI_CMD_REG(0), PCR_CPU_TO_PCI_ORDER_EN);
  67286. +}
  67287. +
  67288. +/*******************************************************************************
  67289. +* mvPciCommandSet - Set PCI comman register value.
  67290. +*
  67291. +* DESCRIPTION:
  67292. +* This function sets a given PCI interface with its command register
  67293. +* value.
  67294. +*
  67295. +* INPUT:
  67296. +* pciIf - PCI interface number.
  67297. +* command - 32bit value to be written to comamnd register.
  67298. +*
  67299. +* OUTPUT:
  67300. +* None.
  67301. +*
  67302. +* RETURN:
  67303. +* MV_BAD_PARAM if pciIf is not in range otherwise MV_OK
  67304. +*
  67305. +*******************************************************************************/
  67306. +MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command)
  67307. +{
  67308. + MV_U32 locBusNum, locDevNum, regVal;
  67309. +
  67310. + locBusNum = mvPciLocalBusNumGet(pciIf);
  67311. + locDevNum = mvPciLocalDevNumGet(pciIf);
  67312. +
  67313. + /* Parameter checking */
  67314. + if (pciIf >= mvCtrlPciMaxIfGet())
  67315. + {
  67316. + mvOsPrintf("mvPciCommandSet: ERR. Invalid PCI IF num %d\n", pciIf);
  67317. + return MV_BAD_PARAM;
  67318. + }
  67319. +
  67320. + /* Set command register */
  67321. + MV_REG_WRITE(PCI_CMD_REG(pciIf), command);
  67322. +
  67323. + /* Upodate device max outstanding split tarnsaction */
  67324. + if ((command & PCR_CPU_TO_PCI_ORDER_EN) &&
  67325. + (command & PCR_PCI_TO_CPU_ORDER_EN))
  67326. + {
  67327. + /* Read PCI-X command register */
  67328. + regVal = mvPciConfigRead (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND);
  67329. +
  67330. + /* clear bits 22:20 */
  67331. + regVal &= 0xff8fffff;
  67332. +
  67333. + /* set reset value */
  67334. + regVal |= (0x3 << 20);
  67335. +
  67336. + /* Write back the value */
  67337. + mvPciConfigWrite (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND, regVal);
  67338. + }
  67339. +
  67340. + return MV_OK;
  67341. +
  67342. +
  67343. +}
  67344. +
  67345. +
  67346. +/*******************************************************************************
  67347. +* mvPciModeGet - Get PCI interface mode.
  67348. +*
  67349. +* DESCRIPTION:
  67350. +* This function returns the given PCI interface mode.
  67351. +*
  67352. +* INPUT:
  67353. +* pciIf - PCI interface number.
  67354. +*
  67355. +* OUTPUT:
  67356. +* pPciMode - Pointer to PCI mode structure.
  67357. +*
  67358. +* RETURN:
  67359. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67360. +*
  67361. +*******************************************************************************/
  67362. +MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode)
  67363. +{
  67364. + MV_U32 pciMode;
  67365. +
  67366. + /* Parameter checking */
  67367. + if (pciIf >= mvCtrlPciMaxIfGet())
  67368. + {
  67369. + mvOsPrintf("mvPciModeGet: ERR. Invalid PCI interface %d\n", pciIf);
  67370. + return MV_BAD_PARAM;
  67371. + }
  67372. + if (NULL == pPciMode)
  67373. + {
  67374. + mvOsPrintf("mvPciModeGet: ERR. pPciMode = NULL \n");
  67375. + return MV_BAD_PARAM;
  67376. + }
  67377. +
  67378. + /* Read pci mode register */
  67379. + pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));
  67380. +
  67381. + switch (pciMode & PMR_PCI_MODE_MASK)
  67382. + {
  67383. + case PMR_PCI_MODE_CONV:
  67384. + pPciMode->pciType = MV_PCI_CONV;
  67385. +
  67386. + if (MV_REG_READ(PCI_DLL_CTRL_REG(pciIf)) & PDC_DLL_EN)
  67387. + {
  67388. + pPciMode->pciSpeed = 66000000; /* 66MHZ */
  67389. + }
  67390. + else
  67391. + {
  67392. + pPciMode->pciSpeed = 33000000; /* 33MHZ */
  67393. + }
  67394. +
  67395. + break;
  67396. +
  67397. + case PMR_PCI_MODE_PCIX_66MHZ:
  67398. + pPciMode->pciType = MV_PCIX;
  67399. + pPciMode->pciSpeed = 66000000; /* 66MHZ */
  67400. + break;
  67401. +
  67402. + case PMR_PCI_MODE_PCIX_100MHZ:
  67403. + pPciMode->pciType = MV_PCIX;
  67404. + pPciMode->pciSpeed = 100000000; /* 100MHZ */
  67405. + break;
  67406. +
  67407. + case PMR_PCI_MODE_PCIX_133MHZ:
  67408. + pPciMode->pciType = MV_PCIX;
  67409. + pPciMode->pciSpeed = 133000000; /* 133MHZ */
  67410. + break;
  67411. +
  67412. + default:
  67413. + {
  67414. + mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");
  67415. + return MV_ERROR;
  67416. + }
  67417. + }
  67418. +
  67419. + switch (pciMode & PMR_PCI_64_MASK)
  67420. + {
  67421. + case PMR_PCI_64_64BIT:
  67422. + pPciMode->pciWidth = MV_PCI_64;
  67423. + break;
  67424. +
  67425. + case PMR_PCI_64_32BIT:
  67426. + pPciMode->pciWidth = MV_PCI_32;
  67427. + break;
  67428. +
  67429. + default:
  67430. + {
  67431. + mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");
  67432. + return MV_ERROR;
  67433. + }
  67434. + }
  67435. +
  67436. + return MV_OK;
  67437. +}
  67438. +
  67439. +/*******************************************************************************
  67440. +* mvPciRetrySet - Set PCI retry counters
  67441. +*
  67442. +* DESCRIPTION:
  67443. +* This function specifies the number of times the PCI controller
  67444. +* retries a transaction before it quits.
  67445. +* Applies to the PCI Master when acting as a requester.
  67446. +* Applies to the PCI slave when acting as a completer (PCI-X mode).
  67447. +* A 0x00 value means a "retry forever".
  67448. +*
  67449. +* INPUT:
  67450. +* pciIf - PCI interface number.
  67451. +* counter - Number of times PCI controller retry. Use counter value
  67452. +* up to PRR_RETRY_CNTR_MAX.
  67453. +*
  67454. +* OUTPUT:
  67455. +* None.
  67456. +*
  67457. +* RETURN:
  67458. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67459. +*
  67460. +*******************************************************************************/
  67461. +MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter)
  67462. +{
  67463. + MV_U32 pciRetry;
  67464. +
  67465. + /* Parameter checking */
  67466. + if (pciIf >= mvCtrlPciMaxIfGet())
  67467. + {
  67468. + mvOsPrintf("mvPciRetrySet: ERR. Invalid PCI interface %d\n", pciIf);
  67469. + return MV_BAD_PARAM;
  67470. + }
  67471. +
  67472. + if (counter >= PRR_RETRY_CNTR_MAX)
  67473. + {
  67474. + mvOsPrintf("mvPciRetrySet: ERR. Invalid counter: %d\n", counter);
  67475. + return MV_BAD_PARAM;
  67476. +
  67477. + }
  67478. +
  67479. + /* Reading PCI retry register */
  67480. + pciRetry = MV_REG_READ(PCI_RETRY_REG(pciIf));
  67481. +
  67482. + pciRetry &= ~PRR_RETRY_CNTR_MASK;
  67483. +
  67484. + pciRetry |= (counter << PRR_RETRY_CNTR_OFFS);
  67485. +
  67486. + /* write new value */
  67487. + MV_REG_WRITE(PCI_RETRY_REG(pciIf), pciRetry);
  67488. +
  67489. + return MV_OK;
  67490. +}
  67491. +
  67492. +
  67493. +/*******************************************************************************
  67494. +* mvPciDiscardTimerSet - Set PCI discard timer
  67495. +*
  67496. +* DESCRIPTION:
  67497. +* This function set PCI discard timer.
  67498. +* In conventional PCI mode:
  67499. +* Specifies the number of PCLK cycles the PCI slave keeps a non-accessed
  67500. +* read buffers (non-completed delayed read) before invalidate the buffer.
  67501. +* Set to '0' to disable the timer. The PCI slave waits for delayed
  67502. +* read completion forever.
  67503. +* In PCI-X mode:
  67504. +* Specifies the number of PCLK cycles the PCI master waits for split
  67505. +* completion transaction, before it invalidates the pre-allocated read
  67506. +* buffer.
  67507. +* Set to '0' to disable the timer. The PCI master waits for split
  67508. +* completion forever.
  67509. +* NOTE: Must be set to a number greater than MV_PCI_MAX_DISCARD_CLK,
  67510. +* unless using the "wait for ever" setting 0x0.
  67511. +* NOTE: Must not be updated while there are pending read requests.
  67512. +*
  67513. +* INPUT:
  67514. +* pciIf - PCI interface number.
  67515. +* pClkCycles - Number of PCI clock cycles.
  67516. +*
  67517. +* OUTPUT:
  67518. +* None.
  67519. +*
  67520. +* RETURN:
  67521. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67522. +*
  67523. +*******************************************************************************/
  67524. +MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles)
  67525. +{
  67526. + MV_U32 pciDiscardTimer;
  67527. +
  67528. + /* Parameter checking */
  67529. + if (pciIf >= mvCtrlPciMaxIfGet())
  67530. + {
  67531. + mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid PCI interface %d\n",
  67532. + pciIf);
  67533. + return MV_BAD_PARAM;
  67534. + }
  67535. +
  67536. + if (pClkCycles >= PDTR_TIMER_MIN)
  67537. + {
  67538. + mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid Clk value: %d\n",
  67539. + pClkCycles);
  67540. + return MV_BAD_PARAM;
  67541. +
  67542. + }
  67543. +
  67544. + /* Read PCI Discard Timer */
  67545. + pciDiscardTimer = MV_REG_READ(PCI_DISCARD_TIMER_REG(pciIf));
  67546. +
  67547. + pciDiscardTimer &= ~PDTR_TIMER_MASK;
  67548. +
  67549. + pciDiscardTimer |= (pClkCycles << PDTR_TIMER_OFFS);
  67550. +
  67551. + /* Write new value */
  67552. + MV_REG_WRITE(PCI_DISCARD_TIMER_REG(pciIf), pciDiscardTimer);
  67553. +
  67554. + return MV_OK;
  67555. +
  67556. +}
  67557. +
  67558. +/* PCI Arbiter routines */
  67559. +
  67560. +/*******************************************************************************
  67561. +* mvPciArbEnable - PCI arbiter enable/disable
  67562. +*
  67563. +* DESCRIPTION:
  67564. +* This fuction enable/disables a given PCI interface arbiter.
  67565. +* NOTE: Arbiter setting can not be changed while in work. It should only
  67566. +* be set once.
  67567. +* INPUT:
  67568. +* pciIf - PCI interface number.
  67569. +* enable - Enable/disable parameter. If enable = MV_TRUE then enable.
  67570. +*
  67571. +* OUTPUT:
  67572. +* None.
  67573. +*
  67574. +* RETURN:
  67575. +* None.
  67576. +*
  67577. +*******************************************************************************/
  67578. +MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable)
  67579. +{
  67580. + MV_U32 regVal;
  67581. +
  67582. + /* Parameter checking */
  67583. + if (pciIf >= mvCtrlPciMaxIfGet())
  67584. + {
  67585. + mvOsPrintf("mvPciArbEnable: ERR. Invalid PCI interface %d\n", pciIf);
  67586. + return MV_ERROR;
  67587. + }
  67588. +
  67589. + /* Set PCI Arbiter Control register according to default configuration */
  67590. + regVal = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
  67591. +
  67592. + /* Make sure arbiter disabled before changing its values */
  67593. + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
  67594. +
  67595. + regVal &= ~PCI_ARBITER_CTRL_DEFAULT_MASK;
  67596. +
  67597. + regVal |= PCI_ARBITER_CTRL_DEFAULT; /* Set default configuration */
  67598. +
  67599. + if (MV_TRUE == enable)
  67600. + {
  67601. + regVal |= PACR_ARB_ENABLE;
  67602. + }
  67603. + else
  67604. + {
  67605. + regVal &= ~PACR_ARB_ENABLE;
  67606. + }
  67607. +
  67608. + /* Write to register */
  67609. + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), regVal);
  67610. +
  67611. + return MV_OK;
  67612. +}
  67613. +
  67614. +
  67615. +/*******************************************************************************
  67616. +* mvPciArbParkDis - Disable arbiter parking on agent
  67617. +*
  67618. +* DESCRIPTION:
  67619. +* This function disables the PCI arbiter from parking on the given agent
  67620. +* list.
  67621. +*
  67622. +* INPUT:
  67623. +* pciIf - PCI interface number.
  67624. +* pciAgentMask - When a bit in the mask is set to '1', parking on
  67625. +* the associated PCI master is disabled. Mask bit
  67626. +* refers to bit 0 - 6. For example disable parking on PCI
  67627. +* agent 3 set pciAgentMask 0x4 (bit 3 is set).
  67628. +*
  67629. +* OUTPUT:
  67630. +* None.
  67631. +*
  67632. +* RETURN:
  67633. +* None.
  67634. +*
  67635. +*******************************************************************************/
  67636. +MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask)
  67637. +{
  67638. + MV_U32 pciArbiterCtrl;
  67639. +
  67640. + /* Parameter checking */
  67641. + if (pciIf >= mvCtrlPciMaxIfGet())
  67642. + {
  67643. + mvOsPrintf("mvPciArbParkDis: ERR. Invalid PCI interface %d\n", pciIf);
  67644. + return MV_ERROR;
  67645. + }
  67646. +
  67647. + /* Reading Arbiter Control register */
  67648. + pciArbiterCtrl = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
  67649. +
  67650. + /* Arbiter must be disabled before changing parking */
  67651. + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
  67652. +
  67653. + /* do the change */
  67654. + pciArbiterCtrl &= ~PACR_PARK_DIS_MASK;
  67655. + pciArbiterCtrl |= (pciAgentMask << PACR_PARK_DIS_OFFS);
  67656. +
  67657. + /* writing new value ( if th earbiter was enabled before the change */
  67658. + /* here it will be reenabled */
  67659. + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);
  67660. +
  67661. + return MV_OK;
  67662. +}
  67663. +
  67664. +
  67665. +/*******************************************************************************
  67666. +* mvPciArbBrokDetectSet - Set PCI arbiter broken detection
  67667. +*
  67668. +* DESCRIPTION:
  67669. +* This function sets the maximum number of cycles that the arbiter
  67670. +* waits for a PCI master to respond to its grant assertion. If a
  67671. +* PCI agent fails to respond within this time, the PCI arbiter aborts
  67672. +* the transaction and performs a new arbitration cycle.
  67673. +* NOTE: Value must be greater than '1' for conventional PCI and
  67674. +* greater than '5' for PCI-X.
  67675. +*
  67676. +* INPUT:
  67677. +* pciIf - PCI interface number.
  67678. +* pClkCycles - Number of PCI clock cycles. If equal to '0' the broken
  67679. +* master detection is disabled.
  67680. +*
  67681. +* OUTPUT:
  67682. +* None.
  67683. +*
  67684. +* RETURN:
  67685. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67686. +*
  67687. +*******************************************************************************/
  67688. +MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles)
  67689. +{
  67690. + MV_U32 pciArbiterCtrl;
  67691. + MV_U32 pciMode;
  67692. +
  67693. + /* Parameter checking */
  67694. + if (pciIf >= mvCtrlPciMaxIfGet())
  67695. + {
  67696. + mvOsPrintf("mvPciArbBrokDetectSet: ERR. Invalid PCI interface %d\n",
  67697. + pciIf);
  67698. + return MV_BAD_PARAM;
  67699. + }
  67700. +
  67701. + /* Checking PCI mode and if pClkCycles is legal value */
  67702. + pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));
  67703. + pciMode &= PMR_PCI_MODE_MASK;
  67704. +
  67705. + if (PMR_PCI_MODE_CONV == pciMode)
  67706. + {
  67707. + if (pClkCycles < PACR_BROKEN_VAL_CONV_MIN)
  67708. + return MV_ERROR;
  67709. + }
  67710. + else
  67711. + {
  67712. + if (pClkCycles < PACR_BROKEN_VAL_PCIX_MIN)
  67713. + return MV_ERROR;
  67714. + }
  67715. +
  67716. + pClkCycles <<= PACR_BROKEN_VAL_OFFS;
  67717. +
  67718. + /* Reading Arbiter Control register */
  67719. + pciArbiterCtrl = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
  67720. + pciArbiterCtrl &= ~PACR_BROKEN_VAL_MASK;
  67721. + pciArbiterCtrl |= pClkCycles;
  67722. +
  67723. + /* Arbiter must be disabled before changing broken detection */
  67724. + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
  67725. +
  67726. + /* writing new value ( if th earbiter was enabled before the change */
  67727. + /* here it will be reenabled */
  67728. +
  67729. + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);
  67730. +
  67731. + return MV_OK;
  67732. +}
  67733. +
  67734. +/* PCI configuration space read write */
  67735. +
  67736. +/*******************************************************************************
  67737. +* mvPciConfigRead - Read from configuration space
  67738. +*
  67739. +* DESCRIPTION:
  67740. +* This function performs a 32 bit read from PCI configuration space.
  67741. +* It supports both type 0 and type 1 of Configuration Transactions
  67742. +* (local and over bridge). In order to read from local bus segment, use
  67743. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  67744. +* will result configuration transaction of type 1 (over bridge).
  67745. +*
  67746. +* INPUT:
  67747. +* pciIf - PCI interface number.
  67748. +* bus - PCI segment bus number.
  67749. +* dev - PCI device number.
  67750. +* func - Function number.
  67751. +* regOffs - Register offset.
  67752. +*
  67753. +* OUTPUT:
  67754. +* None.
  67755. +*
  67756. +* RETURN:
  67757. +* 32bit register data, 0xffffffff on error
  67758. +*
  67759. +*******************************************************************************/
  67760. +MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  67761. + MV_U32 regOff)
  67762. +{
  67763. + MV_U32 pciData = 0;
  67764. +
  67765. + /* Parameter checking */
  67766. + if (PCI_DEFAULT_IF != pciIf)
  67767. + {
  67768. + if (pciIf >= mvCtrlPciMaxIfGet())
  67769. + {
  67770. + mvOsPrintf("mvPciConfigRead: ERR. Invalid PCI interface %d\n",pciIf);
  67771. + return 0xFFFFFFFF;
  67772. + }
  67773. + }
  67774. +
  67775. + if (dev >= MAX_PCI_DEVICES)
  67776. + {
  67777. + DB(mvOsPrintf("mvPciConfigRead: ERR. device number illigal %d\n", dev));
  67778. + return 0xFFFFFFFF;
  67779. + }
  67780. +
  67781. + if (func >= MAX_PCI_FUNCS)
  67782. + {
  67783. + DB(mvOsPrintf("mvPciConfigRead: ERR. function number illigal %d\n", func));
  67784. + return 0xFFFFFFFF;
  67785. + }
  67786. +
  67787. + if (bus >= MAX_PCI_BUSSES)
  67788. + {
  67789. + DB(mvOsPrintf("mvPciConfigRead: ERR. bus number illigal %d\n", bus));
  67790. + return MV_ERROR;
  67791. + }
  67792. +
  67793. +
  67794. + /* Creating PCI address to be passed */
  67795. + pciData |= (bus << PCAR_BUS_NUM_OFFS);
  67796. + pciData |= (dev << PCAR_DEVICE_NUM_OFFS);
  67797. + pciData |= (func << PCAR_FUNC_NUM_OFFS);
  67798. + pciData |= (regOff & PCAR_REG_NUM_MASK);
  67799. +
  67800. + pciData |= PCAR_CONFIG_EN;
  67801. +
  67802. + /* Write the address to the PCI configuration address register */
  67803. + MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);
  67804. +
  67805. + /* In order to let the PCI controller absorbed the address of the read */
  67806. + /* transaction we perform a validity check that the address was written */
  67807. + if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))
  67808. + {
  67809. + return MV_ERROR;
  67810. + }
  67811. + /* Read the Data returned in the PCI Data register */
  67812. + pciData = MV_REG_READ(PCI_CONFIG_DATA_REG(pciIf));
  67813. +
  67814. + return pciData;
  67815. +}
  67816. +
  67817. +/*******************************************************************************
  67818. +* mvPciConfigWrite - Write to configuration space
  67819. +*
  67820. +* DESCRIPTION:
  67821. +* This function performs a 32 bit write to PCI configuration space.
  67822. +* It supports both type 0 and type 1 of Configuration Transactions
  67823. +* (local and over bridge). In order to write to local bus segment, use
  67824. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  67825. +* will result configuration transaction of type 1 (over bridge).
  67826. +*
  67827. +* INPUT:
  67828. +* pciIf - PCI interface number.
  67829. +* bus - PCI segment bus number.
  67830. +* dev - PCI device number.
  67831. +* func - Function number.
  67832. +* regOffs - Register offset.
  67833. +* data - 32bit data.
  67834. +*
  67835. +* OUTPUT:
  67836. +* None.
  67837. +*
  67838. +* RETURN:
  67839. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67840. +*
  67841. +*******************************************************************************/
  67842. +MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  67843. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  67844. +{
  67845. + MV_U32 pciData = 0;
  67846. +
  67847. + /* Parameter checking */
  67848. + if (PCI_DEFAULT_IF != pciIf)
  67849. + {
  67850. + if (pciIf >= mvCtrlPciMaxIfGet())
  67851. + {
  67852. + mvOsPrintf("mvPciConfigWrite: ERR. Invalid PCI interface %d\n",
  67853. + pciIf);
  67854. + return 0xFFFFFFFF;
  67855. + }
  67856. + }
  67857. +
  67858. + if (dev >= MAX_PCI_DEVICES)
  67859. + {
  67860. + mvOsPrintf("mvPciConfigWrite: ERR. device number illigal %d\n",dev);
  67861. + return MV_BAD_PARAM;
  67862. + }
  67863. +
  67864. + if (func >= MAX_PCI_FUNCS)
  67865. + {
  67866. + mvOsPrintf("mvPciConfigWrite: ERR. function number illigal %d\n", func);
  67867. + return MV_ERROR;
  67868. + }
  67869. +
  67870. + if (bus >= MAX_PCI_BUSSES)
  67871. + {
  67872. + mvOsPrintf("mvPciConfigWrite: ERR. bus number illigal %d\n", bus);
  67873. + return MV_ERROR;
  67874. + }
  67875. +
  67876. + /* Creating PCI address to be passed */
  67877. + pciData |= (bus << PCAR_BUS_NUM_OFFS);
  67878. + pciData |= (dev << PCAR_DEVICE_NUM_OFFS);
  67879. + pciData |= (func << PCAR_FUNC_NUM_OFFS);
  67880. + pciData |= (regOff & PCAR_REG_NUM_MASK);
  67881. +
  67882. + pciData |= PCAR_CONFIG_EN;
  67883. +
  67884. + /* Write the address to the PCI configuration address register */
  67885. + MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);
  67886. +
  67887. + /* In order to let the PCI controller absorbed the address of the read */
  67888. + /* transaction we perform a validity check that the address was written */
  67889. + if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))
  67890. + {
  67891. + return MV_ERROR;
  67892. + }
  67893. +
  67894. + /* Write the Data passed to the PCI Data register */
  67895. + MV_REG_WRITE(PCI_CONFIG_DATA_REG(pciIf), data);
  67896. +
  67897. + return MV_OK;
  67898. +}
  67899. +
  67900. +/*******************************************************************************
  67901. +* mvPciMasterEnable - Enable/disale PCI interface master transactions.
  67902. +*
  67903. +* DESCRIPTION:
  67904. +* This function performs read modified write to PCI command status
  67905. +* (offset 0x4) to set/reset bit 2. After this bit is set, the PCI
  67906. +* master is allowed to gain ownership on the bus, otherwise it is
  67907. +* incapable to do so.
  67908. +*
  67909. +* INPUT:
  67910. +* pciIf - PCI interface number.
  67911. +* enable - Enable/disable parameter.
  67912. +*
  67913. +* OUTPUT:
  67914. +* None.
  67915. +*
  67916. +* RETURN:
  67917. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67918. +*
  67919. +*******************************************************************************/
  67920. +MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable)
  67921. +{
  67922. + MV_U32 pciCommandStatus;
  67923. + MV_U32 RegOffs;
  67924. + MV_U32 localBus;
  67925. + MV_U32 localDev;
  67926. +
  67927. + /* Parameter checking */
  67928. + if (pciIf >= mvCtrlPciMaxIfGet())
  67929. + {
  67930. + mvOsPrintf("mvPciMasterEnable: ERR. Invalid PCI interface %d\n", pciIf);
  67931. + return MV_ERROR;
  67932. + }
  67933. +
  67934. + localBus = mvPciLocalBusNumGet(pciIf);
  67935. + localDev = mvPciLocalDevNumGet(pciIf);
  67936. +
  67937. + RegOffs = PCI_STATUS_AND_COMMAND;
  67938. +
  67939. + pciCommandStatus = mvPciConfigRead(pciIf, localBus, localDev, 0, RegOffs);
  67940. +
  67941. + if (MV_TRUE == enable)
  67942. + {
  67943. + pciCommandStatus |= PSCR_MASTER_EN;
  67944. + }
  67945. + else
  67946. + {
  67947. + pciCommandStatus &= ~PSCR_MASTER_EN;
  67948. + }
  67949. +
  67950. + mvPciConfigWrite(pciIf, localBus, localDev, 0, RegOffs, pciCommandStatus);
  67951. +
  67952. + return MV_OK;
  67953. +}
  67954. +
  67955. +
  67956. +/*******************************************************************************
  67957. +* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.
  67958. +*
  67959. +* DESCRIPTION:
  67960. +* This function performs read modified write to PCI command status
  67961. +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
  67962. +* the PCI slave is allowed to respond to PCI IO space access (bit 0)
  67963. +* and PCI memory space access (bit 1).
  67964. +*
  67965. +* INPUT:
  67966. +* pciIf - PCI interface number.
  67967. +* dev - PCI device number.
  67968. +* enable - Enable/disable parameter.
  67969. +*
  67970. +* OUTPUT:
  67971. +* None.
  67972. +*
  67973. +* RETURN:
  67974. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67975. +*
  67976. +*******************************************************************************/
  67977. +MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_BOOL enable)
  67978. +{
  67979. + MV_U32 pciCommandStatus;
  67980. + MV_U32 RegOffs;
  67981. +
  67982. + /* Parameter checking */
  67983. + if (pciIf >= mvCtrlPciMaxIfGet())
  67984. + {
  67985. + mvOsPrintf("mvPciSlaveEnable: ERR. Invalid PCI interface %d\n", pciIf);
  67986. + return MV_BAD_PARAM;
  67987. + }
  67988. + if (dev >= MAX_PCI_DEVICES)
  67989. + {
  67990. + mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n", dev);
  67991. + return MV_BAD_PARAM;
  67992. +
  67993. + }
  67994. +
  67995. + RegOffs = PCI_STATUS_AND_COMMAND;
  67996. +
  67997. + pciCommandStatus=mvPciConfigRead(pciIf, bus, dev, 0, RegOffs);
  67998. +
  67999. + if (MV_TRUE == enable)
  68000. + {
  68001. + pciCommandStatus |= (PSCR_IO_EN | PSCR_MEM_EN);
  68002. + }
  68003. + else
  68004. + {
  68005. + pciCommandStatus &= ~(PSCR_IO_EN | PSCR_MEM_EN);
  68006. + }
  68007. +
  68008. + mvPciConfigWrite(pciIf, bus, dev, 0, RegOffs, pciCommandStatus);
  68009. +
  68010. + return MV_OK;
  68011. +}
  68012. +
  68013. +/*******************************************************************************
  68014. +* mvPciLocalBusNumSet - Set PCI interface local bus number.
  68015. +*
  68016. +* DESCRIPTION:
  68017. +* This function sets given PCI interface its local bus number.
  68018. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  68019. +*
  68020. +* INPUT:
  68021. +* pciIf - PCI interface number.
  68022. +* busNum - Bus number.
  68023. +*
  68024. +* OUTPUT:
  68025. +* None.
  68026. +*
  68027. +* RETURN:
  68028. +* MV_NOT_ALLOWED in case PCI interface is PCI-X.
  68029. +* MV_BAD_PARAM on bad parameters ,
  68030. +* otherwise MV_OK
  68031. +*
  68032. +*******************************************************************************/
  68033. +MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)
  68034. +{
  68035. + MV_U32 pciP2PConfig;
  68036. + MV_PCI_MODE pciMode;
  68037. + MV_U32 localBus;
  68038. + MV_U32 localDev;
  68039. +
  68040. +
  68041. + /* Parameter checking */
  68042. + if (pciIf >= mvCtrlPciMaxIfGet())
  68043. + {
  68044. + mvOsPrintf("mvPciLocalBusNumSet: ERR. Invalid PCI interface %d\n",pciIf);
  68045. + return MV_BAD_PARAM;
  68046. + }
  68047. + if (busNum >= MAX_PCI_BUSSES)
  68048. + {
  68049. + mvOsPrintf("mvPciLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
  68050. + return MV_ERROR;
  68051. +
  68052. + }
  68053. +
  68054. + localBus = mvPciLocalBusNumGet(pciIf);
  68055. + localDev = mvPciLocalDevNumGet(pciIf);
  68056. +
  68057. +
  68058. + /* PCI interface mode */
  68059. + mvPciModeGet(pciIf, &pciMode);
  68060. +
  68061. + /* if PCI type is PCI-X then it is not allowed to change the dev number */
  68062. + if (MV_PCIX == pciMode.pciType)
  68063. + {
  68064. + pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );
  68065. +
  68066. + pciP2PConfig &= ~PXS_BN_MASK;
  68067. +
  68068. + pciP2PConfig |= (busNum << PXS_BN_OFFS) & PXS_BN_MASK;
  68069. +
  68070. + mvPciConfigWrite(pciIf, localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );
  68071. +
  68072. + }
  68073. + else
  68074. + {
  68075. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  68076. +
  68077. + pciP2PConfig &= ~PPCR_BUS_NUM_MASK;
  68078. +
  68079. + pciP2PConfig |= (busNum << PPCR_BUS_NUM_OFFS) & PPCR_BUS_NUM_MASK;
  68080. +
  68081. + MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);
  68082. +
  68083. + }
  68084. +
  68085. +
  68086. + return MV_OK;
  68087. +}
  68088. +
  68089. +
  68090. +/*******************************************************************************
  68091. +* mvPciLocalBusNumGet - Get PCI interface local bus number.
  68092. +*
  68093. +* DESCRIPTION:
  68094. +* This function gets the local bus number of a given PCI interface.
  68095. +*
  68096. +* INPUT:
  68097. +* pciIf - PCI interface number.
  68098. +*
  68099. +* OUTPUT:
  68100. +* None.
  68101. +*
  68102. +* RETURN:
  68103. +* Local bus number.0xffffffff on Error
  68104. +*
  68105. +*******************************************************************************/
  68106. +MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf)
  68107. +{
  68108. + MV_U32 pciP2PConfig;
  68109. +
  68110. + /* Parameter checking */
  68111. + if (PCI_DEFAULT_IF != pciIf)
  68112. + {
  68113. + if (pciIf >= mvCtrlPciMaxIfGet())
  68114. + {
  68115. + mvOsPrintf("mvPciLocalBusNumGet: ERR. Invalid PCI interface %d\n",
  68116. + pciIf);
  68117. + return 0xFFFFFFFF;
  68118. + }
  68119. + }
  68120. +
  68121. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  68122. + pciP2PConfig &= PPCR_BUS_NUM_MASK;
  68123. + return (pciP2PConfig >> PPCR_BUS_NUM_OFFS);
  68124. +}
  68125. +
  68126. +
  68127. +/*******************************************************************************
  68128. +* mvPciLocalDevNumSet - Set PCI interface local device number.
  68129. +*
  68130. +* DESCRIPTION:
  68131. +* This function sets given PCI interface its local device number.
  68132. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  68133. +*
  68134. +* INPUT:
  68135. +* pciIf - PCI interface number.
  68136. +* devNum - Device number.
  68137. +*
  68138. +* OUTPUT:
  68139. +* None.
  68140. +*
  68141. +* RETURN:
  68142. +* MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,
  68143. +* otherwise MV_OK
  68144. +*
  68145. +*******************************************************************************/
  68146. +MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)
  68147. +{
  68148. + MV_U32 pciP2PConfig;
  68149. + MV_PCI_MODE pciMode;
  68150. + MV_U32 localBus;
  68151. + MV_U32 localDev;
  68152. +
  68153. + /* Parameter checking */
  68154. + if (pciIf >= mvCtrlPciMaxIfGet())
  68155. + {
  68156. + mvOsPrintf("mvPciLocalDevNumSet: ERR. Invalid PCI interface %d\n",pciIf);
  68157. + return MV_BAD_PARAM;
  68158. + }
  68159. + if (devNum >= MAX_PCI_DEVICES)
  68160. + {
  68161. + mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n",
  68162. + devNum);
  68163. + return MV_BAD_PARAM;
  68164. +
  68165. + }
  68166. +
  68167. + localBus = mvPciLocalBusNumGet(pciIf);
  68168. + localDev = mvPciLocalDevNumGet(pciIf);
  68169. +
  68170. + /* PCI interface mode */
  68171. + mvPciModeGet(pciIf, &pciMode);
  68172. +
  68173. + /* if PCI type is PCIX then it is not allowed to change the dev number */
  68174. + if (MV_PCIX == pciMode.pciType)
  68175. + {
  68176. + pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );
  68177. +
  68178. + pciP2PConfig &= ~PXS_DN_MASK;
  68179. +
  68180. + pciP2PConfig |= (devNum << PXS_DN_OFFS) & PXS_DN_MASK;
  68181. +
  68182. + mvPciConfigWrite(pciIf,localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );
  68183. + }
  68184. + else
  68185. + {
  68186. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  68187. +
  68188. + pciP2PConfig &= ~PPCR_DEV_NUM_MASK;
  68189. +
  68190. + pciP2PConfig |= (devNum << PPCR_DEV_NUM_OFFS) & PPCR_DEV_NUM_MASK;
  68191. +
  68192. + MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);
  68193. + }
  68194. +
  68195. + return MV_OK;
  68196. +}
  68197. +
  68198. +/*******************************************************************************
  68199. +* mvPciLocalDevNumGet - Get PCI interface local device number.
  68200. +*
  68201. +* DESCRIPTION:
  68202. +* This function gets the local device number of a given PCI interface.
  68203. +*
  68204. +* INPUT:
  68205. +* pciIf - PCI interface number.
  68206. +*
  68207. +* OUTPUT:
  68208. +* None.
  68209. +*
  68210. +* RETURN:
  68211. +* Local device number. 0xffffffff on Error
  68212. +*
  68213. +*******************************************************************************/
  68214. +MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf)
  68215. +{
  68216. + MV_U32 pciP2PConfig;
  68217. +
  68218. + /* Parameter checking */
  68219. +
  68220. + if (PCI_DEFAULT_IF != pciIf)
  68221. + {
  68222. + if (pciIf >= mvCtrlPciMaxIfGet())
  68223. + {
  68224. + mvOsPrintf("mvPciLocalDevNumGet: ERR. Invalid PCI interface %d\n",
  68225. + pciIf);
  68226. + return 0xFFFFFFFF;
  68227. + }
  68228. + }
  68229. +
  68230. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  68231. +
  68232. + pciP2PConfig &= PPCR_DEV_NUM_MASK;
  68233. +
  68234. + return (pciP2PConfig >> PPCR_DEV_NUM_OFFS);
  68235. +}
  68236. +
  68237. +
  68238. +
  68239. +
  68240. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h
  68241. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h 1970-01-01 01:00:00.000000000 +0100
  68242. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h 2010-11-09 20:28:11.412495457 +0100
  68243. @@ -0,0 +1,185 @@
  68244. +/*******************************************************************************
  68245. +Copyright (C) Marvell International Ltd. and its affiliates
  68246. +
  68247. +This software file (the "File") is owned and distributed by Marvell
  68248. +International Ltd. and/or its affiliates ("Marvell") under the following
  68249. +alternative licensing terms. Once you have made an election to distribute the
  68250. +File under one of the following license alternatives, please (i) delete this
  68251. +introductory statement regarding license alternatives, (ii) delete the two
  68252. +license alternatives that you have not elected to use and (iii) preserve the
  68253. +Marvell copyright notice above.
  68254. +
  68255. +********************************************************************************
  68256. +Marvell Commercial License Option
  68257. +
  68258. +If you received this File from Marvell and you have entered into a commercial
  68259. +license agreement (a "Commercial License") with Marvell, the File is licensed
  68260. +to you under the terms of the applicable Commercial License.
  68261. +
  68262. +********************************************************************************
  68263. +Marvell GPL License Option
  68264. +
  68265. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68266. +modify this File in accordance with the terms and conditions of the General
  68267. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  68268. +available along with the File in the license.txt file or by writing to the Free
  68269. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  68270. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  68271. +
  68272. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  68273. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  68274. +DISCLAIMED. The GPL License provides additional details about this warranty
  68275. +disclaimer.
  68276. +********************************************************************************
  68277. +Marvell BSD License Option
  68278. +
  68279. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68280. +modify this File under the following licensing terms.
  68281. +Redistribution and use in source and binary forms, with or without modification,
  68282. +are permitted provided that the following conditions are met:
  68283. +
  68284. + * Redistributions of source code must retain the above copyright notice,
  68285. + this list of conditions and the following disclaimer.
  68286. +
  68287. + * Redistributions in binary form must reproduce the above copyright
  68288. + notice, this list of conditions and the following disclaimer in the
  68289. + documentation and/or other materials provided with the distribution.
  68290. +
  68291. + * Neither the name of Marvell nor the names of its contributors may be
  68292. + used to endorse or promote products derived from this software without
  68293. + specific prior written permission.
  68294. +
  68295. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  68296. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  68297. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  68298. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  68299. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  68300. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  68301. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  68302. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  68303. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  68304. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  68305. +
  68306. +*******************************************************************************/
  68307. +
  68308. +
  68309. +#ifndef __INCPCIH
  68310. +#define __INCPCIH
  68311. +
  68312. +#include "mvCommon.h"
  68313. +#include "mvOs.h"
  68314. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  68315. +#include "pci/mvPciRegs.h"
  68316. +
  68317. +
  68318. +/* NOTE not supported in this driver:
  68319. +
  68320. + Built In Self Test (BIST)
  68321. + Vital Product Data (VPD)
  68322. + Message Signaled Interrupt (MSI)
  68323. + Power Management
  68324. + Compact PCI Hot Swap
  68325. + Header retarget
  68326. +
  68327. +Registers not supported:
  68328. +1) PCI DLL Status and Control (PCI0 0x1D20, PCI1 0x1DA0)
  68329. +2) PCI/MPP Pads Calibration (CI0/MPP[31:16] 0x1D1C, PCI1/MPP[15:0] 0X1D9C)
  68330. +*/
  68331. +
  68332. +/* defines */
  68333. +/* The number of supported PCI interfaces depend on Marvell controller */
  68334. +/* device number. This device number ID is located on the PCI unit */
  68335. +/* configuration header. This creates a loop where calling PCI */
  68336. +/* configuration read/write routine results a call to get PCI configuration */
  68337. +/* information etc. This macro defines a default PCI interface. This PCI */
  68338. +/* interface is sure to exist. */
  68339. +#define PCI_DEFAULT_IF 0
  68340. +
  68341. +
  68342. +/* typedefs */
  68343. +/* The Marvell controller supports both conventional PCI and PCI-X. */
  68344. +/* This enumeration describes the PCI type. */
  68345. +typedef enum _mvPciType
  68346. +{
  68347. + MV_PCI_CONV, /* Conventional PCI */
  68348. + MV_PCIX /* PCI-X */
  68349. +}MV_PCI_TYPE;
  68350. +
  68351. +typedef enum _mvPciMod
  68352. +{
  68353. + MV_PCI_MOD_HOST,
  68354. + MV_PCI_MOD_DEVICE
  68355. +}MV_PCI_MOD;
  68356. +
  68357. +
  68358. +/* The Marvell controller supports both PCI width of 32 and 64 bit. */
  68359. +/* This enumerator describes PCI width */
  68360. +typedef enum _mvPciWidth
  68361. +{
  68362. + MV_PCI_32, /* PCI width 32bit */
  68363. + MV_PCI_64 /* PCI width 64bit */
  68364. +}MV_PCI_WIDTH;
  68365. +
  68366. +/* This structure describes the PCI unit configured type, speed and width. */
  68367. +typedef struct _mvPciMode
  68368. +{
  68369. + MV_PCI_TYPE pciType; /* PCI type */
  68370. + MV_U32 pciSpeed; /* Assuming PCI base clock on board is 33MHz */
  68371. + MV_PCI_WIDTH pciWidth; /* PCI bus width */
  68372. +}MV_PCI_MODE;
  68373. +
  68374. +/* mvPciInit - Initialize PCI interfaces*/
  68375. +MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod);
  68376. +
  68377. +/* mvPciCommandSet - Set PCI comman register value.*/
  68378. +MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command);
  68379. +
  68380. +/* mvPciModeGet - Get PCI interface mode.*/
  68381. +MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode);
  68382. +
  68383. +/* mvPciRetrySet - Set PCI retry counters*/
  68384. +MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter);
  68385. +
  68386. +/* mvPciDiscardTimerSet - Set PCI discard timer*/
  68387. +MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles);
  68388. +
  68389. +/* mvPciArbEnable - PCI arbiter enable/disable*/
  68390. +MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable);
  68391. +
  68392. +/* mvPciArbParkDis - Disable arbiter parking on agent */
  68393. +MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask);
  68394. +
  68395. +/* mvPciArbBrokDetectSet - Set PCI arbiter broken detection */
  68396. +MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles);
  68397. +
  68398. +/* mvPciConfigRead - Read from configuration space */
  68399. +MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  68400. + MV_U32 func,MV_U32 regOff);
  68401. +
  68402. +/* mvPciConfigWrite - Write to configuration space */
  68403. +MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  68404. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  68405. +
  68406. +/* mvPciMasterEnable - Enable/disale PCI interface master transactions.*/
  68407. +MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable);
  68408. +
  68409. +/* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.*/
  68410. +MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,MV_BOOL enable);
  68411. +
  68412. +/* mvPciLocalBusNumSet - Set PCI interface local bus number.*/
  68413. +MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);
  68414. +
  68415. +/* mvPciLocalBusNumGet - Get PCI interface local bus number.*/
  68416. +MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf);
  68417. +
  68418. +/* mvPciLocalDevNumSet - Set PCI interface local device number.*/
  68419. +MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);
  68420. +
  68421. +/* mvPciLocalDevNumGet - Get PCI interface local device number.*/
  68422. +MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf);
  68423. +
  68424. +
  68425. +#endif /* #ifndef __INCPCIH */
  68426. +
  68427. +
  68428. +
  68429. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h
  68430. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h 1970-01-01 01:00:00.000000000 +0100
  68431. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h 2010-11-09 20:28:11.452495500 +0100
  68432. @@ -0,0 +1,411 @@
  68433. +/*******************************************************************************
  68434. +Copyright (C) Marvell International Ltd. and its affiliates
  68435. +
  68436. +This software file (the "File") is owned and distributed by Marvell
  68437. +International Ltd. and/or its affiliates ("Marvell") under the following
  68438. +alternative licensing terms. Once you have made an election to distribute the
  68439. +File under one of the following license alternatives, please (i) delete this
  68440. +introductory statement regarding license alternatives, (ii) delete the two
  68441. +license alternatives that you have not elected to use and (iii) preserve the
  68442. +Marvell copyright notice above.
  68443. +
  68444. +********************************************************************************
  68445. +Marvell Commercial License Option
  68446. +
  68447. +If you received this File from Marvell and you have entered into a commercial
  68448. +license agreement (a "Commercial License") with Marvell, the File is licensed
  68449. +to you under the terms of the applicable Commercial License.
  68450. +
  68451. +********************************************************************************
  68452. +Marvell GPL License Option
  68453. +
  68454. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68455. +modify this File in accordance with the terms and conditions of the General
  68456. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  68457. +available along with the File in the license.txt file or by writing to the Free
  68458. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  68459. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  68460. +
  68461. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  68462. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  68463. +DISCLAIMED. The GPL License provides additional details about this warranty
  68464. +disclaimer.
  68465. +********************************************************************************
  68466. +Marvell BSD License Option
  68467. +
  68468. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68469. +modify this File under the following licensing terms.
  68470. +Redistribution and use in source and binary forms, with or without modification,
  68471. +are permitted provided that the following conditions are met:
  68472. +
  68473. + * Redistributions of source code must retain the above copyright notice,
  68474. + this list of conditions and the following disclaimer.
  68475. +
  68476. + * Redistributions in binary form must reproduce the above copyright
  68477. + notice, this list of conditions and the following disclaimer in the
  68478. + documentation and/or other materials provided with the distribution.
  68479. +
  68480. + * Neither the name of Marvell nor the names of its contributors may be
  68481. + used to endorse or promote products derived from this software without
  68482. + specific prior written permission.
  68483. +
  68484. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  68485. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  68486. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  68487. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  68488. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  68489. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  68490. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  68491. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  68492. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  68493. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  68494. +
  68495. +*******************************************************************************/
  68496. +
  68497. +#ifndef __INCPCIREGSH
  68498. +#define __INCPCIREGSH
  68499. +
  68500. +
  68501. +#include "pci-if/mvPciIfRegs.h"
  68502. +/* defines */
  68503. +#define MAX_PCI_DEVICES 32
  68504. +#define MAX_PCI_FUNCS 8
  68505. +#define MAX_PCI_BUSSES 128
  68506. +
  68507. +/* enumerators */
  68508. +
  68509. +/* This enumerator described the possible PCI slave targets. */
  68510. +/* PCI slave targets are designated memory/IO address spaces that the */
  68511. +/* PCI slave targets can access. They are also refered as "targets" */
  68512. +/* this enumeratoe order is determined by the content of :
  68513. + PCI_BASE_ADDR_ENABLE_REG */
  68514. +
  68515. +
  68516. +/* registers offsetes defines */
  68517. +
  68518. +
  68519. +
  68520. +/*************************/
  68521. +/* PCI control registers */
  68522. +/*************************/
  68523. +/* maen : should add new registers */
  68524. +#define PCI_CMD_REG(pciIf) (0x30c00 + ((pciIf) * 0x80))
  68525. +#define PCI_MODE_REG(pciIf) (0x30d00 + ((pciIf) * 0x80))
  68526. +#define PCI_RETRY_REG(pciIf) (0x30c04 + ((pciIf) * 0x80))
  68527. +#define PCI_DISCARD_TIMER_REG(pciIf) (0x30d04 + ((pciIf) * 0x80))
  68528. +#define PCI_ARBITER_CTRL_REG(pciIf) (0x31d00 + ((pciIf) * 0x80))
  68529. +#define PCI_P2P_CONFIG_REG(pciIf) (0x31d14 + ((pciIf) * 0x80))
  68530. +#define PCI_ACCESS_CTRL_BASEL_REG(pciIf, targetWin) \
  68531. + (0x31e00 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
  68532. +#define PCI_ACCESS_CTRL_BASEH_REG(pciIf, targetWin) \
  68533. + (0x31e04 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
  68534. +#define PCI_ACCESS_CTRL_SIZE_REG(pciIf, targetWin) \
  68535. + (0x31e08 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
  68536. +
  68537. +#define PCI_DLL_CTRL_REG(pciIf) (0x31d20 + ((pciIf) * 0x80))
  68538. +
  68539. +/* PCI Dll Control (PDC)*/
  68540. +#define PDC_DLL_EN BIT0
  68541. +
  68542. +
  68543. +/* PCI Command Register (PCR) */
  68544. +#define PCR_MASTER_BYTE_SWAP_EN BIT0
  68545. +#define PCR_MASTER_WR_COMBINE_EN BIT4
  68546. +#define PCR_MASTER_RD_COMBINE_EN BIT5
  68547. +#define PCR_MASTER_WR_TRIG_WHOLE BIT6
  68548. +#define PCR_MASTER_RD_TRIG_WHOLE BIT7
  68549. +#define PCR_MASTER_MEM_RD_LINE_EN BIT8
  68550. +#define PCR_MASTER_MEM_RD_MULT_EN BIT9
  68551. +#define PCR_MASTER_WORD_SWAP_EN BIT10
  68552. +#define PCR_SLAVE_WORD_SWAP_EN BIT11
  68553. +#define PCR_NS_ACCORDING_RCV_TRANS BIT14
  68554. +#define PCR_MASTER_PCIX_REQ64N_EN BIT15
  68555. +#define PCR_SLAVE_BYTE_SWAP_EN BIT16
  68556. +#define PCR_MASTER_DAC_EN BIT17
  68557. +#define PCR_MASTER_M64_ALLIGN BIT18
  68558. +#define PCR_ERRORS_PROPAGATION_EN BIT19
  68559. +#define PCR_SLAVE_SWAP_ENABLE BIT20
  68560. +#define PCR_MASTER_SWAP_ENABLE BIT21
  68561. +#define PCR_MASTER_INT_SWAP_EN BIT22
  68562. +#define PCR_LOOP_BACK_ENABLE BIT23
  68563. +#define PCR_SLAVE_INTREG_SWAP_OFFS 24
  68564. +#define PCR_SLAVE_INTREG_SWAP_MASK 0x3
  68565. +#define PCR_SLAVE_INTREG_BYTE_SWAP \
  68566. + (MV_BYTE_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  68567. +#define PCR_SLAVE_INTREG_NO_SWAP \
  68568. + (MV_NO_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  68569. +#define PCR_SLAVE_INTREG_BYTE_WORD \
  68570. + (MV_BYTE_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  68571. +#define PCR_SLAVE_INTREG_WORD_SWAP \
  68572. + (MV_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  68573. +#define PCR_RESET_REASSERTION_EN BIT26
  68574. +#define PCR_PCI_TO_CPU_REG_ORDER_EN BIT28
  68575. +#define PCR_CPU_TO_PCI_ORDER_EN BIT29
  68576. +#define PCR_PCI_TO_CPU_ORDER_EN BIT30
  68577. +
  68578. +/* PCI Mode Register (PMR) */
  68579. +#define PMR_PCI_ID_OFFS 0 /* PCI Interface ID */
  68580. +#define PMR_PCI_ID_MASK (0x1 << PMR_PCI_ID_OFFS)
  68581. +#define PMR_PCI_ID_PCI(pciNum) ((pciNum) << PCI_MODE_PCIID_OFFS)
  68582. +
  68583. +#define PMR_PCI_64_OFFS 2 /* 64-bit PCI Interface */
  68584. +#define PMR_PCI_64_MASK (0x1 << PMR_PCI_64_OFFS)
  68585. +#define PMR_PCI_64_64BIT (0x1 << PMR_PCI_64_OFFS)
  68586. +#define PMR_PCI_64_32BIT (0x0 << PMR_PCI_64_OFFS)
  68587. +
  68588. +#define PMR_PCI_MODE_OFFS 4 /* PCI interface mode of operation */
  68589. +#define PMR_PCI_MODE_MASK (0x3 << PMR_PCI_MODE_OFFS)
  68590. +#define PMR_PCI_MODE_CONV (0x0 << PMR_PCI_MODE_OFFS)
  68591. +#define PMR_PCI_MODE_PCIX_66MHZ (0x1 << PMR_PCI_MODE_OFFS)
  68592. +#define PMR_PCI_MODE_PCIX_100MHZ (0x2 << PMR_PCI_MODE_OFFS)
  68593. +#define PMR_PCI_MODE_PCIX_133MHZ (0x3 << PMR_PCI_MODE_OFFS)
  68594. +
  68595. +#define PMR_EXP_ROM_SUPPORT BIT8 /* Expansion ROM Active */
  68596. +
  68597. +#define PMR_PCI_RESET_OFFS 31 /* PCI Interface Reset Indication */
  68598. +#define PMR_PCI_RESET_MASK (0x1 << PMR_PCI_RESET_OFFS)
  68599. +#define PMR_PCI_RESET_PCIXRST (0x0 << PMR_PCI_RESET_OFFS)
  68600. +
  68601. +
  68602. +/* PCI Retry Register (PRR) */
  68603. +#define PRR_RETRY_CNTR_OFFS 16 /* Retry Counter */
  68604. +#define PRR_RETRY_CNTR_MAX 0xff
  68605. +#define PRR_RETRY_CNTR_MASK (PRR_RETRY_CNTR_MAX << PRR_RETRY_CNTR_OFFS)
  68606. +
  68607. +
  68608. +/* PCI Discard Timer Register (PDTR) */
  68609. +#define PDTR_TIMER_OFFS 0 /* Timer */
  68610. +#define PDTR_TIMER_MAX 0xffff
  68611. +#define PDTR_TIMER_MIN 0x7F
  68612. +#define PDTR_TIMER_MASK (PDTR_TIMER_MAX << PDTR_TIMER_OFFS)
  68613. +
  68614. +
  68615. +/* PCI Arbiter Control Register (PACR) */
  68616. +#define PACR_BROKEN_DETECT_EN BIT1 /* Broken Detection Enable */
  68617. +
  68618. +#define PACR_BROKEN_VAL_OFFS 3 /* Broken Value */
  68619. +#define PACR_BROKEN_VAL_MASK (0xf << PACR_BROKEN_VAL_OFFS)
  68620. +#define PACR_BROKEN_VAL_CONV_MIN 0x2
  68621. +#define PACR_BROKEN_VAL_PCIX_MIN 0x6
  68622. +
  68623. +#define PACR_PARK_DIS_OFFS 14 /* Parking Disable */
  68624. +#define PACR_PARK_DIS_MAX_AGENT 0x3f
  68625. +#define PACR_PARK_DIS_MASK (PACR_PARK_DIS_MAX_AGENT<<PACR_PARK_DIS_OFFS)
  68626. +#define PACR_PARK_DIS(agent) ((1 << (agent)) << PACR_PARK_DIS_OFFS)
  68627. +
  68628. +#define PACR_ARB_ENABLE BIT31 /* Enable Internal Arbiter */
  68629. +
  68630. +
  68631. +/* PCI P2P Configuration Register (PPCR) */
  68632. +#define PPCR_2ND_BUS_L_OFFS 0 /* 2nd PCI Interface Bus Range Lower */
  68633. +#define PPCR_2ND_BUS_L_MASK (0xff << PPCR_2ND_BUS_L_OFFS)
  68634. +
  68635. +#define PPCR_2ND_BUS_H_OFFS 8 /* 2nd PCI Interface Bus Range Upper */
  68636. +#define PPCR_2ND_BUS_H_MASK (0xff << PPCR_2ND_BUS_H_OFFS)
  68637. +
  68638. +#define PPCR_BUS_NUM_OFFS 16 /* The PCI interface's Bus number */
  68639. +#define PPCR_BUS_NUM_MASK (0xff << PPCR_BUS_NUM_OFFS)
  68640. +
  68641. +#define PPCR_DEV_NUM_OFFS 24 /* The PCI interface’s Device number */
  68642. +#define PPCR_DEV_NUM_MASK (0xff << PPCR_DEV_NUM_OFFS)
  68643. +
  68644. +
  68645. +/* PCI Access Control Base Low Register (PACBLR) */
  68646. +#define PACBLR_EN BIT0 /* Access control window enable */
  68647. +
  68648. +#define PACBLR_ACCPROT BIT4 /* Access Protect */
  68649. +#define PACBLR_WRPROT BIT5 /* Write Protect */
  68650. +
  68651. +#define PACBLR_PCISWAP_OFFS 6 /* PCI slave Data Swap Control */
  68652. +#define PACBLR_PCISWAP_MASK (0x3 << PACBLR_PCISWAP_OFFS)
  68653. +#define PACBLR_PCISWAP_BYTE (0x0 << PACBLR_PCISWAP_OFFS)
  68654. +#define PACBLR_PCISWAP_NO_SWAP (0x1 << PACBLR_PCISWAP_OFFS)
  68655. +#define PACBLR_PCISWAP_BYTE_WORD (0x2 << PACBLR_PCISWAP_OFFS)
  68656. +#define PACBLR_PCISWAP_WORD (0x3 << PACBLR_PCISWAP_OFFS)
  68657. +
  68658. +#define PACBLR_RDMBURST_OFFS 8 /* Read Max Burst */
  68659. +#define PACBLR_RDMBURST_MASK (0x3 << PACBLR_RDMBURST_OFFS)
  68660. +#define PACBLR_RDMBURST_32BYTE (0x0 << PACBLR_RDMBURST_OFFS)
  68661. +#define PACBLR_RDMBURST_64BYTE (0x1 << PACBLR_RDMBURST_OFFS)
  68662. +#define PACBLR_RDMBURST_128BYTE (0x2 << PACBLR_RDMBURST_OFFS)
  68663. +
  68664. +#define PACBLR_RDSIZE_OFFS 10 /* Typical PCI read transaction Size. */
  68665. +#define PACBLR_RDSIZE_MASK (0x3 << PACBLR_RDSIZE_OFFS)
  68666. +#define PACBLR_RDSIZE_32BYTE (0x0 << PACBLR_RDSIZE_OFFS)
  68667. +#define PACBLR_RDSIZE_64BYTE (0x1 << PACBLR_RDSIZE_OFFS)
  68668. +#define PACBLR_RDSIZE_128BYTE (0x2 << PACBLR_RDSIZE_OFFS)
  68669. +#define PACBLR_RDSIZE_256BYTE (0x3 << PACBLR_RDSIZE_OFFS)
  68670. +
  68671. +#define PACBLR_BASE_L_OFFS 12 /* Corresponds to address bits [31:12] */
  68672. +#define PACBLR_BASE_L_MASK (0xfffff << PACBLR_BASE_L_OFFS)
  68673. +#define PACBLR_BASE_L_ALIGNMENT (1 << PACBLR_BASE_L_OFFS)
  68674. +#define PACBLR_BASE_ALIGN_UP(base) \
  68675. + ((base+PACBLR_BASE_L_ALIGNMENT)&PACBLR_BASE_L_MASK)
  68676. +#define PACBLR_BASE_ALIGN_DOWN(base) (base & PACBLR_BASE_L_MASK)
  68677. +
  68678. +
  68679. +/* PCI Access Control Base High Register (PACBHR) */
  68680. +#define PACBHR_BASE_H_OFFS 0 /* Corresponds to address bits [63:32] */
  68681. +#define PACBHR_CTRL_BASE_H_MASK (0xffffffff << PACBHR_BASE_H_OFFS)
  68682. +
  68683. +/* PCI Access Control Size Register (PACSR) */
  68684. +#define PACSR_WRMBURST_OFFS 8 /* Write Max Burst */
  68685. +#define PACSR_WRMBURST_MASK (0x3 << PACSR_WRMBURST_OFFS)
  68686. +#define PACSR_WRMBURST_32BYTE (0x0 << PACSR_WRMBURST_OFFS)
  68687. +#define PACSR_WRMBURST_64BYTE (0x1 << PACSR_WRMBURST_OFFS)
  68688. +#define PACSR_WRMBURST_128BYTE (0x2 << PACSR_WRMBURST_OFFS)
  68689. +
  68690. +#define PACSR_PCI_ORDERING BIT11 /* PCI Ordering required */
  68691. +
  68692. +#define PACSR_SIZE_OFFS 12 /* PCI access window size */
  68693. +#define PACSR_SIZE_MASK (0xfffff << PACSR_SIZE_OFFS)
  68694. +#define PACSR_SIZE_ALIGNMENT (1 << PACSR_SIZE_OFFS)
  68695. +#define PACSR_SIZE_ALIGN_UP(size) \
  68696. + ((size+PACSR_SIZE_ALIGNMENT)&PACSR_SIZE_MASK)
  68697. +#define PACSR_SIZE_ALIGN_DOWN(size) (size & PACSR_SIZE_MASK)
  68698. +
  68699. +
  68700. +/***************************************/
  68701. +/* PCI Configuration Access Registers */
  68702. +/***************************************/
  68703. +
  68704. +#define PCI_CONFIG_ADDR_REG(pciIf) (0x30C78 - ((pciIf) * 0x80) )
  68705. +#define PCI_CONFIG_DATA_REG(pciIf) (0x30C7C - ((pciIf) * 0x80) )
  68706. +#define PCI_INT_ACK_REG(pciIf) (0x30C34 + ((pciIf) * 0x80) )
  68707. +
  68708. +/* PCI Configuration Address Register (PCAR) */
  68709. +#define PCAR_REG_NUM_OFFS 2
  68710. +#define PCAR_REG_NUM_MASK (0x3F << PCAR_REG_NUM_OFFS)
  68711. +
  68712. +#define PCAR_FUNC_NUM_OFFS 8
  68713. +#define PCAR_FUNC_NUM_MASK (0x7 << PCAR_FUNC_NUM_OFFS)
  68714. +
  68715. +#define PCAR_DEVICE_NUM_OFFS 11
  68716. +#define PCAR_DEVICE_NUM_MASK (0x1F << PCAR_DEVICE_NUM_OFFS)
  68717. +
  68718. +#define PCAR_BUS_NUM_OFFS 16
  68719. +#define PCAR_BUS_NUM_MASK (0xFF << PCAR_BUS_NUM_OFFS)
  68720. +
  68721. +#define PCAR_CONFIG_EN BIT31
  68722. +
  68723. +
  68724. +/***************************************/
  68725. +/* PCI Configuration registers */
  68726. +/***************************************/
  68727. +
  68728. +/*********************************************/
  68729. +/* PCI Configuration, Function 0, Registers */
  68730. +/*********************************************/
  68731. +
  68732. +/* Marvell Specific */
  68733. +#define PCI_SCS0_BASE_ADDR_LOW 0x010
  68734. +#define PCI_SCS0_BASE_ADDR_HIGH 0x014
  68735. +#define PCI_SCS1_BASE_ADDR_LOW 0x018
  68736. +#define PCI_SCS1_BASE_ADDR_HIGH 0x01C
  68737. +#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_L 0x020
  68738. +#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_H 0x024
  68739. +
  68740. +/* capability list */
  68741. +#define PCI_POWER_MNG_CAPABILITY 0x040
  68742. +#define PCI_POWER_MNG_STATUS_CONTROL 0x044
  68743. +#define PCI_VPD_ADDRESS_REG 0x048
  68744. +#define PCI_VPD_DATA_REG 0x04c
  68745. +#define PCI_MSI_MESSAGE_CONTROL 0x050
  68746. +#define PCI_MSI_MESSAGE_ADDR 0x054
  68747. +#define PCI_MSI_MESSAGE_UPPER_ADDR 0x058
  68748. +#define PCI_MSI_MESSAGE_DATA 0x05c
  68749. +#define PCIX_COMMAND 0x060
  68750. +#define PCIX_STATUS 0x064
  68751. +#define PCI_COMPACT_PCI_HOT_SWAP 0x068
  68752. +
  68753. +
  68754. +/*********************************************/
  68755. +/* PCI Configuration, Function 1, Registers */
  68756. +/*********************************************/
  68757. +
  68758. +#define PCI_SCS2_BASE_ADDR_LOW 0x10
  68759. +#define PCI_SCS2_BASE_ADDR_HIGH 0x14
  68760. +#define PCI_SCS3_BASE_ADDR_LOW 0x18
  68761. +#define PCI_SCS3_BASE_ADDR_HIGH 0x1c
  68762. +
  68763. +
  68764. +/***********************************************/
  68765. +/* PCI Configuration, Function 2, Registers */
  68766. +/***********************************************/
  68767. +
  68768. +#define PCI_DEVCS0_BASE_ADDR_LOW 0x10
  68769. +#define PCI_DEVCS0_BASE_ADDR_HIGH 0x14
  68770. +#define PCI_DEVCS1_BASE_ADDR_LOW 0x18
  68771. +#define PCI_DEVCS1_BASE_ADDR_HIGH 0x1c
  68772. +#define PCI_DEVCS2_BASE_ADDR_LOW 0x20
  68773. +#define PCI_DEVCS2_BASE_ADDR_HIGH 0x24
  68774. +
  68775. +/***********************************************/
  68776. +/* PCI Configuration, Function 3, Registers */
  68777. +/***********************************************/
  68778. +
  68779. +#define PCI_BOOTCS_BASE_ADDR_LOW 0x18
  68780. +#define PCI_BOOTCS_BASE_ADDR_HIGH 0x1c
  68781. +
  68782. +/***********************************************/
  68783. +/* PCI Configuration, Function 4, Registers */
  68784. +/***********************************************/
  68785. +
  68786. +#define PCI_P2P_MEM0_BASE_ADDR_LOW 0x10
  68787. +#define PCI_P2P_MEM0_BASE_ADDR_HIGH 0x14
  68788. +#define PCI_P2P_IO_BASE_ADDR 0x20
  68789. +#define PCI_INTER_REGS_IO_MAPPED_BASE_ADDR 0x24
  68790. +
  68791. +/* PCIX_STATUS register fields (PXS) */
  68792. +
  68793. +#define PXS_FN_OFFS 0 /* Description Number */
  68794. +#define PXS_FN_MASK (0x7 << PXS_FN_OFFS)
  68795. +
  68796. +#define PXS_DN_OFFS 3 /* Device Number */
  68797. +#define PXS_DN_MASK (0x1f << PXS_DN_OFFS)
  68798. +
  68799. +#define PXS_BN_OFFS 8 /* Bus Number */
  68800. +#define PXS_BN_MASK (0xff << PXS_BN_OFFS)
  68801. +
  68802. +
  68803. +/* PCI Error Report Register Map */
  68804. +#define PCI_SERRN_MASK_REG(pciIf) (0x30c28 + (pciIf * 0x80))
  68805. +#define PCI_CAUSE_REG(pciIf) (0x31d58 + (pciIf * 0x80))
  68806. +#define PCI_MASK_REG(pciIf) (0x31d5C + (pciIf * 0x80))
  68807. +#define PCI_ERROR_ADDR_LOW_REG(pciIf) (0x31d40 + (pciIf * 0x80))
  68808. +#define PCI_ERROR_ADDR_HIGH_REG(pciIf) (0x31d44 + (pciIf * 0x80))
  68809. +#define PCI_ERROR_ATTRIBUTE_REG(pciIf) (0x31d48 + (pciIf * 0x80))
  68810. +#define PCI_ERROR_COMMAND_REG(pciIf) (0x31d50 + (pciIf * 0x80))
  68811. +
  68812. +/* PCI Interrupt Cause Register (PICR) */
  68813. +#define PICR_ERR_SEL_OFFS 27
  68814. +#define PICR_ERR_SEL_MASK (0x1f << PICR_ERR_SEL_OFFS)
  68815. +
  68816. +/* PCI Error Command Register (PECR) */
  68817. +#define PECR_ERR_CMD_OFFS 0
  68818. +#define PECR_ERR_CMD_MASK (0xf << PECR_ERR_CMD_OFFS)
  68819. +#define PECR_DAC BIT4
  68820. +
  68821. +
  68822. +/* defaults */
  68823. +/* Set bits means value is about to change according to new value */
  68824. +#define PCI_COMMAND_DEFAULT_MASK 0xffffdff1
  68825. +#define PCI_COMMAND_DEFAULT \
  68826. + (PCR_MASTER_WR_TRIG_WHOLE | \
  68827. + PCR_MASTER_RD_TRIG_WHOLE | \
  68828. + PCR_MASTER_MEM_RD_LINE_EN | \
  68829. + PCR_MASTER_MEM_RD_MULT_EN | \
  68830. + PCR_NS_ACCORDING_RCV_TRANS | \
  68831. + PCR_MASTER_PCIX_REQ64N_EN | \
  68832. + PCR_MASTER_DAC_EN | \
  68833. + PCR_MASTER_M64_ALLIGN | \
  68834. + PCR_ERRORS_PROPAGATION_EN)
  68835. +
  68836. +
  68837. +#define PCI_ARBITER_CTRL_DEFAULT_MASK 0x801fc07a
  68838. +#define PCI_ARBITER_CTRL_DEFAULT \
  68839. + (PACR_BROKEN_VAL_PCIX_MIN << PACR_BROKEN_VAL_OFFS)
  68840. +
  68841. +
  68842. +#endif /* #ifndef __INCPCIREGSH */
  68843. +
  68844. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c
  68845. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c 1970-01-01 01:00:00.000000000 +0100
  68846. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c 2010-11-09 20:28:11.512532816 +0100
  68847. @@ -0,0 +1,669 @@
  68848. +/*******************************************************************************
  68849. +Copyright (C) Marvell International Ltd. and its affiliates
  68850. +
  68851. +This software file (the "File") is owned and distributed by Marvell
  68852. +International Ltd. and/or its affiliates ("Marvell") under the following
  68853. +alternative licensing terms. Once you have made an election to distribute the
  68854. +File under one of the following license alternatives, please (i) delete this
  68855. +introductory statement regarding license alternatives, (ii) delete the two
  68856. +license alternatives that you have not elected to use and (iii) preserve the
  68857. +Marvell copyright notice above.
  68858. +
  68859. +********************************************************************************
  68860. +Marvell Commercial License Option
  68861. +
  68862. +If you received this File from Marvell and you have entered into a commercial
  68863. +license agreement (a "Commercial License") with Marvell, the File is licensed
  68864. +to you under the terms of the applicable Commercial License.
  68865. +
  68866. +********************************************************************************
  68867. +Marvell GPL License Option
  68868. +
  68869. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68870. +modify this File in accordance with the terms and conditions of the General
  68871. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  68872. +available along with the File in the license.txt file or by writing to the Free
  68873. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  68874. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  68875. +
  68876. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  68877. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  68878. +DISCLAIMED. The GPL License provides additional details about this warranty
  68879. +disclaimer.
  68880. +********************************************************************************
  68881. +Marvell BSD License Option
  68882. +
  68883. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68884. +modify this File under the following licensing terms.
  68885. +Redistribution and use in source and binary forms, with or without modification,
  68886. +are permitted provided that the following conditions are met:
  68887. +
  68888. + * Redistributions of source code must retain the above copyright notice,
  68889. + this list of conditions and the following disclaimer.
  68890. +
  68891. + * Redistributions in binary form must reproduce the above copyright
  68892. + notice, this list of conditions and the following disclaimer in the
  68893. + documentation and/or other materials provided with the distribution.
  68894. +
  68895. + * Neither the name of Marvell nor the names of its contributors may be
  68896. + used to endorse or promote products derived from this software without
  68897. + specific prior written permission.
  68898. +
  68899. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  68900. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  68901. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  68902. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  68903. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  68904. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  68905. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  68906. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  68907. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  68908. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  68909. +
  68910. +*******************************************************************************/
  68911. +
  68912. +#include "mvPciIf.h"
  68913. +#include "ctrlEnv/sys/mvSysPex.h"
  68914. +
  68915. +#if defined(MV_INCLUDE_PCI)
  68916. +#include "ctrlEnv/sys/mvSysPci.h"
  68917. +#endif
  68918. +
  68919. +
  68920. +/* defines */
  68921. +#ifdef MV_DEBUG
  68922. + #define DB(x) x
  68923. +#else
  68924. + #define DB(x)
  68925. +#endif
  68926. +
  68927. +
  68928. +/*******************************************************************************
  68929. +* mvPciInit - Initialize PCI interfaces
  68930. +*
  68931. +* DESCRIPTION:
  68932. +*
  68933. +* INPUT:
  68934. +*
  68935. +*
  68936. +* OUTPUT:
  68937. +* None.
  68938. +*
  68939. +* RETURN:
  68940. +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
  68941. +*
  68942. +*******************************************************************************/
  68943. +
  68944. +
  68945. +MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode)
  68946. +{
  68947. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  68948. +
  68949. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  68950. + {
  68951. + #if defined(MV_INCLUDE_PCI)
  68952. +
  68953. + MV_PCI_MOD pciMod;
  68954. +
  68955. + if (PCI_IF_MODE_HOST == pciIfmode)
  68956. + {
  68957. + pciMod = MV_PCI_MOD_HOST;
  68958. + }
  68959. + else if (PCI_IF_MODE_DEVICE == pciIfmode)
  68960. + {
  68961. + pciMod = MV_PCI_MOD_DEVICE;
  68962. + }
  68963. + else
  68964. + {
  68965. + mvOsPrintf("%s: ERROR!!! Bus %d mode %d neither host nor device!\n",
  68966. + __FUNCTION__, pciIf, pciIfmode);
  68967. + return MV_FAIL;
  68968. + }
  68969. +
  68970. + return mvPciInit(pciIf - MV_PCI_START_IF, pciMod);
  68971. + #else
  68972. + return MV_OK;
  68973. + #endif
  68974. + }
  68975. + else if (PCI_IF_TYPE_PEX == pciIfType)
  68976. + {
  68977. + #if defined(MV_INCLUDE_PEX)
  68978. +
  68979. + MV_PEX_TYPE pexType;
  68980. +
  68981. + if (PCI_IF_MODE_HOST == pciIfmode)
  68982. + {
  68983. + pexType = MV_PEX_ROOT_COMPLEX;
  68984. + }
  68985. + else if (PCI_IF_MODE_DEVICE == pciIfmode)
  68986. + {
  68987. + pexType = MV_PEX_END_POINT;
  68988. + }
  68989. + else
  68990. + {
  68991. + mvOsPrintf("%s: ERROR!!! Bus %d type %d neither root complex nor" \
  68992. + " end point\n", __FUNCTION__, pciIf, pciIfmode);
  68993. + return MV_FAIL;
  68994. + }
  68995. + return mvPexInit(pciIf - MV_PEX_START_IF, pexType);
  68996. +
  68997. + #else
  68998. + return MV_OK;
  68999. + #endif
  69000. +
  69001. + }
  69002. + else
  69003. + {
  69004. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69005. + }
  69006. +
  69007. + return MV_FAIL;
  69008. +
  69009. +}
  69010. +
  69011. +/* PCI configuration space read write */
  69012. +
  69013. +/*******************************************************************************
  69014. +* mvPciConfigRead - Read from configuration space
  69015. +*
  69016. +* DESCRIPTION:
  69017. +* This function performs a 32 bit read from PCI configuration space.
  69018. +* It supports both type 0 and type 1 of Configuration Transactions
  69019. +* (local and over bridge). In order to read from local bus segment, use
  69020. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  69021. +* will result configuration transaction of type 1 (over bridge).
  69022. +*
  69023. +* INPUT:
  69024. +* pciIf - PCI interface number.
  69025. +* bus - PCI segment bus number.
  69026. +* dev - PCI device number.
  69027. +* func - Function number.
  69028. +* regOffs - Register offset.
  69029. +*
  69030. +* OUTPUT:
  69031. +* None.
  69032. +*
  69033. +* RETURN:
  69034. +* 32bit register data, 0xffffffff on error
  69035. +*
  69036. +*******************************************************************************/
  69037. +MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  69038. + MV_U32 regOff)
  69039. +{
  69040. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69041. +
  69042. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69043. + {
  69044. + #if defined(MV_INCLUDE_PCI)
  69045. + return mvPciConfigRead(pciIf - MV_PCI_START_IF,
  69046. + bus,
  69047. + dev,
  69048. + func,
  69049. + regOff);
  69050. + #else
  69051. + return 0xffffffff;
  69052. + #endif
  69053. + }
  69054. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69055. + {
  69056. + #if defined(MV_INCLUDE_PEX)
  69057. + return mvPexConfigRead(pciIf - MV_PEX_START_IF,
  69058. + bus,
  69059. + dev,
  69060. + func,
  69061. + regOff);
  69062. + #else
  69063. + return 0xffffffff;
  69064. + #endif
  69065. +
  69066. + }
  69067. + else
  69068. + {
  69069. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69070. + }
  69071. +
  69072. + return 0;
  69073. +
  69074. +}
  69075. +
  69076. +/*******************************************************************************
  69077. +* mvPciConfigWrite - Write to configuration space
  69078. +*
  69079. +* DESCRIPTION:
  69080. +* This function performs a 32 bit write to PCI configuration space.
  69081. +* It supports both type 0 and type 1 of Configuration Transactions
  69082. +* (local and over bridge). In order to write to local bus segment, use
  69083. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  69084. +* will result configuration transaction of type 1 (over bridge).
  69085. +*
  69086. +* INPUT:
  69087. +* pciIf - PCI interface number.
  69088. +* bus - PCI segment bus number.
  69089. +* dev - PCI device number.
  69090. +* func - Function number.
  69091. +* regOffs - Register offset.
  69092. +* data - 32bit data.
  69093. +*
  69094. +* OUTPUT:
  69095. +* None.
  69096. +*
  69097. +* RETURN:
  69098. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  69099. +*
  69100. +*******************************************************************************/
  69101. +MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  69102. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  69103. +{
  69104. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69105. +
  69106. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69107. + {
  69108. + #if defined(MV_INCLUDE_PCI)
  69109. + return mvPciConfigWrite(pciIf - MV_PCI_START_IF,
  69110. + bus,
  69111. + dev,
  69112. + func,
  69113. + regOff,
  69114. + data);
  69115. + #else
  69116. + return MV_OK;
  69117. + #endif
  69118. + }
  69119. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69120. + {
  69121. + #if defined(MV_INCLUDE_PEX)
  69122. + return mvPexConfigWrite(pciIf - MV_PEX_START_IF,
  69123. + bus,
  69124. + dev,
  69125. + func,
  69126. + regOff,
  69127. + data);
  69128. + #else
  69129. + return MV_OK;
  69130. + #endif
  69131. +
  69132. + }
  69133. + else
  69134. + {
  69135. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69136. + }
  69137. +
  69138. + return MV_FAIL;
  69139. +
  69140. +}
  69141. +
  69142. +/*******************************************************************************
  69143. +* mvPciMasterEnable - Enable/disale PCI interface master transactions.
  69144. +*
  69145. +* DESCRIPTION:
  69146. +* This function performs read modified write to PCI command status
  69147. +* (offset 0x4) to set/reset bit 2. After this bit is set, the PCI
  69148. +* master is allowed to gain ownership on the bus, otherwise it is
  69149. +* incapable to do so.
  69150. +*
  69151. +* INPUT:
  69152. +* pciIf - PCI interface number.
  69153. +* enable - Enable/disable parameter.
  69154. +*
  69155. +* OUTPUT:
  69156. +* None.
  69157. +*
  69158. +* RETURN:
  69159. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  69160. +*
  69161. +*******************************************************************************/
  69162. +MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable)
  69163. +{
  69164. +
  69165. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69166. +
  69167. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69168. + {
  69169. + #if defined(MV_INCLUDE_PCI)
  69170. + return mvPciMasterEnable(pciIf - MV_PCI_START_IF,
  69171. + enable);
  69172. + #else
  69173. + return MV_OK;
  69174. + #endif
  69175. + }
  69176. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69177. + {
  69178. + #if defined(MV_INCLUDE_PEX)
  69179. + return mvPexMasterEnable(pciIf - MV_PEX_START_IF,
  69180. + enable);
  69181. + #else
  69182. + return MV_OK;
  69183. + #endif
  69184. + }
  69185. + else
  69186. + {
  69187. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69188. + }
  69189. +
  69190. + return MV_FAIL;
  69191. +
  69192. +}
  69193. +
  69194. +
  69195. +/*******************************************************************************
  69196. +* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.
  69197. +*
  69198. +* DESCRIPTION:
  69199. +* This function performs read modified write to PCI command status
  69200. +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
  69201. +* the PCI slave is allowed to respond to PCI IO space access (bit 0)
  69202. +* and PCI memory space access (bit 1).
  69203. +*
  69204. +* INPUT:
  69205. +* pciIf - PCI interface number.
  69206. +* dev - PCI device number.
  69207. +* enable - Enable/disable parameter.
  69208. +*
  69209. +* OUTPUT:
  69210. +* None.
  69211. +*
  69212. +* RETURN:
  69213. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  69214. +*
  69215. +*******************************************************************************/
  69216. +MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev, MV_BOOL enable)
  69217. +{
  69218. +
  69219. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69220. +
  69221. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69222. + {
  69223. + #if defined(MV_INCLUDE_PCI)
  69224. + return mvPciSlaveEnable(pciIf - MV_PCI_START_IF,bus,dev,
  69225. + enable);
  69226. + #else
  69227. + return MV_OK;
  69228. + #endif
  69229. + }
  69230. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69231. + {
  69232. + #if defined(MV_INCLUDE_PEX)
  69233. + return mvPexSlaveEnable(pciIf - MV_PEX_START_IF,bus,dev,
  69234. + enable);
  69235. + #else
  69236. + return MV_OK;
  69237. + #endif
  69238. + }
  69239. + else
  69240. + {
  69241. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69242. + }
  69243. +
  69244. + return MV_FAIL;
  69245. +
  69246. +}
  69247. +
  69248. +/*******************************************************************************
  69249. +* mvPciLocalBusNumSet - Set PCI interface local bus number.
  69250. +*
  69251. +* DESCRIPTION:
  69252. +* This function sets given PCI interface its local bus number.
  69253. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  69254. +*
  69255. +* INPUT:
  69256. +* pciIf - PCI interface number.
  69257. +* busNum - Bus number.
  69258. +*
  69259. +* OUTPUT:
  69260. +* None.
  69261. +*
  69262. +* RETURN:
  69263. +* MV_NOT_ALLOWED in case PCI interface is PCI-X.
  69264. +* MV_BAD_PARAM on bad parameters ,
  69265. +* otherwise MV_OK
  69266. +*
  69267. +*******************************************************************************/
  69268. +MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)
  69269. +{
  69270. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69271. +
  69272. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69273. + {
  69274. + #if defined(MV_INCLUDE_PCI)
  69275. + return mvPciLocalBusNumSet(pciIf - MV_PCI_START_IF,
  69276. + busNum);
  69277. + #else
  69278. + return MV_OK;
  69279. + #endif
  69280. + }
  69281. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69282. + {
  69283. + #if defined(MV_INCLUDE_PEX)
  69284. + return mvPexLocalBusNumSet(pciIf - MV_PEX_START_IF,
  69285. + busNum);
  69286. + #else
  69287. + return MV_OK;
  69288. + #endif
  69289. + }
  69290. + else
  69291. + {
  69292. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69293. + }
  69294. +
  69295. + return MV_FAIL;
  69296. +
  69297. +}
  69298. +
  69299. +/*******************************************************************************
  69300. +* mvPciLocalBusNumGet - Get PCI interface local bus number.
  69301. +*
  69302. +* DESCRIPTION:
  69303. +* This function gets the local bus number of a given PCI interface.
  69304. +*
  69305. +* INPUT:
  69306. +* pciIf - PCI interface number.
  69307. +*
  69308. +* OUTPUT:
  69309. +* None.
  69310. +*
  69311. +* RETURN:
  69312. +* Local bus number.0xffffffff on Error
  69313. +*
  69314. +*******************************************************************************/
  69315. +MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf)
  69316. +{
  69317. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69318. +
  69319. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69320. + {
  69321. + #if defined(MV_INCLUDE_PCI)
  69322. + return mvPciLocalBusNumGet(pciIf - MV_PCI_START_IF);
  69323. + #else
  69324. + return 0xFFFFFFFF;
  69325. + #endif
  69326. + }
  69327. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69328. + {
  69329. + #if defined(MV_INCLUDE_PEX)
  69330. + return mvPexLocalBusNumGet(pciIf - MV_PEX_START_IF);
  69331. + #else
  69332. + return 0xFFFFFFFF;
  69333. + #endif
  69334. +
  69335. + }
  69336. + else
  69337. + {
  69338. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n",__FUNCTION__, pciIf);
  69339. + }
  69340. +
  69341. + return 0;
  69342. +
  69343. +}
  69344. +
  69345. +
  69346. +/*******************************************************************************
  69347. +* mvPciLocalDevNumSet - Set PCI interface local device number.
  69348. +*
  69349. +* DESCRIPTION:
  69350. +* This function sets given PCI interface its local device number.
  69351. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  69352. +*
  69353. +* INPUT:
  69354. +* pciIf - PCI interface number.
  69355. +* devNum - Device number.
  69356. +*
  69357. +* OUTPUT:
  69358. +* None.
  69359. +*
  69360. +* RETURN:
  69361. +* MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,
  69362. +* otherwise MV_OK
  69363. +*
  69364. +*******************************************************************************/
  69365. +MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)
  69366. +{
  69367. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69368. +
  69369. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69370. + {
  69371. + #if defined(MV_INCLUDE_PCI)
  69372. + return mvPciLocalDevNumSet(pciIf - MV_PCI_START_IF,
  69373. + devNum);
  69374. + #else
  69375. + return MV_OK;
  69376. + #endif
  69377. + }
  69378. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69379. + {
  69380. + #if defined(MV_INCLUDE_PEX)
  69381. + return mvPexLocalDevNumSet(pciIf - MV_PEX_START_IF,
  69382. + devNum);
  69383. + #else
  69384. + return MV_OK;
  69385. + #endif
  69386. + }
  69387. + else
  69388. + {
  69389. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69390. + }
  69391. +
  69392. + return MV_FAIL;
  69393. +
  69394. +}
  69395. +
  69396. +/*******************************************************************************
  69397. +* mvPciLocalDevNumGet - Get PCI interface local device number.
  69398. +*
  69399. +* DESCRIPTION:
  69400. +* This function gets the local device number of a given PCI interface.
  69401. +*
  69402. +* INPUT:
  69403. +* pciIf - PCI interface number.
  69404. +*
  69405. +* OUTPUT:
  69406. +* None.
  69407. +*
  69408. +* RETURN:
  69409. +* Local device number. 0xffffffff on Error
  69410. +*
  69411. +*******************************************************************************/
  69412. +MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf)
  69413. +{
  69414. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69415. +
  69416. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69417. + {
  69418. + #if defined(MV_INCLUDE_PCI)
  69419. + return mvPciLocalDevNumGet(pciIf - MV_PCI_START_IF);
  69420. + #else
  69421. + return 0xFFFFFFFF;
  69422. + #endif
  69423. + }
  69424. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69425. + {
  69426. + #if defined(MV_INCLUDE_PEX)
  69427. + return mvPexLocalDevNumGet(pciIf - MV_PEX_START_IF);
  69428. + #else
  69429. + return 0xFFFFFFFF;
  69430. + #endif
  69431. +
  69432. + }
  69433. + else
  69434. + {
  69435. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69436. + }
  69437. +
  69438. + return 0;
  69439. +
  69440. +}
  69441. +
  69442. +/*******************************************************************************
  69443. +* mvPciIfTypeGet -
  69444. +*
  69445. +* DESCRIPTION:
  69446. +*
  69447. +* INPUT:
  69448. +*
  69449. +* OUTPUT:
  69450. +* None.
  69451. +*
  69452. +* RETURN:
  69453. +*
  69454. +*******************************************************************************/
  69455. +
  69456. +PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf)
  69457. +{
  69458. +
  69459. + if ((pciIf >= MV_PCI_START_IF)&&(pciIf < MV_PCI_MAX_IF + MV_PCI_START_IF))
  69460. + {
  69461. + return PCI_IF_TYPE_CONVEN_PCIX;
  69462. + }
  69463. + else if ((pciIf >= MV_PEX_START_IF) &&
  69464. + (pciIf < MV_PEX_MAX_IF + MV_PEX_START_IF))
  69465. + {
  69466. + return PCI_IF_TYPE_PEX;
  69467. +
  69468. + }
  69469. + else
  69470. + {
  69471. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69472. + }
  69473. +
  69474. + return 0xffffffff;
  69475. +
  69476. +}
  69477. +
  69478. +/*******************************************************************************
  69479. +* mvPciIfTypeGet -
  69480. +*
  69481. +* DESCRIPTION:
  69482. +*
  69483. +* INPUT:
  69484. +*
  69485. +* OUTPUT:
  69486. +* None.
  69487. +*
  69488. +* RETURN:
  69489. +*
  69490. +*******************************************************************************/
  69491. +
  69492. +MV_U32 mvPciRealIfNumGet(MV_U32 pciIf)
  69493. +{
  69494. +
  69495. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69496. +
  69497. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69498. + {
  69499. + return (pciIf - MV_PCI_START_IF);
  69500. + }
  69501. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69502. + {
  69503. + return (pciIf - MV_PEX_START_IF);
  69504. +
  69505. + }
  69506. + else
  69507. + {
  69508. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69509. + }
  69510. +
  69511. + return 0xffffffff;
  69512. +
  69513. +}
  69514. +
  69515. +
  69516. +
  69517. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h
  69518. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h 1970-01-01 01:00:00.000000000 +0100
  69519. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h 2010-11-09 20:28:11.552495455 +0100
  69520. @@ -0,0 +1,134 @@
  69521. +/*******************************************************************************
  69522. +Copyright (C) Marvell International Ltd. and its affiliates
  69523. +
  69524. +This software file (the "File") is owned and distributed by Marvell
  69525. +International Ltd. and/or its affiliates ("Marvell") under the following
  69526. +alternative licensing terms. Once you have made an election to distribute the
  69527. +File under one of the following license alternatives, please (i) delete this
  69528. +introductory statement regarding license alternatives, (ii) delete the two
  69529. +license alternatives that you have not elected to use and (iii) preserve the
  69530. +Marvell copyright notice above.
  69531. +
  69532. +********************************************************************************
  69533. +Marvell Commercial License Option
  69534. +
  69535. +If you received this File from Marvell and you have entered into a commercial
  69536. +license agreement (a "Commercial License") with Marvell, the File is licensed
  69537. +to you under the terms of the applicable Commercial License.
  69538. +
  69539. +********************************************************************************
  69540. +Marvell GPL License Option
  69541. +
  69542. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69543. +modify this File in accordance with the terms and conditions of the General
  69544. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  69545. +available along with the File in the license.txt file or by writing to the Free
  69546. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  69547. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  69548. +
  69549. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  69550. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  69551. +DISCLAIMED. The GPL License provides additional details about this warranty
  69552. +disclaimer.
  69553. +********************************************************************************
  69554. +Marvell BSD License Option
  69555. +
  69556. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69557. +modify this File under the following licensing terms.
  69558. +Redistribution and use in source and binary forms, with or without modification,
  69559. +are permitted provided that the following conditions are met:
  69560. +
  69561. + * Redistributions of source code must retain the above copyright notice,
  69562. + this list of conditions and the following disclaimer.
  69563. +
  69564. + * Redistributions in binary form must reproduce the above copyright
  69565. + notice, this list of conditions and the following disclaimer in the
  69566. + documentation and/or other materials provided with the distribution.
  69567. +
  69568. + * Neither the name of Marvell nor the names of its contributors may be
  69569. + used to endorse or promote products derived from this software without
  69570. + specific prior written permission.
  69571. +
  69572. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  69573. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  69574. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  69575. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  69576. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  69577. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  69578. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  69579. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  69580. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  69581. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  69582. +
  69583. +*******************************************************************************/
  69584. +
  69585. +#ifndef __INCPCIIFH
  69586. +#define __INCPCIIFH
  69587. +
  69588. +#include "mvSysHwConfig.h"
  69589. +#include "pci-if/mvPciIfRegs.h"
  69590. +#if defined(MV_INCLUDE_PEX)
  69591. +#include "pex/mvPex.h"
  69592. +#endif
  69593. +#if defined(MV_INCLUDE_PCI)
  69594. +#include "pci/mvPci.h"
  69595. +#endif
  69596. +#include "ctrlEnv/mvCtrlEnvLib.h"
  69597. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  69598. +
  69599. +typedef enum _mvPCIIfType
  69600. +{
  69601. + PCI_IF_TYPE_CONVEN_PCIX,
  69602. + PCI_IF_TYPE_PEX
  69603. +
  69604. +}PCI_IF_TYPE;
  69605. +
  69606. +typedef enum _mvPCIIfMode
  69607. +{
  69608. + PCI_IF_MODE_HOST,
  69609. + PCI_IF_MODE_DEVICE
  69610. +}PCI_IF_MODE;
  69611. +
  69612. +
  69613. +/* Global Functions prototypes */
  69614. +
  69615. +/* mvPciIfInit - Initialize PCI interfaces*/
  69616. +MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode);
  69617. +
  69618. +/* mvPciIfConfigRead - Read from configuration space */
  69619. +MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  69620. + MV_U32 func,MV_U32 regOff);
  69621. +
  69622. +/* mvPciIfConfigWrite - Write to configuration space */
  69623. +MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  69624. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  69625. +
  69626. +/* mvPciIfMasterEnable - Enable/disale PCI interface master transactions.*/
  69627. +MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable);
  69628. +
  69629. +/* mvPciIfSlaveEnable - Enable/disale PCI interface slave transactions.*/
  69630. +MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev,
  69631. + MV_BOOL enable);
  69632. +
  69633. +/* mvPciIfLocalBusNumSet - Set PCI interface local bus number.*/
  69634. +MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);
  69635. +
  69636. +/* mvPciIfLocalBusNumGet - Get PCI interface local bus number.*/
  69637. +MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf);
  69638. +
  69639. +/* mvPciIfLocalDevNumSet - Set PCI interface local device number.*/
  69640. +MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);
  69641. +
  69642. +/* mvPciIfLocalDevNumGet - Get PCI interface local device number.*/
  69643. +MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf);
  69644. +
  69645. +/* mvPciIfTypeGet - Get PCI If type*/
  69646. +PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf);
  69647. +
  69648. +MV_U32 mvPciRealIfNumGet(MV_U32 pciIf);
  69649. +
  69650. +/* mvPciIfAddrDecShow - Display address decode windows attributes */
  69651. +MV_VOID mvPciIfAddrDecShow(MV_VOID);
  69652. +
  69653. +#endif /* #ifndef __INCPCIIFH */
  69654. +
  69655. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h
  69656. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  69657. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h 2010-11-09 20:28:11.592495403 +0100
  69658. @@ -0,0 +1,245 @@
  69659. +/*******************************************************************************
  69660. +Copyright (C) Marvell International Ltd. and its affiliates
  69661. +
  69662. +This software file (the "File") is owned and distributed by Marvell
  69663. +International Ltd. and/or its affiliates ("Marvell") under the following
  69664. +alternative licensing terms. Once you have made an election to distribute the
  69665. +File under one of the following license alternatives, please (i) delete this
  69666. +introductory statement regarding license alternatives, (ii) delete the two
  69667. +license alternatives that you have not elected to use and (iii) preserve the
  69668. +Marvell copyright notice above.
  69669. +
  69670. +********************************************************************************
  69671. +Marvell Commercial License Option
  69672. +
  69673. +If you received this File from Marvell and you have entered into a commercial
  69674. +license agreement (a "Commercial License") with Marvell, the File is licensed
  69675. +to you under the terms of the applicable Commercial License.
  69676. +
  69677. +********************************************************************************
  69678. +Marvell GPL License Option
  69679. +
  69680. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69681. +modify this File in accordance with the terms and conditions of the General
  69682. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  69683. +available along with the File in the license.txt file or by writing to the Free
  69684. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  69685. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  69686. +
  69687. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  69688. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  69689. +DISCLAIMED. The GPL License provides additional details about this warranty
  69690. +disclaimer.
  69691. +********************************************************************************
  69692. +Marvell BSD License Option
  69693. +
  69694. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69695. +modify this File under the following licensing terms.
  69696. +Redistribution and use in source and binary forms, with or without modification,
  69697. +are permitted provided that the following conditions are met:
  69698. +
  69699. + * Redistributions of source code must retain the above copyright notice,
  69700. + this list of conditions and the following disclaimer.
  69701. +
  69702. + * Redistributions in binary form must reproduce the above copyright
  69703. + notice, this list of conditions and the following disclaimer in the
  69704. + documentation and/or other materials provided with the distribution.
  69705. +
  69706. + * Neither the name of Marvell nor the names of its contributors may be
  69707. + used to endorse or promote products derived from this software without
  69708. + specific prior written permission.
  69709. +
  69710. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  69711. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  69712. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  69713. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  69714. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  69715. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  69716. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  69717. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  69718. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  69719. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  69720. +
  69721. +*******************************************************************************/
  69722. +
  69723. +#ifndef __INCPCIIFREGSH
  69724. +#define __INCPCIIFREGSH
  69725. +
  69726. +
  69727. +/* defines */
  69728. +#define MAX_PCI_DEVICES 32
  69729. +#define MAX_PCI_FUNCS 8
  69730. +#define MAX_PCI_BUSSES 128
  69731. +
  69732. +/***************************************/
  69733. +/* PCI Configuration registers */
  69734. +/***************************************/
  69735. +
  69736. +/*********************************************/
  69737. +/* PCI Configuration, Function 0, Registers */
  69738. +/*********************************************/
  69739. +
  69740. +
  69741. +/* Standard registers */
  69742. +#define PCI_DEVICE_AND_VENDOR_ID 0x000
  69743. +#define PCI_STATUS_AND_COMMAND 0x004
  69744. +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008
  69745. +#define PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE 0x00C
  69746. +#define PCI_MEMORY_BAR_BASE_ADDR(barNum) (0x010 + ((barNum) << 2))
  69747. +#define PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID 0x02C
  69748. +#define PCI_EXPANSION_ROM_BASE_ADDR_REG 0x030
  69749. +#define PCI_CAPABILTY_LIST_POINTER 0x034
  69750. +#define PCI_INTERRUPT_PIN_AND_LINE 0x03C
  69751. +
  69752. +
  69753. +/* PCI Device and Vendor ID Register (PDVIR) */
  69754. +#define PDVIR_VEN_ID_OFFS 0 /* Vendor ID */
  69755. +#define PDVIR_VEN_ID_MASK (0xffff << PDVIR_VEN_ID_OFFS)
  69756. +
  69757. +#define PDVIR_DEV_ID_OFFS 16 /* Device ID */
  69758. +#define PDVIR_DEV_ID_MASK (0xffff << PDVIR_DEV_ID_OFFS)
  69759. +
  69760. +/* PCI Status and Command Register (PSCR) */
  69761. +#define PSCR_IO_EN BIT0 /* IO Enable */
  69762. +#define PSCR_MEM_EN BIT1 /* Memory Enable */
  69763. +#define PSCR_MASTER_EN BIT2 /* Master Enable */
  69764. +#define PSCR_SPECIAL_EN BIT3 /* Special Cycle Enable */
  69765. +#define PSCR_MEM_WRI_INV BIT4 /* Memory Write and Invalidate Enable */
  69766. +#define PSCR_VGA BIT5 /* VGA Palette Snoops */
  69767. +#define PSCR_PERR_EN BIT6 /* Parity Errors Respond Enable */
  69768. +#define PSCR_ADDR_STEP BIT7 /* Address Stepping Enable (Wait Cycle En)*/
  69769. +#define PSCR_SERR_EN BIT8 /* Ability to assert SERR# line */
  69770. +#define PSCR_FAST_BTB_EN BIT9 /* generate fast back-to-back transactions*/
  69771. +#define PSCR_CAP_LIST BIT20 /* Capability List Support */
  69772. +#define PSCR_66MHZ_EN BIT21 /* 66 MHz Capable */
  69773. +#define PSCR_UDF_EN BIT22 /* User definable features */
  69774. +#define PSCR_TAR_FAST_BB BIT23 /* fast back-to-back transactions capable */
  69775. +#define PSCR_DATA_PERR BIT24 /* Data Parity reported */
  69776. +
  69777. +#define PSCR_DEVSEL_TIM_OFFS 25 /* DEVSEL timing */
  69778. +#define PSCR_DEVSEL_TIM_MASK (0x3 << PSCR_DEVSEL_TIM_OFFS)
  69779. +#define PSCR_DEVSEL_TIM_FAST (0x0 << PSCR_DEVSEL_TIM_OFFS)
  69780. +#define PSCR_DEVSEL_TIM_MED (0x1 << PSCR_DEVSEL_TIM_OFFS)
  69781. +#define PSCR_DEVSEL_TIM_SLOW (0x2 << PSCR_DEVSEL_TIM_OFFS)
  69782. +
  69783. +#define PSCR_SLAVE_TABORT BIT27 /* Signalled Target Abort */
  69784. +#define PSCR_MASTER_TABORT BIT28 /* Recieved Target Abort */
  69785. +#define PSCR_MABORT BIT29 /* Recieved Master Abort */
  69786. +#define PSCR_SYSERR BIT30 /* Signalled system error */
  69787. +#define PSCR_DET_PARERR BIT31 /* Detect Parity Error */
  69788. +
  69789. +/* PCI configuration register offset=0x08 fields
  69790. + (PCI_CLASS_CODE_AND_REVISION_ID)(PCCRI) */
  69791. +
  69792. +#define PCCRIR_REVID_OFFS 0 /* Revision ID */
  69793. +#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS)
  69794. +
  69795. +#define PCCRIR_FULL_CLASS_OFFS 8 /* Full Class Code */
  69796. +#define PCCRIR_FULL_CLASS_MASK (0xffffff << PCCRIR_FULL_CLASS_OFFS)
  69797. +
  69798. +#define PCCRIR_PROGIF_OFFS 8 /* Prog .I/F*/
  69799. +#define PCCRIR_PROGIF_MASK (0xff << PCCRIR_PROGIF_OFFS)
  69800. +
  69801. +#define PCCRIR_SUB_CLASS_OFFS 16 /* Sub Class*/
  69802. +#define PCCRIR_SUB_CLASS_MASK (0xff << PCCRIR_SUB_CLASS_OFFS)
  69803. +
  69804. +#define PCCRIR_BASE_CLASS_OFFS 24 /* Base Class*/
  69805. +#define PCCRIR_BASE_CLASS_MASK (0xff << PCCRIR_BASE_CLASS_OFFS)
  69806. +
  69807. +/* PCI configuration register offset=0x0C fields
  69808. + (PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE)(PBHTLTCL) */
  69809. +
  69810. +#define PBHTLTCLR_CACHELINE_OFFS 0 /* Specifies the cache line size */
  69811. +#define PBHTLTCLR_CACHELINE_MASK (0xff << PBHTLTCLR_CACHELINE_OFFS)
  69812. +
  69813. +#define PBHTLTCLR_LATTIMER_OFFS 8 /* latency timer */
  69814. +#define PBHTLTCLR_LATTIMER_MASK (0xff << PBHTLTCLR_LATTIMER_OFFS)
  69815. +
  69816. +#define PBHTLTCLR_HEADTYPE_FULL_OFFS 16 /* Full Header Type */
  69817. +#define PBHTLTCLR_HEADTYPE_FULL_MASK (0xff << PBHTLTCLR_HEADTYPE_FULL_OFFS)
  69818. +
  69819. +#define PBHTLTCLR_MULTI_FUNC BIT23 /* Multi/Single function */
  69820. +
  69821. +#define PBHTLTCLR_HEADER_OFFS 16 /* Header type */
  69822. +#define PBHTLTCLR_HEADER_MASK (0x7f << PBHTLTCLR_HEADER_OFFS)
  69823. +#define PBHTLTCLR_HEADER_STANDARD (0x0 << PBHTLTCLR_HEADER_OFFS)
  69824. +#define PBHTLTCLR_HEADER_PCI2PCI_BRIDGE (0x1 << PBHTLTCLR_HEADER_OFFS)
  69825. +
  69826. +
  69827. +#define PBHTLTCLR_BISTCOMP_OFFS 24 /* BIST Completion Code */
  69828. +#define PBHTLTCLR_BISTCOMP_MASK (0xf << PBHTLTCLR_BISTCOMP_OFFS)
  69829. +
  69830. +#define PBHTLTCLR_BISTACT BIT30 /* BIST Activate bit */
  69831. +#define PBHTLTCLR_BISTCAP BIT31 /* BIST Capable Bit */
  69832. +
  69833. +
  69834. +/* PCI Bar Base Low Register (PBBLR) */
  69835. +#define PBBLR_IOSPACE BIT0 /* Memory Space Indicator */
  69836. +
  69837. +#define PBBLR_TYPE_OFFS 1 /* BAR Type/Init Val. */
  69838. +#define PBBLR_TYPE_MASK (0x3 << PBBLR_TYPE_OFFS)
  69839. +#define PBBLR_TYPE_32BIT_ADDR (0x0 << PBBLR_TYPE_OFFS)
  69840. +#define PBBLR_TYPE_64BIT_ADDR (0x2 << PBBLR_TYPE_OFFS)
  69841. +
  69842. +#define PBBLR_PREFETCH_EN BIT3 /* Prefetch Enable */
  69843. +
  69844. +
  69845. +#define PBBLR_MEM_BASE_OFFS 4 /* Memory Bar Base address. Corresponds to
  69846. + address bits [31:4] */
  69847. +#define PBBLR_MEM_BASE_MASK (0xfffffff << PBBLR_MEM_BASE_OFFS)
  69848. +
  69849. +#define PBBLR_IO_BASE_OFFS 2 /* IO Bar Base address. Corresponds to
  69850. + address bits [31:2] */
  69851. +#define PBBLR_IO_BASE_MASK (0x3fffffff << PBBLR_IO_BASE_OFFS)
  69852. +
  69853. +
  69854. +#define PBBLR_BASE_OFFS 12 /* Base address. Address bits [31:12] */
  69855. +#define PBBLR_BASE_MASK (0xfffff << PBBLR_BASE_OFFS)
  69856. +#define PBBLR_BASE_ALIGNMET (1 << PBBLR_BASE_OFFS)
  69857. +
  69858. +
  69859. +/* PCI Bar Base High Fegister (PBBHR) */
  69860. +#define PBBHR_BASE_OFFS 0 /* Base address. Address bits [31:12] */
  69861. +#define PBBHR_BASE_MASK (0xffffffff << PBBHR_BASE_OFFS)
  69862. +
  69863. +
  69864. +/* PCI configuration register offset=0x2C fields
  69865. + (PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID)(PSISVI) */
  69866. +
  69867. +#define PSISVIR_VENID_OFFS 0 /* Subsystem Manufacturer Vendor ID Number */
  69868. +#define PSISVIR_VENID_MASK (0xffff << PSISVIR_VENID_OFFS)
  69869. +
  69870. +#define PSISVIR_DEVID_OFFS 16 /* Subsystem Device ID Number */
  69871. +#define PSISVIR_DEVID_MASK (0xffff << PSISVIR_DEVID_OFFS)
  69872. +
  69873. +/* PCI configuration register offset=0x30 fields
  69874. + (PCI_EXPANSION_ROM_BASE_ADDR_REG)(PERBA) */
  69875. +
  69876. +#define PERBAR_EXPROMEN BIT0 /* Expansion ROM Enable */
  69877. +
  69878. +#define PERBAR_BASE_OFFS 12 /* Expansion ROM Base Address */
  69879. +#define PERBAR_BASE_MASK (0xfffff << PERBAR_BASE_OFFS)
  69880. +
  69881. +/* PCI configuration register offset=0x34 fields
  69882. + (PCI_CAPABILTY_LIST_POINTER)(PCLP) */
  69883. +
  69884. +#define PCLPR_CAPPTR_OFFS 0 /* Capability List Pointer */
  69885. +#define PCLPR_CAPPTR_MASK (0xff << PCLPR_CAPPTR_OFFS)
  69886. +
  69887. +/* PCI configuration register offset=0x3C fields
  69888. + (PCI_INTERRUPT_PIN_AND_LINE)(PIPL) */
  69889. +
  69890. +#define PIPLR_INTLINE_OFFS 0 /* Interrupt line (IRQ) */
  69891. +#define PIPLR_INTLINE_MASK (0xff << PIPLR_INTLINE_OFFS)
  69892. +
  69893. +#define PIPLR_INTPIN_OFFS 8 /* interrupt pin (A,B,C,D) */
  69894. +#define PIPLR_INTPIN_MASK (0xff << PIPLR_INTPIN_OFFS)
  69895. +
  69896. +#define PIPLR_MINGRANT_OFFS 16 /* Minimum Grant on 250 nano seconds units */
  69897. +#define PIPLR_MINGRANT_MASK (0xff << PIPLR_MINGRANT_OFFS)
  69898. +
  69899. +#define PIPLR_MAXLATEN_OFFS 24 /* Maximum latency on 250 nano seconds units */
  69900. +#define PIPLR_MAXLATEN_MASK (0xff << PIPLR_MAXLATEN_OFFS)
  69901. +
  69902. +#endif /* #ifndef __INCPCIIFREGSH */
  69903. +
  69904. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c
  69905. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c 1970-01-01 01:00:00.000000000 +0100
  69906. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c 2010-11-09 20:28:11.632495445 +0100
  69907. @@ -0,0 +1,1006 @@
  69908. +/*******************************************************************************
  69909. +Copyright (C) Marvell International Ltd. and its affiliates
  69910. +
  69911. +This software file (the "File") is owned and distributed by Marvell
  69912. +International Ltd. and/or its affiliates ("Marvell") under the following
  69913. +alternative licensing terms. Once you have made an election to distribute the
  69914. +File under one of the following license alternatives, please (i) delete this
  69915. +introductory statement regarding license alternatives, (ii) delete the two
  69916. +license alternatives that you have not elected to use and (iii) preserve the
  69917. +Marvell copyright notice above.
  69918. +
  69919. +********************************************************************************
  69920. +Marvell Commercial License Option
  69921. +
  69922. +If you received this File from Marvell and you have entered into a commercial
  69923. +license agreement (a "Commercial License") with Marvell, the File is licensed
  69924. +to you under the terms of the applicable Commercial License.
  69925. +
  69926. +********************************************************************************
  69927. +Marvell GPL License Option
  69928. +
  69929. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69930. +modify this File in accordance with the terms and conditions of the General
  69931. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  69932. +available along with the File in the license.txt file or by writing to the Free
  69933. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  69934. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  69935. +
  69936. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  69937. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  69938. +DISCLAIMED. The GPL License provides additional details about this warranty
  69939. +disclaimer.
  69940. +********************************************************************************
  69941. +Marvell BSD License Option
  69942. +
  69943. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69944. +modify this File under the following licensing terms.
  69945. +Redistribution and use in source and binary forms, with or without modification,
  69946. +are permitted provided that the following conditions are met:
  69947. +
  69948. + * Redistributions of source code must retain the above copyright notice,
  69949. + this list of conditions and the following disclaimer.
  69950. +
  69951. + * Redistributions in binary form must reproduce the above copyright
  69952. + notice, this list of conditions and the following disclaimer in the
  69953. + documentation and/or other materials provided with the distribution.
  69954. +
  69955. + * Neither the name of Marvell nor the names of its contributors may be
  69956. + used to endorse or promote products derived from this software without
  69957. + specific prior written permission.
  69958. +
  69959. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  69960. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  69961. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  69962. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  69963. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  69964. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  69965. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  69966. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  69967. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  69968. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  69969. +
  69970. +*******************************************************************************/
  69971. +
  69972. +/* includes */
  69973. +#include "mvPciUtils.h"
  69974. +
  69975. +#include "ctrlEnv/mvCtrlEnvLib.h"
  69976. +
  69977. +/* #define MV_DEBUG */
  69978. +/* defines */
  69979. +#ifdef MV_DEBUG
  69980. + #define DB(x) x
  69981. + #define mvOsPrintf printf
  69982. +#else
  69983. + #define DB(x)
  69984. +#endif
  69985. +
  69986. +/*
  69987. +This module only support scanning of Header type 00h of pci devices
  69988. +There is no suppotr for Header type 01h of pci devices ( PCI bridges )
  69989. +*/
  69990. +
  69991. +
  69992. +static MV_STATUS pciDetectDevice(MV_U32 pciIf,
  69993. + MV_U32 bus,
  69994. + MV_U32 dev,
  69995. + MV_U32 func,
  69996. + MV_PCI_DEVICE *pPciAgent);
  69997. +
  69998. +static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
  69999. + MV_U32 bus,
  70000. + MV_U32 dev,
  70001. + MV_U32 func,
  70002. + MV_PCI_DEVICE *pPciAgent);
  70003. +
  70004. +
  70005. +
  70006. +
  70007. +
  70008. +
  70009. +/*******************************************************************************
  70010. +* mvPciScan - Scan a PCI interface bus
  70011. +*
  70012. +* DESCRIPTION:
  70013. +* Performs a full scan on a PCI interface and returns all possible details
  70014. +* on the agents found on the bus.
  70015. +*
  70016. +* INPUT:
  70017. +* pciIf - PCI Interface
  70018. +* pPciAgents - Pointer to an Array of the pci agents to be detected
  70019. +* pPciAgentsNum - pPciAgents array maximum number of elements
  70020. +*
  70021. +* OUTPUT:
  70022. +* pPciAgents - Array of the pci agents detected on the bus
  70023. +* pPciAgentsNum - Number of pci agents detected on the bus
  70024. +*
  70025. +* RETURN:
  70026. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  70027. +*
  70028. +*******************************************************************************/
  70029. +
  70030. +MV_STATUS mvPciScan(MV_U32 pciIf,
  70031. + MV_PCI_DEVICE *pPciAgents,
  70032. + MV_U32 *pPciAgentsNum)
  70033. +{
  70034. +
  70035. + MV_U32 devIndex,funcIndex=0,busIndex=0,detectedDevNum=0;
  70036. + MV_U32 localBus=mvPciIfLocalBusNumGet(pciIf);
  70037. + MV_PCI_DEVICE *pPciDevice;
  70038. + MV_PCI_DEVICE *pMainDevice;
  70039. +
  70040. + DB(mvOsPrintf("mvPciScan: PCI interface num %d\n", pciIf));
  70041. + /* Parameter checking */
  70042. + if (pciIf >= mvCtrlPexMaxIfGet())
  70043. + {
  70044. + DB(mvOsPrintf("mvPciScan: ERR. Invalid PCI interface num %d\n", pciIf));
  70045. + return MV_BAD_PARAM;
  70046. + }
  70047. + if (NULL == pPciAgents)
  70048. + {
  70049. + DB(mvOsPrintf("mvPciScan: ERR. pPciAgents=NULL \n"));
  70050. + return MV_BAD_PARAM;
  70051. + }
  70052. + if (NULL == pPciAgentsNum)
  70053. + {
  70054. + DB(mvOsPrintf("mvPciScan: ERR. pPciAgentsNum=NULL \n"));
  70055. + return MV_BAD_PARAM;
  70056. + }
  70057. +
  70058. +
  70059. + DB(mvOsPrintf("mvPciScan: PCI interface num %d mvPciMasterEnable\n", pciIf));
  70060. + /* Master enable the MV PCI master */
  70061. + if (MV_OK != mvPciIfMasterEnable(pciIf,MV_TRUE))
  70062. + {
  70063. + DB(mvOsPrintf("mvPciScan: ERR. mvPciMasterEnable failed \n"));
  70064. + return MV_ERROR;
  70065. +
  70066. + }
  70067. +
  70068. + DB(mvOsPrintf("mvPciScan: PCI interface num scan%d\n", pciIf));
  70069. +
  70070. + /* go through all busses */
  70071. + for (busIndex=localBus ; busIndex < MAX_PCI_BUSSES ; busIndex++)
  70072. + {
  70073. + /* go through all possible devices on the local bus */
  70074. + for (devIndex=0 ; devIndex < MAX_PCI_DEVICES ; devIndex++)
  70075. + {
  70076. + /* always start with function equal to zero */
  70077. + funcIndex=0;
  70078. +
  70079. + pPciDevice=&pPciAgents[detectedDevNum];
  70080. + DB(mvOsPrintf("mvPciScan: PCI interface num scan%d:%d\n", busIndex, devIndex));
  70081. +
  70082. + if (MV_ERROR == pciDetectDevice(pciIf,
  70083. + busIndex,
  70084. + devIndex,
  70085. + funcIndex,
  70086. + pPciDevice))
  70087. + {
  70088. + /* no device detected , try the next address */
  70089. + continue;
  70090. + }
  70091. +
  70092. + /* We are here ! means we have detected a device*/
  70093. + /* always we start with only one function per device */
  70094. + pMainDevice = pPciDevice;
  70095. + pPciDevice->funtionsNum = 1;
  70096. +
  70097. +
  70098. + /* move on */
  70099. + detectedDevNum++;
  70100. +
  70101. +
  70102. + /* check if we have no more room for a new device */
  70103. + if (detectedDevNum == *pPciAgentsNum)
  70104. + {
  70105. + DB(mvOsPrintf("mvPciScan: ERR. array passed too small \n"));
  70106. + return MV_ERROR;
  70107. + }
  70108. +
  70109. + /* check the detected device if it is a multi functional device then
  70110. + scan all device functions*/
  70111. + if (pPciDevice->isMultiFunction == MV_TRUE)
  70112. + {
  70113. + /* start with function number 1 because we have already detected
  70114. + function 0 */
  70115. + for (funcIndex=1; funcIndex<MAX_PCI_FUNCS ; funcIndex++)
  70116. + {
  70117. + pPciDevice=&pPciAgents[detectedDevNum];
  70118. +
  70119. + if (MV_ERROR == pciDetectDevice(pciIf,
  70120. + busIndex,
  70121. + devIndex,
  70122. + funcIndex,
  70123. + pPciDevice))
  70124. + {
  70125. + /* no device detected means no more functions !*/
  70126. + continue;
  70127. + }
  70128. + /* We are here ! means we have detected a device */
  70129. +
  70130. + /* move on */
  70131. + pMainDevice->funtionsNum++;
  70132. + detectedDevNum++;
  70133. +
  70134. + /* check if we have no more room for a new device */
  70135. + if (detectedDevNum == *pPciAgentsNum)
  70136. + {
  70137. + DB(mvOsPrintf("mvPciScan: ERR. Array too small\n"));
  70138. + return MV_ERROR;
  70139. + }
  70140. +
  70141. +
  70142. + }
  70143. + }
  70144. +
  70145. + }
  70146. +
  70147. + }
  70148. +
  70149. + /* return the number of devices actually detected on the bus ! */
  70150. + *pPciAgentsNum = detectedDevNum;
  70151. +
  70152. + return MV_OK;
  70153. +
  70154. +}
  70155. +
  70156. +
  70157. +/*******************************************************************************
  70158. +* pciDetectDevice - Detect a pci device parameters
  70159. +*
  70160. +* DESCRIPTION:
  70161. +* This function detect if a pci agent exist on certain address !
  70162. +* and if exists then it fills all possible information on the
  70163. +* agent
  70164. +*
  70165. +* INPUT:
  70166. +* pciIf - PCI Interface
  70167. +* bus - Bus number
  70168. +* dev - Device number
  70169. +* func - Function number
  70170. +*
  70171. +*
  70172. +*
  70173. +* OUTPUT:
  70174. +* pPciAgent - pointer to the pci agent filled with its information
  70175. +*
  70176. +* RETURN:
  70177. +* MV_ERROR if no device , MV_OK otherwise
  70178. +*
  70179. +*******************************************************************************/
  70180. +
  70181. +static MV_STATUS pciDetectDevice(MV_U32 pciIf,
  70182. + MV_U32 bus,
  70183. + MV_U32 dev,
  70184. + MV_U32 func,
  70185. + MV_PCI_DEVICE *pPciAgent)
  70186. +{
  70187. + MV_U32 pciData;
  70188. +
  70189. + /* no Parameters checking ! because it is static function and it is assumed
  70190. + that all parameters were checked in the calling function */
  70191. +
  70192. +
  70193. + /* Try read the PCI Vendor ID and Device ID */
  70194. +
  70195. + /* We will scan only ourselves and the PCI slots that exist on the
  70196. + board, because we may have a case that we have one slot that has
  70197. + a Cardbus connector, and because CardBus answers all IDsels we want
  70198. + to scan only this slot and ourseleves.
  70199. +
  70200. + */
  70201. + #if defined(MV_INCLUDE_PCI)
  70202. + if ((PCI_IF_TYPE_CONVEN_PCIX == mvPciIfTypeGet(pciIf)) &&
  70203. + (DB_88F5181_DDR1_PRPMC != mvBoardIdGet()) &&
  70204. + (DB_88F5181_DDR1_PEXPCI != mvBoardIdGet()) &&
  70205. + (DB_88F5181_DDR1_MNG != mvBoardIdGet()))
  70206. + {
  70207. +
  70208. + if (mvBoardIsOurPciSlot(bus, dev) == MV_FALSE)
  70209. + {
  70210. + return MV_ERROR;
  70211. + }
  70212. + }
  70213. + #endif /* defined(MV_INCLUDE_PCI) */
  70214. +
  70215. + pciData = mvPciIfConfigRead(pciIf, bus,dev,func, PCI_DEVICE_AND_VENDOR_ID);
  70216. +
  70217. + if (PCI_ERROR_CODE == pciData)
  70218. + {
  70219. + /* no device exist */
  70220. + return MV_ERROR;
  70221. + }
  70222. +
  70223. + /* we are here ! means a device is detected */
  70224. +
  70225. + /* fill basic information */
  70226. + pPciAgent->busNumber=bus;
  70227. + pPciAgent->deviceNum=dev;
  70228. + pPciAgent->function=func;
  70229. +
  70230. + /* Fill the PCI Vendor ID and Device ID */
  70231. +
  70232. + pPciAgent->venID = (pciData & PDVIR_VEN_ID_MASK) >> PDVIR_VEN_ID_OFFS;
  70233. + pPciAgent->deviceID = (pciData & PDVIR_DEV_ID_MASK) >> PDVIR_DEV_ID_OFFS;
  70234. +
  70235. + /* Read Status and command */
  70236. + pciData = mvPciIfConfigRead(pciIf,
  70237. + bus,dev,func,
  70238. + PCI_STATUS_AND_COMMAND);
  70239. +
  70240. +
  70241. + /* Fill related Status and Command information*/
  70242. +
  70243. + if (pciData & PSCR_TAR_FAST_BB)
  70244. + {
  70245. + pPciAgent->isFastB2BCapable = MV_TRUE;
  70246. + }
  70247. + else
  70248. + {
  70249. + pPciAgent->isFastB2BCapable = MV_FALSE;
  70250. + }
  70251. +
  70252. + if (pciData & PSCR_CAP_LIST)
  70253. + {
  70254. + pPciAgent->isCapListSupport=MV_TRUE;
  70255. + }
  70256. + else
  70257. + {
  70258. + pPciAgent->isCapListSupport=MV_FALSE;
  70259. + }
  70260. +
  70261. + if (pciData & PSCR_66MHZ_EN)
  70262. + {
  70263. + pPciAgent->is66MHZCapable=MV_TRUE;
  70264. + }
  70265. + else
  70266. + {
  70267. + pPciAgent->is66MHZCapable=MV_FALSE;
  70268. + }
  70269. +
  70270. + /* Read Class Code and Revision */
  70271. + pciData = mvPciIfConfigRead(pciIf,
  70272. + bus,dev,func,
  70273. + PCI_CLASS_CODE_AND_REVISION_ID);
  70274. +
  70275. +
  70276. + pPciAgent->baseClassCode =
  70277. + (pciData & PCCRIR_BASE_CLASS_MASK) >> PCCRIR_BASE_CLASS_OFFS;
  70278. +
  70279. + pPciAgent->subClassCode =
  70280. + (pciData & PCCRIR_SUB_CLASS_MASK) >> PCCRIR_SUB_CLASS_OFFS;
  70281. +
  70282. + pPciAgent->progIf =
  70283. + (pciData & PCCRIR_PROGIF_MASK) >> PCCRIR_PROGIF_OFFS;
  70284. +
  70285. + pPciAgent->revisionID =
  70286. + (pciData & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS;
  70287. +
  70288. + /* Read PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE */
  70289. + pciData = mvPciIfConfigRead(pciIf,
  70290. + bus,dev,func,
  70291. + PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE);
  70292. +
  70293. +
  70294. +
  70295. + pPciAgent->pciCacheLine=
  70296. + (pciData & PBHTLTCLR_CACHELINE_MASK ) >> PBHTLTCLR_CACHELINE_OFFS;
  70297. + pPciAgent->pciLatencyTimer=
  70298. + (pciData & PBHTLTCLR_LATTIMER_MASK) >> PBHTLTCLR_LATTIMER_OFFS;
  70299. +
  70300. + switch (pciData & PBHTLTCLR_HEADER_MASK)
  70301. + {
  70302. + case PBHTLTCLR_HEADER_STANDARD:
  70303. +
  70304. + pPciAgent->pciHeader=MV_PCI_STANDARD;
  70305. + break;
  70306. + case PBHTLTCLR_HEADER_PCI2PCI_BRIDGE:
  70307. +
  70308. + pPciAgent->pciHeader=MV_PCI_PCI2PCI_BRIDGE;
  70309. + break;
  70310. +
  70311. + }
  70312. +
  70313. + if (pciData & PBHTLTCLR_MULTI_FUNC)
  70314. + {
  70315. + pPciAgent->isMultiFunction=MV_TRUE;
  70316. + }
  70317. + else
  70318. + {
  70319. + pPciAgent->isMultiFunction=MV_FALSE;
  70320. + }
  70321. +
  70322. + if (pciData & PBHTLTCLR_BISTCAP)
  70323. + {
  70324. + pPciAgent->isBISTCapable=MV_TRUE;
  70325. + }
  70326. + else
  70327. + {
  70328. + pPciAgent->isBISTCapable=MV_FALSE;
  70329. + }
  70330. +
  70331. +
  70332. + /* read this device pci bars */
  70333. +
  70334. + pciDetectDeviceBars(pciIf,
  70335. + bus,dev,func,
  70336. + pPciAgent);
  70337. +
  70338. +
  70339. + /* check if we are bridge*/
  70340. + if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
  70341. + (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
  70342. + {
  70343. +
  70344. + /* Read P2P_BUSSES_NUM */
  70345. + pciData = mvPciIfConfigRead(pciIf,
  70346. + bus,dev,func,
  70347. + P2P_BUSSES_NUM);
  70348. +
  70349. + pPciAgent->p2pPrimBusNum =
  70350. + (pciData & PBM_PRIME_BUS_NUM_MASK) >> PBM_PRIME_BUS_NUM_OFFS;
  70351. +
  70352. + pPciAgent->p2pSecBusNum =
  70353. + (pciData & PBM_SEC_BUS_NUM_MASK) >> PBM_SEC_BUS_NUM_OFFS;
  70354. +
  70355. + pPciAgent->p2pSubBusNum =
  70356. + (pciData & PBM_SUB_BUS_NUM_MASK) >> PBM_SUB_BUS_NUM_OFFS;
  70357. +
  70358. + pPciAgent->p2pSecLatencyTimer =
  70359. + (pciData & PBM_SEC_LAT_TMR_MASK) >> PBM_SEC_LAT_TMR_OFFS;
  70360. +
  70361. + /* Read P2P_IO_BASE_LIMIT_SEC_STATUS */
  70362. + pciData = mvPciIfConfigRead(pciIf,
  70363. + bus,dev,func,
  70364. + P2P_IO_BASE_LIMIT_SEC_STATUS);
  70365. +
  70366. + pPciAgent->p2pSecStatus =
  70367. + (pciData & PIBLSS_SEC_STATUS_MASK) >> PIBLSS_SEC_STATUS_OFFS;
  70368. +
  70369. +
  70370. + pPciAgent->p2pIObase =
  70371. + (pciData & PIBLSS_IO_BASE_MASK) << PIBLSS_IO_LIMIT_OFFS;
  70372. +
  70373. + /* clear low address (should be zero)*/
  70374. + pPciAgent->p2pIObase &= PIBLSS_HIGH_ADDR_MASK;
  70375. +
  70376. + pPciAgent->p2pIOLimit =
  70377. + (pciData & PIBLSS_IO_LIMIT_MASK);
  70378. +
  70379. + /* fill low address with 0xfff */
  70380. + pPciAgent->p2pIOLimit |= PIBLSS_LOW_ADDR_MASK;
  70381. +
  70382. +
  70383. + switch ((pciData & PIBLSS_ADD_CAP_MASK) >> PIBLSS_ADD_CAP_OFFS)
  70384. + {
  70385. + case PIBLSS_ADD_CAP_16BIT:
  70386. +
  70387. + pPciAgent->bIO32 = MV_FALSE;
  70388. +
  70389. + break;
  70390. + case PIBLSS_ADD_CAP_32BIT:
  70391. +
  70392. + pPciAgent->bIO32 = MV_TRUE;
  70393. +
  70394. + /* Read P2P_IO_BASE_LIMIT_UPPER_16 */
  70395. + pciData = mvPciIfConfigRead(pciIf,
  70396. + bus,dev,func,
  70397. + P2P_IO_BASE_LIMIT_UPPER_16);
  70398. +
  70399. + pPciAgent->p2pIObase |=
  70400. + (pciData & PRBU_IO_UPP_BASE_MASK) << PRBU_IO_UPP_LIMIT_OFFS;
  70401. +
  70402. +
  70403. + pPciAgent->p2pIOLimit |=
  70404. + (pciData & PRBU_IO_UPP_LIMIT_MASK);
  70405. +
  70406. + break;
  70407. +
  70408. + }
  70409. +
  70410. +
  70411. + /* Read P2P_MEM_BASE_LIMIT */
  70412. + pciData = mvPciIfConfigRead(pciIf,
  70413. + bus,dev,func,
  70414. + P2P_MEM_BASE_LIMIT);
  70415. +
  70416. + pPciAgent->p2pMemBase =
  70417. + (pciData & PMBL_MEM_BASE_MASK) << PMBL_MEM_LIMIT_OFFS;
  70418. +
  70419. + /* clear low address */
  70420. + pPciAgent->p2pMemBase &= PMBL_HIGH_ADDR_MASK;
  70421. +
  70422. + pPciAgent->p2pMemLimit =
  70423. + (pciData & PMBL_MEM_LIMIT_MASK);
  70424. +
  70425. + /* add 0xfffff */
  70426. + pPciAgent->p2pMemLimit |= PMBL_LOW_ADDR_MASK;
  70427. +
  70428. +
  70429. + /* Read P2P_PREF_MEM_BASE_LIMIT */
  70430. + pciData = mvPciIfConfigRead(pciIf,
  70431. + bus,dev,func,
  70432. + P2P_PREF_MEM_BASE_LIMIT);
  70433. +
  70434. +
  70435. + pPciAgent->p2pPrefMemBase =
  70436. + (pciData & PRMBL_PREF_MEM_BASE_MASK) << PRMBL_PREF_MEM_LIMIT_OFFS;
  70437. +
  70438. + /* get high address only */
  70439. + pPciAgent->p2pPrefMemBase &= PRMBL_HIGH_ADDR_MASK;
  70440. +
  70441. +
  70442. +
  70443. + pPciAgent->p2pPrefMemLimit =
  70444. + (pciData & PRMBL_PREF_MEM_LIMIT_MASK);
  70445. +
  70446. + /* add 0xfffff */
  70447. + pPciAgent->p2pPrefMemLimit |= PRMBL_LOW_ADDR_MASK;
  70448. +
  70449. + switch (pciData & PRMBL_ADD_CAP_MASK)
  70450. + {
  70451. + case PRMBL_ADD_CAP_32BIT:
  70452. +
  70453. + pPciAgent->bPrefMem64 = MV_FALSE;
  70454. +
  70455. + /* Read P2P_PREF_BASE_UPPER_32 */
  70456. + pPciAgent->p2pPrefBaseUpper32Bits = 0;
  70457. +
  70458. + /* Read P2P_PREF_LIMIT_UPPER_32 */
  70459. + pPciAgent->p2pPrefLimitUpper32Bits = 0;
  70460. +
  70461. + break;
  70462. + case PRMBL_ADD_CAP_64BIT:
  70463. +
  70464. + pPciAgent->bPrefMem64 = MV_TRUE;
  70465. +
  70466. + /* Read P2P_PREF_BASE_UPPER_32 */
  70467. + pPciAgent->p2pPrefBaseUpper32Bits = mvPciIfConfigRead(pciIf,
  70468. + bus,dev,func,
  70469. + P2P_PREF_BASE_UPPER_32);
  70470. +
  70471. + /* Read P2P_PREF_LIMIT_UPPER_32 */
  70472. + pPciAgent->p2pPrefLimitUpper32Bits = mvPciIfConfigRead(pciIf,
  70473. + bus,dev,func,
  70474. + P2P_PREF_LIMIT_UPPER_32);
  70475. +
  70476. + break;
  70477. +
  70478. + }
  70479. +
  70480. + }
  70481. + else /* no bridge */
  70482. + {
  70483. + /* Read PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID */
  70484. + pciData = mvPciIfConfigRead(pciIf,
  70485. + bus,dev,func,
  70486. + PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID);
  70487. +
  70488. +
  70489. + pPciAgent->subSysVenID =
  70490. + (pciData & PSISVIR_VENID_MASK) >> PSISVIR_VENID_OFFS;
  70491. + pPciAgent->subSysID =
  70492. + (pciData & PSISVIR_DEVID_MASK) >> PSISVIR_DEVID_OFFS;
  70493. +
  70494. +
  70495. + /* Read PCI_EXPANSION_ROM_BASE_ADDR_REG */
  70496. + pciData = mvPciIfConfigRead(pciIf,
  70497. + bus,dev,func,
  70498. + PCI_EXPANSION_ROM_BASE_ADDR_REG);
  70499. +
  70500. +
  70501. + if (pciData & PERBAR_EXPROMEN)
  70502. + {
  70503. + pPciAgent->isExpRom = MV_TRUE;
  70504. + }
  70505. + else
  70506. + {
  70507. + pPciAgent->isExpRom = MV_FALSE;
  70508. + }
  70509. +
  70510. + pPciAgent->expRomAddr =
  70511. + (pciData & PERBAR_BASE_MASK) >> PERBAR_BASE_OFFS;
  70512. +
  70513. + }
  70514. +
  70515. +
  70516. + if (MV_TRUE == pPciAgent->isCapListSupport)
  70517. + {
  70518. + /* Read PCI_CAPABILTY_LIST_POINTER */
  70519. + pciData = mvPciIfConfigRead(pciIf,
  70520. + bus,dev,func,
  70521. + PCI_CAPABILTY_LIST_POINTER);
  70522. +
  70523. + pPciAgent->capListPointer =
  70524. + (pciData & PCLPR_CAPPTR_MASK) >> PCLPR_CAPPTR_OFFS;
  70525. +
  70526. + }
  70527. +
  70528. + /* Read PCI_INTERRUPT_PIN_AND_LINE */
  70529. + pciData = mvPciIfConfigRead(pciIf,
  70530. + bus,dev,func,
  70531. + PCI_INTERRUPT_PIN_AND_LINE);
  70532. +
  70533. +
  70534. + pPciAgent->irqLine=
  70535. + (pciData & PIPLR_INTLINE_MASK) >> PIPLR_INTLINE_OFFS;
  70536. +
  70537. + pPciAgent->intPin=
  70538. + (MV_PCI_INT_PIN)(pciData & PIPLR_INTPIN_MASK) >> PIPLR_INTPIN_OFFS;
  70539. +
  70540. + pPciAgent->minGrant=
  70541. + (pciData & PIPLR_MINGRANT_MASK) >> PIPLR_MINGRANT_OFFS;
  70542. + pPciAgent->maxLatency=
  70543. + (pciData & PIPLR_MAXLATEN_MASK) >> PIPLR_MAXLATEN_OFFS;
  70544. +
  70545. + mvPciClassNameGet(pPciAgent->baseClassCode,
  70546. + (MV_8 *)pPciAgent->type);
  70547. +
  70548. + return MV_OK;
  70549. +
  70550. +
  70551. +}
  70552. +
  70553. +/*******************************************************************************
  70554. +* pciDetectDeviceBars - Detect a pci device bars
  70555. +*
  70556. +* DESCRIPTION:
  70557. +* This function detects all pci agent bars
  70558. +*
  70559. +* INPUT:
  70560. +* pciIf - PCI Interface
  70561. +* bus - Bus number
  70562. +* dev - Device number
  70563. +* func - Function number
  70564. +*
  70565. +*
  70566. +*
  70567. +* OUTPUT:
  70568. +* pPciAgent - pointer to the pci agent filled with its information
  70569. +*
  70570. +* RETURN:
  70571. +* detected bars number
  70572. +*
  70573. +*******************************************************************************/
  70574. +static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
  70575. + MV_U32 bus,
  70576. + MV_U32 dev,
  70577. + MV_U32 func,
  70578. + MV_PCI_DEVICE *pPciAgent)
  70579. +{
  70580. + MV_U32 pciData,barIndex,detectedBar=0;
  70581. + MV_U32 tmpBaseHigh=0,tmpBaseLow=0;
  70582. + MV_U32 pciMaxBars=0;
  70583. +
  70584. + pPciAgent->barsNum=0;
  70585. +
  70586. + /* check if we are bridge*/
  70587. + if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
  70588. + (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
  70589. + {
  70590. + pciMaxBars = 2;
  70591. + }
  70592. + else /* no bridge */
  70593. + {
  70594. + pciMaxBars = 6;
  70595. + }
  70596. +
  70597. + /* read this device pci bars */
  70598. + for (barIndex = 0 ; barIndex < pciMaxBars ; barIndex++ )
  70599. + {
  70600. + /* Read PCI_MEMORY_BAR_BASE_ADDR */
  70601. + tmpBaseLow = pciData = mvPciIfConfigRead(pciIf,
  70602. + bus,dev,func,
  70603. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  70604. +
  70605. + pPciAgent->pciBar[detectedBar].barOffset =
  70606. + PCI_MEMORY_BAR_BASE_ADDR(barIndex);
  70607. +
  70608. + /* check if the bar is 32bit or 64bit bar */
  70609. + switch (pciData & PBBLR_TYPE_MASK)
  70610. + {
  70611. + case PBBLR_TYPE_32BIT_ADDR:
  70612. + pPciAgent->pciBar[detectedBar].barType = PCI_32BIT_BAR;
  70613. + break;
  70614. + case PBBLR_TYPE_64BIT_ADDR:
  70615. + pPciAgent->pciBar[detectedBar].barType = PCI_64BIT_BAR;
  70616. + break;
  70617. +
  70618. + }
  70619. +
  70620. + /* check if it is memory or IO bar */
  70621. + if (pciData & PBBLR_IOSPACE)
  70622. + {
  70623. + pPciAgent->pciBar[detectedBar].barMapping=PCI_IO_BAR;
  70624. + }
  70625. + else
  70626. + {
  70627. + pPciAgent->pciBar[detectedBar].barMapping=PCI_MEMORY_BAR;
  70628. + }
  70629. +
  70630. + /* if it is memory bar then check if it is prefetchable */
  70631. + if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
  70632. + {
  70633. + if (pciData & PBBLR_PREFETCH_EN)
  70634. + {
  70635. + pPciAgent->pciBar[detectedBar].isPrefetchable = MV_TRUE;
  70636. + }
  70637. + else
  70638. + {
  70639. + pPciAgent->pciBar[detectedBar].isPrefetchable = MV_FALSE;
  70640. + }
  70641. +
  70642. + pPciAgent->pciBar[detectedBar].barBaseLow =
  70643. + pciData & PBBLR_MEM_BASE_MASK;
  70644. +
  70645. +
  70646. + }
  70647. + else /* IO Bar */
  70648. + {
  70649. + pPciAgent->pciBar[detectedBar].barBaseLow =
  70650. + pciData & PBBLR_IO_BASE_MASK;
  70651. +
  70652. + }
  70653. +
  70654. + pPciAgent->pciBar[detectedBar].barBaseHigh=0;
  70655. +
  70656. + if (PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType)
  70657. + {
  70658. + barIndex++;
  70659. +
  70660. + tmpBaseHigh = pPciAgent->pciBar[detectedBar].barBaseHigh =
  70661. + mvPciIfConfigRead(pciIf,
  70662. + bus,dev,func,
  70663. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  70664. +
  70665. +
  70666. + }
  70667. +
  70668. + /* calculating full base address (64bit) */
  70669. + pPciAgent->pciBar[detectedBar].barBaseAddr =
  70670. + (MV_U64)pPciAgent->pciBar[detectedBar].barBaseHigh;
  70671. +
  70672. + pPciAgent->pciBar[detectedBar].barBaseAddr <<= 32;
  70673. +
  70674. + pPciAgent->pciBar[detectedBar].barBaseAddr |=
  70675. + (MV_U64)pPciAgent->pciBar[detectedBar].barBaseLow;
  70676. +
  70677. +
  70678. +
  70679. + /* get the sizes of the the bar */
  70680. +
  70681. + pPciAgent->pciBar[detectedBar].barSizeHigh=0;
  70682. +
  70683. + if ((PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType) &&
  70684. + (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping))
  70685. +
  70686. + {
  70687. + /* write oxffffffff to the bar to get the size */
  70688. + /* start with sizelow ( original value was saved in tmpBaseLow ) */
  70689. + mvPciIfConfigWrite(pciIf,
  70690. + bus,dev,func,
  70691. + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
  70692. + 0xffffffff);
  70693. +
  70694. + /* read size */
  70695. + pPciAgent->pciBar[detectedBar].barSizeLow =
  70696. + mvPciIfConfigRead(pciIf,
  70697. + bus,dev,func,
  70698. + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1));
  70699. +
  70700. +
  70701. +
  70702. + /* restore original value */
  70703. + mvPciIfConfigWrite(pciIf,
  70704. + bus,dev,func,
  70705. + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
  70706. + tmpBaseLow);
  70707. +
  70708. +
  70709. + /* now do the same for BaseHigh */
  70710. +
  70711. + /* write oxffffffff to the bar to get the size */
  70712. + mvPciIfConfigWrite(pciIf,
  70713. + bus,dev,func,
  70714. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  70715. + 0xffffffff);
  70716. +
  70717. + /* read size */
  70718. + pPciAgent->pciBar[detectedBar].barSizeHigh =
  70719. + mvPciIfConfigRead(pciIf,
  70720. + bus,dev,func,
  70721. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  70722. +
  70723. + /* restore original value */
  70724. + mvPciIfConfigWrite(pciIf,
  70725. + bus,dev,func,
  70726. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  70727. + tmpBaseHigh);
  70728. +
  70729. + if ((0 == pPciAgent->pciBar[detectedBar].barSizeLow)&&
  70730. + (0 == pPciAgent->pciBar[detectedBar].barSizeHigh))
  70731. + {
  70732. + /* this bar is not applicable for this device,
  70733. + ignore all previous settings and check the next bar*/
  70734. +
  70735. + /* we though this was a 64bit bar , and it seems this
  70736. + was wrong ! so decrement barIndex */
  70737. + barIndex--;
  70738. + continue;
  70739. + }
  70740. +
  70741. + /* calculate the full 64 bit size */
  70742. +
  70743. + if (0 != pPciAgent->pciBar[detectedBar].barSizeHigh)
  70744. + {
  70745. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
  70746. +
  70747. + pPciAgent->pciBar[detectedBar].barSizeLow =
  70748. + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
  70749. +
  70750. + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
  70751. +
  70752. + }
  70753. + else
  70754. + {
  70755. +
  70756. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
  70757. +
  70758. + pPciAgent->pciBar[detectedBar].barSizeLow =
  70759. + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
  70760. +
  70761. + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
  70762. +
  70763. + }
  70764. +
  70765. +
  70766. +
  70767. + }
  70768. + else /* 32bit bar */
  70769. + {
  70770. + /* write oxffffffff to the bar to get the size */
  70771. + mvPciIfConfigWrite(pciIf,
  70772. + bus,dev,func,
  70773. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  70774. + 0xffffffff);
  70775. +
  70776. + /* read size */
  70777. + pPciAgent->pciBar[detectedBar].barSizeLow =
  70778. + mvPciIfConfigRead(pciIf,
  70779. + bus,dev,func,
  70780. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  70781. +
  70782. + if (0 == pPciAgent->pciBar[detectedBar].barSizeLow)
  70783. + {
  70784. + /* this bar is not applicable for this device,
  70785. + ignore all previous settings and check the next bar*/
  70786. + continue;
  70787. + }
  70788. +
  70789. +
  70790. + /* restore original value */
  70791. + mvPciIfConfigWrite(pciIf,
  70792. + bus,dev,func,
  70793. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  70794. + tmpBaseLow);
  70795. +
  70796. + /* calculate size low */
  70797. +
  70798. + if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
  70799. + {
  70800. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
  70801. + }
  70802. + else
  70803. + {
  70804. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_IO_BASE_MASK;
  70805. + }
  70806. +
  70807. + pPciAgent->pciBar[detectedBar].barSizeLow =
  70808. + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
  70809. +
  70810. + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
  70811. + pPciAgent->pciBar[detectedBar].barSize =
  70812. + (MV_U64)pPciAgent->pciBar[detectedBar].barSizeLow;
  70813. +
  70814. +
  70815. + }
  70816. +
  70817. + /* we are here ! this means we have already detected a bar for
  70818. + this device , now move on */
  70819. +
  70820. + detectedBar++;
  70821. + pPciAgent->barsNum++;
  70822. + }
  70823. +
  70824. + return detectedBar;
  70825. +}
  70826. +
  70827. +
  70828. +/*******************************************************************************
  70829. +* mvPciClassNameGet - get PCI class name
  70830. +*
  70831. +* DESCRIPTION:
  70832. +* This function returns the PCI class name
  70833. +*
  70834. +* INPUT:
  70835. +* baseClassCode - Base Class Code.
  70836. +*
  70837. +* OUTPUT:
  70838. +* pType - the class name
  70839. +*
  70840. +* RETURN:
  70841. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  70842. +*
  70843. +*******************************************************************************/
  70844. +MV_STATUS mvPciClassNameGet(MV_U32 baseClassCode, MV_8 *pType)
  70845. +{
  70846. +
  70847. + switch(baseClassCode)
  70848. + {
  70849. + case 0x0:
  70850. + strcpy(pType,"Old generation device");
  70851. + break;
  70852. + case 0x1:
  70853. + strcpy(pType,"Mass storage controller");
  70854. + break;
  70855. + case 0x2:
  70856. + strcpy(pType,"Network controller");
  70857. + break;
  70858. + case 0x3:
  70859. + strcpy(pType,"Display controller");
  70860. + break;
  70861. + case 0x4:
  70862. + strcpy(pType,"Multimedia device");
  70863. + break;
  70864. + case 0x5:
  70865. + strcpy(pType,"Memory controller");
  70866. + break;
  70867. + case 0x6:
  70868. + strcpy(pType,"Bridge Device");
  70869. + break;
  70870. + case 0x7:
  70871. + strcpy(pType,"Simple Communication controllers");
  70872. + break;
  70873. + case 0x8:
  70874. + strcpy(pType,"Base system peripherals");
  70875. + break;
  70876. + case 0x9:
  70877. + strcpy(pType,"Input Devices");
  70878. + break;
  70879. + case 0xa:
  70880. + strcpy(pType,"Docking stations");
  70881. + break;
  70882. + case 0xb:
  70883. + strcpy(pType,"Processors");
  70884. + break;
  70885. + case 0xc:
  70886. + strcpy(pType,"Serial bus controllers");
  70887. + break;
  70888. + case 0xd:
  70889. + strcpy(pType,"Wireless controllers");
  70890. + break;
  70891. + case 0xe:
  70892. + strcpy(pType,"Intelligent I/O controllers");
  70893. + break;
  70894. + case 0xf:
  70895. + strcpy(pType,"Satellite communication controllers");
  70896. + break;
  70897. + case 0x10:
  70898. + strcpy(pType,"Encryption/Decryption controllers");
  70899. + break;
  70900. + case 0x11:
  70901. + strcpy(pType,"Data acquisition and signal processing controllers");
  70902. + break;
  70903. + default:
  70904. + strcpy(pType,"Unknown device");
  70905. + break;
  70906. + }
  70907. +
  70908. + return MV_OK;
  70909. +
  70910. +}
  70911. +
  70912. +
  70913. +
  70914. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h
  70915. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h 1970-01-01 01:00:00.000000000 +0100
  70916. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h 2010-11-09 20:28:11.662495451 +0100
  70917. @@ -0,0 +1,323 @@
  70918. +/*******************************************************************************
  70919. +Copyright (C) Marvell International Ltd. and its affiliates
  70920. +
  70921. +This software file (the "File") is owned and distributed by Marvell
  70922. +International Ltd. and/or its affiliates ("Marvell") under the following
  70923. +alternative licensing terms. Once you have made an election to distribute the
  70924. +File under one of the following license alternatives, please (i) delete this
  70925. +introductory statement regarding license alternatives, (ii) delete the two
  70926. +license alternatives that you have not elected to use and (iii) preserve the
  70927. +Marvell copyright notice above.
  70928. +
  70929. +********************************************************************************
  70930. +Marvell Commercial License Option
  70931. +
  70932. +If you received this File from Marvell and you have entered into a commercial
  70933. +license agreement (a "Commercial License") with Marvell, the File is licensed
  70934. +to you under the terms of the applicable Commercial License.
  70935. +
  70936. +********************************************************************************
  70937. +Marvell GPL License Option
  70938. +
  70939. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70940. +modify this File in accordance with the terms and conditions of the General
  70941. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  70942. +available along with the File in the license.txt file or by writing to the Free
  70943. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  70944. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  70945. +
  70946. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  70947. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  70948. +DISCLAIMED. The GPL License provides additional details about this warranty
  70949. +disclaimer.
  70950. +********************************************************************************
  70951. +Marvell BSD License Option
  70952. +
  70953. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70954. +modify this File under the following licensing terms.
  70955. +Redistribution and use in source and binary forms, with or without modification,
  70956. +are permitted provided that the following conditions are met:
  70957. +
  70958. + * Redistributions of source code must retain the above copyright notice,
  70959. + this list of conditions and the following disclaimer.
  70960. +
  70961. + * Redistributions in binary form must reproduce the above copyright
  70962. + notice, this list of conditions and the following disclaimer in the
  70963. + documentation and/or other materials provided with the distribution.
  70964. +
  70965. + * Neither the name of Marvell nor the names of its contributors may be
  70966. + used to endorse or promote products derived from this software without
  70967. + specific prior written permission.
  70968. +
  70969. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  70970. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  70971. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  70972. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  70973. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  70974. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  70975. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  70976. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  70977. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  70978. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  70979. +
  70980. +*******************************************************************************/
  70981. +
  70982. +#ifndef __INCmvPciUtilsh
  70983. +#define __INCmvPciUtilsh
  70984. +
  70985. +/*
  70986. +This module only support scanning of Header type 00h of pci devices
  70987. +There is no suppotr for Header type 01h of pci devices ( PCI bridges )
  70988. +*/
  70989. +
  70990. +/* includes */
  70991. +#include "mvSysHwConfig.h"
  70992. +#include "pci-if/mvPciIf.h"
  70993. +#include "pci/mvPciRegs.h"
  70994. +
  70995. +
  70996. +
  70997. +/* PCI base address low bar mask */
  70998. +#define PCI_ERROR_CODE 0xffffffff
  70999. +
  71000. +#define PCI_BRIDGE_CLASS 0x6
  71001. +#define P2P_BRIDGE_SUB_CLASS_CODE 0x4
  71002. +
  71003. +
  71004. +#define P2P_BUSSES_NUM 0x18
  71005. +#define P2P_IO_BASE_LIMIT_SEC_STATUS 0x1C
  71006. +#define P2P_MEM_BASE_LIMIT 0x20
  71007. +#define P2P_PREF_MEM_BASE_LIMIT 0x24
  71008. +#define P2P_PREF_BASE_UPPER_32 0x28
  71009. +#define P2P_PREF_LIMIT_UPPER_32 0x2C
  71010. +#define P2P_IO_BASE_LIMIT_UPPER_16 0x30
  71011. +#define P2P_EXP_ROM 0x38
  71012. +
  71013. +/* P2P_BUSSES_NUM (PBM) */
  71014. +
  71015. +#define PBM_PRIME_BUS_NUM_OFFS 0
  71016. +#define PBM_PRIME_BUS_NUM_MASK (0xff << PBM_PRIME_BUS_NUM_OFFS)
  71017. +
  71018. +#define PBM_SEC_BUS_NUM_OFFS 8
  71019. +#define PBM_SEC_BUS_NUM_MASK (0xff << PBM_SEC_BUS_NUM_OFFS)
  71020. +
  71021. +#define PBM_SUB_BUS_NUM_OFFS 16
  71022. +#define PBM_SUB_BUS_NUM_MASK (0xff << PBM_SUB_BUS_NUM_OFFS)
  71023. +
  71024. +#define PBM_SEC_LAT_TMR_OFFS 24
  71025. +#define PBM_SEC_LAT_TMR_MASK (0xff << PBM_SEC_LAT_TMR_OFFS)
  71026. +
  71027. +/* P2P_IO_BASE_LIMIT_SEC_STATUS (PIBLSS) */
  71028. +
  71029. +#define PIBLSS_IO_BASE_OFFS 0
  71030. +#define PIBLSS_IO_BASE_MASK (0xff << PIBLSS_IO_BASE_OFFS)
  71031. +
  71032. +#define PIBLSS_ADD_CAP_OFFS 0
  71033. +#define PIBLSS_ADD_CAP_MASK (0x3 << PIBLSS_ADD_CAP_OFFS)
  71034. +#define PIBLSS_ADD_CAP_16BIT (0x0 << PIBLSS_ADD_CAP_OFFS)
  71035. +#define PIBLSS_ADD_CAP_32BIT (0x1 << PIBLSS_ADD_CAP_OFFS)
  71036. +
  71037. +#define PIBLSS_LOW_ADDR_OFFS 0
  71038. +#define PIBLSS_LOW_ADDR_MASK (0xFFF << PIBLSS_LOW_ADDR_OFFS)
  71039. +
  71040. +#define PIBLSS_HIGH_ADDR_OFFS 12
  71041. +#define PIBLSS_HIGH_ADDR_MASK (0xF << PIBLSS_HIGH_ADDR_OFFS)
  71042. +
  71043. +#define PIBLSS_IO_LIMIT_OFFS 8
  71044. +#define PIBLSS_IO_LIMIT_MASK (0xff << PIBLSS_IO_LIMIT_OFFS)
  71045. +
  71046. +#define PIBLSS_SEC_STATUS_OFFS 16
  71047. +#define PIBLSS_SEC_STATUS_MASK (0xffff << PIBLSS_SEC_STATUS_OFFS)
  71048. +
  71049. +
  71050. +/* P2P_MEM_BASE_LIMIT (PMBL)*/
  71051. +
  71052. +#define PMBL_MEM_BASE_OFFS 0
  71053. +#define PMBL_MEM_BASE_MASK (0xffff << PMBL_MEM_BASE_OFFS)
  71054. +
  71055. +#define PMBL_MEM_LIMIT_OFFS 16
  71056. +#define PMBL_MEM_LIMIT_MASK (0xffff << PMBL_MEM_LIMIT_OFFS)
  71057. +
  71058. +
  71059. +#define PMBL_LOW_ADDR_OFFS 0
  71060. +#define PMBL_LOW_ADDR_MASK (0xFFFFF << PMBL_LOW_ADDR_OFFS)
  71061. +
  71062. +#define PMBL_HIGH_ADDR_OFFS 20
  71063. +#define PMBL_HIGH_ADDR_MASK (0xFFF << PMBL_HIGH_ADDR_OFFS)
  71064. +
  71065. +
  71066. +/* P2P_PREF_MEM_BASE_LIMIT (PRMBL) */
  71067. +
  71068. +#define PRMBL_PREF_MEM_BASE_OFFS 0
  71069. +#define PRMBL_PREF_MEM_BASE_MASK (0xffff << PRMBL_PREF_MEM_BASE_OFFS)
  71070. +
  71071. +#define PRMBL_PREF_MEM_LIMIT_OFFS 16
  71072. +#define PRMBL_PREF_MEM_LIMIT_MASK (0xffff<<PRMBL_PREF_MEM_LIMIT_OFFS)
  71073. +
  71074. +#define PRMBL_LOW_ADDR_OFFS 0
  71075. +#define PRMBL_LOW_ADDR_MASK (0xFFFFF << PRMBL_LOW_ADDR_OFFS)
  71076. +
  71077. +#define PRMBL_HIGH_ADDR_OFFS 20
  71078. +#define PRMBL_HIGH_ADDR_MASK (0xFFF << PRMBL_HIGH_ADDR_OFFS)
  71079. +
  71080. +#define PRMBL_ADD_CAP_OFFS 0
  71081. +#define PRMBL_ADD_CAP_MASK (0xf << PRMBL_ADD_CAP_OFFS)
  71082. +#define PRMBL_ADD_CAP_32BIT (0x0 << PRMBL_ADD_CAP_OFFS)
  71083. +#define PRMBL_ADD_CAP_64BIT (0x1 << PRMBL_ADD_CAP_OFFS)
  71084. +
  71085. +/* P2P_IO_BASE_LIMIT_UPPER_16 (PIBLU) */
  71086. +
  71087. +#define PRBU_IO_UPP_BASE_OFFS 0
  71088. +#define PRBU_IO_UPP_BASE_MASK (0xffff << PRBU_IO_UPP_BASE_OFFS)
  71089. +
  71090. +#define PRBU_IO_UPP_LIMIT_OFFS 16
  71091. +#define PRBU_IO_UPP_LIMIT_MASK (0xffff << PRBU_IO_UPP_LIMIT_OFFS)
  71092. +
  71093. +
  71094. +/* typedefs */
  71095. +
  71096. +typedef enum _mvPciBarMapping
  71097. +{
  71098. + PCI_MEMORY_BAR,
  71099. + PCI_IO_BAR,
  71100. + PCI_NO_MAPPING
  71101. +}MV_PCI_BAR_MAPPING;
  71102. +
  71103. +typedef enum _mvPciBarType
  71104. +{
  71105. + PCI_32BIT_BAR,
  71106. + PCI_64BIT_BAR
  71107. +}MV_PCI_BAR_TYPE;
  71108. +
  71109. +typedef enum _mvPciIntPin
  71110. +{
  71111. + MV_PCI_INTA = 1,
  71112. + MV_PCI_INTB = 2,
  71113. + MV_PCI_INTC = 3,
  71114. + MV_PCI_INTD = 4
  71115. +}MV_PCI_INT_PIN;
  71116. +
  71117. +typedef enum _mvPciHeader
  71118. +{
  71119. + MV_PCI_STANDARD,
  71120. + MV_PCI_PCI2PCI_BRIDGE
  71121. +
  71122. +}MV_PCI_HEADER;
  71123. +
  71124. +
  71125. +/* BAR structure */
  71126. +typedef struct _pciBar
  71127. +{
  71128. + MV_U32 barOffset;
  71129. + MV_U32 barBaseLow;
  71130. + MV_U32 barBaseHigh;
  71131. + MV_U32 barSizeLow;
  71132. + MV_U32 barSizeHigh;
  71133. + /* The 'barBaseAddr' is a 64-bit variable
  71134. + that will contain the TOTAL base address
  71135. + value achived by combining both the 'barBaseLow'
  71136. + and the 'barBaseHigh' parameters as follows:
  71137. +
  71138. + BIT: 63 31 0
  71139. + | | |
  71140. + barBaseHigh barBaseLow */
  71141. + MV_U64 barBaseAddr;
  71142. + /* The 'barSize' is a 64-bit variable
  71143. + that will contain the TOTAL size achived
  71144. + by combining both the 'barSizeLow' and
  71145. + the 'barSizeHigh' parameters as follows:
  71146. +
  71147. + BIT: 63 31 0
  71148. + | | |
  71149. + barSizeHigh barSizeLow
  71150. +
  71151. + NOTE: The total size described above
  71152. + is AFTER the size calculation as
  71153. + described in PCI spec rev2.2 */
  71154. + MV_U64 barSize;
  71155. + MV_BOOL isPrefetchable;
  71156. + MV_PCI_BAR_TYPE barType;
  71157. + MV_PCI_BAR_MAPPING barMapping;
  71158. +
  71159. +
  71160. +} PCI_BAR;
  71161. +
  71162. +/* Device information structure */
  71163. +typedef struct _mvPciDevice
  71164. +{
  71165. + /* Device specific information */
  71166. + MV_U32 busNumber; /* Pci agent bus number */
  71167. + MV_U32 deviceNum; /* Pci agent device number */
  71168. + MV_U32 function; /* Pci agent function number */
  71169. +
  71170. + MV_U32 venID; /* Pci agent Vendor ID */
  71171. + MV_U32 deviceID; /* Pci agent Device ID */
  71172. +
  71173. + MV_BOOL isFastB2BCapable; /* Capability of Fast Back to Back
  71174. + transactions */
  71175. + MV_BOOL isCapListSupport; /* Support of Capability list */
  71176. + MV_BOOL is66MHZCapable; /* 66MHZ support */
  71177. +
  71178. + MV_U32 baseClassCode; /* Pci agent base Class Code */
  71179. + MV_U32 subClassCode; /* Pci agent sub Class Code */
  71180. + MV_U32 progIf; /* Pci agent Programing interface */
  71181. + MV_U32 revisionID;
  71182. +
  71183. + PCI_BAR pciBar[6]; /* Pci agent bar list */
  71184. +
  71185. + MV_U32 p2pPrimBusNum; /* P2P Primary Bus number*/
  71186. + MV_U32 p2pSecBusNum; /* P2P Secondary Bus Number*/
  71187. + MV_U32 p2pSubBusNum; /* P2P Subordinate bus Number */
  71188. + MV_U32 p2pSecLatencyTimer; /* P2P Econdary Latency Timer*/
  71189. + MV_U32 p2pIObase; /* P2P IO Base */
  71190. + MV_U32 p2pIOLimit; /* P2P IO Linit */
  71191. + MV_BOOL bIO32;
  71192. + MV_U32 p2pSecStatus; /* P2P Secondary Status */
  71193. + MV_U32 p2pMemBase; /* P2P Memory Space */
  71194. + MV_U32 p2pMemLimit; /* P2P Memory Limit*/
  71195. + MV_U32 p2pPrefMemBase; /* P2P Prefetchable Mem Base*/
  71196. + MV_U32 p2pPrefMemLimit; /* P2P Prefetchable Memory Limit*/
  71197. + MV_BOOL bPrefMem64;
  71198. + MV_U32 p2pPrefBaseUpper32Bits;/* P2P Prefetchable upper 32 bits*/
  71199. + MV_U32 p2pPrefLimitUpper32Bits;/* P2P prefetchable limit upper 32*/
  71200. +
  71201. +
  71202. + MV_U32 pciCacheLine; /* Pci agent cache line */
  71203. + MV_U32 pciLatencyTimer; /* Pci agent Latency timer */
  71204. + MV_PCI_HEADER pciHeader; /* Pci agent header type*/
  71205. + MV_BOOL isMultiFunction; /* Multi function support */
  71206. + MV_BOOL isBISTCapable; /* Self test capable */
  71207. +
  71208. + MV_U32 subSysID; /* Sub System ID */
  71209. + MV_U32 subSysVenID; /* Sub System Vendor ID */
  71210. +
  71211. + MV_BOOL isExpRom; /* Expantion Rom support */
  71212. + MV_U32 expRomAddr; /* Expantion Rom pointer */
  71213. +
  71214. + MV_U32 capListPointer; /* Capability list pointer */
  71215. +
  71216. + MV_U32 irqLine; /* IRQ line */
  71217. + MV_PCI_INT_PIN intPin; /* Interrupt pin */
  71218. + MV_U32 minGrant; /* Minimum grant*/
  71219. + MV_U32 maxLatency; /* Maximum latency*/
  71220. +
  71221. + MV_U32 funtionsNum; /* pci agent total functions number */
  71222. +
  71223. + MV_U32 barsNum;
  71224. + MV_U8 type[60]; /* class name of the pci agent */
  71225. +
  71226. +
  71227. +} MV_PCI_DEVICE;
  71228. +
  71229. +/* PCI gloabl functions */
  71230. +MV_STATUS mvPciClassNameGet(MV_U32 classCode, MV_8 *pType);
  71231. +
  71232. +
  71233. +/* Performs a full scan on both PCIs and returns all possible details on the
  71234. + agents found on the bus. */
  71235. +MV_STATUS mvPciScan(MV_U32 pciIf,
  71236. + MV_PCI_DEVICE *pPciAgents,
  71237. + MV_U32 *pPciAgentsNum);
  71238. +
  71239. +
  71240. +#endif /* #ifndef __INCmvPciUtilsh */
  71241. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c
  71242. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c 1970-01-01 01:00:00.000000000 +0100
  71243. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c 2010-11-09 20:28:11.702495387 +0100
  71244. @@ -0,0 +1,1143 @@
  71245. +/*******************************************************************************
  71246. +Copyright (C) Marvell International Ltd. and its affiliates
  71247. +
  71248. +This software file (the "File") is owned and distributed by Marvell
  71249. +International Ltd. and/or its affiliates ("Marvell") under the following
  71250. +alternative licensing terms. Once you have made an election to distribute the
  71251. +File under one of the following license alternatives, please (i) delete this
  71252. +introductory statement regarding license alternatives, (ii) delete the two
  71253. +license alternatives that you have not elected to use and (iii) preserve the
  71254. +Marvell copyright notice above.
  71255. +
  71256. +********************************************************************************
  71257. +Marvell Commercial License Option
  71258. +
  71259. +If you received this File from Marvell and you have entered into a commercial
  71260. +license agreement (a "Commercial License") with Marvell, the File is licensed
  71261. +to you under the terms of the applicable Commercial License.
  71262. +
  71263. +********************************************************************************
  71264. +Marvell GPL License Option
  71265. +
  71266. +If you received this File from Marvell, you may opt to use, redistribute and/or
  71267. +modify this File in accordance with the terms and conditions of the General
  71268. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  71269. +available along with the File in the license.txt file or by writing to the Free
  71270. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  71271. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  71272. +
  71273. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  71274. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  71275. +DISCLAIMED. The GPL License provides additional details about this warranty
  71276. +disclaimer.
  71277. +********************************************************************************
  71278. +Marvell BSD License Option
  71279. +
  71280. +If you received this File from Marvell, you may opt to use, redistribute and/or
  71281. +modify this File under the following licensing terms.
  71282. +Redistribution and use in source and binary forms, with or without modification,
  71283. +are permitted provided that the following conditions are met:
  71284. +
  71285. + * Redistributions of source code must retain the above copyright notice,
  71286. + this list of conditions and the following disclaimer.
  71287. +
  71288. + * Redistributions in binary form must reproduce the above copyright
  71289. + notice, this list of conditions and the following disclaimer in the
  71290. + documentation and/or other materials provided with the distribution.
  71291. +
  71292. + * Neither the name of Marvell nor the names of its contributors may be
  71293. + used to endorse or promote products derived from this software without
  71294. + specific prior written permission.
  71295. +
  71296. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  71297. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  71298. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  71299. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  71300. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  71301. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  71302. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  71303. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  71304. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  71305. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  71306. +
  71307. +*******************************************************************************/
  71308. +
  71309. +#include "pex/mvPex.h"
  71310. +
  71311. +#include "ctrlEnv/mvCtrlEnvLib.h"
  71312. +
  71313. +/* defines */
  71314. +#ifdef MV_DEBUG
  71315. +#define DB(x) x
  71316. +#else
  71317. +#define DB(x)
  71318. +#endif
  71319. +
  71320. +MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
  71321. +{
  71322. + MV_PEX_MODE pexMode;
  71323. + MV_U32 regVal;
  71324. + MV_U32 status;
  71325. +
  71326. + /* First implement Guideline (GL# PCI Express-2) Wrong Default Value */
  71327. + /* to Transmitter Output Current (TXAMP) Relevant for: 88F5181-A1/B0/B1 */
  71328. + /* and 88F5281-B0 and above, 88F5182, 88F5082, 88F5181L, 88F6082/L */
  71329. +
  71330. + if ((mvCtrlModelGet() != MV_1281_DEV_ID) &&
  71331. + (mvCtrlModelGet() != MV_6281_DEV_ID) &&
  71332. + (mvCtrlModelGet() != MV_6192_DEV_ID) &&
  71333. + (mvCtrlModelGet() != MV_6190_DEV_ID) &&
  71334. + (mvCtrlModelGet() != MV_6180_DEV_ID) &&
  71335. + (mvCtrlModelGet() != MV_6183_DEV_ID) &&
  71336. + (mvCtrlModelGet() != MV_6183L_DEV_ID) &&
  71337. + (mvCtrlModelGet() != MV_78100_DEV_ID) &&
  71338. + (mvCtrlModelGet() != MV_78200_DEV_ID) &&
  71339. + (mvCtrlModelGet() != MV_76100_DEV_ID) &&
  71340. + (mvCtrlModelGet() != MV_78XX0_DEV_ID))
  71341. + {
  71342. +
  71343. + /* Read current value of TXAMP */
  71344. + MV_REG_WRITE(0x41b00, 0x80820000); /* Write the read command */
  71345. +
  71346. + regVal = MV_REG_READ(0x41b00); /* Extract the data */
  71347. +
  71348. + /* Prepare new data for write */
  71349. + regVal &= ~0x7; /* Clear bits [2:0] */
  71350. + regVal |= 0x4; /* Set the new value */
  71351. + regVal &= ~0x80000000; /* Set "write" command */
  71352. + MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
  71353. +
  71354. + }
  71355. + else
  71356. + {
  71357. + /* Implement 1.0V termination GL for 88F1281 device only */
  71358. + /* BIT0 - Common mode feedback */
  71359. + /* BIT3 - TxBuf, extra drive for 1.0V termination */
  71360. + if (mvCtrlModelGet() == MV_1281_DEV_ID)
  71361. + {
  71362. + MV_REG_WRITE(0x41b00, 0x80860000); /* Write the read command */
  71363. + regVal = MV_REG_READ(0x41b00); /* Extract the data */
  71364. + regVal |= (BIT0 | BIT3);
  71365. + regVal &= ~0x80000000; /* Set "write" command */
  71366. + MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
  71367. +
  71368. + MV_REG_WRITE(0x31b00, 0x80860000); /* Write the read command */
  71369. + regVal = MV_REG_READ(0x31b00); /* Extract the data */
  71370. + regVal |= (BIT0 | BIT3);
  71371. + regVal &= ~0x80000000; /* Set "write" command */
  71372. + MV_REG_WRITE(0x31b00, regVal); /* Write the write command */
  71373. + }
  71374. + }
  71375. +
  71376. + if( mvPexModeGet(pexIf, &pexMode) != MV_OK)
  71377. + {
  71378. + mvOsPrintf("PEX init ERR. mvPexModeGet failed (pexType=%d)\n",pexMode.pexType);
  71379. + return MV_ERROR;
  71380. + }
  71381. +
  71382. + /* Check that required PEX type is the one set in reset time */
  71383. + if (pexType != pexMode.pexType)
  71384. + {
  71385. + /* No Link. Shut down the Phy */
  71386. + mvPexPowerDown(pexIf);
  71387. + mvOsPrintf("PEX init ERR. PEX type sampled mismatch (%d,%d)\n",pexType,pexMode.pexType);
  71388. + return MV_ERROR;
  71389. + }
  71390. +
  71391. + if (MV_PEX_ROOT_COMPLEX == pexType)
  71392. + {
  71393. + mvPexLocalBusNumSet(pexIf, PEX_HOST_BUS_NUM(pexIf));
  71394. + mvPexLocalDevNumSet(pexIf, PEX_HOST_DEV_NUM(pexIf));
  71395. +
  71396. + /* Local device master Enable */
  71397. + mvPexMasterEnable(pexIf, MV_TRUE);
  71398. +
  71399. + /* Local device slave Enable */
  71400. + mvPexSlaveEnable(pexIf, mvPexLocalBusNumGet(pexIf),
  71401. + mvPexLocalDevNumGet(pexIf), MV_TRUE);
  71402. + /* Interrupt disable */
  71403. + status = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND));
  71404. + status |= PXSAC_INT_DIS;
  71405. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND), status);
  71406. + }
  71407. +
  71408. + /* now wait 500 ms to be sure the link is valid (spec compliant) */
  71409. + mvOsDelay(500);
  71410. + /* Check if we have link */
  71411. + if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
  71412. + {
  71413. + mvOsPrintf("PEX%d interface detected no Link.\n",pexIf);
  71414. + return MV_NO_SUCH;
  71415. + }
  71416. +
  71417. + if (MV_PEX_WITDH_X1 == pexMode.pexWidth)
  71418. + {
  71419. + mvOsPrintf("PEX%d interface detected Link X1\n",pexIf);
  71420. + }
  71421. + else
  71422. + {
  71423. + mvOsPrintf("PEX%d interface detected Link X4\n",pexIf);
  71424. + }
  71425. +
  71426. +#ifdef PCIE_VIRTUAL_BRIDGE_SUPPORT
  71427. + mvPexVrtBrgInit(pexIf);
  71428. +#endif
  71429. + return MV_OK;
  71430. +}
  71431. +
  71432. +/*******************************************************************************
  71433. +* mvPexModeGet - Get Pex Mode
  71434. +*
  71435. +* DESCRIPTION:
  71436. +*
  71437. +* INPUT:
  71438. +* pexIf - PEX interface number.
  71439. +*
  71440. +* OUTPUT:
  71441. +* pexMode - Pex mode structure
  71442. +*
  71443. +* RETURN:
  71444. +* MV_OK on success , MV_ERROR otherwise
  71445. +*
  71446. +*******************************************************************************/
  71447. +MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode)
  71448. +{
  71449. + MV_U32 pexData;
  71450. +
  71451. + /* Parameter checking */
  71452. + if (PEX_DEFAULT_IF != pexIf)
  71453. + {
  71454. + if (pexIf >= mvCtrlPexMaxIfGet())
  71455. + {
  71456. + mvOsPrintf("mvPexModeGet: ERR. Invalid PEX interface %d\n",pexIf);
  71457. + return MV_ERROR;
  71458. + }
  71459. + }
  71460. +
  71461. + pexData = MV_REG_READ(PEX_CTRL_REG(pexIf));
  71462. +
  71463. + switch (pexData & PXCR_DEV_TYPE_CTRL_MASK)
  71464. + {
  71465. + case PXCR_DEV_TYPE_CTRL_CMPLX:
  71466. + pexMode->pexType = MV_PEX_ROOT_COMPLEX;
  71467. + break;
  71468. + case PXCR_DEV_TYPE_CTRL_POINT:
  71469. + pexMode->pexType = MV_PEX_END_POINT;
  71470. + break;
  71471. +
  71472. + }
  71473. +
  71474. + /* Check if we have link */
  71475. + if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
  71476. + {
  71477. + pexMode->pexLinkUp = MV_FALSE;
  71478. +
  71479. + /* If there is no link, the auto negotiation data is worthless */
  71480. + pexMode->pexWidth = MV_PEX_WITDH_INVALID;
  71481. + }
  71482. + else
  71483. + {
  71484. + pexMode->pexLinkUp = MV_TRUE;
  71485. +
  71486. + /* We have link. The link width is now valid */
  71487. + pexData = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG));
  71488. + pexMode->pexWidth = ((pexData & PXLCSR_NEG_LNK_WDTH_MASK) >>
  71489. + PXLCSR_NEG_LNK_WDTH_OFFS);
  71490. + }
  71491. +
  71492. + return MV_OK;
  71493. +}
  71494. +
  71495. +
  71496. +/* PEX configuration space read write */
  71497. +
  71498. +/*******************************************************************************
  71499. +* mvPexConfigRead - Read from configuration space
  71500. +*
  71501. +* DESCRIPTION:
  71502. +* This function performs a 32 bit read from PEX configuration space.
  71503. +* It supports both type 0 and type 1 of Configuration Transactions
  71504. +* (local and over bridge). In order to read from local bus segment, use
  71505. +* bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
  71506. +* will result configuration transaction of type 1 (over bridge).
  71507. +*
  71508. +* INPUT:
  71509. +* pexIf - PEX interface number.
  71510. +* bus - PEX segment bus number.
  71511. +* dev - PEX device number.
  71512. +* func - Function number.
  71513. +* regOffs - Register offset.
  71514. +*
  71515. +* OUTPUT:
  71516. +* None.
  71517. +*
  71518. +* RETURN:
  71519. +* 32bit register data, 0xffffffff on error
  71520. +*
  71521. +*******************************************************************************/
  71522. +MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  71523. + MV_U32 regOff)
  71524. +{
  71525. +#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
  71526. + return mvPexVrtBrgConfigRead (pexIf, bus, dev, func, regOff);
  71527. +}
  71528. +
  71529. +MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  71530. + MV_U32 regOff)
  71531. +{
  71532. +#endif
  71533. + MV_U32 pexData = 0;
  71534. + MV_U32 localDev,localBus;
  71535. +
  71536. + /* Parameter checking */
  71537. + if (PEX_DEFAULT_IF != pexIf)
  71538. + {
  71539. + if (pexIf >= mvCtrlPexMaxIfGet())
  71540. + {
  71541. + mvOsPrintf("mvPexConfigRead: ERR. Invalid PEX interface %d\n",pexIf);
  71542. + return 0xFFFFFFFF;
  71543. + }
  71544. + }
  71545. +
  71546. + if (dev >= MAX_PEX_DEVICES)
  71547. + {
  71548. + DB(mvOsPrintf("mvPexConfigRead: ERR. device number illigal %d\n", dev));
  71549. + return 0xFFFFFFFF;
  71550. + }
  71551. +
  71552. + if (func >= MAX_PEX_FUNCS)
  71553. + {
  71554. + DB(mvOsPrintf("mvPexConfigRead: ERR. function num illigal %d\n", func));
  71555. + return 0xFFFFFFFF;
  71556. + }
  71557. +
  71558. + if (bus >= MAX_PEX_BUSSES)
  71559. + {
  71560. + DB(mvOsPrintf("mvPexConfigRead: ERR. bus number illigal %d\n", bus));
  71561. + return MV_ERROR;
  71562. + }
  71563. +
  71564. + DB(mvOsPrintf("mvPexConfigRead: pexIf %d, bus %d, dev %d, func %d, regOff 0x%x\n",
  71565. + pexIf, bus, dev, func, regOff));
  71566. +
  71567. + localDev = mvPexLocalDevNumGet(pexIf);
  71568. + localBus = mvPexLocalBusNumGet(pexIf);
  71569. +
  71570. + /* Speed up the process. In case on no link, return MV_ERROR */
  71571. + if ((dev != localDev) || (bus != localBus))
  71572. + {
  71573. + pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
  71574. +
  71575. + if ((pexData & PXSR_DL_DOWN))
  71576. + {
  71577. + return MV_ERROR;
  71578. + }
  71579. + }
  71580. +
  71581. + /* in PCI Express we have only one device number */
  71582. + /* and this number is the first number we encounter
  71583. + else that the localDev*/
  71584. + /* spec pex define return on config read/write on any device */
  71585. + if (bus == localBus)
  71586. + {
  71587. + if (localDev == 0)
  71588. + {
  71589. + /* if local dev is 0 then the first number we encounter
  71590. + after 0 is 1 */
  71591. + if ((dev != 1)&&(dev != localDev))
  71592. + {
  71593. + return MV_ERROR;
  71594. + }
  71595. + }
  71596. + else
  71597. + {
  71598. + /* if local dev is not 0 then the first number we encounter
  71599. + is 0 */
  71600. +
  71601. + if ((dev != 0)&&(dev != localDev))
  71602. + {
  71603. + return MV_ERROR;
  71604. + }
  71605. + }
  71606. + if(func != 0 ) /* i.e bridge */
  71607. + {
  71608. + return MV_ERROR;
  71609. + }
  71610. + }
  71611. +
  71612. +
  71613. + /* Creating PEX address to be passed */
  71614. + pexData = (bus << PXCAR_BUS_NUM_OFFS);
  71615. + pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
  71616. + pexData |= (func << PXCAR_FUNC_NUM_OFFS);
  71617. + pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
  71618. + /* extended register space */
  71619. + pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
  71620. + PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
  71621. +
  71622. + pexData |= PXCAR_CONFIG_EN;
  71623. +
  71624. + /* Write the address to the PEX configuration address register */
  71625. + MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
  71626. +
  71627. + DB(mvOsPrintf("mvPexConfigRead:address pexData=%x ",pexData));
  71628. +
  71629. +
  71630. + /* In order to let the PEX controller absorbed the address of the read */
  71631. + /* transaction we perform a validity check that the address was written */
  71632. + if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
  71633. + {
  71634. + return MV_ERROR;
  71635. + }
  71636. +
  71637. + /* cleaning Master Abort */
  71638. + MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
  71639. + PXSAC_MABORT);
  71640. +#if 0
  71641. + /* Guideline (GL# PCI Express-1) Erroneous Read Data on Configuration */
  71642. + /* This guideline is relevant for all devices except of the following devices:
  71643. + 88F5281-BO and above, 88F5181L-A0 and above, 88F1281 A0 and above
  71644. + 88F6183 A0 and above, 88F6183L */
  71645. + if ( ( (dev != localDev) || (bus != localBus) ) &&
  71646. + (
  71647. + !(MV_5281_DEV_ID == mvCtrlModelGet())&&
  71648. + !((MV_5181_DEV_ID == mvCtrlModelGet())&& (mvCtrlRevGet() >= MV_5181L_A0_REV))&&
  71649. + !(MV_1281_DEV_ID == mvCtrlModelGet())&&
  71650. + !(MV_6183_DEV_ID == mvCtrlModelGet())&&
  71651. + !(MV_6183L_DEV_ID == mvCtrlModelGet())&&
  71652. + !(MV_6281_DEV_ID == mvCtrlModelGet())&&
  71653. + !(MV_6192_DEV_ID == mvCtrlModelGet())&&
  71654. + !(MV_6190_DEV_ID == mvCtrlModelGet())&&
  71655. + !(MV_6180_DEV_ID == mvCtrlModelGet())&&
  71656. + !(MV_78XX0_DEV_ID == mvCtrlModelGet())
  71657. + ))
  71658. + {
  71659. +
  71660. + /* PCI-Express configuration read work-around */
  71661. +
  71662. + /* we will use one of the Punit (AHBToMbus) windows to access the xbar
  71663. + and read the data from there */
  71664. + /*
  71665. + Need to configure the 2 free Punit (AHB to MBus bridge)
  71666. + address decoding windows:
  71667. + Configure the flash Window to handle Configuration space requests
  71668. + for PEX0/1:
  71669. + 1. write 0x7931/0x7941 to the flash window and the size,
  71670. + 79-xbar attr (pci cfg), 3/4-xbar target (pex0/1), 1-WinEn
  71671. + 2. write base to flash window
  71672. +
  71673. + Configuration transactions from the CPU should write/read the data
  71674. + to/from address of the form:
  71675. + addr[31:28] = 0x5 (for PEX0) or 0x6 (for PEX1)
  71676. + addr[27:24] = extended register number
  71677. + addr[23:16] = bus number
  71678. + addr[15:11] = device number
  71679. + addr[10:8] = function number
  71680. + addr[7:0] = register number
  71681. + */
  71682. +
  71683. + #include "ctrlEnv/sys/mvAhbToMbus.h"
  71684. + {
  71685. + MV_U32 winNum;
  71686. + MV_AHB_TO_MBUS_DEC_WIN originWin;
  71687. + MV_U32 pciAddr=0;
  71688. + MV_U32 remapLow=0,remapHigh=0;
  71689. +
  71690. + /*
  71691. + We will use DEV_CS2\Flash window for this workarround
  71692. + */
  71693. +
  71694. + winNum = mvAhbToMbusWinTargetGet(PEX_CONFIG_RW_WA_TARGET);
  71695. +
  71696. + /* save remap values if exist */
  71697. + if ((1 == winNum)||(0 == winNum))
  71698. + {
  71699. + remapLow = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum));
  71700. + remapHigh = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum));
  71701. +
  71702. + }
  71703. +
  71704. +
  71705. + /* save the original window values */
  71706. + mvAhbToMbusWinGet(winNum,&originWin);
  71707. +
  71708. + if (PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES)
  71709. + {
  71710. + /* set the window as xbar window */
  71711. + if (pexIf)
  71712. + {
  71713. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  71714. + (0x7931 | (((originWin.addrWin.size >> 16)-1) ) << 16));
  71715. + }
  71716. + else
  71717. + {
  71718. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  71719. + (0x7941 | (((originWin.addrWin.size >> 16)-1) ) << 16));
  71720. + }
  71721. +
  71722. + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
  71723. + originWin.addrWin.baseLow);
  71724. +
  71725. + /*pciAddr = originWin.addrWin.baseLow;*/
  71726. + pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(
  71727. + (MV_U32)originWin.addrWin.baseLow);
  71728. +
  71729. + }
  71730. + else
  71731. + {
  71732. + /* set the window as xbar window */
  71733. + if (pexIf)
  71734. + {
  71735. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  71736. + (0x7931 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
  71737. + }
  71738. + else
  71739. + {
  71740. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  71741. + (0x7941 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
  71742. + }
  71743. +
  71744. + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
  71745. + PEX_CONFIG_RW_WA_BASE);
  71746. +
  71747. + pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(PEX_CONFIG_RW_WA_BASE);
  71748. + }
  71749. +
  71750. +
  71751. + /* remap should be as base */
  71752. + if ((1 == winNum)||(0 == winNum))
  71753. + {
  71754. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),pciAddr);
  71755. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),0);
  71756. +
  71757. + }
  71758. +
  71759. + /* extended register space */
  71760. + pciAddr |= (bus << 16);
  71761. + pciAddr |= (dev << 11);
  71762. + pciAddr |= (func << 8);
  71763. + pciAddr |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
  71764. +
  71765. + pexData = *(MV_U32*)pciAddr;
  71766. + pexData = MV_32BIT_LE(pexData); /* Data always in LE */
  71767. +
  71768. + /* restore the original window values */
  71769. + mvAhbToMbusWinSet(winNum,&originWin);
  71770. +
  71771. + /* restore original remap values*/
  71772. + if ((1 == winNum)||(0 == winNum))
  71773. + {
  71774. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),remapLow);
  71775. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),remapHigh);
  71776. +
  71777. + }
  71778. + }
  71779. + }
  71780. + else
  71781. +#endif
  71782. + {
  71783. + /* Read the Data returned in the PEX Data register */
  71784. + pexData = MV_REG_READ(PEX_CFG_DATA_REG(pexIf));
  71785. +
  71786. + }
  71787. +
  71788. + DB(mvOsPrintf("mvPexConfigRead: got : %x \n",pexData));
  71789. +
  71790. + return pexData;
  71791. +
  71792. +}
  71793. +
  71794. +/*******************************************************************************
  71795. +* mvPexConfigWrite - Write to configuration space
  71796. +*
  71797. +* DESCRIPTION:
  71798. +* This function performs a 32 bit write to PEX configuration space.
  71799. +* It supports both type 0 and type 1 of Configuration Transactions
  71800. +* (local and over bridge). In order to write to local bus segment, use
  71801. +* bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
  71802. +* will result configuration transaction of type 1 (over bridge).
  71803. +*
  71804. +* INPUT:
  71805. +* pexIf - PEX interface number.
  71806. +* bus - PEX segment bus number.
  71807. +* dev - PEX device number.
  71808. +* func - Function number.
  71809. +* regOffs - Register offset.
  71810. +* data - 32bit data.
  71811. +*
  71812. +* OUTPUT:
  71813. +* None.
  71814. +*
  71815. +* RETURN:
  71816. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  71817. +*
  71818. +*******************************************************************************/
  71819. +MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  71820. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  71821. +{
  71822. +#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
  71823. + return mvPexVrtBrgConfigWrite (pexIf, bus, dev, func, regOff, data);
  71824. +}
  71825. +
  71826. +MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  71827. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  71828. +{
  71829. +#endif
  71830. + MV_U32 pexData = 0;
  71831. + MV_U32 localDev,localBus;
  71832. +
  71833. + /* Parameter checking */
  71834. + if (PEX_DEFAULT_IF != pexIf)
  71835. + {
  71836. + if (pexIf >= mvCtrlPexMaxIfGet())
  71837. + {
  71838. + mvOsPrintf("mvPexConfigWrite: ERR. Invalid PEX interface %d\n",
  71839. + pexIf);
  71840. + return MV_ERROR;
  71841. + }
  71842. + }
  71843. +
  71844. + if (dev >= MAX_PEX_DEVICES)
  71845. + {
  71846. + mvOsPrintf("mvPexConfigWrite: ERR. device number illigal %d\n",dev);
  71847. + return MV_BAD_PARAM;
  71848. + }
  71849. +
  71850. + if (func >= MAX_PEX_FUNCS)
  71851. + {
  71852. + mvOsPrintf("mvPexConfigWrite: ERR. function number illigal %d\n", func);
  71853. + return MV_ERROR;
  71854. + }
  71855. +
  71856. + if (bus >= MAX_PEX_BUSSES)
  71857. + {
  71858. + mvOsPrintf("mvPexConfigWrite: ERR. bus number illigal %d\n", bus);
  71859. + return MV_ERROR;
  71860. + }
  71861. +
  71862. +
  71863. +
  71864. + localDev = mvPexLocalDevNumGet(pexIf);
  71865. + localBus = mvPexLocalBusNumGet(pexIf);
  71866. +
  71867. +
  71868. + /* in PCI Express we have only one device number other than ourselves*/
  71869. + /* and this number is the first number we encounter
  71870. + else than the localDev that can be any valid dev number*/
  71871. + /* pex spec define return on config read/write on any device */
  71872. + if (bus == localBus)
  71873. + {
  71874. +
  71875. + if (localDev == 0)
  71876. + {
  71877. + /* if local dev is 0 then the first number we encounter
  71878. + after 0 is 1 */
  71879. + if ((dev != 1)&&(dev != localDev))
  71880. + {
  71881. + return MV_ERROR;
  71882. + }
  71883. +
  71884. + }
  71885. + else
  71886. + {
  71887. + /* if local dev is not 0 then the first number we encounter
  71888. + is 0 */
  71889. +
  71890. + if ((dev != 0)&&(dev != localDev))
  71891. + {
  71892. + return MV_ERROR;
  71893. + }
  71894. + }
  71895. +
  71896. +
  71897. + }
  71898. +
  71899. + /* if we are not accessing ourselves , then check the link */
  71900. + if ((dev != localDev) || (bus != localBus) )
  71901. + {
  71902. + /* workarround */
  71903. + /* when no link return MV_ERROR */
  71904. +
  71905. + pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
  71906. +
  71907. + if ((pexData & PXSR_DL_DOWN))
  71908. + {
  71909. + return MV_ERROR;
  71910. + }
  71911. +
  71912. + }
  71913. +
  71914. + pexData =0;
  71915. +
  71916. + /* Creating PEX address to be passed */
  71917. + pexData |= (bus << PXCAR_BUS_NUM_OFFS);
  71918. + pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
  71919. + pexData |= (func << PXCAR_FUNC_NUM_OFFS);
  71920. + pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
  71921. + /* extended register space */
  71922. + pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
  71923. + PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
  71924. + pexData |= PXCAR_CONFIG_EN;
  71925. +
  71926. + DB(mvOsPrintf("mvPexConfigWrite: If=%x bus=%x func=%x dev=%x regOff=%x data=%x \n",
  71927. + pexIf,bus,func,dev,regOff,data,pexData) );
  71928. +
  71929. + /* Write the address to the PEX configuration address register */
  71930. + MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
  71931. +
  71932. + /* Clear CPU pipe. Important where CPU can perform OOO execution */
  71933. + CPU_PIPE_FLUSH;
  71934. +
  71935. + /* In order to let the PEX controller absorbed the address of the read */
  71936. + /* transaction we perform a validity check that the address was written */
  71937. + if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
  71938. + {
  71939. + return MV_ERROR;
  71940. + }
  71941. +
  71942. + /* Write the Data passed to the PEX Data register */
  71943. + MV_REG_WRITE(PEX_CFG_DATA_REG(pexIf), data);
  71944. +
  71945. + return MV_OK;
  71946. +
  71947. +}
  71948. +
  71949. +/*******************************************************************************
  71950. +* mvPexMasterEnable - Enable/disale PEX interface master transactions.
  71951. +*
  71952. +* DESCRIPTION:
  71953. +* This function performs read modified write to PEX command status
  71954. +* (offset 0x4) to set/reset bit 2. After this bit is set, the PEX
  71955. +* master is allowed to gain ownership on the bus, otherwise it is
  71956. +* incapable to do so.
  71957. +*
  71958. +* INPUT:
  71959. +* pexIf - PEX interface number.
  71960. +* enable - Enable/disable parameter.
  71961. +*
  71962. +* OUTPUT:
  71963. +* None.
  71964. +*
  71965. +* RETURN:
  71966. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  71967. +*
  71968. +*******************************************************************************/
  71969. +MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable)
  71970. +{
  71971. + MV_U32 pexCommandStatus;
  71972. + MV_U32 localBus;
  71973. + MV_U32 localDev;
  71974. +
  71975. + /* Parameter checking */
  71976. + if (pexIf >= mvCtrlPexMaxIfGet())
  71977. + {
  71978. + mvOsPrintf("mvPexMasterEnable: ERR. Invalid PEX interface %d\n", pexIf);
  71979. + return MV_ERROR;
  71980. + }
  71981. +
  71982. + localBus = mvPexLocalBusNumGet(pexIf);
  71983. + localDev = mvPexLocalDevNumGet(pexIf);
  71984. +
  71985. + pexCommandStatus = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
  71986. + PEX_STATUS_AND_COMMAND));
  71987. +
  71988. +
  71989. + if (MV_TRUE == enable)
  71990. + {
  71991. + pexCommandStatus |= PXSAC_MASTER_EN;
  71992. + }
  71993. + else
  71994. + {
  71995. + pexCommandStatus &= ~PXSAC_MASTER_EN;
  71996. + }
  71997. +
  71998. +
  71999. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
  72000. + pexCommandStatus);
  72001. +
  72002. + return MV_OK;
  72003. +}
  72004. +
  72005. +
  72006. +/*******************************************************************************
  72007. +* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.
  72008. +*
  72009. +* DESCRIPTION:
  72010. +* This function performs read modified write to PEX command status
  72011. +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
  72012. +* the PEX slave is allowed to respond to PEX IO space access (bit 0)
  72013. +* and PEX memory space access (bit 1).
  72014. +*
  72015. +* INPUT:
  72016. +* pexIf - PEX interface number.
  72017. +* dev - PEX device number.
  72018. +* enable - Enable/disable parameter.
  72019. +*
  72020. +* OUTPUT:
  72021. +* None.
  72022. +*
  72023. +* RETURN:
  72024. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  72025. +*
  72026. +*******************************************************************************/
  72027. +MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable)
  72028. +{
  72029. + MV_U32 pexCommandStatus;
  72030. + MV_U32 RegOffs;
  72031. +
  72032. + /* Parameter checking */
  72033. + if (pexIf >= mvCtrlPexMaxIfGet())
  72034. + {
  72035. + mvOsPrintf("mvPexSlaveEnable: ERR. Invalid PEX interface %d\n", pexIf);
  72036. + return MV_BAD_PARAM;
  72037. + }
  72038. + if (dev >= MAX_PEX_DEVICES)
  72039. + {
  72040. + mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n", dev);
  72041. + return MV_BAD_PARAM;
  72042. +
  72043. + }
  72044. +
  72045. +
  72046. + RegOffs = PEX_STATUS_AND_COMMAND;
  72047. +
  72048. + pexCommandStatus = mvPexConfigRead(pexIf, bus, dev, 0, RegOffs);
  72049. +
  72050. + if (MV_TRUE == enable)
  72051. + {
  72052. + pexCommandStatus |= (PXSAC_IO_EN | PXSAC_MEM_EN);
  72053. + }
  72054. + else
  72055. + {
  72056. + pexCommandStatus &= ~(PXSAC_IO_EN | PXSAC_MEM_EN);
  72057. + }
  72058. +
  72059. + mvPexConfigWrite(pexIf, bus, dev, 0, RegOffs, pexCommandStatus);
  72060. +
  72061. + return MV_OK;
  72062. +
  72063. +}
  72064. +
  72065. +/*******************************************************************************
  72066. +* mvPexLocalBusNumSet - Set PEX interface local bus number.
  72067. +*
  72068. +* DESCRIPTION:
  72069. +* This function sets given PEX interface its local bus number.
  72070. +* Note: In case the PEX interface is PEX-X, the information is read-only.
  72071. +*
  72072. +* INPUT:
  72073. +* pexIf - PEX interface number.
  72074. +* busNum - Bus number.
  72075. +*
  72076. +* OUTPUT:
  72077. +* None.
  72078. +*
  72079. +* RETURN:
  72080. +* MV_NOT_ALLOWED in case PEX interface is PEX-X.
  72081. +* MV_BAD_PARAM on bad parameters ,
  72082. +* otherwise MV_OK
  72083. +*
  72084. +*******************************************************************************/
  72085. +MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum)
  72086. +{
  72087. + MV_U32 pexStatus;
  72088. + MV_U32 localBus;
  72089. + MV_U32 localDev;
  72090. +
  72091. +
  72092. + /* Parameter checking */
  72093. + if (pexIf >= mvCtrlPexMaxIfGet())
  72094. + {
  72095. + mvOsPrintf("mvPexLocalBusNumSet: ERR. Invalid PEX interface %d\n",pexIf);
  72096. + return MV_BAD_PARAM;
  72097. + }
  72098. + if (busNum >= MAX_PEX_BUSSES)
  72099. + {
  72100. + mvOsPrintf("mvPexLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
  72101. + return MV_ERROR;
  72102. +
  72103. + }
  72104. +
  72105. + localBus = mvPexLocalBusNumGet(pexIf);
  72106. + localDev = mvPexLocalDevNumGet(pexIf);
  72107. +
  72108. +
  72109. +
  72110. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  72111. +
  72112. + pexStatus &= ~PXSR_PEX_BUS_NUM_MASK;
  72113. +
  72114. + pexStatus |= (busNum << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
  72115. +
  72116. + MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
  72117. +
  72118. +
  72119. + return MV_OK;
  72120. +}
  72121. +
  72122. +
  72123. +/*******************************************************************************
  72124. +* mvPexLocalBusNumGet - Get PEX interface local bus number.
  72125. +*
  72126. +* DESCRIPTION:
  72127. +* This function gets the local bus number of a given PEX interface.
  72128. +*
  72129. +* INPUT:
  72130. +* pexIf - PEX interface number.
  72131. +*
  72132. +* OUTPUT:
  72133. +* None.
  72134. +*
  72135. +* RETURN:
  72136. +* Local bus number.0xffffffff on Error
  72137. +*
  72138. +*******************************************************************************/
  72139. +MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf)
  72140. +{
  72141. + MV_U32 pexStatus;
  72142. +
  72143. + /* Parameter checking */
  72144. + if (PEX_DEFAULT_IF != pexIf)
  72145. + {
  72146. + if (pexIf >= mvCtrlPexMaxIfGet())
  72147. + {
  72148. + mvOsPrintf("mvPexLocalBusNumGet: ERR. Invalid PEX interface %d\n",pexIf);
  72149. + return 0xFFFFFFFF;
  72150. + }
  72151. + }
  72152. +
  72153. +
  72154. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  72155. +
  72156. + pexStatus &= PXSR_PEX_BUS_NUM_MASK;
  72157. +
  72158. + return (pexStatus >> PXSR_PEX_BUS_NUM_OFFS);
  72159. +
  72160. +}
  72161. +
  72162. +
  72163. +/*******************************************************************************
  72164. +* mvPexLocalDevNumSet - Set PEX interface local device number.
  72165. +*
  72166. +* DESCRIPTION:
  72167. +* This function sets given PEX interface its local device number.
  72168. +* Note: In case the PEX interface is PEX-X, the information is read-only.
  72169. +*
  72170. +* INPUT:
  72171. +* pexIf - PEX interface number.
  72172. +* devNum - Device number.
  72173. +*
  72174. +* OUTPUT:
  72175. +* None.
  72176. +*
  72177. +* RETURN:
  72178. +* MV_NOT_ALLOWED in case PEX interface is PEX-X.
  72179. +* MV_BAD_PARAM on bad parameters ,
  72180. +* otherwise MV_OK
  72181. +*
  72182. +*******************************************************************************/
  72183. +MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum)
  72184. +{
  72185. + MV_U32 pexStatus;
  72186. + MV_U32 localBus;
  72187. + MV_U32 localDev;
  72188. +
  72189. + /* Parameter checking */
  72190. + if (pexIf >= mvCtrlPexMaxIfGet())
  72191. + {
  72192. + mvOsPrintf("mvPexLocalDevNumSet: ERR. Invalid PEX interface %d\n",pexIf);
  72193. + return MV_BAD_PARAM;
  72194. + }
  72195. + if (devNum >= MAX_PEX_DEVICES)
  72196. + {
  72197. + mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n",
  72198. + devNum);
  72199. + return MV_BAD_PARAM;
  72200. +
  72201. + }
  72202. +
  72203. + localBus = mvPexLocalBusNumGet(pexIf);
  72204. + localDev = mvPexLocalDevNumGet(pexIf);
  72205. +
  72206. +
  72207. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  72208. +
  72209. + pexStatus &= ~PXSR_PEX_DEV_NUM_MASK;
  72210. +
  72211. + pexStatus |= (devNum << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
  72212. +
  72213. + MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
  72214. +
  72215. +
  72216. + return MV_OK;
  72217. +}
  72218. +
  72219. +/*******************************************************************************
  72220. +* mvPexLocalDevNumGet - Get PEX interface local device number.
  72221. +*
  72222. +* DESCRIPTION:
  72223. +* This function gets the local device number of a given PEX interface.
  72224. +*
  72225. +* INPUT:
  72226. +* pexIf - PEX interface number.
  72227. +*
  72228. +* OUTPUT:
  72229. +* None.
  72230. +*
  72231. +* RETURN:
  72232. +* Local device number. 0xffffffff on Error
  72233. +*
  72234. +*******************************************************************************/
  72235. +MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf)
  72236. +{
  72237. + MV_U32 pexStatus;
  72238. +
  72239. + /* Parameter checking */
  72240. +
  72241. + if (PEX_DEFAULT_IF != pexIf)
  72242. + {
  72243. + if (pexIf >= mvCtrlPexMaxIfGet())
  72244. + {
  72245. + mvOsPrintf("mvPexLocalDevNumGet: ERR. Invalid PEX interface %d\n",
  72246. + pexIf);
  72247. + return 0xFFFFFFFF;
  72248. + }
  72249. + }
  72250. +
  72251. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  72252. +
  72253. + pexStatus &= PXSR_PEX_DEV_NUM_MASK;
  72254. +
  72255. + return (pexStatus >> PXSR_PEX_DEV_NUM_OFFS);
  72256. +}
  72257. +
  72258. +MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value)
  72259. +{
  72260. +
  72261. + MV_U32 regAddr;
  72262. + if (pexIf >= mvCtrlPexMaxIfGet())
  72263. + {
  72264. + mvOsPrintf("mvPexPhyRegRead: ERR. Invalid PEX interface %d\n", pexIf);
  72265. + return;
  72266. + }
  72267. + regAddr = (BIT31 | ((regOffset & 0x3fff) << 16));
  72268. + MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
  72269. + *value = MV_REG_READ(PEX_PHY_ACCESS_REG(pexIf));
  72270. +}
  72271. +
  72272. +
  72273. +MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value)
  72274. +{
  72275. +
  72276. + MV_U32 regAddr;
  72277. + if(pexIf >= mvCtrlPexMaxIfGet())
  72278. + {
  72279. + mvOsPrintf("mvPexPhyRegWrite: ERR. Invalid PEX interface %d\n", pexIf);
  72280. + return;
  72281. + }
  72282. + regAddr = (((regOffset & 0x3fff) << 16) | value);
  72283. + MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
  72284. +}
  72285. +
  72286. +/*******************************************************************************
  72287. +* mvPexActiveStateLinkPMEnable
  72288. +*
  72289. +* DESCRIPTION:
  72290. +* Enable Active Link State Power Management
  72291. +*
  72292. +* INPUT:
  72293. +* pexIf - PEX interface number.
  72294. +* enable - MV_TRUE to enable ASPM, MV_FALSE to disable.
  72295. +*
  72296. +* OUTPUT:
  72297. +* None
  72298. +*
  72299. +* RETURN:
  72300. +* MV_OK on success , MV_ERROR otherwise
  72301. +*
  72302. +*******************************************************************************/
  72303. +MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable)
  72304. +{
  72305. + MV_U32 reg;
  72306. +
  72307. + if(pexIf >= mvCtrlPexMaxIfGet())
  72308. + {
  72309. + mvOsPrintf("mvPexActiveStateLinkPMEnable: ERR. Invalid PEX interface %d\n", pexIf);
  72310. + return MV_ERROR;
  72311. + }
  72312. +
  72313. + reg = MV_REG_READ(PEX_PWR_MNG_EXT_REG(pexIf)) & ~PXPMER_L1_ASPM_EN_MASK;
  72314. + if(enable == MV_TRUE)
  72315. + reg |= PXPMER_L1_ASPM_EN_MASK;
  72316. + MV_REG_WRITE(PEX_PWR_MNG_EXT_REG(pexIf), reg);
  72317. +
  72318. + /* Enable / Disable L0/1 entry */
  72319. + reg = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG))
  72320. + & ~PXLCSR_ASPM_CNT_MASK;
  72321. + if(enable == MV_TRUE)
  72322. + reg |= PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP;
  72323. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG), reg);
  72324. +
  72325. + return MV_OK;
  72326. +}
  72327. +
  72328. +
  72329. +/*******************************************************************************
  72330. +* mvPexForceX1
  72331. +*
  72332. +* DESCRIPTION:
  72333. +* shut down lanes 1-3 if recognize that attached to an x1 end-point
  72334. +* INPUT:
  72335. +* pexIf - PEX interface number.
  72336. +*
  72337. +* OUTPUT:
  72338. +* None
  72339. +*
  72340. +* RETURN:
  72341. +* MV_OK on success , MV_ERROR otherwise
  72342. +*
  72343. +*******************************************************************************/
  72344. +MV_U32 mvPexForceX1(MV_U32 pexIf)
  72345. +{
  72346. + MV_U32 regData = 0;
  72347. + if(pexIf >= mvCtrlPexMaxIfGet())
  72348. + {
  72349. + mvOsPrintf("mvPexForceX1: ERR. Invalid PEX interface %d\n", pexIf);
  72350. + return MV_BAD_PARAM;
  72351. + }
  72352. +
  72353. + regData = MV_REG_READ(PEX_CTRL_REG(pexIf)) & ~(PXCR_CONF_LINK_MASK) ;
  72354. + regData |= PXCR_CONF_LINK_X1;
  72355. +
  72356. + MV_REG_WRITE(PEX_CTRL_REG(pexIf), regData);
  72357. + return MV_OK;
  72358. +}
  72359. +
  72360. +MV_BOOL mvPexIsPowerUp(MV_U32 pexIf)
  72361. +{
  72362. + if(pexIf >= mvCtrlPexMaxIfGet())
  72363. + {
  72364. + mvOsPrintf("mvPexIsPowerUp: ERR. Invalid PEX interface %d\n", pexIf);
  72365. + return MV_FALSE;
  72366. + }
  72367. + return mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf);
  72368. +}
  72369. +
  72370. +
  72371. +MV_VOID mvPexPowerDown(MV_U32 pexIf)
  72372. +{
  72373. + if ( (mvCtrlModelGet() == MV_78XX0_DEV_ID) ||
  72374. + (mvCtrlModelGet() == MV_76100_DEV_ID) ||
  72375. + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
  72376. + (mvCtrlModelGet() == MV_78200_DEV_ID) )
  72377. + {
  72378. + mvCtrlPwrClckSet(PEX_UNIT_ID, pexIf, MV_FALSE);
  72379. + }
  72380. + else
  72381. + {
  72382. + MV_REG_WRITE((0x41B00 -(pexIf)*0x10000), 0x20800087);
  72383. + }
  72384. +}
  72385. +
  72386. +
  72387. +
  72388. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h
  72389. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h 1970-01-01 01:00:00.000000000 +0100
  72390. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h 2010-11-09 20:28:11.742495415 +0100
  72391. @@ -0,0 +1,168 @@
  72392. +/*******************************************************************************
  72393. +Copyright (C) Marvell International Ltd. and its affiliates
  72394. +
  72395. +This software file (the "File") is owned and distributed by Marvell
  72396. +International Ltd. and/or its affiliates ("Marvell") under the following
  72397. +alternative licensing terms. Once you have made an election to distribute the
  72398. +File under one of the following license alternatives, please (i) delete this
  72399. +introductory statement regarding license alternatives, (ii) delete the two
  72400. +license alternatives that you have not elected to use and (iii) preserve the
  72401. +Marvell copyright notice above.
  72402. +
  72403. +********************************************************************************
  72404. +Marvell Commercial License Option
  72405. +
  72406. +If you received this File from Marvell and you have entered into a commercial
  72407. +license agreement (a "Commercial License") with Marvell, the File is licensed
  72408. +to you under the terms of the applicable Commercial License.
  72409. +
  72410. +********************************************************************************
  72411. +Marvell GPL License Option
  72412. +
  72413. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72414. +modify this File in accordance with the terms and conditions of the General
  72415. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  72416. +available along with the File in the license.txt file or by writing to the Free
  72417. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  72418. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  72419. +
  72420. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  72421. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  72422. +DISCLAIMED. The GPL License provides additional details about this warranty
  72423. +disclaimer.
  72424. +********************************************************************************
  72425. +Marvell BSD License Option
  72426. +
  72427. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72428. +modify this File under the following licensing terms.
  72429. +Redistribution and use in source and binary forms, with or without modification,
  72430. +are permitted provided that the following conditions are met:
  72431. +
  72432. + * Redistributions of source code must retain the above copyright notice,
  72433. + this list of conditions and the following disclaimer.
  72434. +
  72435. + * Redistributions in binary form must reproduce the above copyright
  72436. + notice, this list of conditions and the following disclaimer in the
  72437. + documentation and/or other materials provided with the distribution.
  72438. +
  72439. + * Neither the name of Marvell nor the names of its contributors may be
  72440. + used to endorse or promote products derived from this software without
  72441. + specific prior written permission.
  72442. +
  72443. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  72444. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  72445. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  72446. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  72447. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  72448. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  72449. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  72450. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  72451. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  72452. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  72453. +
  72454. +*******************************************************************************/
  72455. +
  72456. +#ifndef __INCPEXH
  72457. +#define __INCPEXH
  72458. +
  72459. +#include "mvCommon.h"
  72460. +#include "mvOs.h"
  72461. +#include "pex/mvPexRegs.h"
  72462. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  72463. +
  72464. +
  72465. +
  72466. +/* NOTE not supported in this driver:*/
  72467. +
  72468. +
  72469. +/* defines */
  72470. +/* The number of supported PEX interfaces depend on Marvell controller */
  72471. +/* device number. This device number ID is located on the PEX unit */
  72472. +/* configuration header. This creates a loop where calling PEX */
  72473. +/* configuration read/write routine results a call to get PEX configuration */
  72474. +/* information etc. This macro defines a default PEX interface. This PEX */
  72475. +/* interface is sure to exist. */
  72476. +#define PEX_DEFAULT_IF 0
  72477. +
  72478. +
  72479. +/* typedefs */
  72480. +/* The Marvell controller supports both root complex and end point devices */
  72481. +/* This enumeration describes the PEX type. */
  72482. +typedef enum _mvPexType
  72483. +{
  72484. + MV_PEX_ROOT_COMPLEX, /* root complex device */
  72485. + MV_PEX_END_POINT /* end point device */
  72486. +}MV_PEX_TYPE;
  72487. +
  72488. +typedef enum _mvPexWidth
  72489. +{
  72490. + MV_PEX_WITDH_X1 = 1,
  72491. + MV_PEX_WITDH_X2,
  72492. + MV_PEX_WITDH_X3,
  72493. + MV_PEX_WITDH_X4,
  72494. + MV_PEX_WITDH_INVALID
  72495. +}MV_PEX_WIDTH;
  72496. +
  72497. +/* PEX Bar attributes */
  72498. +typedef struct _mvPexMode
  72499. +{
  72500. + MV_PEX_TYPE pexType;
  72501. + MV_PEX_WIDTH pexWidth;
  72502. + MV_BOOL pexLinkUp;
  72503. +}MV_PEX_MODE;
  72504. +
  72505. +
  72506. +
  72507. +/* Global Functions prototypes */
  72508. +/* mvPexInit - Initialize PEX interfaces*/
  72509. +MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType);
  72510. +
  72511. +/* mvPexModeGet - Get Pex If mode */
  72512. +MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode);
  72513. +
  72514. +/* mvPexConfigRead - Read from configuration space */
  72515. +MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  72516. + MV_U32 func,MV_U32 regOff);
  72517. +
  72518. +/* mvPexConfigWrite - Write to configuration space */
  72519. +MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  72520. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  72521. +
  72522. +/* mvPexMasterEnable - Enable/disale PEX interface master transactions.*/
  72523. +MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable);
  72524. +
  72525. +/* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.*/
  72526. +MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable);
  72527. +
  72528. +/* mvPexLocalBusNumSet - Set PEX interface local bus number.*/
  72529. +MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum);
  72530. +
  72531. +/* mvPexLocalBusNumGet - Get PEX interface local bus number.*/
  72532. +MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf);
  72533. +
  72534. +/* mvPexLocalDevNumSet - Set PEX interface local device number.*/
  72535. +MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum);
  72536. +
  72537. +/* mvPexLocalDevNumGet - Get PEX interface local device number.*/
  72538. +MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf);
  72539. +/* mvPexForceX1 - Force PEX interface to X1 mode. */
  72540. +MV_U32 mvPexForceX1(MV_U32 pexIf);
  72541. +
  72542. +/* mvPexIsPowerUp - Is PEX interface Power up? */
  72543. +MV_BOOL mvPexIsPowerUp(MV_U32 pexIf);
  72544. +
  72545. +/* mvPexPowerDown - Power Down */
  72546. +MV_VOID mvPexPowerDown(MV_U32 pexIf);
  72547. +
  72548. +/* mvPexPowerUp - Power Up */
  72549. +MV_VOID mvPexPowerUp(MV_U32 pexIf);
  72550. +
  72551. +/* mvPexPhyRegRead - Pex phy read */
  72552. +MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value);
  72553. +
  72554. +/* mvPexPhyRegWrite - Pex phy write */
  72555. +MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value);
  72556. +
  72557. +MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable);
  72558. +
  72559. +#endif /* #ifndef __INCPEXH */
  72560. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h
  72561. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h 1970-01-01 01:00:00.000000000 +0100
  72562. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h 2010-11-09 20:28:11.782495900 +0100
  72563. @@ -0,0 +1,751 @@
  72564. +/*******************************************************************************
  72565. +Copyright (C) Marvell International Ltd. and its affiliates
  72566. +
  72567. +This software file (the "File") is owned and distributed by Marvell
  72568. +International Ltd. and/or its affiliates ("Marvell") under the following
  72569. +alternative licensing terms. Once you have made an election to distribute the
  72570. +File under one of the following license alternatives, please (i) delete this
  72571. +introductory statement regarding license alternatives, (ii) delete the two
  72572. +license alternatives that you have not elected to use and (iii) preserve the
  72573. +Marvell copyright notice above.
  72574. +
  72575. +********************************************************************************
  72576. +Marvell Commercial License Option
  72577. +
  72578. +If you received this File from Marvell and you have entered into a commercial
  72579. +license agreement (a "Commercial License") with Marvell, the File is licensed
  72580. +to you under the terms of the applicable Commercial License.
  72581. +
  72582. +********************************************************************************
  72583. +Marvell GPL License Option
  72584. +
  72585. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72586. +modify this File in accordance with the terms and conditions of the General
  72587. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  72588. +available along with the File in the license.txt file or by writing to the Free
  72589. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  72590. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  72591. +
  72592. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  72593. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  72594. +DISCLAIMED. The GPL License provides additional details about this warranty
  72595. +disclaimer.
  72596. +********************************************************************************
  72597. +Marvell BSD License Option
  72598. +
  72599. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72600. +modify this File under the following licensing terms.
  72601. +Redistribution and use in source and binary forms, with or without modification,
  72602. +are permitted provided that the following conditions are met:
  72603. +
  72604. + * Redistributions of source code must retain the above copyright notice,
  72605. + this list of conditions and the following disclaimer.
  72606. +
  72607. + * Redistributions in binary form must reproduce the above copyright
  72608. + notice, this list of conditions and the following disclaimer in the
  72609. + documentation and/or other materials provided with the distribution.
  72610. +
  72611. + * Neither the name of Marvell nor the names of its contributors may be
  72612. + used to endorse or promote products derived from this software without
  72613. + specific prior written permission.
  72614. +
  72615. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  72616. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  72617. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  72618. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  72619. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  72620. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  72621. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  72622. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  72623. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  72624. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  72625. +
  72626. +*******************************************************************************/
  72627. +
  72628. +#ifndef __INCPEXREGSH
  72629. +#define __INCPEXREGSH
  72630. +
  72631. +#ifdef __cplusplus
  72632. +extern "C" {
  72633. +#endif /* __cplusplus */
  72634. +
  72635. +/* defines */
  72636. +#define MAX_PEX_DEVICES 32
  72637. +#define MAX_PEX_FUNCS 8
  72638. +#define MAX_PEX_BUSSES 256
  72639. +
  72640. +
  72641. +
  72642. +/*********************************************************/
  72643. +/* PCI Express Configuration Cycles Generation Registers */
  72644. +/*********************************************************/
  72645. +
  72646. +#define PEX_CFG_ADDR_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x18F8)
  72647. +#define PEX_CFG_DATA_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x18FC)
  72648. +#define PEX_PHY_ACCESS_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1B00)
  72649. +/* PCI Express Configuration Address Register */
  72650. +/* PEX_CFG_ADDR_REG (PXCAR)*/
  72651. +
  72652. +#define PXCAR_REG_NUM_OFFS 2
  72653. +#define PXCAR_REG_NUM_MAX 0x3F
  72654. +#define PXCAR_REG_NUM_MASK (PXCAR_REG_NUM_MAX << PXCAR_REG_NUM_OFFS)
  72655. +#define PXCAR_FUNC_NUM_OFFS 8
  72656. +#define PXCAR_FUNC_NUM_MAX 0x7
  72657. +#define PXCAR_FUNC_NUM_MASK (PXCAR_FUNC_NUM_MAX << PXCAR_FUNC_NUM_OFFS)
  72658. +#define PXCAR_DEVICE_NUM_OFFS 11
  72659. +#define PXCAR_DEVICE_NUM_MAX 0x1F
  72660. +#define PXCAR_DEVICE_NUM_MASK (PXCAR_DEVICE_NUM_MAX << PXCAR_DEVICE_NUM_OFFS)
  72661. +#define PXCAR_BUS_NUM_OFFS 16
  72662. +#define PXCAR_BUS_NUM_MAX 0xFF
  72663. +#define PXCAR_BUS_NUM_MASK (PXCAR_BUS_NUM_MAX << PXCAR_BUS_NUM_OFFS)
  72664. +#define PXCAR_EXT_REG_NUM_OFFS 24
  72665. +#define PXCAR_EXT_REG_NUM_MAX 0xF
  72666. +
  72667. +/* in pci express register address is now the legacy register address (8 bits)
  72668. +with the new extended register address (more 4 bits) , below is the mask of
  72669. +the upper 4 bits of the full register address */
  72670. +
  72671. +#define PXCAR_REAL_EXT_REG_NUM_OFFS 8
  72672. +#define PXCAR_EXT_REG_NUM_MASK (PXCAR_EXT_REG_NUM_MAX << PXCAR_EXT_REG_NUM_OFFS)
  72673. +#define PXCAR_CONFIG_EN BIT31
  72674. +
  72675. +#define PXCAR_REAL_EXT_REG_NUM_OFFS 8
  72676. +#define PXCAR_REAL_EXT_REG_NUM_MASK (0xF << PXCAR_REAL_EXT_REG_NUM_OFFS)
  72677. +
  72678. +/* The traditional PCI spec defined 6-bit field to describe register offset.*/
  72679. +/* The new PCI Express extend the register offset by an extra 4-bits. */
  72680. +/* The below macro assign 10-bit register offset into the apprpreate */
  72681. +/* fields in the CFG_ADDR_REG */
  72682. +#define PXCAR_REG_OFFS_SET(regOffs) \
  72683. + ( (regOff & PXCAR_REG_NUM_MASK) | \
  72684. + ( ((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >> PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS) )
  72685. +
  72686. +/***********************************/
  72687. +/* PCI Express Interrupt registers */
  72688. +/***********************************/
  72689. +#define PEX_CAUSE_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1900)
  72690. +#define PEX_MASK_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1910)
  72691. +
  72692. +#define PXICR_TX_REQ_IN_DLDOWN_ERR BIT0 /* Transmit request while field */
  72693. + /* <DLDown> of the PCI Express */
  72694. +/* PCI Express Interrupt Cause */
  72695. +/* PEX_INT_CAUSE_REG (PXICR)*/
  72696. +/* PEX_INT_MASK_REG*/
  72697. +/*
  72698. +NOTE:All bits except bits[27:24] are Read/Write Clear only. A cause bit sets
  72699. +upon an error event occurrence. A write of 0 clears the bit. A write of 1 has
  72700. +no affect. Bits[24:27} are set and cleared upon reception of interrupt
  72701. +emulation messages.
  72702. +
  72703. +Mask bit per cause bit. If a bit is set to 1, the corresponding event is
  72704. +enabled. Mask does not affect setting of the Interrupt Cause register bits;
  72705. +it only affects the assertion of the interrupt .*/
  72706. +
  72707. +
  72708. +#define PXICR_MDIS_CAUSE BIT1 /* Attempt to generate PCI transaction
  72709. + while master is disabled */
  72710. +#define PXICR_ERR_WRTO_REG_CAUSE BIT3 /* Erroneous write attempt to
  72711. + PCI Express internal register*/
  72712. +#define PXICR_HIT_DFLT_WIN_ERR BIT4 /* Hit Default Window Error */
  72713. +#define PXICR_RX_RAM_PAR_ERR BIT6 /* Rx RAM Parity Error */
  72714. +#define PXICR_TX_RAM_PAR_ERR BIT7 /* Tx RAM Parity Error */
  72715. +#define PXICR_COR_ERR_DET BIT8 /* Correctable Error Detected*/
  72716. +#define PXICR_NF_ERR_DET BIT9 /* Non-Fatal Error Detected*/
  72717. +#define PXICR_FERR_DET BIT10 /* Fatal Error Detected*/
  72718. +#define PXICR_DSTATE_CHANGE BIT11 /* Dstate Change Indication*/
  72719. +#define PXICR_BIST BIT12 /* PCI-Express BIST activated*/
  72720. +#define PXICR_FLW_CTRL_PROT BIT14 /* Flow Control Protocol Error */
  72721. +
  72722. +#define PXICR_RCV_UR_CA_ERR BIT15 /* Received UR or CA status. */
  72723. +#define PXICR_RCV_ERR_FATAL BIT16 /* Received ERR_FATAL message.*/
  72724. +#define PXICR_RCV_ERR_NON_FATAL BIT17 /* Received ERR_NONFATAL message*/
  72725. +#define PXICR_RCV_ERR_COR BIT18 /* Received ERR_COR message.*/
  72726. +#define PXICR_RCV_CRS BIT19 /* Received CRS completion status*/
  72727. +#define PXICR_SLV_HOT_RESET BIT20 /* Received Hot Reset Indication*/
  72728. +#define PXICR_SLV_DIS_LINK BIT21 /* Slave Disable Link Indication*/
  72729. +#define PXICR_SLV_LB BIT22 /* Slave Loopback Indication*/
  72730. +#define PXICR_LINK_FAIL BIT23 /* Link Failure indication.*/
  72731. +#define PXICR_RCV_INTA BIT24 /* IntA status.*/
  72732. +#define PXICR_RCV_INTB BIT25 /* IntB status.*/
  72733. +#define PXICR_RCV_INTC BIT26 /* IntC status.*/
  72734. +#define PXICR_RCV_INTD BIT27 /* IntD status.*/
  72735. +#define PXICR_RCV_PM_PME BIT28 /* Received PM_PME message. */
  72736. +
  72737. +
  72738. +/********************************************/
  72739. +/* PCI Express Control and Status Registers */
  72740. +/********************************************/
  72741. +#define PEX_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A00)
  72742. +#define PEX_STATUS_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A04)
  72743. +#define PEX_COMPLT_TMEOUT_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A10)
  72744. +#define PEX_PWR_MNG_EXT_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A18)
  72745. +#define PEX_FLOW_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A20)
  72746. +#define PEX_ACK_TMR_4X_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A30)
  72747. +#define PEX_ACK_TMR_1X_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A40)
  72748. +#define PEX_TL_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1AB0)
  72749. +
  72750. +
  72751. +#define PEX_RAM_PARITY_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A50)
  72752. +/* PCI Express Control Register */
  72753. +/* PEX_CTRL_REG (PXCR) */
  72754. +
  72755. +#define PXCR_CONF_LINK_OFFS 0
  72756. +#define PXCR_CONF_LINK_MASK (1 << PXCR_CONF_LINK_OFFS)
  72757. +#define PXCR_CONF_LINK_X4 (0 << PXCR_CONF_LINK_OFFS)
  72758. +#define PXCR_CONF_LINK_X1 (1 << PXCR_CONF_LINK_OFFS)
  72759. +#define PXCR_DEV_TYPE_CTRL_OFFS 1 /*PCI ExpressDevice Type Control*/
  72760. +#define PXCR_DEV_TYPE_CTRL_MASK BIT1
  72761. +#define PXCR_DEV_TYPE_CTRL_CMPLX (1 << PXCR_DEV_TYPE_CTRL_OFFS)
  72762. +#define PXCR_DEV_TYPE_CTRL_POINT (0 << PXCR_DEV_TYPE_CTRL_OFFS)
  72763. +#define PXCR_CFG_MAP_TO_MEM_EN BIT2 /* Configuration Header Mapping
  72764. + to Memory Space Enable */
  72765. +
  72766. +#define PXCR_CFG_MAP_TO_MEM_EN BIT2 /* Configuration Header Mapping
  72767. + to Memory Space Enable*/
  72768. +
  72769. +#define PXCR_RSRV1_OFFS 5
  72770. +#define PXCR_RSRV1_MASK (0x7 << PXCR_RSRV1_OFFS)
  72771. +#define PXCR_RSRV1_VAL (0x0 << PXCR_RSRV1_OFFS)
  72772. +
  72773. +#define PXCR_CONF_MAX_OUTSTND_OFFS 8 /*Maximum outstanding NP requests as a master*/
  72774. +#define PXCR_CONF_MAX_OUTSTND_MASK (0x3 << PXCR_CONF_MAX_OUTSTND_OFFS)
  72775. +
  72776. +
  72777. +#define PXCR_CONF_NFTS_OFFS 16 /*number of FTS Ordered-Sets*/
  72778. +#define PXCR_CONF_NFTS_MASK (0xff << PXCR_CONF_NFTS_OFFS)
  72779. +
  72780. +#define PXCR_CONF_MSTR_HOT_RESET BIT24 /*Master Hot-Reset.*/
  72781. +#define PXCR_CONF_MSTR_LB BIT26 /* Master Loopback */
  72782. +#define PXCR_CONF_MSTR_DIS_SCRMB BIT27 /* Master Disable Scrambling*/
  72783. +#define PXCR_CONF_DIRECT_DIS_SCRMB BIT28 /* Direct Disable Scrambling*/
  72784. +
  72785. +/* PCI Express Status Register */
  72786. +/* PEX_STATUS_REG (PXSR) */
  72787. +
  72788. +#define PXSR_DL_DOWN BIT0 /* DL_Down indication.*/
  72789. +
  72790. +#define PXSR_PEX_BUS_NUM_OFFS 8 /* Bus Number Indication */
  72791. +#define PXSR_PEX_BUS_NUM_MASK (0xff << PXSR_PEX_BUS_NUM_OFFS)
  72792. +
  72793. +#define PXSR_PEX_DEV_NUM_OFFS 16 /* Device Number Indication */
  72794. +#define PXSR_PEX_DEV_NUM_MASK (0x1f << PXSR_PEX_DEV_NUM_OFFS)
  72795. +
  72796. +#define PXSR_PEX_SLV_HOT_RESET BIT24 /* Slave Hot Reset Indication*/
  72797. +#define PXSR_PEX_SLV_DIS_LINK BIT25 /* Slave Disable Link Indication*/
  72798. +#define PXSR_PEX_SLV_LB BIT26 /* Slave Loopback Indication*/
  72799. +#define PXSR_PEX_SLV_DIS_SCRMB BIT27 /* Slave Disable Scrambling Indication*/
  72800. +
  72801. +
  72802. +/* PCI Express Completion Timeout Register */
  72803. +/* PEX_COMPLT_TMEOUT_REG (PXCTR)*/
  72804. +
  72805. +#define PXCTR_CMP_TO_THRSHLD_OFFS 0 /* Completion Timeout Threshold */
  72806. +#define PXCTR_CMP_TO_THRSHLD_MASK (0xffff << PXCTR_CMP_TO_THRSHLD_OFFS)
  72807. +
  72808. +/* PCI Express Power Management Extended Register */
  72809. +/* PEX_PWR_MNG_EXT_REG (PXPMER) */
  72810. +
  72811. +#define PXPMER_L1_ASPM_EN_OFFS 1
  72812. +#define PXPMER_L1_ASPM_EN_MASK (0x1 << PXPMER_L1_ASPM_EN_OFFS)
  72813. +
  72814. +/* PCI Express Flow Control Register */
  72815. +/* PEX_FLOW_CTRL_REG (PXFCR)*/
  72816. +
  72817. +#define PXFCR_PH_INIT_FC_OFFS 0 /*Posted Headers Flow Control Credit
  72818. + Initial Value.*/
  72819. +#define PXFCR_PH_INIT_FC_MASK (0xff << PXFCR_PH_INIT_FC_OFFS)
  72820. +
  72821. +
  72822. +#define PXFCR_NPH_INIT_FC_OFFS 8 /* Classified Non-Posted Headers
  72823. + Flow Control Credit Initial Value*/
  72824. +#define PXFCR_NPH_INIT_FC_MASK (0xff << PXFCR_NPH_INIT_FC_OFFS)
  72825. +
  72826. +#define PXFCR_CH_INIT_FC_OFFS 16 /* Completion Headers Flow Control
  72827. + Credit Initial Value Infinite*/
  72828. +
  72829. +#define PXFCR_CH_INIT_FC_MASK (0xff << PXFCR_CH_INIT_FC_OFFS)
  72830. +
  72831. +#define PXFCR_FC_UPDATE_TO_OFFS 24 /* Flow Control Update Timeout */
  72832. +#define PXFCR_FC_UPDATE_TO_MASK (0xff << PXFCR_FC_UPDATE_TO_OFFS)
  72833. +
  72834. +/* PCI Express Acknowledge Timers (4X) Register */
  72835. +/* PEX_ACK_TMR_4X_REG (PXAT4R) */
  72836. +#define PXAT1R_ACK_LAT_TOX4_OFFS 0 /* Ack Latency Timer Timeout Value */
  72837. +#define PXAT1R_ACK_LAT_TOX4_MASK (0xffff << PXAT4R_ACK_LAT_TOX1_OFFS)
  72838. +#define PXAT1R_ACK_RPLY_TOX4_OFFS 16 /* Ack Replay Timer Timeout Value */
  72839. +#define PXAT1R_ACK_RPLY_TOX4_MASK (0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)
  72840. +
  72841. +/* PCI Express Acknowledge Timers (1X) Register */
  72842. +/* PEX_ACK_TMR_1X_REG (PXAT1R) */
  72843. +
  72844. +#define PXAT1R_ACK_LAT_TOX1_OFFS 0 /* Acknowledge Latency Timer Timeout
  72845. + Value for 1X Link*/
  72846. +#define PXAT1R_ACK_LAT_TOX1_MASK (0xffff << PXAT1R_ACK_LAT_TOX1_OFFS)
  72847. +
  72848. +#define PXAT1R_ACK_RPLY_TOX1_OFFS 16 /* Acknowledge Replay Timer Timeout
  72849. + Value for 1X*/
  72850. +#define PXAT1R_ACK_RPLY_TOX1_MASK (0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)
  72851. +
  72852. +
  72853. +/* PCI Express TL Control Register */
  72854. +/* PEX_TL_CTRL_REG (PXTCR) */
  72855. +
  72856. +#define PXTCR_TX_CMP_BUFF_NO_OFFS 8 /*Number of completion buffers in Tx*/
  72857. +#define PXTCR_TX_CMP_BUFF_NO_MASK (0xf << PXTCR_TX_CMP_BUFF_NO_OFFS)
  72858. +
  72859. +/* PCI Express Debug MAC Control Register */
  72860. +/* PEX_DEBUG_MAC_CTRL_REG (PXDMCR) */
  72861. +
  72862. +#define PXDMCR_LINKUP BIT4
  72863. +
  72864. +
  72865. +
  72866. +/**********************************************/
  72867. +/* PCI Express Configuration Header Registers */
  72868. +/**********************************************/
  72869. +#define PEX_CFG_DIRECT_ACCESS(pexIf,cfgReg) ((PEX_IF_BASE(pexIf)) + (cfgReg))
  72870. +
  72871. +#define PEX_DEVICE_AND_VENDOR_ID 0x000
  72872. +#define PEX_STATUS_AND_COMMAND 0x004
  72873. +#define PEX_CLASS_CODE_AND_REVISION_ID 0x008
  72874. +#define PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE 0x00C
  72875. +#define PEX_MEMORY_BAR_BASE_ADDR(barNum) (0x010 + ((barNum) << 2))
  72876. +#define PEX_MV_BAR_BASE(barNum) (0x010 + (barNum) * 8)
  72877. +#define PEX_MV_BAR_BASE_HIGH(barNum) (0x014 + (barNum) * 8)
  72878. +#define PEX_BAR0_INTER_REG 0x010
  72879. +#define PEX_BAR0_INTER_REG_HIGH 0x014
  72880. +#define PEX_BAR1_REG 0x018
  72881. +#define PEX_BAR1_REG_HIGH 0x01C
  72882. +#define PEX_BAR2_REG 0x020
  72883. +#define PEX_BAR2_REG_HIGH 0x024
  72884. +
  72885. +#define PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID 0x02C
  72886. +#define PEX_EXPANSION_ROM_BASE_ADDR_REG 0x030
  72887. +#define PEX_CAPABILTY_LIST_POINTER 0x034
  72888. +#define PEX_INTERRUPT_PIN_AND_LINE 0x03C
  72889. +
  72890. +/* capability list */
  72891. +#define PEX_POWER_MNG_CAPABILITY 0x040
  72892. +#define PEX_POWER_MNG_STATUS_CONTROL 0x044
  72893. +
  72894. +#define PEX_MSI_MESSAGE_CONTROL 0x050
  72895. +#define PEX_MSI_MESSAGE_ADDR 0x054
  72896. +#define PEX_MSI_MESSAGE_HIGH_ADDR 0x058
  72897. +#define PEX_MSI_MESSAGE_DATA 0x05C
  72898. +
  72899. +#define PEX_CAPABILITY_REG 0x60
  72900. +#define PEX_DEV_CAPABILITY_REG 0x64
  72901. +#define PEX_DEV_CTRL_STAT_REG 0x68
  72902. +#define PEX_LINK_CAPABILITY_REG 0x6C
  72903. +#define PEX_LINK_CTRL_STAT_REG 0x70
  72904. +
  72905. +#define PEX_ADV_ERR_RPRT_HDR_TRGT_REG 0x100
  72906. +#define PEX_UNCORRECT_ERR_STAT_REG 0x104
  72907. +#define PEX_UNCORRECT_ERR_MASK_REG 0x108
  72908. +#define PEX_UNCORRECT_ERR_SERVITY_REG 0x10C
  72909. +#define PEX_CORRECT_ERR_STAT_REG 0x110
  72910. +#define PEX_CORRECT_ERR_MASK_REG 0x114
  72911. +#define PEX_ADV_ERR_CAPABILITY_CTRL_REG 0x118
  72912. +#define PEX_HDR_LOG_FIRST_DWORD_REG 0x11C
  72913. +#define PEX_HDR_LOG_SECOND_DWORD_REG 0x120
  72914. +#define PEX_HDR_LOG_THIRD_DWORD_REG 0x124
  72915. +#define PEX_HDR_LOG_FOURTH_DWORD_REG 0x128
  72916. +
  72917. +
  72918. +
  72919. +/* PCI Express Device and Vendor ID Register*/
  72920. +/*PEX_DEVICE_AND_VENDOR_ID (PXDAVI)*/
  72921. +
  72922. +#define PXDAVI_VEN_ID_OFFS 0 /* Vendor ID */
  72923. +#define PXDAVI_VEN_ID_MASK (0xffff << PXDAVI_VEN_ID_OFFS)
  72924. +
  72925. +#define PXDAVI_DEV_ID_OFFS 16 /* Device ID */
  72926. +#define PXDAVI_DEV_ID_MASK (0xffff << PXDAVI_DEV_ID_OFFS)
  72927. +
  72928. +
  72929. +/* PCI Express Command and Status Register*/
  72930. +/*PEX_STATUS_AND_COMMAND (PXSAC)*/
  72931. +
  72932. +#define PXSAC_IO_EN BIT0 /* IO Enable */
  72933. +#define PXSAC_MEM_EN BIT1 /* Memory Enable */
  72934. +#define PXSAC_MASTER_EN BIT2 /* Master Enable */
  72935. +#define PXSAC_PERR_EN BIT6 /* Parity Errors Respond Enable */
  72936. +#define PXSAC_SERR_EN BIT8 /* Ability to assert SERR# line */
  72937. +#define PXSAC_INT_DIS BIT10 /* Interrupt Disable */
  72938. +#define PXSAC_INT_STAT BIT19 /* Interrupt Status */
  72939. +#define PXSAC_CAP_LIST BIT20 /* Capability List Support */
  72940. +#define PXSAC_MAS_DATA_PERR BIT24 /* Master Data Parity Error */
  72941. +#define PXSAC_SLAVE_TABORT BIT27 /* Signalled Target Abort */
  72942. +#define PXSAC_RT_ABORT BIT28 /* Recieved Target Abort */
  72943. +#define PXSAC_MABORT BIT29 /* Recieved Master Abort */
  72944. +#define PXSAC_SYSERR BIT30 /* Signalled system error */
  72945. +#define PXSAC_DET_PARERR BIT31 /* Detect Parity Error */
  72946. +
  72947. +
  72948. +/* PCI Express Class Code and Revision ID Register*/
  72949. +/*PEX_CLASS_CODE_AND_REVISION_ID (PXCCARI)*/
  72950. +
  72951. +#define PXCCARI_REVID_OFFS 0 /* Revision ID */
  72952. +#define PXCCARI_REVID_MASK (0xff << PXCCARI_REVID_OFFS)
  72953. +
  72954. +#define PXCCARI_FULL_CLASS_OFFS 8 /* Full Class Code */
  72955. +#define PXCCARI_FULL_CLASS_MASK (0xffffff << PXCCARI_FULL_CLASS_OFFS)
  72956. +
  72957. +#define PXCCARI_PROGIF_OFFS 8 /* Prog .I/F*/
  72958. +#define PXCCARI_PROGIF_MASK (0xff << PXCCARI_PROGIF_OFFS)
  72959. +
  72960. +#define PXCCARI_SUB_CLASS_OFFS 16 /* Sub Class*/
  72961. +#define PXCCARI_SUB_CLASS_MASK (0xff << PXCCARI_SUB_CLASS_OFFS)
  72962. +
  72963. +#define PXCCARI_BASE_CLASS_OFFS 24 /* Base Class*/
  72964. +#define PXCCARI_BASE_CLASS_MASK (0xff << PXCCARI_BASE_CLASS_OFFS)
  72965. +
  72966. +
  72967. +/* PCI Express BIST, Header Type and Cache Line Size Register*/
  72968. +/*PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE (PXBHTLTCL)*/
  72969. +
  72970. +#define PXBHTLTCL_CACHELINE_OFFS 0 /* Specifies the cache line size */
  72971. +#define PXBHTLTCL_CACHELINE_MASK (0xff << PXBHTLTCL_CACHELINE_OFFS)
  72972. +
  72973. +#define PXBHTLTCL_HEADTYPE_FULL_OFFS 16 /* Full Header Type */
  72974. +#define PXBHTLTCL_HEADTYPE_FULL_MASK (0xff << PXBHTLTCL_HEADTYPE_FULL_OFFS)
  72975. +
  72976. +#define PXBHTLTCL_MULTI_FUNC BIT23 /* Multi/Single function */
  72977. +
  72978. +#define PXBHTLTCL_HEADER_OFFS 16 /* Header type */
  72979. +#define PXBHTLTCL_HEADER_MASK (0x7f << PXBHTLTCL_HEADER_OFFS)
  72980. +#define PXBHTLTCL_HEADER_STANDARD (0x0 << PXBHTLTCL_HEADER_OFFS)
  72981. +#define PXBHTLTCL_HEADER_PCI2PCI_BRIDGE (0x1 << PXBHTLTCL_HEADER_OFFS)
  72982. +
  72983. +
  72984. +#define PXBHTLTCL_BISTCOMP_OFFS 24 /* BIST Completion Code */
  72985. +#define PXBHTLTCL_BISTCOMP_MASK (0xf << PXBHTLTCL_BISTCOMP_OFFS)
  72986. +
  72987. +#define PXBHTLTCL_BISTACT BIT30 /* BIST Activate bit */
  72988. +#define PXBHTLTCL_BISTCAP BIT31 /* BIST Capable Bit */
  72989. +#define PXBHTLTCL_BISTCAP_OFFS 31
  72990. +#define PXBHTLTCL_BISTCAP_MASK BIT31
  72991. +#define PXBHTLTCL_BISTCAP_VAL 0
  72992. +
  72993. +
  72994. +/* PCI Express Subsystem Device and Vendor ID */
  72995. +/*PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID (PXSIASVI)*/
  72996. +
  72997. +#define PXSIASVI_VENID_OFFS 0 /* Subsystem Manufacturer Vendor ID Number */
  72998. +#define PXSIASVI_VENID_MASK (0xffff << PXSIASVI_VENID_OFFS)
  72999. +
  73000. +#define PXSIASVI_DEVID_OFFS 16 /* Subsystem Device ID Number */
  73001. +#define PXSIASVI_DEVID_MASK (0xffff << PXSIASVI_DEVID_OFFS)
  73002. +
  73003. +
  73004. +/* PCI Express Capability List Pointer Register*/
  73005. +/*PEX_CAPABILTY_LIST_POINTER (PXCLP)*/
  73006. +
  73007. +#define PXCLP_CAPPTR_OFFS 0 /* Capability List Pointer */
  73008. +#define PXCLP_CAPPTR_MASK (0xff << PXCLP_CAPPTR_OFFS)
  73009. +
  73010. +/* PCI Express Interrupt Pin and Line Register */
  73011. +/*PEX_INTERRUPT_PIN_AND_LINE (PXIPAL)*/
  73012. +
  73013. +#define PXIPAL_INTLINE_OFFS 0 /* Interrupt line (IRQ) */
  73014. +#define PXIPAL_INTLINE_MASK (0xff << PXIPAL_INTLINE_OFFS)
  73015. +
  73016. +#define PXIPAL_INTPIN_OFFS 8 /* interrupt pin (A,B,C,D) */
  73017. +#define PXIPAL_INTPIN_MASK (0xff << PXIPAL_INTPIN_OFFS)
  73018. +
  73019. +
  73020. +/* PCI Express Power Management Capability Header Register*/
  73021. +/*PEX_POWER_MNG_CAPABILITY (PXPMC)*/
  73022. +
  73023. +#define PXPMC_CAP_ID_OFFS 0 /* Capability ID */
  73024. +#define PXPMC_CAP_ID_MASK (0xff << PXPMC_CAP_ID_OFFS)
  73025. +
  73026. +#define PXPMC_NEXT_PTR_OFFS 8 /* Next Item Pointer */
  73027. +#define PXPMC_NEXT_PTR_MASK (0xff << PXPMC_NEXT_PTR_OFFS)
  73028. +
  73029. +#define PXPMC_PMC_VER_OFFS 16 /* PCI Power Management Capability Version*/
  73030. +#define PXPMC_PMC_VER_MASK (0x7 << PXPMC_PMC_VER_OFFS)
  73031. +
  73032. +#define PXPMC_DSI BIT21/* Device Specific Initialization */
  73033. +
  73034. +#define PXPMC_AUX_CUR_OFFS 22 /* Auxiliary Current Requirements */
  73035. +#define PXPMC_AUX_CUR_MASK (0x7 << PXPMC_AUX_CUR_OFFS)
  73036. +
  73037. +#define PXPMC_D1_SUP BIT25 /* D1 Power Management support*/
  73038. +
  73039. +#define PXPMC_D2_SUP BIT26 /* D2 Power Management support*/
  73040. +
  73041. +#define PXPMC_PME_SUP_OFFS 27 /* PM Event generation support*/
  73042. +#define PXPMC_PME_SUP_MASK (0x1f << PXPMC_PME_SUP_OFFS)
  73043. +
  73044. +/* PCI Express Power Management Control and Status Register*/
  73045. +/*PEX_POWER_MNG_STATUS_CONTROL (PXPMSC)*/
  73046. +
  73047. +#define PXPMSC_PM_STATE_OFFS 0 /* Power State */
  73048. +#define PXPMSC_PM_STATE_MASK (0x3 << PXPMSC_PM_STATE_OFFS)
  73049. +#define PXPMSC_PM_STATE_D0 (0x0 << PXPMSC_PM_STATE_OFFS)
  73050. +#define PXPMSC_PM_STATE_D1 (0x1 << PXPMSC_PM_STATE_OFFS)
  73051. +#define PXPMSC_PM_STATE_D2 (0x2 << PXPMSC_PM_STATE_OFFS)
  73052. +#define PXPMSC_PM_STATE_D3 (0x3 << PXPMSC_PM_STATE_OFFS)
  73053. +
  73054. +#define PXPMSC_PME_EN BIT8/* PM_PME Message Generation Enable */
  73055. +
  73056. +#define PXPMSC_PM_DATA_SEL_OFFS 9 /* Data Select*/
  73057. +#define PXPMSC_PM_DATA_SEL_MASK (0xf << PXPMSC_PM_DATA_SEL_OFFS)
  73058. +
  73059. +#define PXPMSC_PM_DATA_SCALE_OFFS 13 /* Data Scale */
  73060. +#define PXPMSC_PM_DATA_SCALE_MASK (0x3 << PXPMSC_PM_DATA_SCALE_OFFS)
  73061. +
  73062. +#define PXPMSC_PME_STAT BIT15/* PME Status */
  73063. +
  73064. +#define PXPMSC_PM_DATA_OFFS 24 /* State Data */
  73065. +#define PXPMSC_PM_DATA_MASK (0xff << PXPMSC_PM_DATA_OFFS)
  73066. +
  73067. +
  73068. +/* PCI Express MSI Message Control Register*/
  73069. +/*PEX_MSI_MESSAGE_CONTROL (PXMMC)*/
  73070. +
  73071. +#define PXMMC_CAP_ID_OFFS 0 /* Capability ID */
  73072. +#define PXMMC_CAP_ID_MASK (0xff << PXMMC_CAP_ID_OFFS)
  73073. +
  73074. +#define PXMMC_NEXT_PTR_OFFS 8 /* Next Item Pointer */
  73075. +#define PXMMC_NEXT_PTR_MASK (0xff << PXMMC_NEXT_PTR_OFFS)
  73076. +
  73077. +#define PXMMC_MSI_EN BIT18 /* MSI Enable */
  73078. +
  73079. +#define PXMMC_MULTI_CAP_OFFS 17 /* Multiple Message Capable */
  73080. +#define PXMMC_MULTI_CAP_MASK (0x7 << PXMMC_MULTI_CAP_OFFS)
  73081. +
  73082. +#define PXMMC_MULTI_EN_OFFS 20 /* Multiple Messages Enable */
  73083. +#define PXMMC_MULTI_EN_MASK (0x7 << PXMMC_MULTI_EN_OFFS)
  73084. +
  73085. +#define PXMMC_ADDR64 BIT23 /* 64-bit Addressing Capable */
  73086. +
  73087. +
  73088. +/* PCI Express MSI Message Address Register*/
  73089. +/*PEX_MSI_MESSAGE_ADDR (PXMMA)*/
  73090. +
  73091. +#define PXMMA_MSI_ADDR_OFFS 2 /* Message Address corresponds to
  73092. + Address[31:2] of the MSI MWr TLP*/
  73093. +#define PXMMA_MSI_ADDR_MASK (0x3fffffff << PXMMA_MSI_ADDR_OFFS)
  73094. +
  73095. +
  73096. +/* PCI Express MSI Message Address (High) Register */
  73097. +/*PEX_MSI_MESSAGE_HIGH_ADDR (PXMMHA)*/
  73098. +
  73099. +#define PXMMA_MSI_ADDR_H_OFFS 0 /* Message Upper Address corresponds to
  73100. + Address[63:32] of the MSI MWr TLP*/
  73101. +#define PXMMA_MSI_ADDR_H_MASK (0xffffffff << PXMMA_MSI_ADDR_H_OFFS )
  73102. +
  73103. +
  73104. +/* PCI Express MSI Message Data Register*/
  73105. +/*PEX_MSI_MESSAGE_DATA (PXMMD)*/
  73106. +
  73107. +#define PXMMD_MSI_DATA_OFFS 0 /* Message Data */
  73108. +#define PXMMD_MSI_DATA_MASK (0xffff << PXMMD_MSI_DATA_OFFS )
  73109. +
  73110. +
  73111. +/* PCI Express Capability Register*/
  73112. +/*PEX_CAPABILITY_REG (PXCR)*/
  73113. +
  73114. +#define PXCR_CAP_ID_OFFS 0 /* Capability ID*/
  73115. +#define PXCR_CAP_ID_MASK (0xff << PXCR_CAP_ID_OFFS)
  73116. +
  73117. +#define PXCR_NEXT_PTR_OFFS 8 /* Next Item Pointer*/
  73118. +#define PXCR_NEXT_PTR_MASK (0xff << PXCR_NEXT_PTR_OFFS)
  73119. +
  73120. +#define PXCR_CAP_VER_OFFS 16 /* Capability Version*/
  73121. +#define PXCR_CAP_VER_MASK (0xf << PXCR_CAP_VER_OFFS)
  73122. +
  73123. +#define PXCR_DEV_TYPE_OFFS 20 /* Device/Port Type*/
  73124. +#define PXCR_DEV_TYPE_MASK (0xf << PXCR_DEV_TYPE_OFFS)
  73125. +
  73126. +#define PXCR_SLOT_IMP BIT24 /* Slot Implemented*/
  73127. +
  73128. +#define PXCR_INT_MSG_NUM_OFFS 25 /* Interrupt Message Number*/
  73129. +#define PXCR_INT_MSG_NUM_MASK (0x1f << PXCR_INT_MSG_NUM_OFFS)
  73130. +
  73131. +
  73132. +/* PCI Express Device Capabilities Register */
  73133. +/*PEX_DEV_CAPABILITY_REG (PXDCR)*/
  73134. +
  73135. +#define PXDCR_MAX_PLD_SIZE_SUP_OFFS 0 /* Maximum Payload Size Supported*/
  73136. +#define PXDCR_MAX_PLD_SIZE_SUP_MASK (0x7 << PXDCR_MAX_PLD_SIZE_SUP_OFFS)
  73137. +
  73138. +#define PXDCR_EP_L0S_ACC_LAT_OFFS 6/* Endpoint L0s Acceptable Latency*/
  73139. +#define PXDCR_EP_L0S_ACC_LAT_MASK (0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73140. +#define PXDCR_EP_L0S_ACC_LAT_64NS_LESS (0x0 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73141. +#define PXDCR_EP_L0S_ACC_LAT_64NS_128NS (0x1 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73142. +#define PXDCR_EP_L0S_ACC_LAT_128NS_256NS (0x2 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73143. +#define PXDCR_EP_L0S_ACC_LAT_256NS_512NS (0x3 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73144. +#define PXDCR_EP_L0S_ACC_LAT_512NS_1US (0x4 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73145. +#define PXDCR_EP_L0S_ACC_LAT_1US_2US (0x5 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73146. +#define PXDCR_EP_L0S_ACC_LAT_2US_4US (0x6 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73147. +#define PXDCR_EP_L0S_ACC_LAT_4US_MORE (0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73148. +
  73149. +#define PXDCR_EP_L1_ACC_LAT_OFFS 9 /* Endpoint L1 Acceptable Latency*/
  73150. +#define PXDCR_EP_L1_ACC_LAT_MASK (0x7 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73151. +#define PXDCR_EP_L1_ACC_LAT_64NS_LESS (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73152. +#define PXDCR_EP_L1_ACC_LAT_64NS_128NS (0x1 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73153. +#define PXDCR_EP_L1_ACC_LAT_128NS_256NS (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73154. +#define PXDCR_EP_L1_ACC_LAT_256NS_512NS (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73155. +#define PXDCR_EP_L1_ACC_LAT_512NS_1US (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73156. +#define PXDCR_EP_L1_ACC_LAT_1US_2US (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73157. +#define PXDCR_EP_L1_ACC_LAT_2US_4US (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73158. +#define PXDCR_EP_L1_ACC_LAT_4US_MORE (0x7 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73159. +
  73160. +
  73161. +#define PXDCR_ATT_BUT_PRS_OFFS 12 /* Attention Button Present*/
  73162. +#define PXDCR_ATT_BUT_PRS_MASK BIT12
  73163. +#define PXDCR_ATT_BUT_PRS_IMPLEMENTED BIT12
  73164. +
  73165. +#define PXDCR_ATT_IND_PRS_OFFS 13 /* Attention Indicator Present*/
  73166. +#define PXDCR_ATT_IND_PRS_MASK BIT13
  73167. +#define PXDCR_ATT_IND_PRS_IMPLEMENTED BIT13
  73168. +
  73169. +#define PXDCR_PWR_IND_PRS_OFFS 14/* Power Indicator Present*/
  73170. +#define PXDCR_PWR_IND_PRS_MASK BIT14
  73171. +#define PXDCR_PWR_IND_PRS_IMPLEMENTED BIT14
  73172. +
  73173. +#define PXDCR_CAP_SPL_VAL_OFFS 18 /*Captured Slot Power Limit
  73174. + Value*/
  73175. +#define PXDCR_CAP_SPL_VAL_MASK (0xff << PXDCR_CAP_SPL_VAL_OFFS)
  73176. +
  73177. +#define PXDCR_CAP_SP_LSCL_OFFS 26 /* Captured Slot Power Limit
  73178. + Scale */
  73179. +#define PXDCR_CAP_SP_LSCL_MASK (0x3 << PXDCR_CAP_SP_LSCL_OFFS)
  73180. +
  73181. +/* PCI Express Device Control Status Register */
  73182. +/*PEX_DEV_CTRL_STAT_REG (PXDCSR)*/
  73183. +
  73184. +#define PXDCSR_COR_ERR_REP_EN BIT0 /* Correctable Error Reporting Enable*/
  73185. +#define PXDCSR_NF_ERR_REP_EN BIT1 /* Non-Fatal Error Reporting Enable*/
  73186. +#define PXDCSR_F_ERR_REP_EN BIT2 /* Fatal Error Reporting Enable*/
  73187. +#define PXDCSR_UR_REP_EN BIT3 /* Unsupported Request (UR)
  73188. + Reporting Enable*/
  73189. +#define PXDCSR_EN_RO BIT4 /* Enable Relaxed Ordering*/
  73190. +
  73191. +#define PXDCSR_MAX_PLD_SZ_OFFS 5 /* Maximum Payload Size*/
  73192. +#define PXDCSR_MAX_PLD_SZ_MASK (0x7 << PXDCSR_MAX_PLD_SZ_OFFS)
  73193. +#define PXDCSR_MAX_PLD_SZ_128B (0x0 << PXDCSR_MAX_PLD_SZ_OFFS)
  73194. +#define PXDCSR_EN_NS BIT11 /* Enable No Snoop*/
  73195. +
  73196. +#define PXDCSR_MAX_RD_RQ_SZ_OFFS 12 /* Maximum Read Request Size*/
  73197. +#define PXDCSR_MAX_RD_RQ_SZ_MASK (0x7 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73198. +#define PXDCSR_MAX_RD_RQ_SZ_128B (0x0 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73199. +#define PXDCSR_MAX_RD_RQ_SZ_256B (0x1 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73200. +#define PXDCSR_MAX_RD_RQ_SZ_512B (0x2 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73201. +#define PXDCSR_MAX_RD_RQ_SZ_1KB (0x3 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73202. +#define PXDCSR_MAX_RD_RQ_SZ_2KB (0x4 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73203. +#define PXDCSR_MAX_RD_RQ_SZ_4KB (0x5 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73204. +
  73205. +#define PXDCSR_COR_ERR_DET BIT16 /* Correctable Error Detected*/
  73206. +#define PXDCSR_NF_ERR_DET BIT17 /* Non-Fatal Error Detected.*/
  73207. +#define PXDCSR_F_ERR_DET BIT18 /* Fatal Error Detected.*/
  73208. +#define PXDCSR_UR_DET BIT19 /* Unsupported Request Detected */
  73209. +#define PXDCSR_AUX_PWR_DET BIT20 /* Reserved*/
  73210. +
  73211. +#define PXDCSR_TRANS_PEND_OFFS 21 /* Transactions Pending*/
  73212. +#define PXDCSR_TRANS_PEND_MASK BIT21
  73213. +#define PXDCSR_TRANS_PEND_NOT_COMPLETED (0x1 << PXDCSR_TRANS_PEND_OFFS)
  73214. +
  73215. +
  73216. +/* PCI Express Link Capabilities Register*/
  73217. +/*PEX_LINK_CAPABILITY_REG (PXLCR)*/
  73218. +
  73219. +#define PXLCR_MAX_LINK_SPD_OFFS 0 /* Maximum Link Speed*/
  73220. +#define PXLCR_MAX_LINK_SPD_MASK (0xf << PXLCR_MAX_LINK_SPD_OFFS)
  73221. +
  73222. +#define PXLCR_MAX_LNK_WDTH_OFFS 3 /* Maximum Link Width*/
  73223. +#define PXLCR_MAX_LNK_WDTH_MASK (0x3f << PXLCR_MAX_LNK_WDTH_OFFS)
  73224. +
  73225. +#define PXLCR_ASPM_SUP_OFFS 10 /* Active State Link PM Support*/
  73226. +#define PXLCR_ASPM_SUP_MASK (0x3 << PXLCR_ASPM_SUP_OFFS)
  73227. +
  73228. +#define PXLCR_L0S_EXT_LAT_OFFS 12 /* L0s Exit Latency*/
  73229. +#define PXLCR_L0S_EXT_LAT_MASK (0x7 << PXLCR_L0S_EXT_LAT_OFFS)
  73230. +#define PXLCR_L0S_EXT_LAT_64NS_LESS (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73231. +#define PXLCR_L0S_EXT_LAT_64NS_128NS (0x1 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73232. +#define PXLCR_L0S_EXT_LAT_128NS_256NS (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73233. +#define PXLCR_L0S_EXT_LAT_256NS_512NS (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73234. +#define PXLCR_L0S_EXT_LAT_512NS_1US (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73235. +#define PXLCR_L0S_EXT_LAT_1US_2US (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73236. +#define PXLCR_L0S_EXT_LAT_2US_4US (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73237. +
  73238. +#define PXLCR_POR_TNUM_OFFS 24 /* Port Number */
  73239. +#define PXLCR_POR_TNUM_MASK (0xff << PXLCR_POR_TNUM_OFFS)
  73240. +
  73241. +/* PCI Express Link Control Status Register */
  73242. +/*PEX_LINK_CTRL_STAT_REG (PXLCSR)*/
  73243. +
  73244. +#define PXLCSR_ASPM_CNT_OFFS 0 /* Active State Link PM Control */
  73245. +#define PXLCSR_ASPM_CNT_MASK (0x3 << PXLCSR_ASPM_CNT_OFFS)
  73246. +#define PXLCSR_ASPM_CNT_DISABLED (0x0 << PXLCSR_ASPM_CNT_OFFS)
  73247. +#define PXLCSR_ASPM_CNT_L0S_ENT_SUPP (0x1 << PXLCSR_ASPM_CNT_OFFS)
  73248. +#define PXLCSR_ASPM_CNT_L1S_ENT_SUPP (0x2 << PXLCSR_ASPM_CNT_OFFS)
  73249. +#define PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP (0x3 << PXLCSR_ASPM_CNT_OFFS)
  73250. +
  73251. +#define PXLCSR_RCB_OFFS 3 /* Read Completion Boundary */
  73252. +#define PXLCSR_RCB_MASK BIT3
  73253. +#define PXLCSR_RCB_64B (0 << PXLCSR_RCB_OFFS)
  73254. +#define PXLCSR_RCB_128B (1 << PXLCSR_RCB_OFFS)
  73255. +
  73256. +#define PXLCSR_LNK_DIS BIT4 /* Link Disable */
  73257. +#define PXLCSR_RETRN_LNK BIT5 /* Retrain Link */
  73258. +#define PXLCSR_CMN_CLK_CFG BIT6 /* Common Clock Configuration */
  73259. +#define PXLCSR_EXTD_SNC BIT7 /* Extended Sync */
  73260. +
  73261. +#define PXLCSR_LNK_SPD_OFFS 16 /* Link Speed */
  73262. +#define PXLCSR_LNK_SPD_MASK (0xf << PXLCSR_LNK_SPD_OFFS)
  73263. +
  73264. +#define PXLCSR_NEG_LNK_WDTH_OFFS 20 /* Negotiated Link Width */
  73265. +#define PXLCSR_NEG_LNK_WDTH_MASK (0x3f << PXLCSR_NEG_LNK_WDTH_OFFS)
  73266. +#define PXLCSR_NEG_LNK_WDTH_X1 (0x1 << PXLCSR_NEG_LNK_WDTH_OFFS)
  73267. +
  73268. +#define PXLCSR_LNK_TRN BIT27 /* Link Training */
  73269. +
  73270. +#define PXLCSR_SLT_CLK_CFG_OFFS 28 /* Slot Clock Configuration */
  73271. +#define PXLCSR_SLT_CLK_CFG_MASK BIT28
  73272. +#define PXLCSR_SLT_CLK_CFG_INDPNT (0x0 << PXLCSR_SLT_CLK_CFG_OFFS)
  73273. +#define PXLCSR_SLT_CLK_CFG_REF (0x1 << PXLCSR_SLT_CLK_CFG_OFFS)
  73274. +
  73275. +/* PCI Express Advanced Error Report Header Register */
  73276. +/*PEX_ADV_ERR_RPRT_HDR_TRGT_REG (PXAERHTR)*/
  73277. +
  73278. +/* PCI Express Uncorrectable Error Status Register*/
  73279. +/*PEX_UNCORRECT_ERR_STAT_REG (PXUESR)*/
  73280. +
  73281. +/* PCI Express Uncorrectable Error Mask Register */
  73282. +/*PEX_UNCORRECT_ERR_MASK_REG (PXUEMR)*/
  73283. +
  73284. +/* PCI Express Uncorrectable Error Severity Register */
  73285. +/*PEX_UNCORRECT_ERR_SERVITY_REG (PXUESR)*/
  73286. +
  73287. +/* PCI Express Correctable Error Status Register */
  73288. +/*PEX_CORRECT_ERR_STAT_REG (PXCESR)*/
  73289. +
  73290. +/* PCI Express Correctable Error Mask Register */
  73291. +/*PEX_CORRECT_ERR_MASK_REG (PXCEMR)*/
  73292. +
  73293. +/* PCI Express Advanced Error Capability and Control Register*/
  73294. +/*PEX_ADV_ERR_CAPABILITY_CTRL_REG (PXAECCR)*/
  73295. +
  73296. +/* PCI Express Header Log First DWORD Register*/
  73297. +/*PEX_HDR_LOG_FIRST_DWORD_REG (PXHLFDR)*/
  73298. +
  73299. +/* PCI Express Header Log Second DWORD Register*/
  73300. +/*PEX_HDR_LOG_SECOND_DWORD_REG (PXHLSDR)*/
  73301. +
  73302. +/* PCI Express Header Log Third DWORD Register*/
  73303. +/*PEX_HDR_LOG_THIRD_DWORD_REG (PXHLTDR)*/
  73304. +
  73305. +/* PCI Express Header Log Fourth DWORD Register*/
  73306. +/*PEX_HDR_LOG_FOURTH_DWORD_REG (PXHLFDR)*/
  73307. +
  73308. +#ifdef __cplusplus
  73309. +}
  73310. +#endif /* __cplusplus */
  73311. +
  73312. +#endif /* #ifndef __INCPEXREGSH */
  73313. +
  73314. +
  73315. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c
  73316. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c 1970-01-01 01:00:00.000000000 +0100
  73317. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c 2010-11-09 20:28:11.822495468 +0100
  73318. @@ -0,0 +1,313 @@
  73319. +/*******************************************************************************
  73320. +Copyright (C) Marvell International Ltd. and its affiliates
  73321. +
  73322. +This software file (the "File") is owned and distributed by Marvell
  73323. +International Ltd. and/or its affiliates ("Marvell") under the following
  73324. +alternative licensing terms. Once you have made an election to distribute the
  73325. +File under one of the following license alternatives, please (i) delete this
  73326. +introductory statement regarding license alternatives, (ii) delete the two
  73327. +license alternatives that you have not elected to use and (iii) preserve the
  73328. +Marvell copyright notice above.
  73329. +
  73330. +********************************************************************************
  73331. +Marvell Commercial License Option
  73332. +
  73333. +If you received this File from Marvell and you have entered into a commercial
  73334. +license agreement (a "Commercial License") with Marvell, the File is licensed
  73335. +to you under the terms of the applicable Commercial License.
  73336. +
  73337. +********************************************************************************
  73338. +Marvell GPL License Option
  73339. +
  73340. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73341. +modify this File in accordance with the terms and conditions of the General
  73342. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  73343. +available along with the File in the license.txt file or by writing to the Free
  73344. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  73345. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  73346. +
  73347. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  73348. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  73349. +DISCLAIMED. The GPL License provides additional details about this warranty
  73350. +disclaimer.
  73351. +********************************************************************************
  73352. +Marvell BSD License Option
  73353. +
  73354. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73355. +modify this File under the following licensing terms.
  73356. +Redistribution and use in source and binary forms, with or without modification,
  73357. +are permitted provided that the following conditions are met:
  73358. +
  73359. + * Redistributions of source code must retain the above copyright notice,
  73360. + this list of conditions and the following disclaimer.
  73361. +
  73362. + * Redistributions in binary form must reproduce the above copyright
  73363. + notice, this list of conditions and the following disclaimer in the
  73364. + documentation and/or other materials provided with the distribution.
  73365. +
  73366. + * Neither the name of Marvell nor the names of its contributors may be
  73367. + used to endorse or promote products derived from this software without
  73368. + specific prior written permission.
  73369. +
  73370. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  73371. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  73372. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  73373. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  73374. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  73375. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  73376. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  73377. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  73378. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  73379. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  73380. +
  73381. +*******************************************************************************/
  73382. +
  73383. +#include "mvPex.h"
  73384. +
  73385. +//#define MV_DEBUG
  73386. +/* defines */
  73387. +#ifdef MV_DEBUG
  73388. + #define DB(x) x
  73389. +#else
  73390. + #define DB(x)
  73391. +#endif
  73392. +
  73393. +/* locals */
  73394. +typedef struct
  73395. +{
  73396. + MV_U32 data;
  73397. + MV_U32 mask;
  73398. +}PEX_HEADER_DATA;
  73399. +
  73400. +/* local function forwad decleration */
  73401. +MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  73402. + MV_U32 regOff);
  73403. +MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  73404. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  73405. +void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev);
  73406. +
  73407. +
  73408. +PEX_HEADER_DATA configHdr[16] =
  73409. +{
  73410. +{0x888811ab, 0x00000000}, /*[device ID, vendor ID] */
  73411. +{0x00100007, 0x0000ffff}, /*[status register, command register] */
  73412. +{0x0604000e, 0x00000000}, /*[programming interface, sub class code, class code, revision ID] */
  73413. +{0x00010008, 0x00000000}, /*[BIST, header type, latency time, cache line] */
  73414. +{0x00000000, 0x00000000}, /*[base address 0] */
  73415. +{0x00000000, 0x00000000}, /*[base address 1] */
  73416. +{0x00000000, 0x00ffffff}, /*[secondary latency timersubordinate bus number, secondary bus number, primary bus number] */
  73417. +{0x0000f101, 0x00000000}, /*[secondary status ,IO limit, IO base] */
  73418. +{0x9ff0a000, 0x00000000}, /*[memory limit, memory base] */
  73419. +{0x0001fff1, 0x00000000}, /*[prefetch memory limit, prefetch memory base] */
  73420. +{0xffffffff, 0x00000000}, /*[prefetch memory base upper] */
  73421. +{0x00000000, 0x00000000}, /*[prefetch memory limit upper] */
  73422. +{0xeffff000, 0x00000000}, /*[IO limit upper 16 bits, IO base upper 16 bits] */
  73423. +{0x00000000, 0x00000000}, /*[reserved, capability pointer] */
  73424. +{0x00000000, 0x00000000}, /*[expansion ROM base address] */
  73425. +{0x00000000, 0x000000FF}, /*[bridge control, interrupt pin, interrupt line] */
  73426. +};
  73427. +
  73428. +
  73429. +#define HEADER_WRITE(data, offset) configHdr[offset/4].data = ((configHdr[offset/4].data & ~configHdr[offset/4].mask) | \
  73430. + (data & configHdr[offset/4].mask))
  73431. +#define HEADER_READ(offset) configHdr[offset/4].data
  73432. +
  73433. +/*******************************************************************************
  73434. +* mvVrtBrgPexInit - Initialize PEX interfaces
  73435. +*
  73436. +* DESCRIPTION:
  73437. +*
  73438. +* This function is responsible of intialization of the Pex Interface , It
  73439. +* configure the Pex Bars and Windows in the following manner:
  73440. +*
  73441. +* Assumptions :
  73442. +* Bar0 is always internal registers bar
  73443. +* Bar1 is always the DRAM bar
  73444. +* Bar2 is always the Device bar
  73445. +*
  73446. +* 1) Sets the Internal registers bar base by obtaining the base from
  73447. +* the CPU Interface
  73448. +* 2) Sets the DRAM bar base and size by getting the base and size from
  73449. +* the CPU Interface when the size is the sum of all enabled DRAM
  73450. +* chip selects and the base is the base of CS0 .
  73451. +* 3) Sets the Device bar base and size by getting these values from the
  73452. +* CPU Interface when the base is the base of the lowest base of the
  73453. +* Device chip selects, and the
  73454. +*
  73455. +*
  73456. +* INPUT:
  73457. +*
  73458. +* pexIf - PEX interface number.
  73459. +*
  73460. +*
  73461. +* OUTPUT:
  73462. +* None.
  73463. +*
  73464. +* RETURN:
  73465. +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
  73466. +*
  73467. +*******************************************************************************/
  73468. +MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf)
  73469. +{
  73470. + /* reset PEX tree to recover previous U-boot/Boot configurations */
  73471. + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
  73472. +
  73473. +
  73474. + resetPexConfig(pexIf, localBus, 1);
  73475. + return MV_OK;
  73476. +}
  73477. +
  73478. +
  73479. +MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  73480. + MV_U32 regOff)
  73481. +{
  73482. +
  73483. + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
  73484. + MV_U32 localDev = mvPexLocalDevNumGet(pexIf);
  73485. + MV_U32 val;
  73486. + if(bus == localBus)
  73487. + {
  73488. + if(dev > 1)
  73489. + {
  73490. +/* on the local device allow only device #0 & #1 */
  73491. + return 0xffffffff;
  73492. + }
  73493. + else
  73494. + if (dev == localDev)
  73495. + {
  73496. + /* read the memory controller registers */
  73497. + return mvPexHwConfigRead (pexIf, bus, dev, func, regOff);
  73498. + }
  73499. + else
  73500. + {
  73501. + /* access the virtual brg header */
  73502. + return HEADER_READ(regOff);
  73503. + }
  73504. + }
  73505. + else
  73506. + if(bus == (localBus + 1))
  73507. + {
  73508. + /* access the device behind the virtual bridge */
  73509. + if((dev == localDev) || (dev > 1))
  73510. + {
  73511. + return 0xffffffff;
  73512. + }
  73513. + else
  73514. + {
  73515. + /* access the device behind the virtual bridge, in this case
  73516. + * change the bus number to the local bus number in order to
  73517. + * generate type 0 config cycle
  73518. + */
  73519. + mvPexLocalBusNumSet(pexIf, bus);
  73520. + mvPexLocalDevNumSet(pexIf, 1);
  73521. + val = mvPexHwConfigRead (pexIf, bus, 0, func, regOff);
  73522. + mvPexLocalBusNumSet(pexIf, localBus);
  73523. + mvPexLocalDevNumSet(pexIf, localDev);
  73524. + return val;
  73525. + }
  73526. + }
  73527. + /* for all other devices use the HW function to get the
  73528. + * requested registers
  73529. + */
  73530. + mvPexLocalDevNumSet(pexIf, 1);
  73531. + val = mvPexHwConfigRead (pexIf, bus, dev, func, regOff);
  73532. + mvPexLocalDevNumSet(pexIf, localDev);
  73533. + return val;
  73534. +}
  73535. +
  73536. +
  73537. +MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  73538. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  73539. +{
  73540. + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
  73541. + MV_U32 localDev = mvPexLocalDevNumGet(pexIf);
  73542. + MV_STATUS status;
  73543. +
  73544. + if(bus == localBus)
  73545. + {
  73546. + if(dev > 1)
  73547. + {
  73548. + /* on the local device allow only device #0 & #1 */
  73549. + return MV_ERROR;
  73550. + }
  73551. + else
  73552. + if (dev == localDev)
  73553. + {
  73554. + /* read the memory controller registers */
  73555. + return mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);
  73556. + }
  73557. + else
  73558. + {
  73559. + /* access the virtual brg header */
  73560. + HEADER_WRITE(data, regOff);
  73561. + return MV_OK;
  73562. + }
  73563. + }
  73564. + else
  73565. + if(bus == (localBus + 1))
  73566. + {
  73567. + /* access the device behind the virtual bridge */
  73568. + if((dev == localDev) || (dev > 1))
  73569. + {
  73570. + return MV_ERROR;
  73571. + }
  73572. + else
  73573. + {
  73574. + /* access the device behind the virtual bridge, in this case
  73575. + * change the bus number to the local bus number in order to
  73576. + * generate type 0 config cycle
  73577. + */
  73578. + //return mvPexHwConfigWrite (pexIf, localBus, dev, func, regOff, data);
  73579. + mvPexLocalBusNumSet(pexIf, bus);
  73580. + mvPexLocalDevNumSet(pexIf, 1);
  73581. + status = mvPexHwConfigWrite (pexIf, bus, 0, func, regOff, data);
  73582. + mvPexLocalBusNumSet(pexIf, localBus);
  73583. + mvPexLocalDevNumSet(pexIf, localDev);
  73584. + return status;
  73585. +
  73586. + }
  73587. + }
  73588. + /* for all other devices use the HW function to get the
  73589. + * requested registers
  73590. + */
  73591. + mvPexLocalDevNumSet(pexIf, 1);
  73592. + status = mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);
  73593. + mvPexLocalDevNumSet(pexIf, localDev);
  73594. + return status;
  73595. +}
  73596. +
  73597. +
  73598. +
  73599. +
  73600. +void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev)
  73601. +{
  73602. + MV_U32 tData;
  73603. + MV_U32 i;
  73604. +
  73605. + /* restore the PEX configuration to initialization state */
  73606. + /* in case PEX P2P call recursive and reset config */
  73607. + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x0);
  73608. + if(tData != 0xffffffff)
  73609. + {
  73610. + /* agent had been found - check whether P2P */
  73611. + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x8);
  73612. + if((tData & 0xffff0000) == 0x06040000)
  73613. + {/* P2P */
  73614. + /* get the sec bus and the subordinate */
  73615. + MV_U32 secBus;
  73616. + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x18);
  73617. + secBus = ((tData >> 8) & 0xff);
  73618. + /* now scan on sec bus */
  73619. + for(i = 0;i < 0xff;i++)
  73620. + {
  73621. + resetPexConfig(pexIf, secBus, i);
  73622. + }
  73623. + /* now reset this device */
  73624. + DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));
  73625. + mvPexHwConfigWrite(pexIf, bus, dev, 0x0, 0x18, 0x0);
  73626. + DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));
  73627. + }
  73628. + }
  73629. +}
  73630. +
  73631. +
  73632. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h
  73633. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h 1970-01-01 01:00:00.000000000 +0100
  73634. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h 2010-11-09 20:28:11.861239834 +0100
  73635. @@ -0,0 +1,82 @@
  73636. +/*******************************************************************************
  73637. +Copyright (C) Marvell International Ltd. and its affiliates
  73638. +
  73639. +This software file (the "File") is owned and distributed by Marvell
  73640. +International Ltd. and/or its affiliates ("Marvell") under the following
  73641. +alternative licensing terms. Once you have made an election to distribute the
  73642. +File under one of the following license alternatives, please (i) delete this
  73643. +introductory statement regarding license alternatives, (ii) delete the two
  73644. +license alternatives that you have not elected to use and (iii) preserve the
  73645. +Marvell copyright notice above.
  73646. +
  73647. +********************************************************************************
  73648. +Marvell Commercial License Option
  73649. +
  73650. +If you received this File from Marvell and you have entered into a commercial
  73651. +license agreement (a "Commercial License") with Marvell, the File is licensed
  73652. +to you under the terms of the applicable Commercial License.
  73653. +
  73654. +********************************************************************************
  73655. +Marvell GPL License Option
  73656. +
  73657. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73658. +modify this File in accordance with the terms and conditions of the General
  73659. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  73660. +available along with the File in the license.txt file or by writing to the Free
  73661. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  73662. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  73663. +
  73664. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  73665. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  73666. +DISCLAIMED. The GPL License provides additional details about this warranty
  73667. +disclaimer.
  73668. +********************************************************************************
  73669. +Marvell BSD License Option
  73670. +
  73671. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73672. +modify this File under the following licensing terms.
  73673. +Redistribution and use in source and binary forms, with or without modification,
  73674. +are permitted provided that the following conditions are met:
  73675. +
  73676. + * Redistributions of source code must retain the above copyright notice,
  73677. + this list of conditions and the following disclaimer.
  73678. +
  73679. + * Redistributions in binary form must reproduce the above copyright
  73680. + notice, this list of conditions and the following disclaimer in the
  73681. + documentation and/or other materials provided with the distribution.
  73682. +
  73683. + * Neither the name of Marvell nor the names of its contributors may be
  73684. + used to endorse or promote products derived from this software without
  73685. + specific prior written permission.
  73686. +
  73687. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  73688. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  73689. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  73690. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  73691. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  73692. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  73693. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  73694. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  73695. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  73696. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  73697. +
  73698. +*******************************************************************************/
  73699. +
  73700. +#ifndef __INCVRTBRGPEXH
  73701. +#define __INCVRTBRGPEXH
  73702. +
  73703. +
  73704. +/* Global Functions prototypes */
  73705. +/* mvPexInit - Initialize PEX interfaces*/
  73706. +MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf);
  73707. +
  73708. +/* mvPexConfigRead - Read from configuration space */
  73709. +MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  73710. + MV_U32 func,MV_U32 regOff);
  73711. +
  73712. +/* mvPexConfigWrite - Write to configuration space */
  73713. +MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  73714. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  73715. +
  73716. +
  73717. +#endif /* #ifndef __INCPEXH */
  73718. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c
  73719. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c 1970-01-01 01:00:00.000000000 +0100
  73720. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c 2010-11-09 20:28:11.901246212 +0100
  73721. @@ -0,0 +1,1522 @@
  73722. +/*******************************************************************************
  73723. +Copyright (C) Marvell International Ltd. and its affiliates
  73724. +
  73725. +This software file (the "File") is owned and distributed by Marvell
  73726. +International Ltd. and/or its affiliates ("Marvell") under the following
  73727. +alternative licensing terms. Once you have made an election to distribute the
  73728. +File under one of the following license alternatives, please (i) delete this
  73729. +introductory statement regarding license alternatives, (ii) delete the two
  73730. +license alternatives that you have not elected to use and (iii) preserve the
  73731. +Marvell copyright notice above.
  73732. +
  73733. +********************************************************************************
  73734. +Marvell Commercial License Option
  73735. +
  73736. +If you received this File from Marvell and you have entered into a commercial
  73737. +license agreement (a "Commercial License") with Marvell, the File is licensed
  73738. +to you under the terms of the applicable Commercial License.
  73739. +
  73740. +********************************************************************************
  73741. +Marvell GPL License Option
  73742. +
  73743. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73744. +modify this File in accordance with the terms and conditions of the General
  73745. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  73746. +available along with the File in the license.txt file or by writing to the Free
  73747. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  73748. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  73749. +
  73750. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  73751. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  73752. +DISCLAIMED. The GPL License provides additional details about this warranty
  73753. +disclaimer.
  73754. +********************************************************************************
  73755. +Marvell BSD License Option
  73756. +
  73757. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73758. +modify this File under the following licensing terms.
  73759. +Redistribution and use in source and binary forms, with or without modification,
  73760. +are permitted provided that the following conditions are met:
  73761. +
  73762. + * Redistributions of source code must retain the above copyright notice,
  73763. + this list of conditions and the following disclaimer.
  73764. +
  73765. + * Redistributions in binary form must reproduce the above copyright
  73766. + notice, this list of conditions and the following disclaimer in the
  73767. + documentation and/or other materials provided with the distribution.
  73768. +
  73769. + * Neither the name of Marvell nor the names of its contributors may be
  73770. + used to endorse or promote products derived from this software without
  73771. + specific prior written permission.
  73772. +
  73773. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  73774. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  73775. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  73776. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  73777. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  73778. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  73779. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  73780. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  73781. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  73782. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  73783. +
  73784. +*******************************************************************************/
  73785. +#include "mvOs.h"
  73786. +#include "sflash/mvSFlash.h"
  73787. +#include "sflash/mvSFlashSpec.h"
  73788. +#include "spi/mvSpi.h"
  73789. +#include "spi/mvSpiCmnd.h"
  73790. +#include "ctrlEnv/mvCtrlEnvLib.h"
  73791. +
  73792. +/*#define MV_DEBUG*/
  73793. +#ifdef MV_DEBUG
  73794. +#define DB(x) x
  73795. +#else
  73796. +#define DB(x)
  73797. +#endif
  73798. +
  73799. +/* Globals */
  73800. +static MV_SFLASH_DEVICE_PARAMS sflash[] = {
  73801. + /* ST M25P32 SPI flash, 4MB, 64 sectors of 64K each */
  73802. + {
  73803. + MV_M25P_WREN_CMND_OPCD,
  73804. + MV_M25P_WRDI_CMND_OPCD,
  73805. + MV_M25P_RDID_CMND_OPCD,
  73806. + MV_M25P_RDSR_CMND_OPCD,
  73807. + MV_M25P_WRSR_CMND_OPCD,
  73808. + MV_M25P_READ_CMND_OPCD,
  73809. + MV_M25P_FAST_RD_CMND_OPCD,
  73810. + MV_M25P_PP_CMND_OPCD,
  73811. + MV_M25P_SE_CMND_OPCD,
  73812. + MV_M25P_BE_CMND_OPCD,
  73813. + MV_M25P_RES_CMND_OPCD,
  73814. + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
  73815. + MV_M25P32_SECTOR_SIZE,
  73816. + MV_M25P32_SECTOR_NUMBER,
  73817. + MV_M25P_PAGE_SIZE,
  73818. + "ST M25P32",
  73819. + MV_M25PXXX_ST_MANF_ID,
  73820. + MV_M25P32_DEVICE_ID,
  73821. + MV_M25P32_MAX_SPI_FREQ,
  73822. + MV_M25P32_MAX_FAST_SPI_FREQ,
  73823. + MV_M25P32_FAST_READ_DUMMY_BYTES
  73824. + },
  73825. + /* ST M25P64 SPI flash, 8MB, 128 sectors of 64K each */
  73826. + {
  73827. + MV_M25P_WREN_CMND_OPCD,
  73828. + MV_M25P_WRDI_CMND_OPCD,
  73829. + MV_M25P_RDID_CMND_OPCD,
  73830. + MV_M25P_RDSR_CMND_OPCD,
  73831. + MV_M25P_WRSR_CMND_OPCD,
  73832. + MV_M25P_READ_CMND_OPCD,
  73833. + MV_M25P_FAST_RD_CMND_OPCD,
  73834. + MV_M25P_PP_CMND_OPCD,
  73835. + MV_M25P_SE_CMND_OPCD,
  73836. + MV_M25P_BE_CMND_OPCD,
  73837. + MV_M25P_RES_CMND_OPCD,
  73838. + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
  73839. + MV_M25P64_SECTOR_SIZE,
  73840. + MV_M25P64_SECTOR_NUMBER,
  73841. + MV_M25P_PAGE_SIZE,
  73842. + "ST M25P64",
  73843. + MV_M25PXXX_ST_MANF_ID,
  73844. + MV_M25P64_DEVICE_ID,
  73845. + MV_M25P64_MAX_SPI_FREQ,
  73846. + MV_M25P64_MAX_FAST_SPI_FREQ,
  73847. + MV_M25P64_FAST_READ_DUMMY_BYTES
  73848. + },
  73849. + /* ST M25P128 SPI flash, 16MB, 64 sectors of 256K each */
  73850. + {
  73851. + MV_M25P_WREN_CMND_OPCD,
  73852. + MV_M25P_WRDI_CMND_OPCD,
  73853. + MV_M25P_RDID_CMND_OPCD,
  73854. + MV_M25P_RDSR_CMND_OPCD,
  73855. + MV_M25P_WRSR_CMND_OPCD,
  73856. + MV_M25P_READ_CMND_OPCD,
  73857. + MV_M25P_FAST_RD_CMND_OPCD,
  73858. + MV_M25P_PP_CMND_OPCD,
  73859. + MV_M25P_SE_CMND_OPCD,
  73860. + MV_M25P_BE_CMND_OPCD,
  73861. + MV_M25P_RES_CMND_OPCD,
  73862. + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
  73863. + MV_M25P128_SECTOR_SIZE,
  73864. + MV_M25P128_SECTOR_NUMBER,
  73865. + MV_M25P_PAGE_SIZE,
  73866. + "ST M25P128",
  73867. + MV_M25PXXX_ST_MANF_ID,
  73868. + MV_M25P128_DEVICE_ID,
  73869. + MV_M25P128_MAX_SPI_FREQ,
  73870. + MV_M25P128_MAX_FAST_SPI_FREQ,
  73871. + MV_M25P128_FAST_READ_DUMMY_BYTES
  73872. + },
  73873. + /* Macronix MXIC MX25L6405 SPI flash, 8MB, 128 sectors of 64K each */
  73874. + {
  73875. + MV_MX25L_WREN_CMND_OPCD,
  73876. + MV_MX25L_WRDI_CMND_OPCD,
  73877. + MV_MX25L_RDID_CMND_OPCD,
  73878. + MV_MX25L_RDSR_CMND_OPCD,
  73879. + MV_MX25L_WRSR_CMND_OPCD,
  73880. + MV_MX25L_READ_CMND_OPCD,
  73881. + MV_MX25L_FAST_RD_CMND_OPCD,
  73882. + MV_MX25L_PP_CMND_OPCD,
  73883. + MV_MX25L_SE_CMND_OPCD,
  73884. + MV_MX25L_BE_CMND_OPCD,
  73885. + MV_MX25L_RES_CMND_OPCD,
  73886. + MV_MX25L_DP_CMND_OPCD,
  73887. + MV_MX25L6405_SECTOR_SIZE,
  73888. + MV_MX25L6405_SECTOR_NUMBER,
  73889. + MV_MXIC_PAGE_SIZE,
  73890. + "MXIC MX25L6405",
  73891. + MV_MXIC_MANF_ID,
  73892. + MV_MX25L6405_DEVICE_ID,
  73893. + MV_MX25L6405_MAX_SPI_FREQ,
  73894. + MV_MX25L6405_MAX_FAST_SPI_FREQ,
  73895. + MV_MX25L6405_FAST_READ_DUMMY_BYTES
  73896. + },
  73897. + /* SPANSION S25FL128P SPI flash, 16MB, 64 sectors of 256K each */
  73898. + {
  73899. + MV_S25FL_WREN_CMND_OPCD,
  73900. + MV_S25FL_WRDI_CMND_OPCD,
  73901. + MV_S25FL_RDID_CMND_OPCD,
  73902. + MV_S25FL_RDSR_CMND_OPCD,
  73903. + MV_S25FL_WRSR_CMND_OPCD,
  73904. + MV_S25FL_READ_CMND_OPCD,
  73905. + MV_S25FL_FAST_RD_CMND_OPCD,
  73906. + MV_S25FL_PP_CMND_OPCD,
  73907. + MV_S25FL_SE_CMND_OPCD,
  73908. + MV_S25FL_BE_CMND_OPCD,
  73909. + MV_S25FL_RES_CMND_OPCD,
  73910. + MV_S25FL_DP_CMND_OPCD,
  73911. + MV_S25FL128_SECTOR_SIZE,
  73912. + MV_S25FL128_SECTOR_NUMBER,
  73913. + MV_S25FL_PAGE_SIZE,
  73914. + "SPANSION S25FL128",
  73915. + MV_SPANSION_MANF_ID,
  73916. + MV_S25FL128_DEVICE_ID,
  73917. + MV_S25FL128_MAX_SPI_FREQ,
  73918. + MV_M25P128_MAX_FAST_SPI_FREQ,
  73919. + MV_M25P128_FAST_READ_DUMMY_BYTES
  73920. + }
  73921. +};
  73922. +
  73923. +/* Static Functions */
  73924. +static MV_STATUS mvWriteEnable (MV_SFLASH_INFO * pFlinfo);
  73925. +static MV_STATUS mvStatusRegGet (MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg);
  73926. +static MV_STATUS mvStatusRegSet (MV_SFLASH_INFO * pFlinfo, MV_U8 sr);
  73927. +static MV_STATUS mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo);
  73928. +static MV_STATUS mvSFlashPageWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset, \
  73929. + MV_U8* pPageBuff, MV_U32 buffSize);
  73930. +static MV_STATUS mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, \
  73931. + MV_U8* manId, MV_U16* devId);
  73932. +
  73933. +/*******************************************************************************
  73934. +* mvWriteEnable - serialize the write enable sequence
  73935. +*
  73936. +* DESCRIPTION:
  73937. +* transmit the sequence for write enable
  73938. +*
  73939. +********************************************************************************/
  73940. +static MV_STATUS mvWriteEnable(MV_SFLASH_INFO * pFlinfo)
  73941. +{
  73942. + MV_U8 cmd[MV_SFLASH_WREN_CMND_LENGTH];
  73943. +
  73944. +
  73945. + cmd[0] = sflash[pFlinfo->index].opcdWREN;
  73946. +
  73947. + return mvSpiWriteThenRead(cmd, MV_SFLASH_WREN_CMND_LENGTH, NULL, 0, 0);
  73948. +}
  73949. +
  73950. +/*******************************************************************************
  73951. +* mvStatusRegGet - Retrieve the value of the status register
  73952. +*
  73953. +* DESCRIPTION:
  73954. +* perform the RDSR sequence to get the 8bit status register
  73955. +*
  73956. +********************************************************************************/
  73957. +static MV_STATUS mvStatusRegGet(MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg)
  73958. +{
  73959. + MV_STATUS ret;
  73960. + MV_U8 cmd[MV_SFLASH_RDSR_CMND_LENGTH];
  73961. + MV_U8 sr[MV_SFLASH_RDSR_REPLY_LENGTH];
  73962. +
  73963. +
  73964. +
  73965. +
  73966. + cmd[0] = sflash[pFlinfo->index].opcdRDSR;
  73967. +
  73968. + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDSR_CMND_LENGTH, sr,
  73969. + MV_SFLASH_RDSR_REPLY_LENGTH,0)) != MV_OK)
  73970. + return ret;
  73971. +
  73972. + *pStatReg = sr[0];
  73973. +
  73974. + return MV_OK;
  73975. +}
  73976. +
  73977. +/*******************************************************************************
  73978. +* mvWaitOnWipClear - Block waiting for the WIP (write in progress) to be cleared
  73979. +*
  73980. +* DESCRIPTION:
  73981. +* Block waiting for the WIP (write in progress) to be cleared
  73982. +*
  73983. +********************************************************************************/
  73984. +static MV_STATUS mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo)
  73985. +{
  73986. + MV_STATUS ret;
  73987. + MV_U32 i;
  73988. + MV_U8 stat;
  73989. +
  73990. + for (i=0; i<MV_SFLASH_MAX_WAIT_LOOP; i++)
  73991. + {
  73992. + if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)
  73993. + return ret;
  73994. +
  73995. + if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)
  73996. + return MV_OK;
  73997. + }
  73998. +
  73999. + DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)
  74000. + return MV_TIMEOUT;
  74001. +}
  74002. +
  74003. +/*******************************************************************************
  74004. +* mvWaitOnChipEraseDone - Block waiting for the WIP (write in progress) to be
  74005. +* cleared after a chip erase command which is supposed
  74006. +* to take about 2:30 minutes
  74007. +*
  74008. +* DESCRIPTION:
  74009. +* Block waiting for the WIP (write in progress) to be cleared
  74010. +*
  74011. +********************************************************************************/
  74012. +static MV_STATUS mvWaitOnChipEraseDone(MV_SFLASH_INFO * pFlinfo)
  74013. +{
  74014. + MV_STATUS ret;
  74015. + MV_U32 i;
  74016. + MV_U8 stat;
  74017. +
  74018. + for (i=0; i<MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP; i++)
  74019. + {
  74020. + if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)
  74021. + return ret;
  74022. +
  74023. + if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)
  74024. + return MV_OK;
  74025. + }
  74026. +
  74027. + DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)
  74028. + return MV_TIMEOUT;
  74029. +}
  74030. +
  74031. +/*******************************************************************************
  74032. +* mvStatusRegSet - Set the value of the 8bit status register
  74033. +*
  74034. +* DESCRIPTION:
  74035. +* Set the value of the 8bit status register
  74036. +*
  74037. +********************************************************************************/
  74038. +static MV_STATUS mvStatusRegSet(MV_SFLASH_INFO * pFlinfo, MV_U8 sr)
  74039. +{
  74040. + MV_STATUS ret;
  74041. + MV_U8 cmd[MV_SFLASH_WRSR_CMND_LENGTH];
  74042. +
  74043. +
  74044. + /* Issue the Write enable command prior the WRSR command */
  74045. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  74046. + return ret;
  74047. +
  74048. + /* Write the SR with the new values */
  74049. + cmd[0] = sflash[pFlinfo->index].opcdWRSR;
  74050. + cmd[1] = sr;
  74051. +
  74052. + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_WRSR_CMND_LENGTH, NULL, 0, 0)) != MV_OK)
  74053. + return ret;
  74054. +
  74055. + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
  74056. + return ret;
  74057. +
  74058. + mvOsDelay(1);
  74059. +
  74060. + return MV_OK;
  74061. +}
  74062. +
  74063. +/*******************************************************************************
  74064. +* mvSFlashPageWr - Write up to 256 Bytes in the same page
  74065. +*
  74066. +* DESCRIPTION:
  74067. +* Write a buffer up to the page size in length provided that the whole address
  74068. +* range is within the same page (alligned to page bounderies)
  74069. +*
  74070. +*******************************************************************************/
  74071. +static MV_STATUS mvSFlashPageWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  74072. + MV_U8* pPageBuff, MV_U32 buffSize)
  74073. +{
  74074. + MV_STATUS ret;
  74075. + MV_U8 cmd[MV_SFLASH_PP_CMND_LENGTH];
  74076. +
  74077. +
  74078. + /* Protection - check if the model was detected */
  74079. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74080. + {
  74081. + DB(mvOsPrintf("%s WARNING: Invalid parameter device index!\n", __FUNCTION__);)
  74082. + return MV_BAD_PARAM;
  74083. + }
  74084. +
  74085. + /* check that we do not cross the page bounderies */
  74086. + if (((offset & (sflash[pFlinfo->index].pageSize - 1)) + buffSize) >
  74087. + sflash[pFlinfo->index].pageSize)
  74088. + {
  74089. + DB(mvOsPrintf("%s WARNING: Page allignment problem!\n", __FUNCTION__);)
  74090. + return MV_OUT_OF_RANGE;
  74091. + }
  74092. +
  74093. + /* Issue the Write enable command prior the page program command */
  74094. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  74095. + return ret;
  74096. +
  74097. + cmd[0] = sflash[pFlinfo->index].opcdPP;
  74098. + cmd[1] = ((offset >> 16) & 0xFF);
  74099. + cmd[2] = ((offset >> 8) & 0xFF);
  74100. + cmd[3] = (offset & 0xFF);
  74101. +
  74102. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_PP_CMND_LENGTH, pPageBuff, buffSize)) != MV_OK)
  74103. + return ret;
  74104. +
  74105. + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
  74106. + return ret;
  74107. +
  74108. + return MV_OK;
  74109. +}
  74110. +
  74111. +/*******************************************************************************
  74112. +* mvSFlashWithDefaultsIdGet - Try to read the manufacturer and Device IDs from
  74113. +* the device using the default RDID opcode and the default WREN opcode.
  74114. +*
  74115. +* DESCRIPTION:
  74116. +* This is used to detect a generic device that uses the default opcodes
  74117. +* for the WREN and RDID.
  74118. +*
  74119. +********************************************************************************/
  74120. +static MV_STATUS mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* manId, MV_U16* devId)
  74121. +{
  74122. + MV_STATUS ret;
  74123. + MV_U8 cmdRDID[MV_SFLASH_RDID_CMND_LENGTH];
  74124. + MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];
  74125. +
  74126. +
  74127. +
  74128. + /* Use the default RDID opcode to read the IDs */
  74129. + cmdRDID[0] = MV_SFLASH_DEFAULT_RDID_OPCD; /* unknown model try default */
  74130. + if ((ret = mvSpiWriteThenRead(cmdRDID, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)
  74131. + return ret;
  74132. +
  74133. + *manId = id[0];
  74134. + *devId = 0;
  74135. + *devId |= (id[1] << 8);
  74136. + *devId |= id[2];
  74137. +
  74138. + return MV_OK;
  74139. +}
  74140. +
  74141. +/*
  74142. +#####################################################################################
  74143. +#####################################################################################
  74144. +*/
  74145. +
  74146. +/*******************************************************************************
  74147. +* mvSFlashInit - Initialize the serial flash device
  74148. +*
  74149. +* DESCRIPTION:
  74150. +* Perform the neccessary initialization and configuration
  74151. +*
  74152. +* INPUT:
  74153. +* pFlinfo: pointer to the Flash information structure
  74154. +* pFlinfo->baseAddr: base address in fast mode.
  74155. +* pFlinfo->index: Index of the flash in the sflash tabel. If the SPI
  74156. +* flash device does not support read Id command with
  74157. +* the standard opcode, then the user should supply this
  74158. +* as an input to skip the autodetection process!!!!
  74159. +*
  74160. +* OUTPUT:
  74161. +* pFlinfo: pointer to the Flash information structure after detection
  74162. +* pFlinfo->manufacturerId: Manufacturer ID
  74163. +* pFlinfo->deviceId: Device ID
  74164. +* pFlinfo->sectorSize: size of the sector (all sectors are the same).
  74165. +* pFlinfo->sectorNumber: number of sectors.
  74166. +* pFlinfo->pageSize: size of the page.
  74167. +* pFlinfo->index: Index of the detected flash in the sflash tabel
  74168. +*
  74169. +* RETURN:
  74170. +* Success or Error code.
  74171. +*
  74172. +*
  74173. +*******************************************************************************/
  74174. +MV_STATUS mvSFlashInit (MV_SFLASH_INFO * pFlinfo)
  74175. +{
  74176. + MV_STATUS ret;
  74177. + MV_U8 manf;
  74178. + MV_U16 dev;
  74179. + MV_U32 indx;
  74180. + MV_BOOL detectFlag = MV_FALSE;
  74181. +
  74182. + /* check for NULL pointer */
  74183. + if (pFlinfo == NULL)
  74184. + {
  74185. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74186. + return MV_BAD_PARAM;
  74187. + }
  74188. +
  74189. + /* Initialize the SPI interface with low frequency to make sure that the read ID succeeds */
  74190. + if ((ret = mvSpiInit(MV_SFLASH_BASIC_SPI_FREQ)) != MV_OK)
  74191. + {
  74192. + mvOsPrintf("%s ERROR: Failed to initialize the SPI interface!\n", __FUNCTION__);
  74193. + return ret;
  74194. + }
  74195. +
  74196. + /* First try to read the Manufacturer and Device IDs */
  74197. + if ((ret = mvSFlashIdGet(pFlinfo, &manf, &dev)) != MV_OK)
  74198. + {
  74199. + mvOsPrintf("%s ERROR: Failed to get the SFlash ID!\n", __FUNCTION__);
  74200. + return ret;
  74201. + }
  74202. +
  74203. + /* loop over the whole table and look for the appropriate SFLASH */
  74204. + for (indx=0; indx<MV_ARRAY_SIZE(sflash); indx++)
  74205. + {
  74206. + if ((manf == sflash[indx].manufacturerId) && (dev == sflash[indx].deviceId))
  74207. + {
  74208. + pFlinfo->manufacturerId = manf;
  74209. + pFlinfo->deviceId = dev;
  74210. + pFlinfo->index = indx;
  74211. + detectFlag = MV_TRUE;
  74212. + }
  74213. + }
  74214. +
  74215. + if(!detectFlag)
  74216. + {
  74217. + mvOsPrintf("%s ERROR: Unknown SPI flash device!\n", __FUNCTION__);
  74218. + return MV_FAIL;
  74219. + }
  74220. +
  74221. + /* fill the info based on the model detected */
  74222. + pFlinfo->sectorSize = sflash[pFlinfo->index].sectorSize;
  74223. + pFlinfo->sectorNumber = sflash[pFlinfo->index].sectorNumber;
  74224. + pFlinfo->pageSize = sflash[pFlinfo->index].pageSize;
  74225. +
  74226. + /* Set the SPI frequency to the MAX allowed for the device for best performance */
  74227. + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)
  74228. + {
  74229. + mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);
  74230. + return ret;
  74231. + }
  74232. +
  74233. + /* As default lock the SR */
  74234. + if ((ret = mvSFlashStatRegLock(pFlinfo, MV_TRUE)) != MV_OK)
  74235. + return ret;
  74236. +
  74237. + return MV_OK;
  74238. +}
  74239. +
  74240. +/*******************************************************************************
  74241. +* mvSFlashSectorErase - Erasse a single sector of the serial flash
  74242. +*
  74243. +* DESCRIPTION:
  74244. +* Issue the erase sector command and address
  74245. +*
  74246. +* INPUT:
  74247. +* pFlinfo: pointer to the Flash information structure
  74248. +* secNumber: sector Number to erase (0 -> (sectorNumber-1))
  74249. +*
  74250. +* OUTPUT:
  74251. +* None
  74252. +*
  74253. +* RETURN:
  74254. +* Success or Error code.
  74255. +*
  74256. +*
  74257. +*******************************************************************************/
  74258. +MV_STATUS mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber)
  74259. +{
  74260. + MV_STATUS ret;
  74261. + MV_U8 cmd[MV_SFLASH_SE_CMND_LENGTH];
  74262. +
  74263. + MV_U32 secAddr = (secNumber * pFlinfo->sectorSize);
  74264. +#if 0
  74265. + MV_U32 i;
  74266. + MV_U32 * pW = (MV_U32*) (secAddr + pFlinfo->baseAddr);
  74267. + MV_U32 erasedWord = 0xFFFFFFFF;
  74268. + MV_U32 wordsPerSector = (pFlinfo->sectorSize / sizeof(MV_U32));
  74269. + MV_BOOL eraseNeeded = MV_FALSE;
  74270. +#endif
  74271. + /* check for NULL pointer */
  74272. + if (pFlinfo == NULL)
  74273. + {
  74274. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74275. + return MV_BAD_PARAM;
  74276. + }
  74277. +
  74278. + /* Protection - check if the model was detected */
  74279. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74280. + {
  74281. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74282. + return MV_BAD_PARAM;
  74283. + }
  74284. +
  74285. + /* check that the sector number is valid */
  74286. + if (secNumber >= pFlinfo->sectorNumber)
  74287. + {
  74288. + DB(mvOsPrintf("%s WARNING: Invaild parameter sector number!\n", __FUNCTION__);)
  74289. + return MV_BAD_PARAM;
  74290. + }
  74291. +
  74292. + /* we don't want to access SPI in direct mode from in-direct API,
  74293. + becasue of timing issue between CS asserts. */
  74294. +#if 0
  74295. + /* First compare to FF and check if erase is needed */
  74296. + for (i=0; i<wordsPerSector; i++)
  74297. + {
  74298. + if (memcmp(pW, &erasedWord, sizeof(MV_U32)) != 0)
  74299. + {
  74300. + eraseNeeded = MV_TRUE;
  74301. + break;
  74302. + }
  74303. +
  74304. + ++pW;
  74305. + }
  74306. + if (!eraseNeeded)
  74307. + return MV_OK;
  74308. +#endif
  74309. +
  74310. + cmd[0] = sflash[pFlinfo->index].opcdSE;
  74311. + cmd[1] = ((secAddr >> 16) & 0xFF);
  74312. + cmd[2] = ((secAddr >> 8) & 0xFF);
  74313. + cmd[3] = (secAddr & 0xFF);
  74314. +
  74315. + /* Issue the Write enable command prior the sector erase command */
  74316. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  74317. + return ret;
  74318. +
  74319. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_SE_CMND_LENGTH, NULL, 0)) != MV_OK)
  74320. + return ret;
  74321. +
  74322. + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
  74323. + return ret;
  74324. +
  74325. + return MV_OK;
  74326. +}
  74327. +
  74328. +/*******************************************************************************
  74329. +* mvSFlashChipErase - Erasse the whole serial flash
  74330. +*
  74331. +* DESCRIPTION:
  74332. +* Issue the bulk (chip) erase command
  74333. +*
  74334. +* INPUT:
  74335. +* pFlinfo: pointer to the Flash information structure
  74336. +*
  74337. +* OUTPUT:
  74338. +* None
  74339. +*
  74340. +* RETURN:
  74341. +* Success or Error code.
  74342. +*
  74343. +*
  74344. +*******************************************************************************/
  74345. +MV_STATUS mvSFlashChipErase (MV_SFLASH_INFO * pFlinfo)
  74346. +{
  74347. + MV_STATUS ret;
  74348. + MV_U8 cmd[MV_SFLASH_BE_CMND_LENGTH];
  74349. +
  74350. +
  74351. + /* check for NULL pointer */
  74352. + if (pFlinfo == NULL)
  74353. + {
  74354. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74355. + return MV_BAD_PARAM;
  74356. + }
  74357. +
  74358. + /* Protection - check if the model was detected */
  74359. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74360. + {
  74361. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74362. + return MV_BAD_PARAM;
  74363. + }
  74364. +
  74365. + cmd[0] = sflash[pFlinfo->index].opcdBE;
  74366. +
  74367. + /* Issue the Write enable command prior the Bulk erase command */
  74368. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  74369. + return ret;
  74370. +
  74371. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_BE_CMND_LENGTH, NULL, 0)) != MV_OK)
  74372. + return ret;
  74373. +
  74374. + if ((ret = mvWaitOnChipEraseDone(pFlinfo)) != MV_OK)
  74375. + return ret;
  74376. +
  74377. + return MV_OK;
  74378. +}
  74379. +
  74380. +/*******************************************************************************
  74381. +* mvSFlashBlockRd - Read from the serial flash
  74382. +*
  74383. +* DESCRIPTION:
  74384. +* Issue the read command and address then perfom the needed read
  74385. +*
  74386. +* INPUT:
  74387. +* pFlinfo: pointer to the Flash information structure
  74388. +* offset: byte offset with the flash to start reading from
  74389. +* pReadBuff: pointer to the buffer to read the data in
  74390. +* buffSize: size of the buffer to read.
  74391. +*
  74392. +* OUTPUT:
  74393. +* pReadBuff: pointer to the buffer containing the read data
  74394. +*
  74395. +* RETURN:
  74396. +* Success or Error code.
  74397. +*
  74398. +*
  74399. +*******************************************************************************/
  74400. +MV_STATUS mvSFlashBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  74401. + MV_U8* pReadBuff, MV_U32 buffSize)
  74402. +{
  74403. + MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];
  74404. +
  74405. +
  74406. + /* check for NULL pointer */
  74407. + if ((pFlinfo == NULL) || (pReadBuff == NULL))
  74408. + {
  74409. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74410. + return MV_BAD_PARAM;
  74411. + }
  74412. +
  74413. + /* Protection - check if the model was detected */
  74414. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74415. + {
  74416. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74417. + return MV_BAD_PARAM;
  74418. + }
  74419. +
  74420. + cmd[0] = sflash[pFlinfo->index].opcdREAD;
  74421. + cmd[1] = ((offset >> 16) & 0xFF);
  74422. + cmd[2] = ((offset >> 8) & 0xFF);
  74423. + cmd[3] = (offset & 0xFF);
  74424. +
  74425. + return mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize, 0);
  74426. +}
  74427. +
  74428. +/*******************************************************************************
  74429. +* mvSFlashFastBlockRd - Fast read from the serial flash
  74430. +*
  74431. +* DESCRIPTION:
  74432. +* Issue the fast read command and address then perfom the needed read
  74433. +*
  74434. +* INPUT:
  74435. +* pFlinfo: pointer to the Flash information structure
  74436. +* offset: byte offset with the flash to start reading from
  74437. +* pReadBuff: pointer to the buffer to read the data in
  74438. +* buffSize: size of the buffer to read.
  74439. +*
  74440. +* OUTPUT:
  74441. +* pReadBuff: pointer to the buffer containing the read data
  74442. +*
  74443. +* RETURN:
  74444. +* Success or Error code.
  74445. +*
  74446. +*
  74447. +*******************************************************************************/
  74448. +MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  74449. + MV_U8* pReadBuff, MV_U32 buffSize)
  74450. +{
  74451. + MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];
  74452. + MV_STATUS ret;
  74453. +
  74454. + /* check for NULL pointer */
  74455. + if ((pFlinfo == NULL) || (pReadBuff == NULL))
  74456. + {
  74457. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74458. + return MV_BAD_PARAM;
  74459. + }
  74460. +
  74461. + /* Protection - check if the model was detected */
  74462. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74463. + {
  74464. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74465. + return MV_BAD_PARAM;
  74466. + }
  74467. +
  74468. + /* Set the SPI frequency to the MAX allowed for fast-read operations */
  74469. + mvOsPrintf("Setting freq to %d.\n",sflash[pFlinfo->index].spiMaxFastFreq);
  74470. + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFastFreq)) != MV_OK)
  74471. + {
  74472. + mvOsPrintf("%s ERROR: Failed to set the SPI fast frequency!\n", __FUNCTION__);
  74473. + return ret;
  74474. + }
  74475. +
  74476. + cmd[0] = sflash[pFlinfo->index].opcdFSTRD;
  74477. + cmd[1] = ((offset >> 16) & 0xFF);
  74478. + cmd[2] = ((offset >> 8) & 0xFF);
  74479. + cmd[3] = (offset & 0xFF);
  74480. +
  74481. +
  74482. + ret = mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize,
  74483. + sflash[pFlinfo->index].spiFastRdDummyBytes);
  74484. +
  74485. + /* Reset the SPI frequency to the MAX allowed for the device for best performance */
  74486. + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)
  74487. + {
  74488. + mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);
  74489. + return ret;
  74490. + }
  74491. +
  74492. + return ret;
  74493. +}
  74494. +
  74495. +
  74496. +/*******************************************************************************
  74497. +* mvSFlashBlockWr - Write a buffer with any size
  74498. +*
  74499. +* DESCRIPTION:
  74500. +* write regardless of the page boundaries and size limit per Page
  74501. +* program command
  74502. +*
  74503. +* INPUT:
  74504. +* pFlinfo: pointer to the Flash information structure
  74505. +* offset: byte offset within the flash region
  74506. +* pWriteBuff: pointer to the buffer holding the data to program
  74507. +* buffSize: size of the buffer to write
  74508. +*
  74509. +* OUTPUT:
  74510. +* None
  74511. +*
  74512. +* RETURN:
  74513. +* Success or Error code.
  74514. +*
  74515. +*
  74516. +*******************************************************************************/
  74517. +MV_STATUS mvSFlashBlockWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  74518. + MV_U8* pWriteBuff, MV_U32 buffSize)
  74519. +{
  74520. + MV_STATUS ret;
  74521. + MV_U32 data2write = buffSize;
  74522. + MV_U32 preAllOffset = (offset & MV_SFLASH_PAGE_ALLIGN_MASK(MV_M25P_PAGE_SIZE));
  74523. + MV_U32 preAllSz = (preAllOffset ? (MV_M25P_PAGE_SIZE - preAllOffset) : 0);
  74524. + MV_U32 writeOffset = offset;
  74525. +
  74526. + /* check for NULL pointer */
  74527. +#ifndef CONFIG_MARVELL
  74528. + if(NULL == pWriteBuff)
  74529. + {
  74530. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74531. + return MV_BAD_PARAM;
  74532. + }
  74533. +#endif
  74534. +
  74535. + if (pFlinfo == NULL)
  74536. + {
  74537. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74538. + return MV_BAD_PARAM;
  74539. + }
  74540. +
  74541. + /* Protection - check if the model was detected */
  74542. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74543. + {
  74544. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74545. + return MV_BAD_PARAM;
  74546. + }
  74547. +
  74548. + /* check that the buffer size does not exceed the flash size */
  74549. + if ((offset + buffSize) > mvSFlashSizeGet(pFlinfo))
  74550. + {
  74551. + DB(mvOsPrintf("%s WARNING: Write exceeds flash size!\n", __FUNCTION__);)
  74552. + return MV_OUT_OF_RANGE;
  74553. + }
  74554. +
  74555. + /* check if the total block size is less than the first chunk remainder */
  74556. + if (data2write < preAllSz)
  74557. + preAllSz = data2write;
  74558. +
  74559. + /* check if programing does not start at a 64byte alligned offset */
  74560. + if (preAllSz)
  74561. + {
  74562. + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, preAllSz)) != MV_OK)
  74563. + return ret;
  74564. +
  74565. + /* increment pointers and counters */
  74566. + writeOffset += preAllSz;
  74567. + data2write -= preAllSz;
  74568. + pWriteBuff += preAllSz;
  74569. + }
  74570. +
  74571. + /* program the data that fits in complete page chunks */
  74572. + while (data2write >= sflash[pFlinfo->index].pageSize)
  74573. + {
  74574. + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, sflash[pFlinfo->index].pageSize)) != MV_OK)
  74575. + return ret;
  74576. +
  74577. + /* increment pointers and counters */
  74578. + writeOffset += sflash[pFlinfo->index].pageSize;
  74579. + data2write -= sflash[pFlinfo->index].pageSize;
  74580. + pWriteBuff += sflash[pFlinfo->index].pageSize;
  74581. + }
  74582. +
  74583. + /* program the last partial chunk */
  74584. + if (data2write)
  74585. + {
  74586. + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, data2write)) != MV_OK)
  74587. + return ret;
  74588. + }
  74589. +
  74590. + return MV_OK;
  74591. +}
  74592. +
  74593. +/*******************************************************************************
  74594. +* mvSFlashIdGet - Get the manufacturer and device IDs.
  74595. +*
  74596. +* DESCRIPTION:
  74597. +* Get the Manufacturer and device IDs from the serial flash through
  74598. +* writing the RDID command then reading 3 bytes of data. In case that
  74599. +* this command was called for the first time in order to detect the
  74600. +* manufacturer and device IDs, then the default RDID opcode will be used
  74601. +* unless the device index is indicated by the user (in case the SPI flash
  74602. +* does not use the default RDID opcode).
  74603. +*
  74604. +* INPUT:
  74605. +* pFlinfo: pointer to the Flash information structure
  74606. +* pManId: pointer to the 8bit variable to hold the manufacturing ID
  74607. +* pDevId: pointer to the 16bit variable to hold the device ID
  74608. +*
  74609. +* OUTPUT:
  74610. +* pManId: pointer to the 8bit variable holding the manufacturing ID
  74611. +* pDevId: pointer to the 16bit variable holding the device ID
  74612. +*
  74613. +* RETURN:
  74614. +* Success or Error code.
  74615. +*
  74616. +*
  74617. +*******************************************************************************/
  74618. +MV_STATUS mvSFlashIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId)
  74619. +{
  74620. + MV_STATUS ret;
  74621. + MV_U8 cmd[MV_SFLASH_RDID_CMND_LENGTH];
  74622. + MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];
  74623. +
  74624. +
  74625. +
  74626. + /* check for NULL pointer */
  74627. + if ((pFlinfo == NULL) || (pManId == NULL) || (pDevId == NULL))
  74628. + {
  74629. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74630. + return MV_BAD_PARAM;
  74631. + }
  74632. +
  74633. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74634. + return mvSFlashWithDefaultsIdGet(pFlinfo, pManId, pDevId);
  74635. + else
  74636. + cmd[0] = sflash[pFlinfo->index].opcdRDID;
  74637. +
  74638. + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)
  74639. + return ret;
  74640. +
  74641. + *pManId = id[0];
  74642. + *pDevId = 0;
  74643. + *pDevId |= (id[1] << 8);
  74644. + *pDevId |= id[2];
  74645. +
  74646. + return MV_OK;
  74647. +}
  74648. +
  74649. +/*******************************************************************************
  74650. +* mvSFlashWpRegionSet - Set the Write-Protected region
  74651. +*
  74652. +* DESCRIPTION:
  74653. +* Set the Write-Protected region
  74654. +*
  74655. +* INPUT:
  74656. +* pFlinfo: pointer to the Flash information structure
  74657. +* wpRegion: which region will be protected
  74658. +*
  74659. +* OUTPUT:
  74660. +* None
  74661. +*
  74662. +* RETURN:
  74663. +* Success or Error code.
  74664. +*
  74665. +*
  74666. +*******************************************************************************/
  74667. +MV_STATUS mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion)
  74668. +{
  74669. + MV_U8 wpMask;
  74670. +
  74671. + /* check for NULL pointer */
  74672. + if (pFlinfo == NULL)
  74673. + {
  74674. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74675. + return MV_BAD_PARAM;
  74676. + }
  74677. +
  74678. + /* Protection - check if the model was detected */
  74679. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74680. + {
  74681. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74682. + return MV_BAD_PARAM;
  74683. + }
  74684. +
  74685. + /* Check if the chip is an ST flash; then WP supports only 3 bits */
  74686. + if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)
  74687. + {
  74688. + switch (wpRegion)
  74689. + {
  74690. + case MV_WP_NONE:
  74691. + wpMask = MV_M25P_STATUS_BP_NONE;
  74692. + break;
  74693. +
  74694. + case MV_WP_UPR_1OF128:
  74695. + DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)
  74696. + return MV_NOT_SUPPORTED;
  74697. +
  74698. + case MV_WP_UPR_1OF64:
  74699. + wpMask = MV_M25P_STATUS_BP_1_OF_64;
  74700. + break;
  74701. +
  74702. + case MV_WP_UPR_1OF32:
  74703. + wpMask = MV_M25P_STATUS_BP_1_OF_32;
  74704. + break;
  74705. +
  74706. + case MV_WP_UPR_1OF16:
  74707. + wpMask = MV_M25P_STATUS_BP_1_OF_16;
  74708. + break;
  74709. +
  74710. + case MV_WP_UPR_1OF8:
  74711. + wpMask = MV_M25P_STATUS_BP_1_OF_8;
  74712. + break;
  74713. +
  74714. + case MV_WP_UPR_1OF4:
  74715. + wpMask = MV_M25P_STATUS_BP_1_OF_4;
  74716. + break;
  74717. +
  74718. + case MV_WP_UPR_1OF2:
  74719. + wpMask = MV_M25P_STATUS_BP_1_OF_2;
  74720. + break;
  74721. +
  74722. + case MV_WP_ALL:
  74723. + wpMask = MV_M25P_STATUS_BP_ALL;
  74724. + break;
  74725. +
  74726. + default:
  74727. + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
  74728. + return MV_BAD_PARAM;
  74729. + }
  74730. + }
  74731. + /* check if the manufacturer is MXIC then the WP is 4bits */
  74732. + else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)
  74733. + {
  74734. + switch (wpRegion)
  74735. + {
  74736. + case MV_WP_NONE:
  74737. + wpMask = MV_MX25L_STATUS_BP_NONE;
  74738. + break;
  74739. +
  74740. + case MV_WP_UPR_1OF128:
  74741. + wpMask = MV_MX25L_STATUS_BP_1_OF_128;
  74742. + break;
  74743. +
  74744. + case MV_WP_UPR_1OF64:
  74745. + wpMask = MV_MX25L_STATUS_BP_1_OF_64;
  74746. + break;
  74747. +
  74748. + case MV_WP_UPR_1OF32:
  74749. + wpMask = MV_MX25L_STATUS_BP_1_OF_32;
  74750. + break;
  74751. +
  74752. + case MV_WP_UPR_1OF16:
  74753. + wpMask = MV_MX25L_STATUS_BP_1_OF_16;
  74754. + break;
  74755. +
  74756. + case MV_WP_UPR_1OF8:
  74757. + wpMask = MV_MX25L_STATUS_BP_1_OF_8;
  74758. + break;
  74759. +
  74760. + case MV_WP_UPR_1OF4:
  74761. + wpMask = MV_MX25L_STATUS_BP_1_OF_4;
  74762. + break;
  74763. +
  74764. + case MV_WP_UPR_1OF2:
  74765. + wpMask = MV_MX25L_STATUS_BP_1_OF_2;
  74766. + break;
  74767. +
  74768. + case MV_WP_ALL:
  74769. + wpMask = MV_MX25L_STATUS_BP_ALL;
  74770. + break;
  74771. +
  74772. + default:
  74773. + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
  74774. + return MV_BAD_PARAM;
  74775. + }
  74776. + }
  74777. + /* check if the manufacturer is SPANSION then the WP is 4bits */
  74778. + else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)
  74779. + {
  74780. + switch (wpRegion)
  74781. + {
  74782. + case MV_WP_NONE:
  74783. + wpMask = MV_S25FL_STATUS_BP_NONE;
  74784. + break;
  74785. +
  74786. + case MV_WP_UPR_1OF128:
  74787. + DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)
  74788. + return MV_NOT_SUPPORTED;
  74789. +
  74790. + case MV_WP_UPR_1OF64:
  74791. + wpMask = MV_S25FL_STATUS_BP_1_OF_64;
  74792. + break;
  74793. +
  74794. + case MV_WP_UPR_1OF32:
  74795. + wpMask = MV_S25FL_STATUS_BP_1_OF_32;
  74796. + break;
  74797. +
  74798. + case MV_WP_UPR_1OF16:
  74799. + wpMask = MV_S25FL_STATUS_BP_1_OF_16;
  74800. + break;
  74801. +
  74802. + case MV_WP_UPR_1OF8:
  74803. + wpMask = MV_S25FL_STATUS_BP_1_OF_8;
  74804. + break;
  74805. +
  74806. + case MV_WP_UPR_1OF4:
  74807. + wpMask = MV_S25FL_STATUS_BP_1_OF_4;
  74808. + break;
  74809. +
  74810. + case MV_WP_UPR_1OF2:
  74811. + wpMask = MV_S25FL_STATUS_BP_1_OF_2;
  74812. + break;
  74813. +
  74814. + case MV_WP_ALL:
  74815. + wpMask = MV_S25FL_STATUS_BP_ALL;
  74816. + break;
  74817. +
  74818. +
  74819. + default:
  74820. + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
  74821. + return MV_BAD_PARAM;
  74822. + }
  74823. + }
  74824. + else
  74825. + {
  74826. + DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)
  74827. + return MV_BAD_PARAM;
  74828. + }
  74829. +
  74830. + /* Verify that the SRWD bit is always set - register is s/w locked */
  74831. + wpMask |= MV_SFLASH_STATUS_REG_SRWD_MASK;
  74832. +
  74833. + return mvStatusRegSet(pFlinfo, wpMask);
  74834. +}
  74835. +
  74836. +/*******************************************************************************
  74837. +* mvSFlashWpRegionGet - Get the Write-Protected region configured
  74838. +*
  74839. +* DESCRIPTION:
  74840. +* Get from the chip the Write-Protected region configured
  74841. +*
  74842. +* INPUT:
  74843. +* pFlinfo: pointer to the Flash information structure
  74844. +* pWpRegion: pointer to the variable to return the WP region in
  74845. +*
  74846. +* OUTPUT:
  74847. +* wpRegion: pointer to the variable holding the WP region configured
  74848. +*
  74849. +* RETURN:
  74850. +* Success or Error code.
  74851. +*
  74852. +*
  74853. +*******************************************************************************/
  74854. +MV_STATUS mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion)
  74855. +{
  74856. + MV_STATUS ret;
  74857. + MV_U8 reg;
  74858. +
  74859. + /* check for NULL pointer */
  74860. + if ((pFlinfo == NULL) || (pWpRegion == NULL))
  74861. + {
  74862. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74863. + return MV_BAD_PARAM;
  74864. + }
  74865. +
  74866. + /* Protection - check if the model was detected */
  74867. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74868. + {
  74869. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74870. + return MV_BAD_PARAM;
  74871. + }
  74872. +
  74873. + if ((ret = mvStatusRegGet(pFlinfo, &reg)) != MV_OK)
  74874. + return ret;
  74875. +
  74876. + /* Check if the chip is an ST flash; then WP supports only 3 bits */
  74877. + if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)
  74878. + {
  74879. + switch ((reg & MV_M25P_STATUS_REG_WP_MASK))
  74880. + {
  74881. + case MV_M25P_STATUS_BP_NONE:
  74882. + *pWpRegion = MV_WP_NONE;
  74883. + break;
  74884. +
  74885. + case MV_M25P_STATUS_BP_1_OF_64:
  74886. + *pWpRegion = MV_WP_UPR_1OF64;
  74887. + break;
  74888. +
  74889. + case MV_M25P_STATUS_BP_1_OF_32:
  74890. + *pWpRegion = MV_WP_UPR_1OF32;
  74891. + break;
  74892. +
  74893. + case MV_M25P_STATUS_BP_1_OF_16:
  74894. + *pWpRegion = MV_WP_UPR_1OF16;
  74895. + break;
  74896. +
  74897. + case MV_M25P_STATUS_BP_1_OF_8:
  74898. + *pWpRegion = MV_WP_UPR_1OF8;
  74899. + break;
  74900. +
  74901. + case MV_M25P_STATUS_BP_1_OF_4:
  74902. + *pWpRegion = MV_WP_UPR_1OF4;
  74903. + break;
  74904. +
  74905. + case MV_M25P_STATUS_BP_1_OF_2:
  74906. + *pWpRegion = MV_WP_UPR_1OF2;
  74907. + break;
  74908. +
  74909. + case MV_M25P_STATUS_BP_ALL:
  74910. + *pWpRegion = MV_WP_ALL;
  74911. + break;
  74912. +
  74913. + default:
  74914. + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
  74915. + return MV_BAD_VALUE;
  74916. + }
  74917. + }
  74918. + /* check if the manufacturer is MXIC then the WP is 4bits */
  74919. + else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)
  74920. + {
  74921. + switch ((reg & MV_MX25L_STATUS_REG_WP_MASK))
  74922. + {
  74923. + case MV_MX25L_STATUS_BP_NONE:
  74924. + *pWpRegion = MV_WP_NONE;
  74925. + break;
  74926. +
  74927. + case MV_MX25L_STATUS_BP_1_OF_128:
  74928. + *pWpRegion = MV_WP_UPR_1OF128;
  74929. + break;
  74930. +
  74931. + case MV_MX25L_STATUS_BP_1_OF_64:
  74932. + *pWpRegion = MV_WP_UPR_1OF64;
  74933. + break;
  74934. +
  74935. + case MV_MX25L_STATUS_BP_1_OF_32:
  74936. + *pWpRegion = MV_WP_UPR_1OF32;
  74937. + break;
  74938. +
  74939. + case MV_MX25L_STATUS_BP_1_OF_16:
  74940. + *pWpRegion = MV_WP_UPR_1OF16;
  74941. + break;
  74942. +
  74943. + case MV_MX25L_STATUS_BP_1_OF_8:
  74944. + *pWpRegion = MV_WP_UPR_1OF8;
  74945. + break;
  74946. +
  74947. + case MV_MX25L_STATUS_BP_1_OF_4:
  74948. + *pWpRegion = MV_WP_UPR_1OF4;
  74949. + break;
  74950. +
  74951. + case MV_MX25L_STATUS_BP_1_OF_2:
  74952. + *pWpRegion = MV_WP_UPR_1OF2;
  74953. + break;
  74954. +
  74955. + case MV_MX25L_STATUS_BP_ALL:
  74956. + *pWpRegion = MV_WP_ALL;
  74957. + break;
  74958. +
  74959. + default:
  74960. + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
  74961. + return MV_BAD_VALUE;
  74962. + }
  74963. + }
  74964. + /* Check if the chip is an SPANSION flash; then WP supports only 3 bits */
  74965. + else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)
  74966. + {
  74967. + switch ((reg & MV_S25FL_STATUS_REG_WP_MASK))
  74968. + {
  74969. + case MV_S25FL_STATUS_BP_NONE:
  74970. + *pWpRegion = MV_WP_NONE;
  74971. + break;
  74972. +
  74973. + case MV_S25FL_STATUS_BP_1_OF_64:
  74974. + *pWpRegion = MV_WP_UPR_1OF64;
  74975. + break;
  74976. +
  74977. + case MV_S25FL_STATUS_BP_1_OF_32:
  74978. + *pWpRegion = MV_WP_UPR_1OF32;
  74979. + break;
  74980. +
  74981. + case MV_S25FL_STATUS_BP_1_OF_16:
  74982. + *pWpRegion = MV_WP_UPR_1OF16;
  74983. + break;
  74984. +
  74985. + case MV_S25FL_STATUS_BP_1_OF_8:
  74986. + *pWpRegion = MV_WP_UPR_1OF8;
  74987. + break;
  74988. +
  74989. + case MV_S25FL_STATUS_BP_1_OF_4:
  74990. + *pWpRegion = MV_WP_UPR_1OF4;
  74991. + break;
  74992. +
  74993. + case MV_S25FL_STATUS_BP_1_OF_2:
  74994. + *pWpRegion = MV_WP_UPR_1OF2;
  74995. + break;
  74996. +
  74997. + case MV_S25FL_STATUS_BP_ALL:
  74998. + *pWpRegion = MV_WP_ALL;
  74999. + break;
  75000. +
  75001. + default:
  75002. + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
  75003. + return MV_BAD_VALUE;
  75004. + }
  75005. + }
  75006. + else
  75007. + {
  75008. + DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)
  75009. + return MV_BAD_PARAM;
  75010. + }
  75011. +
  75012. + return MV_OK;
  75013. +}
  75014. +
  75015. +/*******************************************************************************
  75016. +* mvSFlashStatRegLock - Lock the status register for writing - W/Vpp
  75017. +* pin should be low to take effect
  75018. +*
  75019. +* DESCRIPTION:
  75020. +* Lock the access to the Status Register for writing. This will
  75021. +* cause the flash to enter the hardware protection mode if the W/Vpp
  75022. +* is low. If the W/Vpp is hi, the chip will be in soft protection mode, but
  75023. +* the register will continue to be writable if WREN sequence was used.
  75024. +*
  75025. +* INPUT:
  75026. +* pFlinfo: pointer to the Flash information structure
  75027. +* srLock: enable/disable (MV_TRUE/MV_FALSE) status registor lock mechanism
  75028. +*
  75029. +* OUTPUT:
  75030. +* None
  75031. +*
  75032. +* RETURN:
  75033. +* Success or Error code.
  75034. +*
  75035. +*
  75036. +*******************************************************************************/
  75037. +MV_STATUS mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock)
  75038. +{
  75039. + MV_STATUS ret;
  75040. + MV_U8 reg;
  75041. +
  75042. + /* check for NULL pointer */
  75043. + if (pFlinfo == NULL)
  75044. + {
  75045. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75046. + return MV_BAD_PARAM;
  75047. + }
  75048. +
  75049. + /* Protection - check if the model was detected */
  75050. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75051. + {
  75052. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75053. + return MV_BAD_PARAM;
  75054. + }
  75055. +
  75056. + if ((ret = mvStatusRegGet(pFlinfo, &reg)) != MV_OK)
  75057. + return ret;
  75058. +
  75059. + if (srLock)
  75060. + reg |= MV_SFLASH_STATUS_REG_SRWD_MASK;
  75061. + else
  75062. + reg &= ~MV_SFLASH_STATUS_REG_SRWD_MASK;
  75063. +
  75064. + return mvStatusRegSet(pFlinfo, reg);
  75065. +}
  75066. +
  75067. +/*******************************************************************************
  75068. +* mvSFlashSizeGet - Get the size of the SPI flash
  75069. +*
  75070. +* DESCRIPTION:
  75071. +* based on the sector number and size of each sector calculate the total
  75072. +* size of the flash memory.
  75073. +*
  75074. +* INPUT:
  75075. +* pFlinfo: pointer to the Flash information structure
  75076. +*
  75077. +* OUTPUT:
  75078. +* None.
  75079. +*
  75080. +* RETURN:
  75081. +* Size of the flash in bytes.
  75082. +*
  75083. +*
  75084. +*******************************************************************************/
  75085. +MV_U32 mvSFlashSizeGet (MV_SFLASH_INFO * pFlinfo)
  75086. +{
  75087. + /* check for NULL pointer */
  75088. + if (pFlinfo == NULL)
  75089. + {
  75090. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75091. + return 0;
  75092. + }
  75093. +
  75094. + return (pFlinfo->sectorSize * pFlinfo->sectorNumber);
  75095. +}
  75096. +
  75097. +/*******************************************************************************
  75098. +* mvSFlashPowerSaveEnter - Cause the falsh device to go into power save mode
  75099. +*
  75100. +* DESCRIPTION:
  75101. +* Enter a special power save mode.
  75102. +*
  75103. +* INPUT:
  75104. +* pFlinfo: pointer to the Flash information structure
  75105. +*
  75106. +* OUTPUT:
  75107. +* None.
  75108. +*
  75109. +* RETURN:
  75110. +* Size of the flash in bytes.
  75111. +*
  75112. +*
  75113. +*******************************************************************************/
  75114. +MV_STATUS mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo)
  75115. +{
  75116. + MV_STATUS ret;
  75117. + MV_U8 cmd[MV_SFLASH_DP_CMND_LENGTH];
  75118. +
  75119. +
  75120. + /* check for NULL pointer */
  75121. + if (pFlinfo == NULL)
  75122. + {
  75123. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75124. + return 0;
  75125. + }
  75126. +
  75127. + /* Protection - check if the model was detected */
  75128. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75129. + {
  75130. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75131. + return MV_BAD_PARAM;
  75132. + }
  75133. +
  75134. + /* check that power save mode is supported in the specific device */
  75135. + if (sflash[pFlinfo->index].opcdPwrSave == MV_SFLASH_NO_SPECIFIC_OPCD)
  75136. + {
  75137. + DB(mvOsPrintf("%s WARNING: Power save not supported for this device!\n", __FUNCTION__);)
  75138. + return MV_NOT_SUPPORTED;
  75139. + }
  75140. +
  75141. + cmd[0] = sflash[pFlinfo->index].opcdPwrSave;
  75142. +
  75143. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_DP_CMND_LENGTH, NULL, 0)) != MV_OK)
  75144. + return ret;
  75145. +
  75146. + return MV_OK;
  75147. +
  75148. +}
  75149. +
  75150. +/*******************************************************************************
  75151. +* mvSFlashPowerSaveExit - Cause the falsh device to exit the power save mode
  75152. +*
  75153. +* DESCRIPTION:
  75154. +* Exit the deep power save mode.
  75155. +*
  75156. +* INPUT:
  75157. +* pFlinfo: pointer to the Flash information structure
  75158. +*
  75159. +* OUTPUT:
  75160. +* None.
  75161. +*
  75162. +* RETURN:
  75163. +* Size of the flash in bytes.
  75164. +*
  75165. +*
  75166. +*******************************************************************************/
  75167. +MV_STATUS mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo)
  75168. +{
  75169. + MV_STATUS ret;
  75170. + MV_U8 cmd[MV_SFLASH_RES_CMND_LENGTH];
  75171. +
  75172. +
  75173. + /* check for NULL pointer */
  75174. + if (pFlinfo == NULL)
  75175. + {
  75176. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75177. + return 0;
  75178. + }
  75179. +
  75180. + /* Protection - check if the model was detected */
  75181. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75182. + {
  75183. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75184. + return MV_BAD_PARAM;
  75185. + }
  75186. +
  75187. + /* check that power save mode is supported in the specific device */
  75188. + if (sflash[pFlinfo->index].opcdRES == MV_SFLASH_NO_SPECIFIC_OPCD)
  75189. + {
  75190. + DB(mvOsPrintf("%s WARNING: Read Electronic Signature not supported for this device!\n", __FUNCTION__);)
  75191. + return MV_NOT_SUPPORTED;
  75192. + }
  75193. +
  75194. + cmd[0] = sflash[pFlinfo->index].opcdRES;
  75195. +
  75196. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_RES_CMND_LENGTH, NULL, 0)) != MV_OK)
  75197. + return ret;
  75198. +
  75199. + /* add the delay needed for the device to wake up */
  75200. + mvOsDelay(MV_MXIC_DP_EXIT_DELAY); /* 30 ms */
  75201. +
  75202. + return MV_OK;
  75203. +
  75204. +}
  75205. +
  75206. +/*******************************************************************************
  75207. +* mvSFlashModelGet - Retreive the string with the device manufacturer and model
  75208. +*
  75209. +* DESCRIPTION:
  75210. +* Retreive the string with the device manufacturer and model
  75211. +*
  75212. +* INPUT:
  75213. +* pFlinfo: pointer to the Flash information structure
  75214. +*
  75215. +* OUTPUT:
  75216. +* None.
  75217. +*
  75218. +* RETURN:
  75219. +* pointer to the string indicating the device manufacturer and model
  75220. +*
  75221. +*
  75222. +*******************************************************************************/
  75223. +const MV_8 * mvSFlashModelGet (MV_SFLASH_INFO * pFlinfo)
  75224. +{
  75225. + static const MV_8 * unknModel = (const MV_8 *)"Unknown";
  75226. +
  75227. + /* check for NULL pointer */
  75228. + if (pFlinfo == NULL)
  75229. + {
  75230. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75231. + return 0;
  75232. + }
  75233. +
  75234. + /* Protection - check if the model was detected */
  75235. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75236. + {
  75237. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75238. + return unknModel;
  75239. + }
  75240. +
  75241. + return sflash[pFlinfo->index].deviceModel;
  75242. +}
  75243. +
  75244. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h
  75245. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h 1970-01-01 01:00:00.000000000 +0100
  75246. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h 2010-11-09 20:28:11.941246441 +0100
  75247. @@ -0,0 +1,166 @@
  75248. +/*******************************************************************************
  75249. +Copyright (C) Marvell International Ltd. and its affiliates
  75250. +
  75251. +This software file (the "File") is owned and distributed by Marvell
  75252. +International Ltd. and/or its affiliates ("Marvell") under the following
  75253. +alternative licensing terms. Once you have made an election to distribute the
  75254. +File under one of the following license alternatives, please (i) delete this
  75255. +introductory statement regarding license alternatives, (ii) delete the two
  75256. +license alternatives that you have not elected to use and (iii) preserve the
  75257. +Marvell copyright notice above.
  75258. +
  75259. +********************************************************************************
  75260. +Marvell Commercial License Option
  75261. +
  75262. +If you received this File from Marvell and you have entered into a commercial
  75263. +license agreement (a "Commercial License") with Marvell, the File is licensed
  75264. +to you under the terms of the applicable Commercial License.
  75265. +
  75266. +********************************************************************************
  75267. +Marvell GPL License Option
  75268. +
  75269. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75270. +modify this File in accordance with the terms and conditions of the General
  75271. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  75272. +available along with the File in the license.txt file or by writing to the Free
  75273. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  75274. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  75275. +
  75276. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  75277. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  75278. +DISCLAIMED. The GPL License provides additional details about this warranty
  75279. +disclaimer.
  75280. +********************************************************************************
  75281. +Marvell BSD License Option
  75282. +
  75283. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75284. +modify this File under the following licensing terms.
  75285. +Redistribution and use in source and binary forms, with or without modification,
  75286. +are permitted provided that the following conditions are met:
  75287. +
  75288. + * Redistributions of source code must retain the above copyright notice,
  75289. + this list of conditions and the following disclaimer.
  75290. +
  75291. + * Redistributions in binary form must reproduce the above copyright
  75292. + notice, this list of conditions and the following disclaimer in the
  75293. + documentation and/or other materials provided with the distribution.
  75294. +
  75295. + * Neither the name of Marvell nor the names of its contributors may be
  75296. + used to endorse or promote products derived from this software without
  75297. + specific prior written permission.
  75298. +
  75299. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  75300. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  75301. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  75302. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  75303. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  75304. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  75305. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  75306. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  75307. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  75308. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  75309. +
  75310. +*******************************************************************************/
  75311. +
  75312. +#ifndef __INCmvSFlashH
  75313. +#define __INCmvSFlashH
  75314. +
  75315. +#include "mvTypes.h"
  75316. +
  75317. +/* MCAROS */
  75318. +#define MV_SFLASH_PAGE_ALLIGN_MASK(pgSz) (pgSz-1)
  75319. +#define MV_ARRAY_SIZE(a) ((sizeof(a)) / (sizeof(a[0])))
  75320. +
  75321. +/* Constants */
  75322. +#define MV_INVALID_DEVICE_NUMBER 0xFFFFFFFF
  75323. +/* 10 MHz is the minimum possible SPI frequency when tclk is set 200MHz*/
  75324. +#define MV_SFLASH_BASIC_SPI_FREQ 10000000
  75325. +/* enumerations */
  75326. +typedef enum
  75327. +{
  75328. + MV_WP_NONE, /* Unprotect the whole chip */
  75329. + MV_WP_UPR_1OF128, /* Write protect the upper 1/128 part */
  75330. + MV_WP_UPR_1OF64, /* Write protect the upper 1/64 part */
  75331. + MV_WP_UPR_1OF32, /* Write protect the upper 1/32 part */
  75332. + MV_WP_UPR_1OF16, /* Write protect the upper 1/16 part */
  75333. + MV_WP_UPR_1OF8, /* Write protect the upper 1/8 part */
  75334. + MV_WP_UPR_1OF4, /* Write protect the upper 1/4 part */
  75335. + MV_WP_UPR_1OF2, /* Write protect the upper 1/2 part */
  75336. + MV_WP_ALL /* Write protect the whole chip */
  75337. +} MV_SFLASH_WP_REGION;
  75338. +
  75339. +/* Type Definitions */
  75340. +typedef struct
  75341. +{
  75342. + MV_U8 opcdWREN; /* Write enable opcode */
  75343. + MV_U8 opcdWRDI; /* Write disable opcode */
  75344. + MV_U8 opcdRDID; /* Read ID opcode */
  75345. + MV_U8 opcdRDSR; /* Read Status Register opcode */
  75346. + MV_U8 opcdWRSR; /* Write Status register opcode */
  75347. + MV_U8 opcdREAD; /* Read opcode */
  75348. + MV_U8 opcdFSTRD; /* Fast Read opcode */
  75349. + MV_U8 opcdPP; /* Page program opcode */
  75350. + MV_U8 opcdSE; /* Sector erase opcode */
  75351. + MV_U8 opcdBE; /* Bulk erase opcode */
  75352. + MV_U8 opcdRES; /* Read electronic signature */
  75353. + MV_U8 opcdPwrSave; /* Go into power save mode */
  75354. + MV_U32 sectorSize; /* Size of each sector */
  75355. + MV_U32 sectorNumber; /* Number of sectors */
  75356. + MV_U32 pageSize; /* size of each page */
  75357. + const char * deviceModel; /* string with the device model */
  75358. + MV_U32 manufacturerId; /* The manufacturer ID */
  75359. + MV_U32 deviceId; /* Device ID */
  75360. + MV_U32 spiMaxFreq; /* The MAX frequency that can be used with the device */
  75361. + MV_U32 spiMaxFastFreq; /* The MAX frequency that can be used with the device for fast reads */
  75362. + MV_U32 spiFastRdDummyBytes; /* Number of dumy bytes to read before real data when working in fast read mode. */
  75363. +} MV_SFLASH_DEVICE_PARAMS;
  75364. +
  75365. +typedef struct
  75366. +{
  75367. + MV_U32 baseAddr; /* Flash Base Address used in fast mode */
  75368. + MV_U8 manufacturerId; /* Manufacturer ID */
  75369. + MV_U16 deviceId; /* Device ID */
  75370. + MV_U32 sectorSize; /* Size of each sector - all the same */
  75371. + MV_U32 sectorNumber; /* Number of sectors */
  75372. + MV_U32 pageSize; /* Page size - affect allignment */
  75373. + MV_U32 index; /* index of the device in the sflash table (internal parameter) */
  75374. +} MV_SFLASH_INFO;
  75375. +
  75376. +/* Function Prototypes */
  75377. +/* Init */
  75378. +MV_STATUS mvSFlashInit (MV_SFLASH_INFO * pFlinfo);
  75379. +
  75380. +/* erase */
  75381. +MV_STATUS mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber);
  75382. +MV_STATUS mvSFlashChipErase (MV_SFLASH_INFO * pFlinfo);
  75383. +
  75384. +/* Read */
  75385. +MV_STATUS mvSFlashBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  75386. + MV_U8* pReadBuff, MV_U32 buffSize);
  75387. +MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  75388. + MV_U8* pReadBuff, MV_U32 buffSize);
  75389. +
  75390. +/* write regardless of the page boundaries and size limit per Page program command */
  75391. +MV_STATUS mvSFlashBlockWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  75392. + MV_U8* pWriteBuff, MV_U32 buffSize);
  75393. +/* Get IDs */
  75394. +MV_STATUS mvSFlashIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId);
  75395. +
  75396. +/* Set and Get the Write Protection region - if the Status register is not locked */
  75397. +MV_STATUS mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion);
  75398. +MV_STATUS mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion);
  75399. +
  75400. +/* Lock the status register for writing - W/Vpp pin should be low to take effect */
  75401. +MV_STATUS mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock);
  75402. +
  75403. +/* Get the regions sizes */
  75404. +MV_U32 mvSFlashSizeGet (MV_SFLASH_INFO * pFlinfo);
  75405. +
  75406. +/* Cause the falsh device to go into power save mode */
  75407. +MV_STATUS mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo);
  75408. +MV_STATUS mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo);
  75409. +
  75410. +/* Retreive the string with the device manufacturer and model */
  75411. +const MV_8 * mvSFlashModelGet (MV_SFLASH_INFO * pFlinfo);
  75412. +
  75413. +#endif /* __INCmvSFlashH */
  75414. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h
  75415. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h 1970-01-01 01:00:00.000000000 +0100
  75416. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h 2010-11-09 20:28:11.981246772 +0100
  75417. @@ -0,0 +1,233 @@
  75418. +/*******************************************************************************
  75419. +Copyright (C) Marvell International Ltd. and its affiliates
  75420. +
  75421. +This software file (the "File") is owned and distributed by Marvell
  75422. +International Ltd. and/or its affiliates ("Marvell") under the following
  75423. +alternative licensing terms. Once you have made an election to distribute the
  75424. +File under one of the following license alternatives, please (i) delete this
  75425. +introductory statement regarding license alternatives, (ii) delete the two
  75426. +license alternatives that you have not elected to use and (iii) preserve the
  75427. +Marvell copyright notice above.
  75428. +
  75429. +********************************************************************************
  75430. +Marvell Commercial License Option
  75431. +
  75432. +If you received this File from Marvell and you have entered into a commercial
  75433. +license agreement (a "Commercial License") with Marvell, the File is licensed
  75434. +to you under the terms of the applicable Commercial License.
  75435. +
  75436. +********************************************************************************
  75437. +Marvell GPL License Option
  75438. +
  75439. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75440. +modify this File in accordance with the terms and conditions of the General
  75441. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  75442. +available along with the File in the license.txt file or by writing to the Free
  75443. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  75444. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  75445. +
  75446. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  75447. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  75448. +DISCLAIMED. The GPL License provides additional details about this warranty
  75449. +disclaimer.
  75450. +********************************************************************************
  75451. +Marvell BSD License Option
  75452. +
  75453. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75454. +modify this File under the following licensing terms.
  75455. +Redistribution and use in source and binary forms, with or without modification,
  75456. +are permitted provided that the following conditions are met:
  75457. +
  75458. + * Redistributions of source code must retain the above copyright notice,
  75459. + this list of conditions and the following disclaimer.
  75460. +
  75461. + * Redistributions in binary form must reproduce the above copyright
  75462. + notice, this list of conditions and the following disclaimer in the
  75463. + documentation and/or other materials provided with the distribution.
  75464. +
  75465. + * Neither the name of Marvell nor the names of its contributors may be
  75466. + used to endorse or promote products derived from this software without
  75467. + specific prior written permission.
  75468. +
  75469. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  75470. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  75471. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  75472. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  75473. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  75474. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  75475. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  75476. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  75477. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  75478. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  75479. +
  75480. +*******************************************************************************/
  75481. +
  75482. +#ifndef __INCmvSFlashSpecH
  75483. +#define __INCmvSFlashSpecH
  75484. +
  75485. +/* Constants */
  75486. +#define MV_SFLASH_READ_CMND_LENGTH 4 /* 1B opcode + 3B address */
  75487. +#define MV_SFLASH_SE_CMND_LENGTH 4 /* 1B opcode + 3B address */
  75488. +#define MV_SFLASH_BE_CMND_LENGTH 1 /* 1B opcode */
  75489. +#define MV_SFLASH_PP_CMND_LENGTH 4 /* 1B opcode + 3B address */
  75490. +#define MV_SFLASH_WREN_CMND_LENGTH 1 /* 1B opcode */
  75491. +#define MV_SFLASH_WRDI_CMND_LENGTH 1 /* 1B opcode */
  75492. +#define MV_SFLASH_RDID_CMND_LENGTH 1 /* 1B opcode */
  75493. +#define MV_SFLASH_RDID_REPLY_LENGTH 3 /* 1B manf ID and 2B device ID */
  75494. +#define MV_SFLASH_RDSR_CMND_LENGTH 1 /* 1B opcode */
  75495. +#define MV_SFLASH_RDSR_REPLY_LENGTH 1 /* 1B status */
  75496. +#define MV_SFLASH_WRSR_CMND_LENGTH 2 /* 1B opcode + 1B status value */
  75497. +#define MV_SFLASH_DP_CMND_LENGTH 1 /* 1B opcode */
  75498. +#define MV_SFLASH_RES_CMND_LENGTH 1 /* 1B opcode */
  75499. +
  75500. +/* Status Register Bit Masks */
  75501. +#define MV_SFLASH_STATUS_REG_WIP_OFFSET 0 /* bit 0; write in progress */
  75502. +#define MV_SFLASH_STATUS_REG_WP_OFFSET 2 /* bit 2-4; write protect option */
  75503. +#define MV_SFLASH_STATUS_REG_SRWD_OFFSET 7 /* bit 7; lock status register write */
  75504. +#define MV_SFLASH_STATUS_REG_WIP_MASK (0x1 << MV_SFLASH_STATUS_REG_WIP_OFFSET)
  75505. +#define MV_SFLASH_STATUS_REG_SRWD_MASK (0x1 << MV_SFLASH_STATUS_REG_SRWD_OFFSET)
  75506. +
  75507. +#define MV_SFLASH_MAX_WAIT_LOOP 1000000
  75508. +#define MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP 0x50000000
  75509. +
  75510. +#define MV_SFLASH_DEFAULT_RDID_OPCD 0x9F /* Default Read ID */
  75511. +#define MV_SFLASH_DEFAULT_WREN_OPCD 0x06 /* Default Write Enable */
  75512. +#define MV_SFLASH_NO_SPECIFIC_OPCD 0x00
  75513. +
  75514. +/********************************/
  75515. +/* ST M25Pxxx Device Specific */
  75516. +/********************************/
  75517. +
  75518. +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
  75519. +#define MV_M25PXXX_ST_MANF_ID 0x20
  75520. +#define MV_M25P32_DEVICE_ID 0x2016
  75521. +#define MV_M25P32_MAX_SPI_FREQ 20000000 /* 20MHz */
  75522. +#define MV_M25P32_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  75523. +#define MV_M25P32_FAST_READ_DUMMY_BYTES 1
  75524. +#define MV_M25P64_DEVICE_ID 0x2017
  75525. +#define MV_M25P64_MAX_SPI_FREQ 20000000 /* 20MHz */
  75526. +#define MV_M25P64_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  75527. +#define MV_M25P64_FAST_READ_DUMMY_BYTES 1
  75528. +#define MV_M25P128_DEVICE_ID 0x2018
  75529. +#define MV_M25P128_MAX_SPI_FREQ 20000000 /* 20MHz */
  75530. +#define MV_M25P128_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  75531. +#define MV_M25P128_FAST_READ_DUMMY_BYTES 1
  75532. +
  75533. +
  75534. +/* Sector Sizes and population per device model*/
  75535. +#define MV_M25P32_SECTOR_SIZE 0x10000 /* 64K */
  75536. +#define MV_M25P64_SECTOR_SIZE 0x10000 /* 64K */
  75537. +#define MV_M25P128_SECTOR_SIZE 0x40000 /* 256K */
  75538. +#define MV_M25P32_SECTOR_NUMBER 64
  75539. +#define MV_M25P64_SECTOR_NUMBER 128
  75540. +#define MV_M25P128_SECTOR_NUMBER 64
  75541. +#define MV_M25P_PAGE_SIZE 0x100 /* 256 byte */
  75542. +
  75543. +#define MV_M25P_WREN_CMND_OPCD 0x06 /* Write Enable */
  75544. +#define MV_M25P_WRDI_CMND_OPCD 0x04 /* Write Disable */
  75545. +#define MV_M25P_RDID_CMND_OPCD 0x9F /* Read ID */
  75546. +#define MV_M25P_RDSR_CMND_OPCD 0x05 /* Read Status Register */
  75547. +#define MV_M25P_WRSR_CMND_OPCD 0x01 /* Write Status Register */
  75548. +#define MV_M25P_READ_CMND_OPCD 0x03 /* Sequential Read */
  75549. +#define MV_M25P_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
  75550. +#define MV_M25P_PP_CMND_OPCD 0x02 /* Page Program */
  75551. +#define MV_M25P_SE_CMND_OPCD 0xD8 /* Sector Erase */
  75552. +#define MV_M25P_BE_CMND_OPCD 0xC7 /* Bulk Erase */
  75553. +#define MV_M25P_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
  75554. +
  75555. +/* Status Register Write Protect Bit Masks - 3bits */
  75556. +#define MV_M25P_STATUS_REG_WP_MASK (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75557. +#define MV_M25P_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75558. +#define MV_M25P_STATUS_BP_1_OF_64 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75559. +#define MV_M25P_STATUS_BP_1_OF_32 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75560. +#define MV_M25P_STATUS_BP_1_OF_16 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75561. +#define MV_M25P_STATUS_BP_1_OF_8 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75562. +#define MV_M25P_STATUS_BP_1_OF_4 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75563. +#define MV_M25P_STATUS_BP_1_OF_2 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75564. +#define MV_M25P_STATUS_BP_ALL (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75565. +
  75566. +/************************************/
  75567. +/* MXIC MX25L6405 Device Specific */
  75568. +/************************************/
  75569. +
  75570. +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
  75571. +#define MV_MXIC_MANF_ID 0xC2
  75572. +#define MV_MX25L6405_DEVICE_ID 0x2017
  75573. +#define MV_MX25L6405_MAX_SPI_FREQ 20000000 /* 20MHz */
  75574. +#define MV_MX25L6405_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  75575. +#define MV_MX25L6405_FAST_READ_DUMMY_BYTES 1
  75576. +#define MV_MXIC_DP_EXIT_DELAY 30 /* 30 ms */
  75577. +
  75578. +/* Sector Sizes and population per device model*/
  75579. +#define MV_MX25L6405_SECTOR_SIZE 0x10000 /* 64K */
  75580. +#define MV_MX25L6405_SECTOR_NUMBER 128
  75581. +#define MV_MXIC_PAGE_SIZE 0x100 /* 256 byte */
  75582. +
  75583. +#define MV_MX25L_WREN_CMND_OPCD 0x06 /* Write Enable */
  75584. +#define MV_MX25L_WRDI_CMND_OPCD 0x04 /* Write Disable */
  75585. +#define MV_MX25L_RDID_CMND_OPCD 0x9F /* Read ID */
  75586. +#define MV_MX25L_RDSR_CMND_OPCD 0x05 /* Read Status Register */
  75587. +#define MV_MX25L_WRSR_CMND_OPCD 0x01 /* Write Status Register */
  75588. +#define MV_MX25L_READ_CMND_OPCD 0x03 /* Sequential Read */
  75589. +#define MV_MX25L_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
  75590. +#define MV_MX25L_PP_CMND_OPCD 0x02 /* Page Program */
  75591. +#define MV_MX25L_SE_CMND_OPCD 0xD8 /* Sector Erase */
  75592. +#define MV_MX25L_BE_CMND_OPCD 0xC7 /* Bulk Erase */
  75593. +#define MV_MX25L_DP_CMND_OPCD 0xB9 /* Deep Power Down */
  75594. +#define MV_MX25L_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
  75595. +
  75596. +/* Status Register Write Protect Bit Masks - 4bits */
  75597. +#define MV_MX25L_STATUS_REG_WP_MASK (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75598. +#define MV_MX25L_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75599. +#define MV_MX25L_STATUS_BP_1_OF_128 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75600. +#define MV_MX25L_STATUS_BP_1_OF_64 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75601. +#define MV_MX25L_STATUS_BP_1_OF_32 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75602. +#define MV_MX25L_STATUS_BP_1_OF_16 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75603. +#define MV_MX25L_STATUS_BP_1_OF_8 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75604. +#define MV_MX25L_STATUS_BP_1_OF_4 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75605. +#define MV_MX25L_STATUS_BP_1_OF_2 (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75606. +#define MV_MX25L_STATUS_BP_ALL (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75607. +
  75608. +/************************************/
  75609. +/* SPANSION S25FL128P Device Specific */
  75610. +/************************************/
  75611. +
  75612. +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
  75613. +#define MV_SPANSION_MANF_ID 0x01
  75614. +#define MV_S25FL128_DEVICE_ID 0x2018
  75615. +#define MV_S25FL128_MAX_SPI_FREQ 33000000 /* 33MHz */
  75616. +#define MV_S25FL128_MAX_FAST_SPI_FREQ 104000000 /* 104MHz */
  75617. +#define MV_S25FL128_FAST_READ_DUMMY_BYTES 1
  75618. +
  75619. +/* Sector Sizes and population per device model*/
  75620. +#define MV_S25FL128_SECTOR_SIZE 0x40000 /* 256K */
  75621. +#define MV_S25FL128_SECTOR_NUMBER 64
  75622. +#define MV_S25FL_PAGE_SIZE 0x100 /* 256 byte */
  75623. +
  75624. +#define MV_S25FL_WREN_CMND_OPCD 0x06 /* Write Enable */
  75625. +#define MV_S25FL_WRDI_CMND_OPCD 0x04 /* Write Disable */
  75626. +#define MV_S25FL_RDID_CMND_OPCD 0x9F /* Read ID */
  75627. +#define MV_S25FL_RDSR_CMND_OPCD 0x05 /* Read Status Register */
  75628. +#define MV_S25FL_WRSR_CMND_OPCD 0x01 /* Write Status Register */
  75629. +#define MV_S25FL_READ_CMND_OPCD 0x03 /* Sequential Read */
  75630. +#define MV_S25FL_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
  75631. +#define MV_S25FL_PP_CMND_OPCD 0x02 /* Page Program */
  75632. +#define MV_S25FL_SE_CMND_OPCD 0xD8 /* Sector Erase */
  75633. +#define MV_S25FL_BE_CMND_OPCD 0xC7 /* Bulk Erase */
  75634. +#define MV_S25FL_DP_CMND_OPCD 0xB9 /* Deep Power Down */
  75635. +#define MV_S25FL_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
  75636. +
  75637. +/* Status Register Write Protect Bit Masks - 4bits */
  75638. +#define MV_S25FL_STATUS_REG_WP_MASK (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75639. +#define MV_S25FL_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75640. +#define MV_S25FL_STATUS_BP_1_OF_128 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75641. +#define MV_S25FL_STATUS_BP_1_OF_64 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75642. +#define MV_S25FL_STATUS_BP_1_OF_32 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75643. +#define MV_S25FL_STATUS_BP_1_OF_16 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75644. +#define MV_S25FL_STATUS_BP_1_OF_8 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75645. +#define MV_S25FL_STATUS_BP_1_OF_4 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75646. +#define MV_S25FL_STATUS_BP_1_OF_2 (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75647. +#define MV_S25FL_STATUS_BP_ALL (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75648. +
  75649. +#endif /* __INCmvSFlashSpecH */
  75650. +
  75651. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c
  75652. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c 1970-01-01 01:00:00.000000000 +0100
  75653. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c 2010-11-09 20:28:12.022495595 +0100
  75654. @@ -0,0 +1,576 @@
  75655. +/*******************************************************************************
  75656. +Copyright (C) Marvell International Ltd. and its affiliates
  75657. +
  75658. +This software file (the "File") is owned and distributed by Marvell
  75659. +International Ltd. and/or its affiliates ("Marvell") under the following
  75660. +alternative licensing terms. Once you have made an election to distribute the
  75661. +File under one of the following license alternatives, please (i) delete this
  75662. +introductory statement regarding license alternatives, (ii) delete the two
  75663. +license alternatives that you have not elected to use and (iii) preserve the
  75664. +Marvell copyright notice above.
  75665. +
  75666. +********************************************************************************
  75667. +Marvell Commercial License Option
  75668. +
  75669. +If you received this File from Marvell and you have entered into a commercial
  75670. +license agreement (a "Commercial License") with Marvell, the File is licensed
  75671. +to you under the terms of the applicable Commercial License.
  75672. +
  75673. +********************************************************************************
  75674. +Marvell GPL License Option
  75675. +
  75676. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75677. +modify this File in accordance with the terms and conditions of the General
  75678. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  75679. +available along with the File in the license.txt file or by writing to the Free
  75680. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  75681. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  75682. +
  75683. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  75684. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  75685. +DISCLAIMED. The GPL License provides additional details about this warranty
  75686. +disclaimer.
  75687. +********************************************************************************
  75688. +Marvell BSD License Option
  75689. +
  75690. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75691. +modify this File under the following licensing terms.
  75692. +Redistribution and use in source and binary forms, with or without modification,
  75693. +are permitted provided that the following conditions are met:
  75694. +
  75695. + * Redistributions of source code must retain the above copyright notice,
  75696. + this list of conditions and the following disclaimer.
  75697. +
  75698. + * Redistributions in binary form must reproduce the above copyright
  75699. + notice, this list of conditions and the following disclaimer in the
  75700. + documentation and/or other materials provided with the distribution.
  75701. +
  75702. + * Neither the name of Marvell nor the names of its contributors may be
  75703. + used to endorse or promote products derived from this software without
  75704. + specific prior written permission.
  75705. +
  75706. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  75707. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  75708. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  75709. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  75710. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  75711. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  75712. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  75713. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  75714. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  75715. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  75716. +
  75717. +*******************************************************************************/
  75718. +
  75719. +#include "spi/mvSpi.h"
  75720. +#include "spi/mvSpiSpec.h"
  75721. +
  75722. +#include "ctrlEnv/mvCtrlEnvLib.h"
  75723. +
  75724. +/* #define MV_DEBUG */
  75725. +#ifdef MV_DEBUG
  75726. +#define DB(x) x
  75727. +#define mvOsPrintf printf
  75728. +#else
  75729. +#define DB(x)
  75730. +#endif
  75731. +
  75732. +
  75733. +/*******************************************************************************
  75734. +* mvSpi16bitDataTxRx - Transmt and receive data
  75735. +*
  75736. +* DESCRIPTION:
  75737. +* Tx data and block waiting for data to be transmitted
  75738. +*
  75739. +********************************************************************************/
  75740. +static MV_STATUS mvSpi16bitDataTxRx (MV_U16 txData, MV_U16 * pRxData)
  75741. +{
  75742. + MV_U32 i;
  75743. + MV_BOOL ready = MV_FALSE;
  75744. +
  75745. + /* First clear the bit in the interrupt cause register */
  75746. + MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);
  75747. +
  75748. + /* Transmit data */
  75749. + MV_REG_WRITE(MV_SPI_DATA_OUT_REG, MV_16BIT_LE(txData));
  75750. +
  75751. + /* wait with timeout for memory ready */
  75752. + for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)
  75753. + {
  75754. + if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))
  75755. + {
  75756. + ready = MV_TRUE;
  75757. + break;
  75758. + }
  75759. +#ifdef MV_SPI_SLEEP_ON_WAIT
  75760. + mvOsSleep(1);
  75761. +#endif /* MV_SPI_SLEEP_ON_WAIT */
  75762. + }
  75763. +
  75764. + if (!ready)
  75765. + return MV_TIMEOUT;
  75766. +
  75767. + /* check that the RX data is needed */
  75768. + if (pRxData)
  75769. + {
  75770. + if ((MV_U32)pRxData & 0x1) /* check if address is not alligned to 16bit */
  75771. + {
  75772. +#if defined(MV_CPU_LE)
  75773. + /* perform the data write to the buffer in two stages with 8bit each */
  75774. + MV_U8 * bptr = (MV_U8*)pRxData;
  75775. + MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
  75776. + *bptr = (data & 0xFF);
  75777. + ++bptr;
  75778. + *bptr = ((data >> 8) & 0xFF);
  75779. +
  75780. +#elif defined(MV_CPU_BE)
  75781. +
  75782. + /* perform the data write to the buffer in two stages with 8bit each */
  75783. + MV_U8 * bptr = (MV_U8 *)pRxData;
  75784. + MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
  75785. + *bptr = ((data >> 8) & 0xFF);
  75786. + ++bptr;
  75787. + *bptr = (data & 0xFF);
  75788. +
  75789. +#else
  75790. + #error "CPU endianess isn't defined!\n"
  75791. +#endif
  75792. +
  75793. + }
  75794. + else
  75795. + *pRxData = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
  75796. + }
  75797. +
  75798. + return MV_OK;
  75799. +}
  75800. +
  75801. +
  75802. +/*******************************************************************************
  75803. +* mvSpi8bitDataTxRx - Transmt and receive data (8bits)
  75804. +*
  75805. +* DESCRIPTION:
  75806. +* Tx data and block waiting for data to be transmitted
  75807. +*
  75808. +********************************************************************************/
  75809. +static MV_STATUS mvSpi8bitDataTxRx (MV_U8 txData, MV_U8 * pRxData)
  75810. +{
  75811. + MV_U32 i;
  75812. + MV_BOOL ready = MV_FALSE;
  75813. +
  75814. + /* First clear the bit in the interrupt cause register */
  75815. + MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);
  75816. +
  75817. + /* Transmit data */
  75818. + MV_REG_WRITE(MV_SPI_DATA_OUT_REG, txData);
  75819. +
  75820. + /* wait with timeout for memory ready */
  75821. + for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)
  75822. + {
  75823. + if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))
  75824. + {
  75825. + ready = MV_TRUE;
  75826. + break;
  75827. + }
  75828. +#ifdef MV_SPI_SLEEP_ON_WAIT
  75829. + mvOsSleep(1);
  75830. +#endif /* MV_SPI_SLEEP_ON_WAIT */
  75831. + }
  75832. +
  75833. + if (!ready)
  75834. + return MV_TIMEOUT;
  75835. +
  75836. + /* check that the RX data is needed */
  75837. + if (pRxData)
  75838. + *pRxData = MV_REG_READ(MV_SPI_DATA_IN_REG);
  75839. +
  75840. + return MV_OK;
  75841. +}
  75842. +
  75843. +/*
  75844. +#####################################################################################
  75845. +#####################################################################################
  75846. +*/
  75847. +
  75848. +/*******************************************************************************
  75849. +* mvSpiInit - Initialize the SPI controller
  75850. +*
  75851. +* DESCRIPTION:
  75852. +* Perform the neccessary initialization in order to be able to send an
  75853. +* receive over the SPI interface.
  75854. +*
  75855. +* INPUT:
  75856. +* serialBaudRate: Baud rate (SPI clock frequency)
  75857. +* use16BitMode: Whether to use 2bytes (MV_TRUE) or 1bytes (MV_FALSE)
  75858. +*
  75859. +* OUTPUT:
  75860. +* None.
  75861. +*
  75862. +* RETURN:
  75863. +* Success or Error code.
  75864. +*
  75865. +*
  75866. +*******************************************************************************/
  75867. +MV_STATUS mvSpiInit (MV_U32 serialBaudRate)
  75868. +{
  75869. + MV_STATUS ret;
  75870. +
  75871. + /* Set the serial clock */
  75872. + if ((ret = mvSpiBaudRateSet(serialBaudRate)) != MV_OK)
  75873. + return ret;
  75874. +
  75875. + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
  75876. + mvMPPConfigToSPI();
  75877. +
  75878. + /* Configure the default SPI mode to be 16bit */
  75879. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  75880. +
  75881. + /* Fix ac timing on SPI in 6183, 6183L and 78x00 only */
  75882. + if ( (mvCtrlModelGet() == MV_6183_DEV_ID) ||
  75883. + (mvCtrlModelGet() == MV_6183L_DEV_ID) ||
  75884. + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
  75885. + (mvCtrlModelGet() == MV_78200_DEV_ID) ||
  75886. + (mvCtrlModelGet() == MV_76100_DEV_ID))
  75887. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, BIT14);
  75888. +
  75889. + /* Verify that the CS is deasserted */
  75890. + mvSpiCsDeassert();
  75891. +
  75892. + return MV_OK;
  75893. +}
  75894. +
  75895. +/*******************************************************************************
  75896. +* mvSpiBaudRateSet - Set the Frequency of the SPI clock
  75897. +*
  75898. +* DESCRIPTION:
  75899. +* Set the Prescale bits to adapt to the requested baud rate (the clock
  75900. +* used for thr SPI).
  75901. +*
  75902. +* INPUT:
  75903. +* serialBaudRate: Baud rate (SPI clock frequency)
  75904. +*
  75905. +* OUTPUT:
  75906. +* None.
  75907. +*
  75908. +* RETURN:
  75909. +* Success or Error code.
  75910. +*
  75911. +*
  75912. +*******************************************************************************/
  75913. +MV_STATUS mvSpiBaudRateSet (MV_U32 serialBaudRate)
  75914. +{
  75915. + MV_U8 i;
  75916. + /* MV_U8 preScale[32] = {1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  75917. + 2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
  75918. + */
  75919. + MV_U8 preScale[14] = { 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
  75920. + MV_U8 bestPrescaleIndx = 100;
  75921. + MV_U32 minBaudOffset = 0xFFFFFFFF;
  75922. + MV_U32 cpuClk = mvBoardTclkGet(); /*mvCpuPclkGet();*/
  75923. + MV_U32 tempReg;
  75924. +
  75925. + /* Find the best prescale configuration - less or equal */
  75926. + for (i=0; i<14; i++)
  75927. + {
  75928. + /* check for higher - irrelevent */
  75929. + if ((cpuClk / preScale[i]) > serialBaudRate)
  75930. + continue;
  75931. +
  75932. + /* check for exact fit */
  75933. + if ((cpuClk / preScale[i]) == serialBaudRate)
  75934. + {
  75935. + bestPrescaleIndx = i;
  75936. + break;
  75937. + }
  75938. +
  75939. + /* check if this is better than the previous one */
  75940. + if ((serialBaudRate - (cpuClk / preScale[i])) < minBaudOffset)
  75941. + {
  75942. + minBaudOffset = (serialBaudRate - (cpuClk / preScale[i]));
  75943. + bestPrescaleIndx = i;
  75944. + }
  75945. + }
  75946. +
  75947. + if (bestPrescaleIndx > 14)
  75948. + {
  75949. + mvOsPrintf("%s ERROR: SPI baud rate prescale error!\n", __FUNCTION__);
  75950. + return MV_OUT_OF_RANGE;
  75951. + }
  75952. +
  75953. + /* configure the Prescale */
  75954. + tempReg = MV_REG_READ(MV_SPI_IF_CONFIG_REG);
  75955. + tempReg = ((tempReg & ~MV_SPI_CLK_PRESCALE_MASK) | (bestPrescaleIndx + 0x12));
  75956. + MV_REG_WRITE(MV_SPI_IF_CONFIG_REG, tempReg);
  75957. +
  75958. + return MV_OK;
  75959. +}
  75960. +
  75961. +/*******************************************************************************
  75962. +* mvSpiCsAssert - Assert the Chip Select pin indicating a new transfer
  75963. +*
  75964. +* DESCRIPTION:
  75965. +* Assert The chip select - used to select an external SPI device
  75966. +*
  75967. +* INPUT:
  75968. +* None.
  75969. +*
  75970. +* OUTPUT:
  75971. +* None.
  75972. +*
  75973. +* RETURN:
  75974. +* Success or Error code.
  75975. +*
  75976. +********************************************************************************/
  75977. +MV_VOID mvSpiCsAssert(MV_VOID)
  75978. +{
  75979. + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
  75980. + mvMPPConfigToSPI();
  75981. + mvOsUDelay(1);
  75982. + MV_REG_BIT_SET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);
  75983. +}
  75984. +
  75985. +/*******************************************************************************
  75986. +* mvSpiCsDeassert - DeAssert the Chip Select pin indicating the end of a
  75987. +* SPI transfer sequence
  75988. +*
  75989. +* DESCRIPTION:
  75990. +* DeAssert the chip select pin
  75991. +*
  75992. +* INPUT:
  75993. +* None.
  75994. +*
  75995. +* OUTPUT:
  75996. +* None.
  75997. +*
  75998. +* RETURN:
  75999. +* Success or Error code.
  76000. +*
  76001. +********************************************************************************/
  76002. +MV_VOID mvSpiCsDeassert(MV_VOID)
  76003. +{
  76004. + MV_REG_BIT_RESET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);
  76005. +
  76006. + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
  76007. + mvMPPConfigToDefault();
  76008. +}
  76009. +
  76010. +/*******************************************************************************
  76011. +* mvSpiRead - Read a buffer over the SPI interface
  76012. +*
  76013. +* DESCRIPTION:
  76014. +* Receive (read) a buffer over the SPI interface in 16bit chunks. If the
  76015. +* buffer size is odd, then the last chunk will be 8bits. Chip select is not
  76016. +* handled at this level.
  76017. +*
  76018. +* INPUT:
  76019. +* pRxBuff: Pointer to the buffer to hold the received data
  76020. +* buffSize: length of the pRxBuff
  76021. +*
  76022. +* OUTPUT:
  76023. +* pRxBuff: Pointer to the buffer with the received data
  76024. +*
  76025. +* RETURN:
  76026. +* Success or Error code.
  76027. +*
  76028. +*
  76029. +*******************************************************************************/
  76030. +MV_STATUS mvSpiRead (MV_U8* pRxBuff, MV_U32 buffSize)
  76031. +{
  76032. + MV_STATUS ret;
  76033. + MV_U32 bytesLeft = buffSize;
  76034. + MV_U16* rxPtr = (MV_U16*)pRxBuff;
  76035. +
  76036. + /* check for null parameters */
  76037. + if (pRxBuff == NULL)
  76038. + {
  76039. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76040. + return MV_BAD_PARAM;
  76041. + }
  76042. +
  76043. + /* Check that the buffer pointer and the buffer size are 16bit aligned */
  76044. + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))
  76045. + {
  76046. + /* Verify that the SPI mode is in 16bit mode */
  76047. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  76048. +
  76049. + /* TX/RX as long we have complete 16bit chunks */
  76050. + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
  76051. + {
  76052. + /* Transmitted and wait for the transfer to be completed */
  76053. + if ((ret = mvSpi16bitDataTxRx(MV_SPI_DUMMY_WRITE_16BITS, rxPtr)) != MV_OK)
  76054. + return ret;
  76055. +
  76056. + /* increment the pointers */
  76057. + rxPtr++;
  76058. + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
  76059. + }
  76060. +
  76061. + }
  76062. + else
  76063. + {
  76064. + /* Verify that the SPI mode is in 8bit mode */
  76065. + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  76066. +
  76067. + /* TX/RX in 8bit chanks */
  76068. + while (bytesLeft > 0)
  76069. + {
  76070. + /* Transmitted and wait for the transfer to be completed */
  76071. + if ((ret = mvSpi8bitDataTxRx(MV_SPI_DUMMY_WRITE_8BITS, pRxBuff)) != MV_OK)
  76072. + return ret;
  76073. + /* increment the pointers */
  76074. + pRxBuff++;
  76075. + bytesLeft--;
  76076. + }
  76077. + }
  76078. +
  76079. + return MV_OK;
  76080. +}
  76081. +
  76082. +/*******************************************************************************
  76083. +* mvSpiWrite - Transmit a buffer over the SPI interface
  76084. +*
  76085. +* DESCRIPTION:
  76086. +* Transmit a buffer over the SPI interface in 16bit chunks. If the
  76087. +* buffer size is odd, then the last chunk will be 8bits. No chip select
  76088. +* action is taken.
  76089. +*
  76090. +* INPUT:
  76091. +* pTxBuff: Pointer to the buffer holding the TX data
  76092. +* buffSize: length of the pTxBuff
  76093. +*
  76094. +* OUTPUT:
  76095. +* None.
  76096. +*
  76097. +* RETURN:
  76098. +* Success or Error code.
  76099. +*
  76100. +*
  76101. +*******************************************************************************/
  76102. +MV_STATUS mvSpiWrite(MV_U8* pTxBuff, MV_U32 buffSize)
  76103. +{
  76104. + MV_STATUS ret;
  76105. + MV_U32 bytesLeft = buffSize;
  76106. + MV_U16* txPtr = (MV_U16*)pTxBuff;
  76107. +
  76108. + /* check for null parameters */
  76109. + if (pTxBuff == NULL)
  76110. + {
  76111. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76112. + return MV_BAD_PARAM;
  76113. + }
  76114. +
  76115. + /* Check that the buffer pointer and the buffer size are 16bit aligned */
  76116. + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0))
  76117. + {
  76118. + /* Verify that the SPI mode is in 16bit mode */
  76119. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  76120. +
  76121. + /* TX/RX as long we have complete 16bit chunks */
  76122. + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
  76123. + {
  76124. + /* Transmitted and wait for the transfer to be completed */
  76125. + if ((ret = mvSpi16bitDataTxRx(*txPtr, NULL)) != MV_OK)
  76126. + return ret;
  76127. +
  76128. + /* increment the pointers */
  76129. + txPtr++;
  76130. + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
  76131. + }
  76132. + }
  76133. + else
  76134. + {
  76135. +
  76136. + /* Verify that the SPI mode is in 8bit mode */
  76137. + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  76138. +
  76139. + /* TX/RX in 8bit chanks */
  76140. + while (bytesLeft > 0)
  76141. + {
  76142. + /* Transmitted and wait for the transfer to be completed */
  76143. + if ((ret = mvSpi8bitDataTxRx(*pTxBuff, NULL)) != MV_OK)
  76144. + return ret;
  76145. +
  76146. + /* increment the pointers */
  76147. + pTxBuff++;
  76148. + bytesLeft--;
  76149. + }
  76150. + }
  76151. +
  76152. + return MV_OK;
  76153. +}
  76154. +
  76155. +
  76156. +/*******************************************************************************
  76157. +* mvSpiReadWrite - Read and Write a buffer simultanuosely
  76158. +*
  76159. +* DESCRIPTION:
  76160. +* Transmit and receive a buffer over the SPI in 16bit chunks. If the
  76161. +* buffer size is odd, then the last chunk will be 8bits. The SPI chip
  76162. +* select is not handled implicitely.
  76163. +*
  76164. +* INPUT:
  76165. +* pRxBuff: Pointer to the buffer to write the RX info in
  76166. +* pTxBuff: Pointer to the buffer holding the TX info
  76167. +* buffSize: length of both the pTxBuff and pRxBuff
  76168. +*
  76169. +* OUTPUT:
  76170. +* pRxBuff: Pointer of the buffer holding the RX data
  76171. +*
  76172. +* RETURN:
  76173. +* Success or Error code.
  76174. +*
  76175. +*
  76176. +*******************************************************************************/
  76177. +MV_STATUS mvSpiReadWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)
  76178. +{
  76179. + MV_STATUS ret;
  76180. + MV_U32 bytesLeft = buffSize;
  76181. + MV_U16* txPtr = (MV_U16*)pTxBuff;
  76182. + MV_U16* rxPtr = (MV_U16*)pRxBuff;
  76183. +
  76184. + /* check for null parameters */
  76185. + if ((pRxBuff == NULL) || (pTxBuff == NULL))
  76186. + {
  76187. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76188. + return MV_BAD_PARAM;
  76189. + }
  76190. +
  76191. + /* Check that the buffer pointer and the buffer size are 16bit aligned */
  76192. + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))
  76193. + {
  76194. + /* Verify that the SPI mode is in 16bit mode */
  76195. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  76196. +
  76197. + /* TX/RX as long we have complete 16bit chunks */
  76198. + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
  76199. + {
  76200. + /* Transmitted and wait for the transfer to be completed */
  76201. + if ((ret = mvSpi16bitDataTxRx(*txPtr, rxPtr)) != MV_OK)
  76202. + return ret;
  76203. +
  76204. + /* increment the pointers */
  76205. + txPtr++;
  76206. + rxPtr++;
  76207. + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
  76208. + }
  76209. + }
  76210. + else
  76211. + {
  76212. + /* Verify that the SPI mode is in 8bit mode */
  76213. + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  76214. +
  76215. + /* TX/RX in 8bit chanks */
  76216. + while (bytesLeft > 0)
  76217. + {
  76218. + /* Transmitted and wait for the transfer to be completed */
  76219. + if ( (ret = mvSpi8bitDataTxRx(*pTxBuff, pRxBuff) ) != MV_OK)
  76220. + return ret;
  76221. + pRxBuff++;
  76222. + pTxBuff++;
  76223. + bytesLeft--;
  76224. + }
  76225. + }
  76226. +
  76227. + return MV_OK;
  76228. +}
  76229. +
  76230. +
  76231. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c
  76232. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c 1970-01-01 01:00:00.000000000 +0100
  76233. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c 2010-11-09 20:28:12.052495353 +0100
  76234. @@ -0,0 +1,249 @@
  76235. +/*******************************************************************************
  76236. +Copyright (C) Marvell International Ltd. and its affiliates
  76237. +
  76238. +This software file (the "File") is owned and distributed by Marvell
  76239. +International Ltd. and/or its affiliates ("Marvell") under the following
  76240. +alternative licensing terms. Once you have made an election to distribute the
  76241. +File under one of the following license alternatives, please (i) delete this
  76242. +introductory statement regarding license alternatives, (ii) delete the two
  76243. +license alternatives that you have not elected to use and (iii) preserve the
  76244. +Marvell copyright notice above.
  76245. +
  76246. +********************************************************************************
  76247. +Marvell Commercial License Option
  76248. +
  76249. +If you received this File from Marvell and you have entered into a commercial
  76250. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76251. +to you under the terms of the applicable Commercial License.
  76252. +
  76253. +********************************************************************************
  76254. +Marvell GPL License Option
  76255. +
  76256. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76257. +modify this File in accordance with the terms and conditions of the General
  76258. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76259. +available along with the File in the license.txt file or by writing to the Free
  76260. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76261. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76262. +
  76263. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76264. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76265. +DISCLAIMED. The GPL License provides additional details about this warranty
  76266. +disclaimer.
  76267. +********************************************************************************
  76268. +Marvell BSD License Option
  76269. +
  76270. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76271. +modify this File under the following licensing terms.
  76272. +Redistribution and use in source and binary forms, with or without modification,
  76273. +are permitted provided that the following conditions are met:
  76274. +
  76275. + * Redistributions of source code must retain the above copyright notice,
  76276. + this list of conditions and the following disclaimer.
  76277. +
  76278. + * Redistributions in binary form must reproduce the above copyright
  76279. + notice, this list of conditions and the following disclaimer in the
  76280. + documentation and/or other materials provided with the distribution.
  76281. +
  76282. + * Neither the name of Marvell nor the names of its contributors may be
  76283. + used to endorse or promote products derived from this software without
  76284. + specific prior written permission.
  76285. +
  76286. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76287. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76288. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76289. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76290. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76291. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76292. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76293. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76294. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76295. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76296. +
  76297. +*******************************************************************************/
  76298. +
  76299. +#include "spi/mvSpi.h"
  76300. +#include "spi/mvSpiSpec.h"
  76301. +
  76302. +/*#define MV_DEBUG*/
  76303. +#ifdef MV_DEBUG
  76304. +#define DB(x) x
  76305. +#else
  76306. +#define DB(x)
  76307. +#endif
  76308. +
  76309. +
  76310. +/*******************************************************************************
  76311. +* mvSpiReadAndWrite - Read and Write a buffer simultanuousely
  76312. +*
  76313. +* DESCRIPTION:
  76314. +* Transmit and receive a buffer over the SPI in 16bit chunks. If the
  76315. +* buffer size is odd, then the last chunk will be 8bits.
  76316. +*
  76317. +* INPUT:
  76318. +* pRxBuff: Pointer to the buffer to write the RX info in
  76319. +* pTxBuff: Pointer to the buffer holding the TX info
  76320. +* buffSize: length of both the pTxBuff and pRxBuff
  76321. +*
  76322. +* OUTPUT:
  76323. +* pRxBuff: Pointer of the buffer holding the RX data
  76324. +*
  76325. +* RETURN:
  76326. +* Success or Error code.
  76327. +*
  76328. +*
  76329. +*******************************************************************************/
  76330. +MV_STATUS mvSpiReadAndWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)
  76331. +{
  76332. + MV_STATUS ret;
  76333. +
  76334. + /* check for null parameters */
  76335. + if ((pRxBuff == NULL) || (pTxBuff == NULL) || (buffSize == 0))
  76336. + {
  76337. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76338. + return MV_BAD_PARAM;
  76339. + }
  76340. +
  76341. + /* First assert the chip select */
  76342. + mvSpiCsAssert();
  76343. +
  76344. + ret = mvSpiReadWrite(pRxBuff, pTxBuff, buffSize);
  76345. +
  76346. + /* Finally deassert the chip select */
  76347. + mvSpiCsDeassert();
  76348. +
  76349. + return ret;
  76350. +}
  76351. +
  76352. +/*******************************************************************************
  76353. +* mvSpiWriteThenWrite - Serialize a command followed by the data over the TX line
  76354. +*
  76355. +* DESCRIPTION:
  76356. +* Assert the chip select line. Transmit the command buffer followed by
  76357. +* the data buffer. Then deassert the CS line.
  76358. +*
  76359. +* INPUT:
  76360. +* pCmndBuff: Pointer to the command buffer to transmit
  76361. +* cmndSize: length of the command size
  76362. +* pTxDataBuff: Pointer to the data buffer to transmit
  76363. +* txDataSize: length of the data buffer
  76364. +*
  76365. +* OUTPUT:
  76366. +* None.
  76367. +*
  76368. +* RETURN:
  76369. +* Success or Error code.
  76370. +*
  76371. +*
  76372. +*******************************************************************************/
  76373. +MV_STATUS mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff,
  76374. + MV_U32 txDataSize)
  76375. +{
  76376. + MV_STATUS ret = MV_OK, tempRet;
  76377. +
  76378. + /* check for null parameters */
  76379. +#ifndef CONFIG_MARVELL
  76380. + if(NULL == pTxDataBuff)
  76381. + {
  76382. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76383. + return MV_BAD_PARAM;
  76384. + }
  76385. +#endif
  76386. +
  76387. + if (pCmndBuff == NULL)
  76388. + {
  76389. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76390. + return MV_BAD_PARAM;
  76391. + }
  76392. +
  76393. + /* First assert the chip select */
  76394. + mvSpiCsAssert();
  76395. +
  76396. + /* first write the command */
  76397. + if ((cmndSize) && (pCmndBuff != NULL))
  76398. + {
  76399. + if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)
  76400. + ret = tempRet;
  76401. + }
  76402. +
  76403. + /* Then write the data buffer */
  76404. +#ifndef CONFIG_MARVELL
  76405. + if (txDataSize)
  76406. +#else
  76407. + if ((txDataSize) && (pTxDataBuff != NULL))
  76408. +#endif
  76409. + {
  76410. + if ((tempRet = mvSpiWrite(pTxDataBuff, txDataSize)) != MV_OK)
  76411. + ret = tempRet;
  76412. + }
  76413. +
  76414. + /* Finally deassert the chip select */
  76415. + mvSpiCsDeassert();
  76416. +
  76417. + return ret;
  76418. +}
  76419. +
  76420. +/*******************************************************************************
  76421. +* mvSpiWriteThenRead - Serialize a command then read a data buffer
  76422. +*
  76423. +* DESCRIPTION:
  76424. +* Assert the chip select line. Transmit the command buffer then read
  76425. +* the data buffer. Then deassert the CS line.
  76426. +*
  76427. +* INPUT:
  76428. +* pCmndBuff: Pointer to the command buffer to transmit
  76429. +* cmndSize: length of the command size
  76430. +* pRxDataBuff: Pointer to the buffer to read the data in
  76431. +* txDataSize: length of the data buffer
  76432. +*
  76433. +* OUTPUT:
  76434. +* pRxDataBuff: Pointer to the buffer holding the data
  76435. +*
  76436. +* RETURN:
  76437. +* Success or Error code.
  76438. +*
  76439. +*
  76440. +*******************************************************************************/
  76441. +MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,
  76442. + MV_U32 rxDataSize,MV_U32 dummyBytesToRead)
  76443. +{
  76444. + MV_STATUS ret = MV_OK, tempRet;
  76445. + MV_U8 dummyByte;
  76446. +
  76447. + /* check for null parameters */
  76448. + if ((pCmndBuff == NULL) && (pRxDataBuff == NULL))
  76449. + {
  76450. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76451. + return MV_BAD_PARAM;
  76452. + }
  76453. +
  76454. + /* First assert the chip select */
  76455. + mvSpiCsAssert();
  76456. +
  76457. + /* first write the command */
  76458. + if ((cmndSize) && (pCmndBuff != NULL))
  76459. + {
  76460. + if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)
  76461. + ret = tempRet;
  76462. + }
  76463. +
  76464. + /* Read dummy bytes before real data. */
  76465. + while(dummyBytesToRead)
  76466. + {
  76467. + mvSpiRead(&dummyByte,1);
  76468. + dummyBytesToRead--;
  76469. + }
  76470. +
  76471. + /* Then write the data buffer */
  76472. + if ((rxDataSize) && (pRxDataBuff != NULL))
  76473. + {
  76474. + if ((tempRet = mvSpiRead(pRxDataBuff, rxDataSize)) != MV_OK)
  76475. + ret = tempRet;
  76476. + }
  76477. +
  76478. + /* Finally deassert the chip select */
  76479. + mvSpiCsDeassert();
  76480. +
  76481. + return ret;
  76482. +}
  76483. +
  76484. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h
  76485. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h 1970-01-01 01:00:00.000000000 +0100
  76486. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h 2010-11-09 20:28:12.082495364 +0100
  76487. @@ -0,0 +1,82 @@
  76488. +/*******************************************************************************
  76489. +Copyright (C) Marvell International Ltd. and its affiliates
  76490. +
  76491. +This software file (the "File") is owned and distributed by Marvell
  76492. +International Ltd. and/or its affiliates ("Marvell") under the following
  76493. +alternative licensing terms. Once you have made an election to distribute the
  76494. +File under one of the following license alternatives, please (i) delete this
  76495. +introductory statement regarding license alternatives, (ii) delete the two
  76496. +license alternatives that you have not elected to use and (iii) preserve the
  76497. +Marvell copyright notice above.
  76498. +
  76499. +********************************************************************************
  76500. +Marvell Commercial License Option
  76501. +
  76502. +If you received this File from Marvell and you have entered into a commercial
  76503. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76504. +to you under the terms of the applicable Commercial License.
  76505. +
  76506. +********************************************************************************
  76507. +Marvell GPL License Option
  76508. +
  76509. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76510. +modify this File in accordance with the terms and conditions of the General
  76511. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76512. +available along with the File in the license.txt file or by writing to the Free
  76513. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76514. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76515. +
  76516. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76517. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76518. +DISCLAIMED. The GPL License provides additional details about this warranty
  76519. +disclaimer.
  76520. +********************************************************************************
  76521. +Marvell BSD License Option
  76522. +
  76523. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76524. +modify this File under the following licensing terms.
  76525. +Redistribution and use in source and binary forms, with or without modification,
  76526. +are permitted provided that the following conditions are met:
  76527. +
  76528. + * Redistributions of source code must retain the above copyright notice,
  76529. + this list of conditions and the following disclaimer.
  76530. +
  76531. + * Redistributions in binary form must reproduce the above copyright
  76532. + notice, this list of conditions and the following disclaimer in the
  76533. + documentation and/or other materials provided with the distribution.
  76534. +
  76535. + * Neither the name of Marvell nor the names of its contributors may be
  76536. + used to endorse or promote products derived from this software without
  76537. + specific prior written permission.
  76538. +
  76539. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76540. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76541. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76542. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76543. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76544. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76545. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76546. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76547. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76548. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76549. +
  76550. +*******************************************************************************/
  76551. +
  76552. +#ifndef __INCmvSpiCmndhH
  76553. +#define __INCmvSpiCmndhH
  76554. +
  76555. +#include "mvTypes.h"
  76556. +
  76557. +/* Function Prototypes */
  76558. +
  76559. +/* Simultanuous Read and write */
  76560. +MV_STATUS mvSpiReadAndWrite (MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);
  76561. +
  76562. +/* write command - write a command and then write data */
  76563. +MV_STATUS mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff, MV_U32 txDataSize);
  76564. +
  76565. +/* read command - write a command and then read data by writing dummy data */
  76566. +MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,
  76567. + MV_U32 rxDataSize,MV_U32 dummyBytesToRead);
  76568. +
  76569. +#endif /* __INCmvSpiCmndhH */
  76570. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h
  76571. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h 1970-01-01 01:00:00.000000000 +0100
  76572. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h 2010-11-09 20:28:12.121243940 +0100
  76573. @@ -0,0 +1,94 @@
  76574. +/*******************************************************************************
  76575. +Copyright (C) Marvell International Ltd. and its affiliates
  76576. +
  76577. +This software file (the "File") is owned and distributed by Marvell
  76578. +International Ltd. and/or its affiliates ("Marvell") under the following
  76579. +alternative licensing terms. Once you have made an election to distribute the
  76580. +File under one of the following license alternatives, please (i) delete this
  76581. +introductory statement regarding license alternatives, (ii) delete the two
  76582. +license alternatives that you have not elected to use and (iii) preserve the
  76583. +Marvell copyright notice above.
  76584. +
  76585. +********************************************************************************
  76586. +Marvell Commercial License Option
  76587. +
  76588. +If you received this File from Marvell and you have entered into a commercial
  76589. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76590. +to you under the terms of the applicable Commercial License.
  76591. +
  76592. +********************************************************************************
  76593. +Marvell GPL License Option
  76594. +
  76595. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76596. +modify this File in accordance with the terms and conditions of the General
  76597. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76598. +available along with the File in the license.txt file or by writing to the Free
  76599. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76600. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76601. +
  76602. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76603. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76604. +DISCLAIMED. The GPL License provides additional details about this warranty
  76605. +disclaimer.
  76606. +********************************************************************************
  76607. +Marvell BSD License Option
  76608. +
  76609. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76610. +modify this File under the following licensing terms.
  76611. +Redistribution and use in source and binary forms, with or without modification,
  76612. +are permitted provided that the following conditions are met:
  76613. +
  76614. + * Redistributions of source code must retain the above copyright notice,
  76615. + this list of conditions and the following disclaimer.
  76616. +
  76617. + * Redistributions in binary form must reproduce the above copyright
  76618. + notice, this list of conditions and the following disclaimer in the
  76619. + documentation and/or other materials provided with the distribution.
  76620. +
  76621. + * Neither the name of Marvell nor the names of its contributors may be
  76622. + used to endorse or promote products derived from this software without
  76623. + specific prior written permission.
  76624. +
  76625. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76626. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76627. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76628. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76629. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76630. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76631. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76632. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76633. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76634. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76635. +
  76636. +*******************************************************************************/
  76637. +
  76638. +#ifndef __INCmvSpihH
  76639. +#define __INCmvSpihH
  76640. +
  76641. +#include "mvCommon.h"
  76642. +#include "mvOs.h"
  76643. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  76644. +
  76645. +/* Function Prototypes */
  76646. +/* Init */
  76647. +MV_STATUS mvSpiInit (MV_U32 serialBaudRate);
  76648. +
  76649. +/* Set the Frequency of the Spi clock */
  76650. +MV_STATUS mvSpiBaudRateSet(MV_U32 serialBaudRate);
  76651. +
  76652. +/* Assert the SPI chip select */
  76653. +MV_VOID mvSpiCsAssert (MV_VOID);
  76654. +
  76655. +/* De-assert the SPI chip select */
  76656. +MV_VOID mvSpiCsDeassert (MV_VOID);
  76657. +
  76658. +/* Simultanuous Read and write */
  76659. +MV_STATUS mvSpiReadWrite (MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);
  76660. +
  76661. +/* serialize a buffer on the TX line - Rx is ignored */
  76662. +MV_STATUS mvSpiWrite (MV_U8* pTxBuff, MV_U32 buffSize);
  76663. +
  76664. +/* read from the RX line by writing dummy values to the TX line */
  76665. +MV_STATUS mvSpiRead (MV_U8* pRxBuff, MV_U32 buffSize);
  76666. +
  76667. +#endif /* __INCmvSpihH */
  76668. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h
  76669. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h 1970-01-01 01:00:00.000000000 +0100
  76670. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h 2010-11-09 20:28:12.162495430 +0100
  76671. @@ -0,0 +1,98 @@
  76672. +/*******************************************************************************
  76673. +Copyright (C) Marvell International Ltd. and its affiliates
  76674. +
  76675. +This software file (the "File") is owned and distributed by Marvell
  76676. +International Ltd. and/or its affiliates ("Marvell") under the following
  76677. +alternative licensing terms. Once you have made an election to distribute the
  76678. +File under one of the following license alternatives, please (i) delete this
  76679. +introductory statement regarding license alternatives, (ii) delete the two
  76680. +license alternatives that you have not elected to use and (iii) preserve the
  76681. +Marvell copyright notice above.
  76682. +
  76683. +********************************************************************************
  76684. +Marvell Commercial License Option
  76685. +
  76686. +If you received this File from Marvell and you have entered into a commercial
  76687. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76688. +to you under the terms of the applicable Commercial License.
  76689. +
  76690. +********************************************************************************
  76691. +Marvell GPL License Option
  76692. +
  76693. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76694. +modify this File in accordance with the terms and conditions of the General
  76695. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76696. +available along with the File in the license.txt file or by writing to the Free
  76697. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76698. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76699. +
  76700. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76701. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76702. +DISCLAIMED. The GPL License provides additional details about this warranty
  76703. +disclaimer.
  76704. +********************************************************************************
  76705. +Marvell BSD License Option
  76706. +
  76707. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76708. +modify this File under the following licensing terms.
  76709. +Redistribution and use in source and binary forms, with or without modification,
  76710. +are permitted provided that the following conditions are met:
  76711. +
  76712. + * Redistributions of source code must retain the above copyright notice,
  76713. + this list of conditions and the following disclaimer.
  76714. +
  76715. + * Redistributions in binary form must reproduce the above copyright
  76716. + notice, this list of conditions and the following disclaimer in the
  76717. + documentation and/or other materials provided with the distribution.
  76718. +
  76719. + * Neither the name of Marvell nor the names of its contributors may be
  76720. + used to endorse or promote products derived from this software without
  76721. + specific prior written permission.
  76722. +
  76723. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76724. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76725. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76726. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76727. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76728. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76729. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76730. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76731. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76732. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76733. +
  76734. +*******************************************************************************/
  76735. +
  76736. +#ifndef __INCmvSpiSpecH
  76737. +#define __INCmvSpiSpecH
  76738. +
  76739. +/* Constants */
  76740. +#define MV_SPI_WAIT_RDY_MAX_LOOP 100000
  76741. +#define MV_SPI_16_BIT_CHUNK_SIZE 2
  76742. +#define MV_SPI_DUMMY_WRITE_16BITS 0xFFFF
  76743. +#define MV_SPI_DUMMY_WRITE_8BITS 0xFF
  76744. +
  76745. +/* Marvell Flash Device Controller Registers */
  76746. +#define MV_SPI_CTRLR_OFST 0x10600
  76747. +#define MV_SPI_IF_CTRL_REG (MV_SPI_CTRLR_OFST + 0x00)
  76748. +#define MV_SPI_IF_CONFIG_REG (MV_SPI_CTRLR_OFST + 0x04)
  76749. +#define MV_SPI_DATA_OUT_REG (MV_SPI_CTRLR_OFST + 0x08)
  76750. +#define MV_SPI_DATA_IN_REG (MV_SPI_CTRLR_OFST + 0x0c)
  76751. +#define MV_SPI_INT_CAUSE_REG (MV_SPI_CTRLR_OFST + 0x10)
  76752. +#define MV_SPI_INT_CAUSE_MASK_REG (MV_SPI_CTRLR_OFST + 0x14)
  76753. +
  76754. +/* Serial Memory Interface Control Register Masks */
  76755. +#define MV_SPI_CS_ENABLE_OFFSET 0 /* bit 0 */
  76756. +#define MV_SPI_MEMORY_READY_OFFSET 1 /* bit 1 */
  76757. +#define MV_SPI_CS_ENABLE_MASK (0x1 << MV_SPI_CS_ENABLE_OFFSET)
  76758. +#define MV_SPI_MEMORY_READY_MASK (0x1 << MV_SPI_MEMORY_READY_OFFSET)
  76759. +
  76760. +/* Serial Memory Interface Configuration Register Masks */
  76761. +#define MV_SPI_CLK_PRESCALE_OFFSET 0 /* bit 0-4 */
  76762. +#define MV_SPI_BYTE_LENGTH_OFFSET 5 /* bit 5 */
  76763. +#define MV_SPI_ADDRESS_BURST_LENGTH_OFFSET 8 /* bit 8-9 */
  76764. +#define MV_SPI_CLK_PRESCALE_MASK (0x1F << MV_SPI_CLK_PRESCALE_OFFSET)
  76765. +#define MV_SPI_BYTE_LENGTH_MASK (0x1 << MV_SPI_BYTE_LENGTH_OFFSET)
  76766. +#define MV_SPI_ADDRESS_BURST_LENGTH_MASK (0x3 << MV_SPI_ADDRESS_BURST_LENGTH_OFFSET)
  76767. +
  76768. +#endif /* __INCmvSpiSpecH */
  76769. +
  76770. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c
  76771. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c 1970-01-01 01:00:00.000000000 +0100
  76772. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c 2010-11-09 20:28:12.192495512 +0100
  76773. @@ -0,0 +1,1023 @@
  76774. +/*******************************************************************************
  76775. +Copyright (C) Marvell International Ltd. and its affiliates
  76776. +
  76777. +This software file (the "File") is owned and distributed by Marvell
  76778. +International Ltd. and/or its affiliates ("Marvell") under the following
  76779. +alternative licensing terms. Once you have made an election to distribute the
  76780. +File under one of the following license alternatives, please (i) delete this
  76781. +introductory statement regarding license alternatives, (ii) delete the two
  76782. +license alternatives that you have not elected to use and (iii) preserve the
  76783. +Marvell copyright notice above.
  76784. +
  76785. +********************************************************************************
  76786. +Marvell Commercial License Option
  76787. +
  76788. +If you received this File from Marvell and you have entered into a commercial
  76789. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76790. +to you under the terms of the applicable Commercial License.
  76791. +
  76792. +********************************************************************************
  76793. +Marvell GPL License Option
  76794. +
  76795. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76796. +modify this File in accordance with the terms and conditions of the General
  76797. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76798. +available along with the File in the license.txt file or by writing to the Free
  76799. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76800. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76801. +
  76802. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76803. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76804. +DISCLAIMED. The GPL License provides additional details about this warranty
  76805. +disclaimer.
  76806. +********************************************************************************
  76807. +Marvell BSD License Option
  76808. +
  76809. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76810. +modify this File under the following licensing terms.
  76811. +Redistribution and use in source and binary forms, with or without modification,
  76812. +are permitted provided that the following conditions are met:
  76813. +
  76814. + * Redistributions of source code must retain the above copyright notice,
  76815. + this list of conditions and the following disclaimer.
  76816. +
  76817. + * Redistributions in binary form must reproduce the above copyright
  76818. + notice, this list of conditions and the following disclaimer in the
  76819. + documentation and/or other materials provided with the distribution.
  76820. +
  76821. + * Neither the name of Marvell nor the names of its contributors may be
  76822. + used to endorse or promote products derived from this software without
  76823. + specific prior written permission.
  76824. +
  76825. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76826. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76827. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76828. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76829. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76830. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76831. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76832. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76833. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76834. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76835. +
  76836. +*******************************************************************************/
  76837. +
  76838. +
  76839. +#include "mvTwsi.h"
  76840. +#include "mvTwsiSpec.h"
  76841. +#include "cpu/mvCpu.h"
  76842. +
  76843. +
  76844. +/*#define MV_DEBUG*/
  76845. +#ifdef MV_DEBUG
  76846. +#define DB(x) x
  76847. +#else
  76848. +#define DB(x)
  76849. +#endif
  76850. +
  76851. +static MV_VOID twsiIntFlgClr(MV_U8 chanNum);
  76852. +static MV_BOOL twsiMainIntGet(MV_U8 chanNum);
  76853. +static MV_VOID twsiAckBitSet(MV_U8 chanNum);
  76854. +static MV_U32 twsiStsGet(MV_U8 chanNum);
  76855. +static MV_VOID twsiReset(MV_U8 chanNum);
  76856. +static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);
  76857. +static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);
  76858. +static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);
  76859. +static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);
  76860. +static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset,MV_BOOL moreThen256);
  76861. +
  76862. +
  76863. +static MV_BOOL twsiTimeoutChk(MV_U32 timeout, const MV_8 *pString)
  76864. +{
  76865. + if(timeout >= TWSI_TIMEOUT_VALUE)
  76866. + {
  76867. + DB(mvOsPrintf("%s",pString));
  76868. + return MV_TRUE;
  76869. + }
  76870. + return MV_FALSE;
  76871. +
  76872. +}
  76873. +/*******************************************************************************
  76874. +* mvTwsiStartBitSet - Set start bit on the bus
  76875. +*
  76876. +* DESCRIPTION:
  76877. +* This routine sets the start bit on the TWSI bus.
  76878. +* The routine first checks for interrupt flag condition, then it sets
  76879. +* the start bit in the TWSI Control register.
  76880. +* If the interrupt flag condition check previously was set, the function
  76881. +* will clear it.
  76882. +* The function then wait for the start bit to be cleared by the HW.
  76883. +* Then it waits for the interrupt flag to be set and eventually, the
  76884. +* TWSI status is checked to be 0x8 or 0x10(repeated start bit).
  76885. +*
  76886. +* INPUT:
  76887. +* chanNum - TWSI channel.
  76888. +*
  76889. +* OUTPUT:
  76890. +* None.
  76891. +*
  76892. +* RETURN:
  76893. +* MV_OK is start bit was set successfuly on the bus.
  76894. +* MV_FAIL if interrupt flag was set before setting start bit.
  76895. +*
  76896. +*******************************************************************************/
  76897. +MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum)
  76898. +{
  76899. + MV_BOOL isIntFlag = MV_FALSE;
  76900. + MV_U32 timeout, temp;
  76901. +
  76902. + DB(mvOsPrintf("TWSI: mvTwsiStartBitSet \n"));
  76903. + /* check Int flag */
  76904. + if(twsiMainIntGet(chanNum))
  76905. + isIntFlag = MV_TRUE;
  76906. + /* set start Bit */
  76907. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  76908. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_START_BIT);
  76909. +
  76910. + /* in case that the int flag was set before i.e. repeated start bit */
  76911. + if(isIntFlag){
  76912. + DB(mvOsPrintf("TWSI: mvTwsiStartBitSet repeated start Bit\n"));
  76913. + twsiIntFlgClr(chanNum);
  76914. + }
  76915. +
  76916. + /* wait for interrupt */
  76917. + timeout = 0;
  76918. + while(!twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  76919. +
  76920. + /* check for timeout */
  76921. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStartBitSet ERROR - Start Clear bit TimeOut .\n"))
  76922. + return MV_TIMEOUT;
  76923. +
  76924. +
  76925. + /* check that start bit went down */
  76926. + if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_START_BIT) != 0)
  76927. + {
  76928. + mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - start bit didn't went down\n");
  76929. + return MV_FAIL;
  76930. + }
  76931. +
  76932. + /* check the status */
  76933. + temp = twsiStsGet(chanNum);
  76934. + if(( temp != TWSI_START_CON_TRA ) && ( temp != TWSI_REPEATED_START_CON_TRA ))
  76935. + {
  76936. + mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - status %x after Set Start Bit. \n",temp);
  76937. + return MV_FAIL;
  76938. + }
  76939. +
  76940. + return MV_OK;
  76941. +
  76942. +}
  76943. +
  76944. +/*******************************************************************************
  76945. +* mvTwsiStopBitSet - Set stop bit on the bus
  76946. +*
  76947. +* DESCRIPTION:
  76948. +* This routine set the stop bit on the TWSI bus.
  76949. +* The function then wait for the stop bit to be cleared by the HW.
  76950. +* Finally the function checks for status of 0xF8.
  76951. +*
  76952. +* INPUT:
  76953. +* chanNum - TWSI channel
  76954. +*
  76955. +* OUTPUT:
  76956. +* None.
  76957. +*
  76958. +* RETURN:
  76959. +* MV_TRUE is stop bit was set successfuly on the bus.
  76960. +*
  76961. +*******************************************************************************/
  76962. +MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum)
  76963. +{
  76964. + MV_U32 timeout, temp;
  76965. +
  76966. + /* Generate stop bit */
  76967. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  76968. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_STOP_BIT);
  76969. +
  76970. + twsiIntFlgClr(chanNum);
  76971. +
  76972. + /* wait for stop bit to come down */
  76973. + timeout = 0;
  76974. + while( ((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0) && (timeout++ < TWSI_TIMEOUT_VALUE));
  76975. +
  76976. + /* check for timeout */
  76977. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStopBitSet ERROR - Stop bit TimeOut .\n"))
  76978. + return MV_TIMEOUT;
  76979. +
  76980. + /* check that the stop bit went down */
  76981. + if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0)
  76982. + {
  76983. + mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - stop bit didn't went down. \n");
  76984. + return MV_FAIL;
  76985. + }
  76986. +
  76987. + /* check the status */
  76988. + temp = twsiStsGet(chanNum);
  76989. + if( temp != TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0){
  76990. + mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - status %x after Stop Bit. \n", temp);
  76991. + return MV_FAIL;
  76992. + }
  76993. +
  76994. + return MV_OK;
  76995. +}
  76996. +
  76997. +/*******************************************************************************
  76998. +* twsiMainIntGet - Get twsi bit from main Interrupt cause.
  76999. +*
  77000. +* DESCRIPTION:
  77001. +* This routine returns the twsi interrupt flag value.
  77002. +*
  77003. +* INPUT:
  77004. +* None.
  77005. +*
  77006. +* OUTPUT:
  77007. +* None.
  77008. +*
  77009. +* RETURN:
  77010. +* MV_TRUE is interrupt flag is set, MV_FALSE otherwise.
  77011. +*
  77012. +*******************************************************************************/
  77013. +static MV_BOOL twsiMainIntGet(MV_U8 chanNum)
  77014. +{
  77015. + MV_U32 temp;
  77016. +
  77017. + /* get the int flag bit */
  77018. +
  77019. + temp = MV_REG_READ(TWSI_CPU_MAIN_INT_CAUSE_REG);
  77020. + if (temp & (TWSI0_CPU_MAIN_INT_BIT << chanNum))
  77021. + return MV_TRUE;
  77022. +
  77023. + return MV_FALSE;
  77024. +}
  77025. +/*******************************************************************************
  77026. +* twsiIntFlgClr - Clear Interrupt flag.
  77027. +*
  77028. +* DESCRIPTION:
  77029. +* This routine clears the interrupt flag. It does NOT poll the interrupt
  77030. +* to make sure the clear. After clearing the interrupt, it waits for at
  77031. +* least 1 miliseconds.
  77032. +*
  77033. +* INPUT:
  77034. +* chanNum - TWSI channel
  77035. +*
  77036. +* OUTPUT:
  77037. +* None.
  77038. +*
  77039. +* RETURN:
  77040. +* None.
  77041. +*
  77042. +*******************************************************************************/
  77043. +static MV_VOID twsiIntFlgClr(MV_U8 chanNum)
  77044. +{
  77045. + MV_U32 temp;
  77046. +
  77047. + /* wait for 1 mili to prevent TWSI register write after write problems */
  77048. + mvOsDelay(1);
  77049. + /* clear the int flag bit */
  77050. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  77051. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum),temp & ~(TWSI_CONTROL_INT_FLAG_SET));
  77052. +
  77053. + /* wait for 1 mili sec for the clear to take effect */
  77054. + mvOsDelay(1);
  77055. +
  77056. + return;
  77057. +}
  77058. +
  77059. +
  77060. +/*******************************************************************************
  77061. +* twsiAckBitSet - Set acknowledge bit on the bus
  77062. +*
  77063. +* DESCRIPTION:
  77064. +* This routine set the acknowledge bit on the TWSI bus.
  77065. +*
  77066. +* INPUT:
  77067. +* None.
  77068. +*
  77069. +* OUTPUT:
  77070. +* None.
  77071. +*
  77072. +* RETURN:
  77073. +* None.
  77074. +*
  77075. +*******************************************************************************/
  77076. +static MV_VOID twsiAckBitSet(MV_U8 chanNum)
  77077. +{
  77078. + MV_U32 temp;
  77079. +
  77080. + /*Set the Ack bit */
  77081. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  77082. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_ACK);
  77083. +
  77084. + /* Add delay of 1ms */
  77085. + mvOsDelay(1);
  77086. + return;
  77087. +}
  77088. +
  77089. +
  77090. +/*******************************************************************************
  77091. +* twsiInit - Initialize TWSI interface
  77092. +*
  77093. +* DESCRIPTION:
  77094. +* This routine:
  77095. +* -Reset the TWSI.
  77096. +* -Initialize the TWSI clock baud rate according to given frequancy
  77097. +* parameter based on Tclk frequancy and enables TWSI slave.
  77098. +* -Set the ack bit.
  77099. +* -Assign the TWSI slave address according to the TWSI address Type.
  77100. +*
  77101. +*
  77102. +* INPUT:
  77103. +* chanNum - TWSI channel
  77104. +* frequancy - TWSI frequancy in KHz. (up to 100KHZ)
  77105. +*
  77106. +* OUTPUT:
  77107. +* None.
  77108. +*
  77109. +* RETURN:
  77110. +* Actual frequancy.
  77111. +*
  77112. +*******************************************************************************/
  77113. +MV_U32 mvTwsiInit(MV_U8 chanNum, MV_HZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *pTwsiAddr, MV_BOOL generalCallEnable)
  77114. +{
  77115. + MV_U32 n,m,freq,margin,minMargin = 0xffffffff;
  77116. + MV_U32 power;
  77117. + MV_U32 actualFreq = 0,actualN = 0,actualM = 0,val;
  77118. +
  77119. + if(frequancy > 100000)
  77120. + {
  77121. + mvOsPrintf("Warning TWSI frequancy is too high, please use up tp 100Khz. \n");
  77122. + }
  77123. +
  77124. + DB(mvOsPrintf("TWSI: mvTwsiInit - Tclk = %d freq = %d\n",Tclk,frequancy));
  77125. + /* Calucalte N and M for the TWSI clock baud rate */
  77126. + for(n = 0 ; n < 8 ; n++)
  77127. + {
  77128. + for(m = 0 ; m < 16 ; m++)
  77129. + {
  77130. + power = 2 << n; /* power = 2^(n+1) */
  77131. + freq = Tclk/(10*(m+1)*power);
  77132. + margin = MV_ABS(frequancy - freq);
  77133. + if(margin < minMargin)
  77134. + {
  77135. + minMargin = margin;
  77136. + actualFreq = freq;
  77137. + actualN = n;
  77138. + actualM = m;
  77139. + }
  77140. + }
  77141. + }
  77142. + DB(mvOsPrintf("TWSI: mvTwsiInit - actN %d actM %d actFreq %d\n",actualN , actualM, actualFreq));
  77143. + /* Reset the TWSI logic */
  77144. + twsiReset(chanNum);
  77145. +
  77146. + /* Set the baud rate */
  77147. + val = ((actualM<< TWSI_BAUD_RATE_M_OFFS) | actualN << TWSI_BAUD_RATE_N_OFFS);
  77148. + MV_REG_WRITE(TWSI_STATUS_BAUDE_RATE_REG(chanNum),val);
  77149. +
  77150. + /* Enable the TWSI and slave */
  77151. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), TWSI_CONTROL_ENA | TWSI_CONTROL_ACK);
  77152. +
  77153. + /* set the TWSI slave address */
  77154. + if( pTwsiAddr->type == ADDR10_BIT )/* 10 Bit deviceAddress */
  77155. + {
  77156. + /* writing the 2 most significant bits of the 10 bit address*/
  77157. + val = ((pTwsiAddr->address & TWSI_SLAVE_ADDR_10BIT_MASK) >> TWSI_SLAVE_ADDR_10BIT_OFFS );
  77158. + /* bits 7:3 must be 0x11110 */
  77159. + val |= TWSI_SLAVE_ADDR_10BIT_CONST;
  77160. + /* set GCE bit */
  77161. + if(generalCallEnable)
  77162. + val |= TWSI_SLAVE_ADDR_GCE_ENA;
  77163. + /* write slave address */
  77164. + MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum),val);
  77165. +
  77166. + /* writing the 8 least significant bits of the 10 bit address*/
  77167. + val = (pTwsiAddr->address << TWSI_EXTENDED_SLAVE_OFFS) & TWSI_EXTENDED_SLAVE_MASK;
  77168. + MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum), val);
  77169. + }
  77170. + else /*7 bit address*/
  77171. + {
  77172. + /* set the 7 Bits address */
  77173. + MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum),0x0);
  77174. + val = (pTwsiAddr->address << TWSI_SLAVE_ADDR_7BIT_OFFS) & TWSI_SLAVE_ADDR_7BIT_MASK;
  77175. + MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum), val);
  77176. + }
  77177. +
  77178. + /* unmask twsi int */
  77179. + val = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  77180. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), val | TWSI_CONTROL_INT_ENA);
  77181. + /* Add delay of 1ms */
  77182. + mvOsDelay(1);
  77183. +
  77184. + return actualFreq;
  77185. +}
  77186. +
  77187. +
  77188. +/*******************************************************************************
  77189. +* twsiStsGet - Get the TWSI status value.
  77190. +*
  77191. +* DESCRIPTION:
  77192. +* This routine returns the TWSI status value.
  77193. +*
  77194. +* INPUT:
  77195. +* chanNum - TWSI channel
  77196. +*
  77197. +* OUTPUT:
  77198. +* None.
  77199. +*
  77200. +* RETURN:
  77201. +* MV_U32 - the TWSI status.
  77202. +*
  77203. +*******************************************************************************/
  77204. +static MV_U32 twsiStsGet(MV_U8 chanNum)
  77205. +{
  77206. + return MV_REG_READ(TWSI_STATUS_BAUDE_RATE_REG(chanNum));
  77207. +
  77208. +}
  77209. +
  77210. +/*******************************************************************************
  77211. +* twsiReset - Reset the TWSI.
  77212. +*
  77213. +* DESCRIPTION:
  77214. +* Resets the TWSI logic and sets all TWSI registers to their reset values.
  77215. +*
  77216. +* INPUT:
  77217. +* chanNum - TWSI channel
  77218. +*
  77219. +* OUTPUT:
  77220. +* None.
  77221. +*
  77222. +* RETURN:
  77223. +* None
  77224. +*
  77225. +*******************************************************************************/
  77226. +static MV_VOID twsiReset(MV_U8 chanNum)
  77227. +{
  77228. + /* Reset the TWSI logic */
  77229. + MV_REG_WRITE(TWSI_SOFT_RESET_REG(chanNum),0);
  77230. +
  77231. + /* wait for 2 mili sec */
  77232. + mvOsDelay(2);
  77233. +
  77234. + return;
  77235. +}
  77236. +
  77237. +
  77238. +
  77239. +
  77240. +/******************************* POLICY ****************************************/
  77241. +
  77242. +
  77243. +
  77244. +/*******************************************************************************
  77245. +* mvTwsiAddrSet - Set address on TWSI bus.
  77246. +*
  77247. +* DESCRIPTION:
  77248. +* This function Set address (7 or 10 Bit address) on the Twsi Bus.
  77249. +*
  77250. +* INPUT:
  77251. +* chanNum - TWSI channel
  77252. +* pTwsiAddr - twsi address.
  77253. +* command - read / write .
  77254. +*
  77255. +* OUTPUT:
  77256. +* None.
  77257. +*
  77258. +* RETURN:
  77259. +* MV_OK - if setting the address completed succesfully.
  77260. +* MV_FAIL otherwmise.
  77261. +*
  77262. +*******************************************************************************/
  77263. +MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *pTwsiAddr, MV_TWSI_CMD command)
  77264. +{
  77265. + DB(mvOsPrintf("TWSI: mvTwsiAddr7BitSet addr %x , type %d, cmd is %s\n",pTwsiAddr->address,\
  77266. + pTwsiAddr->type, ((command==MV_TWSI_WRITE)?"Write":"Read") ));
  77267. + /* 10 Bit address */
  77268. + if(pTwsiAddr->type == ADDR10_BIT)
  77269. + {
  77270. + return twsiAddr10BitSet(chanNum, pTwsiAddr->address,command);
  77271. + }
  77272. + /* 7 Bit address */
  77273. + else
  77274. + {
  77275. + return twsiAddr7BitSet(chanNum, pTwsiAddr->address,command);
  77276. + }
  77277. +
  77278. +}
  77279. +
  77280. +/*******************************************************************************
  77281. +* twsiAddr10BitSet - Set 10 Bit address on TWSI bus.
  77282. +*
  77283. +* DESCRIPTION:
  77284. +* There are two address phases:
  77285. +* 1) Write '11110' to data register bits [7:3] and 10-bit address MSB
  77286. +* (bits [9:8]) to data register bits [2:1] plus a write(0) or read(1) bit
  77287. +* to the Data register. Then it clears interrupt flag which drive
  77288. +* the address on the TWSI bus. The function then waits for interrupt
  77289. +* flag to be active and status 0x18 (write) or 0x40 (read) to be set.
  77290. +* 2) write the rest of 10-bit address to data register and clears
  77291. +* interrupt flag which drive the address on the TWSI bus. The
  77292. +* function then waits for interrupt flag to be active and status
  77293. +* 0xD0 (write) or 0xE0 (read) to be set.
  77294. +*
  77295. +* INPUT:
  77296. +* chanNum - TWSI channel
  77297. +* deviceAddress - twsi address.
  77298. +* command - read / write .
  77299. +*
  77300. +* OUTPUT:
  77301. +* None.
  77302. +*
  77303. +* RETURN:
  77304. +* MV_OK - if setting the address completed succesfully.
  77305. +* MV_FAIL otherwmise.
  77306. +*
  77307. +*******************************************************************************/
  77308. +static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)
  77309. +{
  77310. + MV_U32 val,timeout;
  77311. +
  77312. + /* writing the 2 most significant bits of the 10 bit address*/
  77313. + val = ((deviceAddress & TWSI_DATA_ADDR_10BIT_MASK) >> TWSI_DATA_ADDR_10BIT_OFFS );
  77314. + /* bits 7:3 must be 0x11110 */
  77315. + val |= TWSI_DATA_ADDR_10BIT_CONST;
  77316. + /* set command */
  77317. + val |= command;
  77318. + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
  77319. + /* WA add a delay */
  77320. + mvOsDelay(1);
  77321. +
  77322. + /* clear Int flag */
  77323. + twsiIntFlgClr(chanNum);
  77324. +
  77325. + /* wait for Int to be Set */
  77326. + timeout = 0;
  77327. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77328. +
  77329. + /* check for timeout */
  77330. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 1st addr (10Bit) Int TimeOut.\n"))
  77331. + return MV_TIMEOUT;
  77332. +
  77333. + /* check the status */
  77334. + val = twsiStsGet(chanNum);
  77335. + if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
  77336. + ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
  77337. + {
  77338. + mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 1st addr (10 Bit) in %s mode.\n"\
  77339. + ,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );
  77340. + return MV_FAIL;
  77341. + }
  77342. +
  77343. + /* set 8 LSB of the address */
  77344. + val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;
  77345. + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
  77346. +
  77347. + /* clear Int flag */
  77348. + twsiIntFlgClr(chanNum);
  77349. +
  77350. + /* wait for Int to be Set */
  77351. + timeout = 0;
  77352. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77353. +
  77354. + /* check for timeout */
  77355. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 2nd (10 Bit) Int TimOut.\n"))
  77356. + return MV_TIMEOUT;
  77357. +
  77358. + /* check the status */
  77359. + val = twsiStsGet(chanNum);
  77360. + if(( (val != TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
  77361. + ( (val != TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
  77362. + {
  77363. + mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 2nd addr(10 Bit) in %s mode.\n"\
  77364. + ,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );
  77365. + return MV_FAIL;
  77366. + }
  77367. +
  77368. + return MV_OK;
  77369. +}
  77370. +
  77371. +/*******************************************************************************
  77372. +* twsiAddr7BitSet - Set 7 Bit address on TWSI bus.
  77373. +*
  77374. +* DESCRIPTION:
  77375. +* This function writes 7 bit address plus a write or read bit to the
  77376. +* Data register. Then it clears interrupt flag which drive the address on
  77377. +* the TWSI bus. The function then waits for interrupt flag to be active
  77378. +* and status 0x18 (write) or 0x40 (read) to be set.
  77379. +*
  77380. +* INPUT:
  77381. +* chanNum - TWSI channel
  77382. +* deviceAddress - twsi address.
  77383. +* command - read / write .
  77384. +*
  77385. +* OUTPUT:
  77386. +* None.
  77387. +*
  77388. +* RETURN:
  77389. +* MV_OK - if setting the address completed succesfully.
  77390. +* MV_FAIL otherwmise.
  77391. +*
  77392. +*******************************************************************************/
  77393. +static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)
  77394. +{
  77395. + MV_U32 val,timeout;
  77396. +
  77397. + /* set the address */
  77398. + val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;
  77399. + /* set command */
  77400. + val |= command;
  77401. + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
  77402. + /* WA add a delay */
  77403. + mvOsDelay(1);
  77404. +
  77405. + /* clear Int flag */
  77406. + twsiIntFlgClr(chanNum);
  77407. +
  77408. + /* wait for Int to be Set */
  77409. + timeout = 0;
  77410. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77411. +
  77412. + /* check for timeout */
  77413. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr7BitSet ERROR - Addr (7 Bit) int TimeOut.\n"))
  77414. + return MV_TIMEOUT;
  77415. +
  77416. + /* check the status */
  77417. + val = twsiStsGet(chanNum);
  77418. + if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
  77419. + ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
  77420. + {
  77421. + /* only in debug, since in boot we try to read the SPD of both DRAM, and we don't
  77422. + want error messeges in case DIMM doesn't exist. */
  77423. + DB(mvOsPrintf("TWSI: twsiAddr7BitSet ERROR - status %x addr (7 Bit) in %s mode.\n"\
  77424. + ,val,((command==MV_TWSI_WRITE)?"Write":"Read") ));
  77425. + return MV_FAIL;
  77426. + }
  77427. +
  77428. + return MV_OK;
  77429. +}
  77430. +
  77431. +/*******************************************************************************
  77432. +* twsiDataWrite - Trnasmit a data block over TWSI bus.
  77433. +*
  77434. +* DESCRIPTION:
  77435. +* This function writes a given data block to TWSI bus in 8 bit granularity.
  77436. +* first The function waits for interrupt flag to be active then
  77437. +* For each 8-bit data:
  77438. +* The function writes data to data register. It then clears
  77439. +* interrupt flag which drives the data on the TWSI bus.
  77440. +* The function then waits for interrupt flag to be active and status
  77441. +* 0x28 to be set.
  77442. +*
  77443. +*
  77444. +* INPUT:
  77445. +* chanNum - TWSI channel
  77446. +* pBlock - Data block.
  77447. +* blockSize - number of chars in pBlock.
  77448. +*
  77449. +* OUTPUT:
  77450. +* None.
  77451. +*
  77452. +* RETURN:
  77453. +* MV_OK - if transmiting the block completed succesfully,
  77454. +* MV_BAD_PARAM - if pBlock is NULL,
  77455. +* MV_FAIL otherwmise.
  77456. +*
  77457. +*******************************************************************************/
  77458. +static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)
  77459. +{
  77460. + MV_U32 timeout, temp, blockSizeWr = blockSize;
  77461. +
  77462. + if(NULL == pBlock)
  77463. + return MV_BAD_PARAM;
  77464. +
  77465. + /* wait for Int to be Set */
  77466. + timeout = 0;
  77467. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77468. +
  77469. + /* check for timeout */
  77470. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))
  77471. + return MV_TIMEOUT;
  77472. +
  77473. + while(blockSizeWr)
  77474. + {
  77475. + /* write the data*/
  77476. + MV_REG_WRITE(TWSI_DATA_REG(chanNum),(MV_U32)*pBlock);
  77477. + DB(mvOsPrintf("TWSI: twsiDataTransmit place = %d write %x \n",\
  77478. + blockSize - blockSizeWr, *pBlock));
  77479. + pBlock++;
  77480. + blockSizeWr--;
  77481. +
  77482. + twsiIntFlgClr(chanNum);
  77483. +
  77484. + /* wait for Int to be Set */
  77485. + timeout = 0;
  77486. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77487. +
  77488. + /* check for timeout */
  77489. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))
  77490. + return MV_TIMEOUT;
  77491. +
  77492. + /* check the status */
  77493. + temp = twsiStsGet(chanNum);
  77494. + if(temp != TWSI_M_TRAN_DATA_BYTE_ACK_REC)
  77495. + {
  77496. + mvOsPrintf("TWSI: twsiDataTransmit ERROR - status %x in write trans\n",temp);
  77497. + return MV_FAIL;
  77498. + }
  77499. +
  77500. + }
  77501. +
  77502. + return MV_OK;
  77503. +}
  77504. +
  77505. +/*******************************************************************************
  77506. +* twsiDataReceive - Receive data block from TWSI bus.
  77507. +*
  77508. +* DESCRIPTION:
  77509. +* This function receive data block from TWSI bus in 8bit granularity
  77510. +* into pBlock buffer.
  77511. +* first The function waits for interrupt flag to be active then
  77512. +* For each 8-bit data:
  77513. +* It clears the interrupt flag which allows the next data to be
  77514. +* received from TWSI bus.
  77515. +* The function waits for interrupt flag to be active,
  77516. +* and status reg is 0x50.
  77517. +* Then the function reads data from data register, and copies it to
  77518. +* the given buffer.
  77519. +*
  77520. +* INPUT:
  77521. +* chanNum - TWSI channel
  77522. +* blockSize - number of bytes to read.
  77523. +*
  77524. +* OUTPUT:
  77525. +* pBlock - Data block.
  77526. +*
  77527. +* RETURN:
  77528. +* MV_OK - if receive transaction completed succesfully,
  77529. +* MV_BAD_PARAM - if pBlock is NULL,
  77530. +* MV_FAIL otherwmise.
  77531. +*
  77532. +*******************************************************************************/
  77533. +static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)
  77534. +{
  77535. + MV_U32 timeout, temp, blockSizeRd = blockSize;
  77536. + if(NULL == pBlock)
  77537. + return MV_BAD_PARAM;
  77538. +
  77539. + /* wait for Int to be Set */
  77540. + timeout = 0;
  77541. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77542. +
  77543. + /* check for timeout */
  77544. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data int Time out .\n"))
  77545. + return MV_TIMEOUT;
  77546. +
  77547. + while(blockSizeRd)
  77548. + {
  77549. + if(blockSizeRd == 1)
  77550. + {
  77551. + /* clear ack and Int flag */
  77552. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  77553. + temp &= ~(TWSI_CONTROL_ACK);
  77554. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp);
  77555. + }
  77556. + twsiIntFlgClr(chanNum);
  77557. + /* wait for Int to be Set */
  77558. + timeout = 0;
  77559. + while( (!twsiMainIntGet(chanNum)) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77560. +
  77561. + /* check for timeout */
  77562. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data Int Time out .\n"))
  77563. + return MV_TIMEOUT;
  77564. +
  77565. + /* check the status */
  77566. + temp = twsiStsGet(chanNum);
  77567. + if((temp != TWSI_M_REC_RD_DATA_ACK_TRA) && (blockSizeRd !=1))
  77568. + {
  77569. + mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in read trans \n",temp);
  77570. + return MV_FAIL;
  77571. + }
  77572. + else if((temp != TWSI_M_REC_RD_DATA_ACK_NOT_TRA) && (blockSizeRd ==1))
  77573. + {
  77574. + mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in Rd Terminate\n",temp);
  77575. + return MV_FAIL;
  77576. + }
  77577. +
  77578. + /* read the data*/
  77579. + *pBlock = (MV_U8)MV_REG_READ(TWSI_DATA_REG(chanNum));
  77580. + DB(mvOsPrintf("TWSI: twsiDataReceive place %d read %x \n",\
  77581. + blockSize - blockSizeRd,*pBlock));
  77582. + pBlock++;
  77583. + blockSizeRd--;
  77584. + }
  77585. +
  77586. + return MV_OK;
  77587. +}
  77588. +
  77589. +
  77590. +
  77591. +/*******************************************************************************
  77592. +* twsiTargetOffsSet - Set TWST target offset on TWSI bus.
  77593. +*
  77594. +* DESCRIPTION:
  77595. +* The function support TWSI targets that have inside address space (for
  77596. +* example EEPROMs). The function:
  77597. +* 1) Convert the given offset into pBlock and size.
  77598. +* in case the offset should be set to a TWSI slave which support
  77599. +* more then 256 bytes offset, the offset setting will be done
  77600. +* in 2 transactions.
  77601. +* 2) Use twsiDataTransmit to place those on the bus.
  77602. +*
  77603. +* INPUT:
  77604. +* chanNum - TWSI channel
  77605. +* offset - offset to be set on the EEPROM device.
  77606. +* moreThen256 - whether the EEPROM device support more then 256 byte offset.
  77607. +*
  77608. +* OUTPUT:
  77609. +* None.
  77610. +*
  77611. +* RETURN:
  77612. +* MV_OK - if setting the offset completed succesfully.
  77613. +* MV_FAIL otherwmise.
  77614. +*
  77615. +*******************************************************************************/
  77616. +static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset, MV_BOOL moreThen256)
  77617. +{
  77618. + MV_U8 offBlock[2];
  77619. + MV_U32 offSize;
  77620. +
  77621. + if(moreThen256 == MV_TRUE)
  77622. + {
  77623. + offBlock[0] = (offset >> 8) & 0xff;
  77624. + offBlock[1] = offset & 0xff;
  77625. + offSize = 2;
  77626. + }
  77627. + else
  77628. + {
  77629. + offBlock[0] = offset & 0xff;
  77630. + offSize = 1;
  77631. + }
  77632. + DB(mvOsPrintf("TWSI: twsiTargetOffsSet offSize = %x addr1 = %x addr2 = %x\n",\
  77633. + offSize,offBlock[0],offBlock[1]));
  77634. + return twsiDataTransmit(chanNum, offBlock, offSize);
  77635. +
  77636. +}
  77637. +
  77638. +/*******************************************************************************
  77639. +* mvTwsiRead - Read data block from a TWSI Slave.
  77640. +*
  77641. +* DESCRIPTION:
  77642. +* The function calls the following functions:
  77643. +* -) mvTwsiStartBitSet();
  77644. +* if(EEPROM device)
  77645. +* -) mvTwsiAddrSet(w);
  77646. +* -) twsiTargetOffsSet();
  77647. +* -) mvTwsiStartBitSet();
  77648. +* -) mvTwsiAddrSet(r);
  77649. +* -) twsiDataReceive();
  77650. +* -) mvTwsiStopBitSet();
  77651. +*
  77652. +* INPUT:
  77653. +* chanNum - TWSI channel
  77654. +* pTwsiSlave - Twsi Slave structure.
  77655. +* blockSize - number of bytes to read.
  77656. +*
  77657. +* OUTPUT:
  77658. +* pBlock - Data block.
  77659. +*
  77660. +* RETURN:
  77661. +* MV_OK - if EEPROM read transaction completed succesfully,
  77662. +* MV_BAD_PARAM - if pBlock is NULL,
  77663. +* MV_FAIL otherwmise.
  77664. +*
  77665. +*******************************************************************************/
  77666. +MV_STATUS mvTwsiRead(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)
  77667. +{
  77668. + if((NULL == pBlock) || (NULL == pTwsiSlave))
  77669. + return MV_BAD_PARAM;
  77670. + if(MV_OK != mvTwsiStartBitSet(chanNum))
  77671. + {
  77672. + mvTwsiStopBitSet(chanNum);
  77673. + return MV_FAIL;
  77674. + }
  77675. +
  77676. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));
  77677. +
  77678. + /* in case offset exsist (i.e. eeprom ) */
  77679. + if(MV_TRUE == pTwsiSlave->validOffset)
  77680. + {
  77681. + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE))
  77682. + {
  77683. + mvTwsiStopBitSet(chanNum);
  77684. + return MV_FAIL;
  77685. + }
  77686. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));
  77687. + if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256))
  77688. + {
  77689. + mvTwsiStopBitSet(chanNum);
  77690. + return MV_FAIL;
  77691. + }
  77692. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiTargetOffsSet\n"));
  77693. + if(MV_OK != mvTwsiStartBitSet(chanNum))
  77694. + {
  77695. + mvTwsiStopBitSet(chanNum);
  77696. + return MV_FAIL;
  77697. + }
  77698. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));
  77699. + }
  77700. + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_READ))
  77701. + {
  77702. + mvTwsiStopBitSet(chanNum);
  77703. + return MV_FAIL;
  77704. + }
  77705. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));
  77706. + if(MV_OK != twsiDataReceive(chanNum, pBlock, blockSize))
  77707. + {
  77708. + mvTwsiStopBitSet(chanNum);
  77709. + return MV_FAIL;
  77710. + }
  77711. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiDataReceive\n"));
  77712. +
  77713. + if(MV_OK != mvTwsiStopBitSet(chanNum))
  77714. + {
  77715. + return MV_FAIL;
  77716. + }
  77717. +
  77718. + twsiAckBitSet(chanNum);
  77719. +
  77720. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStopBitSet\n"));
  77721. +
  77722. + return MV_OK;
  77723. +}
  77724. +
  77725. +/*******************************************************************************
  77726. +* mvTwsiWrite - Write data block to a TWSI Slave.
  77727. +*
  77728. +* DESCRIPTION:
  77729. +* The function calls the following functions:
  77730. +* -) mvTwsiStartBitSet();
  77731. +* -) mvTwsiAddrSet();
  77732. +* -)if(EEPROM device)
  77733. +* -) twsiTargetOffsSet();
  77734. +* -) twsiDataTransmit();
  77735. +* -) mvTwsiStopBitSet();
  77736. +*
  77737. +* INPUT:
  77738. +* chanNum - TWSI channel
  77739. +* eepromAddress - eeprom address.
  77740. +* blockSize - number of bytes to write.
  77741. +* pBlock - Data block.
  77742. +*
  77743. +* OUTPUT:
  77744. +* None
  77745. +*
  77746. +* RETURN:
  77747. +* MV_OK - if EEPROM read transaction completed succesfully.
  77748. +* MV_BAD_PARAM - if pBlock is NULL,
  77749. +* MV_FAIL otherwmise.
  77750. +*
  77751. +* NOTE: Part of the EEPROM, required that the offset will be aligned to the
  77752. +* max write burst supported.
  77753. +*******************************************************************************/
  77754. +MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)
  77755. +{
  77756. + if((NULL == pBlock) || (NULL == pTwsiSlave))
  77757. + return MV_BAD_PARAM;
  77758. +
  77759. + if(MV_OK != mvTwsiStartBitSet(chanNum))
  77760. + {
  77761. + mvTwsiStopBitSet(chanNum);
  77762. + return MV_FAIL;
  77763. + }
  77764. +
  77765. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStartBitSet\n"));
  77766. + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE))
  77767. + {
  77768. + mvTwsiStopBitSet(chanNum);
  77769. + return MV_FAIL;
  77770. + }
  77771. + DB(mvOsPrintf("TWSI :mvTwsiEepromWrite after mvTwsiAddrSet\n"));
  77772. +
  77773. + /* in case offset exsist (i.e. eeprom ) */
  77774. + if(MV_TRUE == pTwsiSlave->validOffset)
  77775. + {
  77776. + if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256))
  77777. + {
  77778. + mvTwsiStopBitSet(chanNum);
  77779. + return MV_FAIL;
  77780. + }
  77781. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiTargetOffsSet\n"));
  77782. + }
  77783. + if(MV_OK != twsiDataTransmit(chanNum, pBlock, blockSize))
  77784. + {
  77785. + mvTwsiStopBitSet(chanNum);
  77786. + return MV_FAIL;
  77787. + }
  77788. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiDataTransmit\n"));
  77789. + if(MV_OK != mvTwsiStopBitSet(chanNum))
  77790. + {
  77791. + return MV_FAIL;
  77792. + }
  77793. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStopBitSet\n"));
  77794. +
  77795. + return MV_OK;
  77796. +}
  77797. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h
  77798. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h 1970-01-01 01:00:00.000000000 +0100
  77799. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h 2010-11-09 20:28:12.231824496 +0100
  77800. @@ -0,0 +1,121 @@
  77801. +/*******************************************************************************
  77802. +Copyright (C) Marvell International Ltd. and its affiliates
  77803. +
  77804. +This software file (the "File") is owned and distributed by Marvell
  77805. +International Ltd. and/or its affiliates ("Marvell") under the following
  77806. +alternative licensing terms. Once you have made an election to distribute the
  77807. +File under one of the following license alternatives, please (i) delete this
  77808. +introductory statement regarding license alternatives, (ii) delete the two
  77809. +license alternatives that you have not elected to use and (iii) preserve the
  77810. +Marvell copyright notice above.
  77811. +
  77812. +********************************************************************************
  77813. +Marvell Commercial License Option
  77814. +
  77815. +If you received this File from Marvell and you have entered into a commercial
  77816. +license agreement (a "Commercial License") with Marvell, the File is licensed
  77817. +to you under the terms of the applicable Commercial License.
  77818. +
  77819. +********************************************************************************
  77820. +Marvell GPL License Option
  77821. +
  77822. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77823. +modify this File in accordance with the terms and conditions of the General
  77824. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  77825. +available along with the File in the license.txt file or by writing to the Free
  77826. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  77827. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  77828. +
  77829. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  77830. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  77831. +DISCLAIMED. The GPL License provides additional details about this warranty
  77832. +disclaimer.
  77833. +********************************************************************************
  77834. +Marvell BSD License Option
  77835. +
  77836. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77837. +modify this File under the following licensing terms.
  77838. +Redistribution and use in source and binary forms, with or without modification,
  77839. +are permitted provided that the following conditions are met:
  77840. +
  77841. + * Redistributions of source code must retain the above copyright notice,
  77842. + this list of conditions and the following disclaimer.
  77843. +
  77844. + * Redistributions in binary form must reproduce the above copyright
  77845. + notice, this list of conditions and the following disclaimer in the
  77846. + documentation and/or other materials provided with the distribution.
  77847. +
  77848. + * Neither the name of Marvell nor the names of its contributors may be
  77849. + used to endorse or promote products derived from this software without
  77850. + specific prior written permission.
  77851. +
  77852. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  77853. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  77854. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  77855. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  77856. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  77857. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  77858. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  77859. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  77860. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  77861. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  77862. +
  77863. +*******************************************************************************/
  77864. +#ifndef __INCmvTwsiH
  77865. +#define __INCmvTwsiH
  77866. +
  77867. +#ifdef __cplusplus
  77868. +extern "C" {
  77869. +#endif /* __cplusplus */
  77870. +
  77871. +/* need to update this includes */
  77872. +#include "twsi/mvTwsiSpec.h"
  77873. +#include "ctrlEnv/mvCtrlEnvLib.h"
  77874. +
  77875. +
  77876. +/* The TWSI interface supports both 7-bit and 10-bit addressing. */
  77877. +/* This enumerator describes addressing type. */
  77878. +typedef enum _mvTwsiAddrType
  77879. +{
  77880. + ADDR7_BIT, /* 7 bit address */
  77881. + ADDR10_BIT /* 10 bit address */
  77882. +}MV_TWSI_ADDR_TYPE;
  77883. +
  77884. +/* This structure describes TWSI address. */
  77885. +typedef struct _mvTwsiAddr
  77886. +{
  77887. + MV_U32 address; /* address */
  77888. + MV_TWSI_ADDR_TYPE type; /* Address type */
  77889. +}MV_TWSI_ADDR;
  77890. +
  77891. +/* This structure describes a TWSI slave. */
  77892. +typedef struct _mvTwsiSlave
  77893. +{
  77894. + MV_TWSI_ADDR slaveAddr;
  77895. + MV_BOOL validOffset; /* whether the slave has offset (i.e. Eeprom etc.) */
  77896. + MV_U32 offset; /* offset in the slave. */
  77897. + MV_BOOL moreThen256; /* whether the ofset is bigger then 256 */
  77898. +}MV_TWSI_SLAVE;
  77899. +
  77900. +/* This enumerator describes TWSI protocol commands. */
  77901. +typedef enum _mvTwsiCmd
  77902. +{
  77903. + MV_TWSI_WRITE, /* TWSI write command - 0 according to spec */
  77904. + MV_TWSI_READ /* TWSI read command - 1 according to spec */
  77905. +}MV_TWSI_CMD;
  77906. +
  77907. +MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum);
  77908. +MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum);
  77909. +MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *twsiAddr, MV_TWSI_CMD command);
  77910. +
  77911. +MV_U32 mvTwsiInit(MV_U8 chanNum, MV_KHZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *twsiAddr, MV_BOOL generalCallEnable);
  77912. +MV_STATUS mvTwsiRead (MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);
  77913. +MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);
  77914. +
  77915. +
  77916. +#ifdef __cplusplus
  77917. +}
  77918. +#endif /* __cplusplus */
  77919. +
  77920. +#endif /* __INCmvTwsiH */
  77921. +
  77922. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h
  77923. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h 1970-01-01 01:00:00.000000000 +0100
  77924. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h 2010-11-09 20:28:12.272374071 +0100
  77925. @@ -0,0 +1,160 @@
  77926. +/*******************************************************************************
  77927. +Copyright (C) Marvell International Ltd. and its affiliates
  77928. +
  77929. +This software file (the "File") is owned and distributed by Marvell
  77930. +International Ltd. and/or its affiliates ("Marvell") under the following
  77931. +alternative licensing terms. Once you have made an election to distribute the
  77932. +File under one of the following license alternatives, please (i) delete this
  77933. +introductory statement regarding license alternatives, (ii) delete the two
  77934. +license alternatives that you have not elected to use and (iii) preserve the
  77935. +Marvell copyright notice above.
  77936. +
  77937. +********************************************************************************
  77938. +Marvell Commercial License Option
  77939. +
  77940. +If you received this File from Marvell and you have entered into a commercial
  77941. +license agreement (a "Commercial License") with Marvell, the File is licensed
  77942. +to you under the terms of the applicable Commercial License.
  77943. +
  77944. +********************************************************************************
  77945. +Marvell GPL License Option
  77946. +
  77947. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77948. +modify this File in accordance with the terms and conditions of the General
  77949. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  77950. +available along with the File in the license.txt file or by writing to the Free
  77951. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  77952. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  77953. +
  77954. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  77955. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  77956. +DISCLAIMED. The GPL License provides additional details about this warranty
  77957. +disclaimer.
  77958. +********************************************************************************
  77959. +Marvell BSD License Option
  77960. +
  77961. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77962. +modify this File under the following licensing terms.
  77963. +Redistribution and use in source and binary forms, with or without modification,
  77964. +are permitted provided that the following conditions are met:
  77965. +
  77966. + * Redistributions of source code must retain the above copyright notice,
  77967. + this list of conditions and the following disclaimer.
  77968. +
  77969. + * Redistributions in binary form must reproduce the above copyright
  77970. + notice, this list of conditions and the following disclaimer in the
  77971. + documentation and/or other materials provided with the distribution.
  77972. +
  77973. + * Neither the name of Marvell nor the names of its contributors may be
  77974. + used to endorse or promote products derived from this software without
  77975. + specific prior written permission.
  77976. +
  77977. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  77978. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  77979. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  77980. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  77981. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  77982. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  77983. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  77984. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  77985. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  77986. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  77987. +
  77988. +*******************************************************************************/
  77989. +/****************************************/
  77990. +/* TWSI Registers */
  77991. +/****************************************/
  77992. +#ifndef __INCmvTwsiSpech
  77993. +#define __INCmvTwsiSpech
  77994. +
  77995. +#ifdef __cplusplus
  77996. +extern "C" {
  77997. +#endif /* __cplusplus */
  77998. +
  77999. +/* defines */
  78000. +#define TWSI_SLAVE_ADDR_REG(chanNum) (TWSI_SLAVE_BASE(chanNum)+ 0x00)
  78001. +
  78002. +#define TWSI_SLAVE_ADDR_GCE_ENA BIT0
  78003. +#define TWSI_SLAVE_ADDR_7BIT_OFFS 0x1
  78004. +#define TWSI_SLAVE_ADDR_7BIT_MASK (0xFF << TWSI_SLAVE_ADDR_7BIT_OFFS)
  78005. +#define TWSI_SLAVE_ADDR_10BIT_OFFS 0x7
  78006. +#define TWSI_SLAVE_ADDR_10BIT_MASK 0x300
  78007. +#define TWSI_SLAVE_ADDR_10BIT_CONST 0xF0
  78008. +
  78009. +
  78010. +#define TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x10)
  78011. +#define TWSI_EXTENDED_SLAVE_OFFS 0
  78012. +#define TWSI_EXTENDED_SLAVE_MASK (0xFF << TWSI_EXTENDED_SLAVE_OFFS)
  78013. +
  78014. +
  78015. +#define TWSI_DATA_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x04)
  78016. +#define TWSI_DATA_COMMAND_OFFS 0x0
  78017. +#define TWSI_DATA_COMMAND_MASK (0x1 << TWSI_DATA_COMMAND_OFFS)
  78018. +#define TWSI_DATA_COMMAND_WR (0x1 << TWSI_DATA_COMMAND_OFFS)
  78019. +#define TWSI_DATA_COMMAND_RD (0x0 << TWSI_DATA_COMMAND_OFFS)
  78020. +#define TWSI_DATA_ADDR_7BIT_OFFS 0x1
  78021. +#define TWSI_DATA_ADDR_7BIT_MASK (0xFF << TWSI_DATA_ADDR_7BIT_OFFS)
  78022. +#define TWSI_DATA_ADDR_10BIT_OFFS 0x7
  78023. +#define TWSI_DATA_ADDR_10BIT_MASK 0x300
  78024. +#define TWSI_DATA_ADDR_10BIT_CONST 0xF0
  78025. +
  78026. +
  78027. +#define TWSI_CONTROL_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x08)
  78028. +#define TWSI_CONTROL_ACK BIT2
  78029. +#define TWSI_CONTROL_INT_FLAG_SET BIT3
  78030. +#define TWSI_CONTROL_STOP_BIT BIT4
  78031. +#define TWSI_CONTROL_START_BIT BIT5
  78032. +#define TWSI_CONTROL_ENA BIT6
  78033. +#define TWSI_CONTROL_INT_ENA BIT7
  78034. +
  78035. +
  78036. +#define TWSI_STATUS_BAUDE_RATE_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x0c)
  78037. +#define TWSI_BAUD_RATE_N_OFFS 0
  78038. +#define TWSI_BAUD_RATE_N_MASK (0x7 << TWSI_BAUD_RATE_N_OFFS)
  78039. +#define TWSI_BAUD_RATE_M_OFFS 3
  78040. +#define TWSI_BAUD_RATE_M_MASK (0xF << TWSI_BAUD_RATE_M_OFFS)
  78041. +
  78042. +#define TWSI_SOFT_RESET_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x1c)
  78043. +
  78044. +/* defines */
  78045. +#define TWSI_TIMEOUT_VALUE 0x500
  78046. +
  78047. +/* TWSI status codes */
  78048. +#define TWSI_BUS_ERROR 0x00
  78049. +#define TWSI_START_CON_TRA 0x08
  78050. +#define TWSI_REPEATED_START_CON_TRA 0x10
  78051. +#define TWSI_AD_PLS_WR_BIT_TRA_ACK_REC 0x18
  78052. +#define TWSI_AD_PLS_WR_BIT_TRA_ACK_NOT_REC 0x20
  78053. +#define TWSI_M_TRAN_DATA_BYTE_ACK_REC 0x28
  78054. +#define TWSI_M_TRAN_DATA_BYTE_ACK_NOT_REC 0x30
  78055. +#define TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA 0x38
  78056. +#define TWSI_AD_PLS_RD_BIT_TRA_ACK_REC 0x40
  78057. +#define TWSI_AD_PLS_RD_BIT_TRA_ACK_NOT_REC 0x48
  78058. +#define TWSI_M_REC_RD_DATA_ACK_TRA 0x50
  78059. +#define TWSI_M_REC_RD_DATA_ACK_NOT_TRA 0x58
  78060. +#define TWSI_SLA_REC_AD_PLS_WR_BIT_ACK_TRA 0x60
  78061. +#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_W 0x68
  78062. +#define TWSI_GNL_CALL_REC_ACK_TRA 0x70
  78063. +#define TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA 0x78
  78064. +#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_TRAN 0x80
  78065. +#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_NOT_TRAN 0x88
  78066. +#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_TRAN 0x90
  78067. +#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_NOT_TRAN 0x98
  78068. +#define TWSI_SLA_REC_STOP_OR_REPEATED_STRT_CON 0xA0
  78069. +#define TWSI_SLA_REC_AD_PLS_RD_BIT_ACK_TRA 0xA8
  78070. +#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_R 0xB0
  78071. +#define TWSI_SLA_TRA_RD_DATA_ACK_REC 0xB8
  78072. +#define TWSI_SLA_TRA_RD_DATA_ACK_NOT_REC 0xC0
  78073. +#define TWSI_SLA_TRA_LAST_RD_DATA_ACK_REC 0xC8
  78074. +#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC 0xD0
  78075. +#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_NOT_REC 0xD8
  78076. +#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC 0xE0
  78077. +#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_NOT_REC 0xE8
  78078. +#define TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0 0xF8
  78079. +
  78080. +
  78081. +#ifdef __cplusplus
  78082. +}
  78083. +#endif /* __cplusplus */
  78084. +
  78085. +#endif /* __INCmvTwsiSpech */
  78086. diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h
  78087. --- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h 1970-01-01 01:00:00.000000000 +0100
  78088. +++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h 2010-11-09 20:28:12.322486315 +0100
  78089. @@ -0,0 +1,375 @@
  78090. +/*******************************************************************************
  78091. +Copyright (C) Marvell International Ltd. and its affiliates
  78092. +
  78093. +********************************************************************************
  78094. +Marvell GPL License Option
  78095. +
  78096. +If you received this File from Marvell, you may opt to use, redistribute and/or
  78097. +modify this File in accordance with the terms and conditions of the General
  78098. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  78099. +available along with the File in the license.txt file or by writing to the Free
  78100. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  78101. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  78102. +
  78103. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  78104. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  78105. +DISCLAIMED. The GPL License provides additional details about this warranty
  78106. +disclaimer.
  78107. +
  78108. +*******************************************************************************/
  78109. +/*******************************************************************************
  78110. +* mvSysHwCfg.h - Marvell system HW configuration file
  78111. +*
  78112. +* DESCRIPTION:
  78113. +* None.
  78114. +*
  78115. +* DEPENDENCIES:
  78116. +* None.
  78117. +*
  78118. +*******************************************************************************/
  78119. +
  78120. +#ifndef __INCmvSysHwConfigh
  78121. +#define __INCmvSysHwConfigh
  78122. +
  78123. +#include "../../../../include/linux/autoconf.h"
  78124. +
  78125. +#define CONFIG_MARVELL 1
  78126. +
  78127. +/* includes */
  78128. +#define _1K 0x00000400
  78129. +#define _4K 0x00001000
  78130. +#define _8K 0x00002000
  78131. +#define _16K 0x00004000
  78132. +#define _32K 0x00008000
  78133. +#define _64K 0x00010000
  78134. +#define _128K 0x00020000
  78135. +#define _256K 0x00040000
  78136. +#define _512K 0x00080000
  78137. +
  78138. +#define _1M 0x00100000
  78139. +#define _2M 0x00200000
  78140. +#define _4M 0x00400000
  78141. +#define _8M 0x00800000
  78142. +#define _16M 0x01000000
  78143. +#define _32M 0x02000000
  78144. +#define _64M 0x04000000
  78145. +#define _128M 0x08000000
  78146. +#define _256M 0x10000000
  78147. +#define _512M 0x20000000
  78148. +
  78149. +#define _1G 0x40000000
  78150. +#define _2G 0x80000000
  78151. +
  78152. +/****************************************/
  78153. +/* Soc supporeted Units definitions */
  78154. +/****************************************/
  78155. +
  78156. +#ifdef CONFIG_MV_INCLUDE_PEX
  78157. +#define MV_INCLUDE_PEX
  78158. +#endif
  78159. +#ifdef CONFIG_MV_INCLUDE_TWSI
  78160. +#define MV_INCLUDE_TWSI
  78161. +#endif
  78162. +#ifdef CONFIG_MV_INCLUDE_CESA
  78163. +#define MV_INCLUDE_CESA
  78164. +#endif
  78165. +#ifdef CONFIG_MV_INCLUDE_GIG_ETH
  78166. +#define MV_INCLUDE_GIG_ETH
  78167. +#endif
  78168. +#ifdef CONFIG_MV_INCLUDE_INTEG_SATA
  78169. +#define MV_INCLUDE_INTEG_SATA
  78170. +#define MV_INCLUDE_SATA
  78171. +#endif
  78172. +#ifdef CONFIG_MV_INCLUDE_USB
  78173. +#define MV_INCLUDE_USB
  78174. +#define MV_USB_VOLTAGE_FIX
  78175. +#endif
  78176. +#ifdef CONFIG_MV_INCLUDE_NAND
  78177. +#define MV_INCLUDE_NAND
  78178. +#endif
  78179. +#ifdef CONFIG_MV_INCLUDE_TDM
  78180. +#define MV_INCLUDE_TDM
  78181. +#endif
  78182. +#ifdef CONFIG_MV_INCLUDE_XOR
  78183. +#define MV_INCLUDE_XOR
  78184. +#endif
  78185. +#ifdef CONFIG_MV_INCLUDE_TWSI
  78186. +#define MV_INCLUDE_TWSI
  78187. +#endif
  78188. +#ifdef CONFIG_MV_INCLUDE_UART
  78189. +#define MV_INCLUDE_UART
  78190. +#endif
  78191. +#ifdef CONFIG_MV_INCLUDE_SPI
  78192. +#define MV_INCLUDE_SPI
  78193. +#endif
  78194. +#ifdef CONFIG_MV_INCLUDE_SFLASH_MTD
  78195. +#define MV_INCLUDE_SFLASH_MTD
  78196. +#endif
  78197. +#ifdef CONFIG_MV_INCLUDE_AUDIO
  78198. +#define MV_INCLUDE_AUDIO
  78199. +#endif
  78200. +#ifdef CONFIG_MV_INCLUDE_TS
  78201. +#define MV_INCLUDE_TS
  78202. +#endif
  78203. +#ifdef CONFIG_MV_INCLUDE_SDIO
  78204. +#define MV_INCLUDE_SDIO
  78205. +#endif
  78206. +
  78207. +
  78208. +/* NAND flash stuff */
  78209. +#ifdef CONFIG_MV_NAND_BOOT
  78210. +#define MV_NAND_BOOT
  78211. +#endif
  78212. +#ifdef CONFIG_MV_NAND
  78213. +#define MV_NAND
  78214. +#endif
  78215. +
  78216. +/* SPI flash stuff */
  78217. +#ifdef CONFIG_MV_SPI_BOOT
  78218. +#define MV_SPI_BOOT
  78219. +#endif
  78220. +
  78221. +
  78222. +/****************************************************************/
  78223. +/************* General configuration ********************/
  78224. +/****************************************************************/
  78225. +
  78226. +/* Enable Clock Power Control */
  78227. +#define MV_INCLUDE_CLK_PWR_CNTRL
  78228. +
  78229. +/* Disable the DEVICE BAR in the PEX */
  78230. +#define MV_DISABLE_PEX_DEVICE_BAR
  78231. +
  78232. +/* Allow the usage of early printings during initialization */
  78233. +#define MV_INCLUDE_EARLY_PRINTK
  78234. +
  78235. +/****************************************************************/
  78236. +/************* NFP configuration ********************************/
  78237. +/****************************************************************/
  78238. +#define MV_NFP_SEC_Q_SIZE 64
  78239. +#define MV_NFP_SEC_REQ_Q_SIZE 1000
  78240. +
  78241. +
  78242. +
  78243. +/****************************************************************/
  78244. +/************* CESA configuration ********************/
  78245. +/****************************************************************/
  78246. +
  78247. +#ifdef MV_INCLUDE_CESA
  78248. +
  78249. +#define MV_CESA_MAX_CHAN 4
  78250. +
  78251. +/* Use 2K of SRAM */
  78252. +#define MV_CESA_MAX_BUF_SIZE 1600
  78253. +
  78254. +#endif /* MV_INCLUDE_CESA */
  78255. +
  78256. +#if defined(CONFIG_MV_INCLUDE_GIG_ETH)
  78257. +
  78258. +#ifdef CONFIG_MV_NFP_STATS
  78259. +#define MV_FP_STATISTICS
  78260. +#else
  78261. +#undef MV_FP_STATISTICS
  78262. +#endif
  78263. +/* Default configuration for SKB_REUSE: 0 - Disabled, 1 - Enabled */
  78264. +#define MV_ETH_SKB_REUSE_DEFAULT 1
  78265. +/* Default configuration for TX_EN workaround: 0 - Disabled, 1 - Enabled */
  78266. +#define MV_ETH_TX_EN_DEFAULT 0
  78267. +
  78268. +/* un-comment if you want to perform tx_done from within the poll function */
  78269. +/* #define ETH_TX_DONE_ISR */
  78270. +
  78271. +/* put descriptors in uncached memory */
  78272. +/* #define ETH_DESCR_UNCACHED */
  78273. +
  78274. +/* Descriptors location: DRAM/internal-SRAM */
  78275. +#define ETH_DESCR_IN_SDRAM
  78276. +#undef ETH_DESCR_IN_SRAM /* No integrated SRAM in 88Fxx81 devices */
  78277. +
  78278. +#if defined(ETH_DESCR_IN_SRAM)
  78279. +#if defined(ETH_DESCR_UNCACHED)
  78280. + #define ETH_DESCR_CONFIG_STR "Uncached descriptors in integrated SRAM"
  78281. +#else
  78282. + #define ETH_DESCR_CONFIG_STR "Cached descriptors in integrated SRAM"
  78283. +#endif
  78284. +#elif defined(ETH_DESCR_IN_SDRAM)
  78285. +#if defined(ETH_DESCR_UNCACHED)
  78286. + #define ETH_DESCR_CONFIG_STR "Uncached descriptors in DRAM"
  78287. +#else
  78288. + #define ETH_DESCR_CONFIG_STR "Cached descriptors in DRAM"
  78289. +#endif
  78290. +#else
  78291. + #error "Ethernet descriptors location undefined"
  78292. +#endif /* ETH_DESCR_IN_SRAM or ETH_DESCR_IN_SDRAM*/
  78293. +
  78294. +/* SW Sync-Barrier: not relevant for 88fxx81*/
  78295. +/* Reasnable to define this macro when descriptors in SRAM and buffers in DRAM */
  78296. +/* In RX the CPU theoretically might see himself as the descriptor owner, */
  78297. +/* although the buffer hadn't been written to DRAM yet. Performance cost. */
  78298. +/* #define INCLUDE_SYNC_BARR */
  78299. +
  78300. +/* Buffers cache coherency method (buffers in DRAM) */
  78301. +#ifndef MV_CACHE_COHER_SW
  78302. +/* Taken from mvCommon.h */
  78303. +/* Memory uncached, HW or SW cache coherency is not needed */
  78304. +#define MV_UNCACHED 0
  78305. +/* Memory cached, HW cache coherency supported in WriteThrough mode */
  78306. +#define MV_CACHE_COHER_HW_WT 1
  78307. +/* Memory cached, HW cache coherency supported in WriteBack mode */
  78308. +#define MV_CACHE_COHER_HW_WB 2
  78309. +/* Memory cached, No HW cache coherency, Cache coherency must be in SW */
  78310. +#define MV_CACHE_COHER_SW 3
  78311. +
  78312. +#endif
  78313. +
  78314. +/* DRAM cache coherency configuration */
  78315. +#define MV_CACHE_COHERENCY MV_CACHE_COHER_SW
  78316. +
  78317. +
  78318. +#define ETHER_DRAM_COHER MV_CACHE_COHER_SW /* No HW coherency in 88Fxx81 devices */
  78319. +
  78320. +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB)
  78321. + #define ETH_SDRAM_CONFIG_STR "DRAM HW cache coherency (write-back)"
  78322. +#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT)
  78323. + #define ETH_SDRAM_CONFIG_STR "DRAM HW cache coherency (write-through)"
  78324. +#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_SW)
  78325. + #define ETH_SDRAM_CONFIG_STR "DRAM SW cache-coherency"
  78326. +#elif (ETHER_DRAM_COHER == MV_UNCACHED)
  78327. +# define ETH_SDRAM_CONFIG_STR "DRAM uncached"
  78328. +#else
  78329. + #error "Ethernet-DRAM undefined"
  78330. +#endif /* ETHER_DRAM_COHER */
  78331. +
  78332. +
  78333. +/****************************************************************/
  78334. +/************* Ethernet driver configuration ********************/
  78335. +/****************************************************************/
  78336. +
  78337. +/* port's default queueus */
  78338. +#define ETH_DEF_TXQ 0
  78339. +#define ETH_DEF_RXQ 0
  78340. +
  78341. +#define MV_ETH_RX_Q_NUM CONFIG_MV_ETH_RX_Q_NUM
  78342. +#define MV_ETH_TX_Q_NUM CONFIG_MV_ETH_TX_Q_NUM
  78343. +
  78344. +/* interrupt coalescing setting */
  78345. +#define ETH_TX_COAL 200
  78346. +#define ETH_RX_COAL 200
  78347. +
  78348. +/* Checksum offloading */
  78349. +#define TX_CSUM_OFFLOAD
  78350. +#define RX_CSUM_OFFLOAD
  78351. +
  78352. +#endif /* CONFIG_MV_INCLUDE_GIG_ETH */
  78353. +
  78354. +/****************************************************************/
  78355. +/*************** Telephony configuration ************************/
  78356. +/****************************************************************/
  78357. +#if defined(CONFIG_MV_TDM_LINEAR_MODE)
  78358. + #define MV_TDM_LINEAR_MODE
  78359. +#elif defined(CONFIG_MV_TDM_ULAW_MODE)
  78360. + #define MV_TDM_ULAW_MODE
  78361. +#endif
  78362. +
  78363. +#if defined(CONFIG_MV_TDM_5CHANNELS)
  78364. + #define MV_TDM_5CHANNELS
  78365. +#endif
  78366. +
  78367. +#if defined(CONFIG_MV_TDM_USE_EXTERNAL_PCLK_SOURCE)
  78368. + #define MV_TDM_USE_EXTERNAL_PCLK_SOURCE
  78369. +#endif
  78370. +
  78371. +/* We use the following registers to store DRAM interface pre configuration */
  78372. +/* auto-detection results */
  78373. +/* IMPORTANT: We are using mask register for that purpose. Before writing */
  78374. +/* to units mask register, make sure main maks register is set to disable */
  78375. +/* all interrupts. */
  78376. +#define DRAM_BUF_REG0 0x30810 /* sdram bank 0 size */
  78377. +#define DRAM_BUF_REG1 0x30820 /* sdram config */
  78378. +#define DRAM_BUF_REG2 0x30830 /* sdram mode */
  78379. +#define DRAM_BUF_REG3 0x308c4 /* dunit control low */
  78380. +#define DRAM_BUF_REG4 0x60a90 /* sdram address control */
  78381. +#define DRAM_BUF_REG5 0x60a94 /* sdram timing control low */
  78382. +#define DRAM_BUF_REG6 0x60a98 /* sdram timing control high */
  78383. +#define DRAM_BUF_REG7 0x60a9c /* sdram ODT control low */
  78384. +#define DRAM_BUF_REG8 0x60b90 /* sdram ODT control high */
  78385. +#define DRAM_BUF_REG9 0x60b94 /* sdram Dunit ODT control */
  78386. +#define DRAM_BUF_REG10 0x60b98 /* sdram Extended Mode */
  78387. +#define DRAM_BUF_REG11 0x60b9c /* sdram Ddr2 Time Low Reg */
  78388. +#define DRAM_BUF_REG12 0x60a00 /* sdram Ddr2 Time High Reg */
  78389. +#define DRAM_BUF_REG13 0x60a04 /* dunit Ctrl High */
  78390. +#define DRAM_BUF_REG14 0x60b00 /* sdram second DIMM exist */
  78391. +
  78392. +/* Following the pre-configuration registers default values restored after */
  78393. +/* auto-detection is done */
  78394. +#define DRAM_BUF_REG_DV 0
  78395. +
  78396. +/* System Mapping */
  78397. +#define SDRAM_CS0_BASE 0x00000000
  78398. +#define SDRAM_CS0_SIZE _256M
  78399. +
  78400. +#define SDRAM_CS1_BASE 0x10000000
  78401. +#define SDRAM_CS1_SIZE _256M
  78402. +
  78403. +#define SDRAM_CS2_BASE 0x20000000
  78404. +#define SDRAM_CS2_SIZE _256M
  78405. +
  78406. +#define SDRAM_CS3_BASE 0x30000000
  78407. +#define SDRAM_CS3_SIZE _256M
  78408. +
  78409. +/* PEX */
  78410. +#define PEX0_MEM_BASE 0xe8000000
  78411. +#define PEX0_MEM_SIZE _128M
  78412. +
  78413. +#define PEX0_IO_BASE 0xf2000000
  78414. +#define PEX0_IO_SIZE _1M
  78415. +
  78416. +/* Device Chip Selects */
  78417. +#define NFLASH_CS_BASE 0xfa000000
  78418. +#define NFLASH_CS_SIZE _2M
  78419. +
  78420. +#define SPI_CS_BASE 0xf4000000
  78421. +#define SPI_CS_SIZE _16M
  78422. +
  78423. +#define CRYPT_ENG_BASE 0xf0000000
  78424. +#define CRYPT_ENG_SIZE _2M
  78425. +
  78426. +#define BOOTDEV_CS_BASE 0xff800000
  78427. +#define BOOTDEV_CS_SIZE _8M
  78428. +
  78429. +/* CS2 - BOOTROM */
  78430. +#define DEVICE_CS2_BASE 0xff900000
  78431. +#define DEVICE_CS2_SIZE _1M
  78432. +
  78433. +/* PEX Work arround */
  78434. +/* the target we will use for the workarround */
  78435. +#define PEX_CONFIG_RW_WA_TARGET PEX0_MEM
  78436. +/*a flag that indicates if we are going to use the
  78437. +size and base of the target we using for the workarround
  78438. +window */
  78439. +#define PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES 1
  78440. +/* if the above flag is 0 then the following values
  78441. +will be used for the workarround window base and size,
  78442. +otherwise the following defines will be ignored */
  78443. +#define PEX_CONFIG_RW_WA_BASE 0xF3000000
  78444. +#define PEX_CONFIG_RW_WA_SIZE _16M
  78445. +
  78446. +/* Internal registers: size is defined in Controllerenvironment */
  78447. +#define INTER_REGS_BASE 0xFEE00000
  78448. +
  78449. +/* DRAM detection stuff */
  78450. +#define MV_DRAM_AUTO_SIZE
  78451. +
  78452. +/* Board clock detection */
  78453. +#define TCLK_AUTO_DETECT /* Use Tclk auto detection */
  78454. +#define SYSCLK_AUTO_DETECT /* Use SysClk auto detection */
  78455. +#define PCLCK_AUTO_DETECT /* Use PClk auto detection */
  78456. +#define L2CLK_AUTO_DETECT /* Use L2Clk auto detection */
  78457. +
  78458. +/* PEX-PCI\PCI-PCI Bridge*/
  78459. +#define PCI0_IF_PTP 0 /* Bridge exist on pciIf0*/
  78460. +
  78461. +
  78462. +
  78463. +#endif /* __INCmvSysHwConfigh */
  78464. +
  78465. diff -Nur linux-2.6.36.orig/crypto/ocf/Makefile linux-2.6.36/crypto/ocf/Makefile
  78466. --- linux-2.6.36.orig/crypto/ocf/Makefile 1970-01-01 01:00:00.000000000 +0100
  78467. +++ linux-2.6.36/crypto/ocf/Makefile 2010-11-09 20:28:12.342495369 +0100
  78468. @@ -0,0 +1,124 @@
  78469. +# for SGlinux builds
  78470. +-include $(ROOTDIR)/modules/.config
  78471. +
  78472. +OCF_OBJS = crypto.o criov.o
  78473. +
  78474. +ifdef CONFIG_OCF_RANDOMHARVEST
  78475. + OCF_OBJS += random.o
  78476. +endif
  78477. +
  78478. +ifdef CONFIG_OCF_FIPS
  78479. + OCF_OBJS += rndtest.o
  78480. +endif
  78481. +
  78482. +# Add in autoconf.h to get #defines for CONFIG_xxx
  78483. +AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h
  78484. +ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))
  78485. + EXTRA_CFLAGS += -include $(AUTOCONF_H)
  78486. + export EXTRA_CFLAGS
  78487. +endif
  78488. +
  78489. +ifndef obj
  78490. + obj ?= .
  78491. + _obj = subdir
  78492. + mod-subdirs := safe hifn ixp4xx talitos ocfnull
  78493. + export-objs += crypto.o criov.o random.o
  78494. + list-multi += ocf.o
  78495. + _slash :=
  78496. +else
  78497. + _obj = obj
  78498. + _slash := /
  78499. +endif
  78500. +
  78501. +EXTRA_CFLAGS += -I$(obj)/.
  78502. +
  78503. +obj-$(CONFIG_OCF_OCF) += ocf.o
  78504. +obj-$(CONFIG_OCF_CRYPTODEV) += cryptodev.o
  78505. +obj-$(CONFIG_OCF_CRYPTOSOFT) += cryptosoft.o
  78506. +obj-$(CONFIG_OCF_BENCH) += ocf-bench.o
  78507. +
  78508. +$(_obj)-$(CONFIG_OCF_SAFE) += safe$(_slash)
  78509. +$(_obj)-$(CONFIG_OCF_HIFN) += hifn$(_slash)
  78510. +$(_obj)-$(CONFIG_OCF_IXP4XX) += ixp4xx$(_slash)
  78511. +$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)
  78512. +$(_obj)-$(CONFIG_OCF_PASEMI) += pasemi$(_slash)
  78513. +$(_obj)-$(CONFIG_OCF_EP80579) += ep80579$(_slash)
  78514. +$(_obj)-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon$(_slash)
  78515. +$(_obj)-$(CONFIG_OCF_KIRKWOOD) += kirkwood$(_slash)
  78516. +$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
  78517. +$(_obj)-$(CONFIG_OCF_C7108) += c7108$(_slash)
  78518. +
  78519. +ocf-objs := $(OCF_OBJS)
  78520. +
  78521. +$(list-multi) dummy1: $(ocf-objs)
  78522. + $(LD) -r -o $@ $(ocf-objs)
  78523. +
  78524. +.PHONY:
  78525. +clean:
  78526. + rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c
  78527. + rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags
  78528. +
  78529. +ifdef TOPDIR
  78530. +-include $(TOPDIR)/Rules.make
  78531. +endif
  78532. +
  78533. +#
  78534. +# release gen targets
  78535. +#
  78536. +
  78537. +.PHONY: patch
  78538. +patch:
  78539. + REL=`date +%Y%m%d`; \
  78540. + patch=ocf-linux-$$REL.patch; \
  78541. + patch24=ocf-linux-24-$$REL.patch; \
  78542. + patch26=ocf-linux-26-$$REL.patch; \
  78543. + ( \
  78544. + find . -name Makefile; \
  78545. + find . -name Config.in; \
  78546. + find . -name Kconfig; \
  78547. + find . -name README; \
  78548. + find . -name '*.[ch]' | grep -v '.mod.c'; \
  78549. + ) | while read t; do \
  78550. + diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \
  78551. + done > $$patch; \
  78552. + cat patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
  78553. + cat patches/linux-2.6.33-ocf.patch $$patch > $$patch26
  78554. +
  78555. +.PHONY: tarball
  78556. +tarball:
  78557. + REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \
  78558. + CURDIR=`pwd`; \
  78559. + rm -rf /tmp/ocf-linux-$$REL*; \
  78560. + mkdir -p $$RELDIR/tools; \
  78561. + cp README* $$RELDIR; \
  78562. + cp patches/openss*.patch $$RELDIR; \
  78563. + cp patches/crypto-tools.patch $$RELDIR; \
  78564. + cp tools/[!C]* $$RELDIR/tools; \
  78565. + cd ..; \
  78566. + tar cvf $$RELDIR/ocf-linux.tar \
  78567. + --exclude=CVS \
  78568. + --exclude=.* \
  78569. + --exclude=*.o \
  78570. + --exclude=*.ko \
  78571. + --exclude=*.mod.* \
  78572. + --exclude=README* \
  78573. + --exclude=ocf-*.patch \
  78574. + --exclude=ocf/patches/openss*.patch \
  78575. + --exclude=ocf/patches/crypto-tools.patch \
  78576. + --exclude=ocf/tools \
  78577. + ocf; \
  78578. + gzip -9 $$RELDIR/ocf-linux.tar; \
  78579. + cd /tmp; \
  78580. + tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \
  78581. + gzip -9 ocf-linux-$$REL.tar; \
  78582. + cd $$CURDIR/../../user; \
  78583. + rm -rf /tmp/crypto-tools-$$REL*; \
  78584. + tar cvf /tmp/crypto-tools-$$REL.tar \
  78585. + --exclude=CVS \
  78586. + --exclude=.* \
  78587. + --exclude=*.o \
  78588. + --exclude=cryptotest \
  78589. + --exclude=cryptokeytest \
  78590. + crypto-tools; \
  78591. + gzip -9 /tmp/crypto-tools-$$REL.tar
  78592. +
  78593. diff -Nur linux-2.6.36.orig/crypto/ocf/ocf-bench.c linux-2.6.36/crypto/ocf/ocf-bench.c
  78594. --- linux-2.6.36.orig/crypto/ocf/ocf-bench.c 1970-01-01 01:00:00.000000000 +0100
  78595. +++ linux-2.6.36/crypto/ocf/ocf-bench.c 2010-11-09 20:28:12.381251524 +0100
  78596. @@ -0,0 +1,436 @@
  78597. +/*
  78598. + * A loadable module that benchmarks the OCF crypto speed from kernel space.
  78599. + *
  78600. + * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
  78601. + *
  78602. + * LICENSE TERMS
  78603. + *
  78604. + * The free distribution and use of this software in both source and binary
  78605. + * form is allowed (with or without changes) provided that:
  78606. + *
  78607. + * 1. distributions of this source code include the above copyright
  78608. + * notice, this list of conditions and the following disclaimer;
  78609. + *
  78610. + * 2. distributions in binary form include the above copyright
  78611. + * notice, this list of conditions and the following disclaimer
  78612. + * in the documentation and/or other associated materials;
  78613. + *
  78614. + * 3. the copyright holder's name is not used to endorse products
  78615. + * built using this software without specific written permission.
  78616. + *
  78617. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  78618. + * may be distributed under the terms of the GNU General Public License (GPL),
  78619. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  78620. + *
  78621. + * DISCLAIMER
  78622. + *
  78623. + * This software is provided 'as is' with no explicit or implied warranties
  78624. + * in respect of its properties, including, but not limited to, correctness
  78625. + * and/or fitness for purpose.
  78626. + */
  78627. +
  78628. +
  78629. +#ifndef AUTOCONF_INCLUDED
  78630. +#include <linux/config.h>
  78631. +#endif
  78632. +#include <linux/module.h>
  78633. +#include <linux/init.h>
  78634. +#include <linux/list.h>
  78635. +#include <linux/slab.h>
  78636. +#include <linux/wait.h>
  78637. +#include <linux/sched.h>
  78638. +#include <linux/spinlock.h>
  78639. +#include <linux/version.h>
  78640. +#include <linux/interrupt.h>
  78641. +#include <cryptodev.h>
  78642. +
  78643. +#ifdef I_HAVE_AN_XSCALE_WITH_INTEL_SDK
  78644. +#define BENCH_IXP_ACCESS_LIB 1
  78645. +#endif
  78646. +#ifdef BENCH_IXP_ACCESS_LIB
  78647. +#include <IxTypes.h>
  78648. +#include <IxOsBuffMgt.h>
  78649. +#include <IxNpeDl.h>
  78650. +#include <IxCryptoAcc.h>
  78651. +#include <IxQMgr.h>
  78652. +#include <IxOsServices.h>
  78653. +#include <IxOsCacheMMU.h>
  78654. +#endif
  78655. +
  78656. +/*
  78657. + * support for access lib version 1.4
  78658. + */
  78659. +#ifndef IX_MBUF_PRIV
  78660. +#define IX_MBUF_PRIV(x) ((x)->priv)
  78661. +#endif
  78662. +
  78663. +/*
  78664. + * the number of simultaneously active requests
  78665. + */
  78666. +static int request_q_len = 20;
  78667. +module_param(request_q_len, int, 0);
  78668. +MODULE_PARM_DESC(request_q_len, "Number of outstanding requests");
  78669. +/*
  78670. + * how many requests we want to have processed
  78671. + */
  78672. +static int request_num = 1024;
  78673. +module_param(request_num, int, 0);
  78674. +MODULE_PARM_DESC(request_num, "run for at least this many requests");
  78675. +/*
  78676. + * the size of each request
  78677. + */
  78678. +static int request_size = 1500;
  78679. +module_param(request_size, int, 0);
  78680. +MODULE_PARM_DESC(request_size, "size of each request");
  78681. +
  78682. +/*
  78683. + * a structure for each request
  78684. + */
  78685. +typedef struct {
  78686. + struct work_struct work;
  78687. +#ifdef BENCH_IXP_ACCESS_LIB
  78688. + IX_MBUF mbuf;
  78689. +#endif
  78690. + unsigned char *buffer;
  78691. +} request_t;
  78692. +
  78693. +static request_t *requests;
  78694. +
  78695. +static int outstanding;
  78696. +static int total;
  78697. +
  78698. +/*************************************************************************/
  78699. +/*
  78700. + * OCF benchmark routines
  78701. + */
  78702. +
  78703. +static uint64_t ocf_cryptoid;
  78704. +static int ocf_init(void);
  78705. +static int ocf_cb(struct cryptop *crp);
  78706. +static void ocf_request(void *arg);
  78707. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  78708. +static void ocf_request_wq(struct work_struct *work);
  78709. +#endif
  78710. +
  78711. +static int
  78712. +ocf_init(void)
  78713. +{
  78714. + int error;
  78715. + struct cryptoini crie, cria;
  78716. + struct cryptodesc crda, crde;
  78717. +
  78718. + memset(&crie, 0, sizeof(crie));
  78719. + memset(&cria, 0, sizeof(cria));
  78720. + memset(&crde, 0, sizeof(crde));
  78721. + memset(&crda, 0, sizeof(crda));
  78722. +
  78723. + cria.cri_alg = CRYPTO_SHA1_HMAC;
  78724. + cria.cri_klen = 20 * 8;
  78725. + cria.cri_key = "0123456789abcdefghij";
  78726. +
  78727. + crie.cri_alg = CRYPTO_3DES_CBC;
  78728. + crie.cri_klen = 24 * 8;
  78729. + crie.cri_key = "0123456789abcdefghijklmn";
  78730. +
  78731. + crie.cri_next = &cria;
  78732. +
  78733. + error = crypto_newsession(&ocf_cryptoid, &crie, 0);
  78734. + if (error) {
  78735. + printk("crypto_newsession failed %d\n", error);
  78736. + return -1;
  78737. + }
  78738. + return 0;
  78739. +}
  78740. +
  78741. +static int
  78742. +ocf_cb(struct cryptop *crp)
  78743. +{
  78744. + request_t *r = (request_t *) crp->crp_opaque;
  78745. +
  78746. + if (crp->crp_etype)
  78747. + printk("Error in OCF processing: %d\n", crp->crp_etype);
  78748. + total++;
  78749. + crypto_freereq(crp);
  78750. + crp = NULL;
  78751. +
  78752. + if (total > request_num) {
  78753. + outstanding--;
  78754. + return 0;
  78755. + }
  78756. +
  78757. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  78758. + INIT_WORK(&r->work, ocf_request_wq);
  78759. +#else
  78760. + INIT_WORK(&r->work, ocf_request, r);
  78761. +#endif
  78762. + schedule_work(&r->work);
  78763. + return 0;
  78764. +}
  78765. +
  78766. +
  78767. +static void
  78768. +ocf_request(void *arg)
  78769. +{
  78770. + request_t *r = arg;
  78771. + struct cryptop *crp = crypto_getreq(2);
  78772. + struct cryptodesc *crde, *crda;
  78773. +
  78774. + if (!crp) {
  78775. + outstanding--;
  78776. + return;
  78777. + }
  78778. +
  78779. + crde = crp->crp_desc;
  78780. + crda = crde->crd_next;
  78781. +
  78782. + crda->crd_skip = 0;
  78783. + crda->crd_flags = 0;
  78784. + crda->crd_len = request_size;
  78785. + crda->crd_inject = request_size;
  78786. + crda->crd_alg = CRYPTO_SHA1_HMAC;
  78787. + crda->crd_key = "0123456789abcdefghij";
  78788. + crda->crd_klen = 20 * 8;
  78789. +
  78790. + crde->crd_skip = 0;
  78791. + crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_ENCRYPT;
  78792. + crde->crd_len = request_size;
  78793. + crde->crd_inject = request_size;
  78794. + crde->crd_alg = CRYPTO_3DES_CBC;
  78795. + crde->crd_key = "0123456789abcdefghijklmn";
  78796. + crde->crd_klen = 24 * 8;
  78797. +
  78798. + crp->crp_ilen = request_size + 64;
  78799. + crp->crp_flags = CRYPTO_F_CBIMM;
  78800. + crp->crp_buf = (caddr_t) r->buffer;
  78801. + crp->crp_callback = ocf_cb;
  78802. + crp->crp_sid = ocf_cryptoid;
  78803. + crp->crp_opaque = (caddr_t) r;
  78804. + crypto_dispatch(crp);
  78805. +}
  78806. +
  78807. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  78808. +static void
  78809. +ocf_request_wq(struct work_struct *work)
  78810. +{
  78811. + request_t *r = container_of(work, request_t, work);
  78812. + ocf_request(r);
  78813. +}
  78814. +#endif
  78815. +
  78816. +/*************************************************************************/
  78817. +#ifdef BENCH_IXP_ACCESS_LIB
  78818. +/*************************************************************************/
  78819. +/*
  78820. + * CryptoAcc benchmark routines
  78821. + */
  78822. +
  78823. +static IxCryptoAccCtx ixp_ctx;
  78824. +static UINT32 ixp_ctx_id;
  78825. +static IX_MBUF ixp_pri;
  78826. +static IX_MBUF ixp_sec;
  78827. +static int ixp_registered = 0;
  78828. +
  78829. +static void ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp,
  78830. + IxCryptoAccStatus status);
  78831. +static void ixp_perform_cb(UINT32 ctx_id, IX_MBUF *sbufp, IX_MBUF *dbufp,
  78832. + IxCryptoAccStatus status);
  78833. +static void ixp_request(void *arg);
  78834. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  78835. +static void ixp_request_wq(struct work_struct *work);
  78836. +#endif
  78837. +
  78838. +static int
  78839. +ixp_init(void)
  78840. +{
  78841. + IxCryptoAccStatus status;
  78842. +
  78843. + ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
  78844. + ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  78845. + ixp_ctx.cipherCtx.cipherKeyLen = 24;
  78846. + ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  78847. + ixp_ctx.cipherCtx.cipherInitialVectorLen = IX_CRYPTO_ACC_DES_IV_64;
  78848. + memcpy(ixp_ctx.cipherCtx.key.cipherKey, "0123456789abcdefghijklmn", 24);
  78849. +
  78850. + ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
  78851. + ixp_ctx.authCtx.authDigestLen = 12;
  78852. + ixp_ctx.authCtx.aadLen = 0;
  78853. + ixp_ctx.authCtx.authKeyLen = 20;
  78854. + memcpy(ixp_ctx.authCtx.key.authKey, "0123456789abcdefghij", 20);
  78855. +
  78856. + ixp_ctx.useDifferentSrcAndDestMbufs = 0;
  78857. + ixp_ctx.operation = IX_CRYPTO_ACC_OP_ENCRYPT_AUTH ;
  78858. +
  78859. + IX_MBUF_MLEN(&ixp_pri) = IX_MBUF_PKT_LEN(&ixp_pri) = 128;
  78860. + IX_MBUF_MDATA(&ixp_pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  78861. + IX_MBUF_MLEN(&ixp_sec) = IX_MBUF_PKT_LEN(&ixp_sec) = 128;
  78862. + IX_MBUF_MDATA(&ixp_sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  78863. +
  78864. + status = ixCryptoAccCtxRegister(&ixp_ctx, &ixp_pri, &ixp_sec,
  78865. + ixp_register_cb, ixp_perform_cb, &ixp_ctx_id);
  78866. +
  78867. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {
  78868. + while (!ixp_registered)
  78869. + schedule();
  78870. + return ixp_registered < 0 ? -1 : 0;
  78871. + }
  78872. +
  78873. + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
  78874. + return -1;
  78875. +}
  78876. +
  78877. +static void
  78878. +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
  78879. +{
  78880. + if (bufp) {
  78881. + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
  78882. + kfree(IX_MBUF_MDATA(bufp));
  78883. + IX_MBUF_MDATA(bufp) = NULL;
  78884. + }
  78885. +
  78886. + if (IX_CRYPTO_ACC_STATUS_WAIT == status)
  78887. + return;
  78888. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  78889. + ixp_registered = 1;
  78890. + else
  78891. + ixp_registered = -1;
  78892. +}
  78893. +
  78894. +static void
  78895. +ixp_perform_cb(
  78896. + UINT32 ctx_id,
  78897. + IX_MBUF *sbufp,
  78898. + IX_MBUF *dbufp,
  78899. + IxCryptoAccStatus status)
  78900. +{
  78901. + request_t *r = NULL;
  78902. +
  78903. + total++;
  78904. + if (total > request_num) {
  78905. + outstanding--;
  78906. + return;
  78907. + }
  78908. +
  78909. + if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {
  78910. + printk("crappo %p %p\n", sbufp, r);
  78911. + outstanding--;
  78912. + return;
  78913. + }
  78914. +
  78915. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  78916. + INIT_WORK(&r->work, ixp_request_wq);
  78917. +#else
  78918. + INIT_WORK(&r->work, ixp_request, r);
  78919. +#endif
  78920. + schedule_work(&r->work);
  78921. +}
  78922. +
  78923. +static void
  78924. +ixp_request(void *arg)
  78925. +{
  78926. + request_t *r = arg;
  78927. + IxCryptoAccStatus status;
  78928. +
  78929. + memset(&r->mbuf, 0, sizeof(r->mbuf));
  78930. + IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;
  78931. + IX_MBUF_MDATA(&r->mbuf) = r->buffer;
  78932. + IX_MBUF_PRIV(&r->mbuf) = r;
  78933. + status = ixCryptoAccAuthCryptPerform(ixp_ctx_id, &r->mbuf, NULL,
  78934. + 0, request_size, 0, request_size, request_size, r->buffer);
  78935. + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
  78936. + printk("status1 = %d\n", status);
  78937. + outstanding--;
  78938. + return;
  78939. + }
  78940. + return;
  78941. +}
  78942. +
  78943. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  78944. +static void
  78945. +ixp_request_wq(struct work_struct *work)
  78946. +{
  78947. + request_t *r = container_of(work, request_t, work);
  78948. + ixp_request(r);
  78949. +}
  78950. +#endif
  78951. +
  78952. +/*************************************************************************/
  78953. +#endif /* BENCH_IXP_ACCESS_LIB */
  78954. +/*************************************************************************/
  78955. +
  78956. +int
  78957. +ocfbench_init(void)
  78958. +{
  78959. + int i, jstart, jstop;
  78960. +
  78961. + printk("Crypto Speed tests\n");
  78962. +
  78963. + requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);
  78964. + if (!requests) {
  78965. + printk("malloc failed\n");
  78966. + return -EINVAL;
  78967. + }
  78968. +
  78969. + for (i = 0; i < request_q_len; i++) {
  78970. + /* +64 for return data */
  78971. + requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
  78972. + if (!requests[i].buffer) {
  78973. + printk("malloc failed\n");
  78974. + return -EINVAL;
  78975. + }
  78976. + memset(requests[i].buffer, '0' + i, request_size + 128);
  78977. + }
  78978. +
  78979. + /*
  78980. + * OCF benchmark
  78981. + */
  78982. + printk("OCF: testing ...\n");
  78983. + ocf_init();
  78984. + total = outstanding = 0;
  78985. + jstart = jiffies;
  78986. + for (i = 0; i < request_q_len; i++) {
  78987. + outstanding++;
  78988. + ocf_request(&requests[i]);
  78989. + }
  78990. + while (outstanding > 0)
  78991. + schedule();
  78992. + jstop = jiffies;
  78993. +
  78994. + printk("OCF: %d requests of %d bytes in %d jiffies\n", total, request_size,
  78995. + jstop - jstart);
  78996. +
  78997. +#ifdef BENCH_IXP_ACCESS_LIB
  78998. + /*
  78999. + * IXP benchmark
  79000. + */
  79001. + printk("IXP: testing ...\n");
  79002. + ixp_init();
  79003. + total = outstanding = 0;
  79004. + jstart = jiffies;
  79005. + for (i = 0; i < request_q_len; i++) {
  79006. + outstanding++;
  79007. + ixp_request(&requests[i]);
  79008. + }
  79009. + while (outstanding > 0)
  79010. + schedule();
  79011. + jstop = jiffies;
  79012. +
  79013. + printk("IXP: %d requests of %d bytes in %d jiffies\n", total, request_size,
  79014. + jstop - jstart);
  79015. +#endif /* BENCH_IXP_ACCESS_LIB */
  79016. +
  79017. + for (i = 0; i < request_q_len; i++)
  79018. + kfree(requests[i].buffer);
  79019. + kfree(requests);
  79020. + return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */
  79021. +}
  79022. +
  79023. +static void __exit ocfbench_exit(void)
  79024. +{
  79025. +}
  79026. +
  79027. +module_init(ocfbench_init);
  79028. +module_exit(ocfbench_exit);
  79029. +
  79030. +MODULE_LICENSE("BSD");
  79031. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  79032. +MODULE_DESCRIPTION("Benchmark various in-kernel crypto speeds");
  79033. diff -Nur linux-2.6.36.orig/crypto/ocf/ocf-compat.h linux-2.6.36/crypto/ocf/ocf-compat.h
  79034. --- linux-2.6.36.orig/crypto/ocf/ocf-compat.h 1970-01-01 01:00:00.000000000 +0100
  79035. +++ linux-2.6.36/crypto/ocf/ocf-compat.h 2010-11-09 20:28:12.422358492 +0100
  79036. @@ -0,0 +1,294 @@
  79037. +#ifndef _BSD_COMPAT_H_
  79038. +#define _BSD_COMPAT_H_ 1
  79039. +/****************************************************************************/
  79040. +/*
  79041. + * Provide compat routines for older linux kernels and BSD kernels
  79042. + *
  79043. + * Written by David McCullough <david_mccullough@mcafee.com>
  79044. + * Copyright (C) 2010 David McCullough <david_mccullough@mcafee.com>
  79045. + *
  79046. + * LICENSE TERMS
  79047. + *
  79048. + * The free distribution and use of this software in both source and binary
  79049. + * form is allowed (with or without changes) provided that:
  79050. + *
  79051. + * 1. distributions of this source code include the above copyright
  79052. + * notice, this list of conditions and the following disclaimer;
  79053. + *
  79054. + * 2. distributions in binary form include the above copyright
  79055. + * notice, this list of conditions and the following disclaimer
  79056. + * in the documentation and/or other associated materials;
  79057. + *
  79058. + * 3. the copyright holder's name is not used to endorse products
  79059. + * built using this software without specific written permission.
  79060. + *
  79061. + * ALTERNATIVELY, provided that this notice is retained in full, this file
  79062. + * may be distributed under the terms of the GNU General Public License (GPL),
  79063. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  79064. + *
  79065. + * DISCLAIMER
  79066. + *
  79067. + * This software is provided 'as is' with no explicit or implied warranties
  79068. + * in respect of its properties, including, but not limited to, correctness
  79069. + * and/or fitness for purpose.
  79070. + */
  79071. +/****************************************************************************/
  79072. +#ifdef __KERNEL__
  79073. +/*
  79074. + * fake some BSD driver interface stuff specifically for OCF use
  79075. + */
  79076. +
  79077. +typedef struct ocf_device *device_t;
  79078. +
  79079. +typedef struct {
  79080. + int (*cryptodev_newsession)(device_t dev, u_int32_t *sidp, struct cryptoini *cri);
  79081. + int (*cryptodev_freesession)(device_t dev, u_int64_t tid);
  79082. + int (*cryptodev_process)(device_t dev, struct cryptop *crp, int hint);
  79083. + int (*cryptodev_kprocess)(device_t dev, struct cryptkop *krp, int hint);
  79084. +} device_method_t;
  79085. +#define DEVMETHOD(id, func) id: func
  79086. +
  79087. +struct ocf_device {
  79088. + char name[32]; /* the driver name */
  79089. + char nameunit[32]; /* the driver name + HW instance */
  79090. + int unit;
  79091. + device_method_t methods;
  79092. + void *softc;
  79093. +};
  79094. +
  79095. +#define CRYPTODEV_NEWSESSION(dev, sid, cri) \
  79096. + ((*(dev)->methods.cryptodev_newsession)(dev,sid,cri))
  79097. +#define CRYPTODEV_FREESESSION(dev, sid) \
  79098. + ((*(dev)->methods.cryptodev_freesession)(dev, sid))
  79099. +#define CRYPTODEV_PROCESS(dev, crp, hint) \
  79100. + ((*(dev)->methods.cryptodev_process)(dev, crp, hint))
  79101. +#define CRYPTODEV_KPROCESS(dev, krp, hint) \
  79102. + ((*(dev)->methods.cryptodev_kprocess)(dev, krp, hint))
  79103. +
  79104. +#define device_get_name(dev) ((dev)->name)
  79105. +#define device_get_nameunit(dev) ((dev)->nameunit)
  79106. +#define device_get_unit(dev) ((dev)->unit)
  79107. +#define device_get_softc(dev) ((dev)->softc)
  79108. +
  79109. +#define softc_device_decl \
  79110. + struct ocf_device _device; \
  79111. + device_t
  79112. +
  79113. +#define softc_device_init(_sc, _name, _unit, _methods) \
  79114. + if (1) {\
  79115. + strncpy((_sc)->_device.name, _name, sizeof((_sc)->_device.name) - 1); \
  79116. + snprintf((_sc)->_device.nameunit, sizeof((_sc)->_device.name), "%s%d", _name, _unit); \
  79117. + (_sc)->_device.unit = _unit; \
  79118. + (_sc)->_device.methods = _methods; \
  79119. + (_sc)->_device.softc = (void *) _sc; \
  79120. + *(device_t *)((softc_get_device(_sc))+1) = &(_sc)->_device; \
  79121. + } else
  79122. +
  79123. +#define softc_get_device(_sc) (&(_sc)->_device)
  79124. +
  79125. +/*
  79126. + * iomem support for 2.4 and 2.6 kernels
  79127. + */
  79128. +#include <linux/version.h>
  79129. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  79130. +#define ocf_iomem_t unsigned long
  79131. +
  79132. +/*
  79133. + * implement simple workqueue like support for older kernels
  79134. + */
  79135. +
  79136. +#include <linux/tqueue.h>
  79137. +
  79138. +#define work_struct tq_struct
  79139. +
  79140. +#define INIT_WORK(wp, fp, ap) \
  79141. + do { \
  79142. + (wp)->sync = 0; \
  79143. + (wp)->routine = (fp); \
  79144. + (wp)->data = (ap); \
  79145. + } while (0)
  79146. +
  79147. +#define schedule_work(wp) \
  79148. + do { \
  79149. + queue_task((wp), &tq_immediate); \
  79150. + mark_bh(IMMEDIATE_BH); \
  79151. + } while (0)
  79152. +
  79153. +#define flush_scheduled_work() run_task_queue(&tq_immediate)
  79154. +
  79155. +#else
  79156. +#define ocf_iomem_t void __iomem *
  79157. +
  79158. +#include <linux/workqueue.h>
  79159. +
  79160. +#endif
  79161. +
  79162. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
  79163. +#include <linux/fdtable.h>
  79164. +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
  79165. +#define files_fdtable(files) (files)
  79166. +#endif
  79167. +
  79168. +#ifdef MODULE_PARM
  79169. +#undef module_param /* just in case */
  79170. +#define module_param(a,b,c) MODULE_PARM(a,"i")
  79171. +#endif
  79172. +
  79173. +#define bzero(s,l) memset(s,0,l)
  79174. +#define bcopy(s,d,l) memcpy(d,s,l)
  79175. +#define bcmp(x, y, l) memcmp(x,y,l)
  79176. +
  79177. +#define MIN(x,y) ((x) < (y) ? (x) : (y))
  79178. +
  79179. +#define device_printf(dev, a...) ({ \
  79180. + printk("%s: ", device_get_nameunit(dev)); printk(a); \
  79181. + })
  79182. +
  79183. +#undef printf
  79184. +#define printf(fmt...) printk(fmt)
  79185. +
  79186. +#define KASSERT(c,p) if (!(c)) { printk p ; } else
  79187. +
  79188. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  79189. +#define ocf_daemonize(str) \
  79190. + daemonize(); \
  79191. + spin_lock_irq(&current->sigmask_lock); \
  79192. + sigemptyset(&current->blocked); \
  79193. + recalc_sigpending(current); \
  79194. + spin_unlock_irq(&current->sigmask_lock); \
  79195. + sprintf(current->comm, str);
  79196. +#else
  79197. +#define ocf_daemonize(str) daemonize(str);
  79198. +#endif
  79199. +
  79200. +#define TAILQ_INSERT_TAIL(q,d,m) list_add_tail(&(d)->m, (q))
  79201. +#define TAILQ_EMPTY(q) list_empty(q)
  79202. +#define TAILQ_FOREACH(v, q, m) list_for_each_entry(v, q, m)
  79203. +
  79204. +#define read_random(p,l) get_random_bytes(p,l)
  79205. +
  79206. +#define DELAY(x) ((x) > 2000 ? mdelay((x)/1000) : udelay(x))
  79207. +#define strtoul simple_strtoul
  79208. +
  79209. +#define pci_get_vendor(dev) ((dev)->vendor)
  79210. +#define pci_get_device(dev) ((dev)->device)
  79211. +
  79212. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  79213. +#define pci_set_consistent_dma_mask(dev, mask) (0)
  79214. +#endif
  79215. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
  79216. +#define pci_dma_sync_single_for_cpu pci_dma_sync_single
  79217. +#endif
  79218. +
  79219. +#ifndef DMA_32BIT_MASK
  79220. +#define DMA_32BIT_MASK 0x00000000ffffffffULL
  79221. +#endif
  79222. +
  79223. +#ifndef htole32
  79224. +#define htole32(x) cpu_to_le32(x)
  79225. +#endif
  79226. +#ifndef htobe32
  79227. +#define htobe32(x) cpu_to_be32(x)
  79228. +#endif
  79229. +#ifndef htole16
  79230. +#define htole16(x) cpu_to_le16(x)
  79231. +#endif
  79232. +#ifndef htobe16
  79233. +#define htobe16(x) cpu_to_be16(x)
  79234. +#endif
  79235. +
  79236. +/* older kernels don't have these */
  79237. +
  79238. +#include <asm/irq.h>
  79239. +#if !defined(IRQ_NONE) && !defined(IRQ_RETVAL)
  79240. +#define IRQ_NONE
  79241. +#define IRQ_HANDLED
  79242. +#define IRQ_WAKE_THREAD
  79243. +#define IRQ_RETVAL
  79244. +#define irqreturn_t void
  79245. +typedef irqreturn_t (*irq_handler_t)(int irq, void *arg, struct pt_regs *regs);
  79246. +#endif
  79247. +#ifndef IRQF_SHARED
  79248. +#define IRQF_SHARED SA_SHIRQ
  79249. +#endif
  79250. +
  79251. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  79252. +# define strlcpy(dest,src,len) \
  79253. + ({strncpy(dest,src,(len)-1); ((char *)dest)[(len)-1] = '\0'; })
  79254. +#endif
  79255. +
  79256. +#ifndef MAX_ERRNO
  79257. +#define MAX_ERRNO 4095
  79258. +#endif
  79259. +#ifndef IS_ERR_VALUE
  79260. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,5)
  79261. +#include <linux/err.h>
  79262. +#endif
  79263. +#ifndef IS_ERR_VALUE
  79264. +#define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-MAX_ERRNO)
  79265. +#endif
  79266. +#endif
  79267. +
  79268. +/*
  79269. + * common debug for all
  79270. + */
  79271. +#if 1
  79272. +#define dprintk(a...) do { if (debug) printk(a); } while(0)
  79273. +#else
  79274. +#define dprintk(a...)
  79275. +#endif
  79276. +
  79277. +#ifndef SLAB_ATOMIC
  79278. +/* Changed in 2.6.20, must use GFP_ATOMIC now */
  79279. +#define SLAB_ATOMIC GFP_ATOMIC
  79280. +#endif
  79281. +
  79282. +/*
  79283. + * need some additional support for older kernels */
  79284. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,2)
  79285. +#define pci_register_driver_compat(driver, rc) \
  79286. + do { \
  79287. + if ((rc) > 0) { \
  79288. + (rc) = 0; \
  79289. + } else if (rc == 0) { \
  79290. + (rc) = -ENODEV; \
  79291. + } else { \
  79292. + pci_unregister_driver(driver); \
  79293. + } \
  79294. + } while (0)
  79295. +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
  79296. +#define pci_register_driver_compat(driver,rc) ((rc) = (rc) < 0 ? (rc) : 0)
  79297. +#else
  79298. +#define pci_register_driver_compat(driver,rc)
  79299. +#endif
  79300. +
  79301. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
  79302. +
  79303. +#include <linux/mm.h>
  79304. +#include <asm/scatterlist.h>
  79305. +
  79306. +static inline void sg_set_page(struct scatterlist *sg, struct page *page,
  79307. + unsigned int len, unsigned int offset)
  79308. +{
  79309. + sg->page = page;
  79310. + sg->offset = offset;
  79311. + sg->length = len;
  79312. +}
  79313. +
  79314. +static inline void *sg_virt(struct scatterlist *sg)
  79315. +{
  79316. + return page_address(sg->page) + sg->offset;
  79317. +}
  79318. +
  79319. +#define sg_init_table(sg, n)
  79320. +
  79321. +#endif
  79322. +
  79323. +#ifndef late_initcall
  79324. +#define late_initcall(init) module_init(init)
  79325. +#endif
  79326. +
  79327. +#endif /* __KERNEL__ */
  79328. +
  79329. +/****************************************************************************/
  79330. +#endif /* _BSD_COMPAT_H_ */
  79331. diff -Nur linux-2.6.36.orig/crypto/ocf/ocfnull/Makefile linux-2.6.36/crypto/ocf/ocfnull/Makefile
  79332. --- linux-2.6.36.orig/crypto/ocf/ocfnull/Makefile 1970-01-01 01:00:00.000000000 +0100
  79333. +++ linux-2.6.36/crypto/ocf/ocfnull/Makefile 2010-11-09 20:28:12.462495574 +0100
  79334. @@ -0,0 +1,12 @@
  79335. +# for SGlinux builds
  79336. +-include $(ROOTDIR)/modules/.config
  79337. +
  79338. +obj-$(CONFIG_OCF_OCFNULL) += ocfnull.o
  79339. +
  79340. +obj ?= .
  79341. +EXTRA_CFLAGS += -I$(obj)/..
  79342. +
  79343. +ifdef TOPDIR
  79344. +-include $(TOPDIR)/Rules.make
  79345. +endif
  79346. +
  79347. diff -Nur linux-2.6.36.orig/crypto/ocf/ocfnull/ocfnull.c linux-2.6.36/crypto/ocf/ocfnull/ocfnull.c
  79348. --- linux-2.6.36.orig/crypto/ocf/ocfnull/ocfnull.c 1970-01-01 01:00:00.000000000 +0100
  79349. +++ linux-2.6.36/crypto/ocf/ocfnull/ocfnull.c 2010-11-09 20:28:12.501251038 +0100
  79350. @@ -0,0 +1,203 @@
  79351. +/*
  79352. + * An OCF module for determining the cost of crypto versus the cost of
  79353. + * IPSec processing outside of OCF. This modules gives us the effect of
  79354. + * zero cost encryption, of course you will need to run it at both ends
  79355. + * since it does no crypto at all.
  79356. + *
  79357. + * Written by David McCullough <david_mccullough@mcafee.com>
  79358. + * Copyright (C) 2006-2010 David McCullough
  79359. + *
  79360. + * LICENSE TERMS
  79361. + *
  79362. + * The free distribution and use of this software in both source and binary
  79363. + * form is allowed (with or without changes) provided that:
  79364. + *
  79365. + * 1. distributions of this source code include the above copyright
  79366. + * notice, this list of conditions and the following disclaimer;
  79367. + *
  79368. + * 2. distributions in binary form include the above copyright
  79369. + * notice, this list of conditions and the following disclaimer
  79370. + * in the documentation and/or other associated materials;
  79371. + *
  79372. + * 3. the copyright holder's name is not used to endorse products
  79373. + * built using this software without specific written permission.
  79374. + *
  79375. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  79376. + * may be distributed under the terms of the GNU General Public License (GPL),
  79377. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  79378. + *
  79379. + * DISCLAIMER
  79380. + *
  79381. + * This software is provided 'as is' with no explicit or implied warranties
  79382. + * in respect of its properties, including, but not limited to, correctness
  79383. + * and/or fitness for purpose.
  79384. + */
  79385. +
  79386. +#ifndef AUTOCONF_INCLUDED
  79387. +#include <linux/config.h>
  79388. +#endif
  79389. +#include <linux/module.h>
  79390. +#include <linux/init.h>
  79391. +#include <linux/list.h>
  79392. +#include <linux/slab.h>
  79393. +#include <linux/sched.h>
  79394. +#include <linux/wait.h>
  79395. +#include <linux/crypto.h>
  79396. +#include <linux/interrupt.h>
  79397. +
  79398. +#include <cryptodev.h>
  79399. +#include <uio.h>
  79400. +
  79401. +static int32_t null_id = -1;
  79402. +static u_int32_t null_sesnum = 0;
  79403. +
  79404. +static int null_process(device_t, struct cryptop *, int);
  79405. +static int null_newsession(device_t, u_int32_t *, struct cryptoini *);
  79406. +static int null_freesession(device_t, u_int64_t);
  79407. +
  79408. +#define debug ocfnull_debug
  79409. +int ocfnull_debug = 0;
  79410. +module_param(ocfnull_debug, int, 0644);
  79411. +MODULE_PARM_DESC(ocfnull_debug, "Enable debug");
  79412. +
  79413. +/*
  79414. + * dummy device structure
  79415. + */
  79416. +
  79417. +static struct {
  79418. + softc_device_decl sc_dev;
  79419. +} nulldev;
  79420. +
  79421. +static device_method_t null_methods = {
  79422. + /* crypto device methods */
  79423. + DEVMETHOD(cryptodev_newsession, null_newsession),
  79424. + DEVMETHOD(cryptodev_freesession,null_freesession),
  79425. + DEVMETHOD(cryptodev_process, null_process),
  79426. +};
  79427. +
  79428. +/*
  79429. + * Generate a new software session.
  79430. + */
  79431. +static int
  79432. +null_newsession(device_t arg, u_int32_t *sid, struct cryptoini *cri)
  79433. +{
  79434. + dprintk("%s()\n", __FUNCTION__);
  79435. + if (sid == NULL || cri == NULL) {
  79436. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  79437. + return EINVAL;
  79438. + }
  79439. +
  79440. + if (null_sesnum == 0)
  79441. + null_sesnum++;
  79442. + *sid = null_sesnum++;
  79443. + return 0;
  79444. +}
  79445. +
  79446. +
  79447. +/*
  79448. + * Free a session.
  79449. + */
  79450. +static int
  79451. +null_freesession(device_t arg, u_int64_t tid)
  79452. +{
  79453. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  79454. +
  79455. + dprintk("%s()\n", __FUNCTION__);
  79456. + if (sid > null_sesnum) {
  79457. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  79458. + return EINVAL;
  79459. + }
  79460. +
  79461. + /* Silently accept and return */
  79462. + if (sid == 0)
  79463. + return 0;
  79464. + return 0;
  79465. +}
  79466. +
  79467. +
  79468. +/*
  79469. + * Process a request.
  79470. + */
  79471. +static int
  79472. +null_process(device_t arg, struct cryptop *crp, int hint)
  79473. +{
  79474. + unsigned int lid;
  79475. +
  79476. + dprintk("%s()\n", __FUNCTION__);
  79477. +
  79478. + /* Sanity check */
  79479. + if (crp == NULL) {
  79480. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  79481. + return EINVAL;
  79482. + }
  79483. +
  79484. + crp->crp_etype = 0;
  79485. +
  79486. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  79487. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  79488. + crp->crp_etype = EINVAL;
  79489. + goto done;
  79490. + }
  79491. +
  79492. + /*
  79493. + * find the session we are using
  79494. + */
  79495. +
  79496. + lid = crp->crp_sid & 0xffffffff;
  79497. + if (lid >= null_sesnum || lid == 0) {
  79498. + crp->crp_etype = ENOENT;
  79499. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  79500. + goto done;
  79501. + }
  79502. +
  79503. +done:
  79504. + crypto_done(crp);
  79505. + return 0;
  79506. +}
  79507. +
  79508. +
  79509. +/*
  79510. + * our driver startup and shutdown routines
  79511. + */
  79512. +
  79513. +static int
  79514. +null_init(void)
  79515. +{
  79516. + dprintk("%s(%p)\n", __FUNCTION__, null_init);
  79517. +
  79518. + memset(&nulldev, 0, sizeof(nulldev));
  79519. + softc_device_init(&nulldev, "ocfnull", 0, null_methods);
  79520. +
  79521. + null_id = crypto_get_driverid(softc_get_device(&nulldev),
  79522. + CRYPTOCAP_F_HARDWARE);
  79523. + if (null_id < 0)
  79524. + panic("ocfnull: crypto device cannot initialize!");
  79525. +
  79526. +#define REGISTER(alg) \
  79527. + crypto_register(null_id,alg,0,0)
  79528. + REGISTER(CRYPTO_DES_CBC);
  79529. + REGISTER(CRYPTO_3DES_CBC);
  79530. + REGISTER(CRYPTO_RIJNDAEL128_CBC);
  79531. + REGISTER(CRYPTO_MD5);
  79532. + REGISTER(CRYPTO_SHA1);
  79533. + REGISTER(CRYPTO_MD5_HMAC);
  79534. + REGISTER(CRYPTO_SHA1_HMAC);
  79535. +#undef REGISTER
  79536. +
  79537. + return 0;
  79538. +}
  79539. +
  79540. +static void
  79541. +null_exit(void)
  79542. +{
  79543. + dprintk("%s()\n", __FUNCTION__);
  79544. + crypto_unregister_all(null_id);
  79545. + null_id = -1;
  79546. +}
  79547. +
  79548. +module_init(null_init);
  79549. +module_exit(null_exit);
  79550. +
  79551. +MODULE_LICENSE("Dual BSD/GPL");
  79552. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  79553. +MODULE_DESCRIPTION("ocfnull - claims a lot but does nothing");
  79554. diff -Nur linux-2.6.36.orig/crypto/ocf/pasemi/Makefile linux-2.6.36/crypto/ocf/pasemi/Makefile
  79555. --- linux-2.6.36.orig/crypto/ocf/pasemi/Makefile 1970-01-01 01:00:00.000000000 +0100
  79556. +++ linux-2.6.36/crypto/ocf/pasemi/Makefile 2010-11-09 20:28:12.532495480 +0100
  79557. @@ -0,0 +1,12 @@
  79558. +# for SGlinux builds
  79559. +-include $(ROOTDIR)/modules/.config
  79560. +
  79561. +obj-$(CONFIG_OCF_PASEMI) += pasemi.o
  79562. +
  79563. +obj ?= .
  79564. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  79565. +
  79566. +ifdef TOPDIR
  79567. +-include $(TOPDIR)/Rules.make
  79568. +endif
  79569. +
  79570. diff -Nur linux-2.6.36.orig/crypto/ocf/pasemi/pasemi.c linux-2.6.36/crypto/ocf/pasemi/pasemi.c
  79571. --- linux-2.6.36.orig/crypto/ocf/pasemi/pasemi.c 1970-01-01 01:00:00.000000000 +0100
  79572. +++ linux-2.6.36/crypto/ocf/pasemi/pasemi.c 2010-11-09 20:28:12.572495531 +0100
  79573. @@ -0,0 +1,1009 @@
  79574. +/*
  79575. + * Copyright (C) 2007 PA Semi, Inc
  79576. + *
  79577. + * Driver for the PA Semi PWRficient DMA Crypto Engine
  79578. + *
  79579. + * This program is free software; you can redistribute it and/or modify
  79580. + * it under the terms of the GNU General Public License version 2 as
  79581. + * published by the Free Software Foundation.
  79582. + *
  79583. + * This program is distributed in the hope that it will be useful,
  79584. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  79585. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  79586. + * GNU General Public License for more details.
  79587. + *
  79588. + * You should have received a copy of the GNU General Public License
  79589. + * along with this program; if not, write to the Free Software
  79590. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  79591. + */
  79592. +
  79593. +#ifndef AUTOCONF_INCLUDED
  79594. +#include <linux/config.h>
  79595. +#endif
  79596. +#include <linux/module.h>
  79597. +#include <linux/init.h>
  79598. +#include <linux/interrupt.h>
  79599. +#include <linux/timer.h>
  79600. +#include <linux/random.h>
  79601. +#include <linux/skbuff.h>
  79602. +#include <asm/scatterlist.h>
  79603. +#include <linux/moduleparam.h>
  79604. +#include <linux/pci.h>
  79605. +#include <cryptodev.h>
  79606. +#include <uio.h>
  79607. +#include "pasemi_fnu.h"
  79608. +
  79609. +#define DRV_NAME "pasemi"
  79610. +
  79611. +#define TIMER_INTERVAL 1000
  79612. +
  79613. +static void __devexit pasemi_dma_remove(struct pci_dev *pdev);
  79614. +static struct pasdma_status volatile * dma_status;
  79615. +
  79616. +static int debug;
  79617. +module_param(debug, int, 0644);
  79618. +MODULE_PARM_DESC(debug, "Enable debug");
  79619. +
  79620. +static void pasemi_desc_start(struct pasemi_desc *desc, u64 hdr)
  79621. +{
  79622. + desc->postop = 0;
  79623. + desc->quad[0] = hdr;
  79624. + desc->quad_cnt = 1;
  79625. + desc->size = 1;
  79626. +}
  79627. +
  79628. +static void pasemi_desc_build(struct pasemi_desc *desc, u64 val)
  79629. +{
  79630. + desc->quad[desc->quad_cnt++] = val;
  79631. + desc->size = (desc->quad_cnt + 1) / 2;
  79632. +}
  79633. +
  79634. +static void pasemi_desc_hdr(struct pasemi_desc *desc, u64 hdr)
  79635. +{
  79636. + desc->quad[0] |= hdr;
  79637. +}
  79638. +
  79639. +static int pasemi_desc_size(struct pasemi_desc *desc)
  79640. +{
  79641. + return desc->size;
  79642. +}
  79643. +
  79644. +static void pasemi_ring_add_desc(
  79645. + struct pasemi_fnu_txring *ring,
  79646. + struct pasemi_desc *desc,
  79647. + struct cryptop *crp) {
  79648. + int i;
  79649. + int ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
  79650. +
  79651. + TX_DESC_INFO(ring, ring->next_to_fill).desc_size = desc->size;
  79652. + TX_DESC_INFO(ring, ring->next_to_fill).desc_postop = desc->postop;
  79653. + TX_DESC_INFO(ring, ring->next_to_fill).cf_crp = crp;
  79654. +
  79655. + for (i = 0; i < desc->quad_cnt; i += 2) {
  79656. + ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
  79657. + ring->desc[ring_index] = desc->quad[i];
  79658. + ring->desc[ring_index + 1] = desc->quad[i + 1];
  79659. + ring->next_to_fill++;
  79660. + }
  79661. +
  79662. + if (desc->quad_cnt & 1)
  79663. + ring->desc[ring_index + 1] = 0;
  79664. +}
  79665. +
  79666. +static void pasemi_ring_incr(struct pasemi_softc *sc, int chan_index, int incr)
  79667. +{
  79668. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_INCR(sc->base_chan + chan_index),
  79669. + incr);
  79670. +}
  79671. +
  79672. +/*
  79673. + * Generate a new software session.
  79674. + */
  79675. +static int
  79676. +pasemi_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  79677. +{
  79678. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  79679. + struct pasemi_softc *sc = device_get_softc(dev);
  79680. + struct pasemi_session *ses = NULL, **sespp;
  79681. + int sesn, blksz = 0;
  79682. + u64 ccmd = 0;
  79683. + unsigned long flags;
  79684. + struct pasemi_desc init_desc;
  79685. + struct pasemi_fnu_txring *txring;
  79686. +
  79687. + DPRINTF("%s()\n", __FUNCTION__);
  79688. + if (sidp == NULL || cri == NULL || sc == NULL) {
  79689. + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
  79690. + return -EINVAL;
  79691. + }
  79692. + for (c = cri; c != NULL; c = c->cri_next) {
  79693. + if (ALG_IS_SIG(c->cri_alg)) {
  79694. + if (macini)
  79695. + return -EINVAL;
  79696. + macini = c;
  79697. + } else if (ALG_IS_CIPHER(c->cri_alg)) {
  79698. + if (encini)
  79699. + return -EINVAL;
  79700. + encini = c;
  79701. + } else {
  79702. + DPRINTF("UNKNOWN c->cri_alg %d\n", c->cri_alg);
  79703. + return -EINVAL;
  79704. + }
  79705. + }
  79706. + if (encini == NULL && macini == NULL)
  79707. + return -EINVAL;
  79708. + if (encini) {
  79709. + /* validate key length */
  79710. + switch (encini->cri_alg) {
  79711. + case CRYPTO_DES_CBC:
  79712. + if (encini->cri_klen != 64)
  79713. + return -EINVAL;
  79714. + ccmd = DMA_CALGO_DES;
  79715. + break;
  79716. + case CRYPTO_3DES_CBC:
  79717. + if (encini->cri_klen != 192)
  79718. + return -EINVAL;
  79719. + ccmd = DMA_CALGO_3DES;
  79720. + break;
  79721. + case CRYPTO_AES_CBC:
  79722. + if (encini->cri_klen != 128 &&
  79723. + encini->cri_klen != 192 &&
  79724. + encini->cri_klen != 256)
  79725. + return -EINVAL;
  79726. + ccmd = DMA_CALGO_AES;
  79727. + break;
  79728. + case CRYPTO_ARC4:
  79729. + if (encini->cri_klen != 128)
  79730. + return -EINVAL;
  79731. + ccmd = DMA_CALGO_ARC;
  79732. + break;
  79733. + default:
  79734. + DPRINTF("UNKNOWN encini->cri_alg %d\n",
  79735. + encini->cri_alg);
  79736. + return -EINVAL;
  79737. + }
  79738. + }
  79739. +
  79740. + if (macini) {
  79741. + switch (macini->cri_alg) {
  79742. + case CRYPTO_MD5:
  79743. + case CRYPTO_MD5_HMAC:
  79744. + blksz = 16;
  79745. + break;
  79746. + case CRYPTO_SHA1:
  79747. + case CRYPTO_SHA1_HMAC:
  79748. + blksz = 20;
  79749. + break;
  79750. + default:
  79751. + DPRINTF("UNKNOWN macini->cri_alg %d\n",
  79752. + macini->cri_alg);
  79753. + return -EINVAL;
  79754. + }
  79755. + if (((macini->cri_klen + 7) / 8) > blksz) {
  79756. + DPRINTF("key length %d bigger than blksize %d not supported\n",
  79757. + ((macini->cri_klen + 7) / 8), blksz);
  79758. + return -EINVAL;
  79759. + }
  79760. + }
  79761. +
  79762. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  79763. + if (sc->sc_sessions[sesn] == NULL) {
  79764. + sc->sc_sessions[sesn] = (struct pasemi_session *)
  79765. + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
  79766. + ses = sc->sc_sessions[sesn];
  79767. + break;
  79768. + } else if (sc->sc_sessions[sesn]->used == 0) {
  79769. + ses = sc->sc_sessions[sesn];
  79770. + break;
  79771. + }
  79772. + }
  79773. +
  79774. + if (ses == NULL) {
  79775. + sespp = (struct pasemi_session **)
  79776. + kzalloc(sc->sc_nsessions * 2 *
  79777. + sizeof(struct pasemi_session *), GFP_ATOMIC);
  79778. + if (sespp == NULL)
  79779. + return -ENOMEM;
  79780. + memcpy(sespp, sc->sc_sessions,
  79781. + sc->sc_nsessions * sizeof(struct pasemi_session *));
  79782. + kfree(sc->sc_sessions);
  79783. + sc->sc_sessions = sespp;
  79784. + sesn = sc->sc_nsessions;
  79785. + ses = sc->sc_sessions[sesn] = (struct pasemi_session *)
  79786. + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
  79787. + if (ses == NULL)
  79788. + return -ENOMEM;
  79789. + sc->sc_nsessions *= 2;
  79790. + }
  79791. +
  79792. + ses->used = 1;
  79793. +
  79794. + ses->dma_addr = pci_map_single(sc->dma_pdev, (void *) ses->civ,
  79795. + sizeof(struct pasemi_session), DMA_TO_DEVICE);
  79796. +
  79797. + /* enter the channel scheduler */
  79798. + spin_lock_irqsave(&sc->sc_chnlock, flags);
  79799. +
  79800. + /* ARC4 has to be processed by the even channel */
  79801. + if (encini && (encini->cri_alg == CRYPTO_ARC4))
  79802. + ses->chan = sc->sc_lastchn & ~1;
  79803. + else
  79804. + ses->chan = sc->sc_lastchn;
  79805. + sc->sc_lastchn = (sc->sc_lastchn + 1) % sc->sc_num_channels;
  79806. +
  79807. + spin_unlock_irqrestore(&sc->sc_chnlock, flags);
  79808. +
  79809. + txring = &sc->tx[ses->chan];
  79810. +
  79811. + if (encini) {
  79812. + ses->ccmd = ccmd;
  79813. +
  79814. + /* get an IV */
  79815. + /* XXX may read fewer than requested */
  79816. + get_random_bytes(ses->civ, sizeof(ses->civ));
  79817. +
  79818. + ses->keysz = (encini->cri_klen - 63) / 64;
  79819. + memcpy(ses->key, encini->cri_key, (ses->keysz + 1) * 8);
  79820. +
  79821. + pasemi_desc_start(&init_desc,
  79822. + XCT_CTRL_HDR(ses->chan, (encini && macini) ? 0x68 : 0x40, DMA_FN_CIV0));
  79823. + pasemi_desc_build(&init_desc,
  79824. + XCT_FUN_SRC_PTR((encini && macini) ? 0x68 : 0x40, ses->dma_addr));
  79825. + }
  79826. + if (macini) {
  79827. + if (macini->cri_alg == CRYPTO_MD5_HMAC ||
  79828. + macini->cri_alg == CRYPTO_SHA1_HMAC)
  79829. + memcpy(ses->hkey, macini->cri_key, blksz);
  79830. + else {
  79831. + /* Load initialization constants(RFC 1321, 3174) */
  79832. + ses->hiv[0] = 0x67452301efcdab89ULL;
  79833. + ses->hiv[1] = 0x98badcfe10325476ULL;
  79834. + ses->hiv[2] = 0xc3d2e1f000000000ULL;
  79835. + }
  79836. + ses->hseq = 0ULL;
  79837. + }
  79838. +
  79839. + spin_lock_irqsave(&txring->fill_lock, flags);
  79840. +
  79841. + if (((txring->next_to_fill + pasemi_desc_size(&init_desc)) -
  79842. + txring->next_to_clean) > TX_RING_SIZE) {
  79843. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  79844. + return ERESTART;
  79845. + }
  79846. +
  79847. + if (encini) {
  79848. + pasemi_ring_add_desc(txring, &init_desc, NULL);
  79849. + pasemi_ring_incr(sc, ses->chan,
  79850. + pasemi_desc_size(&init_desc));
  79851. + }
  79852. +
  79853. + txring->sesn = sesn;
  79854. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  79855. +
  79856. + *sidp = PASEMI_SID(sesn);
  79857. + return 0;
  79858. +}
  79859. +
  79860. +/*
  79861. + * Deallocate a session.
  79862. + */
  79863. +static int
  79864. +pasemi_freesession(device_t dev, u_int64_t tid)
  79865. +{
  79866. + struct pasemi_softc *sc = device_get_softc(dev);
  79867. + int session;
  79868. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  79869. +
  79870. + DPRINTF("%s()\n", __FUNCTION__);
  79871. +
  79872. + if (sc == NULL)
  79873. + return -EINVAL;
  79874. + session = PASEMI_SESSION(sid);
  79875. + if (session >= sc->sc_nsessions || !sc->sc_sessions[session])
  79876. + return -EINVAL;
  79877. +
  79878. + pci_unmap_single(sc->dma_pdev,
  79879. + sc->sc_sessions[session]->dma_addr,
  79880. + sizeof(struct pasemi_session), DMA_TO_DEVICE);
  79881. + memset(sc->sc_sessions[session], 0,
  79882. + sizeof(struct pasemi_session));
  79883. +
  79884. + return 0;
  79885. +}
  79886. +
  79887. +static int
  79888. +pasemi_process(device_t dev, struct cryptop *crp, int hint)
  79889. +{
  79890. +
  79891. + int err = 0, ivsize, srclen = 0, reinit = 0, reinit_size = 0, chsel;
  79892. + struct pasemi_softc *sc = device_get_softc(dev);
  79893. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  79894. + caddr_t ivp;
  79895. + struct pasemi_desc init_desc, work_desc;
  79896. + struct pasemi_session *ses;
  79897. + struct sk_buff *skb;
  79898. + struct uio *uiop;
  79899. + unsigned long flags;
  79900. + struct pasemi_fnu_txring *txring;
  79901. +
  79902. + DPRINTF("%s()\n", __FUNCTION__);
  79903. +
  79904. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL)
  79905. + return -EINVAL;
  79906. +
  79907. + crp->crp_etype = 0;
  79908. + if (PASEMI_SESSION(crp->crp_sid) >= sc->sc_nsessions)
  79909. + return -EINVAL;
  79910. +
  79911. + ses = sc->sc_sessions[PASEMI_SESSION(crp->crp_sid)];
  79912. +
  79913. + crd1 = crp->crp_desc;
  79914. + if (crd1 == NULL) {
  79915. + err = -EINVAL;
  79916. + goto errout;
  79917. + }
  79918. + crd2 = crd1->crd_next;
  79919. +
  79920. + if (ALG_IS_SIG(crd1->crd_alg)) {
  79921. + maccrd = crd1;
  79922. + if (crd2 == NULL)
  79923. + enccrd = NULL;
  79924. + else if (ALG_IS_CIPHER(crd2->crd_alg) &&
  79925. + (crd2->crd_flags & CRD_F_ENCRYPT) == 0)
  79926. + enccrd = crd2;
  79927. + else
  79928. + goto erralg;
  79929. + } else if (ALG_IS_CIPHER(crd1->crd_alg)) {
  79930. + enccrd = crd1;
  79931. + if (crd2 == NULL)
  79932. + maccrd = NULL;
  79933. + else if (ALG_IS_SIG(crd2->crd_alg) &&
  79934. + (crd1->crd_flags & CRD_F_ENCRYPT))
  79935. + maccrd = crd2;
  79936. + else
  79937. + goto erralg;
  79938. + } else
  79939. + goto erralg;
  79940. +
  79941. + chsel = ses->chan;
  79942. +
  79943. + txring = &sc->tx[chsel];
  79944. +
  79945. + if (enccrd && !maccrd) {
  79946. + if (enccrd->crd_alg == CRYPTO_ARC4)
  79947. + reinit = 1;
  79948. + reinit_size = 0x40;
  79949. + srclen = crp->crp_ilen;
  79950. +
  79951. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I
  79952. + | XCT_FUN_FUN(chsel));
  79953. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  79954. + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_ENC);
  79955. + else
  79956. + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_DEC);
  79957. + } else if (enccrd && maccrd) {
  79958. + if (enccrd->crd_alg == CRYPTO_ARC4)
  79959. + reinit = 1;
  79960. + reinit_size = 0x68;
  79961. +
  79962. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  79963. + /* Encrypt -> Authenticate */
  79964. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_ENC_SIG
  79965. + | XCT_FUN_A | XCT_FUN_FUN(chsel));
  79966. + srclen = maccrd->crd_skip + maccrd->crd_len;
  79967. + } else {
  79968. + /* Authenticate -> Decrypt */
  79969. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG_DEC
  79970. + | XCT_FUN_24BRES | XCT_FUN_FUN(chsel));
  79971. + pasemi_desc_build(&work_desc, 0);
  79972. + pasemi_desc_build(&work_desc, 0);
  79973. + pasemi_desc_build(&work_desc, 0);
  79974. + work_desc.postop = PASEMI_CHECK_SIG;
  79975. + srclen = crp->crp_ilen;
  79976. + }
  79977. +
  79978. + pasemi_desc_hdr(&work_desc, XCT_FUN_SHL(maccrd->crd_skip / 4));
  79979. + pasemi_desc_hdr(&work_desc, XCT_FUN_CHL(enccrd->crd_skip - maccrd->crd_skip));
  79980. + } else if (!enccrd && maccrd) {
  79981. + srclen = maccrd->crd_len;
  79982. +
  79983. + pasemi_desc_start(&init_desc,
  79984. + XCT_CTRL_HDR(chsel, 0x58, DMA_FN_HKEY0));
  79985. + pasemi_desc_build(&init_desc,
  79986. + XCT_FUN_SRC_PTR(0x58, ((struct pasemi_session *)ses->dma_addr)->hkey));
  79987. +
  79988. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG
  79989. + | XCT_FUN_A | XCT_FUN_FUN(chsel));
  79990. + }
  79991. +
  79992. + if (enccrd) {
  79993. + switch (enccrd->crd_alg) {
  79994. + case CRYPTO_3DES_CBC:
  79995. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_3DES |
  79996. + XCT_FUN_BCM_CBC);
  79997. + ivsize = sizeof(u64);
  79998. + break;
  79999. + case CRYPTO_DES_CBC:
  80000. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_DES |
  80001. + XCT_FUN_BCM_CBC);
  80002. + ivsize = sizeof(u64);
  80003. + break;
  80004. + case CRYPTO_AES_CBC:
  80005. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_AES |
  80006. + XCT_FUN_BCM_CBC);
  80007. + ivsize = 2 * sizeof(u64);
  80008. + break;
  80009. + case CRYPTO_ARC4:
  80010. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_ARC);
  80011. + ivsize = 0;
  80012. + break;
  80013. + default:
  80014. + printk(DRV_NAME ": unimplemented enccrd->crd_alg %d\n",
  80015. + enccrd->crd_alg);
  80016. + err = -EINVAL;
  80017. + goto errout;
  80018. + }
  80019. +
  80020. + ivp = (ivsize == sizeof(u64)) ? (caddr_t) &ses->civ[1] : (caddr_t) &ses->civ[0];
  80021. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  80022. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  80023. + memcpy(ivp, enccrd->crd_iv, ivsize);
  80024. + /* If IV is not present in the buffer already, it has to be copied there */
  80025. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0)
  80026. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  80027. + enccrd->crd_inject, ivsize, ivp);
  80028. + } else {
  80029. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  80030. + /* IV is provided expicitly in descriptor */
  80031. + memcpy(ivp, enccrd->crd_iv, ivsize);
  80032. + else
  80033. + /* IV is provided in the packet */
  80034. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  80035. + enccrd->crd_inject, ivsize,
  80036. + ivp);
  80037. + }
  80038. + }
  80039. +
  80040. + if (maccrd) {
  80041. + switch (maccrd->crd_alg) {
  80042. + case CRYPTO_MD5:
  80043. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_MD5 |
  80044. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  80045. + break;
  80046. + case CRYPTO_SHA1:
  80047. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_SHA1 |
  80048. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  80049. + break;
  80050. + case CRYPTO_MD5_HMAC:
  80051. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_MD5 |
  80052. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  80053. + break;
  80054. + case CRYPTO_SHA1_HMAC:
  80055. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_SHA1 |
  80056. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  80057. + break;
  80058. + default:
  80059. + printk(DRV_NAME ": unimplemented maccrd->crd_alg %d\n",
  80060. + maccrd->crd_alg);
  80061. + err = -EINVAL;
  80062. + goto errout;
  80063. + }
  80064. + }
  80065. +
  80066. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  80067. + /* using SKB buffers */
  80068. + skb = (struct sk_buff *)crp->crp_buf;
  80069. + if (skb_shinfo(skb)->nr_frags) {
  80070. + printk(DRV_NAME ": skb frags unimplemented\n");
  80071. + err = -EINVAL;
  80072. + goto errout;
  80073. + }
  80074. + pasemi_desc_build(
  80075. + &work_desc,
  80076. + XCT_FUN_DST_PTR(skb->len, pci_map_single(
  80077. + sc->dma_pdev, skb->data,
  80078. + skb->len, DMA_TO_DEVICE)));
  80079. + pasemi_desc_build(
  80080. + &work_desc,
  80081. + XCT_FUN_SRC_PTR(
  80082. + srclen, pci_map_single(
  80083. + sc->dma_pdev, skb->data,
  80084. + srclen, DMA_TO_DEVICE)));
  80085. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  80086. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  80087. + /* using IOV buffers */
  80088. + uiop = (struct uio *)crp->crp_buf;
  80089. + if (uiop->uio_iovcnt > 1) {
  80090. + printk(DRV_NAME ": iov frags unimplemented\n");
  80091. + err = -EINVAL;
  80092. + goto errout;
  80093. + }
  80094. +
  80095. + /* crp_olen is never set; always use crp_ilen */
  80096. + pasemi_desc_build(
  80097. + &work_desc,
  80098. + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
  80099. + sc->dma_pdev,
  80100. + uiop->uio_iov->iov_base,
  80101. + crp->crp_ilen, DMA_TO_DEVICE)));
  80102. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  80103. +
  80104. + pasemi_desc_build(
  80105. + &work_desc,
  80106. + XCT_FUN_SRC_PTR(srclen, pci_map_single(
  80107. + sc->dma_pdev,
  80108. + uiop->uio_iov->iov_base,
  80109. + srclen, DMA_TO_DEVICE)));
  80110. + } else {
  80111. + /* using contig buffers */
  80112. + pasemi_desc_build(
  80113. + &work_desc,
  80114. + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
  80115. + sc->dma_pdev,
  80116. + crp->crp_buf,
  80117. + crp->crp_ilen, DMA_TO_DEVICE)));
  80118. + pasemi_desc_build(
  80119. + &work_desc,
  80120. + XCT_FUN_SRC_PTR(srclen, pci_map_single(
  80121. + sc->dma_pdev,
  80122. + crp->crp_buf, srclen,
  80123. + DMA_TO_DEVICE)));
  80124. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  80125. + }
  80126. +
  80127. + spin_lock_irqsave(&txring->fill_lock, flags);
  80128. +
  80129. + if (txring->sesn != PASEMI_SESSION(crp->crp_sid)) {
  80130. + txring->sesn = PASEMI_SESSION(crp->crp_sid);
  80131. + reinit = 1;
  80132. + }
  80133. +
  80134. + if (enccrd) {
  80135. + pasemi_desc_start(&init_desc,
  80136. + XCT_CTRL_HDR(chsel, reinit ? reinit_size : 0x10, DMA_FN_CIV0));
  80137. + pasemi_desc_build(&init_desc,
  80138. + XCT_FUN_SRC_PTR(reinit ? reinit_size : 0x10, ses->dma_addr));
  80139. + }
  80140. +
  80141. + if (((txring->next_to_fill + pasemi_desc_size(&init_desc) +
  80142. + pasemi_desc_size(&work_desc)) -
  80143. + txring->next_to_clean) > TX_RING_SIZE) {
  80144. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  80145. + err = ERESTART;
  80146. + goto errout;
  80147. + }
  80148. +
  80149. + pasemi_ring_add_desc(txring, &init_desc, NULL);
  80150. + pasemi_ring_add_desc(txring, &work_desc, crp);
  80151. +
  80152. + pasemi_ring_incr(sc, chsel,
  80153. + pasemi_desc_size(&init_desc) +
  80154. + pasemi_desc_size(&work_desc));
  80155. +
  80156. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  80157. +
  80158. + mod_timer(&txring->crypto_timer, jiffies + TIMER_INTERVAL);
  80159. +
  80160. + return 0;
  80161. +
  80162. +erralg:
  80163. + printk(DRV_NAME ": unsupported algorithm or algorithm order alg1 %d alg2 %d\n",
  80164. + crd1->crd_alg, crd2->crd_alg);
  80165. + err = -EINVAL;
  80166. +
  80167. +errout:
  80168. + if (err != ERESTART) {
  80169. + crp->crp_etype = err;
  80170. + crypto_done(crp);
  80171. + }
  80172. + return err;
  80173. +}
  80174. +
  80175. +static int pasemi_clean_tx(struct pasemi_softc *sc, int chan)
  80176. +{
  80177. + int i, j, ring_idx;
  80178. + struct pasemi_fnu_txring *ring = &sc->tx[chan];
  80179. + u16 delta_cnt;
  80180. + int flags, loops = 10;
  80181. + int desc_size;
  80182. + struct cryptop *crp;
  80183. +
  80184. + spin_lock_irqsave(&ring->clean_lock, flags);
  80185. +
  80186. + while ((delta_cnt = (dma_status->tx_sta[sc->base_chan + chan]
  80187. + & PAS_STATUS_PCNT_M) - ring->total_pktcnt)
  80188. + && loops--) {
  80189. +
  80190. + for (i = 0; i < delta_cnt; i++) {
  80191. + desc_size = TX_DESC_INFO(ring, ring->next_to_clean).desc_size;
  80192. + crp = TX_DESC_INFO(ring, ring->next_to_clean).cf_crp;
  80193. + if (crp) {
  80194. + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
  80195. + if (TX_DESC_INFO(ring, ring->next_to_clean).desc_postop & PASEMI_CHECK_SIG) {
  80196. + /* Need to make sure signature matched,
  80197. + * if not - return error */
  80198. + if (!(ring->desc[ring_idx + 1] & (1ULL << 63)))
  80199. + crp->crp_etype = -EINVAL;
  80200. + }
  80201. + crypto_done(TX_DESC_INFO(ring,
  80202. + ring->next_to_clean).cf_crp);
  80203. + TX_DESC_INFO(ring, ring->next_to_clean).cf_crp = NULL;
  80204. + pci_unmap_single(
  80205. + sc->dma_pdev,
  80206. + XCT_PTR_ADDR_LEN(ring->desc[ring_idx + 1]),
  80207. + PCI_DMA_TODEVICE);
  80208. +
  80209. + ring->desc[ring_idx] = ring->desc[ring_idx + 1] = 0;
  80210. +
  80211. + ring->next_to_clean++;
  80212. + for (j = 1; j < desc_size; j++) {
  80213. + ring_idx = 2 *
  80214. + (ring->next_to_clean &
  80215. + (TX_RING_SIZE-1));
  80216. + pci_unmap_single(
  80217. + sc->dma_pdev,
  80218. + XCT_PTR_ADDR_LEN(ring->desc[ring_idx]),
  80219. + PCI_DMA_TODEVICE);
  80220. + if (ring->desc[ring_idx + 1])
  80221. + pci_unmap_single(
  80222. + sc->dma_pdev,
  80223. + XCT_PTR_ADDR_LEN(
  80224. + ring->desc[
  80225. + ring_idx + 1]),
  80226. + PCI_DMA_TODEVICE);
  80227. + ring->desc[ring_idx] =
  80228. + ring->desc[ring_idx + 1] = 0;
  80229. + ring->next_to_clean++;
  80230. + }
  80231. + } else {
  80232. + for (j = 0; j < desc_size; j++) {
  80233. + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
  80234. + ring->desc[ring_idx] =
  80235. + ring->desc[ring_idx + 1] = 0;
  80236. + ring->next_to_clean++;
  80237. + }
  80238. + }
  80239. + }
  80240. +
  80241. + ring->total_pktcnt += delta_cnt;
  80242. + }
  80243. + spin_unlock_irqrestore(&ring->clean_lock, flags);
  80244. +
  80245. + return 0;
  80246. +}
  80247. +
  80248. +static void sweepup_tx(struct pasemi_softc *sc)
  80249. +{
  80250. + int i;
  80251. +
  80252. + for (i = 0; i < sc->sc_num_channels; i++)
  80253. + pasemi_clean_tx(sc, i);
  80254. +}
  80255. +
  80256. +static irqreturn_t pasemi_intr(int irq, void *arg, struct pt_regs *regs)
  80257. +{
  80258. + struct pasemi_softc *sc = arg;
  80259. + unsigned int reg;
  80260. + int chan = irq - sc->base_irq;
  80261. + int chan_index = sc->base_chan + chan;
  80262. + u64 stat = dma_status->tx_sta[chan_index];
  80263. +
  80264. + DPRINTF("%s()\n", __FUNCTION__);
  80265. +
  80266. + if (!(stat & PAS_STATUS_CAUSE_M))
  80267. + return IRQ_NONE;
  80268. +
  80269. + pasemi_clean_tx(sc, chan);
  80270. +
  80271. + stat = dma_status->tx_sta[chan_index];
  80272. +
  80273. + reg = PAS_IOB_DMA_TXCH_RESET_PINTC |
  80274. + PAS_IOB_DMA_TXCH_RESET_PCNT(sc->tx[chan].total_pktcnt);
  80275. +
  80276. + if (stat & PAS_STATUS_SOFT)
  80277. + reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
  80278. +
  80279. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), reg);
  80280. +
  80281. +
  80282. + return IRQ_HANDLED;
  80283. +}
  80284. +
  80285. +static int pasemi_dma_setup_tx_resources(struct pasemi_softc *sc, int chan)
  80286. +{
  80287. + u32 val;
  80288. + int chan_index = chan + sc->base_chan;
  80289. + int ret;
  80290. + struct pasemi_fnu_txring *ring;
  80291. +
  80292. + ring = &sc->tx[chan];
  80293. +
  80294. + spin_lock_init(&ring->fill_lock);
  80295. + spin_lock_init(&ring->clean_lock);
  80296. +
  80297. + ring->desc_info = kzalloc(sizeof(struct pasemi_desc_info) *
  80298. + TX_RING_SIZE, GFP_KERNEL);
  80299. + if (!ring->desc_info)
  80300. + return -ENOMEM;
  80301. +
  80302. + /* Allocate descriptors */
  80303. + ring->desc = dma_alloc_coherent(&sc->dma_pdev->dev,
  80304. + TX_RING_SIZE *
  80305. + 2 * sizeof(u64),
  80306. + &ring->dma, GFP_KERNEL);
  80307. + if (!ring->desc)
  80308. + return -ENOMEM;
  80309. +
  80310. + memset((void *) ring->desc, 0, TX_RING_SIZE * 2 * sizeof(u64));
  80311. +
  80312. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), 0x30);
  80313. +
  80314. + ring->total_pktcnt = 0;
  80315. +
  80316. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEL(chan_index),
  80317. + PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
  80318. +
  80319. + val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
  80320. + val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2);
  80321. +
  80322. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEU(chan_index), val);
  80323. +
  80324. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_CFG(chan_index),
  80325. + PAS_DMA_TXCHAN_CFG_TY_FUNC |
  80326. + PAS_DMA_TXCHAN_CFG_TATTR(chan) |
  80327. + PAS_DMA_TXCHAN_CFG_WT(2));
  80328. +
  80329. + /* enable tx channel */
  80330. + out_le32(sc->dma_regs +
  80331. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  80332. + PAS_DMA_TXCHAN_TCMDSTA_EN);
  80333. +
  80334. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_CFG(chan_index),
  80335. + PAS_IOB_DMA_TXCH_CFG_CNTTH(1000));
  80336. +
  80337. + ring->next_to_fill = 0;
  80338. + ring->next_to_clean = 0;
  80339. +
  80340. + snprintf(ring->irq_name, sizeof(ring->irq_name),
  80341. + "%s%d", "crypto", chan);
  80342. +
  80343. + ring->irq = irq_create_mapping(NULL, sc->base_irq + chan);
  80344. + ret = request_irq(ring->irq, (irq_handler_t)
  80345. + pasemi_intr, IRQF_DISABLED, ring->irq_name, sc);
  80346. + if (ret) {
  80347. + printk(KERN_ERR DRV_NAME ": failed to hook irq %d ret %d\n",
  80348. + ring->irq, ret);
  80349. + ring->irq = -1;
  80350. + return ret;
  80351. + }
  80352. +
  80353. + setup_timer(&ring->crypto_timer, (void *) sweepup_tx, (unsigned long) sc);
  80354. +
  80355. + return 0;
  80356. +}
  80357. +
  80358. +static device_method_t pasemi_methods = {
  80359. + /* crypto device methods */
  80360. + DEVMETHOD(cryptodev_newsession, pasemi_newsession),
  80361. + DEVMETHOD(cryptodev_freesession, pasemi_freesession),
  80362. + DEVMETHOD(cryptodev_process, pasemi_process),
  80363. +};
  80364. +
  80365. +/* Set up the crypto device structure, private data,
  80366. + * and anything else we need before we start */
  80367. +
  80368. +static int __devinit
  80369. +pasemi_dma_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  80370. +{
  80371. + struct pasemi_softc *sc;
  80372. + int ret, i;
  80373. +
  80374. + DPRINTF(KERN_ERR "%s()\n", __FUNCTION__);
  80375. +
  80376. + sc = kzalloc(sizeof(*sc), GFP_KERNEL);
  80377. + if (!sc)
  80378. + return -ENOMEM;
  80379. +
  80380. + softc_device_init(sc, DRV_NAME, 1, pasemi_methods);
  80381. +
  80382. + pci_set_drvdata(pdev, sc);
  80383. +
  80384. + spin_lock_init(&sc->sc_chnlock);
  80385. +
  80386. + sc->sc_sessions = (struct pasemi_session **)
  80387. + kzalloc(PASEMI_INITIAL_SESSIONS *
  80388. + sizeof(struct pasemi_session *), GFP_ATOMIC);
  80389. + if (sc->sc_sessions == NULL) {
  80390. + ret = -ENOMEM;
  80391. + goto out;
  80392. + }
  80393. +
  80394. + sc->sc_nsessions = PASEMI_INITIAL_SESSIONS;
  80395. + sc->sc_lastchn = 0;
  80396. + sc->base_irq = pdev->irq + 6;
  80397. + sc->base_chan = 6;
  80398. + sc->sc_cid = -1;
  80399. + sc->dma_pdev = pdev;
  80400. +
  80401. + sc->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
  80402. + if (!sc->iob_pdev) {
  80403. + dev_err(&pdev->dev, "Can't find I/O Bridge\n");
  80404. + ret = -ENODEV;
  80405. + goto out;
  80406. + }
  80407. +
  80408. + /* This is hardcoded and ugly, but we have some firmware versions
  80409. + * who don't provide the register space in the device tree. Luckily
  80410. + * they are at well-known locations so we can just do the math here.
  80411. + */
  80412. + sc->dma_regs =
  80413. + ioremap(0xe0000000 + (sc->dma_pdev->devfn << 12), 0x2000);
  80414. + sc->iob_regs =
  80415. + ioremap(0xe0000000 + (sc->iob_pdev->devfn << 12), 0x2000);
  80416. + if (!sc->dma_regs || !sc->iob_regs) {
  80417. + dev_err(&pdev->dev, "Can't map registers\n");
  80418. + ret = -ENODEV;
  80419. + goto out;
  80420. + }
  80421. +
  80422. + dma_status = __ioremap(0xfd800000, 0x1000, 0);
  80423. + if (!dma_status) {
  80424. + ret = -ENODEV;
  80425. + dev_err(&pdev->dev, "Can't map dmastatus space\n");
  80426. + goto out;
  80427. + }
  80428. +
  80429. + sc->tx = (struct pasemi_fnu_txring *)
  80430. + kzalloc(sizeof(struct pasemi_fnu_txring)
  80431. + * 8, GFP_KERNEL);
  80432. + if (!sc->tx) {
  80433. + ret = -ENOMEM;
  80434. + goto out;
  80435. + }
  80436. +
  80437. + /* Initialize the h/w */
  80438. + out_le32(sc->dma_regs + PAS_DMA_COM_CFG,
  80439. + (in_le32(sc->dma_regs + PAS_DMA_COM_CFG) |
  80440. + PAS_DMA_COM_CFG_FWF));
  80441. + out_le32(sc->dma_regs + PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
  80442. +
  80443. + for (i = 0; i < PASEMI_FNU_CHANNELS; i++) {
  80444. + sc->sc_num_channels++;
  80445. + ret = pasemi_dma_setup_tx_resources(sc, i);
  80446. + if (ret)
  80447. + goto out;
  80448. + }
  80449. +
  80450. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),
  80451. + CRYPTOCAP_F_HARDWARE);
  80452. + if (sc->sc_cid < 0) {
  80453. + printk(KERN_ERR DRV_NAME ": could not get crypto driver id\n");
  80454. + ret = -ENXIO;
  80455. + goto out;
  80456. + }
  80457. +
  80458. + /* register algorithms with the framework */
  80459. + printk(DRV_NAME ":");
  80460. +
  80461. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  80462. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  80463. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  80464. + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
  80465. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  80466. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  80467. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  80468. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  80469. +
  80470. + return 0;
  80471. +
  80472. +out:
  80473. + pasemi_dma_remove(pdev);
  80474. + return ret;
  80475. +}
  80476. +
  80477. +#define MAX_RETRIES 5000
  80478. +
  80479. +static void pasemi_free_tx_resources(struct pasemi_softc *sc, int chan)
  80480. +{
  80481. + struct pasemi_fnu_txring *ring = &sc->tx[chan];
  80482. + int chan_index = chan + sc->base_chan;
  80483. + int retries;
  80484. + u32 stat;
  80485. +
  80486. + /* Stop the channel */
  80487. + out_le32(sc->dma_regs +
  80488. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  80489. + PAS_DMA_TXCHAN_TCMDSTA_ST);
  80490. +
  80491. + for (retries = 0; retries < MAX_RETRIES; retries++) {
  80492. + stat = in_le32(sc->dma_regs +
  80493. + PAS_DMA_TXCHAN_TCMDSTA(chan_index));
  80494. + if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
  80495. + break;
  80496. + cond_resched();
  80497. + }
  80498. +
  80499. + if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
  80500. + dev_err(&sc->dma_pdev->dev, "Failed to stop tx channel %d\n",
  80501. + chan_index);
  80502. +
  80503. + /* Disable the channel */
  80504. + out_le32(sc->dma_regs +
  80505. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  80506. + 0);
  80507. +
  80508. + if (ring->desc_info)
  80509. + kfree((void *) ring->desc_info);
  80510. + if (ring->desc)
  80511. + dma_free_coherent(&sc->dma_pdev->dev,
  80512. + TX_RING_SIZE *
  80513. + 2 * sizeof(u64),
  80514. + (void *) ring->desc, ring->dma);
  80515. + if (ring->irq != -1)
  80516. + free_irq(ring->irq, sc);
  80517. +
  80518. + del_timer(&ring->crypto_timer);
  80519. +}
  80520. +
  80521. +static void __devexit pasemi_dma_remove(struct pci_dev *pdev)
  80522. +{
  80523. + struct pasemi_softc *sc = pci_get_drvdata(pdev);
  80524. + int i;
  80525. +
  80526. + DPRINTF("%s()\n", __FUNCTION__);
  80527. +
  80528. + if (sc->sc_cid >= 0) {
  80529. + crypto_unregister_all(sc->sc_cid);
  80530. + }
  80531. +
  80532. + if (sc->tx) {
  80533. + for (i = 0; i < sc->sc_num_channels; i++)
  80534. + pasemi_free_tx_resources(sc, i);
  80535. +
  80536. + kfree(sc->tx);
  80537. + }
  80538. + if (sc->sc_sessions) {
  80539. + for (i = 0; i < sc->sc_nsessions; i++)
  80540. + kfree(sc->sc_sessions[i]);
  80541. + kfree(sc->sc_sessions);
  80542. + }
  80543. + if (sc->iob_pdev)
  80544. + pci_dev_put(sc->iob_pdev);
  80545. + if (sc->dma_regs)
  80546. + iounmap(sc->dma_regs);
  80547. + if (sc->iob_regs)
  80548. + iounmap(sc->iob_regs);
  80549. + kfree(sc);
  80550. +}
  80551. +
  80552. +static struct pci_device_id pasemi_dma_pci_tbl[] = {
  80553. + { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa007) },
  80554. +};
  80555. +
  80556. +MODULE_DEVICE_TABLE(pci, pasemi_dma_pci_tbl);
  80557. +
  80558. +static struct pci_driver pasemi_dma_driver = {
  80559. + .name = "pasemi_dma",
  80560. + .id_table = pasemi_dma_pci_tbl,
  80561. + .probe = pasemi_dma_probe,
  80562. + .remove = __devexit_p(pasemi_dma_remove),
  80563. +};
  80564. +
  80565. +static void __exit pasemi_dma_cleanup_module(void)
  80566. +{
  80567. + pci_unregister_driver(&pasemi_dma_driver);
  80568. + __iounmap(dma_status);
  80569. + dma_status = NULL;
  80570. +}
  80571. +
  80572. +int pasemi_dma_init_module(void)
  80573. +{
  80574. + return pci_register_driver(&pasemi_dma_driver);
  80575. +}
  80576. +
  80577. +module_init(pasemi_dma_init_module);
  80578. +module_exit(pasemi_dma_cleanup_module);
  80579. +
  80580. +MODULE_LICENSE("Dual BSD/GPL");
  80581. +MODULE_AUTHOR("Egor Martovetsky egor@pasemi.com");
  80582. +MODULE_DESCRIPTION("OCF driver for PA Semi PWRficient DMA Crypto Engine");
  80583. diff -Nur linux-2.6.36.orig/crypto/ocf/pasemi/pasemi_fnu.h linux-2.6.36/crypto/ocf/pasemi/pasemi_fnu.h
  80584. --- linux-2.6.36.orig/crypto/ocf/pasemi/pasemi_fnu.h 1970-01-01 01:00:00.000000000 +0100
  80585. +++ linux-2.6.36/crypto/ocf/pasemi/pasemi_fnu.h 2010-11-09 20:28:12.612495424 +0100
  80586. @@ -0,0 +1,410 @@
  80587. +/*
  80588. + * Copyright (C) 2007 PA Semi, Inc
  80589. + *
  80590. + * Driver for the PA Semi PWRficient DMA Crypto Engine, soft state and
  80591. + * hardware register layouts.
  80592. + *
  80593. + * This program is free software; you can redistribute it and/or modify
  80594. + * it under the terms of the GNU General Public License version 2 as
  80595. + * published by the Free Software Foundation.
  80596. + *
  80597. + * This program is distributed in the hope that it will be useful,
  80598. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  80599. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  80600. + * GNU General Public License for more details.
  80601. + *
  80602. + * You should have received a copy of the GNU General Public License
  80603. + * along with this program; if not, write to the Free Software
  80604. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  80605. + */
  80606. +
  80607. +#ifndef PASEMI_FNU_H
  80608. +#define PASEMI_FNU_H
  80609. +
  80610. +#include <linux/spinlock.h>
  80611. +
  80612. +#define PASEMI_SESSION(sid) ((sid) & 0xffffffff)
  80613. +#define PASEMI_SID(sesn) ((sesn) & 0xffffffff)
  80614. +#define DPRINTF(a...) if (debug) { printk(DRV_NAME ": " a); }
  80615. +
  80616. +/* Must be a power of two */
  80617. +#define RX_RING_SIZE 512
  80618. +#define TX_RING_SIZE 512
  80619. +#define TX_DESC(ring, num) ((ring)->desc[2 * (num & (TX_RING_SIZE-1))])
  80620. +#define TX_DESC_INFO(ring, num) ((ring)->desc_info[(num) & (TX_RING_SIZE-1)])
  80621. +#define MAX_DESC_SIZE 8
  80622. +#define PASEMI_INITIAL_SESSIONS 10
  80623. +#define PASEMI_FNU_CHANNELS 8
  80624. +
  80625. +/* DMA descriptor */
  80626. +struct pasemi_desc {
  80627. + u64 quad[2*MAX_DESC_SIZE];
  80628. + int quad_cnt;
  80629. + int size;
  80630. + int postop;
  80631. +};
  80632. +
  80633. +/*
  80634. + * Holds per descriptor data
  80635. + */
  80636. +struct pasemi_desc_info {
  80637. + int desc_size;
  80638. + int desc_postop;
  80639. +#define PASEMI_CHECK_SIG 0x1
  80640. +
  80641. + struct cryptop *cf_crp;
  80642. +};
  80643. +
  80644. +/*
  80645. + * Holds per channel data
  80646. + */
  80647. +struct pasemi_fnu_txring {
  80648. + volatile u64 *desc;
  80649. + volatile struct
  80650. + pasemi_desc_info *desc_info;
  80651. + dma_addr_t dma;
  80652. + struct timer_list crypto_timer;
  80653. + spinlock_t fill_lock;
  80654. + spinlock_t clean_lock;
  80655. + unsigned int next_to_fill;
  80656. + unsigned int next_to_clean;
  80657. + u16 total_pktcnt;
  80658. + int irq;
  80659. + int sesn;
  80660. + char irq_name[10];
  80661. +};
  80662. +
  80663. +/*
  80664. + * Holds data specific to a single pasemi device.
  80665. + */
  80666. +struct pasemi_softc {
  80667. + softc_device_decl sc_cdev;
  80668. + struct pci_dev *dma_pdev; /* device backpointer */
  80669. + struct pci_dev *iob_pdev; /* device backpointer */
  80670. + void __iomem *dma_regs;
  80671. + void __iomem *iob_regs;
  80672. + int base_irq;
  80673. + int base_chan;
  80674. + int32_t sc_cid; /* crypto tag */
  80675. + int sc_nsessions;
  80676. + struct pasemi_session **sc_sessions;
  80677. + int sc_num_channels;/* number of crypto channels */
  80678. +
  80679. + /* pointer to the array of txring datastructures, one txring per channel */
  80680. + struct pasemi_fnu_txring *tx;
  80681. +
  80682. + /*
  80683. + * mutual exclusion for the channel scheduler
  80684. + */
  80685. + spinlock_t sc_chnlock;
  80686. + /* last channel used, for now use round-robin to allocate channels */
  80687. + int sc_lastchn;
  80688. +};
  80689. +
  80690. +struct pasemi_session {
  80691. + u64 civ[2];
  80692. + u64 keysz;
  80693. + u64 key[4];
  80694. + u64 ccmd;
  80695. + u64 hkey[4];
  80696. + u64 hseq;
  80697. + u64 giv[2];
  80698. + u64 hiv[4];
  80699. +
  80700. + int used;
  80701. + dma_addr_t dma_addr;
  80702. + int chan;
  80703. +};
  80704. +
  80705. +/* status register layout in IOB region, at 0xfd800000 */
  80706. +struct pasdma_status {
  80707. + u64 rx_sta[64];
  80708. + u64 tx_sta[20];
  80709. +};
  80710. +
  80711. +#define ALG_IS_CIPHER(alg) ((alg == CRYPTO_DES_CBC) || \
  80712. + (alg == CRYPTO_3DES_CBC) || \
  80713. + (alg == CRYPTO_AES_CBC) || \
  80714. + (alg == CRYPTO_ARC4) || \
  80715. + (alg == CRYPTO_NULL_CBC))
  80716. +
  80717. +#define ALG_IS_SIG(alg) ((alg == CRYPTO_MD5) || \
  80718. + (alg == CRYPTO_MD5_HMAC) || \
  80719. + (alg == CRYPTO_SHA1) || \
  80720. + (alg == CRYPTO_SHA1_HMAC) || \
  80721. + (alg == CRYPTO_NULL_HMAC))
  80722. +
  80723. +enum {
  80724. + PAS_DMA_COM_TXCMD = 0x100, /* Transmit Command Register */
  80725. + PAS_DMA_COM_TXSTA = 0x104, /* Transmit Status Register */
  80726. + PAS_DMA_COM_RXCMD = 0x108, /* Receive Command Register */
  80727. + PAS_DMA_COM_RXSTA = 0x10c, /* Receive Status Register */
  80728. + PAS_DMA_COM_CFG = 0x114, /* DMA Configuration Register */
  80729. +};
  80730. +
  80731. +/* All these registers live in the PCI configuration space for the DMA PCI
  80732. + * device. Use the normal PCI config access functions for them.
  80733. + */
  80734. +
  80735. +#define PAS_DMA_COM_CFG_FWF 0x18000000
  80736. +
  80737. +#define PAS_DMA_COM_TXCMD_EN 0x00000001 /* enable */
  80738. +#define PAS_DMA_COM_TXSTA_ACT 0x00000001 /* active */
  80739. +#define PAS_DMA_COM_RXCMD_EN 0x00000001 /* enable */
  80740. +#define PAS_DMA_COM_RXSTA_ACT 0x00000001 /* active */
  80741. +
  80742. +#define _PAS_DMA_TXCHAN_STRIDE 0x20 /* Size per channel */
  80743. +#define _PAS_DMA_TXCHAN_TCMDSTA 0x300 /* Command / Status */
  80744. +#define _PAS_DMA_TXCHAN_CFG 0x304 /* Configuration */
  80745. +#define _PAS_DMA_TXCHAN_DSCRBU 0x308 /* Descriptor BU Allocation */
  80746. +#define _PAS_DMA_TXCHAN_INCR 0x310 /* Descriptor increment */
  80747. +#define _PAS_DMA_TXCHAN_CNT 0x314 /* Descriptor count/offset */
  80748. +#define _PAS_DMA_TXCHAN_BASEL 0x318 /* Descriptor ring base (low) */
  80749. +#define _PAS_DMA_TXCHAN_BASEU 0x31c /* (high) */
  80750. +#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE)
  80751. +#define PAS_DMA_TXCHAN_TCMDSTA_EN 0x00000001 /* Enabled */
  80752. +#define PAS_DMA_TXCHAN_TCMDSTA_ST 0x00000002 /* Stop interface */
  80753. +#define PAS_DMA_TXCHAN_TCMDSTA_ACT 0x00010000 /* Active */
  80754. +#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
  80755. +#define PAS_DMA_TXCHAN_CFG_TY_FUNC 0x00000002 /* Type = interface */
  80756. +#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */
  80757. +#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c
  80758. +#define PAS_DMA_TXCHAN_CFG_TATTR_S 2
  80759. +#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
  80760. + PAS_DMA_TXCHAN_CFG_TATTR_M)
  80761. +#define PAS_DMA_TXCHAN_CFG_WT_M 0x000001c0
  80762. +#define PAS_DMA_TXCHAN_CFG_WT_S 6
  80763. +#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
  80764. + PAS_DMA_TXCHAN_CFG_WT_M)
  80765. +#define PAS_DMA_TXCHAN_CFG_LPSQ_FAST 0x00000400
  80766. +#define PAS_DMA_TXCHAN_CFG_LPDQ_FAST 0x00000800
  80767. +#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */
  80768. +#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */
  80769. +#define PAS_DMA_TXCHAN_CFG_UP 0x00004000 /* update tx descr when sent */
  80770. +#define PAS_DMA_TXCHAN_INCR(c) (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
  80771. +#define PAS_DMA_TXCHAN_BASEL(c) (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
  80772. +#define PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0
  80773. +#define PAS_DMA_TXCHAN_BASEL_BRBL_S 0
  80774. +#define PAS_DMA_TXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \
  80775. + PAS_DMA_TXCHAN_BASEL_BRBL_M)
  80776. +#define PAS_DMA_TXCHAN_BASEU(c) (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE)
  80777. +#define PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff
  80778. +#define PAS_DMA_TXCHAN_BASEU_BRBH_S 0
  80779. +#define PAS_DMA_TXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \
  80780. + PAS_DMA_TXCHAN_BASEU_BRBH_M)
  80781. +/* # of cache lines worth of buffer ring */
  80782. +#define PAS_DMA_TXCHAN_BASEU_SIZ_M 0x3fff0000
  80783. +#define PAS_DMA_TXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */
  80784. +#define PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \
  80785. + PAS_DMA_TXCHAN_BASEU_SIZ_M)
  80786. +
  80787. +#define PAS_STATUS_PCNT_M 0x000000000000ffffull
  80788. +#define PAS_STATUS_PCNT_S 0
  80789. +#define PAS_STATUS_DCNT_M 0x00000000ffff0000ull
  80790. +#define PAS_STATUS_DCNT_S 16
  80791. +#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull
  80792. +#define PAS_STATUS_BPCNT_S 32
  80793. +#define PAS_STATUS_CAUSE_M 0xf000000000000000ull
  80794. +#define PAS_STATUS_TIMER 0x1000000000000000ull
  80795. +#define PAS_STATUS_ERROR 0x2000000000000000ull
  80796. +#define PAS_STATUS_SOFT 0x4000000000000000ull
  80797. +#define PAS_STATUS_INT 0x8000000000000000ull
  80798. +
  80799. +#define PAS_IOB_DMA_RXCH_CFG(i) (0x1100 + (i)*4)
  80800. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_M 0x00000fff
  80801. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_S 0
  80802. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \
  80803. + PAS_IOB_DMA_RXCH_CFG_CNTTH_M)
  80804. +#define PAS_IOB_DMA_TXCH_CFG(i) (0x1200 + (i)*4)
  80805. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_M 0x00000fff
  80806. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_S 0
  80807. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \
  80808. + PAS_IOB_DMA_TXCH_CFG_CNTTH_M)
  80809. +#define PAS_IOB_DMA_RXCH_STAT(i) (0x1300 + (i)*4)
  80810. +#define PAS_IOB_DMA_RXCH_STAT_INTGEN 0x00001000
  80811. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_M 0x00000fff
  80812. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_S 0
  80813. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\
  80814. + PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
  80815. +#define PAS_IOB_DMA_TXCH_STAT(i) (0x1400 + (i)*4)
  80816. +#define PAS_IOB_DMA_TXCH_STAT_INTGEN 0x00001000
  80817. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_M 0x00000fff
  80818. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_S 0
  80819. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\
  80820. + PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
  80821. +#define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4)
  80822. +#define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000
  80823. +#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 16
  80824. +#define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \
  80825. + PAS_IOB_DMA_RXCH_RESET_PCNT_M)
  80826. +#define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020
  80827. +#define PAS_IOB_DMA_RXCH_RESET_DCNTRST 0x00000010
  80828. +#define PAS_IOB_DMA_RXCH_RESET_TINTC 0x00000008
  80829. +#define PAS_IOB_DMA_RXCH_RESET_DINTC 0x00000004
  80830. +#define PAS_IOB_DMA_RXCH_RESET_SINTC 0x00000002
  80831. +#define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001
  80832. +#define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4)
  80833. +#define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000
  80834. +#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 16
  80835. +#define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \
  80836. + PAS_IOB_DMA_TXCH_RESET_PCNT_M)
  80837. +#define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020
  80838. +#define PAS_IOB_DMA_TXCH_RESET_DCNTRST 0x00000010
  80839. +#define PAS_IOB_DMA_TXCH_RESET_TINTC 0x00000008
  80840. +#define PAS_IOB_DMA_TXCH_RESET_DINTC 0x00000004
  80841. +#define PAS_IOB_DMA_TXCH_RESET_SINTC 0x00000002
  80842. +#define PAS_IOB_DMA_TXCH_RESET_PINTC 0x00000001
  80843. +
  80844. +#define PAS_IOB_DMA_COM_TIMEOUTCFG 0x1700
  80845. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M 0x00ffffff
  80846. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S 0
  80847. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x) (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \
  80848. + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M)
  80849. +
  80850. +/* Transmit descriptor fields */
  80851. +#define XCT_MACTX_T 0x8000000000000000ull
  80852. +#define XCT_MACTX_ST 0x4000000000000000ull
  80853. +#define XCT_MACTX_NORES 0x0000000000000000ull
  80854. +#define XCT_MACTX_8BRES 0x1000000000000000ull
  80855. +#define XCT_MACTX_24BRES 0x2000000000000000ull
  80856. +#define XCT_MACTX_40BRES 0x3000000000000000ull
  80857. +#define XCT_MACTX_I 0x0800000000000000ull
  80858. +#define XCT_MACTX_O 0x0400000000000000ull
  80859. +#define XCT_MACTX_E 0x0200000000000000ull
  80860. +#define XCT_MACTX_VLAN_M 0x0180000000000000ull
  80861. +#define XCT_MACTX_VLAN_NOP 0x0000000000000000ull
  80862. +#define XCT_MACTX_VLAN_REMOVE 0x0080000000000000ull
  80863. +#define XCT_MACTX_VLAN_INSERT 0x0100000000000000ull
  80864. +#define XCT_MACTX_VLAN_REPLACE 0x0180000000000000ull
  80865. +#define XCT_MACTX_CRC_M 0x0060000000000000ull
  80866. +#define XCT_MACTX_CRC_NOP 0x0000000000000000ull
  80867. +#define XCT_MACTX_CRC_INSERT 0x0020000000000000ull
  80868. +#define XCT_MACTX_CRC_PAD 0x0040000000000000ull
  80869. +#define XCT_MACTX_CRC_REPLACE 0x0060000000000000ull
  80870. +#define XCT_MACTX_SS 0x0010000000000000ull
  80871. +#define XCT_MACTX_LLEN_M 0x00007fff00000000ull
  80872. +#define XCT_MACTX_LLEN_S 32ull
  80873. +#define XCT_MACTX_LLEN(x) ((((long)(x)) << XCT_MACTX_LLEN_S) & \
  80874. + XCT_MACTX_LLEN_M)
  80875. +#define XCT_MACTX_IPH_M 0x00000000f8000000ull
  80876. +#define XCT_MACTX_IPH_S 27ull
  80877. +#define XCT_MACTX_IPH(x) ((((long)(x)) << XCT_MACTX_IPH_S) & \
  80878. + XCT_MACTX_IPH_M)
  80879. +#define XCT_MACTX_IPO_M 0x0000000007c00000ull
  80880. +#define XCT_MACTX_IPO_S 22ull
  80881. +#define XCT_MACTX_IPO(x) ((((long)(x)) << XCT_MACTX_IPO_S) & \
  80882. + XCT_MACTX_IPO_M)
  80883. +#define XCT_MACTX_CSUM_M 0x0000000000000060ull
  80884. +#define XCT_MACTX_CSUM_NOP 0x0000000000000000ull
  80885. +#define XCT_MACTX_CSUM_TCP 0x0000000000000040ull
  80886. +#define XCT_MACTX_CSUM_UDP 0x0000000000000060ull
  80887. +#define XCT_MACTX_V6 0x0000000000000010ull
  80888. +#define XCT_MACTX_C 0x0000000000000004ull
  80889. +#define XCT_MACTX_AL2 0x0000000000000002ull
  80890. +
  80891. +#define XCT_PTR_T 0x8000000000000000ull
  80892. +#define XCT_PTR_LEN_M 0x7ffff00000000000ull
  80893. +#define XCT_PTR_LEN_S 44
  80894. +#define XCT_PTR_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & \
  80895. + XCT_PTR_LEN_M)
  80896. +#define XCT_PTR_ADDR_M 0x00000fffffffffffull
  80897. +#define XCT_PTR_ADDR_S 0
  80898. +#define XCT_PTR_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & \
  80899. + XCT_PTR_ADDR_M)
  80900. +
  80901. +/* Function descriptor fields */
  80902. +#define XCT_FUN_T 0x8000000000000000ull
  80903. +#define XCT_FUN_ST 0x4000000000000000ull
  80904. +#define XCT_FUN_NORES 0x0000000000000000ull
  80905. +#define XCT_FUN_8BRES 0x1000000000000000ull
  80906. +#define XCT_FUN_24BRES 0x2000000000000000ull
  80907. +#define XCT_FUN_40BRES 0x3000000000000000ull
  80908. +#define XCT_FUN_I 0x0800000000000000ull
  80909. +#define XCT_FUN_O 0x0400000000000000ull
  80910. +#define XCT_FUN_E 0x0200000000000000ull
  80911. +#define XCT_FUN_FUN_S 54
  80912. +#define XCT_FUN_FUN_M 0x01c0000000000000ull
  80913. +#define XCT_FUN_FUN(num) ((((long)(num)) << XCT_FUN_FUN_S) & \
  80914. + XCT_FUN_FUN_M)
  80915. +#define XCT_FUN_CRM_NOP 0x0000000000000000ull
  80916. +#define XCT_FUN_CRM_SIG 0x0008000000000000ull
  80917. +#define XCT_FUN_CRM_ENC 0x0010000000000000ull
  80918. +#define XCT_FUN_CRM_DEC 0x0018000000000000ull
  80919. +#define XCT_FUN_CRM_SIG_ENC 0x0020000000000000ull
  80920. +#define XCT_FUN_CRM_ENC_SIG 0x0028000000000000ull
  80921. +#define XCT_FUN_CRM_SIG_DEC 0x0030000000000000ull
  80922. +#define XCT_FUN_CRM_DEC_SIG 0x0038000000000000ull
  80923. +#define XCT_FUN_LLEN_M 0x0007ffff00000000ull
  80924. +#define XCT_FUN_LLEN_S 32ULL
  80925. +#define XCT_FUN_LLEN(x) ((((long)(x)) << XCT_FUN_LLEN_S) & \
  80926. + XCT_FUN_LLEN_M)
  80927. +#define XCT_FUN_SHL_M 0x00000000f8000000ull
  80928. +#define XCT_FUN_SHL_S 27ull
  80929. +#define XCT_FUN_SHL(x) ((((long)(x)) << XCT_FUN_SHL_S) & \
  80930. + XCT_FUN_SHL_M)
  80931. +#define XCT_FUN_CHL_M 0x0000000007c00000ull
  80932. +#define XCT_FUN_CHL_S 22ull
  80933. +#define XCT_FUN_CHL(x) ((((long)(x)) << XCT_FUN_CHL_S) & \
  80934. + XCT_FUN_CHL_M)
  80935. +#define XCT_FUN_HSZ_M 0x00000000003c0000ull
  80936. +#define XCT_FUN_HSZ_S 18ull
  80937. +#define XCT_FUN_HSZ(x) ((((long)(x)) << XCT_FUN_HSZ_S) & \
  80938. + XCT_FUN_HSZ_M)
  80939. +#define XCT_FUN_ALG_DES 0x0000000000000000ull
  80940. +#define XCT_FUN_ALG_3DES 0x0000000000008000ull
  80941. +#define XCT_FUN_ALG_AES 0x0000000000010000ull
  80942. +#define XCT_FUN_ALG_ARC 0x0000000000018000ull
  80943. +#define XCT_FUN_ALG_KASUMI 0x0000000000020000ull
  80944. +#define XCT_FUN_BCM_ECB 0x0000000000000000ull
  80945. +#define XCT_FUN_BCM_CBC 0x0000000000001000ull
  80946. +#define XCT_FUN_BCM_CFB 0x0000000000002000ull
  80947. +#define XCT_FUN_BCM_OFB 0x0000000000003000ull
  80948. +#define XCT_FUN_BCM_CNT 0x0000000000003800ull
  80949. +#define XCT_FUN_BCM_KAS_F8 0x0000000000002800ull
  80950. +#define XCT_FUN_BCM_KAS_F9 0x0000000000001800ull
  80951. +#define XCT_FUN_BCP_NO_PAD 0x0000000000000000ull
  80952. +#define XCT_FUN_BCP_ZRO 0x0000000000000200ull
  80953. +#define XCT_FUN_BCP_PL 0x0000000000000400ull
  80954. +#define XCT_FUN_BCP_INCR 0x0000000000000600ull
  80955. +#define XCT_FUN_SIG_MD5 (0ull << 4)
  80956. +#define XCT_FUN_SIG_SHA1 (2ull << 4)
  80957. +#define XCT_FUN_SIG_HMAC_MD5 (8ull << 4)
  80958. +#define XCT_FUN_SIG_HMAC_SHA1 (10ull << 4)
  80959. +#define XCT_FUN_A 0x0000000000000008ull
  80960. +#define XCT_FUN_C 0x0000000000000004ull
  80961. +#define XCT_FUN_AL2 0x0000000000000002ull
  80962. +#define XCT_FUN_SE 0x0000000000000001ull
  80963. +
  80964. +#define XCT_FUN_SRC_PTR(len, addr) (XCT_PTR_LEN(len) | XCT_PTR_ADDR(addr))
  80965. +#define XCT_FUN_DST_PTR(len, addr) (XCT_FUN_SRC_PTR(len, addr) | \
  80966. + 0x8000000000000000ull)
  80967. +
  80968. +#define XCT_CTRL_HDR_FUN_NUM_M 0x01c0000000000000ull
  80969. +#define XCT_CTRL_HDR_FUN_NUM_S 54
  80970. +#define XCT_CTRL_HDR_LEN_M 0x0007ffff00000000ull
  80971. +#define XCT_CTRL_HDR_LEN_S 32
  80972. +#define XCT_CTRL_HDR_REG_M 0x00000000000000ffull
  80973. +#define XCT_CTRL_HDR_REG_S 0
  80974. +
  80975. +#define XCT_CTRL_HDR(funcN,len,reg) (0x9400000000000000ull | \
  80976. + ((((long)(funcN)) << XCT_CTRL_HDR_FUN_NUM_S) \
  80977. + & XCT_CTRL_HDR_FUN_NUM_M) | \
  80978. + ((((long)(len)) << \
  80979. + XCT_CTRL_HDR_LEN_S) & XCT_CTRL_HDR_LEN_M) | \
  80980. + ((((long)(reg)) << \
  80981. + XCT_CTRL_HDR_REG_S) & XCT_CTRL_HDR_REG_M))
  80982. +
  80983. +/* Function config command options */
  80984. +#define DMA_CALGO_DES 0x00
  80985. +#define DMA_CALGO_3DES 0x01
  80986. +#define DMA_CALGO_AES 0x02
  80987. +#define DMA_CALGO_ARC 0x03
  80988. +
  80989. +#define DMA_FN_CIV0 0x02
  80990. +#define DMA_FN_CIV1 0x03
  80991. +#define DMA_FN_HKEY0 0x0a
  80992. +
  80993. +#define XCT_PTR_ADDR_LEN(ptr) ((ptr) & XCT_PTR_ADDR_M), \
  80994. + (((ptr) & XCT_PTR_LEN_M) >> XCT_PTR_LEN_S)
  80995. +
  80996. +#endif /* PASEMI_FNU_H */
  80997. diff -Nur linux-2.6.36.orig/crypto/ocf/random.c linux-2.6.36/crypto/ocf/random.c
  80998. --- linux-2.6.36.orig/crypto/ocf/random.c 1970-01-01 01:00:00.000000000 +0100
  80999. +++ linux-2.6.36/crypto/ocf/random.c 2010-11-09 20:28:12.652495434 +0100
  81000. @@ -0,0 +1,322 @@
  81001. +/*
  81002. + * A system independant way of adding entropy to the kernels pool
  81003. + * this way the drivers can focus on the real work and we can take
  81004. + * care of pushing it to the appropriate place in the kernel.
  81005. + *
  81006. + * This should be fast and callable from timers/interrupts
  81007. + *
  81008. + * Written by David McCullough <david_mccullough@mcafee.com>
  81009. + * Copyright (C) 2006-2010 David McCullough
  81010. + * Copyright (C) 2004-2005 Intel Corporation.
  81011. + *
  81012. + * LICENSE TERMS
  81013. + *
  81014. + * The free distribution and use of this software in both source and binary
  81015. + * form is allowed (with or without changes) provided that:
  81016. + *
  81017. + * 1. distributions of this source code include the above copyright
  81018. + * notice, this list of conditions and the following disclaimer;
  81019. + *
  81020. + * 2. distributions in binary form include the above copyright
  81021. + * notice, this list of conditions and the following disclaimer
  81022. + * in the documentation and/or other associated materials;
  81023. + *
  81024. + * 3. the copyright holder's name is not used to endorse products
  81025. + * built using this software without specific written permission.
  81026. + *
  81027. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  81028. + * may be distributed under the terms of the GNU General Public License (GPL),
  81029. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  81030. + *
  81031. + * DISCLAIMER
  81032. + *
  81033. + * This software is provided 'as is' with no explicit or implied warranties
  81034. + * in respect of its properties, including, but not limited to, correctness
  81035. + * and/or fitness for purpose.
  81036. + */
  81037. +
  81038. +#ifndef AUTOCONF_INCLUDED
  81039. +#include <linux/config.h>
  81040. +#endif
  81041. +#include <linux/module.h>
  81042. +#include <linux/init.h>
  81043. +#include <linux/list.h>
  81044. +#include <linux/slab.h>
  81045. +#include <linux/wait.h>
  81046. +#include <linux/sched.h>
  81047. +#include <linux/spinlock.h>
  81048. +#include <linux/version.h>
  81049. +#include <linux/unistd.h>
  81050. +#include <linux/poll.h>
  81051. +#include <linux/random.h>
  81052. +#include <cryptodev.h>
  81053. +
  81054. +#ifdef CONFIG_OCF_FIPS
  81055. +#include "rndtest.h"
  81056. +#endif
  81057. +
  81058. +#ifndef HAS_RANDOM_INPUT_WAIT
  81059. +#error "Please do not enable OCF_RANDOMHARVEST unless you have applied patches"
  81060. +#endif
  81061. +
  81062. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
  81063. +#include <linux/sched.h>
  81064. +#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
  81065. +#endif
  81066. +
  81067. +/*
  81068. + * a hack to access the debug levels from the crypto driver
  81069. + */
  81070. +extern int crypto_debug;
  81071. +#define debug crypto_debug
  81072. +
  81073. +/*
  81074. + * a list of all registered random providers
  81075. + */
  81076. +static LIST_HEAD(random_ops);
  81077. +static int started = 0;
  81078. +static int initted = 0;
  81079. +
  81080. +struct random_op {
  81081. + struct list_head random_list;
  81082. + u_int32_t driverid;
  81083. + int (*read_random)(void *arg, u_int32_t *buf, int len);
  81084. + void *arg;
  81085. +};
  81086. +
  81087. +static int random_proc(void *arg);
  81088. +
  81089. +static pid_t randomproc = (pid_t) -1;
  81090. +static spinlock_t random_lock;
  81091. +
  81092. +/*
  81093. + * just init the spin locks
  81094. + */
  81095. +static int
  81096. +crypto_random_init(void)
  81097. +{
  81098. + spin_lock_init(&random_lock);
  81099. + initted = 1;
  81100. + return(0);
  81101. +}
  81102. +
  81103. +/*
  81104. + * Add the given random reader to our list (if not present)
  81105. + * and start the thread (if not already started)
  81106. + *
  81107. + * we have to assume that driver id is ok for now
  81108. + */
  81109. +int
  81110. +crypto_rregister(
  81111. + u_int32_t driverid,
  81112. + int (*read_random)(void *arg, u_int32_t *buf, int len),
  81113. + void *arg)
  81114. +{
  81115. + unsigned long flags;
  81116. + int ret = 0;
  81117. + struct random_op *rops, *tmp;
  81118. +
  81119. + dprintk("%s,%d: %s(0x%x, %p, %p)\n", __FILE__, __LINE__,
  81120. + __FUNCTION__, driverid, read_random, arg);
  81121. +
  81122. + if (!initted)
  81123. + crypto_random_init();
  81124. +
  81125. +#if 0
  81126. + struct cryptocap *cap;
  81127. +
  81128. + cap = crypto_checkdriver(driverid);
  81129. + if (!cap)
  81130. + return EINVAL;
  81131. +#endif
  81132. +
  81133. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  81134. + if (rops->driverid == driverid && rops->read_random == read_random)
  81135. + return EEXIST;
  81136. + }
  81137. +
  81138. + rops = (struct random_op *) kmalloc(sizeof(*rops), GFP_KERNEL);
  81139. + if (!rops)
  81140. + return ENOMEM;
  81141. +
  81142. + rops->driverid = driverid;
  81143. + rops->read_random = read_random;
  81144. + rops->arg = arg;
  81145. +
  81146. + spin_lock_irqsave(&random_lock, flags);
  81147. + list_add_tail(&rops->random_list, &random_ops);
  81148. + if (!started) {
  81149. + randomproc = kernel_thread(random_proc, NULL, CLONE_FS|CLONE_FILES);
  81150. + if (randomproc < 0) {
  81151. + ret = randomproc;
  81152. + printk("crypto: crypto_rregister cannot start random thread; "
  81153. + "error %d", ret);
  81154. + } else
  81155. + started = 1;
  81156. + }
  81157. + spin_unlock_irqrestore(&random_lock, flags);
  81158. +
  81159. + return ret;
  81160. +}
  81161. +EXPORT_SYMBOL(crypto_rregister);
  81162. +
  81163. +int
  81164. +crypto_runregister_all(u_int32_t driverid)
  81165. +{
  81166. + struct random_op *rops, *tmp;
  81167. + unsigned long flags;
  81168. +
  81169. + dprintk("%s,%d: %s(0x%x)\n", __FILE__, __LINE__, __FUNCTION__, driverid);
  81170. +
  81171. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  81172. + if (rops->driverid == driverid) {
  81173. + list_del(&rops->random_list);
  81174. + kfree(rops);
  81175. + }
  81176. + }
  81177. +
  81178. + spin_lock_irqsave(&random_lock, flags);
  81179. + if (list_empty(&random_ops) && started)
  81180. + kill_proc(randomproc, SIGKILL, 1);
  81181. + spin_unlock_irqrestore(&random_lock, flags);
  81182. + return(0);
  81183. +}
  81184. +EXPORT_SYMBOL(crypto_runregister_all);
  81185. +
  81186. +/*
  81187. + * while we can add entropy to random.c continue to read random data from
  81188. + * the drivers and push it to random.
  81189. + */
  81190. +static int
  81191. +random_proc(void *arg)
  81192. +{
  81193. + int n;
  81194. + int wantcnt;
  81195. + int bufcnt = 0;
  81196. + int retval = 0;
  81197. + int *buf = NULL;
  81198. +
  81199. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  81200. + daemonize();
  81201. + spin_lock_irq(&current->sigmask_lock);
  81202. + sigemptyset(&current->blocked);
  81203. + recalc_sigpending(current);
  81204. + spin_unlock_irq(&current->sigmask_lock);
  81205. + sprintf(current->comm, "ocf-random");
  81206. +#else
  81207. + daemonize("ocf-random");
  81208. + allow_signal(SIGKILL);
  81209. +#endif
  81210. +
  81211. + (void) get_fs();
  81212. + set_fs(get_ds());
  81213. +
  81214. +#ifdef CONFIG_OCF_FIPS
  81215. +#define NUM_INT (RNDTEST_NBYTES/sizeof(int))
  81216. +#else
  81217. +#define NUM_INT 32
  81218. +#endif
  81219. +
  81220. + /*
  81221. + * some devices can transferr their RNG data direct into memory,
  81222. + * so make sure it is device friendly
  81223. + */
  81224. + buf = kmalloc(NUM_INT * sizeof(int), GFP_DMA);
  81225. + if (NULL == buf) {
  81226. + printk("crypto: RNG could not allocate memory\n");
  81227. + retval = -ENOMEM;
  81228. + goto bad_alloc;
  81229. + }
  81230. +
  81231. + wantcnt = NUM_INT; /* start by adding some entropy */
  81232. +
  81233. + /*
  81234. + * its possible due to errors or driver removal that we no longer
  81235. + * have anything to do, if so exit or we will consume all the CPU
  81236. + * doing nothing
  81237. + */
  81238. + while (!list_empty(&random_ops)) {
  81239. + struct random_op *rops, *tmp;
  81240. +
  81241. +#ifdef CONFIG_OCF_FIPS
  81242. + if (wantcnt)
  81243. + wantcnt = NUM_INT; /* FIPs mode can do 20000 bits or none */
  81244. +#endif
  81245. +
  81246. + /* see if we can get enough entropy to make the world
  81247. + * a better place.
  81248. + */
  81249. + while (bufcnt < wantcnt && bufcnt < NUM_INT) {
  81250. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  81251. +
  81252. + n = (*rops->read_random)(rops->arg, &buf[bufcnt],
  81253. + NUM_INT - bufcnt);
  81254. +
  81255. + /* on failure remove the random number generator */
  81256. + if (n == -1) {
  81257. + list_del(&rops->random_list);
  81258. + printk("crypto: RNG (driverid=0x%x) failed, disabling\n",
  81259. + rops->driverid);
  81260. + kfree(rops);
  81261. + } else if (n > 0)
  81262. + bufcnt += n;
  81263. + }
  81264. + /* give up CPU for a bit, just in case as this is a loop */
  81265. + schedule();
  81266. + }
  81267. +
  81268. +
  81269. +#ifdef CONFIG_OCF_FIPS
  81270. + if (bufcnt > 0 && rndtest_buf((unsigned char *) &buf[0])) {
  81271. + dprintk("crypto: buffer had fips errors, discarding\n");
  81272. + bufcnt = 0;
  81273. + }
  81274. +#endif
  81275. +
  81276. + /*
  81277. + * if we have a certified buffer, we can send some data
  81278. + * to /dev/random and move along
  81279. + */
  81280. + if (bufcnt > 0) {
  81281. + /* add what we have */
  81282. + random_input_words(buf, bufcnt, bufcnt*sizeof(int)*8);
  81283. + bufcnt = 0;
  81284. + }
  81285. +
  81286. + /* give up CPU for a bit so we don't hog while filling */
  81287. + schedule();
  81288. +
  81289. + /* wait for needing more */
  81290. + wantcnt = random_input_wait();
  81291. +
  81292. + if (wantcnt <= 0)
  81293. + wantcnt = 0; /* try to get some info again */
  81294. + else
  81295. + /* round up to one word or we can loop forever */
  81296. + wantcnt = (wantcnt + (sizeof(int)*8)) / (sizeof(int)*8);
  81297. + if (wantcnt > NUM_INT) {
  81298. + wantcnt = NUM_INT;
  81299. + }
  81300. +
  81301. + if (signal_pending(current)) {
  81302. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  81303. + spin_lock_irq(&current->sigmask_lock);
  81304. +#endif
  81305. + flush_signals(current);
  81306. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  81307. + spin_unlock_irq(&current->sigmask_lock);
  81308. +#endif
  81309. + }
  81310. + }
  81311. +
  81312. + kfree(buf);
  81313. +
  81314. +bad_alloc:
  81315. + spin_lock_irq(&random_lock);
  81316. + randomproc = (pid_t) -1;
  81317. + started = 0;
  81318. + spin_unlock_irq(&random_lock);
  81319. +
  81320. + return retval;
  81321. +}
  81322. +
  81323. diff -Nur linux-2.6.36.orig/crypto/ocf/README linux-2.6.36/crypto/ocf/README
  81324. --- linux-2.6.36.orig/crypto/ocf/README 1970-01-01 01:00:00.000000000 +0100
  81325. +++ linux-2.6.36/crypto/ocf/README 2010-11-09 20:28:12.681240186 +0100
  81326. @@ -0,0 +1,167 @@
  81327. +README - ocf-linux-20100325
  81328. +---------------------------
  81329. +
  81330. +This README provides instructions for getting ocf-linux compiled and
  81331. +operating in a generic linux environment. For other information you
  81332. +might like to visit the home page for this project:
  81333. +
  81334. + http://ocf-linux.sourceforge.net/
  81335. +
  81336. +Adding OCF to linux
  81337. +-------------------
  81338. +
  81339. + Not much in this file for now, just some notes. I usually build
  81340. + the ocf support as modules but it can be built into the kernel as
  81341. + well. To use it:
  81342. +
  81343. + * mknod /dev/crypto c 10 70
  81344. +
  81345. + * to add OCF to your kernel source, you have two options. Apply
  81346. + the kernel specific patch:
  81347. +
  81348. + cd linux-2.4*; gunzip < ocf-linux-24-XXXXXXXX.patch.gz | patch -p1
  81349. + cd linux-2.6*; gunzip < ocf-linux-26-XXXXXXXX.patch.gz | patch -p1
  81350. +
  81351. + if you do one of the above, then you can proceed to the next step,
  81352. + or you can do the above process by hand with using the patches against
  81353. + linux-2.4.35 and 2.6.33 to include the ocf code under crypto/ocf.
  81354. + Here's how to add it:
  81355. +
  81356. + for 2.4.35 (and later)
  81357. +
  81358. + cd linux-2.4.35/crypto
  81359. + tar xvzf ocf-linux.tar.gz
  81360. + cd ..
  81361. + patch -p1 < crypto/ocf/patches/linux-2.4.35-ocf.patch
  81362. +
  81363. + for 2.6.23 (and later), find the kernel patch specific (or nearest)
  81364. + to your kernel versions and then:
  81365. +
  81366. + cd linux-2.6.NN/crypto
  81367. + tar xvzf ocf-linux.tar.gz
  81368. + cd ..
  81369. + patch -p1 < crypto/ocf/patches/linux-2.6.NN-ocf.patch
  81370. +
  81371. + It should be easy to take this patch and apply it to other more
  81372. + recent versions of the kernels. The same patches should also work
  81373. + relatively easily on kernels as old as 2.6.11 and 2.4.18.
  81374. +
  81375. + * under 2.4 if you are on a non-x86 platform, you may need to:
  81376. +
  81377. + cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY
  81378. +
  81379. + so that you can build the kernel crypto support needed for the cryptosoft
  81380. + driver.
  81381. +
  81382. + * For simplicity you should enable all the crypto support in your kernel
  81383. + except for the test driver. Likewise for the OCF options. Do not
  81384. + enable OCF crypto drivers for HW that you do not have (for example
  81385. + ixp4xx will not compile on non-Xscale systems).
  81386. +
  81387. + * make sure that cryptodev.h (from ocf-linux.tar.gz) is installed as
  81388. + crypto/cryptodev.h in an include directory that is used for building
  81389. + applications for your platform. For example on a host system that
  81390. + might be:
  81391. +
  81392. + /usr/include/crypto/cryptodev.h
  81393. +
  81394. + * patch your openssl-0.9.8n code with the openssl-0.9.8n.patch.
  81395. + (NOTE: there is no longer a need to patch ssh). The patch is against:
  81396. + openssl-0_9_8e
  81397. +
  81398. + If you need a patch for an older version of openssl, you should look
  81399. + to older OCF releases. This patch is unlikely to work on older
  81400. + openssl versions.
  81401. +
  81402. + openssl-0.9.8n.patch
  81403. + - enables --with-cryptodev for non BSD systems
  81404. + - adds -cpu option to openssl speed for calculating CPU load
  81405. + under linux
  81406. + - fixes null pointer in openssl speed multi thread output.
  81407. + - fixes test keys to work with linux crypto's more stringent
  81408. + key checking.
  81409. + - adds MD5/SHA acceleration (Ronen Shitrit), only enabled
  81410. + with the --with-cryptodev-digests option
  81411. + - fixes bug in engine code caching.
  81412. +
  81413. + * build crypto-tools-XXXXXXXX.tar.gz if you want to try some of the BSD
  81414. + tools for testing OCF (ie., cryptotest).
  81415. +
  81416. +How to load the OCF drivers
  81417. +---------------------------
  81418. +
  81419. + First insert the base modules:
  81420. +
  81421. + insmod ocf
  81422. + insmod cryptodev
  81423. +
  81424. + You can then install the software OCF driver with:
  81425. +
  81426. + insmod cryptosoft
  81427. +
  81428. + and one or more of the OCF HW drivers with:
  81429. +
  81430. + insmod safe
  81431. + insmod hifn7751
  81432. + insmod ixp4xx
  81433. + ...
  81434. +
  81435. + all the drivers take a debug option to enable verbose debug so that
  81436. + you can see what is going on. For debug you load them as:
  81437. +
  81438. + insmod ocf crypto_debug=1
  81439. + insmod cryptodev cryptodev_debug=1
  81440. + insmod cryptosoft swcr_debug=1
  81441. +
  81442. + You may load more than one OCF crypto driver but then there is no guarantee
  81443. + as to which will be used.
  81444. +
  81445. + You can also enable debug at run time on 2.6 systems with the following:
  81446. +
  81447. + echo 1 > /sys/module/ocf/parameters/crypto_debug
  81448. + echo 1 > /sys/module/cryptodev/parameters/cryptodev_debug
  81449. + echo 1 > /sys/module/cryptosoft/parameters/swcr_debug
  81450. + echo 1 > /sys/module/hifn7751/parameters/hifn_debug
  81451. + echo 1 > /sys/module/safe/parameters/safe_debug
  81452. + echo 1 > /sys/module/ixp4xx/parameters/ixp_debug
  81453. + ...
  81454. +
  81455. +Testing the OCF support
  81456. +-----------------------
  81457. +
  81458. + run "cryptotest", it should do a short test for a couple of
  81459. + des packets. If it does everything is working.
  81460. +
  81461. + If this works, then ssh will use the driver when invoked as:
  81462. +
  81463. + ssh -c 3des username@host
  81464. +
  81465. + to see for sure that it is operating, enable debug as defined above.
  81466. +
  81467. + To get a better idea of performance run:
  81468. +
  81469. + cryptotest 100 4096
  81470. +
  81471. + There are more options to cryptotest, see the help.
  81472. +
  81473. + It is also possible to use openssl to test the speed of the crypto
  81474. + drivers.
  81475. +
  81476. + openssl speed -evp des -engine cryptodev -elapsed
  81477. + openssl speed -evp des3 -engine cryptodev -elapsed
  81478. + openssl speed -evp aes128 -engine cryptodev -elapsed
  81479. +
  81480. + and multiple threads (10) with:
  81481. +
  81482. + openssl speed -evp des -engine cryptodev -elapsed -multi 10
  81483. + openssl speed -evp des3 -engine cryptodev -elapsed -multi 10
  81484. + openssl speed -evp aes128 -engine cryptodev -elapsed -multi 10
  81485. +
  81486. + for public key testing you can try:
  81487. +
  81488. + cryptokeytest
  81489. + openssl speed -engine cryptodev rsa -elapsed
  81490. + openssl speed -engine cryptodev dsa -elapsed
  81491. +
  81492. +David McCullough
  81493. +david_mccullough@mcafee.com
  81494. diff -Nur linux-2.6.36.orig/crypto/ocf/rndtest.c linux-2.6.36/crypto/ocf/rndtest.c
  81495. --- linux-2.6.36.orig/crypto/ocf/rndtest.c 1970-01-01 01:00:00.000000000 +0100
  81496. +++ linux-2.6.36/crypto/ocf/rndtest.c 2010-11-09 20:28:12.722495563 +0100
  81497. @@ -0,0 +1,300 @@
  81498. +/* $OpenBSD$ */
  81499. +
  81500. +/*
  81501. + * OCF/Linux port done by David McCullough <david_mccullough@mcafee.com>
  81502. + * Copyright (C) 2006-2010 David McCullough
  81503. + * Copyright (C) 2004-2005 Intel Corporation.
  81504. + * The license and original author are listed below.
  81505. + *
  81506. + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
  81507. + * All rights reserved.
  81508. + *
  81509. + * Redistribution and use in source and binary forms, with or without
  81510. + * modification, are permitted provided that the following conditions
  81511. + * are met:
  81512. + * 1. Redistributions of source code must retain the above copyright
  81513. + * notice, this list of conditions and the following disclaimer.
  81514. + * 2. Redistributions in binary form must reproduce the above copyright
  81515. + * notice, this list of conditions and the following disclaimer in the
  81516. + * documentation and/or other materials provided with the distribution.
  81517. + * 3. All advertising materials mentioning features or use of this software
  81518. + * must display the following acknowledgement:
  81519. + * This product includes software developed by Jason L. Wright
  81520. + * 4. The name of the author may not be used to endorse or promote products
  81521. + * derived from this software without specific prior written permission.
  81522. + *
  81523. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  81524. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  81525. + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  81526. + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  81527. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  81528. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  81529. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  81530. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  81531. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  81532. + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  81533. + * POSSIBILITY OF SUCH DAMAGE.
  81534. + */
  81535. +
  81536. +#ifndef AUTOCONF_INCLUDED
  81537. +#include <linux/config.h>
  81538. +#endif
  81539. +#include <linux/module.h>
  81540. +#include <linux/list.h>
  81541. +#include <linux/wait.h>
  81542. +#include <linux/time.h>
  81543. +#include <linux/version.h>
  81544. +#include <linux/unistd.h>
  81545. +#include <linux/kernel.h>
  81546. +#include <linux/string.h>
  81547. +#include <linux/time.h>
  81548. +#include <cryptodev.h>
  81549. +#include "rndtest.h"
  81550. +
  81551. +static struct rndtest_stats rndstats;
  81552. +
  81553. +static void rndtest_test(struct rndtest_state *);
  81554. +
  81555. +/* The tests themselves */
  81556. +static int rndtest_monobit(struct rndtest_state *);
  81557. +static int rndtest_runs(struct rndtest_state *);
  81558. +static int rndtest_longruns(struct rndtest_state *);
  81559. +static int rndtest_chi_4(struct rndtest_state *);
  81560. +
  81561. +static int rndtest_runs_check(struct rndtest_state *, int, int *);
  81562. +static void rndtest_runs_record(struct rndtest_state *, int, int *);
  81563. +
  81564. +static const struct rndtest_testfunc {
  81565. + int (*test)(struct rndtest_state *);
  81566. +} rndtest_funcs[] = {
  81567. + { rndtest_monobit },
  81568. + { rndtest_runs },
  81569. + { rndtest_chi_4 },
  81570. + { rndtest_longruns },
  81571. +};
  81572. +
  81573. +#define RNDTEST_NTESTS (sizeof(rndtest_funcs)/sizeof(rndtest_funcs[0]))
  81574. +
  81575. +static void
  81576. +rndtest_test(struct rndtest_state *rsp)
  81577. +{
  81578. + int i, rv = 0;
  81579. +
  81580. + rndstats.rst_tests++;
  81581. + for (i = 0; i < RNDTEST_NTESTS; i++)
  81582. + rv |= (*rndtest_funcs[i].test)(rsp);
  81583. + rsp->rs_discard = (rv != 0);
  81584. +}
  81585. +
  81586. +
  81587. +extern int crypto_debug;
  81588. +#define rndtest_verbose 2
  81589. +#define rndtest_report(rsp, failure, fmt, a...) \
  81590. + { if (failure || crypto_debug) { printk("rng_test: " fmt "\n", a); } else; }
  81591. +
  81592. +#define RNDTEST_MONOBIT_MINONES 9725
  81593. +#define RNDTEST_MONOBIT_MAXONES 10275
  81594. +
  81595. +static int
  81596. +rndtest_monobit(struct rndtest_state *rsp)
  81597. +{
  81598. + int i, ones = 0, j;
  81599. + u_int8_t r;
  81600. +
  81601. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  81602. + r = rsp->rs_buf[i];
  81603. + for (j = 0; j < 8; j++, r <<= 1)
  81604. + if (r & 0x80)
  81605. + ones++;
  81606. + }
  81607. + if (ones > RNDTEST_MONOBIT_MINONES &&
  81608. + ones < RNDTEST_MONOBIT_MAXONES) {
  81609. + if (rndtest_verbose > 1)
  81610. + rndtest_report(rsp, 0, "monobit pass (%d < %d < %d)",
  81611. + RNDTEST_MONOBIT_MINONES, ones,
  81612. + RNDTEST_MONOBIT_MAXONES);
  81613. + return (0);
  81614. + } else {
  81615. + if (rndtest_verbose)
  81616. + rndtest_report(rsp, 1,
  81617. + "monobit failed (%d ones)", ones);
  81618. + rndstats.rst_monobit++;
  81619. + return (-1);
  81620. + }
  81621. +}
  81622. +
  81623. +#define RNDTEST_RUNS_NINTERVAL 6
  81624. +
  81625. +static const struct rndtest_runs_tabs {
  81626. + u_int16_t min, max;
  81627. +} rndtest_runs_tab[] = {
  81628. + { 2343, 2657 },
  81629. + { 1135, 1365 },
  81630. + { 542, 708 },
  81631. + { 251, 373 },
  81632. + { 111, 201 },
  81633. + { 111, 201 },
  81634. +};
  81635. +
  81636. +static int
  81637. +rndtest_runs(struct rndtest_state *rsp)
  81638. +{
  81639. + int i, j, ones, zeros, rv = 0;
  81640. + int onei[RNDTEST_RUNS_NINTERVAL], zeroi[RNDTEST_RUNS_NINTERVAL];
  81641. + u_int8_t c;
  81642. +
  81643. + bzero(onei, sizeof(onei));
  81644. + bzero(zeroi, sizeof(zeroi));
  81645. + ones = zeros = 0;
  81646. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  81647. + c = rsp->rs_buf[i];
  81648. + for (j = 0; j < 8; j++, c <<= 1) {
  81649. + if (c & 0x80) {
  81650. + ones++;
  81651. + rndtest_runs_record(rsp, zeros, zeroi);
  81652. + zeros = 0;
  81653. + } else {
  81654. + zeros++;
  81655. + rndtest_runs_record(rsp, ones, onei);
  81656. + ones = 0;
  81657. + }
  81658. + }
  81659. + }
  81660. + rndtest_runs_record(rsp, ones, onei);
  81661. + rndtest_runs_record(rsp, zeros, zeroi);
  81662. +
  81663. + rv |= rndtest_runs_check(rsp, 0, zeroi);
  81664. + rv |= rndtest_runs_check(rsp, 1, onei);
  81665. +
  81666. + if (rv)
  81667. + rndstats.rst_runs++;
  81668. +
  81669. + return (rv);
  81670. +}
  81671. +
  81672. +static void
  81673. +rndtest_runs_record(struct rndtest_state *rsp, int len, int *intrv)
  81674. +{
  81675. + if (len == 0)
  81676. + return;
  81677. + if (len > RNDTEST_RUNS_NINTERVAL)
  81678. + len = RNDTEST_RUNS_NINTERVAL;
  81679. + len -= 1;
  81680. + intrv[len]++;
  81681. +}
  81682. +
  81683. +static int
  81684. +rndtest_runs_check(struct rndtest_state *rsp, int val, int *src)
  81685. +{
  81686. + int i, rv = 0;
  81687. +
  81688. + for (i = 0; i < RNDTEST_RUNS_NINTERVAL; i++) {
  81689. + if (src[i] < rndtest_runs_tab[i].min ||
  81690. + src[i] > rndtest_runs_tab[i].max) {
  81691. + rndtest_report(rsp, 1,
  81692. + "%s interval %d failed (%d, %d-%d)",
  81693. + val ? "ones" : "zeros",
  81694. + i + 1, src[i], rndtest_runs_tab[i].min,
  81695. + rndtest_runs_tab[i].max);
  81696. + rv = -1;
  81697. + } else {
  81698. + rndtest_report(rsp, 0,
  81699. + "runs pass %s interval %d (%d < %d < %d)",
  81700. + val ? "ones" : "zeros",
  81701. + i + 1, rndtest_runs_tab[i].min, src[i],
  81702. + rndtest_runs_tab[i].max);
  81703. + }
  81704. + }
  81705. + return (rv);
  81706. +}
  81707. +
  81708. +static int
  81709. +rndtest_longruns(struct rndtest_state *rsp)
  81710. +{
  81711. + int i, j, ones = 0, zeros = 0, maxones = 0, maxzeros = 0;
  81712. + u_int8_t c;
  81713. +
  81714. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  81715. + c = rsp->rs_buf[i];
  81716. + for (j = 0; j < 8; j++, c <<= 1) {
  81717. + if (c & 0x80) {
  81718. + zeros = 0;
  81719. + ones++;
  81720. + if (ones > maxones)
  81721. + maxones = ones;
  81722. + } else {
  81723. + ones = 0;
  81724. + zeros++;
  81725. + if (zeros > maxzeros)
  81726. + maxzeros = zeros;
  81727. + }
  81728. + }
  81729. + }
  81730. +
  81731. + if (maxones < 26 && maxzeros < 26) {
  81732. + rndtest_report(rsp, 0, "longruns pass (%d ones, %d zeros)",
  81733. + maxones, maxzeros);
  81734. + return (0);
  81735. + } else {
  81736. + rndtest_report(rsp, 1, "longruns fail (%d ones, %d zeros)",
  81737. + maxones, maxzeros);
  81738. + rndstats.rst_longruns++;
  81739. + return (-1);
  81740. + }
  81741. +}
  81742. +
  81743. +/*
  81744. + * chi^2 test over 4 bits: (this is called the poker test in FIPS 140-2,
  81745. + * but it is really the chi^2 test over 4 bits (the poker test as described
  81746. + * by Knuth vol 2 is something different, and I take him as authoritative
  81747. + * on nomenclature over NIST).
  81748. + */
  81749. +#define RNDTEST_CHI4_K 16
  81750. +#define RNDTEST_CHI4_K_MASK (RNDTEST_CHI4_K - 1)
  81751. +
  81752. +/*
  81753. + * The unnormalized values are used so that we don't have to worry about
  81754. + * fractional precision. The "real" value is found by:
  81755. + * (V - 1562500) * (16 / 5000) = Vn (where V is the unnormalized value)
  81756. + */
  81757. +#define RNDTEST_CHI4_VMIN 1563181 /* 2.1792 */
  81758. +#define RNDTEST_CHI4_VMAX 1576929 /* 46.1728 */
  81759. +
  81760. +static int
  81761. +rndtest_chi_4(struct rndtest_state *rsp)
  81762. +{
  81763. + unsigned int freq[RNDTEST_CHI4_K], i, sum;
  81764. +
  81765. + for (i = 0; i < RNDTEST_CHI4_K; i++)
  81766. + freq[i] = 0;
  81767. +
  81768. + /* Get number of occurances of each 4 bit pattern */
  81769. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  81770. + freq[(rsp->rs_buf[i] >> 4) & RNDTEST_CHI4_K_MASK]++;
  81771. + freq[(rsp->rs_buf[i] >> 0) & RNDTEST_CHI4_K_MASK]++;
  81772. + }
  81773. +
  81774. + for (i = 0, sum = 0; i < RNDTEST_CHI4_K; i++)
  81775. + sum += freq[i] * freq[i];
  81776. +
  81777. + if (sum >= 1563181 && sum <= 1576929) {
  81778. + rndtest_report(rsp, 0, "chi^2(4): pass (sum %u)", sum);
  81779. + return (0);
  81780. + } else {
  81781. + rndtest_report(rsp, 1, "chi^2(4): failed (sum %u)", sum);
  81782. + rndstats.rst_chi++;
  81783. + return (-1);
  81784. + }
  81785. +}
  81786. +
  81787. +int
  81788. +rndtest_buf(unsigned char *buf)
  81789. +{
  81790. + struct rndtest_state rsp;
  81791. +
  81792. + memset(&rsp, 0, sizeof(rsp));
  81793. + rsp.rs_buf = buf;
  81794. + rndtest_test(&rsp);
  81795. + return(rsp.rs_discard);
  81796. +}
  81797. +
  81798. diff -Nur linux-2.6.36.orig/crypto/ocf/rndtest.h linux-2.6.36/crypto/ocf/rndtest.h
  81799. --- linux-2.6.36.orig/crypto/ocf/rndtest.h 1970-01-01 01:00:00.000000000 +0100
  81800. +++ linux-2.6.36/crypto/ocf/rndtest.h 2010-11-09 20:28:12.762495556 +0100
  81801. @@ -0,0 +1,54 @@
  81802. +/* $FreeBSD: src/sys/dev/rndtest/rndtest.h,v 1.1 2003/03/11 22:54:44 sam Exp $ */
  81803. +/* $OpenBSD$ */
  81804. +
  81805. +/*
  81806. + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
  81807. + * All rights reserved.
  81808. + *
  81809. + * Redistribution and use in source and binary forms, with or without
  81810. + * modification, are permitted provided that the following conditions
  81811. + * are met:
  81812. + * 1. Redistributions of source code must retain the above copyright
  81813. + * notice, this list of conditions and the following disclaimer.
  81814. + * 2. Redistributions in binary form must reproduce the above copyright
  81815. + * notice, this list of conditions and the following disclaimer in the
  81816. + * documentation and/or other materials provided with the distribution.
  81817. + * 3. All advertising materials mentioning features or use of this software
  81818. + * must display the following acknowledgement:
  81819. + * This product includes software developed by Jason L. Wright
  81820. + * 4. The name of the author may not be used to endorse or promote products
  81821. + * derived from this software without specific prior written permission.
  81822. + *
  81823. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  81824. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  81825. + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  81826. + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  81827. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  81828. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  81829. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  81830. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  81831. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  81832. + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  81833. + * POSSIBILITY OF SUCH DAMAGE.
  81834. + */
  81835. +
  81836. +
  81837. +/* Some of the tests depend on these values */
  81838. +#define RNDTEST_NBYTES 2500
  81839. +#define RNDTEST_NBITS (8 * RNDTEST_NBYTES)
  81840. +
  81841. +struct rndtest_state {
  81842. + int rs_discard; /* discard/accept random data */
  81843. + u_int8_t *rs_buf;
  81844. +};
  81845. +
  81846. +struct rndtest_stats {
  81847. + u_int32_t rst_discard; /* number of bytes discarded */
  81848. + u_int32_t rst_tests; /* number of test runs */
  81849. + u_int32_t rst_monobit; /* monobit test failures */
  81850. + u_int32_t rst_runs; /* 0/1 runs failures */
  81851. + u_int32_t rst_longruns; /* longruns failures */
  81852. + u_int32_t rst_chi; /* chi^2 failures */
  81853. +};
  81854. +
  81855. +extern int rndtest_buf(unsigned char *buf);
  81856. diff -Nur linux-2.6.36.orig/crypto/ocf/safe/Makefile linux-2.6.36/crypto/ocf/safe/Makefile
  81857. --- linux-2.6.36.orig/crypto/ocf/safe/Makefile 1970-01-01 01:00:00.000000000 +0100
  81858. +++ linux-2.6.36/crypto/ocf/safe/Makefile 2010-11-09 20:28:12.805576889 +0100
  81859. @@ -0,0 +1,12 @@
  81860. +# for SGlinux builds
  81861. +-include $(ROOTDIR)/modules/.config
  81862. +
  81863. +obj-$(CONFIG_OCF_SAFE) += safe.o
  81864. +
  81865. +obj ?= .
  81866. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  81867. +
  81868. +ifdef TOPDIR
  81869. +-include $(TOPDIR)/Rules.make
  81870. +endif
  81871. +
  81872. diff -Nur linux-2.6.36.orig/crypto/ocf/safe/md5.c linux-2.6.36/crypto/ocf/safe/md5.c
  81873. --- linux-2.6.36.orig/crypto/ocf/safe/md5.c 1970-01-01 01:00:00.000000000 +0100
  81874. +++ linux-2.6.36/crypto/ocf/safe/md5.c 2010-11-09 20:28:12.842495449 +0100
  81875. @@ -0,0 +1,308 @@
  81876. +/* $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
  81877. +/*
  81878. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  81879. + * All rights reserved.
  81880. + *
  81881. + * Redistribution and use in source and binary forms, with or without
  81882. + * modification, are permitted provided that the following conditions
  81883. + * are met:
  81884. + * 1. Redistributions of source code must retain the above copyright
  81885. + * notice, this list of conditions and the following disclaimer.
  81886. + * 2. Redistributions in binary form must reproduce the above copyright
  81887. + * notice, this list of conditions and the following disclaimer in the
  81888. + * documentation and/or other materials provided with the distribution.
  81889. + * 3. Neither the name of the project nor the names of its contributors
  81890. + * may be used to endorse or promote products derived from this software
  81891. + * without specific prior written permission.
  81892. + *
  81893. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  81894. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  81895. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  81896. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  81897. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  81898. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  81899. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  81900. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  81901. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  81902. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  81903. + * SUCH DAMAGE.
  81904. + */
  81905. +
  81906. +#if 0
  81907. +#include <sys/cdefs.h>
  81908. +__FBSDID("$FreeBSD: src/sys/crypto/md5.c,v 1.9 2004/01/27 19:49:19 des Exp $");
  81909. +
  81910. +#include <sys/types.h>
  81911. +#include <sys/cdefs.h>
  81912. +#include <sys/time.h>
  81913. +#include <sys/systm.h>
  81914. +#include <crypto/md5.h>
  81915. +#endif
  81916. +
  81917. +#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
  81918. +
  81919. +#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
  81920. +#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
  81921. +#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
  81922. +#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
  81923. +
  81924. +#define ROUND1(a, b, c, d, k, s, i) { \
  81925. + (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
  81926. + (a) = SHIFT((a), (s)); \
  81927. + (a) = (b) + (a); \
  81928. +}
  81929. +
  81930. +#define ROUND2(a, b, c, d, k, s, i) { \
  81931. + (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
  81932. + (a) = SHIFT((a), (s)); \
  81933. + (a) = (b) + (a); \
  81934. +}
  81935. +
  81936. +#define ROUND3(a, b, c, d, k, s, i) { \
  81937. + (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
  81938. + (a) = SHIFT((a), (s)); \
  81939. + (a) = (b) + (a); \
  81940. +}
  81941. +
  81942. +#define ROUND4(a, b, c, d, k, s, i) { \
  81943. + (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
  81944. + (a) = SHIFT((a), (s)); \
  81945. + (a) = (b) + (a); \
  81946. +}
  81947. +
  81948. +#define Sa 7
  81949. +#define Sb 12
  81950. +#define Sc 17
  81951. +#define Sd 22
  81952. +
  81953. +#define Se 5
  81954. +#define Sf 9
  81955. +#define Sg 14
  81956. +#define Sh 20
  81957. +
  81958. +#define Si 4
  81959. +#define Sj 11
  81960. +#define Sk 16
  81961. +#define Sl 23
  81962. +
  81963. +#define Sm 6
  81964. +#define Sn 10
  81965. +#define So 15
  81966. +#define Sp 21
  81967. +
  81968. +#define MD5_A0 0x67452301
  81969. +#define MD5_B0 0xefcdab89
  81970. +#define MD5_C0 0x98badcfe
  81971. +#define MD5_D0 0x10325476
  81972. +
  81973. +/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
  81974. +static const u_int32_t T[65] = {
  81975. + 0,
  81976. + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
  81977. + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
  81978. + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
  81979. + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
  81980. +
  81981. + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
  81982. + 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
  81983. + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
  81984. + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
  81985. +
  81986. + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
  81987. + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
  81988. + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
  81989. + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
  81990. +
  81991. + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
  81992. + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
  81993. + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
  81994. + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
  81995. +};
  81996. +
  81997. +static const u_int8_t md5_paddat[MD5_BUFLEN] = {
  81998. + 0x80, 0, 0, 0, 0, 0, 0, 0,
  81999. + 0, 0, 0, 0, 0, 0, 0, 0,
  82000. + 0, 0, 0, 0, 0, 0, 0, 0,
  82001. + 0, 0, 0, 0, 0, 0, 0, 0,
  82002. + 0, 0, 0, 0, 0, 0, 0, 0,
  82003. + 0, 0, 0, 0, 0, 0, 0, 0,
  82004. + 0, 0, 0, 0, 0, 0, 0, 0,
  82005. + 0, 0, 0, 0, 0, 0, 0, 0,
  82006. +};
  82007. +
  82008. +static void md5_calc(u_int8_t *, md5_ctxt *);
  82009. +
  82010. +void md5_init(ctxt)
  82011. + md5_ctxt *ctxt;
  82012. +{
  82013. + ctxt->md5_n = 0;
  82014. + ctxt->md5_i = 0;
  82015. + ctxt->md5_sta = MD5_A0;
  82016. + ctxt->md5_stb = MD5_B0;
  82017. + ctxt->md5_stc = MD5_C0;
  82018. + ctxt->md5_std = MD5_D0;
  82019. + bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
  82020. +}
  82021. +
  82022. +void md5_loop(ctxt, input, len)
  82023. + md5_ctxt *ctxt;
  82024. + u_int8_t *input;
  82025. + u_int len; /* number of bytes */
  82026. +{
  82027. + u_int gap, i;
  82028. +
  82029. + ctxt->md5_n += len * 8; /* byte to bit */
  82030. + gap = MD5_BUFLEN - ctxt->md5_i;
  82031. +
  82032. + if (len >= gap) {
  82033. + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  82034. + gap);
  82035. + md5_calc(ctxt->md5_buf, ctxt);
  82036. +
  82037. + for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
  82038. + md5_calc((u_int8_t *)(input + i), ctxt);
  82039. + }
  82040. +
  82041. + ctxt->md5_i = len - i;
  82042. + bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
  82043. + } else {
  82044. + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  82045. + len);
  82046. + ctxt->md5_i += len;
  82047. + }
  82048. +}
  82049. +
  82050. +void md5_pad(ctxt)
  82051. + md5_ctxt *ctxt;
  82052. +{
  82053. + u_int gap;
  82054. +
  82055. + /* Don't count up padding. Keep md5_n. */
  82056. + gap = MD5_BUFLEN - ctxt->md5_i;
  82057. + if (gap > 8) {
  82058. + bcopy(md5_paddat,
  82059. + (void *)(ctxt->md5_buf + ctxt->md5_i),
  82060. + gap - sizeof(ctxt->md5_n));
  82061. + } else {
  82062. + /* including gap == 8 */
  82063. + bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
  82064. + gap);
  82065. + md5_calc(ctxt->md5_buf, ctxt);
  82066. + bcopy((md5_paddat + gap),
  82067. + (void *)ctxt->md5_buf,
  82068. + MD5_BUFLEN - sizeof(ctxt->md5_n));
  82069. + }
  82070. +
  82071. + /* 8 byte word */
  82072. +#if BYTE_ORDER == LITTLE_ENDIAN
  82073. + bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
  82074. +#endif
  82075. +#if BYTE_ORDER == BIG_ENDIAN
  82076. + ctxt->md5_buf[56] = ctxt->md5_n8[7];
  82077. + ctxt->md5_buf[57] = ctxt->md5_n8[6];
  82078. + ctxt->md5_buf[58] = ctxt->md5_n8[5];
  82079. + ctxt->md5_buf[59] = ctxt->md5_n8[4];
  82080. + ctxt->md5_buf[60] = ctxt->md5_n8[3];
  82081. + ctxt->md5_buf[61] = ctxt->md5_n8[2];
  82082. + ctxt->md5_buf[62] = ctxt->md5_n8[1];
  82083. + ctxt->md5_buf[63] = ctxt->md5_n8[0];
  82084. +#endif
  82085. +
  82086. + md5_calc(ctxt->md5_buf, ctxt);
  82087. +}
  82088. +
  82089. +void md5_result(digest, ctxt)
  82090. + u_int8_t *digest;
  82091. + md5_ctxt *ctxt;
  82092. +{
  82093. + /* 4 byte words */
  82094. +#if BYTE_ORDER == LITTLE_ENDIAN
  82095. + bcopy(&ctxt->md5_st8[0], digest, 16);
  82096. +#endif
  82097. +#if BYTE_ORDER == BIG_ENDIAN
  82098. + digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
  82099. + digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
  82100. + digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
  82101. + digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
  82102. + digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
  82103. + digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
  82104. + digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
  82105. + digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
  82106. +#endif
  82107. +}
  82108. +
  82109. +static void md5_calc(b64, ctxt)
  82110. + u_int8_t *b64;
  82111. + md5_ctxt *ctxt;
  82112. +{
  82113. + u_int32_t A = ctxt->md5_sta;
  82114. + u_int32_t B = ctxt->md5_stb;
  82115. + u_int32_t C = ctxt->md5_stc;
  82116. + u_int32_t D = ctxt->md5_std;
  82117. +#if BYTE_ORDER == LITTLE_ENDIAN
  82118. + u_int32_t *X = (u_int32_t *)b64;
  82119. +#endif
  82120. +#if BYTE_ORDER == BIG_ENDIAN
  82121. + /* 4 byte words */
  82122. + /* what a brute force but fast! */
  82123. + u_int32_t X[16];
  82124. + u_int8_t *y = (u_int8_t *)X;
  82125. + y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
  82126. + y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
  82127. + y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
  82128. + y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
  82129. + y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
  82130. + y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
  82131. + y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
  82132. + y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
  82133. + y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
  82134. + y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
  82135. + y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
  82136. + y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
  82137. + y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
  82138. + y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
  82139. + y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
  82140. + y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
  82141. +#endif
  82142. +
  82143. + ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
  82144. + ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
  82145. + ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
  82146. + ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
  82147. + ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
  82148. + ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
  82149. + ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
  82150. + ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
  82151. +
  82152. + ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
  82153. + ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
  82154. + ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
  82155. + ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
  82156. + ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
  82157. + ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
  82158. + ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
  82159. + ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
  82160. +
  82161. + ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
  82162. + ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
  82163. + ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
  82164. + ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
  82165. + ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
  82166. + ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
  82167. + ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
  82168. + ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
  82169. +
  82170. + ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
  82171. + ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
  82172. + ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
  82173. + ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
  82174. + ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
  82175. + ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
  82176. + ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
  82177. + ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
  82178. +
  82179. + ctxt->md5_sta += A;
  82180. + ctxt->md5_stb += B;
  82181. + ctxt->md5_stc += C;
  82182. + ctxt->md5_std += D;
  82183. +}
  82184. diff -Nur linux-2.6.36.orig/crypto/ocf/safe/md5.h linux-2.6.36/crypto/ocf/safe/md5.h
  82185. --- linux-2.6.36.orig/crypto/ocf/safe/md5.h 1970-01-01 01:00:00.000000000 +0100
  82186. +++ linux-2.6.36/crypto/ocf/safe/md5.h 2010-11-09 20:28:12.881683669 +0100
  82187. @@ -0,0 +1,76 @@
  82188. +/* $FreeBSD: src/sys/crypto/md5.h,v 1.4 2002/03/20 05:13:50 alfred Exp $ */
  82189. +/* $KAME: md5.h,v 1.4 2000/03/27 04:36:22 sumikawa Exp $ */
  82190. +
  82191. +/*
  82192. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  82193. + * All rights reserved.
  82194. + *
  82195. + * Redistribution and use in source and binary forms, with or without
  82196. + * modification, are permitted provided that the following conditions
  82197. + * are met:
  82198. + * 1. Redistributions of source code must retain the above copyright
  82199. + * notice, this list of conditions and the following disclaimer.
  82200. + * 2. Redistributions in binary form must reproduce the above copyright
  82201. + * notice, this list of conditions and the following disclaimer in the
  82202. + * documentation and/or other materials provided with the distribution.
  82203. + * 3. Neither the name of the project nor the names of its contributors
  82204. + * may be used to endorse or promote products derived from this software
  82205. + * without specific prior written permission.
  82206. + *
  82207. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  82208. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  82209. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  82210. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  82211. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  82212. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  82213. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  82214. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  82215. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  82216. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  82217. + * SUCH DAMAGE.
  82218. + */
  82219. +
  82220. +#ifndef _NETINET6_MD5_H_
  82221. +#define _NETINET6_MD5_H_
  82222. +
  82223. +#define MD5_BUFLEN 64
  82224. +
  82225. +typedef struct {
  82226. + union {
  82227. + u_int32_t md5_state32[4];
  82228. + u_int8_t md5_state8[16];
  82229. + } md5_st;
  82230. +
  82231. +#define md5_sta md5_st.md5_state32[0]
  82232. +#define md5_stb md5_st.md5_state32[1]
  82233. +#define md5_stc md5_st.md5_state32[2]
  82234. +#define md5_std md5_st.md5_state32[3]
  82235. +#define md5_st8 md5_st.md5_state8
  82236. +
  82237. + union {
  82238. + u_int64_t md5_count64;
  82239. + u_int8_t md5_count8[8];
  82240. + } md5_count;
  82241. +#define md5_n md5_count.md5_count64
  82242. +#define md5_n8 md5_count.md5_count8
  82243. +
  82244. + u_int md5_i;
  82245. + u_int8_t md5_buf[MD5_BUFLEN];
  82246. +} md5_ctxt;
  82247. +
  82248. +extern void md5_init(md5_ctxt *);
  82249. +extern void md5_loop(md5_ctxt *, u_int8_t *, u_int);
  82250. +extern void md5_pad(md5_ctxt *);
  82251. +extern void md5_result(u_int8_t *, md5_ctxt *);
  82252. +
  82253. +/* compatibility */
  82254. +#define MD5_CTX md5_ctxt
  82255. +#define MD5Init(x) md5_init((x))
  82256. +#define MD5Update(x, y, z) md5_loop((x), (y), (z))
  82257. +#define MD5Final(x, y) \
  82258. +do { \
  82259. + md5_pad((y)); \
  82260. + md5_result((x), (y)); \
  82261. +} while (0)
  82262. +
  82263. +#endif /* ! _NETINET6_MD5_H_*/
  82264. diff -Nur linux-2.6.36.orig/crypto/ocf/safe/safe.c linux-2.6.36/crypto/ocf/safe/safe.c
  82265. --- linux-2.6.36.orig/crypto/ocf/safe/safe.c 1970-01-01 01:00:00.000000000 +0100
  82266. +++ linux-2.6.36/crypto/ocf/safe/safe.c 2010-11-09 20:28:12.922204086 +0100
  82267. @@ -0,0 +1,2288 @@
  82268. +/*-
  82269. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  82270. + * Copyright (C) 2004-2010 David McCullough
  82271. + * The license and original author are listed below.
  82272. + *
  82273. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  82274. + * Copyright (c) 2003 Global Technology Associates, Inc.
  82275. + * All rights reserved.
  82276. + *
  82277. + * Redistribution and use in source and binary forms, with or without
  82278. + * modification, are permitted provided that the following conditions
  82279. + * are met:
  82280. + * 1. Redistributions of source code must retain the above copyright
  82281. + * notice, this list of conditions and the following disclaimer.
  82282. + * 2. Redistributions in binary form must reproduce the above copyright
  82283. + * notice, this list of conditions and the following disclaimer in the
  82284. + * documentation and/or other materials provided with the distribution.
  82285. + *
  82286. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  82287. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  82288. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  82289. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  82290. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  82291. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  82292. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  82293. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  82294. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  82295. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  82296. + * SUCH DAMAGE.
  82297. + *
  82298. +__FBSDID("$FreeBSD: src/sys/dev/safe/safe.c,v 1.18 2007/03/21 03:42:50 sam Exp $");
  82299. + */
  82300. +
  82301. +#ifndef AUTOCONF_INCLUDED
  82302. +#include <linux/config.h>
  82303. +#endif
  82304. +#include <linux/module.h>
  82305. +#include <linux/kernel.h>
  82306. +#include <linux/init.h>
  82307. +#include <linux/list.h>
  82308. +#include <linux/slab.h>
  82309. +#include <linux/wait.h>
  82310. +#include <linux/sched.h>
  82311. +#include <linux/pci.h>
  82312. +#include <linux/delay.h>
  82313. +#include <linux/interrupt.h>
  82314. +#include <linux/spinlock.h>
  82315. +#include <linux/random.h>
  82316. +#include <linux/version.h>
  82317. +#include <linux/skbuff.h>
  82318. +#include <asm/io.h>
  82319. +
  82320. +/*
  82321. + * SafeNet SafeXcel-1141 hardware crypto accelerator
  82322. + */
  82323. +
  82324. +#include <cryptodev.h>
  82325. +#include <uio.h>
  82326. +#include <safe/safereg.h>
  82327. +#include <safe/safevar.h>
  82328. +
  82329. +#if 1
  82330. +#define DPRINTF(a) do { \
  82331. + if (debug) { \
  82332. + printk("%s: ", sc ? \
  82333. + device_get_nameunit(sc->sc_dev) : "safe"); \
  82334. + printk a; \
  82335. + } \
  82336. + } while (0)
  82337. +#else
  82338. +#define DPRINTF(a)
  82339. +#endif
  82340. +
  82341. +/*
  82342. + * until we find a cleaner way, include the BSD md5/sha1 code
  82343. + * here
  82344. + */
  82345. +#define HMAC_HACK 1
  82346. +#ifdef HMAC_HACK
  82347. +#define LITTLE_ENDIAN 1234
  82348. +#define BIG_ENDIAN 4321
  82349. +#ifdef __LITTLE_ENDIAN
  82350. +#define BYTE_ORDER LITTLE_ENDIAN
  82351. +#endif
  82352. +#ifdef __BIG_ENDIAN
  82353. +#define BYTE_ORDER BIG_ENDIAN
  82354. +#endif
  82355. +#include <safe/md5.h>
  82356. +#include <safe/md5.c>
  82357. +#include <safe/sha1.h>
  82358. +#include <safe/sha1.c>
  82359. +
  82360. +u_int8_t hmac_ipad_buffer[64] = {
  82361. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  82362. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  82363. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  82364. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  82365. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  82366. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  82367. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  82368. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
  82369. +};
  82370. +
  82371. +u_int8_t hmac_opad_buffer[64] = {
  82372. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  82373. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  82374. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  82375. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  82376. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  82377. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  82378. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  82379. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
  82380. +};
  82381. +#endif /* HMAC_HACK */
  82382. +
  82383. +/* add proc entry for this */
  82384. +struct safe_stats safestats;
  82385. +
  82386. +#define debug safe_debug
  82387. +int safe_debug = 0;
  82388. +module_param(safe_debug, int, 0644);
  82389. +MODULE_PARM_DESC(safe_debug, "Enable debug");
  82390. +
  82391. +static void safe_callback(struct safe_softc *, struct safe_ringentry *);
  82392. +static void safe_feed(struct safe_softc *, struct safe_ringentry *);
  82393. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  82394. +static void safe_rng_init(struct safe_softc *);
  82395. +int safe_rngbufsize = 8; /* 32 bytes each read */
  82396. +module_param(safe_rngbufsize, int, 0644);
  82397. +MODULE_PARM_DESC(safe_rngbufsize, "RNG polling buffer size (32-bit words)");
  82398. +int safe_rngmaxalarm = 8; /* max alarms before reset */
  82399. +module_param(safe_rngmaxalarm, int, 0644);
  82400. +MODULE_PARM_DESC(safe_rngmaxalarm, "RNG max alarms before reset");
  82401. +#endif /* SAFE_NO_RNG */
  82402. +
  82403. +static void safe_totalreset(struct safe_softc *sc);
  82404. +static int safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op);
  82405. +static int safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op);
  82406. +static int safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re);
  82407. +static int safe_kprocess(device_t dev, struct cryptkop *krp, int hint);
  82408. +static int safe_kstart(struct safe_softc *sc);
  82409. +static int safe_ksigbits(struct safe_softc *sc, struct crparam *cr);
  82410. +static void safe_kfeed(struct safe_softc *sc);
  82411. +static void safe_kpoll(unsigned long arg);
  82412. +static void safe_kload_reg(struct safe_softc *sc, u_int32_t off,
  82413. + u_int32_t len, struct crparam *n);
  82414. +
  82415. +static int safe_newsession(device_t, u_int32_t *, struct cryptoini *);
  82416. +static int safe_freesession(device_t, u_int64_t);
  82417. +static int safe_process(device_t, struct cryptop *, int);
  82418. +
  82419. +static device_method_t safe_methods = {
  82420. + /* crypto device methods */
  82421. + DEVMETHOD(cryptodev_newsession, safe_newsession),
  82422. + DEVMETHOD(cryptodev_freesession,safe_freesession),
  82423. + DEVMETHOD(cryptodev_process, safe_process),
  82424. + DEVMETHOD(cryptodev_kprocess, safe_kprocess),
  82425. +};
  82426. +
  82427. +#define READ_REG(sc,r) readl((sc)->sc_base_addr + (r))
  82428. +#define WRITE_REG(sc,r,val) writel((val), (sc)->sc_base_addr + (r))
  82429. +
  82430. +#define SAFE_MAX_CHIPS 8
  82431. +static struct safe_softc *safe_chip_idx[SAFE_MAX_CHIPS];
  82432. +
  82433. +/*
  82434. + * split our buffers up into safe DMAable byte fragments to avoid lockup
  82435. + * bug in 1141 HW on rev 1.0.
  82436. + */
  82437. +
  82438. +static int
  82439. +pci_map_linear(
  82440. + struct safe_softc *sc,
  82441. + struct safe_operand *buf,
  82442. + void *addr,
  82443. + int len)
  82444. +{
  82445. + dma_addr_t tmp;
  82446. + int chunk, tlen = len;
  82447. +
  82448. + tmp = pci_map_single(sc->sc_pcidev, addr, len, PCI_DMA_BIDIRECTIONAL);
  82449. +
  82450. + buf->mapsize += len;
  82451. + while (len > 0) {
  82452. + chunk = (len > sc->sc_max_dsize) ? sc->sc_max_dsize : len;
  82453. + buf->segs[buf->nsegs].ds_addr = tmp;
  82454. + buf->segs[buf->nsegs].ds_len = chunk;
  82455. + buf->segs[buf->nsegs].ds_tlen = tlen;
  82456. + buf->nsegs++;
  82457. + tmp += chunk;
  82458. + len -= chunk;
  82459. + tlen = 0;
  82460. + }
  82461. + return 0;
  82462. +}
  82463. +
  82464. +/*
  82465. + * map in a given uio buffer (great on some arches :-)
  82466. + */
  82467. +
  82468. +static int
  82469. +pci_map_uio(struct safe_softc *sc, struct safe_operand *buf, struct uio *uio)
  82470. +{
  82471. + struct iovec *iov = uio->uio_iov;
  82472. + int n;
  82473. +
  82474. + DPRINTF(("%s()\n", __FUNCTION__));
  82475. +
  82476. + buf->mapsize = 0;
  82477. + buf->nsegs = 0;
  82478. +
  82479. + for (n = 0; n < uio->uio_iovcnt; n++) {
  82480. + pci_map_linear(sc, buf, iov->iov_base, iov->iov_len);
  82481. + iov++;
  82482. + }
  82483. +
  82484. + /* identify this buffer by the first segment */
  82485. + buf->map = (void *) buf->segs[0].ds_addr;
  82486. + return(0);
  82487. +}
  82488. +
  82489. +/*
  82490. + * map in a given sk_buff
  82491. + */
  82492. +
  82493. +static int
  82494. +pci_map_skb(struct safe_softc *sc,struct safe_operand *buf,struct sk_buff *skb)
  82495. +{
  82496. + int i;
  82497. +
  82498. + DPRINTF(("%s()\n", __FUNCTION__));
  82499. +
  82500. + buf->mapsize = 0;
  82501. + buf->nsegs = 0;
  82502. +
  82503. + pci_map_linear(sc, buf, skb->data, skb_headlen(skb));
  82504. +
  82505. + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
  82506. + pci_map_linear(sc, buf,
  82507. + page_address(skb_shinfo(skb)->frags[i].page) +
  82508. + skb_shinfo(skb)->frags[i].page_offset,
  82509. + skb_shinfo(skb)->frags[i].size);
  82510. + }
  82511. +
  82512. + /* identify this buffer by the first segment */
  82513. + buf->map = (void *) buf->segs[0].ds_addr;
  82514. + return(0);
  82515. +}
  82516. +
  82517. +
  82518. +#if 0 /* not needed at this time */
  82519. +static void
  82520. +pci_sync_operand(struct safe_softc *sc, struct safe_operand *buf)
  82521. +{
  82522. + int i;
  82523. +
  82524. + DPRINTF(("%s()\n", __FUNCTION__));
  82525. + for (i = 0; i < buf->nsegs; i++)
  82526. + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
  82527. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  82528. +}
  82529. +#endif
  82530. +
  82531. +static void
  82532. +pci_unmap_operand(struct safe_softc *sc, struct safe_operand *buf)
  82533. +{
  82534. + int i;
  82535. + DPRINTF(("%s()\n", __FUNCTION__));
  82536. + for (i = 0; i < buf->nsegs; i++) {
  82537. + if (buf->segs[i].ds_tlen) {
  82538. + DPRINTF(("%s - unmap %d 0x%x %d\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
  82539. + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
  82540. + buf->segs[i].ds_tlen, PCI_DMA_BIDIRECTIONAL);
  82541. + DPRINTF(("%s - unmap %d 0x%x %d done\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
  82542. + }
  82543. + buf->segs[i].ds_addr = 0;
  82544. + buf->segs[i].ds_len = 0;
  82545. + buf->segs[i].ds_tlen = 0;
  82546. + }
  82547. + buf->nsegs = 0;
  82548. + buf->mapsize = 0;
  82549. + buf->map = 0;
  82550. +}
  82551. +
  82552. +
  82553. +/*
  82554. + * SafeXcel Interrupt routine
  82555. + */
  82556. +static irqreturn_t
  82557. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  82558. +safe_intr(int irq, void *arg)
  82559. +#else
  82560. +safe_intr(int irq, void *arg, struct pt_regs *regs)
  82561. +#endif
  82562. +{
  82563. + struct safe_softc *sc = arg;
  82564. + int stat;
  82565. + unsigned long flags;
  82566. +
  82567. + stat = READ_REG(sc, SAFE_HM_STAT);
  82568. +
  82569. + DPRINTF(("%s(stat=0x%x)\n", __FUNCTION__, stat));
  82570. +
  82571. + if (stat == 0) /* shared irq, not for us */
  82572. + return IRQ_NONE;
  82573. +
  82574. + WRITE_REG(sc, SAFE_HI_CLR, stat); /* IACK */
  82575. +
  82576. + if ((stat & SAFE_INT_PE_DDONE)) {
  82577. + /*
  82578. + * Descriptor(s) done; scan the ring and
  82579. + * process completed operations.
  82580. + */
  82581. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  82582. + while (sc->sc_back != sc->sc_front) {
  82583. + struct safe_ringentry *re = sc->sc_back;
  82584. +
  82585. +#ifdef SAFE_DEBUG
  82586. + if (debug) {
  82587. + safe_dump_ringstate(sc, __func__);
  82588. + safe_dump_request(sc, __func__, re);
  82589. + }
  82590. +#endif
  82591. + /*
  82592. + * safe_process marks ring entries that were allocated
  82593. + * but not used with a csr of zero. This insures the
  82594. + * ring front pointer never needs to be set backwards
  82595. + * in the event that an entry is allocated but not used
  82596. + * because of a setup error.
  82597. + */
  82598. + DPRINTF(("%s re->re_desc.d_csr=0x%x\n", __FUNCTION__, re->re_desc.d_csr));
  82599. + if (re->re_desc.d_csr != 0) {
  82600. + if (!SAFE_PE_CSR_IS_DONE(re->re_desc.d_csr)) {
  82601. + DPRINTF(("%s !CSR_IS_DONE\n", __FUNCTION__));
  82602. + break;
  82603. + }
  82604. + if (!SAFE_PE_LEN_IS_DONE(re->re_desc.d_len)) {
  82605. + DPRINTF(("%s !LEN_IS_DONE\n", __FUNCTION__));
  82606. + break;
  82607. + }
  82608. + sc->sc_nqchip--;
  82609. + safe_callback(sc, re);
  82610. + }
  82611. + if (++(sc->sc_back) == sc->sc_ringtop)
  82612. + sc->sc_back = sc->sc_ring;
  82613. + }
  82614. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  82615. + }
  82616. +
  82617. + /*
  82618. + * Check to see if we got any DMA Error
  82619. + */
  82620. + if (stat & SAFE_INT_PE_ERROR) {
  82621. + printk("%s: dmaerr dmastat %08x\n", device_get_nameunit(sc->sc_dev),
  82622. + (int)READ_REG(sc, SAFE_PE_DMASTAT));
  82623. + safestats.st_dmaerr++;
  82624. + safe_totalreset(sc);
  82625. +#if 0
  82626. + safe_feed(sc);
  82627. +#endif
  82628. + }
  82629. +
  82630. + if (sc->sc_needwakeup) { /* XXX check high watermark */
  82631. + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
  82632. + DPRINTF(("%s: wakeup crypto %x\n", __func__,
  82633. + sc->sc_needwakeup));
  82634. + sc->sc_needwakeup &= ~wakeup;
  82635. + crypto_unblock(sc->sc_cid, wakeup);
  82636. + }
  82637. +
  82638. + return IRQ_HANDLED;
  82639. +}
  82640. +
  82641. +/*
  82642. + * safe_feed() - post a request to chip
  82643. + */
  82644. +static void
  82645. +safe_feed(struct safe_softc *sc, struct safe_ringentry *re)
  82646. +{
  82647. + DPRINTF(("%s()\n", __FUNCTION__));
  82648. +#ifdef SAFE_DEBUG
  82649. + if (debug) {
  82650. + safe_dump_ringstate(sc, __func__);
  82651. + safe_dump_request(sc, __func__, re);
  82652. + }
  82653. +#endif
  82654. + sc->sc_nqchip++;
  82655. + if (sc->sc_nqchip > safestats.st_maxqchip)
  82656. + safestats.st_maxqchip = sc->sc_nqchip;
  82657. + /* poke h/w to check descriptor ring, any value can be written */
  82658. + WRITE_REG(sc, SAFE_HI_RD_DESCR, 0);
  82659. +}
  82660. +
  82661. +#define N(a) (sizeof(a) / sizeof (a[0]))
  82662. +static void
  82663. +safe_setup_enckey(struct safe_session *ses, caddr_t key)
  82664. +{
  82665. + int i;
  82666. +
  82667. + bcopy(key, ses->ses_key, ses->ses_klen / 8);
  82668. +
  82669. + /* PE is little-endian, insure proper byte order */
  82670. + for (i = 0; i < N(ses->ses_key); i++)
  82671. + ses->ses_key[i] = htole32(ses->ses_key[i]);
  82672. +}
  82673. +
  82674. +static void
  82675. +safe_setup_mackey(struct safe_session *ses, int algo, caddr_t key, int klen)
  82676. +{
  82677. +#ifdef HMAC_HACK
  82678. + MD5_CTX md5ctx;
  82679. + SHA1_CTX sha1ctx;
  82680. + int i;
  82681. +
  82682. +
  82683. + for (i = 0; i < klen; i++)
  82684. + key[i] ^= HMAC_IPAD_VAL;
  82685. +
  82686. + if (algo == CRYPTO_MD5_HMAC) {
  82687. + MD5Init(&md5ctx);
  82688. + MD5Update(&md5ctx, key, klen);
  82689. + MD5Update(&md5ctx, hmac_ipad_buffer, MD5_HMAC_BLOCK_LEN - klen);
  82690. + bcopy(md5ctx.md5_st8, ses->ses_hminner, sizeof(md5ctx.md5_st8));
  82691. + } else {
  82692. + SHA1Init(&sha1ctx);
  82693. + SHA1Update(&sha1ctx, key, klen);
  82694. + SHA1Update(&sha1ctx, hmac_ipad_buffer,
  82695. + SHA1_HMAC_BLOCK_LEN - klen);
  82696. + bcopy(sha1ctx.h.b32, ses->ses_hminner, sizeof(sha1ctx.h.b32));
  82697. + }
  82698. +
  82699. + for (i = 0; i < klen; i++)
  82700. + key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
  82701. +
  82702. + if (algo == CRYPTO_MD5_HMAC) {
  82703. + MD5Init(&md5ctx);
  82704. + MD5Update(&md5ctx, key, klen);
  82705. + MD5Update(&md5ctx, hmac_opad_buffer, MD5_HMAC_BLOCK_LEN - klen);
  82706. + bcopy(md5ctx.md5_st8, ses->ses_hmouter, sizeof(md5ctx.md5_st8));
  82707. + } else {
  82708. + SHA1Init(&sha1ctx);
  82709. + SHA1Update(&sha1ctx, key, klen);
  82710. + SHA1Update(&sha1ctx, hmac_opad_buffer,
  82711. + SHA1_HMAC_BLOCK_LEN - klen);
  82712. + bcopy(sha1ctx.h.b32, ses->ses_hmouter, sizeof(sha1ctx.h.b32));
  82713. + }
  82714. +
  82715. + for (i = 0; i < klen; i++)
  82716. + key[i] ^= HMAC_OPAD_VAL;
  82717. +
  82718. +#if 0
  82719. + /*
  82720. + * this code prevents SHA working on a BE host,
  82721. + * so it is obviously wrong. I think the byte
  82722. + * swap setup we do with the chip fixes this for us
  82723. + */
  82724. +
  82725. + /* PE is little-endian, insure proper byte order */
  82726. + for (i = 0; i < N(ses->ses_hminner); i++) {
  82727. + ses->ses_hminner[i] = htole32(ses->ses_hminner[i]);
  82728. + ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]);
  82729. + }
  82730. +#endif
  82731. +#else /* HMAC_HACK */
  82732. + printk("safe: md5/sha not implemented\n");
  82733. +#endif /* HMAC_HACK */
  82734. +}
  82735. +#undef N
  82736. +
  82737. +/*
  82738. + * Allocate a new 'session' and return an encoded session id. 'sidp'
  82739. + * contains our registration id, and should contain an encoded session
  82740. + * id on successful allocation.
  82741. + */
  82742. +static int
  82743. +safe_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  82744. +{
  82745. + struct safe_softc *sc = device_get_softc(dev);
  82746. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  82747. + struct safe_session *ses = NULL;
  82748. + int sesn;
  82749. +
  82750. + DPRINTF(("%s()\n", __FUNCTION__));
  82751. +
  82752. + if (sidp == NULL || cri == NULL || sc == NULL)
  82753. + return (EINVAL);
  82754. +
  82755. + for (c = cri; c != NULL; c = c->cri_next) {
  82756. + if (c->cri_alg == CRYPTO_MD5_HMAC ||
  82757. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  82758. + c->cri_alg == CRYPTO_NULL_HMAC) {
  82759. + if (macini)
  82760. + return (EINVAL);
  82761. + macini = c;
  82762. + } else if (c->cri_alg == CRYPTO_DES_CBC ||
  82763. + c->cri_alg == CRYPTO_3DES_CBC ||
  82764. + c->cri_alg == CRYPTO_AES_CBC ||
  82765. + c->cri_alg == CRYPTO_NULL_CBC) {
  82766. + if (encini)
  82767. + return (EINVAL);
  82768. + encini = c;
  82769. + } else
  82770. + return (EINVAL);
  82771. + }
  82772. + if (encini == NULL && macini == NULL)
  82773. + return (EINVAL);
  82774. + if (encini) { /* validate key length */
  82775. + switch (encini->cri_alg) {
  82776. + case CRYPTO_DES_CBC:
  82777. + if (encini->cri_klen != 64)
  82778. + return (EINVAL);
  82779. + break;
  82780. + case CRYPTO_3DES_CBC:
  82781. + if (encini->cri_klen != 192)
  82782. + return (EINVAL);
  82783. + break;
  82784. + case CRYPTO_AES_CBC:
  82785. + if (encini->cri_klen != 128 &&
  82786. + encini->cri_klen != 192 &&
  82787. + encini->cri_klen != 256)
  82788. + return (EINVAL);
  82789. + break;
  82790. + }
  82791. + }
  82792. +
  82793. + if (sc->sc_sessions == NULL) {
  82794. + ses = sc->sc_sessions = (struct safe_session *)
  82795. + kmalloc(sizeof(struct safe_session), SLAB_ATOMIC);
  82796. + if (ses == NULL)
  82797. + return (ENOMEM);
  82798. + memset(ses, 0, sizeof(struct safe_session));
  82799. + sesn = 0;
  82800. + sc->sc_nsessions = 1;
  82801. + } else {
  82802. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  82803. + if (sc->sc_sessions[sesn].ses_used == 0) {
  82804. + ses = &sc->sc_sessions[sesn];
  82805. + break;
  82806. + }
  82807. + }
  82808. +
  82809. + if (ses == NULL) {
  82810. + sesn = sc->sc_nsessions;
  82811. + ses = (struct safe_session *)
  82812. + kmalloc((sesn + 1) * sizeof(struct safe_session), SLAB_ATOMIC);
  82813. + if (ses == NULL)
  82814. + return (ENOMEM);
  82815. + memset(ses, 0, (sesn + 1) * sizeof(struct safe_session));
  82816. + bcopy(sc->sc_sessions, ses, sesn *
  82817. + sizeof(struct safe_session));
  82818. + bzero(sc->sc_sessions, sesn *
  82819. + sizeof(struct safe_session));
  82820. + kfree(sc->sc_sessions);
  82821. + sc->sc_sessions = ses;
  82822. + ses = &sc->sc_sessions[sesn];
  82823. + sc->sc_nsessions++;
  82824. + }
  82825. + }
  82826. +
  82827. + bzero(ses, sizeof(struct safe_session));
  82828. + ses->ses_used = 1;
  82829. +
  82830. + if (encini) {
  82831. + /* get an IV */
  82832. + /* XXX may read fewer than requested */
  82833. + read_random(ses->ses_iv, sizeof(ses->ses_iv));
  82834. +
  82835. + ses->ses_klen = encini->cri_klen;
  82836. + if (encini->cri_key != NULL)
  82837. + safe_setup_enckey(ses, encini->cri_key);
  82838. + }
  82839. +
  82840. + if (macini) {
  82841. + ses->ses_mlen = macini->cri_mlen;
  82842. + if (ses->ses_mlen == 0) {
  82843. + if (macini->cri_alg == CRYPTO_MD5_HMAC)
  82844. + ses->ses_mlen = MD5_HASH_LEN;
  82845. + else
  82846. + ses->ses_mlen = SHA1_HASH_LEN;
  82847. + }
  82848. +
  82849. + if (macini->cri_key != NULL) {
  82850. + safe_setup_mackey(ses, macini->cri_alg, macini->cri_key,
  82851. + macini->cri_klen / 8);
  82852. + }
  82853. + }
  82854. +
  82855. + *sidp = SAFE_SID(device_get_unit(sc->sc_dev), sesn);
  82856. + return (0);
  82857. +}
  82858. +
  82859. +/*
  82860. + * Deallocate a session.
  82861. + */
  82862. +static int
  82863. +safe_freesession(device_t dev, u_int64_t tid)
  82864. +{
  82865. + struct safe_softc *sc = device_get_softc(dev);
  82866. + int session, ret;
  82867. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  82868. +
  82869. + DPRINTF(("%s()\n", __FUNCTION__));
  82870. +
  82871. + if (sc == NULL)
  82872. + return (EINVAL);
  82873. +
  82874. + session = SAFE_SESSION(sid);
  82875. + if (session < sc->sc_nsessions) {
  82876. + bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
  82877. + ret = 0;
  82878. + } else
  82879. + ret = EINVAL;
  82880. + return (ret);
  82881. +}
  82882. +
  82883. +
  82884. +static int
  82885. +safe_process(device_t dev, struct cryptop *crp, int hint)
  82886. +{
  82887. + struct safe_softc *sc = device_get_softc(dev);
  82888. + int err = 0, i, nicealign, uniform;
  82889. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  82890. + int bypass, oplen, ivsize;
  82891. + caddr_t iv;
  82892. + int16_t coffset;
  82893. + struct safe_session *ses;
  82894. + struct safe_ringentry *re;
  82895. + struct safe_sarec *sa;
  82896. + struct safe_pdesc *pd;
  82897. + u_int32_t cmd0, cmd1, staterec;
  82898. + unsigned long flags;
  82899. +
  82900. + DPRINTF(("%s()\n", __FUNCTION__));
  82901. +
  82902. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
  82903. + safestats.st_invalid++;
  82904. + return (EINVAL);
  82905. + }
  82906. + if (SAFE_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
  82907. + safestats.st_badsession++;
  82908. + return (EINVAL);
  82909. + }
  82910. +
  82911. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  82912. + if (sc->sc_front == sc->sc_back && sc->sc_nqchip != 0) {
  82913. + safestats.st_ringfull++;
  82914. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  82915. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  82916. + return (ERESTART);
  82917. + }
  82918. + re = sc->sc_front;
  82919. +
  82920. + staterec = re->re_sa.sa_staterec; /* save */
  82921. + /* NB: zero everything but the PE descriptor */
  82922. + bzero(&re->re_sa, sizeof(struct safe_ringentry) - sizeof(re->re_desc));
  82923. + re->re_sa.sa_staterec = staterec; /* restore */
  82924. +
  82925. + re->re_crp = crp;
  82926. + re->re_sesn = SAFE_SESSION(crp->crp_sid);
  82927. +
  82928. + re->re_src.nsegs = 0;
  82929. + re->re_dst.nsegs = 0;
  82930. +
  82931. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  82932. + re->re_src_skb = (struct sk_buff *)crp->crp_buf;
  82933. + re->re_dst_skb = (struct sk_buff *)crp->crp_buf;
  82934. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  82935. + re->re_src_io = (struct uio *)crp->crp_buf;
  82936. + re->re_dst_io = (struct uio *)crp->crp_buf;
  82937. + } else {
  82938. + safestats.st_badflags++;
  82939. + err = EINVAL;
  82940. + goto errout; /* XXX we don't handle contiguous blocks! */
  82941. + }
  82942. +
  82943. + sa = &re->re_sa;
  82944. + ses = &sc->sc_sessions[re->re_sesn];
  82945. +
  82946. + crd1 = crp->crp_desc;
  82947. + if (crd1 == NULL) {
  82948. + safestats.st_nodesc++;
  82949. + err = EINVAL;
  82950. + goto errout;
  82951. + }
  82952. + crd2 = crd1->crd_next;
  82953. +
  82954. + cmd0 = SAFE_SA_CMD0_BASIC; /* basic group operation */
  82955. + cmd1 = 0;
  82956. + if (crd2 == NULL) {
  82957. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  82958. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  82959. + crd1->crd_alg == CRYPTO_NULL_HMAC) {
  82960. + maccrd = crd1;
  82961. + enccrd = NULL;
  82962. + cmd0 |= SAFE_SA_CMD0_OP_HASH;
  82963. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  82964. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  82965. + crd1->crd_alg == CRYPTO_AES_CBC ||
  82966. + crd1->crd_alg == CRYPTO_NULL_CBC) {
  82967. + maccrd = NULL;
  82968. + enccrd = crd1;
  82969. + cmd0 |= SAFE_SA_CMD0_OP_CRYPT;
  82970. + } else {
  82971. + safestats.st_badalg++;
  82972. + err = EINVAL;
  82973. + goto errout;
  82974. + }
  82975. + } else {
  82976. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  82977. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  82978. + crd1->crd_alg == CRYPTO_NULL_HMAC) &&
  82979. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  82980. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  82981. + crd2->crd_alg == CRYPTO_AES_CBC ||
  82982. + crd2->crd_alg == CRYPTO_NULL_CBC) &&
  82983. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  82984. + maccrd = crd1;
  82985. + enccrd = crd2;
  82986. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  82987. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  82988. + crd1->crd_alg == CRYPTO_AES_CBC ||
  82989. + crd1->crd_alg == CRYPTO_NULL_CBC) &&
  82990. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  82991. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  82992. + crd2->crd_alg == CRYPTO_NULL_HMAC) &&
  82993. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  82994. + enccrd = crd1;
  82995. + maccrd = crd2;
  82996. + } else {
  82997. + safestats.st_badalg++;
  82998. + err = EINVAL;
  82999. + goto errout;
  83000. + }
  83001. + cmd0 |= SAFE_SA_CMD0_OP_BOTH;
  83002. + }
  83003. +
  83004. + if (enccrd) {
  83005. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
  83006. + safe_setup_enckey(ses, enccrd->crd_key);
  83007. +
  83008. + if (enccrd->crd_alg == CRYPTO_DES_CBC) {
  83009. + cmd0 |= SAFE_SA_CMD0_DES;
  83010. + cmd1 |= SAFE_SA_CMD1_CBC;
  83011. + ivsize = 2*sizeof(u_int32_t);
  83012. + } else if (enccrd->crd_alg == CRYPTO_3DES_CBC) {
  83013. + cmd0 |= SAFE_SA_CMD0_3DES;
  83014. + cmd1 |= SAFE_SA_CMD1_CBC;
  83015. + ivsize = 2*sizeof(u_int32_t);
  83016. + } else if (enccrd->crd_alg == CRYPTO_AES_CBC) {
  83017. + cmd0 |= SAFE_SA_CMD0_AES;
  83018. + cmd1 |= SAFE_SA_CMD1_CBC;
  83019. + if (ses->ses_klen == 128)
  83020. + cmd1 |= SAFE_SA_CMD1_AES128;
  83021. + else if (ses->ses_klen == 192)
  83022. + cmd1 |= SAFE_SA_CMD1_AES192;
  83023. + else
  83024. + cmd1 |= SAFE_SA_CMD1_AES256;
  83025. + ivsize = 4*sizeof(u_int32_t);
  83026. + } else {
  83027. + cmd0 |= SAFE_SA_CMD0_CRYPT_NULL;
  83028. + ivsize = 0;
  83029. + }
  83030. +
  83031. + /*
  83032. + * Setup encrypt/decrypt state. When using basic ops
  83033. + * we can't use an inline IV because hash/crypt offset
  83034. + * must be from the end of the IV to the start of the
  83035. + * crypt data and this leaves out the preceding header
  83036. + * from the hash calculation. Instead we place the IV
  83037. + * in the state record and set the hash/crypt offset to
  83038. + * copy both the header+IV.
  83039. + */
  83040. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  83041. + cmd0 |= SAFE_SA_CMD0_OUTBOUND;
  83042. +
  83043. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  83044. + iv = enccrd->crd_iv;
  83045. + else
  83046. + iv = (caddr_t) ses->ses_iv;
  83047. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  83048. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  83049. + enccrd->crd_inject, ivsize, iv);
  83050. + }
  83051. + bcopy(iv, re->re_sastate.sa_saved_iv, ivsize);
  83052. + /* make iv LE */
  83053. + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
  83054. + re->re_sastate.sa_saved_iv[i] =
  83055. + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
  83056. + cmd0 |= SAFE_SA_CMD0_IVLD_STATE | SAFE_SA_CMD0_SAVEIV;
  83057. + re->re_flags |= SAFE_QFLAGS_COPYOUTIV;
  83058. + } else {
  83059. + cmd0 |= SAFE_SA_CMD0_INBOUND;
  83060. +
  83061. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  83062. + bcopy(enccrd->crd_iv,
  83063. + re->re_sastate.sa_saved_iv, ivsize);
  83064. + } else {
  83065. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  83066. + enccrd->crd_inject, ivsize,
  83067. + (caddr_t)re->re_sastate.sa_saved_iv);
  83068. + }
  83069. + /* make iv LE */
  83070. + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
  83071. + re->re_sastate.sa_saved_iv[i] =
  83072. + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
  83073. + cmd0 |= SAFE_SA_CMD0_IVLD_STATE;
  83074. + }
  83075. + /*
  83076. + * For basic encryption use the zero pad algorithm.
  83077. + * This pads results to an 8-byte boundary and
  83078. + * suppresses padding verification for inbound (i.e.
  83079. + * decrypt) operations.
  83080. + *
  83081. + * NB: Not sure if the 8-byte pad boundary is a problem.
  83082. + */
  83083. + cmd0 |= SAFE_SA_CMD0_PAD_ZERO;
  83084. +
  83085. + /* XXX assert key bufs have the same size */
  83086. + bcopy(ses->ses_key, sa->sa_key, sizeof(sa->sa_key));
  83087. + }
  83088. +
  83089. + if (maccrd) {
  83090. + if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  83091. + safe_setup_mackey(ses, maccrd->crd_alg,
  83092. + maccrd->crd_key, maccrd->crd_klen / 8);
  83093. + }
  83094. +
  83095. + if (maccrd->crd_alg == CRYPTO_MD5_HMAC) {
  83096. + cmd0 |= SAFE_SA_CMD0_MD5;
  83097. + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
  83098. + } else if (maccrd->crd_alg == CRYPTO_SHA1_HMAC) {
  83099. + cmd0 |= SAFE_SA_CMD0_SHA1;
  83100. + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
  83101. + } else {
  83102. + cmd0 |= SAFE_SA_CMD0_HASH_NULL;
  83103. + }
  83104. + /*
  83105. + * Digest data is loaded from the SA and the hash
  83106. + * result is saved to the state block where we
  83107. + * retrieve it for return to the caller.
  83108. + */
  83109. + /* XXX assert digest bufs have the same size */
  83110. + bcopy(ses->ses_hminner, sa->sa_indigest,
  83111. + sizeof(sa->sa_indigest));
  83112. + bcopy(ses->ses_hmouter, sa->sa_outdigest,
  83113. + sizeof(sa->sa_outdigest));
  83114. +
  83115. + cmd0 |= SAFE_SA_CMD0_HSLD_SA | SAFE_SA_CMD0_SAVEHASH;
  83116. + re->re_flags |= SAFE_QFLAGS_COPYOUTICV;
  83117. + }
  83118. +
  83119. + if (enccrd && maccrd) {
  83120. + /*
  83121. + * The offset from hash data to the start of
  83122. + * crypt data is the difference in the skips.
  83123. + */
  83124. + bypass = maccrd->crd_skip;
  83125. + coffset = enccrd->crd_skip - maccrd->crd_skip;
  83126. + if (coffset < 0) {
  83127. + DPRINTF(("%s: hash does not precede crypt; "
  83128. + "mac skip %u enc skip %u\n",
  83129. + __func__, maccrd->crd_skip, enccrd->crd_skip));
  83130. + safestats.st_skipmismatch++;
  83131. + err = EINVAL;
  83132. + goto errout;
  83133. + }
  83134. + oplen = enccrd->crd_skip + enccrd->crd_len;
  83135. + if (maccrd->crd_skip + maccrd->crd_len != oplen) {
  83136. + DPRINTF(("%s: hash amount %u != crypt amount %u\n",
  83137. + __func__, maccrd->crd_skip + maccrd->crd_len,
  83138. + oplen));
  83139. + safestats.st_lenmismatch++;
  83140. + err = EINVAL;
  83141. + goto errout;
  83142. + }
  83143. +#ifdef SAFE_DEBUG
  83144. + if (debug) {
  83145. + printf("mac: skip %d, len %d, inject %d\n",
  83146. + maccrd->crd_skip, maccrd->crd_len,
  83147. + maccrd->crd_inject);
  83148. + printf("enc: skip %d, len %d, inject %d\n",
  83149. + enccrd->crd_skip, enccrd->crd_len,
  83150. + enccrd->crd_inject);
  83151. + printf("bypass %d coffset %d oplen %d\n",
  83152. + bypass, coffset, oplen);
  83153. + }
  83154. +#endif
  83155. + if (coffset & 3) { /* offset must be 32-bit aligned */
  83156. + DPRINTF(("%s: coffset %u misaligned\n",
  83157. + __func__, coffset));
  83158. + safestats.st_coffmisaligned++;
  83159. + err = EINVAL;
  83160. + goto errout;
  83161. + }
  83162. + coffset >>= 2;
  83163. + if (coffset > 255) { /* offset must be <256 dwords */
  83164. + DPRINTF(("%s: coffset %u too big\n",
  83165. + __func__, coffset));
  83166. + safestats.st_cofftoobig++;
  83167. + err = EINVAL;
  83168. + goto errout;
  83169. + }
  83170. + /*
  83171. + * Tell the hardware to copy the header to the output.
  83172. + * The header is defined as the data from the end of
  83173. + * the bypass to the start of data to be encrypted.
  83174. + * Typically this is the inline IV. Note that you need
  83175. + * to do this even if src+dst are the same; it appears
  83176. + * that w/o this bit the crypted data is written
  83177. + * immediately after the bypass data.
  83178. + */
  83179. + cmd1 |= SAFE_SA_CMD1_HDRCOPY;
  83180. + /*
  83181. + * Disable IP header mutable bit handling. This is
  83182. + * needed to get correct HMAC calculations.
  83183. + */
  83184. + cmd1 |= SAFE_SA_CMD1_MUTABLE;
  83185. + } else {
  83186. + if (enccrd) {
  83187. + bypass = enccrd->crd_skip;
  83188. + oplen = bypass + enccrd->crd_len;
  83189. + } else {
  83190. + bypass = maccrd->crd_skip;
  83191. + oplen = bypass + maccrd->crd_len;
  83192. + }
  83193. + coffset = 0;
  83194. + }
  83195. + /* XXX verify multiple of 4 when using s/g */
  83196. + if (bypass > 96) { /* bypass offset must be <= 96 bytes */
  83197. + DPRINTF(("%s: bypass %u too big\n", __func__, bypass));
  83198. + safestats.st_bypasstoobig++;
  83199. + err = EINVAL;
  83200. + goto errout;
  83201. + }
  83202. +
  83203. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  83204. + if (pci_map_skb(sc, &re->re_src, re->re_src_skb)) {
  83205. + safestats.st_noload++;
  83206. + err = ENOMEM;
  83207. + goto errout;
  83208. + }
  83209. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  83210. + if (pci_map_uio(sc, &re->re_src, re->re_src_io)) {
  83211. + safestats.st_noload++;
  83212. + err = ENOMEM;
  83213. + goto errout;
  83214. + }
  83215. + }
  83216. + nicealign = safe_dmamap_aligned(sc, &re->re_src);
  83217. + uniform = safe_dmamap_uniform(sc, &re->re_src);
  83218. +
  83219. + DPRINTF(("src nicealign %u uniform %u nsegs %u\n",
  83220. + nicealign, uniform, re->re_src.nsegs));
  83221. + if (re->re_src.nsegs > 1) {
  83222. + re->re_desc.d_src = sc->sc_spalloc.dma_paddr +
  83223. + ((caddr_t) sc->sc_spfree - (caddr_t) sc->sc_spring);
  83224. + for (i = 0; i < re->re_src_nsegs; i++) {
  83225. + /* NB: no need to check if there's space */
  83226. + pd = sc->sc_spfree;
  83227. + if (++(sc->sc_spfree) == sc->sc_springtop)
  83228. + sc->sc_spfree = sc->sc_spring;
  83229. +
  83230. + KASSERT((pd->pd_flags&3) == 0 ||
  83231. + (pd->pd_flags&3) == SAFE_PD_DONE,
  83232. + ("bogus source particle descriptor; flags %x",
  83233. + pd->pd_flags));
  83234. + pd->pd_addr = re->re_src_segs[i].ds_addr;
  83235. + pd->pd_size = re->re_src_segs[i].ds_len;
  83236. + pd->pd_flags = SAFE_PD_READY;
  83237. + }
  83238. + cmd0 |= SAFE_SA_CMD0_IGATHER;
  83239. + } else {
  83240. + /*
  83241. + * No need for gather, reference the operand directly.
  83242. + */
  83243. + re->re_desc.d_src = re->re_src_segs[0].ds_addr;
  83244. + }
  83245. +
  83246. + if (enccrd == NULL && maccrd != NULL) {
  83247. + /*
  83248. + * Hash op; no destination needed.
  83249. + */
  83250. + } else {
  83251. + if (crp->crp_flags & (CRYPTO_F_IOV|CRYPTO_F_SKBUF)) {
  83252. + if (!nicealign) {
  83253. + safestats.st_iovmisaligned++;
  83254. + err = EINVAL;
  83255. + goto errout;
  83256. + }
  83257. + if (uniform != 1) {
  83258. + device_printf(sc->sc_dev, "!uniform source\n");
  83259. + if (!uniform) {
  83260. + /*
  83261. + * There's no way to handle the DMA
  83262. + * requirements with this uio. We
  83263. + * could create a separate DMA area for
  83264. + * the result and then copy it back,
  83265. + * but for now we just bail and return
  83266. + * an error. Note that uio requests
  83267. + * > SAFE_MAX_DSIZE are handled because
  83268. + * the DMA map and segment list for the
  83269. + * destination wil result in a
  83270. + * destination particle list that does
  83271. + * the necessary scatter DMA.
  83272. + */
  83273. + safestats.st_iovnotuniform++;
  83274. + err = EINVAL;
  83275. + goto errout;
  83276. + }
  83277. + } else
  83278. + re->re_dst = re->re_src;
  83279. + } else {
  83280. + safestats.st_badflags++;
  83281. + err = EINVAL;
  83282. + goto errout;
  83283. + }
  83284. +
  83285. + if (re->re_dst.nsegs > 1) {
  83286. + re->re_desc.d_dst = sc->sc_dpalloc.dma_paddr +
  83287. + ((caddr_t) sc->sc_dpfree - (caddr_t) sc->sc_dpring);
  83288. + for (i = 0; i < re->re_dst_nsegs; i++) {
  83289. + pd = sc->sc_dpfree;
  83290. + KASSERT((pd->pd_flags&3) == 0 ||
  83291. + (pd->pd_flags&3) == SAFE_PD_DONE,
  83292. + ("bogus dest particle descriptor; flags %x",
  83293. + pd->pd_flags));
  83294. + if (++(sc->sc_dpfree) == sc->sc_dpringtop)
  83295. + sc->sc_dpfree = sc->sc_dpring;
  83296. + pd->pd_addr = re->re_dst_segs[i].ds_addr;
  83297. + pd->pd_flags = SAFE_PD_READY;
  83298. + }
  83299. + cmd0 |= SAFE_SA_CMD0_OSCATTER;
  83300. + } else {
  83301. + /*
  83302. + * No need for scatter, reference the operand directly.
  83303. + */
  83304. + re->re_desc.d_dst = re->re_dst_segs[0].ds_addr;
  83305. + }
  83306. + }
  83307. +
  83308. + /*
  83309. + * All done with setup; fillin the SA command words
  83310. + * and the packet engine descriptor. The operation
  83311. + * is now ready for submission to the hardware.
  83312. + */
  83313. + sa->sa_cmd0 = cmd0 | SAFE_SA_CMD0_IPCI | SAFE_SA_CMD0_OPCI;
  83314. + sa->sa_cmd1 = cmd1
  83315. + | (coffset << SAFE_SA_CMD1_OFFSET_S)
  83316. + | SAFE_SA_CMD1_SAREV1 /* Rev 1 SA data structure */
  83317. + | SAFE_SA_CMD1_SRPCI
  83318. + ;
  83319. + /*
  83320. + * NB: the order of writes is important here. In case the
  83321. + * chip is scanning the ring because of an outstanding request
  83322. + * it might nab this one too. In that case we need to make
  83323. + * sure the setup is complete before we write the length
  83324. + * field of the descriptor as it signals the descriptor is
  83325. + * ready for processing.
  83326. + */
  83327. + re->re_desc.d_csr = SAFE_PE_CSR_READY | SAFE_PE_CSR_SAPCI;
  83328. + if (maccrd)
  83329. + re->re_desc.d_csr |= SAFE_PE_CSR_LOADSA | SAFE_PE_CSR_HASHFINAL;
  83330. + wmb();
  83331. + re->re_desc.d_len = oplen
  83332. + | SAFE_PE_LEN_READY
  83333. + | (bypass << SAFE_PE_LEN_BYPASS_S)
  83334. + ;
  83335. +
  83336. + safestats.st_ipackets++;
  83337. + safestats.st_ibytes += oplen;
  83338. +
  83339. + if (++(sc->sc_front) == sc->sc_ringtop)
  83340. + sc->sc_front = sc->sc_ring;
  83341. +
  83342. + /* XXX honor batching */
  83343. + safe_feed(sc, re);
  83344. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  83345. + return (0);
  83346. +
  83347. +errout:
  83348. + if (re->re_src.map != re->re_dst.map)
  83349. + pci_unmap_operand(sc, &re->re_dst);
  83350. + if (re->re_src.map)
  83351. + pci_unmap_operand(sc, &re->re_src);
  83352. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  83353. + if (err != ERESTART) {
  83354. + crp->crp_etype = err;
  83355. + crypto_done(crp);
  83356. + } else {
  83357. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  83358. + }
  83359. + return (err);
  83360. +}
  83361. +
  83362. +static void
  83363. +safe_callback(struct safe_softc *sc, struct safe_ringentry *re)
  83364. +{
  83365. + struct cryptop *crp = (struct cryptop *)re->re_crp;
  83366. + struct cryptodesc *crd;
  83367. +
  83368. + DPRINTF(("%s()\n", __FUNCTION__));
  83369. +
  83370. + safestats.st_opackets++;
  83371. + safestats.st_obytes += re->re_dst.mapsize;
  83372. +
  83373. + if (re->re_desc.d_csr & SAFE_PE_CSR_STATUS) {
  83374. + device_printf(sc->sc_dev, "csr 0x%x cmd0 0x%x cmd1 0x%x\n",
  83375. + re->re_desc.d_csr,
  83376. + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1);
  83377. + safestats.st_peoperr++;
  83378. + crp->crp_etype = EIO; /* something more meaningful? */
  83379. + }
  83380. +
  83381. + if (re->re_dst.map != NULL && re->re_dst.map != re->re_src.map)
  83382. + pci_unmap_operand(sc, &re->re_dst);
  83383. + pci_unmap_operand(sc, &re->re_src);
  83384. +
  83385. + /*
  83386. + * If result was written to a differet mbuf chain, swap
  83387. + * it in as the return value and reclaim the original.
  83388. + */
  83389. + if ((crp->crp_flags & CRYPTO_F_SKBUF) && re->re_src_skb != re->re_dst_skb) {
  83390. + device_printf(sc->sc_dev, "no CRYPTO_F_SKBUF swapping support\n");
  83391. + /* kfree_skb(skb) */
  83392. + /* crp->crp_buf = (caddr_t)re->re_dst_skb */
  83393. + return;
  83394. + }
  83395. +
  83396. + if (re->re_flags & SAFE_QFLAGS_COPYOUTIV) {
  83397. + /* copy out IV for future use */
  83398. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  83399. + int i;
  83400. + int ivsize;
  83401. +
  83402. + if (crd->crd_alg == CRYPTO_DES_CBC ||
  83403. + crd->crd_alg == CRYPTO_3DES_CBC) {
  83404. + ivsize = 2*sizeof(u_int32_t);
  83405. + } else if (crd->crd_alg == CRYPTO_AES_CBC) {
  83406. + ivsize = 4*sizeof(u_int32_t);
  83407. + } else
  83408. + continue;
  83409. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  83410. + crd->crd_skip + crd->crd_len - ivsize, ivsize,
  83411. + (caddr_t)sc->sc_sessions[re->re_sesn].ses_iv);
  83412. + for (i = 0;
  83413. + i < ivsize/sizeof(sc->sc_sessions[re->re_sesn].ses_iv[0]);
  83414. + i++)
  83415. + sc->sc_sessions[re->re_sesn].ses_iv[i] =
  83416. + cpu_to_le32(sc->sc_sessions[re->re_sesn].ses_iv[i]);
  83417. + break;
  83418. + }
  83419. + }
  83420. +
  83421. + if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) {
  83422. + /* copy out ICV result */
  83423. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  83424. + if (!(crd->crd_alg == CRYPTO_MD5_HMAC ||
  83425. + crd->crd_alg == CRYPTO_SHA1_HMAC ||
  83426. + crd->crd_alg == CRYPTO_NULL_HMAC))
  83427. + continue;
  83428. + if (crd->crd_alg == CRYPTO_SHA1_HMAC) {
  83429. + /*
  83430. + * SHA-1 ICV's are byte-swapped; fix 'em up
  83431. + * before copy them to their destination.
  83432. + */
  83433. + re->re_sastate.sa_saved_indigest[0] =
  83434. + cpu_to_be32(re->re_sastate.sa_saved_indigest[0]);
  83435. + re->re_sastate.sa_saved_indigest[1] =
  83436. + cpu_to_be32(re->re_sastate.sa_saved_indigest[1]);
  83437. + re->re_sastate.sa_saved_indigest[2] =
  83438. + cpu_to_be32(re->re_sastate.sa_saved_indigest[2]);
  83439. + } else {
  83440. + re->re_sastate.sa_saved_indigest[0] =
  83441. + cpu_to_le32(re->re_sastate.sa_saved_indigest[0]);
  83442. + re->re_sastate.sa_saved_indigest[1] =
  83443. + cpu_to_le32(re->re_sastate.sa_saved_indigest[1]);
  83444. + re->re_sastate.sa_saved_indigest[2] =
  83445. + cpu_to_le32(re->re_sastate.sa_saved_indigest[2]);
  83446. + }
  83447. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  83448. + crd->crd_inject,
  83449. + sc->sc_sessions[re->re_sesn].ses_mlen,
  83450. + (caddr_t)re->re_sastate.sa_saved_indigest);
  83451. + break;
  83452. + }
  83453. + }
  83454. + crypto_done(crp);
  83455. +}
  83456. +
  83457. +
  83458. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  83459. +#define SAFE_RNG_MAXWAIT 1000
  83460. +
  83461. +static void
  83462. +safe_rng_init(struct safe_softc *sc)
  83463. +{
  83464. + u_int32_t w, v;
  83465. + int i;
  83466. +
  83467. + DPRINTF(("%s()\n", __FUNCTION__));
  83468. +
  83469. + WRITE_REG(sc, SAFE_RNG_CTRL, 0);
  83470. + /* use default value according to the manual */
  83471. + WRITE_REG(sc, SAFE_RNG_CNFG, 0x834); /* magic from SafeNet */
  83472. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  83473. +
  83474. + /*
  83475. + * There is a bug in rev 1.0 of the 1140 that when the RNG
  83476. + * is brought out of reset the ready status flag does not
  83477. + * work until the RNG has finished its internal initialization.
  83478. + *
  83479. + * So in order to determine the device is through its
  83480. + * initialization we must read the data register, using the
  83481. + * status reg in the read in case it is initialized. Then read
  83482. + * the data register until it changes from the first read.
  83483. + * Once it changes read the data register until it changes
  83484. + * again. At this time the RNG is considered initialized.
  83485. + * This could take between 750ms - 1000ms in time.
  83486. + */
  83487. + i = 0;
  83488. + w = READ_REG(sc, SAFE_RNG_OUT);
  83489. + do {
  83490. + v = READ_REG(sc, SAFE_RNG_OUT);
  83491. + if (v != w) {
  83492. + w = v;
  83493. + break;
  83494. + }
  83495. + DELAY(10);
  83496. + } while (++i < SAFE_RNG_MAXWAIT);
  83497. +
  83498. + /* Wait Until data changes again */
  83499. + i = 0;
  83500. + do {
  83501. + v = READ_REG(sc, SAFE_RNG_OUT);
  83502. + if (v != w)
  83503. + break;
  83504. + DELAY(10);
  83505. + } while (++i < SAFE_RNG_MAXWAIT);
  83506. +}
  83507. +
  83508. +static __inline void
  83509. +safe_rng_disable_short_cycle(struct safe_softc *sc)
  83510. +{
  83511. + DPRINTF(("%s()\n", __FUNCTION__));
  83512. +
  83513. + WRITE_REG(sc, SAFE_RNG_CTRL,
  83514. + READ_REG(sc, SAFE_RNG_CTRL) &~ SAFE_RNG_CTRL_SHORTEN);
  83515. +}
  83516. +
  83517. +static __inline void
  83518. +safe_rng_enable_short_cycle(struct safe_softc *sc)
  83519. +{
  83520. + DPRINTF(("%s()\n", __FUNCTION__));
  83521. +
  83522. + WRITE_REG(sc, SAFE_RNG_CTRL,
  83523. + READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN);
  83524. +}
  83525. +
  83526. +static __inline u_int32_t
  83527. +safe_rng_read(struct safe_softc *sc)
  83528. +{
  83529. + int i;
  83530. +
  83531. + i = 0;
  83532. + while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT)
  83533. + ;
  83534. + return READ_REG(sc, SAFE_RNG_OUT);
  83535. +}
  83536. +
  83537. +static int
  83538. +safe_read_random(void *arg, u_int32_t *buf, int maxwords)
  83539. +{
  83540. + struct safe_softc *sc = (struct safe_softc *) arg;
  83541. + int i, rc;
  83542. +
  83543. + DPRINTF(("%s()\n", __FUNCTION__));
  83544. +
  83545. + safestats.st_rng++;
  83546. + /*
  83547. + * Fetch the next block of data.
  83548. + */
  83549. + if (maxwords > safe_rngbufsize)
  83550. + maxwords = safe_rngbufsize;
  83551. + if (maxwords > SAFE_RNG_MAXBUFSIZ)
  83552. + maxwords = SAFE_RNG_MAXBUFSIZ;
  83553. +retry:
  83554. + /* read as much as we can */
  83555. + for (rc = 0; rc < maxwords; rc++) {
  83556. + if (READ_REG(sc, SAFE_RNG_STAT) != 0)
  83557. + break;
  83558. + buf[rc] = READ_REG(sc, SAFE_RNG_OUT);
  83559. + }
  83560. + if (rc == 0)
  83561. + return 0;
  83562. + /*
  83563. + * Check the comparator alarm count and reset the h/w if
  83564. + * it exceeds our threshold. This guards against the
  83565. + * hardware oscillators resonating with external signals.
  83566. + */
  83567. + if (READ_REG(sc, SAFE_RNG_ALM_CNT) > safe_rngmaxalarm) {
  83568. + u_int32_t freq_inc, w;
  83569. +
  83570. + DPRINTF(("%s: alarm count %u exceeds threshold %u\n", __func__,
  83571. + (unsigned)READ_REG(sc, SAFE_RNG_ALM_CNT), safe_rngmaxalarm));
  83572. + safestats.st_rngalarm++;
  83573. + safe_rng_enable_short_cycle(sc);
  83574. + freq_inc = 18;
  83575. + for (i = 0; i < 64; i++) {
  83576. + w = READ_REG(sc, SAFE_RNG_CNFG);
  83577. + freq_inc = ((w + freq_inc) & 0x3fL);
  83578. + w = ((w & ~0x3fL) | freq_inc);
  83579. + WRITE_REG(sc, SAFE_RNG_CNFG, w);
  83580. +
  83581. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  83582. +
  83583. + (void) safe_rng_read(sc);
  83584. + DELAY(25);
  83585. +
  83586. + if (READ_REG(sc, SAFE_RNG_ALM_CNT) == 0) {
  83587. + safe_rng_disable_short_cycle(sc);
  83588. + goto retry;
  83589. + }
  83590. + freq_inc = 1;
  83591. + }
  83592. + safe_rng_disable_short_cycle(sc);
  83593. + } else
  83594. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  83595. +
  83596. + return(rc);
  83597. +}
  83598. +#endif /* defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG) */
  83599. +
  83600. +
  83601. +/*
  83602. + * Resets the board. Values in the regesters are left as is
  83603. + * from the reset (i.e. initial values are assigned elsewhere).
  83604. + */
  83605. +static void
  83606. +safe_reset_board(struct safe_softc *sc)
  83607. +{
  83608. + u_int32_t v;
  83609. + /*
  83610. + * Reset the device. The manual says no delay
  83611. + * is needed between marking and clearing reset.
  83612. + */
  83613. + DPRINTF(("%s()\n", __FUNCTION__));
  83614. +
  83615. + v = READ_REG(sc, SAFE_PE_DMACFG) &~
  83616. + (SAFE_PE_DMACFG_PERESET | SAFE_PE_DMACFG_PDRRESET |
  83617. + SAFE_PE_DMACFG_SGRESET);
  83618. + WRITE_REG(sc, SAFE_PE_DMACFG, v
  83619. + | SAFE_PE_DMACFG_PERESET
  83620. + | SAFE_PE_DMACFG_PDRRESET
  83621. + | SAFE_PE_DMACFG_SGRESET);
  83622. + WRITE_REG(sc, SAFE_PE_DMACFG, v);
  83623. +}
  83624. +
  83625. +/*
  83626. + * Initialize registers we need to touch only once.
  83627. + */
  83628. +static void
  83629. +safe_init_board(struct safe_softc *sc)
  83630. +{
  83631. + u_int32_t v, dwords;
  83632. +
  83633. + DPRINTF(("%s()\n", __FUNCTION__));
  83634. +
  83635. + v = READ_REG(sc, SAFE_PE_DMACFG);
  83636. + v &=~ ( SAFE_PE_DMACFG_PEMODE
  83637. + | SAFE_PE_DMACFG_FSENA /* failsafe enable */
  83638. + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
  83639. + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
  83640. + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
  83641. + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
  83642. + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
  83643. + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
  83644. + );
  83645. + v |= SAFE_PE_DMACFG_FSENA /* failsafe enable */
  83646. + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
  83647. + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
  83648. + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
  83649. + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
  83650. + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
  83651. +#if 0
  83652. + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
  83653. +#endif
  83654. + ;
  83655. + WRITE_REG(sc, SAFE_PE_DMACFG, v);
  83656. +
  83657. +#ifdef __BIG_ENDIAN
  83658. + /* tell the safenet that we are 4321 and not 1234 */
  83659. + WRITE_REG(sc, SAFE_ENDIAN, 0xe4e41b1b);
  83660. +#endif
  83661. +
  83662. + if (sc->sc_chiprev == SAFE_REV(1,0)) {
  83663. + /*
  83664. + * Avoid large PCI DMA transfers. Rev 1.0 has a bug where
  83665. + * "target mode transfers" done while the chip is DMA'ing
  83666. + * >1020 bytes cause the hardware to lockup. To avoid this
  83667. + * we reduce the max PCI transfer size and use small source
  83668. + * particle descriptors (<= 256 bytes).
  83669. + */
  83670. + WRITE_REG(sc, SAFE_DMA_CFG, 256);
  83671. + device_printf(sc->sc_dev,
  83672. + "Reduce max DMA size to %u words for rev %u.%u WAR\n",
  83673. + (unsigned) ((READ_REG(sc, SAFE_DMA_CFG)>>2) & 0xff),
  83674. + (unsigned) SAFE_REV_MAJ(sc->sc_chiprev),
  83675. + (unsigned) SAFE_REV_MIN(sc->sc_chiprev));
  83676. + sc->sc_max_dsize = 256;
  83677. + } else {
  83678. + sc->sc_max_dsize = SAFE_MAX_DSIZE;
  83679. + }
  83680. +
  83681. + /* NB: operands+results are overlaid */
  83682. + WRITE_REG(sc, SAFE_PE_PDRBASE, sc->sc_ringalloc.dma_paddr);
  83683. + WRITE_REG(sc, SAFE_PE_RDRBASE, sc->sc_ringalloc.dma_paddr);
  83684. + /*
  83685. + * Configure ring entry size and number of items in the ring.
  83686. + */
  83687. + KASSERT((sizeof(struct safe_ringentry) % sizeof(u_int32_t)) == 0,
  83688. + ("PE ring entry not 32-bit aligned!"));
  83689. + dwords = sizeof(struct safe_ringentry) / sizeof(u_int32_t);
  83690. + WRITE_REG(sc, SAFE_PE_RINGCFG,
  83691. + (dwords << SAFE_PE_RINGCFG_OFFSET_S) | SAFE_MAX_NQUEUE);
  83692. + WRITE_REG(sc, SAFE_PE_RINGPOLL, 0); /* disable polling */
  83693. +
  83694. + WRITE_REG(sc, SAFE_PE_GRNGBASE, sc->sc_spalloc.dma_paddr);
  83695. + WRITE_REG(sc, SAFE_PE_SRNGBASE, sc->sc_dpalloc.dma_paddr);
  83696. + WRITE_REG(sc, SAFE_PE_PARTSIZE,
  83697. + (SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART);
  83698. + /*
  83699. + * NB: destination particles are fixed size. We use
  83700. + * an mbuf cluster and require all results go to
  83701. + * clusters or smaller.
  83702. + */
  83703. + WRITE_REG(sc, SAFE_PE_PARTCFG, sc->sc_max_dsize);
  83704. +
  83705. + /* it's now safe to enable PE mode, do it */
  83706. + WRITE_REG(sc, SAFE_PE_DMACFG, v | SAFE_PE_DMACFG_PEMODE);
  83707. +
  83708. + /*
  83709. + * Configure hardware to use level-triggered interrupts and
  83710. + * to interrupt after each descriptor is processed.
  83711. + */
  83712. + WRITE_REG(sc, SAFE_HI_CFG, SAFE_HI_CFG_LEVEL);
  83713. + WRITE_REG(sc, SAFE_HI_CLR, 0xffffffff);
  83714. + WRITE_REG(sc, SAFE_HI_DESC_CNT, 1);
  83715. + WRITE_REG(sc, SAFE_HI_MASK, SAFE_INT_PE_DDONE | SAFE_INT_PE_ERROR);
  83716. +}
  83717. +
  83718. +
  83719. +/*
  83720. + * Clean up after a chip crash.
  83721. + * It is assumed that the caller in splimp()
  83722. + */
  83723. +static void
  83724. +safe_cleanchip(struct safe_softc *sc)
  83725. +{
  83726. + DPRINTF(("%s()\n", __FUNCTION__));
  83727. +
  83728. + if (sc->sc_nqchip != 0) {
  83729. + struct safe_ringentry *re = sc->sc_back;
  83730. +
  83731. + while (re != sc->sc_front) {
  83732. + if (re->re_desc.d_csr != 0)
  83733. + safe_free_entry(sc, re);
  83734. + if (++re == sc->sc_ringtop)
  83735. + re = sc->sc_ring;
  83736. + }
  83737. + sc->sc_back = re;
  83738. + sc->sc_nqchip = 0;
  83739. + }
  83740. +}
  83741. +
  83742. +/*
  83743. + * free a safe_q
  83744. + * It is assumed that the caller is within splimp().
  83745. + */
  83746. +static int
  83747. +safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re)
  83748. +{
  83749. + struct cryptop *crp;
  83750. +
  83751. + DPRINTF(("%s()\n", __FUNCTION__));
  83752. +
  83753. + /*
  83754. + * Free header MCR
  83755. + */
  83756. + if ((re->re_dst_skb != NULL) && (re->re_src_skb != re->re_dst_skb))
  83757. +#ifdef NOTYET
  83758. + m_freem(re->re_dst_m);
  83759. +#else
  83760. + printk("%s,%d: SKB not supported\n", __FILE__, __LINE__);
  83761. +#endif
  83762. +
  83763. + crp = (struct cryptop *)re->re_crp;
  83764. +
  83765. + re->re_desc.d_csr = 0;
  83766. +
  83767. + crp->crp_etype = EFAULT;
  83768. + crypto_done(crp);
  83769. + return(0);
  83770. +}
  83771. +
  83772. +/*
  83773. + * Routine to reset the chip and clean up.
  83774. + * It is assumed that the caller is in splimp()
  83775. + */
  83776. +static void
  83777. +safe_totalreset(struct safe_softc *sc)
  83778. +{
  83779. + DPRINTF(("%s()\n", __FUNCTION__));
  83780. +
  83781. + safe_reset_board(sc);
  83782. + safe_init_board(sc);
  83783. + safe_cleanchip(sc);
  83784. +}
  83785. +
  83786. +/*
  83787. + * Is the operand suitable aligned for direct DMA. Each
  83788. + * segment must be aligned on a 32-bit boundary and all
  83789. + * but the last segment must be a multiple of 4 bytes.
  83790. + */
  83791. +static int
  83792. +safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op)
  83793. +{
  83794. + int i;
  83795. +
  83796. + DPRINTF(("%s()\n", __FUNCTION__));
  83797. +
  83798. + for (i = 0; i < op->nsegs; i++) {
  83799. + if (op->segs[i].ds_addr & 3)
  83800. + return (0);
  83801. + if (i != (op->nsegs - 1) && (op->segs[i].ds_len & 3))
  83802. + return (0);
  83803. + }
  83804. + return (1);
  83805. +}
  83806. +
  83807. +/*
  83808. + * Is the operand suitable for direct DMA as the destination
  83809. + * of an operation. The hardware requires that each ``particle''
  83810. + * but the last in an operation result have the same size. We
  83811. + * fix that size at SAFE_MAX_DSIZE bytes. This routine returns
  83812. + * 0 if some segment is not a multiple of of this size, 1 if all
  83813. + * segments are exactly this size, or 2 if segments are at worst
  83814. + * a multple of this size.
  83815. + */
  83816. +static int
  83817. +safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op)
  83818. +{
  83819. + int result = 1;
  83820. +
  83821. + DPRINTF(("%s()\n", __FUNCTION__));
  83822. +
  83823. + if (op->nsegs > 0) {
  83824. + int i;
  83825. +
  83826. + for (i = 0; i < op->nsegs-1; i++) {
  83827. + if (op->segs[i].ds_len % sc->sc_max_dsize)
  83828. + return (0);
  83829. + if (op->segs[i].ds_len != sc->sc_max_dsize)
  83830. + result = 2;
  83831. + }
  83832. + }
  83833. + return (result);
  83834. +}
  83835. +
  83836. +static int
  83837. +safe_kprocess(device_t dev, struct cryptkop *krp, int hint)
  83838. +{
  83839. + struct safe_softc *sc = device_get_softc(dev);
  83840. + struct safe_pkq *q;
  83841. + unsigned long flags;
  83842. +
  83843. + DPRINTF(("%s()\n", __FUNCTION__));
  83844. +
  83845. + if (sc == NULL) {
  83846. + krp->krp_status = EINVAL;
  83847. + goto err;
  83848. + }
  83849. +
  83850. + if (krp->krp_op != CRK_MOD_EXP) {
  83851. + krp->krp_status = EOPNOTSUPP;
  83852. + goto err;
  83853. + }
  83854. +
  83855. + q = (struct safe_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
  83856. + if (q == NULL) {
  83857. + krp->krp_status = ENOMEM;
  83858. + goto err;
  83859. + }
  83860. + memset(q, 0, sizeof(*q));
  83861. + q->pkq_krp = krp;
  83862. + INIT_LIST_HEAD(&q->pkq_list);
  83863. +
  83864. + spin_lock_irqsave(&sc->sc_pkmtx, flags);
  83865. + list_add_tail(&q->pkq_list, &sc->sc_pkq);
  83866. + safe_kfeed(sc);
  83867. + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
  83868. + return (0);
  83869. +
  83870. +err:
  83871. + crypto_kdone(krp);
  83872. + return (0);
  83873. +}
  83874. +
  83875. +#define SAFE_CRK_PARAM_BASE 0
  83876. +#define SAFE_CRK_PARAM_EXP 1
  83877. +#define SAFE_CRK_PARAM_MOD 2
  83878. +
  83879. +static int
  83880. +safe_kstart(struct safe_softc *sc)
  83881. +{
  83882. + struct cryptkop *krp = sc->sc_pkq_cur->pkq_krp;
  83883. + int exp_bits, mod_bits, base_bits;
  83884. + u_int32_t op, a_off, b_off, c_off, d_off;
  83885. +
  83886. + DPRINTF(("%s()\n", __FUNCTION__));
  83887. +
  83888. + if (krp->krp_iparams < 3 || krp->krp_oparams != 1) {
  83889. + krp->krp_status = EINVAL;
  83890. + return (1);
  83891. + }
  83892. +
  83893. + base_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_BASE]);
  83894. + if (base_bits > 2048)
  83895. + goto too_big;
  83896. + if (base_bits <= 0) /* 5. base not zero */
  83897. + goto too_small;
  83898. +
  83899. + exp_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_EXP]);
  83900. + if (exp_bits > 2048)
  83901. + goto too_big;
  83902. + if (exp_bits <= 0) /* 1. exponent word length > 0 */
  83903. + goto too_small; /* 4. exponent not zero */
  83904. +
  83905. + mod_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_MOD]);
  83906. + if (mod_bits > 2048)
  83907. + goto too_big;
  83908. + if (mod_bits <= 32) /* 2. modulus word length > 1 */
  83909. + goto too_small; /* 8. MSW of modulus != zero */
  83910. + if (mod_bits < exp_bits) /* 3 modulus len >= exponent len */
  83911. + goto too_small;
  83912. + if ((krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p[0] & 1) == 0)
  83913. + goto bad_domain; /* 6. modulus is odd */
  83914. + if (mod_bits > krp->krp_param[krp->krp_iparams].crp_nbits)
  83915. + goto too_small; /* make sure result will fit */
  83916. +
  83917. + /* 7. modulus > base */
  83918. + if (mod_bits < base_bits)
  83919. + goto too_small;
  83920. + if (mod_bits == base_bits) {
  83921. + u_int8_t *basep, *modp;
  83922. + int i;
  83923. +
  83924. + basep = krp->krp_param[SAFE_CRK_PARAM_BASE].crp_p +
  83925. + ((base_bits + 7) / 8) - 1;
  83926. + modp = krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p +
  83927. + ((mod_bits + 7) / 8) - 1;
  83928. +
  83929. + for (i = 0; i < (mod_bits + 7) / 8; i++, basep--, modp--) {
  83930. + if (*modp < *basep)
  83931. + goto too_small;
  83932. + if (*modp > *basep)
  83933. + break;
  83934. + }
  83935. + }
  83936. +
  83937. + /* And on the 9th step, he rested. */
  83938. +
  83939. + WRITE_REG(sc, SAFE_PK_A_LEN, (exp_bits + 31) / 32);
  83940. + WRITE_REG(sc, SAFE_PK_B_LEN, (mod_bits + 31) / 32);
  83941. + if (mod_bits > 1024) {
  83942. + op = SAFE_PK_FUNC_EXP4;
  83943. + a_off = 0x000;
  83944. + b_off = 0x100;
  83945. + c_off = 0x200;
  83946. + d_off = 0x300;
  83947. + } else {
  83948. + op = SAFE_PK_FUNC_EXP16;
  83949. + a_off = 0x000;
  83950. + b_off = 0x080;
  83951. + c_off = 0x100;
  83952. + d_off = 0x180;
  83953. + }
  83954. + sc->sc_pk_reslen = b_off - a_off;
  83955. + sc->sc_pk_resoff = d_off;
  83956. +
  83957. + /* A is exponent, B is modulus, C is base, D is result */
  83958. + safe_kload_reg(sc, a_off, b_off - a_off,
  83959. + &krp->krp_param[SAFE_CRK_PARAM_EXP]);
  83960. + WRITE_REG(sc, SAFE_PK_A_ADDR, a_off >> 2);
  83961. + safe_kload_reg(sc, b_off, b_off - a_off,
  83962. + &krp->krp_param[SAFE_CRK_PARAM_MOD]);
  83963. + WRITE_REG(sc, SAFE_PK_B_ADDR, b_off >> 2);
  83964. + safe_kload_reg(sc, c_off, b_off - a_off,
  83965. + &krp->krp_param[SAFE_CRK_PARAM_BASE]);
  83966. + WRITE_REG(sc, SAFE_PK_C_ADDR, c_off >> 2);
  83967. + WRITE_REG(sc, SAFE_PK_D_ADDR, d_off >> 2);
  83968. +
  83969. + WRITE_REG(sc, SAFE_PK_FUNC, op | SAFE_PK_FUNC_RUN);
  83970. +
  83971. + return (0);
  83972. +
  83973. +too_big:
  83974. + krp->krp_status = E2BIG;
  83975. + return (1);
  83976. +too_small:
  83977. + krp->krp_status = ERANGE;
  83978. + return (1);
  83979. +bad_domain:
  83980. + krp->krp_status = EDOM;
  83981. + return (1);
  83982. +}
  83983. +
  83984. +static int
  83985. +safe_ksigbits(struct safe_softc *sc, struct crparam *cr)
  83986. +{
  83987. + u_int plen = (cr->crp_nbits + 7) / 8;
  83988. + int i, sig = plen * 8;
  83989. + u_int8_t c, *p = cr->crp_p;
  83990. +
  83991. + DPRINTF(("%s()\n", __FUNCTION__));
  83992. +
  83993. + for (i = plen - 1; i >= 0; i--) {
  83994. + c = p[i];
  83995. + if (c != 0) {
  83996. + while ((c & 0x80) == 0) {
  83997. + sig--;
  83998. + c <<= 1;
  83999. + }
  84000. + break;
  84001. + }
  84002. + sig -= 8;
  84003. + }
  84004. + return (sig);
  84005. +}
  84006. +
  84007. +static void
  84008. +safe_kfeed(struct safe_softc *sc)
  84009. +{
  84010. + struct safe_pkq *q, *tmp;
  84011. +
  84012. + DPRINTF(("%s()\n", __FUNCTION__));
  84013. +
  84014. + if (list_empty(&sc->sc_pkq) && sc->sc_pkq_cur == NULL)
  84015. + return;
  84016. + if (sc->sc_pkq_cur != NULL)
  84017. + return;
  84018. + list_for_each_entry_safe(q, tmp, &sc->sc_pkq, pkq_list) {
  84019. + sc->sc_pkq_cur = q;
  84020. + list_del(&q->pkq_list);
  84021. + if (safe_kstart(sc) != 0) {
  84022. + crypto_kdone(q->pkq_krp);
  84023. + kfree(q);
  84024. + sc->sc_pkq_cur = NULL;
  84025. + } else {
  84026. + /* op started, start polling */
  84027. + mod_timer(&sc->sc_pkto, jiffies + 1);
  84028. + break;
  84029. + }
  84030. + }
  84031. +}
  84032. +
  84033. +static void
  84034. +safe_kpoll(unsigned long arg)
  84035. +{
  84036. + struct safe_softc *sc = NULL;
  84037. + struct safe_pkq *q;
  84038. + struct crparam *res;
  84039. + int i;
  84040. + u_int32_t buf[64];
  84041. + unsigned long flags;
  84042. +
  84043. + DPRINTF(("%s()\n", __FUNCTION__));
  84044. +
  84045. + if (arg >= SAFE_MAX_CHIPS)
  84046. + return;
  84047. + sc = safe_chip_idx[arg];
  84048. + if (!sc) {
  84049. + DPRINTF(("%s() - bad callback\n", __FUNCTION__));
  84050. + return;
  84051. + }
  84052. +
  84053. + spin_lock_irqsave(&sc->sc_pkmtx, flags);
  84054. + if (sc->sc_pkq_cur == NULL)
  84055. + goto out;
  84056. + if (READ_REG(sc, SAFE_PK_FUNC) & SAFE_PK_FUNC_RUN) {
  84057. + /* still running, check back later */
  84058. + mod_timer(&sc->sc_pkto, jiffies + 1);
  84059. + goto out;
  84060. + }
  84061. +
  84062. + q = sc->sc_pkq_cur;
  84063. + res = &q->pkq_krp->krp_param[q->pkq_krp->krp_iparams];
  84064. + bzero(buf, sizeof(buf));
  84065. + bzero(res->crp_p, (res->crp_nbits + 7) / 8);
  84066. + for (i = 0; i < sc->sc_pk_reslen >> 2; i++)
  84067. + buf[i] = le32_to_cpu(READ_REG(sc, SAFE_PK_RAM_START +
  84068. + sc->sc_pk_resoff + (i << 2)));
  84069. + bcopy(buf, res->crp_p, (res->crp_nbits + 7) / 8);
  84070. + /*
  84071. + * reduce the bits that need copying if possible
  84072. + */
  84073. + res->crp_nbits = min(res->crp_nbits,sc->sc_pk_reslen * 8);
  84074. + res->crp_nbits = safe_ksigbits(sc, res);
  84075. +
  84076. + for (i = SAFE_PK_RAM_START; i < SAFE_PK_RAM_END; i += 4)
  84077. + WRITE_REG(sc, i, 0);
  84078. +
  84079. + crypto_kdone(q->pkq_krp);
  84080. + kfree(q);
  84081. + sc->sc_pkq_cur = NULL;
  84082. +
  84083. + safe_kfeed(sc);
  84084. +out:
  84085. + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
  84086. +}
  84087. +
  84088. +static void
  84089. +safe_kload_reg(struct safe_softc *sc, u_int32_t off, u_int32_t len,
  84090. + struct crparam *n)
  84091. +{
  84092. + u_int32_t buf[64], i;
  84093. +
  84094. + DPRINTF(("%s()\n", __FUNCTION__));
  84095. +
  84096. + bzero(buf, sizeof(buf));
  84097. + bcopy(n->crp_p, buf, (n->crp_nbits + 7) / 8);
  84098. +
  84099. + for (i = 0; i < len >> 2; i++)
  84100. + WRITE_REG(sc, SAFE_PK_RAM_START + off + (i << 2),
  84101. + cpu_to_le32(buf[i]));
  84102. +}
  84103. +
  84104. +#ifdef SAFE_DEBUG
  84105. +static void
  84106. +safe_dump_dmastatus(struct safe_softc *sc, const char *tag)
  84107. +{
  84108. + printf("%s: ENDIAN 0x%x SRC 0x%x DST 0x%x STAT 0x%x\n"
  84109. + , tag
  84110. + , READ_REG(sc, SAFE_DMA_ENDIAN)
  84111. + , READ_REG(sc, SAFE_DMA_SRCADDR)
  84112. + , READ_REG(sc, SAFE_DMA_DSTADDR)
  84113. + , READ_REG(sc, SAFE_DMA_STAT)
  84114. + );
  84115. +}
  84116. +
  84117. +static void
  84118. +safe_dump_intrstate(struct safe_softc *sc, const char *tag)
  84119. +{
  84120. + printf("%s: HI_CFG 0x%x HI_MASK 0x%x HI_DESC_CNT 0x%x HU_STAT 0x%x HM_STAT 0x%x\n"
  84121. + , tag
  84122. + , READ_REG(sc, SAFE_HI_CFG)
  84123. + , READ_REG(sc, SAFE_HI_MASK)
  84124. + , READ_REG(sc, SAFE_HI_DESC_CNT)
  84125. + , READ_REG(sc, SAFE_HU_STAT)
  84126. + , READ_REG(sc, SAFE_HM_STAT)
  84127. + );
  84128. +}
  84129. +
  84130. +static void
  84131. +safe_dump_ringstate(struct safe_softc *sc, const char *tag)
  84132. +{
  84133. + u_int32_t estat = READ_REG(sc, SAFE_PE_ERNGSTAT);
  84134. +
  84135. + /* NB: assume caller has lock on ring */
  84136. + printf("%s: ERNGSTAT %x (next %u) back %lu front %lu\n",
  84137. + tag,
  84138. + estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S),
  84139. + (unsigned long)(sc->sc_back - sc->sc_ring),
  84140. + (unsigned long)(sc->sc_front - sc->sc_ring));
  84141. +}
  84142. +
  84143. +static void
  84144. +safe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re)
  84145. +{
  84146. + int ix, nsegs;
  84147. +
  84148. + ix = re - sc->sc_ring;
  84149. + printf("%s: %p (%u): csr %x src %x dst %x sa %x len %x\n"
  84150. + , tag
  84151. + , re, ix
  84152. + , re->re_desc.d_csr
  84153. + , re->re_desc.d_src
  84154. + , re->re_desc.d_dst
  84155. + , re->re_desc.d_sa
  84156. + , re->re_desc.d_len
  84157. + );
  84158. + if (re->re_src.nsegs > 1) {
  84159. + ix = (re->re_desc.d_src - sc->sc_spalloc.dma_paddr) /
  84160. + sizeof(struct safe_pdesc);
  84161. + for (nsegs = re->re_src.nsegs; nsegs; nsegs--) {
  84162. + printf(" spd[%u] %p: %p size %u flags %x"
  84163. + , ix, &sc->sc_spring[ix]
  84164. + , (caddr_t)(uintptr_t) sc->sc_spring[ix].pd_addr
  84165. + , sc->sc_spring[ix].pd_size
  84166. + , sc->sc_spring[ix].pd_flags
  84167. + );
  84168. + if (sc->sc_spring[ix].pd_size == 0)
  84169. + printf(" (zero!)");
  84170. + printf("\n");
  84171. + if (++ix == SAFE_TOTAL_SPART)
  84172. + ix = 0;
  84173. + }
  84174. + }
  84175. + if (re->re_dst.nsegs > 1) {
  84176. + ix = (re->re_desc.d_dst - sc->sc_dpalloc.dma_paddr) /
  84177. + sizeof(struct safe_pdesc);
  84178. + for (nsegs = re->re_dst.nsegs; nsegs; nsegs--) {
  84179. + printf(" dpd[%u] %p: %p flags %x\n"
  84180. + , ix, &sc->sc_dpring[ix]
  84181. + , (caddr_t)(uintptr_t) sc->sc_dpring[ix].pd_addr
  84182. + , sc->sc_dpring[ix].pd_flags
  84183. + );
  84184. + if (++ix == SAFE_TOTAL_DPART)
  84185. + ix = 0;
  84186. + }
  84187. + }
  84188. + printf("sa: cmd0 %08x cmd1 %08x staterec %x\n",
  84189. + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec);
  84190. + printf("sa: key %x %x %x %x %x %x %x %x\n"
  84191. + , re->re_sa.sa_key[0]
  84192. + , re->re_sa.sa_key[1]
  84193. + , re->re_sa.sa_key[2]
  84194. + , re->re_sa.sa_key[3]
  84195. + , re->re_sa.sa_key[4]
  84196. + , re->re_sa.sa_key[5]
  84197. + , re->re_sa.sa_key[6]
  84198. + , re->re_sa.sa_key[7]
  84199. + );
  84200. + printf("sa: indigest %x %x %x %x %x\n"
  84201. + , re->re_sa.sa_indigest[0]
  84202. + , re->re_sa.sa_indigest[1]
  84203. + , re->re_sa.sa_indigest[2]
  84204. + , re->re_sa.sa_indigest[3]
  84205. + , re->re_sa.sa_indigest[4]
  84206. + );
  84207. + printf("sa: outdigest %x %x %x %x %x\n"
  84208. + , re->re_sa.sa_outdigest[0]
  84209. + , re->re_sa.sa_outdigest[1]
  84210. + , re->re_sa.sa_outdigest[2]
  84211. + , re->re_sa.sa_outdigest[3]
  84212. + , re->re_sa.sa_outdigest[4]
  84213. + );
  84214. + printf("sr: iv %x %x %x %x\n"
  84215. + , re->re_sastate.sa_saved_iv[0]
  84216. + , re->re_sastate.sa_saved_iv[1]
  84217. + , re->re_sastate.sa_saved_iv[2]
  84218. + , re->re_sastate.sa_saved_iv[3]
  84219. + );
  84220. + printf("sr: hashbc %u indigest %x %x %x %x %x\n"
  84221. + , re->re_sastate.sa_saved_hashbc
  84222. + , re->re_sastate.sa_saved_indigest[0]
  84223. + , re->re_sastate.sa_saved_indigest[1]
  84224. + , re->re_sastate.sa_saved_indigest[2]
  84225. + , re->re_sastate.sa_saved_indigest[3]
  84226. + , re->re_sastate.sa_saved_indigest[4]
  84227. + );
  84228. +}
  84229. +
  84230. +static void
  84231. +safe_dump_ring(struct safe_softc *sc, const char *tag)
  84232. +{
  84233. + unsigned long flags;
  84234. +
  84235. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  84236. + printf("\nSafeNet Ring State:\n");
  84237. + safe_dump_intrstate(sc, tag);
  84238. + safe_dump_dmastatus(sc, tag);
  84239. + safe_dump_ringstate(sc, tag);
  84240. + if (sc->sc_nqchip) {
  84241. + struct safe_ringentry *re = sc->sc_back;
  84242. + do {
  84243. + safe_dump_request(sc, tag, re);
  84244. + if (++re == sc->sc_ringtop)
  84245. + re = sc->sc_ring;
  84246. + } while (re != sc->sc_front);
  84247. + }
  84248. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  84249. +}
  84250. +#endif /* SAFE_DEBUG */
  84251. +
  84252. +
  84253. +static int safe_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  84254. +{
  84255. + struct safe_softc *sc = NULL;
  84256. + u32 mem_start, mem_len, cmd;
  84257. + int i, rc, devinfo;
  84258. + dma_addr_t raddr;
  84259. + static int num_chips = 0;
  84260. +
  84261. + DPRINTF(("%s()\n", __FUNCTION__));
  84262. +
  84263. + if (pci_enable_device(dev) < 0)
  84264. + return(-ENODEV);
  84265. +
  84266. + if (!dev->irq) {
  84267. + printk("safe: found device with no IRQ assigned. check BIOS settings!");
  84268. + pci_disable_device(dev);
  84269. + return(-ENODEV);
  84270. + }
  84271. +
  84272. + if (pci_set_mwi(dev)) {
  84273. + printk("safe: pci_set_mwi failed!");
  84274. + return(-ENODEV);
  84275. + }
  84276. +
  84277. + sc = (struct safe_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  84278. + if (!sc)
  84279. + return(-ENOMEM);
  84280. + memset(sc, 0, sizeof(*sc));
  84281. +
  84282. + softc_device_init(sc, "safe", num_chips, safe_methods);
  84283. +
  84284. + sc->sc_irq = -1;
  84285. + sc->sc_cid = -1;
  84286. + sc->sc_pcidev = dev;
  84287. + if (num_chips < SAFE_MAX_CHIPS) {
  84288. + safe_chip_idx[device_get_unit(sc->sc_dev)] = sc;
  84289. + num_chips++;
  84290. + }
  84291. +
  84292. + INIT_LIST_HEAD(&sc->sc_pkq);
  84293. + spin_lock_init(&sc->sc_pkmtx);
  84294. +
  84295. + pci_set_drvdata(sc->sc_pcidev, sc);
  84296. +
  84297. + /* we read its hardware registers as memory */
  84298. + mem_start = pci_resource_start(sc->sc_pcidev, 0);
  84299. + mem_len = pci_resource_len(sc->sc_pcidev, 0);
  84300. +
  84301. + sc->sc_base_addr = (ocf_iomem_t) ioremap(mem_start, mem_len);
  84302. + if (!sc->sc_base_addr) {
  84303. + device_printf(sc->sc_dev, "failed to ioremap 0x%x-0x%x\n",
  84304. + mem_start, mem_start + mem_len - 1);
  84305. + goto out;
  84306. + }
  84307. +
  84308. + /* fix up the bus size */
  84309. + if (pci_set_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
  84310. + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
  84311. + goto out;
  84312. + }
  84313. + if (pci_set_consistent_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
  84314. + device_printf(sc->sc_dev, "No usable consistent DMA configuration, aborting.\n");
  84315. + goto out;
  84316. + }
  84317. +
  84318. + pci_set_master(sc->sc_pcidev);
  84319. +
  84320. + pci_read_config_dword(sc->sc_pcidev, PCI_COMMAND, &cmd);
  84321. +
  84322. + if (!(cmd & PCI_COMMAND_MEMORY)) {
  84323. + device_printf(sc->sc_dev, "failed to enable memory mapping\n");
  84324. + goto out;
  84325. + }
  84326. +
  84327. + if (!(cmd & PCI_COMMAND_MASTER)) {
  84328. + device_printf(sc->sc_dev, "failed to enable bus mastering\n");
  84329. + goto out;
  84330. + }
  84331. +
  84332. + rc = request_irq(dev->irq, safe_intr, IRQF_SHARED, "safe", sc);
  84333. + if (rc) {
  84334. + device_printf(sc->sc_dev, "failed to hook irq %d\n", sc->sc_irq);
  84335. + goto out;
  84336. + }
  84337. + sc->sc_irq = dev->irq;
  84338. +
  84339. + sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) &
  84340. + (SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN);
  84341. +
  84342. + /*
  84343. + * Allocate packet engine descriptors.
  84344. + */
  84345. + sc->sc_ringalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  84346. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  84347. + &sc->sc_ringalloc.dma_paddr);
  84348. + if (!sc->sc_ringalloc.dma_vaddr) {
  84349. + device_printf(sc->sc_dev, "cannot allocate PE descriptor ring\n");
  84350. + goto out;
  84351. + }
  84352. +
  84353. + /*
  84354. + * Hookup the static portion of all our data structures.
  84355. + */
  84356. + sc->sc_ring = (struct safe_ringentry *) sc->sc_ringalloc.dma_vaddr;
  84357. + sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE;
  84358. + sc->sc_front = sc->sc_ring;
  84359. + sc->sc_back = sc->sc_ring;
  84360. + raddr = sc->sc_ringalloc.dma_paddr;
  84361. + bzero(sc->sc_ring, SAFE_MAX_NQUEUE * sizeof(struct safe_ringentry));
  84362. + for (i = 0; i < SAFE_MAX_NQUEUE; i++) {
  84363. + struct safe_ringentry *re = &sc->sc_ring[i];
  84364. +
  84365. + re->re_desc.d_sa = raddr +
  84366. + offsetof(struct safe_ringentry, re_sa);
  84367. + re->re_sa.sa_staterec = raddr +
  84368. + offsetof(struct safe_ringentry, re_sastate);
  84369. +
  84370. + raddr += sizeof (struct safe_ringentry);
  84371. + }
  84372. + spin_lock_init(&sc->sc_ringmtx);
  84373. +
  84374. + /*
  84375. + * Allocate scatter and gather particle descriptors.
  84376. + */
  84377. + sc->sc_spalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  84378. + SAFE_TOTAL_SPART * sizeof (struct safe_pdesc),
  84379. + &sc->sc_spalloc.dma_paddr);
  84380. + if (!sc->sc_spalloc.dma_vaddr) {
  84381. + device_printf(sc->sc_dev, "cannot allocate source particle descriptor ring\n");
  84382. + goto out;
  84383. + }
  84384. + sc->sc_spring = (struct safe_pdesc *) sc->sc_spalloc.dma_vaddr;
  84385. + sc->sc_springtop = sc->sc_spring + SAFE_TOTAL_SPART;
  84386. + sc->sc_spfree = sc->sc_spring;
  84387. + bzero(sc->sc_spring, SAFE_TOTAL_SPART * sizeof(struct safe_pdesc));
  84388. +
  84389. + sc->sc_dpalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  84390. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  84391. + &sc->sc_dpalloc.dma_paddr);
  84392. + if (!sc->sc_dpalloc.dma_vaddr) {
  84393. + device_printf(sc->sc_dev, "cannot allocate destination particle descriptor ring\n");
  84394. + goto out;
  84395. + }
  84396. + sc->sc_dpring = (struct safe_pdesc *) sc->sc_dpalloc.dma_vaddr;
  84397. + sc->sc_dpringtop = sc->sc_dpring + SAFE_TOTAL_DPART;
  84398. + sc->sc_dpfree = sc->sc_dpring;
  84399. + bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc));
  84400. +
  84401. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc), CRYPTOCAP_F_HARDWARE);
  84402. + if (sc->sc_cid < 0) {
  84403. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  84404. + goto out;
  84405. + }
  84406. +
  84407. + printf("%s:", device_get_nameunit(sc->sc_dev));
  84408. +
  84409. + devinfo = READ_REG(sc, SAFE_DEVINFO);
  84410. + if (devinfo & SAFE_DEVINFO_RNG) {
  84411. + sc->sc_flags |= SAFE_FLAGS_RNG;
  84412. + printf(" rng");
  84413. + }
  84414. + if (devinfo & SAFE_DEVINFO_PKEY) {
  84415. + printf(" key");
  84416. + sc->sc_flags |= SAFE_FLAGS_KEY;
  84417. + crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0);
  84418. +#if 0
  84419. + crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0);
  84420. +#endif
  84421. + init_timer(&sc->sc_pkto);
  84422. + sc->sc_pkto.function = safe_kpoll;
  84423. + sc->sc_pkto.data = (unsigned long) device_get_unit(sc->sc_dev);
  84424. + }
  84425. + if (devinfo & SAFE_DEVINFO_DES) {
  84426. + printf(" des/3des");
  84427. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  84428. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  84429. + }
  84430. + if (devinfo & SAFE_DEVINFO_AES) {
  84431. + printf(" aes");
  84432. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  84433. + }
  84434. + if (devinfo & SAFE_DEVINFO_MD5) {
  84435. + printf(" md5");
  84436. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  84437. + }
  84438. + if (devinfo & SAFE_DEVINFO_SHA1) {
  84439. + printf(" sha1");
  84440. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  84441. + }
  84442. + printf(" null");
  84443. + crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0);
  84444. + crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0);
  84445. + /* XXX other supported algorithms */
  84446. + printf("\n");
  84447. +
  84448. + safe_reset_board(sc); /* reset h/w */
  84449. + safe_init_board(sc); /* init h/w */
  84450. +
  84451. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  84452. + if (sc->sc_flags & SAFE_FLAGS_RNG) {
  84453. + safe_rng_init(sc);
  84454. + crypto_rregister(sc->sc_cid, safe_read_random, sc);
  84455. + }
  84456. +#endif /* SAFE_NO_RNG */
  84457. +
  84458. + return (0);
  84459. +
  84460. +out:
  84461. + if (sc->sc_cid >= 0)
  84462. + crypto_unregister_all(sc->sc_cid);
  84463. + if (sc->sc_irq != -1)
  84464. + free_irq(sc->sc_irq, sc);
  84465. + if (sc->sc_ringalloc.dma_vaddr)
  84466. + pci_free_consistent(sc->sc_pcidev,
  84467. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  84468. + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
  84469. + if (sc->sc_spalloc.dma_vaddr)
  84470. + pci_free_consistent(sc->sc_pcidev,
  84471. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  84472. + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
  84473. + if (sc->sc_dpalloc.dma_vaddr)
  84474. + pci_free_consistent(sc->sc_pcidev,
  84475. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  84476. + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
  84477. + kfree(sc);
  84478. + return(-ENODEV);
  84479. +}
  84480. +
  84481. +static void safe_remove(struct pci_dev *dev)
  84482. +{
  84483. + struct safe_softc *sc = pci_get_drvdata(dev);
  84484. +
  84485. + DPRINTF(("%s()\n", __FUNCTION__));
  84486. +
  84487. + /* XXX wait/abort active ops */
  84488. +
  84489. + WRITE_REG(sc, SAFE_HI_MASK, 0); /* disable interrupts */
  84490. +
  84491. + del_timer_sync(&sc->sc_pkto);
  84492. +
  84493. + crypto_unregister_all(sc->sc_cid);
  84494. +
  84495. + safe_cleanchip(sc);
  84496. +
  84497. + if (sc->sc_irq != -1)
  84498. + free_irq(sc->sc_irq, sc);
  84499. + if (sc->sc_ringalloc.dma_vaddr)
  84500. + pci_free_consistent(sc->sc_pcidev,
  84501. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  84502. + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
  84503. + if (sc->sc_spalloc.dma_vaddr)
  84504. + pci_free_consistent(sc->sc_pcidev,
  84505. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  84506. + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
  84507. + if (sc->sc_dpalloc.dma_vaddr)
  84508. + pci_free_consistent(sc->sc_pcidev,
  84509. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  84510. + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
  84511. + sc->sc_irq = -1;
  84512. + sc->sc_ringalloc.dma_vaddr = NULL;
  84513. + sc->sc_spalloc.dma_vaddr = NULL;
  84514. + sc->sc_dpalloc.dma_vaddr = NULL;
  84515. +}
  84516. +
  84517. +static struct pci_device_id safe_pci_tbl[] = {
  84518. + { PCI_VENDOR_SAFENET, PCI_PRODUCT_SAFEXCEL,
  84519. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  84520. + { },
  84521. +};
  84522. +MODULE_DEVICE_TABLE(pci, safe_pci_tbl);
  84523. +
  84524. +static struct pci_driver safe_driver = {
  84525. + .name = "safe",
  84526. + .id_table = safe_pci_tbl,
  84527. + .probe = safe_probe,
  84528. + .remove = safe_remove,
  84529. + /* add PM stuff here one day */
  84530. +};
  84531. +
  84532. +static int __init safe_init (void)
  84533. +{
  84534. + struct safe_softc *sc = NULL;
  84535. + int rc;
  84536. +
  84537. + DPRINTF(("%s(%p)\n", __FUNCTION__, safe_init));
  84538. +
  84539. + rc = pci_register_driver(&safe_driver);
  84540. + pci_register_driver_compat(&safe_driver, rc);
  84541. +
  84542. + return rc;
  84543. +}
  84544. +
  84545. +static void __exit safe_exit (void)
  84546. +{
  84547. + pci_unregister_driver(&safe_driver);
  84548. +}
  84549. +
  84550. +module_init(safe_init);
  84551. +module_exit(safe_exit);
  84552. +
  84553. +MODULE_LICENSE("BSD");
  84554. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  84555. +MODULE_DESCRIPTION("OCF driver for safenet PCI crypto devices");
  84556. diff -Nur linux-2.6.36.orig/crypto/ocf/safe/safereg.h linux-2.6.36/crypto/ocf/safe/safereg.h
  84557. --- linux-2.6.36.orig/crypto/ocf/safe/safereg.h 1970-01-01 01:00:00.000000000 +0100
  84558. +++ linux-2.6.36/crypto/ocf/safe/safereg.h 2010-11-09 20:28:12.962495464 +0100
  84559. @@ -0,0 +1,421 @@
  84560. +/*-
  84561. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  84562. + * Copyright (c) 2003 Global Technology Associates, Inc.
  84563. + * All rights reserved.
  84564. + *
  84565. + * Redistribution and use in source and binary forms, with or without
  84566. + * modification, are permitted provided that the following conditions
  84567. + * are met:
  84568. + * 1. Redistributions of source code must retain the above copyright
  84569. + * notice, this list of conditions and the following disclaimer.
  84570. + * 2. Redistributions in binary form must reproduce the above copyright
  84571. + * notice, this list of conditions and the following disclaimer in the
  84572. + * documentation and/or other materials provided with the distribution.
  84573. + *
  84574. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  84575. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  84576. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  84577. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  84578. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  84579. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  84580. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  84581. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  84582. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  84583. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  84584. + * SUCH DAMAGE.
  84585. + *
  84586. + * $FreeBSD: src/sys/dev/safe/safereg.h,v 1.1 2003/07/21 21:46:07 sam Exp $
  84587. + */
  84588. +#ifndef _SAFE_SAFEREG_H_
  84589. +#define _SAFE_SAFEREG_H_
  84590. +
  84591. +/*
  84592. + * Register definitions for SafeNet SafeXcel-1141 crypto device.
  84593. + * Definitions from revision 1.3 (Nov 6 2002) of the User's Manual.
  84594. + */
  84595. +
  84596. +#define BS_BAR 0x10 /* DMA base address register */
  84597. +#define BS_TRDY_TIMEOUT 0x40 /* TRDY timeout */
  84598. +#define BS_RETRY_TIMEOUT 0x41 /* DMA retry timeout */
  84599. +
  84600. +#define PCI_VENDOR_SAFENET 0x16ae /* SafeNet, Inc. */
  84601. +
  84602. +/* SafeNet */
  84603. +#define PCI_PRODUCT_SAFEXCEL 0x1141 /* 1141 */
  84604. +
  84605. +#define SAFE_PE_CSR 0x0000 /* Packet Enginge Ctrl/Status */
  84606. +#define SAFE_PE_SRC 0x0004 /* Packet Engine Source */
  84607. +#define SAFE_PE_DST 0x0008 /* Packet Engine Destination */
  84608. +#define SAFE_PE_SA 0x000c /* Packet Engine SA */
  84609. +#define SAFE_PE_LEN 0x0010 /* Packet Engine Length */
  84610. +#define SAFE_PE_DMACFG 0x0040 /* Packet Engine DMA Configuration */
  84611. +#define SAFE_PE_DMASTAT 0x0044 /* Packet Engine DMA Status */
  84612. +#define SAFE_PE_PDRBASE 0x0048 /* Packet Engine Descriptor Ring Base */
  84613. +#define SAFE_PE_RDRBASE 0x004c /* Packet Engine Result Ring Base */
  84614. +#define SAFE_PE_RINGCFG 0x0050 /* Packet Engine Ring Configuration */
  84615. +#define SAFE_PE_RINGPOLL 0x0054 /* Packet Engine Ring Poll */
  84616. +#define SAFE_PE_IRNGSTAT 0x0058 /* Packet Engine Internal Ring Status */
  84617. +#define SAFE_PE_ERNGSTAT 0x005c /* Packet Engine External Ring Status */
  84618. +#define SAFE_PE_IOTHRESH 0x0060 /* Packet Engine I/O Threshold */
  84619. +#define SAFE_PE_GRNGBASE 0x0064 /* Packet Engine Gather Ring Base */
  84620. +#define SAFE_PE_SRNGBASE 0x0068 /* Packet Engine Scatter Ring Base */
  84621. +#define SAFE_PE_PARTSIZE 0x006c /* Packet Engine Particlar Ring Size */
  84622. +#define SAFE_PE_PARTCFG 0x0070 /* Packet Engine Particle Ring Config */
  84623. +#define SAFE_CRYPTO_CTRL 0x0080 /* Crypto Control */
  84624. +#define SAFE_DEVID 0x0084 /* Device ID */
  84625. +#define SAFE_DEVINFO 0x0088 /* Device Info */
  84626. +#define SAFE_HU_STAT 0x00a0 /* Host Unmasked Status */
  84627. +#define SAFE_HM_STAT 0x00a4 /* Host Masked Status (read-only) */
  84628. +#define SAFE_HI_CLR 0x00a4 /* Host Clear Interrupt (write-only) */
  84629. +#define SAFE_HI_MASK 0x00a8 /* Host Mask Control */
  84630. +#define SAFE_HI_CFG 0x00ac /* Interrupt Configuration */
  84631. +#define SAFE_HI_RD_DESCR 0x00b4 /* Force Descriptor Read */
  84632. +#define SAFE_HI_DESC_CNT 0x00b8 /* Host Descriptor Done Count */
  84633. +#define SAFE_DMA_ENDIAN 0x00c0 /* Master Endian Status */
  84634. +#define SAFE_DMA_SRCADDR 0x00c4 /* DMA Source Address Status */
  84635. +#define SAFE_DMA_DSTADDR 0x00c8 /* DMA Destination Address Status */
  84636. +#define SAFE_DMA_STAT 0x00cc /* DMA Current Status */
  84637. +#define SAFE_DMA_CFG 0x00d4 /* DMA Configuration/Status */
  84638. +#define SAFE_ENDIAN 0x00e0 /* Endian Configuration */
  84639. +#define SAFE_PK_A_ADDR 0x0800 /* Public Key A Address */
  84640. +#define SAFE_PK_B_ADDR 0x0804 /* Public Key B Address */
  84641. +#define SAFE_PK_C_ADDR 0x0808 /* Public Key C Address */
  84642. +#define SAFE_PK_D_ADDR 0x080c /* Public Key D Address */
  84643. +#define SAFE_PK_A_LEN 0x0810 /* Public Key A Length */
  84644. +#define SAFE_PK_B_LEN 0x0814 /* Public Key B Length */
  84645. +#define SAFE_PK_SHIFT 0x0818 /* Public Key Shift */
  84646. +#define SAFE_PK_FUNC 0x081c /* Public Key Function */
  84647. +#define SAFE_PK_RAM_START 0x1000 /* Public Key RAM start address */
  84648. +#define SAFE_PK_RAM_END 0x1fff /* Public Key RAM end address */
  84649. +
  84650. +#define SAFE_RNG_OUT 0x0100 /* RNG Output */
  84651. +#define SAFE_RNG_STAT 0x0104 /* RNG Status */
  84652. +#define SAFE_RNG_CTRL 0x0108 /* RNG Control */
  84653. +#define SAFE_RNG_A 0x010c /* RNG A */
  84654. +#define SAFE_RNG_B 0x0110 /* RNG B */
  84655. +#define SAFE_RNG_X_LO 0x0114 /* RNG X [31:0] */
  84656. +#define SAFE_RNG_X_MID 0x0118 /* RNG X [63:32] */
  84657. +#define SAFE_RNG_X_HI 0x011c /* RNG X [80:64] */
  84658. +#define SAFE_RNG_X_CNTR 0x0120 /* RNG Counter */
  84659. +#define SAFE_RNG_ALM_CNT 0x0124 /* RNG Alarm Count */
  84660. +#define SAFE_RNG_CNFG 0x0128 /* RNG Configuration */
  84661. +#define SAFE_RNG_LFSR1_LO 0x012c /* RNG LFSR1 [31:0] */
  84662. +#define SAFE_RNG_LFSR1_HI 0x0130 /* RNG LFSR1 [47:32] */
  84663. +#define SAFE_RNG_LFSR2_LO 0x0134 /* RNG LFSR1 [31:0] */
  84664. +#define SAFE_RNG_LFSR2_HI 0x0138 /* RNG LFSR1 [47:32] */
  84665. +
  84666. +#define SAFE_PE_CSR_READY 0x00000001 /* ready for processing */
  84667. +#define SAFE_PE_CSR_DONE 0x00000002 /* h/w completed processing */
  84668. +#define SAFE_PE_CSR_LOADSA 0x00000004 /* load SA digests */
  84669. +#define SAFE_PE_CSR_HASHFINAL 0x00000010 /* do hash pad & write result */
  84670. +#define SAFE_PE_CSR_SABUSID 0x000000c0 /* bus id for SA */
  84671. +#define SAFE_PE_CSR_SAPCI 0x00000040 /* PCI bus id for SA */
  84672. +#define SAFE_PE_CSR_NXTHDR 0x0000ff00 /* next hdr value for IPsec */
  84673. +#define SAFE_PE_CSR_FPAD 0x0000ff00 /* fixed pad for basic ops */
  84674. +#define SAFE_PE_CSR_STATUS 0x00ff0000 /* operation result status */
  84675. +#define SAFE_PE_CSR_AUTH_FAIL 0x00010000 /* ICV mismatch (inbound) */
  84676. +#define SAFE_PE_CSR_PAD_FAIL 0x00020000 /* pad verify fail (inbound) */
  84677. +#define SAFE_PE_CSR_SEQ_FAIL 0x00040000 /* sequence number (inbound) */
  84678. +#define SAFE_PE_CSR_XERROR 0x00080000 /* extended error follows */
  84679. +#define SAFE_PE_CSR_XECODE 0x00f00000 /* extended error code */
  84680. +#define SAFE_PE_CSR_XECODE_S 20
  84681. +#define SAFE_PE_CSR_XECODE_BADCMD 0 /* invalid command */
  84682. +#define SAFE_PE_CSR_XECODE_BADALG 1 /* invalid algorithm */
  84683. +#define SAFE_PE_CSR_XECODE_ALGDIS 2 /* algorithm disabled */
  84684. +#define SAFE_PE_CSR_XECODE_ZEROLEN 3 /* zero packet length */
  84685. +#define SAFE_PE_CSR_XECODE_DMAERR 4 /* bus DMA error */
  84686. +#define SAFE_PE_CSR_XECODE_PIPEABORT 5 /* secondary bus DMA error */
  84687. +#define SAFE_PE_CSR_XECODE_BADSPI 6 /* IPsec SPI mismatch */
  84688. +#define SAFE_PE_CSR_XECODE_TIMEOUT 10 /* failsafe timeout */
  84689. +#define SAFE_PE_CSR_PAD 0xff000000 /* ESP padding control/status */
  84690. +#define SAFE_PE_CSR_PAD_MIN 0x00000000 /* minimum IPsec padding */
  84691. +#define SAFE_PE_CSR_PAD_16 0x08000000 /* pad to 16-byte boundary */
  84692. +#define SAFE_PE_CSR_PAD_32 0x10000000 /* pad to 32-byte boundary */
  84693. +#define SAFE_PE_CSR_PAD_64 0x20000000 /* pad to 64-byte boundary */
  84694. +#define SAFE_PE_CSR_PAD_128 0x40000000 /* pad to 128-byte boundary */
  84695. +#define SAFE_PE_CSR_PAD_256 0x80000000 /* pad to 256-byte boundary */
  84696. +
  84697. +/*
  84698. + * Check the CSR to see if the PE has returned ownership to
  84699. + * the host. Note that before processing a descriptor this
  84700. + * must be done followed by a check of the SAFE_PE_LEN register
  84701. + * status bits to avoid premature processing of a descriptor
  84702. + * on its way back to the host.
  84703. + */
  84704. +#define SAFE_PE_CSR_IS_DONE(_csr) \
  84705. + (((_csr) & (SAFE_PE_CSR_READY | SAFE_PE_CSR_DONE)) == SAFE_PE_CSR_DONE)
  84706. +
  84707. +#define SAFE_PE_LEN_LENGTH 0x000fffff /* total length (bytes) */
  84708. +#define SAFE_PE_LEN_READY 0x00400000 /* ready for processing */
  84709. +#define SAFE_PE_LEN_DONE 0x00800000 /* h/w completed processing */
  84710. +#define SAFE_PE_LEN_BYPASS 0xff000000 /* bypass offset (bytes) */
  84711. +#define SAFE_PE_LEN_BYPASS_S 24
  84712. +
  84713. +#define SAFE_PE_LEN_IS_DONE(_len) \
  84714. + (((_len) & (SAFE_PE_LEN_READY | SAFE_PE_LEN_DONE)) == SAFE_PE_LEN_DONE)
  84715. +
  84716. +/* NB: these apply to HU_STAT, HM_STAT, HI_CLR, and HI_MASK */
  84717. +#define SAFE_INT_PE_CDONE 0x00000002 /* PE context done */
  84718. +#define SAFE_INT_PE_DDONE 0x00000008 /* PE descriptor done */
  84719. +#define SAFE_INT_PE_ERROR 0x00000010 /* PE error */
  84720. +#define SAFE_INT_PE_ODONE 0x00000020 /* PE operation done */
  84721. +
  84722. +#define SAFE_HI_CFG_PULSE 0x00000001 /* use pulse interrupt */
  84723. +#define SAFE_HI_CFG_LEVEL 0x00000000 /* use level interrupt */
  84724. +#define SAFE_HI_CFG_AUTOCLR 0x00000002 /* auto-clear pulse interrupt */
  84725. +
  84726. +#define SAFE_ENDIAN_PASS 0x000000e4 /* straight pass-thru */
  84727. +#define SAFE_ENDIAN_SWAB 0x0000001b /* swap bytes in 32-bit word */
  84728. +
  84729. +#define SAFE_PE_DMACFG_PERESET 0x00000001 /* reset packet engine */
  84730. +#define SAFE_PE_DMACFG_PDRRESET 0x00000002 /* reset PDR counters/ptrs */
  84731. +#define SAFE_PE_DMACFG_SGRESET 0x00000004 /* reset scatter/gather cache */
  84732. +#define SAFE_PE_DMACFG_FSENA 0x00000008 /* enable failsafe reset */
  84733. +#define SAFE_PE_DMACFG_PEMODE 0x00000100 /* packet engine mode */
  84734. +#define SAFE_PE_DMACFG_SAPREC 0x00000200 /* SA precedes packet */
  84735. +#define SAFE_PE_DMACFG_PKFOLL 0x00000400 /* packet follows descriptor */
  84736. +#define SAFE_PE_DMACFG_GPRBID 0x00003000 /* gather particle ring busid */
  84737. +#define SAFE_PE_DMACFG_GPRPCI 0x00001000 /* PCI gather particle ring */
  84738. +#define SAFE_PE_DMACFG_SPRBID 0x0000c000 /* scatter part. ring busid */
  84739. +#define SAFE_PE_DMACFG_SPRPCI 0x00004000 /* PCI scatter part. ring */
  84740. +#define SAFE_PE_DMACFG_ESDESC 0x00010000 /* endian swap descriptors */
  84741. +#define SAFE_PE_DMACFG_ESSA 0x00020000 /* endian swap SA data */
  84742. +#define SAFE_PE_DMACFG_ESPACKET 0x00040000 /* endian swap packet data */
  84743. +#define SAFE_PE_DMACFG_ESPDESC 0x00080000 /* endian swap particle desc. */
  84744. +#define SAFE_PE_DMACFG_NOPDRUP 0x00100000 /* supp. PDR ownership update */
  84745. +#define SAFE_PD_EDMACFG_PCIMODE 0x01000000 /* PCI target mode */
  84746. +
  84747. +#define SAFE_PE_DMASTAT_PEIDONE 0x00000001 /* PE core input done */
  84748. +#define SAFE_PE_DMASTAT_PEODONE 0x00000002 /* PE core output done */
  84749. +#define SAFE_PE_DMASTAT_ENCDONE 0x00000004 /* encryption done */
  84750. +#define SAFE_PE_DMASTAT_IHDONE 0x00000008 /* inner hash done */
  84751. +#define SAFE_PE_DMASTAT_OHDONE 0x00000010 /* outer hash (HMAC) done */
  84752. +#define SAFE_PE_DMASTAT_PADFLT 0x00000020 /* crypto pad fault */
  84753. +#define SAFE_PE_DMASTAT_ICVFLT 0x00000040 /* ICV fault */
  84754. +#define SAFE_PE_DMASTAT_SPIMIS 0x00000080 /* SPI mismatch */
  84755. +#define SAFE_PE_DMASTAT_CRYPTO 0x00000100 /* crypto engine timeout */
  84756. +#define SAFE_PE_DMASTAT_CQACT 0x00000200 /* command queue active */
  84757. +#define SAFE_PE_DMASTAT_IRACT 0x00000400 /* input request active */
  84758. +#define SAFE_PE_DMASTAT_ORACT 0x00000800 /* output request active */
  84759. +#define SAFE_PE_DMASTAT_PEISIZE 0x003ff000 /* PE input size:32-bit words */
  84760. +#define SAFE_PE_DMASTAT_PEOSIZE 0xffc00000 /* PE out. size:32-bit words */
  84761. +
  84762. +#define SAFE_PE_RINGCFG_SIZE 0x000003ff /* ring size (descriptors) */
  84763. +#define SAFE_PE_RINGCFG_OFFSET 0xffff0000 /* offset btw desc's (dwords) */
  84764. +#define SAFE_PE_RINGCFG_OFFSET_S 16
  84765. +
  84766. +#define SAFE_PE_RINGPOLL_POLL 0x00000fff /* polling frequency/divisor */
  84767. +#define SAFE_PE_RINGPOLL_RETRY 0x03ff0000 /* polling frequency/divisor */
  84768. +#define SAFE_PE_RINGPOLL_CONT 0x80000000 /* continuously poll */
  84769. +
  84770. +#define SAFE_PE_IRNGSTAT_CQAVAIL 0x00000001 /* command queue available */
  84771. +
  84772. +#define SAFE_PE_ERNGSTAT_NEXT 0x03ff0000 /* index of next packet desc. */
  84773. +#define SAFE_PE_ERNGSTAT_NEXT_S 16
  84774. +
  84775. +#define SAFE_PE_IOTHRESH_INPUT 0x000003ff /* input threshold (dwords) */
  84776. +#define SAFE_PE_IOTHRESH_OUTPUT 0x03ff0000 /* output threshold (dwords) */
  84777. +
  84778. +#define SAFE_PE_PARTCFG_SIZE 0x0000ffff /* scatter particle size */
  84779. +#define SAFE_PE_PARTCFG_GBURST 0x00030000 /* gather particle burst */
  84780. +#define SAFE_PE_PARTCFG_GBURST_2 0x00000000
  84781. +#define SAFE_PE_PARTCFG_GBURST_4 0x00010000
  84782. +#define SAFE_PE_PARTCFG_GBURST_8 0x00020000
  84783. +#define SAFE_PE_PARTCFG_GBURST_16 0x00030000
  84784. +#define SAFE_PE_PARTCFG_SBURST 0x000c0000 /* scatter particle burst */
  84785. +#define SAFE_PE_PARTCFG_SBURST_2 0x00000000
  84786. +#define SAFE_PE_PARTCFG_SBURST_4 0x00040000
  84787. +#define SAFE_PE_PARTCFG_SBURST_8 0x00080000
  84788. +#define SAFE_PE_PARTCFG_SBURST_16 0x000c0000
  84789. +
  84790. +#define SAFE_PE_PARTSIZE_SCAT 0xffff0000 /* scatter particle ring size */
  84791. +#define SAFE_PE_PARTSIZE_GATH 0x0000ffff /* gather particle ring size */
  84792. +
  84793. +#define SAFE_CRYPTO_CTRL_3DES 0x00000001 /* enable 3DES support */
  84794. +#define SAFE_CRYPTO_CTRL_PKEY 0x00010000 /* enable public key support */
  84795. +#define SAFE_CRYPTO_CTRL_RNG 0x00020000 /* enable RNG support */
  84796. +
  84797. +#define SAFE_DEVINFO_REV_MIN 0x0000000f /* minor rev for chip */
  84798. +#define SAFE_DEVINFO_REV_MAJ 0x000000f0 /* major rev for chip */
  84799. +#define SAFE_DEVINFO_REV_MAJ_S 4
  84800. +#define SAFE_DEVINFO_DES 0x00000100 /* DES/3DES support present */
  84801. +#define SAFE_DEVINFO_ARC4 0x00000200 /* ARC4 support present */
  84802. +#define SAFE_DEVINFO_AES 0x00000400 /* AES support present */
  84803. +#define SAFE_DEVINFO_MD5 0x00001000 /* MD5 support present */
  84804. +#define SAFE_DEVINFO_SHA1 0x00002000 /* SHA-1 support present */
  84805. +#define SAFE_DEVINFO_RIPEMD 0x00004000 /* RIPEMD support present */
  84806. +#define SAFE_DEVINFO_DEFLATE 0x00010000 /* Deflate support present */
  84807. +#define SAFE_DEVINFO_SARAM 0x00100000 /* on-chip SA RAM present */
  84808. +#define SAFE_DEVINFO_EMIBUS 0x00200000 /* EMI bus present */
  84809. +#define SAFE_DEVINFO_PKEY 0x00400000 /* public key support present */
  84810. +#define SAFE_DEVINFO_RNG 0x00800000 /* RNG present */
  84811. +
  84812. +#define SAFE_REV(_maj, _min) (((_maj) << SAFE_DEVINFO_REV_MAJ_S) | (_min))
  84813. +#define SAFE_REV_MAJ(_chiprev) \
  84814. + (((_chiprev) & SAFE_DEVINFO_REV_MAJ) >> SAFE_DEVINFO_REV_MAJ_S)
  84815. +#define SAFE_REV_MIN(_chiprev) ((_chiprev) & SAFE_DEVINFO_REV_MIN)
  84816. +
  84817. +#define SAFE_PK_FUNC_MULT 0x00000001 /* Multiply function */
  84818. +#define SAFE_PK_FUNC_SQUARE 0x00000004 /* Square function */
  84819. +#define SAFE_PK_FUNC_ADD 0x00000010 /* Add function */
  84820. +#define SAFE_PK_FUNC_SUB 0x00000020 /* Subtract function */
  84821. +#define SAFE_PK_FUNC_LSHIFT 0x00000040 /* Left-shift function */
  84822. +#define SAFE_PK_FUNC_RSHIFT 0x00000080 /* Right-shift function */
  84823. +#define SAFE_PK_FUNC_DIV 0x00000100 /* Divide function */
  84824. +#define SAFE_PK_FUNC_CMP 0x00000400 /* Compare function */
  84825. +#define SAFE_PK_FUNC_COPY 0x00000800 /* Copy function */
  84826. +#define SAFE_PK_FUNC_EXP16 0x00002000 /* Exponentiate (4-bit ACT) */
  84827. +#define SAFE_PK_FUNC_EXP4 0x00004000 /* Exponentiate (2-bit ACT) */
  84828. +#define SAFE_PK_FUNC_RUN 0x00008000 /* start/status */
  84829. +
  84830. +#define SAFE_RNG_STAT_BUSY 0x00000001 /* busy, data not valid */
  84831. +
  84832. +#define SAFE_RNG_CTRL_PRE_LFSR 0x00000001 /* enable output pre-LFSR */
  84833. +#define SAFE_RNG_CTRL_TST_MODE 0x00000002 /* enable test mode */
  84834. +#define SAFE_RNG_CTRL_TST_RUN 0x00000004 /* start test state machine */
  84835. +#define SAFE_RNG_CTRL_ENA_RING1 0x00000008 /* test entropy oscillator #1 */
  84836. +#define SAFE_RNG_CTRL_ENA_RING2 0x00000010 /* test entropy oscillator #2 */
  84837. +#define SAFE_RNG_CTRL_DIS_ALARM 0x00000020 /* disable RNG alarm reports */
  84838. +#define SAFE_RNG_CTRL_TST_CLOCK 0x00000040 /* enable test clock */
  84839. +#define SAFE_RNG_CTRL_SHORTEN 0x00000080 /* shorten state timers */
  84840. +#define SAFE_RNG_CTRL_TST_ALARM 0x00000100 /* simulate alarm state */
  84841. +#define SAFE_RNG_CTRL_RST_LFSR 0x00000200 /* reset LFSR */
  84842. +
  84843. +/*
  84844. + * Packet engine descriptor. Note that d_csr is a copy of the
  84845. + * SAFE_PE_CSR register and all definitions apply, and d_len
  84846. + * is a copy of the SAFE_PE_LEN register and all definitions apply.
  84847. + * d_src and d_len may point directly to contiguous data or to a
  84848. + * list of ``particle descriptors'' when using scatter/gather i/o.
  84849. + */
  84850. +struct safe_desc {
  84851. + u_int32_t d_csr; /* per-packet control/status */
  84852. + u_int32_t d_src; /* source address */
  84853. + u_int32_t d_dst; /* destination address */
  84854. + u_int32_t d_sa; /* SA address */
  84855. + u_int32_t d_len; /* length, bypass, status */
  84856. +};
  84857. +
  84858. +/*
  84859. + * Scatter/Gather particle descriptor.
  84860. + *
  84861. + * NB: scatter descriptors do not specify a size; this is fixed
  84862. + * by the setting of the SAFE_PE_PARTCFG register.
  84863. + */
  84864. +struct safe_pdesc {
  84865. + u_int32_t pd_addr; /* particle address */
  84866. +#ifdef __BIG_ENDIAN
  84867. + u_int16_t pd_flags; /* control word */
  84868. + u_int16_t pd_size; /* particle size (bytes) */
  84869. +#else
  84870. + u_int16_t pd_flags; /* control word */
  84871. + u_int16_t pd_size; /* particle size (bytes) */
  84872. +#endif
  84873. +};
  84874. +
  84875. +#define SAFE_PD_READY 0x0001 /* ready for processing */
  84876. +#define SAFE_PD_DONE 0x0002 /* h/w completed processing */
  84877. +
  84878. +/*
  84879. + * Security Association (SA) Record (Rev 1). One of these is
  84880. + * required for each operation processed by the packet engine.
  84881. + */
  84882. +struct safe_sarec {
  84883. + u_int32_t sa_cmd0;
  84884. + u_int32_t sa_cmd1;
  84885. + u_int32_t sa_resv0;
  84886. + u_int32_t sa_resv1;
  84887. + u_int32_t sa_key[8]; /* DES/3DES/AES key */
  84888. + u_int32_t sa_indigest[5]; /* inner digest */
  84889. + u_int32_t sa_outdigest[5]; /* outer digest */
  84890. + u_int32_t sa_spi; /* SPI */
  84891. + u_int32_t sa_seqnum; /* sequence number */
  84892. + u_int32_t sa_seqmask[2]; /* sequence number mask */
  84893. + u_int32_t sa_resv2;
  84894. + u_int32_t sa_staterec; /* address of state record */
  84895. + u_int32_t sa_resv3[2];
  84896. + u_int32_t sa_samgmt0; /* SA management field 0 */
  84897. + u_int32_t sa_samgmt1; /* SA management field 0 */
  84898. +};
  84899. +
  84900. +#define SAFE_SA_CMD0_OP 0x00000007 /* operation code */
  84901. +#define SAFE_SA_CMD0_OP_CRYPT 0x00000000 /* encrypt/decrypt (basic) */
  84902. +#define SAFE_SA_CMD0_OP_BOTH 0x00000001 /* encrypt-hash/hash-decrypto */
  84903. +#define SAFE_SA_CMD0_OP_HASH 0x00000003 /* hash (outbound-only) */
  84904. +#define SAFE_SA_CMD0_OP_ESP 0x00000000 /* ESP in/out (proto) */
  84905. +#define SAFE_SA_CMD0_OP_AH 0x00000001 /* AH in/out (proto) */
  84906. +#define SAFE_SA_CMD0_INBOUND 0x00000008 /* inbound operation */
  84907. +#define SAFE_SA_CMD0_OUTBOUND 0x00000000 /* outbound operation */
  84908. +#define SAFE_SA_CMD0_GROUP 0x00000030 /* operation group */
  84909. +#define SAFE_SA_CMD0_BASIC 0x00000000 /* basic operation */
  84910. +#define SAFE_SA_CMD0_PROTO 0x00000010 /* protocol/packet operation */
  84911. +#define SAFE_SA_CMD0_BUNDLE 0x00000020 /* bundled operation (resvd) */
  84912. +#define SAFE_SA_CMD0_PAD 0x000000c0 /* crypto pad method */
  84913. +#define SAFE_SA_CMD0_PAD_IPSEC 0x00000000 /* IPsec padding */
  84914. +#define SAFE_SA_CMD0_PAD_PKCS7 0x00000040 /* PKCS#7 padding */
  84915. +#define SAFE_SA_CMD0_PAD_CONS 0x00000080 /* constant padding */
  84916. +#define SAFE_SA_CMD0_PAD_ZERO 0x000000c0 /* zero padding */
  84917. +#define SAFE_SA_CMD0_CRYPT_ALG 0x00000f00 /* symmetric crypto algorithm */
  84918. +#define SAFE_SA_CMD0_DES 0x00000000 /* DES crypto algorithm */
  84919. +#define SAFE_SA_CMD0_3DES 0x00000100 /* 3DES crypto algorithm */
  84920. +#define SAFE_SA_CMD0_AES 0x00000300 /* AES crypto algorithm */
  84921. +#define SAFE_SA_CMD0_CRYPT_NULL 0x00000f00 /* null crypto algorithm */
  84922. +#define SAFE_SA_CMD0_HASH_ALG 0x0000f000 /* hash algorithm */
  84923. +#define SAFE_SA_CMD0_MD5 0x00000000 /* MD5 hash algorithm */
  84924. +#define SAFE_SA_CMD0_SHA1 0x00001000 /* SHA-1 hash algorithm */
  84925. +#define SAFE_SA_CMD0_HASH_NULL 0x0000f000 /* null hash algorithm */
  84926. +#define SAFE_SA_CMD0_HDR_PROC 0x00080000 /* header processing */
  84927. +#define SAFE_SA_CMD0_IBUSID 0x00300000 /* input bus id */
  84928. +#define SAFE_SA_CMD0_IPCI 0x00100000 /* PCI input bus id */
  84929. +#define SAFE_SA_CMD0_OBUSID 0x00c00000 /* output bus id */
  84930. +#define SAFE_SA_CMD0_OPCI 0x00400000 /* PCI output bus id */
  84931. +#define SAFE_SA_CMD0_IVLD 0x03000000 /* IV loading */
  84932. +#define SAFE_SA_CMD0_IVLD_NONE 0x00000000 /* IV no load (reuse) */
  84933. +#define SAFE_SA_CMD0_IVLD_IBUF 0x01000000 /* IV load from input buffer */
  84934. +#define SAFE_SA_CMD0_IVLD_STATE 0x02000000 /* IV load from state */
  84935. +#define SAFE_SA_CMD0_HSLD 0x0c000000 /* hash state loading */
  84936. +#define SAFE_SA_CMD0_HSLD_SA 0x00000000 /* hash state load from SA */
  84937. +#define SAFE_SA_CMD0_HSLD_STATE 0x08000000 /* hash state load from state */
  84938. +#define SAFE_SA_CMD0_HSLD_NONE 0x0c000000 /* hash state no load */
  84939. +#define SAFE_SA_CMD0_SAVEIV 0x10000000 /* save IV */
  84940. +#define SAFE_SA_CMD0_SAVEHASH 0x20000000 /* save hash state */
  84941. +#define SAFE_SA_CMD0_IGATHER 0x40000000 /* input gather */
  84942. +#define SAFE_SA_CMD0_OSCATTER 0x80000000 /* output scatter */
  84943. +
  84944. +#define SAFE_SA_CMD1_HDRCOPY 0x00000002 /* copy header to output */
  84945. +#define SAFE_SA_CMD1_PAYCOPY 0x00000004 /* copy payload to output */
  84946. +#define SAFE_SA_CMD1_PADCOPY 0x00000008 /* copy pad to output */
  84947. +#define SAFE_SA_CMD1_IPV4 0x00000000 /* IPv4 protocol */
  84948. +#define SAFE_SA_CMD1_IPV6 0x00000010 /* IPv6 protocol */
  84949. +#define SAFE_SA_CMD1_MUTABLE 0x00000020 /* mutable bit processing */
  84950. +#define SAFE_SA_CMD1_SRBUSID 0x000000c0 /* state record bus id */
  84951. +#define SAFE_SA_CMD1_SRPCI 0x00000040 /* state record from PCI */
  84952. +#define SAFE_SA_CMD1_CRMODE 0x00000300 /* crypto mode */
  84953. +#define SAFE_SA_CMD1_ECB 0x00000000 /* ECB crypto mode */
  84954. +#define SAFE_SA_CMD1_CBC 0x00000100 /* CBC crypto mode */
  84955. +#define SAFE_SA_CMD1_OFB 0x00000200 /* OFB crypto mode */
  84956. +#define SAFE_SA_CMD1_CFB 0x00000300 /* CFB crypto mode */
  84957. +#define SAFE_SA_CMD1_CRFEEDBACK 0x00000c00 /* crypto feedback mode */
  84958. +#define SAFE_SA_CMD1_64BIT 0x00000000 /* 64-bit crypto feedback */
  84959. +#define SAFE_SA_CMD1_8BIT 0x00000400 /* 8-bit crypto feedback */
  84960. +#define SAFE_SA_CMD1_1BIT 0x00000800 /* 1-bit crypto feedback */
  84961. +#define SAFE_SA_CMD1_128BIT 0x00000c00 /* 128-bit crypto feedback */
  84962. +#define SAFE_SA_CMD1_OPTIONS 0x00001000 /* HMAC/options mutable bit */
  84963. +#define SAFE_SA_CMD1_HMAC SAFE_SA_CMD1_OPTIONS
  84964. +#define SAFE_SA_CMD1_SAREV1 0x00008000 /* SA Revision 1 */
  84965. +#define SAFE_SA_CMD1_OFFSET 0x00ff0000 /* hash/crypto offset(dwords) */
  84966. +#define SAFE_SA_CMD1_OFFSET_S 16
  84967. +#define SAFE_SA_CMD1_AESKEYLEN 0x0f000000 /* AES key length */
  84968. +#define SAFE_SA_CMD1_AES128 0x02000000 /* 128-bit AES key */
  84969. +#define SAFE_SA_CMD1_AES192 0x03000000 /* 192-bit AES key */
  84970. +#define SAFE_SA_CMD1_AES256 0x04000000 /* 256-bit AES key */
  84971. +
  84972. +/*
  84973. + * Security Associate State Record (Rev 1).
  84974. + */
  84975. +struct safe_sastate {
  84976. + u_int32_t sa_saved_iv[4]; /* saved IV (DES/3DES/AES) */
  84977. + u_int32_t sa_saved_hashbc; /* saved hash byte count */
  84978. + u_int32_t sa_saved_indigest[5]; /* saved inner digest */
  84979. +};
  84980. +#endif /* _SAFE_SAFEREG_H_ */
  84981. diff -Nur linux-2.6.36.orig/crypto/ocf/safe/safevar.h linux-2.6.36/crypto/ocf/safe/safevar.h
  84982. --- linux-2.6.36.orig/crypto/ocf/safe/safevar.h 1970-01-01 01:00:00.000000000 +0100
  84983. +++ linux-2.6.36/crypto/ocf/safe/safevar.h 2010-11-09 20:28:13.022495375 +0100
  84984. @@ -0,0 +1,230 @@
  84985. +/*-
  84986. + * The linux port of this code done by David McCullough
  84987. + * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
  84988. + * The license and original author are listed below.
  84989. + *
  84990. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  84991. + * Copyright (c) 2003 Global Technology Associates, Inc.
  84992. + * All rights reserved.
  84993. + *
  84994. + * Redistribution and use in source and binary forms, with or without
  84995. + * modification, are permitted provided that the following conditions
  84996. + * are met:
  84997. + * 1. Redistributions of source code must retain the above copyright
  84998. + * notice, this list of conditions and the following disclaimer.
  84999. + * 2. Redistributions in binary form must reproduce the above copyright
  85000. + * notice, this list of conditions and the following disclaimer in the
  85001. + * documentation and/or other materials provided with the distribution.
  85002. + *
  85003. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  85004. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  85005. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  85006. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  85007. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  85008. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  85009. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  85010. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  85011. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  85012. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  85013. + * SUCH DAMAGE.
  85014. + *
  85015. + * $FreeBSD: src/sys/dev/safe/safevar.h,v 1.2 2006/05/17 18:34:26 pjd Exp $
  85016. + */
  85017. +#ifndef _SAFE_SAFEVAR_H_
  85018. +#define _SAFE_SAFEVAR_H_
  85019. +
  85020. +/* Maximum queue length */
  85021. +#ifndef SAFE_MAX_NQUEUE
  85022. +#define SAFE_MAX_NQUEUE 60
  85023. +#endif
  85024. +
  85025. +#define SAFE_MAX_PART 64 /* Maximum scatter/gather depth */
  85026. +#define SAFE_DMA_BOUNDARY 0 /* No boundary for source DMA ops */
  85027. +#define SAFE_MAX_DSIZE 2048 /* MCLBYTES Fixed scatter particle size */
  85028. +#define SAFE_MAX_SSIZE 0x0ffff /* Maximum gather particle size */
  85029. +#define SAFE_MAX_DMA 0xfffff /* Maximum PE operand size (20 bits) */
  85030. +/* total src+dst particle descriptors */
  85031. +#define SAFE_TOTAL_DPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
  85032. +#define SAFE_TOTAL_SPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
  85033. +
  85034. +#define SAFE_RNG_MAXBUFSIZ 128 /* 32-bit words */
  85035. +
  85036. +#define SAFE_CARD(sid) (((sid) & 0xf0000000) >> 28)
  85037. +#define SAFE_SESSION(sid) ( (sid) & 0x0fffffff)
  85038. +#define SAFE_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
  85039. +
  85040. +#define SAFE_DEF_RTY 0xff /* PCI Retry Timeout */
  85041. +#define SAFE_DEF_TOUT 0xff /* PCI TRDY Timeout */
  85042. +#define SAFE_DEF_CACHELINE 0x01 /* Cache Line setting */
  85043. +
  85044. +#ifdef __KERNEL__
  85045. +/*
  85046. + * State associated with the allocation of each chunk
  85047. + * of memory setup for DMA.
  85048. + */
  85049. +struct safe_dma_alloc {
  85050. + dma_addr_t dma_paddr;
  85051. + void *dma_vaddr;
  85052. +};
  85053. +
  85054. +/*
  85055. + * Cryptographic operand state. One of these exists for each
  85056. + * source and destination operand passed in from the crypto
  85057. + * subsystem. When possible source and destination operands
  85058. + * refer to the same memory. More often they are distinct.
  85059. + * We track the virtual address of each operand as well as
  85060. + * where each is mapped for DMA.
  85061. + */
  85062. +struct safe_operand {
  85063. + union {
  85064. + struct sk_buff *skb;
  85065. + struct uio *io;
  85066. + } u;
  85067. + void *map;
  85068. + int mapsize; /* total number of bytes in segs */
  85069. + struct {
  85070. + dma_addr_t ds_addr;
  85071. + int ds_len;
  85072. + int ds_tlen;
  85073. + } segs[SAFE_MAX_PART];
  85074. + int nsegs;
  85075. +};
  85076. +
  85077. +/*
  85078. + * Packet engine ring entry and cryptographic operation state.
  85079. + * The packet engine requires a ring of descriptors that contain
  85080. + * pointers to various cryptographic state. However the ring
  85081. + * configuration register allows you to specify an arbitrary size
  85082. + * for ring entries. We use this feature to collect most of the
  85083. + * state for each cryptographic request into one spot. Other than
  85084. + * ring entries only the ``particle descriptors'' (scatter/gather
  85085. + * lists) and the actual operand data are kept separate. The
  85086. + * particle descriptors must also be organized in rings. The
  85087. + * operand data can be located aribtrarily (modulo alignment constraints).
  85088. + *
  85089. + * Note that the descriptor ring is mapped onto the PCI bus so
  85090. + * the hardware can DMA data. This means the entire ring must be
  85091. + * contiguous.
  85092. + */
  85093. +struct safe_ringentry {
  85094. + struct safe_desc re_desc; /* command descriptor */
  85095. + struct safe_sarec re_sa; /* SA record */
  85096. + struct safe_sastate re_sastate; /* SA state record */
  85097. +
  85098. + struct cryptop *re_crp; /* crypto operation */
  85099. +
  85100. + struct safe_operand re_src; /* source operand */
  85101. + struct safe_operand re_dst; /* destination operand */
  85102. +
  85103. + int re_sesn; /* crypto session ID */
  85104. + int re_flags;
  85105. +#define SAFE_QFLAGS_COPYOUTIV 0x1 /* copy back on completion */
  85106. +#define SAFE_QFLAGS_COPYOUTICV 0x2 /* copy back on completion */
  85107. +};
  85108. +
  85109. +#define re_src_skb re_src.u.skb
  85110. +#define re_src_io re_src.u.io
  85111. +#define re_src_map re_src.map
  85112. +#define re_src_nsegs re_src.nsegs
  85113. +#define re_src_segs re_src.segs
  85114. +#define re_src_mapsize re_src.mapsize
  85115. +
  85116. +#define re_dst_skb re_dst.u.skb
  85117. +#define re_dst_io re_dst.u.io
  85118. +#define re_dst_map re_dst.map
  85119. +#define re_dst_nsegs re_dst.nsegs
  85120. +#define re_dst_segs re_dst.segs
  85121. +#define re_dst_mapsize re_dst.mapsize
  85122. +
  85123. +struct rndstate_test;
  85124. +
  85125. +struct safe_session {
  85126. + u_int32_t ses_used;
  85127. + u_int32_t ses_klen; /* key length in bits */
  85128. + u_int32_t ses_key[8]; /* DES/3DES/AES key */
  85129. + u_int32_t ses_mlen; /* hmac length in bytes */
  85130. + u_int32_t ses_hminner[5]; /* hmac inner state */
  85131. + u_int32_t ses_hmouter[5]; /* hmac outer state */
  85132. + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
  85133. +};
  85134. +
  85135. +struct safe_pkq {
  85136. + struct list_head pkq_list;
  85137. + struct cryptkop *pkq_krp;
  85138. +};
  85139. +
  85140. +struct safe_softc {
  85141. + softc_device_decl sc_dev;
  85142. + u32 sc_irq;
  85143. +
  85144. + struct pci_dev *sc_pcidev;
  85145. + ocf_iomem_t sc_base_addr;
  85146. +
  85147. + u_int sc_chiprev; /* major/minor chip revision */
  85148. + int sc_flags; /* device specific flags */
  85149. +#define SAFE_FLAGS_KEY 0x01 /* has key accelerator */
  85150. +#define SAFE_FLAGS_RNG 0x02 /* hardware rng */
  85151. + int sc_suspended;
  85152. + int sc_needwakeup; /* notify crypto layer */
  85153. + int32_t sc_cid; /* crypto tag */
  85154. +
  85155. + struct safe_dma_alloc sc_ringalloc; /* PE ring allocation state */
  85156. + struct safe_ringentry *sc_ring; /* PE ring */
  85157. + struct safe_ringentry *sc_ringtop; /* PE ring top */
  85158. + struct safe_ringentry *sc_front; /* next free entry */
  85159. + struct safe_ringentry *sc_back; /* next pending entry */
  85160. + int sc_nqchip; /* # passed to chip */
  85161. + spinlock_t sc_ringmtx; /* PE ring lock */
  85162. + struct safe_pdesc *sc_spring; /* src particle ring */
  85163. + struct safe_pdesc *sc_springtop; /* src particle ring top */
  85164. + struct safe_pdesc *sc_spfree; /* next free src particle */
  85165. + struct safe_dma_alloc sc_spalloc; /* src particle ring state */
  85166. + struct safe_pdesc *sc_dpring; /* dest particle ring */
  85167. + struct safe_pdesc *sc_dpringtop; /* dest particle ring top */
  85168. + struct safe_pdesc *sc_dpfree; /* next free dest particle */
  85169. + struct safe_dma_alloc sc_dpalloc; /* dst particle ring state */
  85170. + int sc_nsessions; /* # of sessions */
  85171. + struct safe_session *sc_sessions; /* sessions */
  85172. +
  85173. + struct timer_list sc_pkto; /* PK polling */
  85174. + spinlock_t sc_pkmtx; /* PK lock */
  85175. + struct list_head sc_pkq; /* queue of PK requests */
  85176. + struct safe_pkq *sc_pkq_cur; /* current processing request */
  85177. + u_int32_t sc_pk_reslen, sc_pk_resoff;
  85178. +
  85179. + int sc_max_dsize; /* maximum safe DMA size */
  85180. +};
  85181. +#endif /* __KERNEL__ */
  85182. +
  85183. +struct safe_stats {
  85184. + u_int64_t st_ibytes;
  85185. + u_int64_t st_obytes;
  85186. + u_int32_t st_ipackets;
  85187. + u_int32_t st_opackets;
  85188. + u_int32_t st_invalid; /* invalid argument */
  85189. + u_int32_t st_badsession; /* invalid session id */
  85190. + u_int32_t st_badflags; /* flags indicate !(mbuf | uio) */
  85191. + u_int32_t st_nodesc; /* op submitted w/o descriptors */
  85192. + u_int32_t st_badalg; /* unsupported algorithm */
  85193. + u_int32_t st_ringfull; /* PE descriptor ring full */
  85194. + u_int32_t st_peoperr; /* PE marked error */
  85195. + u_int32_t st_dmaerr; /* PE DMA error */
  85196. + u_int32_t st_bypasstoobig; /* bypass > 96 bytes */
  85197. + u_int32_t st_skipmismatch; /* enc part begins before auth part */
  85198. + u_int32_t st_lenmismatch; /* enc length different auth length */
  85199. + u_int32_t st_coffmisaligned; /* crypto offset not 32-bit aligned */
  85200. + u_int32_t st_cofftoobig; /* crypto offset > 255 words */
  85201. + u_int32_t st_iovmisaligned; /* iov op not aligned */
  85202. + u_int32_t st_iovnotuniform; /* iov op not suitable */
  85203. + u_int32_t st_unaligned; /* unaligned src caused copy */
  85204. + u_int32_t st_notuniform; /* non-uniform src caused copy */
  85205. + u_int32_t st_nomap; /* bus_dmamap_create failed */
  85206. + u_int32_t st_noload; /* bus_dmamap_load_* failed */
  85207. + u_int32_t st_nombuf; /* MGET* failed */
  85208. + u_int32_t st_nomcl; /* MCLGET* failed */
  85209. + u_int32_t st_maxqchip; /* max mcr1 ops out for processing */
  85210. + u_int32_t st_rng; /* RNG requests */
  85211. + u_int32_t st_rngalarm; /* RNG alarm requests */
  85212. + u_int32_t st_noicvcopy; /* ICV data copies suppressed */
  85213. +};
  85214. +#endif /* _SAFE_SAFEVAR_H_ */
  85215. diff -Nur linux-2.6.36.orig/crypto/ocf/safe/sha1.c linux-2.6.36/crypto/ocf/safe/sha1.c
  85216. --- linux-2.6.36.orig/crypto/ocf/safe/sha1.c 1970-01-01 01:00:00.000000000 +0100
  85217. +++ linux-2.6.36/crypto/ocf/safe/sha1.c 2010-11-09 20:28:13.072495484 +0100
  85218. @@ -0,0 +1,279 @@
  85219. +/* $KAME: sha1.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
  85220. +/*
  85221. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  85222. + * All rights reserved.
  85223. + *
  85224. + * Redistribution and use in source and binary forms, with or without
  85225. + * modification, are permitted provided that the following conditions
  85226. + * are met:
  85227. + * 1. Redistributions of source code must retain the above copyright
  85228. + * notice, this list of conditions and the following disclaimer.
  85229. + * 2. Redistributions in binary form must reproduce the above copyright
  85230. + * notice, this list of conditions and the following disclaimer in the
  85231. + * documentation and/or other materials provided with the distribution.
  85232. + * 3. Neither the name of the project nor the names of its contributors
  85233. + * may be used to endorse or promote products derived from this software
  85234. + * without specific prior written permission.
  85235. + *
  85236. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  85237. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  85238. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  85239. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  85240. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  85241. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  85242. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  85243. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  85244. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  85245. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  85246. + * SUCH DAMAGE.
  85247. + */
  85248. +
  85249. +/*
  85250. + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
  85251. + * based on: http://csrc.nist.gov/fips/fip180-1.txt
  85252. + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
  85253. + */
  85254. +
  85255. +#if 0
  85256. +#include <sys/cdefs.h>
  85257. +__FBSDID("$FreeBSD: src/sys/crypto/sha1.c,v 1.9 2003/06/10 21:36:57 obrien Exp $");
  85258. +
  85259. +#include <sys/types.h>
  85260. +#include <sys/cdefs.h>
  85261. +#include <sys/time.h>
  85262. +#include <sys/systm.h>
  85263. +
  85264. +#include <crypto/sha1.h>
  85265. +#endif
  85266. +
  85267. +/* sanity check */
  85268. +#if BYTE_ORDER != BIG_ENDIAN
  85269. +# if BYTE_ORDER != LITTLE_ENDIAN
  85270. +# define unsupported 1
  85271. +# endif
  85272. +#endif
  85273. +
  85274. +#ifndef unsupported
  85275. +
  85276. +/* constant table */
  85277. +static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
  85278. +#define K(t) _K[(t) / 20]
  85279. +
  85280. +#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
  85281. +#define F1(b, c, d) (((b) ^ (c)) ^ (d))
  85282. +#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
  85283. +#define F3(b, c, d) (((b) ^ (c)) ^ (d))
  85284. +
  85285. +#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
  85286. +
  85287. +#undef H
  85288. +#define H(n) (ctxt->h.b32[(n)])
  85289. +#define COUNT (ctxt->count)
  85290. +#define BCOUNT (ctxt->c.b64[0] / 8)
  85291. +#define W(n) (ctxt->m.b32[(n)])
  85292. +
  85293. +#define PUTBYTE(x) { \
  85294. + ctxt->m.b8[(COUNT % 64)] = (x); \
  85295. + COUNT++; \
  85296. + COUNT %= 64; \
  85297. + ctxt->c.b64[0] += 8; \
  85298. + if (COUNT % 64 == 0) \
  85299. + sha1_step(ctxt); \
  85300. + }
  85301. +
  85302. +#define PUTPAD(x) { \
  85303. + ctxt->m.b8[(COUNT % 64)] = (x); \
  85304. + COUNT++; \
  85305. + COUNT %= 64; \
  85306. + if (COUNT % 64 == 0) \
  85307. + sha1_step(ctxt); \
  85308. + }
  85309. +
  85310. +static void sha1_step(struct sha1_ctxt *);
  85311. +
  85312. +static void
  85313. +sha1_step(ctxt)
  85314. + struct sha1_ctxt *ctxt;
  85315. +{
  85316. + u_int32_t a, b, c, d, e;
  85317. + size_t t, s;
  85318. + u_int32_t tmp;
  85319. +
  85320. +#if BYTE_ORDER == LITTLE_ENDIAN
  85321. + struct sha1_ctxt tctxt;
  85322. + bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);
  85323. + ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
  85324. + ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
  85325. + ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
  85326. + ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
  85327. + ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
  85328. + ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
  85329. + ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
  85330. + ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
  85331. + ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
  85332. + ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
  85333. + ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
  85334. + ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
  85335. + ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
  85336. + ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
  85337. + ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
  85338. + ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
  85339. + ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
  85340. + ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
  85341. + ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
  85342. + ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
  85343. + ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
  85344. + ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
  85345. + ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
  85346. + ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
  85347. + ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
  85348. + ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
  85349. + ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
  85350. + ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
  85351. + ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
  85352. + ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
  85353. + ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
  85354. + ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
  85355. +#endif
  85356. +
  85357. + a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
  85358. +
  85359. + for (t = 0; t < 20; t++) {
  85360. + s = t & 0x0f;
  85361. + if (t >= 16) {
  85362. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  85363. + }
  85364. + tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
  85365. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  85366. + }
  85367. + for (t = 20; t < 40; t++) {
  85368. + s = t & 0x0f;
  85369. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  85370. + tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
  85371. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  85372. + }
  85373. + for (t = 40; t < 60; t++) {
  85374. + s = t & 0x0f;
  85375. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  85376. + tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
  85377. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  85378. + }
  85379. + for (t = 60; t < 80; t++) {
  85380. + s = t & 0x0f;
  85381. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  85382. + tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
  85383. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  85384. + }
  85385. +
  85386. + H(0) = H(0) + a;
  85387. + H(1) = H(1) + b;
  85388. + H(2) = H(2) + c;
  85389. + H(3) = H(3) + d;
  85390. + H(4) = H(4) + e;
  85391. +
  85392. + bzero(&ctxt->m.b8[0], 64);
  85393. +}
  85394. +
  85395. +/*------------------------------------------------------------*/
  85396. +
  85397. +void
  85398. +sha1_init(ctxt)
  85399. + struct sha1_ctxt *ctxt;
  85400. +{
  85401. + bzero(ctxt, sizeof(struct sha1_ctxt));
  85402. + H(0) = 0x67452301;
  85403. + H(1) = 0xefcdab89;
  85404. + H(2) = 0x98badcfe;
  85405. + H(3) = 0x10325476;
  85406. + H(4) = 0xc3d2e1f0;
  85407. +}
  85408. +
  85409. +void
  85410. +sha1_pad(ctxt)
  85411. + struct sha1_ctxt *ctxt;
  85412. +{
  85413. + size_t padlen; /*pad length in bytes*/
  85414. + size_t padstart;
  85415. +
  85416. + PUTPAD(0x80);
  85417. +
  85418. + padstart = COUNT % 64;
  85419. + padlen = 64 - padstart;
  85420. + if (padlen < 8) {
  85421. + bzero(&ctxt->m.b8[padstart], padlen);
  85422. + COUNT += padlen;
  85423. + COUNT %= 64;
  85424. + sha1_step(ctxt);
  85425. + padstart = COUNT % 64; /* should be 0 */
  85426. + padlen = 64 - padstart; /* should be 64 */
  85427. + }
  85428. + bzero(&ctxt->m.b8[padstart], padlen - 8);
  85429. + COUNT += (padlen - 8);
  85430. + COUNT %= 64;
  85431. +#if BYTE_ORDER == BIG_ENDIAN
  85432. + PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
  85433. + PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
  85434. + PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
  85435. + PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
  85436. +#else
  85437. + PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
  85438. + PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
  85439. + PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
  85440. + PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
  85441. +#endif
  85442. +}
  85443. +
  85444. +void
  85445. +sha1_loop(ctxt, input, len)
  85446. + struct sha1_ctxt *ctxt;
  85447. + const u_int8_t *input;
  85448. + size_t len;
  85449. +{
  85450. + size_t gaplen;
  85451. + size_t gapstart;
  85452. + size_t off;
  85453. + size_t copysiz;
  85454. +
  85455. + off = 0;
  85456. +
  85457. + while (off < len) {
  85458. + gapstart = COUNT % 64;
  85459. + gaplen = 64 - gapstart;
  85460. +
  85461. + copysiz = (gaplen < len - off) ? gaplen : len - off;
  85462. + bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz);
  85463. + COUNT += copysiz;
  85464. + COUNT %= 64;
  85465. + ctxt->c.b64[0] += copysiz * 8;
  85466. + if (COUNT % 64 == 0)
  85467. + sha1_step(ctxt);
  85468. + off += copysiz;
  85469. + }
  85470. +}
  85471. +
  85472. +void
  85473. +sha1_result(ctxt, digest0)
  85474. + struct sha1_ctxt *ctxt;
  85475. + caddr_t digest0;
  85476. +{
  85477. + u_int8_t *digest;
  85478. +
  85479. + digest = (u_int8_t *)digest0;
  85480. + sha1_pad(ctxt);
  85481. +#if BYTE_ORDER == BIG_ENDIAN
  85482. + bcopy(&ctxt->h.b8[0], digest, 20);
  85483. +#else
  85484. + digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
  85485. + digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
  85486. + digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
  85487. + digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
  85488. + digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
  85489. + digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
  85490. + digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
  85491. + digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
  85492. + digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
  85493. + digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
  85494. +#endif
  85495. +}
  85496. +
  85497. +#endif /*unsupported*/
  85498. diff -Nur linux-2.6.36.orig/crypto/ocf/safe/sha1.h linux-2.6.36/crypto/ocf/safe/sha1.h
  85499. --- linux-2.6.36.orig/crypto/ocf/safe/sha1.h 1970-01-01 01:00:00.000000000 +0100
  85500. +++ linux-2.6.36/crypto/ocf/safe/sha1.h 2010-11-09 20:28:13.112495423 +0100
  85501. @@ -0,0 +1,72 @@
  85502. +/* $FreeBSD: src/sys/crypto/sha1.h,v 1.8 2002/03/20 05:13:50 alfred Exp $ */
  85503. +/* $KAME: sha1.h,v 1.5 2000/03/27 04:36:23 sumikawa Exp $ */
  85504. +
  85505. +/*
  85506. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  85507. + * All rights reserved.
  85508. + *
  85509. + * Redistribution and use in source and binary forms, with or without
  85510. + * modification, are permitted provided that the following conditions
  85511. + * are met:
  85512. + * 1. Redistributions of source code must retain the above copyright
  85513. + * notice, this list of conditions and the following disclaimer.
  85514. + * 2. Redistributions in binary form must reproduce the above copyright
  85515. + * notice, this list of conditions and the following disclaimer in the
  85516. + * documentation and/or other materials provided with the distribution.
  85517. + * 3. Neither the name of the project nor the names of its contributors
  85518. + * may be used to endorse or promote products derived from this software
  85519. + * without specific prior written permission.
  85520. + *
  85521. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  85522. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  85523. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  85524. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  85525. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  85526. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  85527. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  85528. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  85529. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  85530. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  85531. + * SUCH DAMAGE.
  85532. + */
  85533. +/*
  85534. + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
  85535. + * based on: http://csrc.nist.gov/fips/fip180-1.txt
  85536. + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
  85537. + */
  85538. +
  85539. +#ifndef _NETINET6_SHA1_H_
  85540. +#define _NETINET6_SHA1_H_
  85541. +
  85542. +struct sha1_ctxt {
  85543. + union {
  85544. + u_int8_t b8[20];
  85545. + u_int32_t b32[5];
  85546. + } h;
  85547. + union {
  85548. + u_int8_t b8[8];
  85549. + u_int64_t b64[1];
  85550. + } c;
  85551. + union {
  85552. + u_int8_t b8[64];
  85553. + u_int32_t b32[16];
  85554. + } m;
  85555. + u_int8_t count;
  85556. +};
  85557. +
  85558. +#ifdef __KERNEL__
  85559. +extern void sha1_init(struct sha1_ctxt *);
  85560. +extern void sha1_pad(struct sha1_ctxt *);
  85561. +extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);
  85562. +extern void sha1_result(struct sha1_ctxt *, caddr_t);
  85563. +
  85564. +/* compatibilty with other SHA1 source codes */
  85565. +typedef struct sha1_ctxt SHA1_CTX;
  85566. +#define SHA1Init(x) sha1_init((x))
  85567. +#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
  85568. +#define SHA1Final(x, y) sha1_result((y), (x))
  85569. +#endif /* __KERNEL__ */
  85570. +
  85571. +#define SHA1_RESULTLEN (160/8)
  85572. +
  85573. +#endif /*_NETINET6_SHA1_H_*/
  85574. diff -Nur linux-2.6.36.orig/crypto/ocf/talitos/Makefile linux-2.6.36/crypto/ocf/talitos/Makefile
  85575. --- linux-2.6.36.orig/crypto/ocf/talitos/Makefile 1970-01-01 01:00:00.000000000 +0100
  85576. +++ linux-2.6.36/crypto/ocf/talitos/Makefile 2010-11-09 20:28:13.155214387 +0100
  85577. @@ -0,0 +1,12 @@
  85578. +# for SGlinux builds
  85579. +-include $(ROOTDIR)/modules/.config
  85580. +
  85581. +obj-$(CONFIG_OCF_TALITOS) += talitos.o
  85582. +
  85583. +obj ?= .
  85584. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  85585. +
  85586. +ifdef TOPDIR
  85587. +-include $(TOPDIR)/Rules.make
  85588. +endif
  85589. +
  85590. diff -Nur linux-2.6.36.orig/crypto/ocf/talitos/talitos.c linux-2.6.36/crypto/ocf/talitos/talitos.c
  85591. --- linux-2.6.36.orig/crypto/ocf/talitos/talitos.c 1970-01-01 01:00:00.000000000 +0100
  85592. +++ linux-2.6.36/crypto/ocf/talitos/talitos.c 2010-11-09 20:28:13.192104548 +0100
  85593. @@ -0,0 +1,1359 @@
  85594. +/*
  85595. + * crypto/ocf/talitos/talitos.c
  85596. + *
  85597. + * An OCF-Linux module that uses Freescale's SEC to do the crypto.
  85598. + * Based on crypto/ocf/hifn and crypto/ocf/safe OCF drivers
  85599. + *
  85600. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  85601. + *
  85602. + * This code written by Kim A. B. Phillips <kim.phillips@freescale.com>
  85603. + * some code copied from files with the following:
  85604. + * Copyright (C) 2004-2007 David McCullough <david_mccullough@mcafee.com>
  85605. + *
  85606. + * Redistribution and use in source and binary forms, with or without
  85607. + * modification, are permitted provided that the following conditions
  85608. + * are met:
  85609. + *
  85610. + * 1. Redistributions of source code must retain the above copyright
  85611. + * notice, this list of conditions and the following disclaimer.
  85612. + * 2. Redistributions in binary form must reproduce the above copyright
  85613. + * notice, this list of conditions and the following disclaimer in the
  85614. + * documentation and/or other materials provided with the distribution.
  85615. + * 3. The name of the author may not be used to endorse or promote products
  85616. + * derived from this software without specific prior written permission.
  85617. + *
  85618. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  85619. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  85620. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  85621. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  85622. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  85623. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  85624. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  85625. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  85626. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  85627. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  85628. + *
  85629. + * ---------------------------------------------------------------------------
  85630. + *
  85631. + * NOTES:
  85632. + *
  85633. + * The Freescale SEC (also known as 'talitos') resides on the
  85634. + * internal bus, and runs asynchronous to the processor core. It has
  85635. + * a wide gamut of cryptographic acceleration features, including single-
  85636. + * pass IPsec (also known as algorithm chaining). To properly utilize
  85637. + * all of the SEC's performance enhancing features, further reworking
  85638. + * of higher level code (framework, applications) will be necessary.
  85639. + *
  85640. + * The following table shows which SEC version is present in which devices:
  85641. + *
  85642. + * Devices SEC version
  85643. + *
  85644. + * 8272, 8248 SEC 1.0
  85645. + * 885, 875 SEC 1.2
  85646. + * 8555E, 8541E SEC 2.0
  85647. + * 8349E SEC 2.01
  85648. + * 8548E SEC 2.1
  85649. + *
  85650. + * The following table shows the features offered by each SEC version:
  85651. + *
  85652. + * Max. chan-
  85653. + * version Bus I/F Clock nels DEU AESU AFEU MDEU PKEU RNG KEU
  85654. + *
  85655. + * SEC 1.0 internal 64b 100MHz 4 1 1 1 1 1 1 0
  85656. + * SEC 1.2 internal 32b 66MHz 1 1 1 0 1 0 0 0
  85657. + * SEC 2.0 internal 64b 166MHz 4 1 1 1 1 1 1 0
  85658. + * SEC 2.01 internal 64b 166MHz 4 1 1 1 1 1 1 0
  85659. + * SEC 2.1 internal 64b 333MHz 4 1 1 1 1 1 1 1
  85660. + *
  85661. + * Each execution unit in the SEC has two modes of execution; channel and
  85662. + * slave/debug. This driver employs the channel infrastructure in the
  85663. + * device for convenience. Only the RNG is directly accessed due to the
  85664. + * convenience of its random fifo pool. The relationship between the
  85665. + * channels and execution units is depicted in the following diagram:
  85666. + *
  85667. + * ------- ------------
  85668. + * ---| ch0 |---| |
  85669. + * ------- | |
  85670. + * | |------+-------+-------+-------+------------
  85671. + * ------- | | | | | | |
  85672. + * ---| ch1 |---| | | | | | |
  85673. + * ------- | | ------ ------ ------ ------ ------
  85674. + * |controller| |DEU | |AESU| |MDEU| |PKEU| ... |RNG |
  85675. + * ------- | | ------ ------ ------ ------ ------
  85676. + * ---| ch2 |---| | | | | | |
  85677. + * ------- | | | | | | |
  85678. + * | |------+-------+-------+-------+------------
  85679. + * ------- | |
  85680. + * ---| ch3 |---| |
  85681. + * ------- ------------
  85682. + *
  85683. + * Channel ch0 may drive an aes operation to the aes unit (AESU),
  85684. + * and, at the same time, ch1 may drive a message digest operation
  85685. + * to the mdeu. Each channel has an input descriptor FIFO, and the
  85686. + * FIFO can contain, e.g. on the 8541E, up to 24 entries, before a
  85687. + * a buffer overrun error is triggered. The controller is responsible
  85688. + * for fetching the data from descriptor pointers, and passing the
  85689. + * data to the appropriate EUs. The controller also writes the
  85690. + * cryptographic operation's result to memory. The SEC notifies
  85691. + * completion by triggering an interrupt and/or setting the 1st byte
  85692. + * of the hdr field to 0xff.
  85693. + *
  85694. + * TODO:
  85695. + * o support more algorithms
  85696. + * o support more versions of the SEC
  85697. + * o add support for linux 2.4
  85698. + * o scatter-gather (sg) support
  85699. + * o add support for public key ops (PKEU)
  85700. + * o add statistics
  85701. + */
  85702. +
  85703. +#ifndef AUTOCONF_INCLUDED
  85704. +#include <linux/config.h>
  85705. +#endif
  85706. +#include <linux/module.h>
  85707. +#include <linux/init.h>
  85708. +#include <linux/interrupt.h>
  85709. +#include <linux/spinlock.h>
  85710. +#include <linux/random.h>
  85711. +#include <linux/skbuff.h>
  85712. +#include <asm/scatterlist.h>
  85713. +#include <linux/dma-mapping.h> /* dma_map_single() */
  85714. +#include <linux/moduleparam.h>
  85715. +
  85716. +#include <linux/version.h>
  85717. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
  85718. +#include <linux/platform_device.h>
  85719. +#endif
  85720. +
  85721. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  85722. +#include <linux/of_platform.h>
  85723. +#endif
  85724. +
  85725. +#include <cryptodev.h>
  85726. +#include <uio.h>
  85727. +
  85728. +#define DRV_NAME "talitos"
  85729. +
  85730. +#include "talitos_dev.h"
  85731. +#include "talitos_soft.h"
  85732. +
  85733. +#define read_random(p,l) get_random_bytes(p,l)
  85734. +
  85735. +const char talitos_driver_name[] = "Talitos OCF";
  85736. +const char talitos_driver_version[] = "0.2";
  85737. +
  85738. +static int talitos_newsession(device_t dev, u_int32_t *sidp,
  85739. + struct cryptoini *cri);
  85740. +static int talitos_freesession(device_t dev, u_int64_t tid);
  85741. +static int talitos_process(device_t dev, struct cryptop *crp, int hint);
  85742. +static void dump_talitos_status(struct talitos_softc *sc);
  85743. +static int talitos_submit(struct talitos_softc *sc, struct talitos_desc *td,
  85744. + int chsel);
  85745. +static void talitos_doneprocessing(struct talitos_softc *sc);
  85746. +static void talitos_init_device(struct talitos_softc *sc);
  85747. +static void talitos_reset_device_master(struct talitos_softc *sc);
  85748. +static void talitos_reset_device(struct talitos_softc *sc);
  85749. +static void talitos_errorprocessing(struct talitos_softc *sc);
  85750. +#ifdef CONFIG_PPC_MERGE
  85751. +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match);
  85752. +static int talitos_remove(struct of_device *ofdev);
  85753. +#else
  85754. +static int talitos_probe(struct platform_device *pdev);
  85755. +static int talitos_remove(struct platform_device *pdev);
  85756. +#endif
  85757. +#ifdef CONFIG_OCF_RANDOMHARVEST
  85758. +static int talitos_read_random(void *arg, u_int32_t *buf, int maxwords);
  85759. +static void talitos_rng_init(struct talitos_softc *sc);
  85760. +#endif
  85761. +
  85762. +static device_method_t talitos_methods = {
  85763. + /* crypto device methods */
  85764. + DEVMETHOD(cryptodev_newsession, talitos_newsession),
  85765. + DEVMETHOD(cryptodev_freesession,talitos_freesession),
  85766. + DEVMETHOD(cryptodev_process, talitos_process),
  85767. +};
  85768. +
  85769. +#define debug talitos_debug
  85770. +int talitos_debug = 0;
  85771. +module_param(talitos_debug, int, 0644);
  85772. +MODULE_PARM_DESC(talitos_debug, "Enable debug");
  85773. +
  85774. +static inline void talitos_write(volatile unsigned *addr, u32 val)
  85775. +{
  85776. + out_be32(addr, val);
  85777. +}
  85778. +
  85779. +static inline u32 talitos_read(volatile unsigned *addr)
  85780. +{
  85781. + u32 val;
  85782. + val = in_be32(addr);
  85783. + return val;
  85784. +}
  85785. +
  85786. +static void dump_talitos_status(struct talitos_softc *sc)
  85787. +{
  85788. + unsigned int v, v_hi, i, *ptr;
  85789. + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
  85790. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_MCR_HI);
  85791. + printk(KERN_INFO "%s: MCR 0x%08x_%08x\n",
  85792. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  85793. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
  85794. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
  85795. + printk(KERN_INFO "%s: IMR 0x%08x_%08x\n",
  85796. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  85797. + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
  85798. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
  85799. + printk(KERN_INFO "%s: ISR 0x%08x_%08x\n",
  85800. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  85801. + for (i = 0; i < sc->sc_num_channels; i++) {
  85802. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  85803. + TALITOS_CH_CDPR);
  85804. + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  85805. + TALITOS_CH_CDPR_HI);
  85806. + printk(KERN_INFO "%s: CDPR ch%d 0x%08x_%08x\n",
  85807. + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
  85808. + }
  85809. + for (i = 0; i < sc->sc_num_channels; i++) {
  85810. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  85811. + TALITOS_CH_CCPSR);
  85812. + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  85813. + TALITOS_CH_CCPSR_HI);
  85814. + printk(KERN_INFO "%s: CCPSR ch%d 0x%08x_%08x\n",
  85815. + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
  85816. + }
  85817. + ptr = sc->sc_base_addr + TALITOS_CH_DESCBUF;
  85818. + for (i = 0; i < 16; i++) {
  85819. + v = talitos_read(ptr++); v_hi = talitos_read(ptr++);
  85820. + printk(KERN_INFO "%s: DESCBUF ch0 0x%08x_%08x (tdp%02d)\n",
  85821. + device_get_nameunit(sc->sc_cdev), v, v_hi, i);
  85822. + }
  85823. + return;
  85824. +}
  85825. +
  85826. +
  85827. +#ifdef CONFIG_OCF_RANDOMHARVEST
  85828. +/*
  85829. + * pull random numbers off the RNG FIFO, not exceeding amount available
  85830. + */
  85831. +static int
  85832. +talitos_read_random(void *arg, u_int32_t *buf, int maxwords)
  85833. +{
  85834. + struct talitos_softc *sc = (struct talitos_softc *) arg;
  85835. + int rc;
  85836. + u_int32_t v;
  85837. +
  85838. + DPRINTF("%s()\n", __FUNCTION__);
  85839. +
  85840. + /* check for things like FIFO underflow */
  85841. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
  85842. + if (unlikely(v)) {
  85843. + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
  85844. + device_get_nameunit(sc->sc_cdev), v);
  85845. + return 0;
  85846. + }
  85847. + /*
  85848. + * OFL is number of available 64-bit words,
  85849. + * shift and convert to a 32-bit word count
  85850. + */
  85851. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI);
  85852. + v = (v & TALITOS_RNGSR_HI_OFL) >> (16 - 1);
  85853. + if (maxwords > v)
  85854. + maxwords = v;
  85855. + for (rc = 0; rc < maxwords; rc++) {
  85856. + buf[rc] = talitos_read(sc->sc_base_addr +
  85857. + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
  85858. + }
  85859. + if (maxwords & 1) {
  85860. + /*
  85861. + * RNG will complain with an AE in the RNGISR
  85862. + * if we don't complete the pairs of 32-bit reads
  85863. + * to its 64-bit register based FIFO
  85864. + */
  85865. + v = talitos_read(sc->sc_base_addr +
  85866. + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
  85867. + }
  85868. +
  85869. + return rc;
  85870. +}
  85871. +
  85872. +static void
  85873. +talitos_rng_init(struct talitos_softc *sc)
  85874. +{
  85875. + u_int32_t v;
  85876. +
  85877. + DPRINTF("%s()\n", __FUNCTION__);
  85878. + /* reset RNG EU */
  85879. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGRCR_HI);
  85880. + v |= TALITOS_RNGRCR_HI_SR;
  85881. + talitos_write(sc->sc_base_addr + TALITOS_RNGRCR_HI, v);
  85882. + while ((talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI)
  85883. + & TALITOS_RNGSR_HI_RD) == 0)
  85884. + cpu_relax();
  85885. + /*
  85886. + * we tell the RNG to start filling the RNG FIFO
  85887. + * by writing the RNGDSR
  85888. + */
  85889. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGDSR_HI);
  85890. + talitos_write(sc->sc_base_addr + TALITOS_RNGDSR_HI, v);
  85891. + /*
  85892. + * 64 bits of data will be pushed onto the FIFO every
  85893. + * 256 SEC cycles until the FIFO is full. The RNG then
  85894. + * attempts to keep the FIFO full.
  85895. + */
  85896. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
  85897. + if (v) {
  85898. + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
  85899. + device_get_nameunit(sc->sc_cdev), v);
  85900. + return;
  85901. + }
  85902. + /*
  85903. + * n.b. we need to add a FIPS test here - if the RNG is going
  85904. + * to fail, it's going to fail at reset time
  85905. + */
  85906. + return;
  85907. +}
  85908. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  85909. +
  85910. +/*
  85911. + * Generate a new software session.
  85912. + */
  85913. +static int
  85914. +talitos_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  85915. +{
  85916. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  85917. + struct talitos_softc *sc = device_get_softc(dev);
  85918. + struct talitos_session *ses = NULL;
  85919. + int sesn;
  85920. +
  85921. + DPRINTF("%s()\n", __FUNCTION__);
  85922. + if (sidp == NULL || cri == NULL || sc == NULL) {
  85923. + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
  85924. + return EINVAL;
  85925. + }
  85926. + for (c = cri; c != NULL; c = c->cri_next) {
  85927. + if (c->cri_alg == CRYPTO_MD5 ||
  85928. + c->cri_alg == CRYPTO_MD5_HMAC ||
  85929. + c->cri_alg == CRYPTO_SHA1 ||
  85930. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  85931. + c->cri_alg == CRYPTO_NULL_HMAC) {
  85932. + if (macini)
  85933. + return EINVAL;
  85934. + macini = c;
  85935. + } else if (c->cri_alg == CRYPTO_DES_CBC ||
  85936. + c->cri_alg == CRYPTO_3DES_CBC ||
  85937. + c->cri_alg == CRYPTO_AES_CBC ||
  85938. + c->cri_alg == CRYPTO_NULL_CBC) {
  85939. + if (encini)
  85940. + return EINVAL;
  85941. + encini = c;
  85942. + } else {
  85943. + DPRINTF("UNKNOWN c->cri_alg %d\n", encini->cri_alg);
  85944. + return EINVAL;
  85945. + }
  85946. + }
  85947. + if (encini == NULL && macini == NULL)
  85948. + return EINVAL;
  85949. + if (encini) {
  85950. + /* validate key length */
  85951. + switch (encini->cri_alg) {
  85952. + case CRYPTO_DES_CBC:
  85953. + if (encini->cri_klen != 64)
  85954. + return EINVAL;
  85955. + break;
  85956. + case CRYPTO_3DES_CBC:
  85957. + if (encini->cri_klen != 192) {
  85958. + return EINVAL;
  85959. + }
  85960. + break;
  85961. + case CRYPTO_AES_CBC:
  85962. + if (encini->cri_klen != 128 &&
  85963. + encini->cri_klen != 192 &&
  85964. + encini->cri_klen != 256)
  85965. + return EINVAL;
  85966. + break;
  85967. + default:
  85968. + DPRINTF("UNKNOWN encini->cri_alg %d\n",
  85969. + encini->cri_alg);
  85970. + return EINVAL;
  85971. + }
  85972. + }
  85973. +
  85974. + if (sc->sc_sessions == NULL) {
  85975. + ses = sc->sc_sessions = (struct talitos_session *)
  85976. + kmalloc(sizeof(struct talitos_session), SLAB_ATOMIC);
  85977. + if (ses == NULL)
  85978. + return ENOMEM;
  85979. + memset(ses, 0, sizeof(struct talitos_session));
  85980. + sesn = 0;
  85981. + sc->sc_nsessions = 1;
  85982. + } else {
  85983. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  85984. + if (sc->sc_sessions[sesn].ses_used == 0) {
  85985. + ses = &sc->sc_sessions[sesn];
  85986. + break;
  85987. + }
  85988. + }
  85989. +
  85990. + if (ses == NULL) {
  85991. + /* allocating session */
  85992. + sesn = sc->sc_nsessions;
  85993. + ses = (struct talitos_session *) kmalloc(
  85994. + (sesn + 1) * sizeof(struct talitos_session),
  85995. + SLAB_ATOMIC);
  85996. + if (ses == NULL)
  85997. + return ENOMEM;
  85998. + memset(ses, 0,
  85999. + (sesn + 1) * sizeof(struct talitos_session));
  86000. + memcpy(ses, sc->sc_sessions,
  86001. + sesn * sizeof(struct talitos_session));
  86002. + memset(sc->sc_sessions, 0,
  86003. + sesn * sizeof(struct talitos_session));
  86004. + kfree(sc->sc_sessions);
  86005. + sc->sc_sessions = ses;
  86006. + ses = &sc->sc_sessions[sesn];
  86007. + sc->sc_nsessions++;
  86008. + }
  86009. + }
  86010. +
  86011. + ses->ses_used = 1;
  86012. +
  86013. + if (encini) {
  86014. + /* get an IV */
  86015. + /* XXX may read fewer than requested */
  86016. + read_random(ses->ses_iv, sizeof(ses->ses_iv));
  86017. +
  86018. + ses->ses_klen = (encini->cri_klen + 7) / 8;
  86019. + memcpy(ses->ses_key, encini->cri_key, ses->ses_klen);
  86020. + if (macini) {
  86021. + /* doing hash on top of cipher */
  86022. + ses->ses_hmac_len = (macini->cri_klen + 7) / 8;
  86023. + memcpy(ses->ses_hmac, macini->cri_key,
  86024. + ses->ses_hmac_len);
  86025. + }
  86026. + } else if (macini) {
  86027. + /* doing hash */
  86028. + ses->ses_klen = (macini->cri_klen + 7) / 8;
  86029. + memcpy(ses->ses_key, macini->cri_key, ses->ses_klen);
  86030. + }
  86031. +
  86032. + /* back compat way of determining MSC result len */
  86033. + if (macini) {
  86034. + ses->ses_mlen = macini->cri_mlen;
  86035. + if (ses->ses_mlen == 0) {
  86036. + if (macini->cri_alg == CRYPTO_MD5_HMAC)
  86037. + ses->ses_mlen = MD5_HASH_LEN;
  86038. + else
  86039. + ses->ses_mlen = SHA1_HASH_LEN;
  86040. + }
  86041. + }
  86042. +
  86043. + /* really should make up a template td here,
  86044. + * and only fill things like i/o and direction in process() */
  86045. +
  86046. + /* assign session ID */
  86047. + *sidp = TALITOS_SID(sc->sc_num, sesn);
  86048. + return 0;
  86049. +}
  86050. +
  86051. +/*
  86052. + * Deallocate a session.
  86053. + */
  86054. +static int
  86055. +talitos_freesession(device_t dev, u_int64_t tid)
  86056. +{
  86057. + struct talitos_softc *sc = device_get_softc(dev);
  86058. + int session, ret;
  86059. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  86060. +
  86061. + if (sc == NULL)
  86062. + return EINVAL;
  86063. + session = TALITOS_SESSION(sid);
  86064. + if (session < sc->sc_nsessions) {
  86065. + memset(&sc->sc_sessions[session], 0,
  86066. + sizeof(sc->sc_sessions[session]));
  86067. + ret = 0;
  86068. + } else
  86069. + ret = EINVAL;
  86070. + return ret;
  86071. +}
  86072. +
  86073. +/*
  86074. + * launch device processing - it will come back with done notification
  86075. + * in the form of an interrupt and/or HDR_DONE_BITS in header
  86076. + */
  86077. +static int
  86078. +talitos_submit(
  86079. + struct talitos_softc *sc,
  86080. + struct talitos_desc *td,
  86081. + int chsel)
  86082. +{
  86083. + u_int32_t v;
  86084. +
  86085. + v = dma_map_single(NULL, td, sizeof(*td), DMA_TO_DEVICE);
  86086. + talitos_write(sc->sc_base_addr +
  86087. + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF, 0);
  86088. + talitos_write(sc->sc_base_addr +
  86089. + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF_HI, v);
  86090. + return 0;
  86091. +}
  86092. +
  86093. +static int
  86094. +talitos_process(device_t dev, struct cryptop *crp, int hint)
  86095. +{
  86096. + int i, err = 0, ivsize;
  86097. + struct talitos_softc *sc = device_get_softc(dev);
  86098. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  86099. + caddr_t iv;
  86100. + struct talitos_session *ses;
  86101. + struct talitos_desc *td;
  86102. + unsigned long flags;
  86103. + /* descriptor mappings */
  86104. + int hmac_key, hmac_data, cipher_iv, cipher_key,
  86105. + in_fifo, out_fifo, cipher_iv_out;
  86106. + static int chsel = -1;
  86107. +
  86108. + DPRINTF("%s()\n", __FUNCTION__);
  86109. +
  86110. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
  86111. + return EINVAL;
  86112. + }
  86113. + crp->crp_etype = 0;
  86114. + if (TALITOS_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
  86115. + return EINVAL;
  86116. + }
  86117. +
  86118. + ses = &sc->sc_sessions[TALITOS_SESSION(crp->crp_sid)];
  86119. +
  86120. + /* enter the channel scheduler */
  86121. + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  86122. +
  86123. + /* reuse channel that already had/has requests for the required EU */
  86124. + for (i = 0; i < sc->sc_num_channels; i++) {
  86125. + if (sc->sc_chnlastalg[i] == crp->crp_desc->crd_alg)
  86126. + break;
  86127. + }
  86128. + if (i == sc->sc_num_channels) {
  86129. + /*
  86130. + * haven't seen this algo the last sc_num_channels or more
  86131. + * use round robin in this case
  86132. + * nb: sc->sc_num_channels must be power of 2
  86133. + */
  86134. + chsel = (chsel + 1) & (sc->sc_num_channels - 1);
  86135. + } else {
  86136. + /*
  86137. + * matches channel with same target execution unit;
  86138. + * use same channel in this case
  86139. + */
  86140. + chsel = i;
  86141. + }
  86142. + sc->sc_chnlastalg[chsel] = crp->crp_desc->crd_alg;
  86143. +
  86144. + /* release the channel scheduler lock */
  86145. + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  86146. +
  86147. + /* acquire the selected channel fifo lock */
  86148. + spin_lock_irqsave(&sc->sc_chnfifolock[chsel], flags);
  86149. +
  86150. + /* find and reserve next available descriptor-cryptop pair */
  86151. + for (i = 0; i < sc->sc_chfifo_len; i++) {
  86152. + if (sc->sc_chnfifo[chsel][i].cf_desc.hdr == 0) {
  86153. + /*
  86154. + * ensure correct descriptor formation by
  86155. + * avoiding inadvertently setting "optional" entries
  86156. + * e.g. not using "optional" dptr2 for MD/HMAC descs
  86157. + */
  86158. + memset(&sc->sc_chnfifo[chsel][i].cf_desc,
  86159. + 0, sizeof(*td));
  86160. + /* reserve it with done notification request bit */
  86161. + sc->sc_chnfifo[chsel][i].cf_desc.hdr |=
  86162. + TALITOS_DONE_NOTIFY;
  86163. + break;
  86164. + }
  86165. + }
  86166. + spin_unlock_irqrestore(&sc->sc_chnfifolock[chsel], flags);
  86167. +
  86168. + if (i == sc->sc_chfifo_len) {
  86169. + /* fifo full */
  86170. + err = ERESTART;
  86171. + goto errout;
  86172. + }
  86173. +
  86174. + td = &sc->sc_chnfifo[chsel][i].cf_desc;
  86175. + sc->sc_chnfifo[chsel][i].cf_crp = crp;
  86176. +
  86177. + crd1 = crp->crp_desc;
  86178. + if (crd1 == NULL) {
  86179. + err = EINVAL;
  86180. + goto errout;
  86181. + }
  86182. + crd2 = crd1->crd_next;
  86183. + /* prevent compiler warning */
  86184. + hmac_key = 0;
  86185. + hmac_data = 0;
  86186. + if (crd2 == NULL) {
  86187. + td->hdr |= TD_TYPE_COMMON_NONSNOOP_NO_AFEU;
  86188. + /* assign descriptor dword ptr mappings for this desc. type */
  86189. + cipher_iv = 1;
  86190. + cipher_key = 2;
  86191. + in_fifo = 3;
  86192. + cipher_iv_out = 5;
  86193. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  86194. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  86195. + crd1->crd_alg == CRYPTO_SHA1 ||
  86196. + crd1->crd_alg == CRYPTO_MD5) {
  86197. + out_fifo = 5;
  86198. + maccrd = crd1;
  86199. + enccrd = NULL;
  86200. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  86201. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  86202. + crd1->crd_alg == CRYPTO_AES_CBC ||
  86203. + crd1->crd_alg == CRYPTO_ARC4) {
  86204. + out_fifo = 4;
  86205. + maccrd = NULL;
  86206. + enccrd = crd1;
  86207. + } else {
  86208. + DPRINTF("UNKNOWN crd1->crd_alg %d\n", crd1->crd_alg);
  86209. + err = EINVAL;
  86210. + goto errout;
  86211. + }
  86212. + } else {
  86213. + if (sc->sc_desc_types & TALITOS_HAS_DT_IPSEC_ESP) {
  86214. + td->hdr |= TD_TYPE_IPSEC_ESP;
  86215. + } else {
  86216. + DPRINTF("unimplemented: multiple descriptor ipsec\n");
  86217. + err = EINVAL;
  86218. + goto errout;
  86219. + }
  86220. + /* assign descriptor dword ptr mappings for this desc. type */
  86221. + hmac_key = 0;
  86222. + hmac_data = 1;
  86223. + cipher_iv = 2;
  86224. + cipher_key = 3;
  86225. + in_fifo = 4;
  86226. + out_fifo = 5;
  86227. + cipher_iv_out = 6;
  86228. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  86229. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  86230. + crd1->crd_alg == CRYPTO_MD5 ||
  86231. + crd1->crd_alg == CRYPTO_SHA1) &&
  86232. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  86233. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  86234. + crd2->crd_alg == CRYPTO_AES_CBC ||
  86235. + crd2->crd_alg == CRYPTO_ARC4) &&
  86236. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  86237. + maccrd = crd1;
  86238. + enccrd = crd2;
  86239. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  86240. + crd1->crd_alg == CRYPTO_ARC4 ||
  86241. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  86242. + crd1->crd_alg == CRYPTO_AES_CBC) &&
  86243. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  86244. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  86245. + crd2->crd_alg == CRYPTO_MD5 ||
  86246. + crd2->crd_alg == CRYPTO_SHA1) &&
  86247. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  86248. + enccrd = crd1;
  86249. + maccrd = crd2;
  86250. + } else {
  86251. + /* We cannot order the SEC as requested */
  86252. + printk("%s: cannot do the order\n",
  86253. + device_get_nameunit(sc->sc_cdev));
  86254. + err = EINVAL;
  86255. + goto errout;
  86256. + }
  86257. + }
  86258. + /* assign in_fifo and out_fifo based on input/output struct type */
  86259. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  86260. + /* using SKB buffers */
  86261. + struct sk_buff *skb = (struct sk_buff *)crp->crp_buf;
  86262. + if (skb_shinfo(skb)->nr_frags) {
  86263. + printk("%s: skb frags unimplemented\n",
  86264. + device_get_nameunit(sc->sc_cdev));
  86265. + err = EINVAL;
  86266. + goto errout;
  86267. + }
  86268. + td->ptr[in_fifo].ptr = dma_map_single(NULL, skb->data,
  86269. + skb->len, DMA_TO_DEVICE);
  86270. + td->ptr[in_fifo].len = skb->len;
  86271. + td->ptr[out_fifo].ptr = dma_map_single(NULL, skb->data,
  86272. + skb->len, DMA_TO_DEVICE);
  86273. + td->ptr[out_fifo].len = skb->len;
  86274. + td->ptr[hmac_data].ptr = dma_map_single(NULL, skb->data,
  86275. + skb->len, DMA_TO_DEVICE);
  86276. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  86277. + /* using IOV buffers */
  86278. + struct uio *uiop = (struct uio *)crp->crp_buf;
  86279. + if (uiop->uio_iovcnt > 1) {
  86280. + printk("%s: iov frags unimplemented\n",
  86281. + device_get_nameunit(sc->sc_cdev));
  86282. + err = EINVAL;
  86283. + goto errout;
  86284. + }
  86285. + td->ptr[in_fifo].ptr = dma_map_single(NULL,
  86286. + uiop->uio_iov->iov_base, crp->crp_ilen, DMA_TO_DEVICE);
  86287. + td->ptr[in_fifo].len = crp->crp_ilen;
  86288. + /* crp_olen is never set; always use crp_ilen */
  86289. + td->ptr[out_fifo].ptr = dma_map_single(NULL,
  86290. + uiop->uio_iov->iov_base,
  86291. + crp->crp_ilen, DMA_TO_DEVICE);
  86292. + td->ptr[out_fifo].len = crp->crp_ilen;
  86293. + } else {
  86294. + /* using contig buffers */
  86295. + td->ptr[in_fifo].ptr = dma_map_single(NULL,
  86296. + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
  86297. + td->ptr[in_fifo].len = crp->crp_ilen;
  86298. + td->ptr[out_fifo].ptr = dma_map_single(NULL,
  86299. + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
  86300. + td->ptr[out_fifo].len = crp->crp_ilen;
  86301. + }
  86302. + if (enccrd) {
  86303. + switch (enccrd->crd_alg) {
  86304. + case CRYPTO_3DES_CBC:
  86305. + td->hdr |= TALITOS_MODE0_DEU_3DES;
  86306. + /* FALLTHROUGH */
  86307. + case CRYPTO_DES_CBC:
  86308. + td->hdr |= TALITOS_SEL0_DEU
  86309. + | TALITOS_MODE0_DEU_CBC;
  86310. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  86311. + td->hdr |= TALITOS_MODE0_DEU_ENC;
  86312. + ivsize = 2*sizeof(u_int32_t);
  86313. + DPRINTF("%cDES ses %d ch %d len %d\n",
  86314. + (td->hdr & TALITOS_MODE0_DEU_3DES)?'3':'1',
  86315. + (u32)TALITOS_SESSION(crp->crp_sid),
  86316. + chsel, td->ptr[in_fifo].len);
  86317. + break;
  86318. + case CRYPTO_AES_CBC:
  86319. + td->hdr |= TALITOS_SEL0_AESU
  86320. + | TALITOS_MODE0_AESU_CBC;
  86321. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  86322. + td->hdr |= TALITOS_MODE0_AESU_ENC;
  86323. + ivsize = 4*sizeof(u_int32_t);
  86324. + DPRINTF("AES ses %d ch %d len %d\n",
  86325. + (u32)TALITOS_SESSION(crp->crp_sid),
  86326. + chsel, td->ptr[in_fifo].len);
  86327. + break;
  86328. + default:
  86329. + printk("%s: unimplemented enccrd->crd_alg %d\n",
  86330. + device_get_nameunit(sc->sc_cdev), enccrd->crd_alg);
  86331. + err = EINVAL;
  86332. + goto errout;
  86333. + }
  86334. + /*
  86335. + * Setup encrypt/decrypt state. When using basic ops
  86336. + * we can't use an inline IV because hash/crypt offset
  86337. + * must be from the end of the IV to the start of the
  86338. + * crypt data and this leaves out the preceding header
  86339. + * from the hash calculation. Instead we place the IV
  86340. + * in the state record and set the hash/crypt offset to
  86341. + * copy both the header+IV.
  86342. + */
  86343. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  86344. + td->hdr |= TALITOS_DIR_OUTBOUND;
  86345. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  86346. + iv = enccrd->crd_iv;
  86347. + else
  86348. + iv = (caddr_t) ses->ses_iv;
  86349. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  86350. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  86351. + enccrd->crd_inject, ivsize, iv);
  86352. + }
  86353. + } else {
  86354. + td->hdr |= TALITOS_DIR_INBOUND;
  86355. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  86356. + iv = enccrd->crd_iv;
  86357. + bcopy(enccrd->crd_iv, iv, ivsize);
  86358. + } else {
  86359. + iv = (caddr_t) ses->ses_iv;
  86360. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  86361. + enccrd->crd_inject, ivsize, iv);
  86362. + }
  86363. + }
  86364. + td->ptr[cipher_iv].ptr = dma_map_single(NULL, iv, ivsize,
  86365. + DMA_TO_DEVICE);
  86366. + td->ptr[cipher_iv].len = ivsize;
  86367. + /*
  86368. + * we don't need the cipher iv out length/pointer
  86369. + * field to do ESP IPsec. Therefore we set the len field as 0,
  86370. + * which tells the SEC not to do anything with this len/ptr
  86371. + * field. Previously, when length/pointer as pointing to iv,
  86372. + * it gave us corruption of packets.
  86373. + */
  86374. + td->ptr[cipher_iv_out].len = 0;
  86375. + }
  86376. + if (enccrd && maccrd) {
  86377. + /* this is ipsec only for now */
  86378. + td->hdr |= TALITOS_SEL1_MDEU
  86379. + | TALITOS_MODE1_MDEU_INIT
  86380. + | TALITOS_MODE1_MDEU_PAD;
  86381. + switch (maccrd->crd_alg) {
  86382. + case CRYPTO_MD5:
  86383. + td->hdr |= TALITOS_MODE1_MDEU_MD5;
  86384. + break;
  86385. + case CRYPTO_MD5_HMAC:
  86386. + td->hdr |= TALITOS_MODE1_MDEU_MD5_HMAC;
  86387. + break;
  86388. + case CRYPTO_SHA1:
  86389. + td->hdr |= TALITOS_MODE1_MDEU_SHA1;
  86390. + break;
  86391. + case CRYPTO_SHA1_HMAC:
  86392. + td->hdr |= TALITOS_MODE1_MDEU_SHA1_HMAC;
  86393. + break;
  86394. + default:
  86395. + /* We cannot order the SEC as requested */
  86396. + printk("%s: cannot do the order\n",
  86397. + device_get_nameunit(sc->sc_cdev));
  86398. + err = EINVAL;
  86399. + goto errout;
  86400. + }
  86401. + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
  86402. + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
  86403. + /*
  86404. + * The offset from hash data to the start of
  86405. + * crypt data is the difference in the skips.
  86406. + */
  86407. + /* ipsec only for now */
  86408. + td->ptr[hmac_key].ptr = dma_map_single(NULL,
  86409. + ses->ses_hmac, ses->ses_hmac_len, DMA_TO_DEVICE);
  86410. + td->ptr[hmac_key].len = ses->ses_hmac_len;
  86411. + td->ptr[in_fifo].ptr += enccrd->crd_skip;
  86412. + td->ptr[in_fifo].len = enccrd->crd_len;
  86413. + td->ptr[out_fifo].ptr += enccrd->crd_skip;
  86414. + td->ptr[out_fifo].len = enccrd->crd_len;
  86415. + /* bytes of HMAC to postpend to ciphertext */
  86416. + td->ptr[out_fifo].extent = ses->ses_mlen;
  86417. + td->ptr[hmac_data].ptr += maccrd->crd_skip;
  86418. + td->ptr[hmac_data].len = enccrd->crd_skip - maccrd->crd_skip;
  86419. + }
  86420. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  86421. + printk("%s: CRD_F_KEY_EXPLICIT unimplemented\n",
  86422. + device_get_nameunit(sc->sc_cdev));
  86423. + }
  86424. + }
  86425. + if (!enccrd && maccrd) {
  86426. + /* single MD5 or SHA */
  86427. + td->hdr |= TALITOS_SEL0_MDEU
  86428. + | TALITOS_MODE0_MDEU_INIT
  86429. + | TALITOS_MODE0_MDEU_PAD;
  86430. + switch (maccrd->crd_alg) {
  86431. + case CRYPTO_MD5:
  86432. + td->hdr |= TALITOS_MODE0_MDEU_MD5;
  86433. + DPRINTF("MD5 ses %d ch %d len %d\n",
  86434. + (u32)TALITOS_SESSION(crp->crp_sid),
  86435. + chsel, td->ptr[in_fifo].len);
  86436. + break;
  86437. + case CRYPTO_MD5_HMAC:
  86438. + td->hdr |= TALITOS_MODE0_MDEU_MD5_HMAC;
  86439. + break;
  86440. + case CRYPTO_SHA1:
  86441. + td->hdr |= TALITOS_MODE0_MDEU_SHA1;
  86442. + DPRINTF("SHA1 ses %d ch %d len %d\n",
  86443. + (u32)TALITOS_SESSION(crp->crp_sid),
  86444. + chsel, td->ptr[in_fifo].len);
  86445. + break;
  86446. + case CRYPTO_SHA1_HMAC:
  86447. + td->hdr |= TALITOS_MODE0_MDEU_SHA1_HMAC;
  86448. + break;
  86449. + default:
  86450. + /* We cannot order the SEC as requested */
  86451. + DPRINTF("cannot do the order\n");
  86452. + err = EINVAL;
  86453. + goto errout;
  86454. + }
  86455. +
  86456. + if (crp->crp_flags & CRYPTO_F_IOV)
  86457. + td->ptr[out_fifo].ptr += maccrd->crd_inject;
  86458. +
  86459. + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
  86460. + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
  86461. + td->ptr[hmac_key].ptr = dma_map_single(NULL,
  86462. + ses->ses_hmac, ses->ses_hmac_len,
  86463. + DMA_TO_DEVICE);
  86464. + td->ptr[hmac_key].len = ses->ses_hmac_len;
  86465. + }
  86466. + }
  86467. + else {
  86468. + /* using process key (session data has duplicate) */
  86469. + td->ptr[cipher_key].ptr = dma_map_single(NULL,
  86470. + enccrd->crd_key, (enccrd->crd_klen + 7) / 8,
  86471. + DMA_TO_DEVICE);
  86472. + td->ptr[cipher_key].len = (enccrd->crd_klen + 7) / 8;
  86473. + }
  86474. + /* descriptor complete - GO! */
  86475. + return talitos_submit(sc, td, chsel);
  86476. +
  86477. +errout:
  86478. + if (err != ERESTART) {
  86479. + crp->crp_etype = err;
  86480. + crypto_done(crp);
  86481. + }
  86482. + return err;
  86483. +}
  86484. +
  86485. +/* go through all channels descriptors, notifying OCF what has
  86486. + * _and_hasn't_ successfully completed and reset the device
  86487. + * (otherwise it's up to decoding desc hdrs!)
  86488. + */
  86489. +static void talitos_errorprocessing(struct talitos_softc *sc)
  86490. +{
  86491. + unsigned long flags;
  86492. + int i, j;
  86493. +
  86494. + /* disable further scheduling until under control */
  86495. + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  86496. +
  86497. + if (debug) dump_talitos_status(sc);
  86498. + /* go through descriptors, try and salvage those successfully done,
  86499. + * and EIO those that weren't
  86500. + */
  86501. + for (i = 0; i < sc->sc_num_channels; i++) {
  86502. + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
  86503. + for (j = 0; j < sc->sc_chfifo_len; j++) {
  86504. + if (sc->sc_chnfifo[i][j].cf_desc.hdr) {
  86505. + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
  86506. + & TALITOS_HDR_DONE_BITS)
  86507. + != TALITOS_HDR_DONE_BITS) {
  86508. + /* this one didn't finish */
  86509. + /* signify in crp->etype */
  86510. + sc->sc_chnfifo[i][j].cf_crp->crp_etype
  86511. + = EIO;
  86512. + }
  86513. + } else
  86514. + continue; /* free entry */
  86515. + /* either way, notify ocf */
  86516. + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
  86517. + /* and tag it available again
  86518. + *
  86519. + * memset to ensure correct descriptor formation by
  86520. + * avoiding inadvertently setting "optional" entries
  86521. + * e.g. not using "optional" dptr2 MD/HMAC processing
  86522. + */
  86523. + memset(&sc->sc_chnfifo[i][j].cf_desc,
  86524. + 0, sizeof(struct talitos_desc));
  86525. + }
  86526. + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
  86527. + }
  86528. + /* reset and initialize the SEC h/w device */
  86529. + talitos_reset_device(sc);
  86530. + talitos_init_device(sc);
  86531. +#ifdef CONFIG_OCF_RANDOMHARVEST
  86532. + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG)
  86533. + talitos_rng_init(sc);
  86534. +#endif
  86535. +
  86536. + /* Okay. Stand by. */
  86537. + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  86538. +
  86539. + return;
  86540. +}
  86541. +
  86542. +/* go through all channels descriptors, notifying OCF what's been done */
  86543. +static void talitos_doneprocessing(struct talitos_softc *sc)
  86544. +{
  86545. + unsigned long flags;
  86546. + int i, j;
  86547. +
  86548. + /* go through descriptors looking for done bits */
  86549. + for (i = 0; i < sc->sc_num_channels; i++) {
  86550. + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
  86551. + for (j = 0; j < sc->sc_chfifo_len; j++) {
  86552. + /* descriptor has done bits set? */
  86553. + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
  86554. + & TALITOS_HDR_DONE_BITS)
  86555. + == TALITOS_HDR_DONE_BITS) {
  86556. + /* notify ocf */
  86557. + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
  86558. + /* and tag it available again
  86559. + *
  86560. + * memset to ensure correct descriptor formation by
  86561. + * avoiding inadvertently setting "optional" entries
  86562. + * e.g. not using "optional" dptr2 MD/HMAC processing
  86563. + */
  86564. + memset(&sc->sc_chnfifo[i][j].cf_desc,
  86565. + 0, sizeof(struct talitos_desc));
  86566. + }
  86567. + }
  86568. + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
  86569. + }
  86570. + return;
  86571. +}
  86572. +
  86573. +static irqreturn_t
  86574. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  86575. +talitos_intr(int irq, void *arg)
  86576. +#else
  86577. +talitos_intr(int irq, void *arg, struct pt_regs *regs)
  86578. +#endif
  86579. +{
  86580. + struct talitos_softc *sc = arg;
  86581. + u_int32_t v, v_hi;
  86582. +
  86583. + /* ack */
  86584. + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
  86585. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
  86586. + talitos_write(sc->sc_base_addr + TALITOS_ICR, v);
  86587. + talitos_write(sc->sc_base_addr + TALITOS_ICR_HI, v_hi);
  86588. +
  86589. + if (unlikely(v & TALITOS_ISR_ERROR)) {
  86590. + /* Okay, Houston, we've had a problem here. */
  86591. + printk(KERN_DEBUG "%s: got error interrupt - ISR 0x%08x_%08x\n",
  86592. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  86593. + talitos_errorprocessing(sc);
  86594. + } else
  86595. + if (likely(v & TALITOS_ISR_DONE)) {
  86596. + talitos_doneprocessing(sc);
  86597. + }
  86598. + return IRQ_HANDLED;
  86599. +}
  86600. +
  86601. +/*
  86602. + * Initialize registers we need to touch only once.
  86603. + */
  86604. +static void
  86605. +talitos_init_device(struct talitos_softc *sc)
  86606. +{
  86607. + u_int32_t v;
  86608. + int i;
  86609. +
  86610. + DPRINTF("%s()\n", __FUNCTION__);
  86611. +
  86612. + /* init all channels */
  86613. + for (i = 0; i < sc->sc_num_channels; i++) {
  86614. + v = talitos_read(sc->sc_base_addr +
  86615. + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI);
  86616. + v |= TALITOS_CH_CCCR_HI_CDWE
  86617. + | TALITOS_CH_CCCR_HI_CDIE; /* invoke interrupt if done */
  86618. + talitos_write(sc->sc_base_addr +
  86619. + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI, v);
  86620. + }
  86621. + /* enable all interrupts */
  86622. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
  86623. + v |= TALITOS_IMR_ALL;
  86624. + talitos_write(sc->sc_base_addr + TALITOS_IMR, v);
  86625. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
  86626. + v |= TALITOS_IMR_HI_ERRONLY;
  86627. + talitos_write(sc->sc_base_addr + TALITOS_IMR_HI, v);
  86628. + return;
  86629. +}
  86630. +
  86631. +/*
  86632. + * set the master reset bit on the device.
  86633. + */
  86634. +static void
  86635. +talitos_reset_device_master(struct talitos_softc *sc)
  86636. +{
  86637. + u_int32_t v;
  86638. +
  86639. + /* Reset the device by writing 1 to MCR:SWR and waiting 'til cleared */
  86640. + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
  86641. + talitos_write(sc->sc_base_addr + TALITOS_MCR, v | TALITOS_MCR_SWR);
  86642. +
  86643. + while (talitos_read(sc->sc_base_addr + TALITOS_MCR) & TALITOS_MCR_SWR)
  86644. + cpu_relax();
  86645. +
  86646. + return;
  86647. +}
  86648. +
  86649. +/*
  86650. + * Resets the device. Values in the registers are left as is
  86651. + * from the reset (i.e. initial values are assigned elsewhere).
  86652. + */
  86653. +static void
  86654. +talitos_reset_device(struct talitos_softc *sc)
  86655. +{
  86656. + u_int32_t v;
  86657. + int i;
  86658. +
  86659. + DPRINTF("%s()\n", __FUNCTION__);
  86660. +
  86661. + /*
  86662. + * Master reset
  86663. + * errata documentation: warning: certain SEC interrupts
  86664. + * are not fully cleared by writing the MCR:SWR bit,
  86665. + * set bit twice to completely reset
  86666. + */
  86667. + talitos_reset_device_master(sc); /* once */
  86668. + talitos_reset_device_master(sc); /* and once again */
  86669. +
  86670. + /* reset all channels */
  86671. + for (i = 0; i < sc->sc_num_channels; i++) {
  86672. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  86673. + TALITOS_CH_CCCR);
  86674. + talitos_write(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  86675. + TALITOS_CH_CCCR, v | TALITOS_CH_CCCR_RESET);
  86676. + }
  86677. +}
  86678. +
  86679. +/* Set up the crypto device structure, private data,
  86680. + * and anything else we need before we start */
  86681. +#ifdef CONFIG_PPC_MERGE
  86682. +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match)
  86683. +#else
  86684. +static int talitos_probe(struct platform_device *pdev)
  86685. +#endif
  86686. +{
  86687. + struct talitos_softc *sc = NULL;
  86688. + struct resource *r;
  86689. +#ifdef CONFIG_PPC_MERGE
  86690. + struct device *device = &ofdev->dev;
  86691. + struct device_node *np = ofdev->node;
  86692. + const unsigned int *prop;
  86693. + int err;
  86694. + struct resource res;
  86695. +#endif
  86696. + static int num_chips = 0;
  86697. + int rc;
  86698. + int i;
  86699. +
  86700. + DPRINTF("%s()\n", __FUNCTION__);
  86701. +
  86702. + sc = (struct talitos_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  86703. + if (!sc)
  86704. + return -ENOMEM;
  86705. + memset(sc, 0, sizeof(*sc));
  86706. +
  86707. + softc_device_init(sc, DRV_NAME, num_chips, talitos_methods);
  86708. +
  86709. + sc->sc_irq = -1;
  86710. + sc->sc_cid = -1;
  86711. +#ifndef CONFIG_PPC_MERGE
  86712. + sc->sc_dev = pdev;
  86713. +#endif
  86714. + sc->sc_num = num_chips++;
  86715. +
  86716. +#ifdef CONFIG_PPC_MERGE
  86717. + dev_set_drvdata(device, sc);
  86718. +#else
  86719. + platform_set_drvdata(sc->sc_dev, sc);
  86720. +#endif
  86721. +
  86722. + /* get the irq line */
  86723. +#ifdef CONFIG_PPC_MERGE
  86724. + err = of_address_to_resource(np, 0, &res);
  86725. + if (err)
  86726. + return -EINVAL;
  86727. + r = &res;
  86728. +
  86729. + sc->sc_irq = irq_of_parse_and_map(np, 0);
  86730. +#else
  86731. + /* get a pointer to the register memory */
  86732. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  86733. +
  86734. + sc->sc_irq = platform_get_irq(pdev, 0);
  86735. +#endif
  86736. + rc = request_irq(sc->sc_irq, talitos_intr, 0,
  86737. + device_get_nameunit(sc->sc_cdev), sc);
  86738. + if (rc) {
  86739. + printk(KERN_ERR "%s: failed to hook irq %d\n",
  86740. + device_get_nameunit(sc->sc_cdev), sc->sc_irq);
  86741. + sc->sc_irq = -1;
  86742. + goto out;
  86743. + }
  86744. +
  86745. + sc->sc_base_addr = (ocf_iomem_t) ioremap(r->start, (r->end - r->start));
  86746. + if (!sc->sc_base_addr) {
  86747. + printk(KERN_ERR "%s: failed to ioremap\n",
  86748. + device_get_nameunit(sc->sc_cdev));
  86749. + goto out;
  86750. + }
  86751. +
  86752. + /* figure out our SEC's properties and capabilities */
  86753. + sc->sc_chiprev = (u64)talitos_read(sc->sc_base_addr + TALITOS_ID) << 32
  86754. + | talitos_read(sc->sc_base_addr + TALITOS_ID_HI);
  86755. + DPRINTF("sec id 0x%llx\n", sc->sc_chiprev);
  86756. +
  86757. +#ifdef CONFIG_PPC_MERGE
  86758. + /* get SEC properties from device tree, defaulting to SEC 2.0 */
  86759. +
  86760. + prop = of_get_property(np, "num-channels", NULL);
  86761. + sc->sc_num_channels = prop ? *prop : TALITOS_NCHANNELS_SEC_2_0;
  86762. +
  86763. + prop = of_get_property(np, "channel-fifo-len", NULL);
  86764. + sc->sc_chfifo_len = prop ? *prop : TALITOS_CHFIFOLEN_SEC_2_0;
  86765. +
  86766. + prop = of_get_property(np, "exec-units-mask", NULL);
  86767. + sc->sc_exec_units = prop ? *prop : TALITOS_HAS_EUS_SEC_2_0;
  86768. +
  86769. + prop = of_get_property(np, "descriptor-types-mask", NULL);
  86770. + sc->sc_desc_types = prop ? *prop : TALITOS_HAS_DESCTYPES_SEC_2_0;
  86771. +#else
  86772. + /* bulk should go away with openfirmware flat device tree support */
  86773. + if (sc->sc_chiprev & TALITOS_ID_SEC_2_0) {
  86774. + sc->sc_num_channels = TALITOS_NCHANNELS_SEC_2_0;
  86775. + sc->sc_chfifo_len = TALITOS_CHFIFOLEN_SEC_2_0;
  86776. + sc->sc_exec_units = TALITOS_HAS_EUS_SEC_2_0;
  86777. + sc->sc_desc_types = TALITOS_HAS_DESCTYPES_SEC_2_0;
  86778. + } else {
  86779. + printk(KERN_ERR "%s: failed to id device\n",
  86780. + device_get_nameunit(sc->sc_cdev));
  86781. + goto out;
  86782. + }
  86783. +#endif
  86784. +
  86785. + /* + 1 is for the meta-channel lock used by the channel scheduler */
  86786. + sc->sc_chnfifolock = (spinlock_t *) kmalloc(
  86787. + (sc->sc_num_channels + 1) * sizeof(spinlock_t), GFP_KERNEL);
  86788. + if (!sc->sc_chnfifolock)
  86789. + goto out;
  86790. + for (i = 0; i < sc->sc_num_channels + 1; i++) {
  86791. + spin_lock_init(&sc->sc_chnfifolock[i]);
  86792. + }
  86793. +
  86794. + sc->sc_chnlastalg = (int *) kmalloc(
  86795. + sc->sc_num_channels * sizeof(int), GFP_KERNEL);
  86796. + if (!sc->sc_chnlastalg)
  86797. + goto out;
  86798. + memset(sc->sc_chnlastalg, 0, sc->sc_num_channels * sizeof(int));
  86799. +
  86800. + sc->sc_chnfifo = (struct desc_cryptop_pair **) kmalloc(
  86801. + sc->sc_num_channels * sizeof(struct desc_cryptop_pair *),
  86802. + GFP_KERNEL);
  86803. + if (!sc->sc_chnfifo)
  86804. + goto out;
  86805. + for (i = 0; i < sc->sc_num_channels; i++) {
  86806. + sc->sc_chnfifo[i] = (struct desc_cryptop_pair *) kmalloc(
  86807. + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair),
  86808. + GFP_KERNEL);
  86809. + if (!sc->sc_chnfifo[i])
  86810. + goto out;
  86811. + memset(sc->sc_chnfifo[i], 0,
  86812. + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair));
  86813. + }
  86814. +
  86815. + /* reset and initialize the SEC h/w device */
  86816. + talitos_reset_device(sc);
  86817. + talitos_init_device(sc);
  86818. +
  86819. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  86820. + if (sc->sc_cid < 0) {
  86821. + printk(KERN_ERR "%s: could not get crypto driver id\n",
  86822. + device_get_nameunit(sc->sc_cdev));
  86823. + goto out;
  86824. + }
  86825. +
  86826. + /* register algorithms with the framework */
  86827. + printk("%s:", device_get_nameunit(sc->sc_cdev));
  86828. +
  86829. + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG) {
  86830. + printk(" rng");
  86831. +#ifdef CONFIG_OCF_RANDOMHARVEST
  86832. + talitos_rng_init(sc);
  86833. + crypto_rregister(sc->sc_cid, talitos_read_random, sc);
  86834. +#endif
  86835. + }
  86836. + if (sc->sc_exec_units & TALITOS_HAS_EU_DEU) {
  86837. + printk(" des/3des");
  86838. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  86839. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  86840. + }
  86841. + if (sc->sc_exec_units & TALITOS_HAS_EU_AESU) {
  86842. + printk(" aes");
  86843. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  86844. + }
  86845. + if (sc->sc_exec_units & TALITOS_HAS_EU_MDEU) {
  86846. + printk(" md5");
  86847. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  86848. + /* HMAC support only with IPsec for now */
  86849. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  86850. + printk(" sha1");
  86851. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  86852. + /* HMAC support only with IPsec for now */
  86853. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  86854. + }
  86855. + printk("\n");
  86856. + return 0;
  86857. +
  86858. +out:
  86859. +#ifndef CONFIG_PPC_MERGE
  86860. + talitos_remove(pdev);
  86861. +#endif
  86862. + return -ENOMEM;
  86863. +}
  86864. +
  86865. +#ifdef CONFIG_PPC_MERGE
  86866. +static int talitos_remove(struct of_device *ofdev)
  86867. +#else
  86868. +static int talitos_remove(struct platform_device *pdev)
  86869. +#endif
  86870. +{
  86871. +#ifdef CONFIG_PPC_MERGE
  86872. + struct talitos_softc *sc = dev_get_drvdata(&ofdev->dev);
  86873. +#else
  86874. + struct talitos_softc *sc = platform_get_drvdata(pdev);
  86875. +#endif
  86876. + int i;
  86877. +
  86878. + DPRINTF("%s()\n", __FUNCTION__);
  86879. + if (sc->sc_cid >= 0)
  86880. + crypto_unregister_all(sc->sc_cid);
  86881. + if (sc->sc_chnfifo) {
  86882. + for (i = 0; i < sc->sc_num_channels; i++)
  86883. + if (sc->sc_chnfifo[i])
  86884. + kfree(sc->sc_chnfifo[i]);
  86885. + kfree(sc->sc_chnfifo);
  86886. + }
  86887. + if (sc->sc_chnlastalg)
  86888. + kfree(sc->sc_chnlastalg);
  86889. + if (sc->sc_chnfifolock)
  86890. + kfree(sc->sc_chnfifolock);
  86891. + if (sc->sc_irq != -1)
  86892. + free_irq(sc->sc_irq, sc);
  86893. + if (sc->sc_base_addr)
  86894. + iounmap((void *) sc->sc_base_addr);
  86895. + kfree(sc);
  86896. + return 0;
  86897. +}
  86898. +
  86899. +#ifdef CONFIG_PPC_MERGE
  86900. +static struct of_device_id talitos_match[] = {
  86901. + {
  86902. + .type = "crypto",
  86903. + .compatible = "talitos",
  86904. + },
  86905. + {},
  86906. +};
  86907. +
  86908. +MODULE_DEVICE_TABLE(of, talitos_match);
  86909. +
  86910. +static struct of_platform_driver talitos_driver = {
  86911. + .name = DRV_NAME,
  86912. + .match_table = talitos_match,
  86913. + .probe = talitos_probe,
  86914. + .remove = talitos_remove,
  86915. +};
  86916. +
  86917. +static int __init talitos_init(void)
  86918. +{
  86919. + return of_register_platform_driver(&talitos_driver);
  86920. +}
  86921. +
  86922. +static void __exit talitos_exit(void)
  86923. +{
  86924. + of_unregister_platform_driver(&talitos_driver);
  86925. +}
  86926. +#else
  86927. +/* Structure for a platform device driver */
  86928. +static struct platform_driver talitos_driver = {
  86929. + .probe = talitos_probe,
  86930. + .remove = talitos_remove,
  86931. + .driver = {
  86932. + .name = "fsl-sec2",
  86933. + }
  86934. +};
  86935. +
  86936. +static int __init talitos_init(void)
  86937. +{
  86938. + return platform_driver_register(&talitos_driver);
  86939. +}
  86940. +
  86941. +static void __exit talitos_exit(void)
  86942. +{
  86943. + platform_driver_unregister(&talitos_driver);
  86944. +}
  86945. +#endif
  86946. +
  86947. +module_init(talitos_init);
  86948. +module_exit(talitos_exit);
  86949. +
  86950. +MODULE_LICENSE("Dual BSD/GPL");
  86951. +MODULE_AUTHOR("kim.phillips@freescale.com");
  86952. +MODULE_DESCRIPTION("OCF driver for Freescale SEC (talitos)");
  86953. diff -Nur linux-2.6.36.orig/crypto/ocf/talitos/talitos_dev.h linux-2.6.36/crypto/ocf/talitos/talitos_dev.h
  86954. --- linux-2.6.36.orig/crypto/ocf/talitos/talitos_dev.h 1970-01-01 01:00:00.000000000 +0100
  86955. +++ linux-2.6.36/crypto/ocf/talitos/talitos_dev.h 2010-11-09 20:28:13.232495491 +0100
  86956. @@ -0,0 +1,277 @@
  86957. +/*
  86958. + * Freescale SEC (talitos) device dependent data structures
  86959. + *
  86960. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  86961. + *
  86962. + * Redistribution and use in source and binary forms, with or without
  86963. + * modification, are permitted provided that the following conditions
  86964. + * are met:
  86965. + *
  86966. + * 1. Redistributions of source code must retain the above copyright
  86967. + * notice, this list of conditions and the following disclaimer.
  86968. + * 2. Redistributions in binary form must reproduce the above copyright
  86969. + * notice, this list of conditions and the following disclaimer in the
  86970. + * documentation and/or other materials provided with the distribution.
  86971. + * 3. The name of the author may not be used to endorse or promote products
  86972. + * derived from this software without specific prior written permission.
  86973. + *
  86974. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  86975. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  86976. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  86977. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  86978. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  86979. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  86980. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  86981. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  86982. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  86983. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  86984. + *
  86985. + */
  86986. +
  86987. +/* device ID register values */
  86988. +#define TALITOS_ID_SEC_2_0 0x40
  86989. +#define TALITOS_ID_SEC_2_1 0x40 /* cross ref with IP block revision reg */
  86990. +
  86991. +/*
  86992. + * following num_channels, channel-fifo-depth, exec-unit-mask, and
  86993. + * descriptor-types-mask are for forward-compatibility with openfirmware
  86994. + * flat device trees
  86995. + */
  86996. +
  86997. +/*
  86998. + * num_channels : the number of channels available in each SEC version.
  86999. + */
  87000. +
  87001. +/* n.b. this driver requires these values be a power of 2 */
  87002. +#define TALITOS_NCHANNELS_SEC_1_0 4
  87003. +#define TALITOS_NCHANNELS_SEC_1_2 1
  87004. +#define TALITOS_NCHANNELS_SEC_2_0 4
  87005. +#define TALITOS_NCHANNELS_SEC_2_01 4
  87006. +#define TALITOS_NCHANNELS_SEC_2_1 4
  87007. +#define TALITOS_NCHANNELS_SEC_2_4 4
  87008. +
  87009. +/*
  87010. + * channel-fifo-depth : The number of descriptor
  87011. + * pointers a channel fetch fifo can hold.
  87012. + */
  87013. +#define TALITOS_CHFIFOLEN_SEC_1_0 1
  87014. +#define TALITOS_CHFIFOLEN_SEC_1_2 1
  87015. +#define TALITOS_CHFIFOLEN_SEC_2_0 24
  87016. +#define TALITOS_CHFIFOLEN_SEC_2_01 24
  87017. +#define TALITOS_CHFIFOLEN_SEC_2_1 24
  87018. +#define TALITOS_CHFIFOLEN_SEC_2_4 24
  87019. +
  87020. +/*
  87021. + * exec-unit-mask : The bitmask representing what Execution Units (EUs)
  87022. + * are available. EU information should be encoded following the SEC's
  87023. + * EU_SEL0 bitfield documentation, i.e. as follows:
  87024. + *
  87025. + * bit 31 = set if SEC permits no-EU selection (should be always set)
  87026. + * bit 30 = set if SEC has the ARC4 EU (AFEU)
  87027. + * bit 29 = set if SEC has the des/3des EU (DEU)
  87028. + * bit 28 = set if SEC has the message digest EU (MDEU)
  87029. + * bit 27 = set if SEC has the random number generator EU (RNG)
  87030. + * bit 26 = set if SEC has the public key EU (PKEU)
  87031. + * bit 25 = set if SEC has the aes EU (AESU)
  87032. + * bit 24 = set if SEC has the Kasumi EU (KEU)
  87033. + *
  87034. + */
  87035. +#define TALITOS_HAS_EU_NONE (1<<0)
  87036. +#define TALITOS_HAS_EU_AFEU (1<<1)
  87037. +#define TALITOS_HAS_EU_DEU (1<<2)
  87038. +#define TALITOS_HAS_EU_MDEU (1<<3)
  87039. +#define TALITOS_HAS_EU_RNG (1<<4)
  87040. +#define TALITOS_HAS_EU_PKEU (1<<5)
  87041. +#define TALITOS_HAS_EU_AESU (1<<6)
  87042. +#define TALITOS_HAS_EU_KEU (1<<7)
  87043. +
  87044. +/* the corresponding masks for each SEC version */
  87045. +#define TALITOS_HAS_EUS_SEC_1_0 0x7f
  87046. +#define TALITOS_HAS_EUS_SEC_1_2 0x4d
  87047. +#define TALITOS_HAS_EUS_SEC_2_0 0x7f
  87048. +#define TALITOS_HAS_EUS_SEC_2_01 0x7f
  87049. +#define TALITOS_HAS_EUS_SEC_2_1 0xff
  87050. +#define TALITOS_HAS_EUS_SEC_2_4 0x7f
  87051. +
  87052. +/*
  87053. + * descriptor-types-mask : The bitmask representing what descriptors
  87054. + * are available. Descriptor type information should be encoded
  87055. + * following the SEC's Descriptor Header Dword DESC_TYPE field
  87056. + * documentation, i.e. as follows:
  87057. + *
  87058. + * bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type
  87059. + * bit 1 = set if SEC supports the ipsec_esp descriptor type
  87060. + * bit 2 = set if SEC supports the common_nonsnoop desc. type
  87061. + * bit 3 = set if SEC supports the 802.11i AES ccmp desc. type
  87062. + * bit 4 = set if SEC supports the hmac_snoop_no_afeu desc. type
  87063. + * bit 5 = set if SEC supports the srtp descriptor type
  87064. + * bit 6 = set if SEC supports the non_hmac_snoop_no_afeu desc.type
  87065. + * bit 7 = set if SEC supports the pkeu_assemble descriptor type
  87066. + * bit 8 = set if SEC supports the aesu_key_expand_output desc.type
  87067. + * bit 9 = set if SEC supports the pkeu_ptmul descriptor type
  87068. + * bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type
  87069. + * bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type
  87070. + *
  87071. + * ..and so on and so forth.
  87072. + */
  87073. +#define TALITOS_HAS_DT_AESU_CTR_NONSNOOP (1<<0)
  87074. +#define TALITOS_HAS_DT_IPSEC_ESP (1<<1)
  87075. +#define TALITOS_HAS_DT_COMMON_NONSNOOP (1<<2)
  87076. +
  87077. +/* the corresponding masks for each SEC version */
  87078. +#define TALITOS_HAS_DESCTYPES_SEC_2_0 0x01010ebf
  87079. +#define TALITOS_HAS_DESCTYPES_SEC_2_1 0x012b0ebf
  87080. +
  87081. +/*
  87082. + * a TALITOS_xxx_HI address points to the low data bits (32-63) of the register
  87083. + */
  87084. +
  87085. +/* global register offset addresses */
  87086. +#define TALITOS_ID 0x1020
  87087. +#define TALITOS_ID_HI 0x1024
  87088. +#define TALITOS_MCR 0x1030 /* master control register */
  87089. +#define TALITOS_MCR_HI 0x1038 /* master control register */
  87090. +#define TALITOS_MCR_SWR 0x1
  87091. +#define TALITOS_IMR 0x1008 /* interrupt mask register */
  87092. +#define TALITOS_IMR_ALL 0x00010fff /* enable all interrupts mask */
  87093. +#define TALITOS_IMR_ERRONLY 0x00010aaa /* enable error interrupts */
  87094. +#define TALITOS_IMR_HI 0x100C /* interrupt mask register */
  87095. +#define TALITOS_IMR_HI_ALL 0x00323333 /* enable all interrupts mask */
  87096. +#define TALITOS_IMR_HI_ERRONLY 0x00222222 /* enable error interrupts */
  87097. +#define TALITOS_ISR 0x1010 /* interrupt status register */
  87098. +#define TALITOS_ISR_ERROR 0x00010faa /* errors mask */
  87099. +#define TALITOS_ISR_DONE 0x00000055 /* channel(s) done mask */
  87100. +#define TALITOS_ISR_HI 0x1014 /* interrupt status register */
  87101. +#define TALITOS_ICR 0x1018 /* interrupt clear register */
  87102. +#define TALITOS_ICR_HI 0x101C /* interrupt clear register */
  87103. +
  87104. +/* channel register address stride */
  87105. +#define TALITOS_CH_OFFSET 0x100
  87106. +
  87107. +/* channel register offset addresses and bits */
  87108. +#define TALITOS_CH_CCCR 0x1108 /* Crypto-Channel Config Register */
  87109. +#define TALITOS_CH_CCCR_RESET 0x1 /* Channel Reset bit */
  87110. +#define TALITOS_CH_CCCR_HI 0x110c /* Crypto-Channel Config Register */
  87111. +#define TALITOS_CH_CCCR_HI_CDWE 0x10 /* Channel done writeback enable bit */
  87112. +#define TALITOS_CH_CCCR_HI_NT 0x4 /* Notification type bit */
  87113. +#define TALITOS_CH_CCCR_HI_CDIE 0x2 /* Channel Done Interrupt Enable bit */
  87114. +#define TALITOS_CH_CCPSR 0x1110 /* Crypto-Channel Pointer Status Reg */
  87115. +#define TALITOS_CH_CCPSR_HI 0x1114 /* Crypto-Channel Pointer Status Reg */
  87116. +#define TALITOS_CH_FF 0x1148 /* Fetch FIFO */
  87117. +#define TALITOS_CH_FF_HI 0x114c /* Fetch FIFO's FETCH_ADRS */
  87118. +#define TALITOS_CH_CDPR 0x1140 /* Crypto-Channel Pointer Status Reg */
  87119. +#define TALITOS_CH_CDPR_HI 0x1144 /* Crypto-Channel Pointer Status Reg */
  87120. +#define TALITOS_CH_DESCBUF 0x1180 /* (thru 11bf) Crypto-Channel
  87121. + * Descriptor Buffer (debug) */
  87122. +
  87123. +/* execution unit register offset addresses and bits */
  87124. +#define TALITOS_DEUSR 0x2028 /* DEU status register */
  87125. +#define TALITOS_DEUSR_HI 0x202c /* DEU status register */
  87126. +#define TALITOS_DEUISR 0x2030 /* DEU interrupt status register */
  87127. +#define TALITOS_DEUISR_HI 0x2034 /* DEU interrupt status register */
  87128. +#define TALITOS_DEUICR 0x2038 /* DEU interrupt control register */
  87129. +#define TALITOS_DEUICR_HI 0x203c /* DEU interrupt control register */
  87130. +#define TALITOS_AESUISR 0x4030 /* AESU interrupt status register */
  87131. +#define TALITOS_AESUISR_HI 0x4034 /* AESU interrupt status register */
  87132. +#define TALITOS_AESUICR 0x4038 /* AESU interrupt control register */
  87133. +#define TALITOS_AESUICR_HI 0x403c /* AESU interrupt control register */
  87134. +#define TALITOS_MDEUISR 0x6030 /* MDEU interrupt status register */
  87135. +#define TALITOS_MDEUISR_HI 0x6034 /* MDEU interrupt status register */
  87136. +#define TALITOS_RNGSR 0xa028 /* RNG status register */
  87137. +#define TALITOS_RNGSR_HI 0xa02c /* RNG status register */
  87138. +#define TALITOS_RNGSR_HI_RD 0x1 /* RNG Reset done */
  87139. +#define TALITOS_RNGSR_HI_OFL 0xff0000/* number of dwords in RNG output FIFO*/
  87140. +#define TALITOS_RNGDSR 0xa010 /* RNG data size register */
  87141. +#define TALITOS_RNGDSR_HI 0xa014 /* RNG data size register */
  87142. +#define TALITOS_RNG_FIFO 0xa800 /* RNG FIFO - pool of random numbers */
  87143. +#define TALITOS_RNGISR 0xa030 /* RNG Interrupt status register */
  87144. +#define TALITOS_RNGISR_HI 0xa034 /* RNG Interrupt status register */
  87145. +#define TALITOS_RNGRCR 0xa018 /* RNG Reset control register */
  87146. +#define TALITOS_RNGRCR_HI 0xa01c /* RNG Reset control register */
  87147. +#define TALITOS_RNGRCR_HI_SR 0x1 /* RNG RNGRCR:Software Reset */
  87148. +
  87149. +/* descriptor pointer entry */
  87150. +struct talitos_desc_ptr {
  87151. + u16 len; /* length */
  87152. + u8 extent; /* jump (to s/g link table) and extent */
  87153. + u8 res; /* reserved */
  87154. + u32 ptr; /* pointer */
  87155. +};
  87156. +
  87157. +/* descriptor */
  87158. +struct talitos_desc {
  87159. + u32 hdr; /* header */
  87160. + u32 res; /* reserved */
  87161. + struct talitos_desc_ptr ptr[7]; /* ptr/len pair array */
  87162. +};
  87163. +
  87164. +/* talitos descriptor header (hdr) bits */
  87165. +
  87166. +/* primary execution unit select */
  87167. +#define TALITOS_SEL0_AFEU 0x10000000
  87168. +#define TALITOS_SEL0_DEU 0x20000000
  87169. +#define TALITOS_SEL0_MDEU 0x30000000
  87170. +#define TALITOS_SEL0_RNG 0x40000000
  87171. +#define TALITOS_SEL0_PKEU 0x50000000
  87172. +#define TALITOS_SEL0_AESU 0x60000000
  87173. +
  87174. +/* primary execution unit mode (MODE0) and derivatives */
  87175. +#define TALITOS_MODE0_AESU_CBC 0x00200000
  87176. +#define TALITOS_MODE0_AESU_ENC 0x00100000
  87177. +#define TALITOS_MODE0_DEU_CBC 0x00400000
  87178. +#define TALITOS_MODE0_DEU_3DES 0x00200000
  87179. +#define TALITOS_MODE0_DEU_ENC 0x00100000
  87180. +#define TALITOS_MODE0_MDEU_INIT 0x01000000 /* init starting regs */
  87181. +#define TALITOS_MODE0_MDEU_HMAC 0x00800000
  87182. +#define TALITOS_MODE0_MDEU_PAD 0x00400000 /* PD */
  87183. +#define TALITOS_MODE0_MDEU_MD5 0x00200000
  87184. +#define TALITOS_MODE0_MDEU_SHA256 0x00100000
  87185. +#define TALITOS_MODE0_MDEU_SHA1 0x00000000 /* SHA-160 */
  87186. +#define TALITOS_MODE0_MDEU_MD5_HMAC \
  87187. + (TALITOS_MODE0_MDEU_MD5 | TALITOS_MODE0_MDEU_HMAC)
  87188. +#define TALITOS_MODE0_MDEU_SHA256_HMAC \
  87189. + (TALITOS_MODE0_MDEU_SHA256 | TALITOS_MODE0_MDEU_HMAC)
  87190. +#define TALITOS_MODE0_MDEU_SHA1_HMAC \
  87191. + (TALITOS_MODE0_MDEU_SHA1 | TALITOS_MODE0_MDEU_HMAC)
  87192. +
  87193. +/* secondary execution unit select (SEL1) */
  87194. +/* it's MDEU or nothing */
  87195. +#define TALITOS_SEL1_MDEU 0x00030000
  87196. +
  87197. +/* secondary execution unit mode (MODE1) and derivatives */
  87198. +#define TALITOS_MODE1_MDEU_INIT 0x00001000 /* init starting regs */
  87199. +#define TALITOS_MODE1_MDEU_HMAC 0x00000800
  87200. +#define TALITOS_MODE1_MDEU_PAD 0x00000400 /* PD */
  87201. +#define TALITOS_MODE1_MDEU_MD5 0x00000200
  87202. +#define TALITOS_MODE1_MDEU_SHA256 0x00000100
  87203. +#define TALITOS_MODE1_MDEU_SHA1 0x00000000 /* SHA-160 */
  87204. +#define TALITOS_MODE1_MDEU_MD5_HMAC \
  87205. + (TALITOS_MODE1_MDEU_MD5 | TALITOS_MODE1_MDEU_HMAC)
  87206. +#define TALITOS_MODE1_MDEU_SHA256_HMAC \
  87207. + (TALITOS_MODE1_MDEU_SHA256 | TALITOS_MODE1_MDEU_HMAC)
  87208. +#define TALITOS_MODE1_MDEU_SHA1_HMAC \
  87209. + (TALITOS_MODE1_MDEU_SHA1 | TALITOS_MODE1_MDEU_HMAC)
  87210. +
  87211. +/* direction of overall data flow (DIR) */
  87212. +#define TALITOS_DIR_OUTBOUND 0x00000000
  87213. +#define TALITOS_DIR_INBOUND 0x00000002
  87214. +
  87215. +/* done notification (DN) */
  87216. +#define TALITOS_DONE_NOTIFY 0x00000001
  87217. +
  87218. +/* descriptor types */
  87219. +/* odd numbers here are valid on SEC2 and greater only (e.g. ipsec_esp) */
  87220. +#define TD_TYPE_AESU_CTR_NONSNOOP (0 << 3)
  87221. +#define TD_TYPE_IPSEC_ESP (1 << 3)
  87222. +#define TD_TYPE_COMMON_NONSNOOP_NO_AFEU (2 << 3)
  87223. +#define TD_TYPE_HMAC_SNOOP_NO_AFEU (4 << 3)
  87224. +
  87225. +#define TALITOS_HDR_DONE_BITS 0xff000000
  87226. +
  87227. +#define DPRINTF(a...) do { \
  87228. + if (debug) { \
  87229. + printk("%s: ", sc ? \
  87230. + device_get_nameunit(sc->sc_cdev) : "talitos"); \
  87231. + printk(a); \
  87232. + } \
  87233. + } while (0)
  87234. diff -Nur linux-2.6.36.orig/crypto/ocf/talitos/talitos_soft.h linux-2.6.36/crypto/ocf/talitos/talitos_soft.h
  87235. --- linux-2.6.36.orig/crypto/ocf/talitos/talitos_soft.h 1970-01-01 01:00:00.000000000 +0100
  87236. +++ linux-2.6.36/crypto/ocf/talitos/talitos_soft.h 2010-11-09 20:28:13.272495451 +0100
  87237. @@ -0,0 +1,77 @@
  87238. +/*
  87239. + * Freescale SEC data structures for integration with ocf-linux
  87240. + *
  87241. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  87242. + *
  87243. + * Redistribution and use in source and binary forms, with or without
  87244. + * modification, are permitted provided that the following conditions
  87245. + * are met:
  87246. + *
  87247. + * 1. Redistributions of source code must retain the above copyright
  87248. + * notice, this list of conditions and the following disclaimer.
  87249. + * 2. Redistributions in binary form must reproduce the above copyright
  87250. + * notice, this list of conditions and the following disclaimer in the
  87251. + * documentation and/or other materials provided with the distribution.
  87252. + * 3. The name of the author may not be used to endorse or promote products
  87253. + * derived from this software without specific prior written permission.
  87254. + *
  87255. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  87256. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  87257. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  87258. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  87259. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  87260. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  87261. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  87262. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  87263. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  87264. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  87265. + */
  87266. +
  87267. +/*
  87268. + * paired descriptor and associated crypto operation
  87269. + */
  87270. +struct desc_cryptop_pair {
  87271. + struct talitos_desc cf_desc; /* descriptor ptr */
  87272. + struct cryptop *cf_crp; /* cryptop ptr */
  87273. +};
  87274. +
  87275. +/*
  87276. + * Holds data specific to a single talitos device.
  87277. + */
  87278. +struct talitos_softc {
  87279. + softc_device_decl sc_cdev;
  87280. + struct platform_device *sc_dev; /* device backpointer */
  87281. + ocf_iomem_t sc_base_addr;
  87282. + int sc_irq;
  87283. + int sc_num; /* if we have multiple chips */
  87284. + int32_t sc_cid; /* crypto tag */
  87285. + u64 sc_chiprev; /* major/minor chip revision */
  87286. + int sc_nsessions;
  87287. + struct talitos_session *sc_sessions;
  87288. + int sc_num_channels;/* number of crypto channels */
  87289. + int sc_chfifo_len; /* channel fetch fifo len */
  87290. + int sc_exec_units; /* execution units mask */
  87291. + int sc_desc_types; /* descriptor types mask */
  87292. + /*
  87293. + * mutual exclusion for intra-channel resources, e.g. fetch fifos
  87294. + * the last entry is a meta-channel lock used by the channel scheduler
  87295. + */
  87296. + spinlock_t *sc_chnfifolock;
  87297. + /* sc_chnlastalgo contains last algorithm for that channel */
  87298. + int *sc_chnlastalg;
  87299. + /* sc_chnfifo holds pending descriptor--crypto operation pairs */
  87300. + struct desc_cryptop_pair **sc_chnfifo;
  87301. +};
  87302. +
  87303. +struct talitos_session {
  87304. + u_int32_t ses_used;
  87305. + u_int32_t ses_klen; /* key length in bits */
  87306. + u_int32_t ses_key[8]; /* DES/3DES/AES key */
  87307. + u_int32_t ses_hmac[5]; /* hmac inner state */
  87308. + u_int32_t ses_hmac_len; /* hmac length */
  87309. + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
  87310. + u_int32_t ses_mlen; /* desired hash result len (12=ipsec or 16) */
  87311. +};
  87312. +
  87313. +#define TALITOS_SESSION(sid) ((sid) & 0x0fffffff)
  87314. +#define TALITOS_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
  87315. diff -Nur linux-2.6.36.orig/crypto/ocf/uio.h linux-2.6.36/crypto/ocf/uio.h
  87316. --- linux-2.6.36.orig/crypto/ocf/uio.h 1970-01-01 01:00:00.000000000 +0100
  87317. +++ linux-2.6.36/crypto/ocf/uio.h 2010-11-09 20:28:13.313482727 +0100
  87318. @@ -0,0 +1,54 @@
  87319. +#ifndef _OCF_UIO_H_
  87320. +#define _OCF_UIO_H_
  87321. +
  87322. +#include <linux/uio.h>
  87323. +
  87324. +/*
  87325. + * The linux uio.h doesn't have all we need. To be fully api compatible
  87326. + * with the BSD cryptodev, we need to keep this around. Perhaps this can
  87327. + * be moved back into the linux/uio.h
  87328. + *
  87329. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  87330. + * Copyright (C) 2006-2010 David McCullough
  87331. + * Copyright (C) 2004-2005 Intel Corporation.
  87332. + *
  87333. + * LICENSE TERMS
  87334. + *
  87335. + * The free distribution and use of this software in both source and binary
  87336. + * form is allowed (with or without changes) provided that:
  87337. + *
  87338. + * 1. distributions of this source code include the above copyright
  87339. + * notice, this list of conditions and the following disclaimer;
  87340. + *
  87341. + * 2. distributions in binary form include the above copyright
  87342. + * notice, this list of conditions and the following disclaimer
  87343. + * in the documentation and/or other associated materials;
  87344. + *
  87345. + * 3. the copyright holder's name is not used to endorse products
  87346. + * built using this software without specific written permission.
  87347. + *
  87348. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  87349. + * may be distributed under the terms of the GNU General Public License (GPL),
  87350. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  87351. + *
  87352. + * DISCLAIMER
  87353. + *
  87354. + * This software is provided 'as is' with no explicit or implied warranties
  87355. + * in respect of its properties, including, but not limited to, correctness
  87356. + * and/or fitness for purpose.
  87357. + * ---------------------------------------------------------------------------
  87358. + */
  87359. +
  87360. +struct uio {
  87361. + struct iovec *uio_iov;
  87362. + int uio_iovcnt;
  87363. + off_t uio_offset;
  87364. + int uio_resid;
  87365. +#if 0
  87366. + enum uio_seg uio_segflg;
  87367. + enum uio_rw uio_rw;
  87368. + struct thread *uio_td;
  87369. +#endif
  87370. +};
  87371. +
  87372. +#endif
  87373. diff -Nur linux-2.6.36.orig/drivers/char/random.c linux-2.6.36/drivers/char/random.c
  87374. --- linux-2.6.36.orig/drivers/char/random.c 2010-10-20 22:30:22.000000000 +0200
  87375. +++ linux-2.6.36/drivers/char/random.c 2010-11-09 20:28:13.352495461 +0100
  87376. @@ -129,6 +129,9 @@
  87377. * unsigned int value);
  87378. * void add_interrupt_randomness(int irq);
  87379. *
  87380. + * void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
  87381. + * int random_input_wait(void);
  87382. + *
  87383. * add_input_randomness() uses the input layer interrupt timing, as well as
  87384. * the event type information from the hardware.
  87385. *
  87386. @@ -140,6 +143,13 @@
  87387. * a better measure, since the timing of the disk interrupts are more
  87388. * unpredictable.
  87389. *
  87390. + * random_input_words() just provides a raw block of entropy to the input
  87391. + * pool, such as from a hardware entropy generator.
  87392. + *
  87393. + * random_input_wait() suspends the caller until such time as the
  87394. + * entropy pool falls below the write threshold, and returns a count of how
  87395. + * much entropy (in bits) is needed to sustain the pool.
  87396. + *
  87397. * All of these routines try to estimate how many bits of randomness a
  87398. * particular randomness source. They do this by keeping track of the
  87399. * first and second order deltas of the event timings.
  87400. @@ -259,6 +269,7 @@
  87401. #define SEC_XFER_SIZE 512
  87402. #define EXTRACT_SIZE 10
  87403. +
  87404. /*
  87405. * The minimum number of bits of entropy before we wake up a read on
  87406. * /dev/random. Should be enough to do a significant reseed.
  87407. @@ -552,6 +563,60 @@
  87408. spin_unlock_irqrestore(&r->lock, flags);
  87409. }
  87410. +/*
  87411. + * random_input_words - add bulk entropy to pool
  87412. + *
  87413. + * @buf: buffer to add
  87414. + * @wordcount: number of __u32 words to add
  87415. + * @ent_count: total amount of entropy (in bits) to credit
  87416. + *
  87417. + * this provides bulk input of entropy to the input pool
  87418. + *
  87419. + */
  87420. +void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
  87421. +{
  87422. + mix_pool_bytes(&input_pool, buf, wordcount*4);
  87423. +
  87424. + credit_entropy_bits(&input_pool, ent_count);
  87425. +
  87426. + DEBUG_ENT("crediting %d bits => %d\n",
  87427. + ent_count, input_pool.entropy_count);
  87428. + /*
  87429. + * Wake up waiting processes if we have enough
  87430. + * entropy.
  87431. + */
  87432. + if (input_pool.entropy_count >= random_read_wakeup_thresh)
  87433. + wake_up_interruptible(&random_read_wait);
  87434. +}
  87435. +EXPORT_SYMBOL(random_input_words);
  87436. +
  87437. +/*
  87438. + * random_input_wait - wait until random needs entropy
  87439. + *
  87440. + * this function sleeps until the /dev/random subsystem actually
  87441. + * needs more entropy, and then return the amount of entropy
  87442. + * that it would be nice to have added to the system.
  87443. + */
  87444. +int random_input_wait(void)
  87445. +{
  87446. + int count;
  87447. +
  87448. + wait_event_interruptible(random_write_wait,
  87449. + input_pool.entropy_count < random_write_wakeup_thresh);
  87450. +
  87451. + count = random_write_wakeup_thresh - input_pool.entropy_count;
  87452. +
  87453. + /* likely we got woken up due to a signal */
  87454. + if (count <= 0) count = random_read_wakeup_thresh;
  87455. +
  87456. + DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
  87457. + count,
  87458. + input_pool.entropy_count, random_write_wakeup_thresh);
  87459. +
  87460. + return count;
  87461. +}
  87462. +EXPORT_SYMBOL(random_input_wait);
  87463. +
  87464. /*********************************************************************
  87465. *
  87466. * Entropy input management
  87467. diff -Nur linux-2.6.36.orig/fs/fcntl.c linux-2.6.36/fs/fcntl.c
  87468. --- linux-2.6.36.orig/fs/fcntl.c 2010-10-20 22:30:22.000000000 +0200
  87469. +++ linux-2.6.36/fs/fcntl.c 2010-11-09 20:28:13.392495458 +0100
  87470. @@ -142,6 +142,7 @@
  87471. }
  87472. return ret;
  87473. }
  87474. +EXPORT_SYMBOL(sys_dup);
  87475. #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
  87476. diff -Nur linux-2.6.36.orig/include/linux/miscdevice.h linux-2.6.36/include/linux/miscdevice.h
  87477. --- linux-2.6.36.orig/include/linux/miscdevice.h 2010-10-20 22:30:22.000000000 +0200
  87478. +++ linux-2.6.36/include/linux/miscdevice.h 2010-11-09 20:28:13.432495492 +0100
  87479. @@ -18,6 +18,7 @@
  87480. #define APOLLO_MOUSE_MINOR 7
  87481. #define PC110PAD_MINOR 9
  87482. /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
  87483. +#define CRYPTODEV_MINOR 70 /* /dev/crypto */
  87484. #define WATCHDOG_MINOR 130 /* Watchdog timer */
  87485. #define TEMP_MINOR 131 /* Temperature Sensor */
  87486. #define RTC_MINOR 135
  87487. diff -Nur linux-2.6.36.orig/include/linux/random.h linux-2.6.36/include/linux/random.h
  87488. --- linux-2.6.36.orig/include/linux/random.h 2010-10-20 22:30:22.000000000 +0200
  87489. +++ linux-2.6.36/include/linux/random.h 2010-11-09 20:28:13.597270121 +0100
  87490. @@ -9,6 +9,7 @@
  87491. #include <linux/types.h>
  87492. #include <linux/ioctl.h>
  87493. +#include <linux/types.h> /* for __u32 in user space */
  87494. #include <linux/irqnr.h>
  87495. /* ioctl()'s for the random number generator */
  87496. @@ -34,6 +35,30 @@
  87497. /* Clear the entropy pool and associated counters. (Superuser only.) */
  87498. #define RNDCLEARPOOL _IO( 'R', 0x06 )
  87499. +#ifdef CONFIG_FIPS_RNG
  87500. +
  87501. +/* Size of seed value - equal to AES blocksize */
  87502. +#define AES_BLOCK_SIZE_BYTES 16
  87503. +#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
  87504. +/* Size of AES key */
  87505. +#define KEY_SIZE_BYTES 16
  87506. +
  87507. +/* ioctl() structure used by FIPS 140-2 Tests */
  87508. +struct rand_fips_test {
  87509. + unsigned char key[KEY_SIZE_BYTES]; /* Input */
  87510. + unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
  87511. + unsigned char seed[SEED_SIZE_BYTES]; /* Input */
  87512. + unsigned char result[SEED_SIZE_BYTES]; /* Output */
  87513. +};
  87514. +
  87515. +/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
  87516. +#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
  87517. +
  87518. +/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
  87519. +#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
  87520. +
  87521. +#endif /* #ifdef CONFIG_FIPS_RNG */
  87522. +
  87523. struct rand_pool_info {
  87524. int entropy_count;
  87525. int buf_size;
  87526. @@ -54,6 +79,10 @@
  87527. unsigned int value);
  87528. extern void add_interrupt_randomness(int irq);
  87529. +extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
  87530. +extern int random_input_wait(void);
  87531. +#define HAS_RANDOM_INPUT_WAIT 1
  87532. +
  87533. extern void get_random_bytes(void *buf, int nbytes);
  87534. void generate_random_uuid(unsigned char uuid_out[16]);